It should be useful add a policy for let a group of users to view the node even if the node is set as private.
I've tried to modify the module adding on private_nodes_perm():

  foreach ($types as $v) {
    $permissions[] = 'user can view private node (type: ' . $v . ')';
  }

So, in the private_nodes_check_access() we can check this policy too. I've add this:

  $node = node_load(array('nid' => $nid));
  $type = $node->type;
  $nodetypes = private_nodes_get_node_types();
  if (user_access('user can view private node (type: ' . $nodetypes[$type] . ')')) {
    return true;
  }

before the check of the ($is_owner || $is_admin || !isset ($level)).

What do you think?

Comments

ben_scott’s picture

I think that's a great idea - I'll add it to the module when I get a moment. :)

Thanks very much.

finex’s picture

StatusFileSize
new835 bytes

Here is the patch for the head version of private nodes.

finex’s picture

I'm using this patch with the views module, but the views module doesn't work correctly with the "user can view private node of type" permission:
1) i've set a node as private (owner user John)
2) the user Tom have the "user can view private node of type" permission.
3) Tom can access to the node (ok, the permission so work)
4) Tom doesn't view the node from a views that should list the node.

We need to fix the private_nodes_db_rewrite_sql(). I'll try.

finex’s picture

Before the:

  }
  return $return; 
}

on the private_nodes_db_rewrite_sql() function, I've added this code:


$types = private_nodes_get_node_types();

$permissions = "";

if(is_array($types)){
  foreach ($types as $v) {
    if (user_access('user can view private node of type: ' . $v)) {
      $permissions =  $permissions . "OR node.type = '" . $v ."' ";
    }
  }
}
  
if ($permissions != "") {
  $permissions = " OR ( " . substr($permissions, 2) . " )";
<strong>  $return['where'] = $return['where'] . $permissions;  /* ON THE VIEWS MODULE THIS CODE IS OK BUT IT BREAK THE FORUM AND THE IMAGE MODULES */</strong>
}

With this code the views module show the correct records: when an user can view the private nodes, the views show them. But I've found two big problem: the forums and the image gallery stop work! Both show zero records.

I don't know how to execute this code only in the views.

finex’s picture

Sorry, the problem on the image gallery module was an error introduced by a misconfiguration. The problem is only in the forum.

Mantichora’s picture

I have tried your code, it seems to work for me but I did change the location.
Maybe you should try it too?

if(($primary_field=='nid' && ...){
  ...
  if($user->uid){
    $types = private_nodes_get_node_types();
    $permissions = "";
    if(is_array($types)){
      foreach ($types as $v) {
        if (user_access('user can view private node of type: ' . $v)) {
          $permissions =  $permissions . " OR node.type = '" . $v ."'";
        }
      }
    }

    if (function_exists('private_nodes_get_uid_of_buddies')) {
       $buddies=private_nodes_get_uid_of_buddies($user->uid);
       
       if(is_array($buddies)){ //user has buddies
         $buddies=implode(',',private_nodes_get_uid_of_buddies($user->uid));
         $return['where'] = "(pn.nid is null OR (pn.level=".PRIVATE_NODES_BUDDIES." AND {$primary_table}.uid IN (".$buddies."))  OR {$primary_table}.uid=".$user->uid." $permissions)";
       }else{ //user doesn't have any buddies
         $return['where'] = "(pn.nid is null OR {$primary_table}.uid=".$user->uid." $permissions)";
       } 
finex’s picture

StatusFileSize
new2.56 KB

Moving the code work as before: The image gallery and the forum does't work.

On the forum I've this error:

user warning: Unknown column 'node.type' in 'where clause' query: SELECT r.tid, COUNT( DISTINCT(n.nid)) AS topic_count, SUM(l.comment_count) AS comment_count FROM node n INNER JOIN node_comment_statistics l ON n.nid = l.nid INNER JOIN term_node r ON n.nid = r.nid INNER JOIN node_access na ON na.nid = n.nid LEFT OUTER JOIN private_nodes pn ON pn.nid = n.nid WHERE (na.grant_view >= 1 AND ((na.gid = 0 AND na.realm = 'all') OR (na.gid = 2 AND na.realm = 'term_access') OR (na.gid = 3 AND na.realm = 'term_access') OR (na.gid = 4 AND na.realm = 'term_access') OR (na.gid = 11 AND na.realm = 'term_access') OR (na.gid = 16 AND na.realm = 'term_access') OR (na.gid = 17 AND na.realm = 'term_access'))) AND ((pn.nid is null OR n.uid=10 OR node.type = 'comunicazione' OR node.type = 'movimento' OR node.type = 'resoconto')) AND ( n.status = 1 AND n.type = 'forum' ) GROUP BY r.tid in /web/htdocs/www.arteficidelfuoco.com/home/includes/database.mysql.inc on line 172.

Where "comunicazione", "movimento" and "resoconto" are the node type which the current user can view with the

user_access('user can view private node of type: ' . $v)

permission.

In the same way on the image gallery I've this:

user warning: Unknown column 'node.type' in 'where clause' query: SELECT t.tid, COUNT( DISTINCT(n.nid)) AS c FROM term_node t INNER JOIN node n ON t.nid = n.nid INNER JOIN node_access na ON na.nid = n.nid LEFT OUTER JOIN private_nodes pn ON pn.nid = n.nid WHERE (na.grant_view >= 1 AND ((na.gid = 0 AND na.realm = 'all') OR (na.gid = 2 AND na.realm = 'term_access') OR (na.gid = 3 AND na.realm = 'term_access') OR (na.gid = 4 AND na.realm = 'term_access') OR (na.gid = 11 AND na.realm = 'term_access') OR (na.gid = 16 AND na.realm = 'term_access') OR (na.gid = 17 AND na.realm = 'term_access'))) AND ((pn.nid is null OR n.uid=10 OR n.type = 'comunicazione' OR node.type = 'movimento' OR node.type = 'resoconto')) AND ( n.status = 1 AND n.type = 'image' ) GROUP BY t.tid in /web/htdocs/www.arteficidelfuoco.com/home/includes/database.mysql.inc on line 172.

The problem is on the name assigned to the node table: on the views the alias is "node" on the forum or the image gallery, it is "n".
I've tried to change the code:

$permissions =  $permissions . " OR node.type = '" . $v ."'";

to:

$permissions =  $permissions . " OR n.type = '" . $v ."'";

In this way the forum and the image gallery works correctly, but the views created with the views module stop working because them use the alias "node" for the node table.

We have to use this code for have this function work correctly:

$permissions =  $permissions . " OR {$primary_table}.type = '" . $v ."'";

I attach the full patch to the private module, for the current version available:
http://ftp.drupal.org/files/projects/private_nodes-5.x-1.x-dev.tar.gz

If someone can test the patch after we should apply it to the module.

Thanks all!

:-)

finex’s picture

StatusFileSize
new2.48 KB

Updated patch, the previous one is wrong.

finex’s picture

There is an issue to this patch.
Actually the private_nodes_get_node_types() return the NAME of the node type, not the TYPE.
In this way if the NAME contains special char (such spaces) the queries will be broken.
The Simple solution is to modify the rivate_nodes_get_node_types().
From:

function private_nodes_get_node_types() {

  $types = node_get_types();

  foreach ($types as $k => $v) {
    if (function_exists('is_nodeprofile')) {
      if (!is_nodeprofile($k)) {
        $node_types[$k] = strtolower($v->name);
      }
    }else{
      $node_types[$k] = strtolower($v->name);	
    }
  }

  return $node_types;

}

To:

function private_nodes_get_node_types() {

  $types = node_get_types();

  foreach ($types as $k => $v) {
    if (function_exists('is_nodeprofile')) {
      if (!is_nodeprofile($k)) {
        $node_types[$k] = strtolower($v->type);
      }
    }else{
      $node_types[$k] = strtolower($v->type;	
    }
  }

  return $node_types;

}

I've full tested this and it works flawlessly.