You are here

Applying node access on a non-node based view

CZÖVEK András's picture

The Views module automatically joins the node_access table only for node based views. In any other case we need to take care of the proper access handling ourselves.

Using Views we were listing field_collections attached to nodes.These few lines of code solved joining the node_access table properly:

/**
 * Implements hook_query_TAG_alter().
 */
function MYMODULE_query_views_MYVIEWNAME_alter($query) {
  // Add a node_access join to a field_collection view.
  $query->addTag('node_access')->addMetaData('base_table', 'field_data_MYFIELDCOLLECTIONNAME');
  _node_query_node_access_alter($query, 'entity');
}

Explanation:

  1. MYMODULE is the name of the module implementing the hook.
  2. MYVIEWNAME is the machine name of the view.
  3. The hook runs because every views query gets the views_MYVIEWNAME tag.
  4. MYFIELDCOLLECTIONNAME is the machine name of the field collection field on the node.
  5. Due to the 'entity' argument of the _node_query_node_access_alter($query, 'entity'); call the 'field_data_MYFIELDCOLLECTIONNAME' table will be joined to the node_access table through its 'entity_id' column. If we have a 'nid' column then we should use 'node' instead of 'entity'.

Comments

Isn't this a bug, then? I don't remeber any warning in Views interface concerning this.

You might look upon this as a bug but Views cannot really do anything about it since when the base table is not {node} it has no information on whether node_access is needed or not. For instance, field collections can be attached to users as well and in that case node_access has no use at all.