I'm having difficulty with a particular node type that is not giving my users access according to my custom code. Please check my code?

Scenario:

Node type Openings have a field for Organisation id.
User has same field for Organisation id.

When the user has role "organisation" then they should have full access to all Openings with their Organisation id.

However, in practise, I am finding authorship to be denying them,  where the author is an admin or another role with full perms.


  function mymodule_node_access($node, $op, $account)
{
//implement hook_node_access
  // https://docs.backdropcms.org/api/backdrop/core%21modules%21node%21node.api.php/function/hook_node_access/1
  // this does a check against the Organisation field of a Org Contact, and gives them access to UPDATE the org
// and ensures Coordinators don't have access to other stuff they shouldn't
  foreach ($account->roles as $k => $role) {
    
    if ($role == "organisation") {
      $u = user_load($account->uid);
      $n = 1;
      if(isset($node->nid)) { $n = node_load($node->nid); }
      $noid = 0;
      if (isset($n->field_organisation['und'][0])) {
        $noid=$n->field_organisation['und'][0]['target_id'];        
      }
      if (isset($u->field_organisation['und'][0])) {
        $oid = $u->field_organisation['und'][0]['target_id']; // the orgID
        
        if (isset($node->nid) && $oid == $node->nid && $op == "update") { //for org update
          return NODE_ACCESS_ALLOW;
        }
        
        if ($oid == $noid) { // for Openings
         
          return NODE_ACCESS_ALLOW;
          
        } elseif( $noid !=0 && $op=='update'){ // the case when the Coordinator comes to another Org's Openings: deny them access to EDIT ('update')
         
         return NODE_ACCESS_DENY;
        }
      }
    }
  }
  return NODE_ACCESS_IGNORE;
}

Accepted answer

Turns out all I needed was this module: https://backdropcms.org/project/view_unpublished

Most helpful answers

One suggestion would be to "fail early".  It looks like if the user does not have the organisation field set, none of the other code matters.

if ($role == "organisation") {
  $u = user_load($account->uid);
  if (!isset($u->field_organisation['und'][0])) {
      return NODE_ACCESS_IGNORE;
  }
  ...

This will help simplify your code and debugging.

Also, the node object should already be loaded and available in $node so that removes two more lines of code.

Comments

Hi onyx. No time to debug for you, but have you try step-debugging, or inserting dpm() before each return to check if the logic is working in your code? Also, keep in mind that other hook_node_access implementations in other modules may also be interfering with permissions. 

One suggestion would be to "fail early".  It looks like if the user does not have the organisation field set, none of the other code matters.

if ($role == "organisation") {
  $u = user_load($account->uid);
  if (!isset($u->field_organisation['und'][0])) {
      return NODE_ACCESS_IGNORE;
  }
  ...

This will help simplify your code and debugging.

Also, the node object should already be loaded and available in $node so that removes two more lines of code.

I am seeing via dpm debug that the nodes that are authored by someone else are not even being interrogated at the view level; they are simply avoiding the hook_node_access call. 

Yet the view is not filtering upon authorship.

The same view, previewed by admin with the org's id passed, will show all of the nodes. 

I also note on this screen:

"Furthermore note that content which is not published is treated in a different way by Backdrop: it can be viewed only by its author or users with the administer nodes permission."

That permission is set, but the Org Coordinator is still unable to see in Views unpublished nodes that are not authored by themselves.

Hmmm, from D7 ancient tomes:

from https://drupal.stackexchange.com/questions/7056/limit-which-roles-can-view-a-node-basing-on-its-content-type

yet https://docs.backdropcms.org/api/backdrop/core%21modules%21node%21node.api.php/function/hook_node_access/1 doesn't mention anything of the kind.

And this is the problem; the Views of content I am using are ignoring my hook_node_access attempts to allow them a special view of this content.

So, is there another hook I should be using that Views pays attention to?