Drupal 8: How to prevent access to pages for an anonymous user

5 Sep.2017
For members only

Suppose before you is the task to prohibit access to some pages for an anonymous user.

For this, there are several great modules in Drupal, some of them:

These modules are very good and customizable, but what if for some reason you try to avoid unnecessary modules on the site and need a very simple solution?

In this case, we can use a very short code in our module.

All we need is to create a boolean field called "For members only" (field_private is machine name) and add some PHP code.

File
YOURMODULE.module
/**
 * Implements hook_node_access().
 */
function YOURMODULE_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account) {
  $type = $node->bundle();
 
  switch ($op) {
    case 'view':
 
      if (\Drupal::currentUser()->isAnonymous() && $node->field_private->value && $node->field_private->value == 1) {
        return AccessResult::forbidden()->cachePerPermissions();
      }
      return AccessResult::neutral();
 
      break;
 
    default:
      // No opinion.
  }
 
  return AccessResult::neutral();
}

You just need to create hook_node_access and check the user and the value of the field.

File
YOURMODULE.module
/**
 * Implements hook_pathauto_alias_alter().
 *
 * @param $alias
 * @param array $context
 */
function YOURMODULE_pathauto_alias_alter(&$alias, array &$context) {
 
  if ($context['module'] != 'node') {
    return;
  }
 
  $node = $context['data']['node'];
 
  if (!isset($node->field_private->value)) {
    return;
  }
  else {
    if ($node->field_private->value == 1) {
      $alias = '/for-members' . $alias;
    }
    else {
      $alias = '/public' . $alias;
    }
  }
}

Optionally, if you use the pathauto module, you can add the prefix to the path when saving the node.

Conclusion

Voilà! As you see everything is very simple and easy. I hope you are like it.

And of course, I will be happy with any comments and new ideas. Until next time...