So I am researching Taxonomy Access Control (TAC) and Domain Access (DA) integration (though this applies to Organic Groups (OG) and other modules as well). And here's the problem.
node_access_rebuild(), as far as I can tell, is only designed to work with a single access control system.
When node access modules are enabled and disabled, this function is typically invoked. (As demonstrated by the node access example module.
Problem is this first line of the function:
<?php
function node_access_rebuild() {
db_query("DELETE FROM {node_access}");
?>Well, this is great if OG is the only node access module that you use. But if there are existing node access records, they get deleted as well.
DA, for example, stores all of its access records in the {node_access} table. It loads them onto the node during node_load(). If this DELETE statement did not exist, then when node_access_rebuild() finally loaded and re-saved the nodes, existing DA rules would be preserved.
I see two obvious paths to solving this problem. One I like; one I do not.
1) Make node_access_rebuild() more selective, like cache_clear_all(), in what it chooses to delete from the {node_access} table. If your module is being uninstalled, you might do this:
<?php
function mymodule_disable() {
node_access_rebuild($remove = array('my_realm', 'my_other_realm'));
}
?>And then we modify node_access_rebuild() to account for this.
<?php
function node_access_rebuild($remove = array()) {
if (empty($remove)) {
db_query("DELETE FROM {node_access}");
}
else {
db_query("DELETE FROM {node_access} WHERE realm IN (". implode(',', $remove) .")");
}
//...
?>I think this is the preferred solution, but it is an API change and would require coordination across contributed modules to make the change work.
2) Store your node access data in a separate table, so that it is not destroyed by node_access_rebuild().
I thought about this approach for DA, and decided against it because I did not want to store the same data in two places.
Am I now going to have to re-think that decision?

Comments
To be fair
DA calls node_access_rebuild(), as well, during domain_enable() and domain_disable(), because the API says to.
--
http://ken.therickards.com/
http://savannahnow.com/user/2
http://blufftontoday.com/user/3
--
http://ken.therickards.com/
Fixed, but not fixed
I just finished testing some code that solves this issue by implementing #2, above.
However, DA and TAC, at least, now have the following problem.
The "rebuild permissions" button at 'admin/content/node-settings' does not reset the {node_access} table to its original state. Since both modules store data in external tables, they allow node_access_rebuild() to re-insert their data.
While this behavior is desirable when installing additional modules, it is not desirable from this specific form. Which is yet another indicator that node_access_rebuild() needs to be rewritten entirely for D7. If not sooner.
It also seems to me that installing DA or TAC after running OG for a while would delete all existing OG rules when node_access_rebuild() is run.
I am, by the way, proposing a session at DrupalCon Boston where we can hash through these issues for D7.
--
http://ken.therickards.com/
http://savannahnow.com/user/2
http://blufftontoday.com/user/3
--
http://ken.therickards.com/
Count me in... I keep doing access stuff I don't understand
However, my understanding is that all access control modules should be, if not storing, then deriving their data from other sources-- not storing settings or whatever in {node_access} but populating {node_access} when asked.
Have you verified an actual conflict/problem?
benjamin, Agaric Design Collective
benjamin, agaric
Seems to be true
I think you are right, but I should re-check the documentation to be sure that is clear. I had hoped to be able to store all data inside {node_access}.
It could be that I simply misunderstand the issue.
--
http://ken.therickards.com/
http://savannahnow.com/user/2
http://blufftontoday.com/user/3
--
http://ken.therickards.com/
Documentation
It's documented, but not explicilty stated that you need your own table.
http://api.drupal.org/api/file/developer/examples/node_access_example.mo...
Should add something to that page with respect to node_access_rebuild.
In order to maintain your node access rules when additional modules are enabled, you should always store your module's specific data inside its own database table. Storing rules only in {node_access} may cause them to be deleted when new modules are installed.--
http://ken.therickards.com/
http://savannahnow.com/user/2
http://blufftontoday.com/user/3
--
http://ken.therickards.com/