the views assumes private nodes as regular nodes, so if we define for example 10 nodes to display in the view, if the first two nodes are private, then the view will display only 8 nodes.

To prevent this, I think the better would be to implement the hook views_alter_query, in order to add a new "WHERE private=0" in the query.

Here is the patch:

/**
 * Hook views_query_alter
 */
function private_views_query_alter(&$query, &$view) {
  if (!user_access('access private content')) {
    // the user has no access to private content
    // so we alter the query
   
    $query->add_table('private');
    $private_join = array(
      'left' => array(
        'table' => 'node',
        'field' => 'nid'
      ),
      'right' => array(
        'table' => 'private',
        'field' => 'nid'
      ),
    );
    $query->joins['private'][1]=$private_join;
    $query->add_where('private.private = 0');
  }
}

Comments

dingbats’s picture

But, would this make it impossible to have a block of "My private nodes"?

dingbats’s picture

I'm running 6.x-1.x-dev, with an altered version of your code,

/**
* Hook views_query_alter
*/
function private_views_query_alter(&$view, &$query) {
  if (!user_access('access private content')) {
    // the user has no access to private content
    // so we alter the query
    $private_join = array(
      'left' => array(
        'table' => 'node',
        'field' => 'nid'
      ),
      'right' => array(
        'table' => 'private',
        'field' => 'nid'
      ),
    );

    $query->add_table('private', 'node', $private_join);
    $query->add_where(0, 'private.private = 0');
  } 
}   

Assuming I create a new view: a page of my nodes that I have marked private, this is the SQL generated:

SELECT node.nid AS nid,
   node.sticky AS node_sticky,
   node.created AS node_created
 FROM node node 
 LEFT JOIN private private ON node.nid = private.nid
 WHERE (node.promote <> 0) AND (private.private = 1) AND (private.private = 0)
   ORDER BY node_sticky DESC, node_created DESC

The constraint (private.private = 1) AND (private.private = 0) will always bring up an empty set.

dingbats’s picture

Sorry for confusing anybody who tried the above code and did not get the same query result. I had made some patches to my Private module to integrate it with Views. See #361392: Views integration drupal 5.x for more info.

greggles’s picture

Issue summary: View changes
Status: Active » Closed (outdated)

Marking this as closed-outdated as the 5.x version is no longer supported and I don't think this issue affects the 6.x and later versions.

If the problem persists on newer versions, please reopen this issue.

Thanks!