Lists like views will not be passed through hook_node_access(), as this would create too much overhead. Views does a query on the database to get the results. hook_node_access() is run in PHP, so these won't work (easily/well/efficently) together.
To deal with lists, you will need to create a grant system, using hook_node_access_records() and hook_node_grants(). This system writes to the {node_access}
table in the database, and when a list is created, the database query is cross-referenced with that table.
hook_node_access_records() is called when a node is saved. Modules that implement this hook can set up various states by which the node is allowed to be accessed.
hook_node_grants() is then called when the node is viewed/updated/deleted. A set of potential grants is created based on the current environment, and these are compared with the states created in hook_node_access_records(). If there is a match, access is provided.
In your case, hook_node_access_records() should create a state whereby if the node has the field field_content_protect
, then a state should be created upon which view access can be either granted or denied in hook_node_grants(). Example:
function MODULE_node_access_records(\Drupal\node\NodeInterface $node) {
if ($node->hasField('field_content_protect')) {
$grants = [];
$grants[] = [
'realm' => 'MODULE_protect_content',
// This is set to 1. In hook_node_grants(),
// A value will be created based on the user's
// logged in state, and compared to this value.
'gid' => 1,
'grant_view' => 1,
'grant_update' => 0,
'grant_delete' => 0,
];
return $grants;
}
}
The above sets up a state, whereby if a grant is created for the realm MODULE_protect_content
that has a value of 1, the user should be granted view access. The next thing is to implement hook_node_grants()
and create a grant based on the current user's status.
function MODULE_node_grants() {
$current_user = \Drupal::currentUser();
$grants = [];
// This will set a value of 0 (zero) or 1 (one)
// for the realm MODULE_protect_content. If the
// value is 1 (authenticated user) the user will
// be provided view access to the node. Note
// that an array of values must be passed for
// realms.
$status = (int) $current_user->isAuthenticated();
$grants['MODULE_protect_content'] = [$status];
return $grants.
}
For the above code, a grant is created based on the logged in status of the current user. If they are logged in, $status
will equal 1
, which is compared with the state provided in hook_node_access_records()
providing access to the user.
You could actually alter the above hook_node_grants() to only return a grant if the user is logged in. I'm not sure which one would be more efficient. I suspect the code below may be:
function MODULE_node_grants() {
$current_user = \Drupal::currentUser();
if ($status = (int) $current_user->isAuthenticated()) {
$grants = [];
// This will set a value of 1 (one)
// for the realm MODULE_protect_content, which
// matches the state created in
// hook_node_access_records(). Note that
// an array of values must be passed for
// realms.
$grants['MODULE_protect_content'] = [$status];
return $grants.
}
}