Rob, I have recently wrestled with this limitation, too, in the development of my node_visibility_bysite module [1]... Rob Thorne wrote:
I'm writing a module for 4.7 that needs to control access to nodes that are only viewable by users who are approved via an external module. To determine if a node is viewable, I need to check the user *and* the node id. This would work, except for a design decision that was made "for performance". Here's what it says in the docs, in the article about "Node access rights" (http://api.drupal.org/api/HEAD/group/node_access):
In node listings, the process above is followed except that hook_access <http://api.drupal.org/api/HEAD/function/hook_access>() is not called on each node for performance reasons and for proper functioning of the pager system. When adding a node listing to your module, be sure to use db_rewrite_sql <http://api.drupal.org/api/HEAD/function/db_rewrite_sql>() to add the appropriate clauses to your query for access checks.
In other words, even if you set up your hook_access to prohibit viewing of your content, Drupal 4.7 *will display your private content to an anonymous user*. Once your private node gets added to the list, there are no further checks to your hook access to determine if your node is safe to display. I don't see any way that hook_db_rewrite_sql can be used for this purpose, since there is no simple relationship between the current user and whether a node should be viewable, short of doing one of the following things:
* I could use a IN () clause to list every node id of the given type that the given user is allowed to see. This may work in my current situation, but there can easily be *thousands* of these in some applications. So this is not a general solution.
[snip] In my case, I ended up with a core hack similar to what you describe here. That is, I did a module-specific conditional extension within db_rewrite_sql. The problem and its solution, I believe, is implicit in your note. There is an underlying presumption in the node_access mechanism that content access conditions are limited to decisions about users and their roles. IOW, _any_ node access decision must be made in the absence of knowledge about the node in question.
<rant> IMNHO, this is complete insane. </rant>
It is an annoyance for sure, but it is probably not completely insane. It is situations like this, however, where I truly miss pure object design (having spent over 20 years as a Smalltalker). I believe the best solution, in your case and mine, is to have a reasoned discussion on how to extend the node access mechanism to be "node-aware." I believe tweaking the parameter spec of this hook mechanism _may_ be all that is needed to allow both user/role and node-state conditional decisions about content visibility. I say "_may_ all that is needed" because there is the possibility that execution-order issues may bite us if we were to rely on a single stage node access mechanism. There may need to be a two-stage mechanism that allows node-state conditions to be applied prior to user/role conditions. Regardless of how best to do it, I agree 100% that we need a more flexible node access hook mechanism. --Sohodojo Jim-- [1] http://lists.drupal.org/archives/development/2006-04/msg00010.html -- Jim Salmons and Timlynn Babitsky Founders and Research Directors Sohodojo - http://sohodojo.com