I have a website that has 3 different types of users: anonymous, registered, elite registered. I have setup the appropriate permissions but my problem is the following: if a user does not have the appropriate permissions to see a piece of content, the content does not appear anywhere on my listings. For example, it does not appear in the results of the Search API, it does not appear in the entity reference listings or the Views.

I want the nodes to appear in various listings but when you try to access the actual node, to get a message that prompts you to register/upgrade your account.

Is this a way to configure such a behavior site-wide? Or would I have to handle the permissions on a per-item basis (e.g. setup the views or override the entity reference permission handling to show the results regardless of the permissions and redirect the Access Denied page to an "Upgrade your account" page)?

2 Answers 2


Here's one way to do it:

  1. Set up your permissions to reference a taxonomy.
  2. Add a hook to change the view_mode of a node you don't want a user to see.

Ours looks like this, we are using a taxonomy called 'Access Level' to control what level of access a node should be shown at (field_access_level). Roles can be given permission against any, all or none of the various taxonomy terms, really useful for segregating products on a Drupal site.

 * Implements hook_perm().
function i_security_access_permission() {
  $permissions = array();
  $terms = taxonomy_get_tree(11);
  // Define permissions using taxonomy Access Level vocabulary
  foreach ($terms as $term) {
    $permissions[$term->name] = array(
      'title' => t($term->name),
      'description' => t('Access content from '. $term->name),
    $permissions['Edit Role Names'] = array(
      'title' => t('Edit Role Names'),
      'description' => t('Allows users to edit role Names'),
  return $permissions;

 * Implements hook_entity_view_mode_alter
 * Sets the view mode to full or teaser based on user access rights
function i_security_access_entity_view_mode_alter (&$view_mode, $context) {
  if (array_key_exists("field_access_level",$context['entity'])) {
    $access_tid = $context['entity']->field_access_level['und'][0]['tid'];

    $access =  taxonomy_term_load($access_tid);
    // Checks if user has access to content
    if (!user_access($access->name) && $view_mode != 'search_index') {
      $view_mode = 'teaser';

You can improve upon it by adding a test for view_mode in your node template and displaying a login button and/or your exhortation to upgrade when the node is shown in teaser mode. Same applies for views.

Some things to note:

  • If you're using a taxonomy and programmatically mapping it to permissions, make sure users can't change the taxonomy terms because all of the permissions get lost
  • User can however, add new taxonomies and remove unwanted ones with impunity. Especially since if you remove a term and then add it back in, the permissions you have set for your roles magically reappear (at least they have in my experience).
  • The && $view_mode != 'search_index' near the end is because I found this was interfering with Apache Solr indexing the site: it was only indexing teasers! I'm not sure what other view_modes there are, so be careful with this.

I wonder if we have the makings of contrib module here?

  • Thank you for the excellent response. One thing that I didn't get is if you are using a module to handle access via terms like Taxonomy Access Control or if you are manually handling all permissions
    – user6102
    Commented Sep 11, 2014 at 0:04
  • No contrib modules were used for this, it plugs straight into the permissions and taxonomy modules =) If you wanted to restrict access to a particular taxonomy I can recommend VPPR.
    – Darvanen
    Commented Sep 11, 2014 at 0:14

you could use a simple 'flag' system...

  • set a boolean field or a dropdown for simpler editing, using field permissions module to restrict who can view/edit this field

  • use Rules to check on view content if the viewer role matches the 'flag' (or minimally matches - i.e. setting the field to 1 allows roles with a level '1' access or higher to access the node). Otherwise it redirects to an access denied page

In this way, the node isn't inherently restricted by the access controls of Drupal, but Rules will make sure it can't actually be viewed as a whole.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.