Site-wide altering of access behavior in Drupal site 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)?
Here's one way to do it:


Set up your permissions to reference a taxonomy.
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-&gt;name] = array(
      'title' =&gt; t($term-&gt;name),
      'description' =&gt; t('Access content from '. $term-&gt;name),
    );
    $permissions['Edit Role Names'] = array(
      'title' =&gt; t('Edit Role Names'),
      'description' =&gt; 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 (&amp;$view_mode, $context) {
  if (array_key_exists("field_access_level",$context['entity'])) {
    $access_tid = $context['entity']-&gt;field_access_level['und'][0]['tid'];

    $access =  taxonomy_term_load($access_tid);
    // Checks if user has access to content
    if (!user_access($access-&gt;name) &amp;&amp; $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 &amp;&amp; $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?