Every entity has got an access() method which determines the access of a certain user (defaults to the current) to a certain operation (usually view/create/update/delete, additional ones can be used.)
use Drupal\node\Entity\Node;
$entity = Node::load(123);
if ($entity->access('view')) {
print entity_view($entity, 'full');
}
A default entity access controlhandler (Drupal\Core\Entity\EntityAccessControlHandler
) is provided that takes care of a static cache for access checks and also invokes a hook named after the entity_type (hook_{$entity_type}_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account)
). This follows the same pattern as hook_node_access() in 7.x. If no hook implementation returns something, checkAccess() is invoked.
A custom access control handler for an entity type can be specified using the following annotation syntax. Such an access control handler must implement EntityAccessControlHandlerInterface, which is a given if the default implementation is extended.
It is also possible to specify an admin_permission annotation if the access logic only depends on that single permission, see [#2108305].
/**
* @EntityType(
* controllers = {
* "access" = "Drupal\my_module\MyEntityAccessControlHandler"
* },
* )
*/
Typically, those entity access control handlers override the EntityAccessControlHandler::checkAccess
method to profit from the default cache and hook support, or they can override the EntityAccessControlHandler::access()
to make sure that certain checks can not be overruled by a hook.
Create access is separated and doesn't get an already instantiated entity object but a context array and optionally the entity bundle. This is to avoid costly object initialization if it's not necessary. Use \Drupal::entityManager()->getAccessControlHandler($entity_type)->createAccess($bundle);
to check create access.
class MyEntityAccessControlHandler extends EntityAccessControlHandler {
public function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
if ($langcode != LanguageInterface::LANGCODE_DEFAULT) {
return $account->hasPermission('view test entity translations');
}
return $account->hasPermission('view test entity');
}
public function access(EntityInterface $entity, $operation, $langcode = LANGUAGE_DEFAULT, AccountInterface $account = NULL) {
if ($account->hasPermission('bypass node access')) {
return TRUE;
}
if (!$account->hasPermission('access content') && $operation == 'view') {
return FALSE;
}
return parent::access($entity, $operation, $langcode, $account);
}
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
$configured_types = node_permissions_get_configured_types();
if (isset($configured_types[$entity_bundle])) {
return $account->hasPermission('create ' . $entity_bundle . ' content');
}
}
}
Modules wishing to assert access control over entities that they do not own may use hook_ENTITY_TYPE_create_access(\Drupal\Core\Session\AccountInterface $account, array $context, $entity_bundle)
to assert access to create a new entity.
Old access functions like node_access()
and term_access()
have been removed.