Issue #2057377 by Xano: Added Implement hook_entity_access() and hook_entity_create_access().

8.0.x
Alex Pott 2013-09-22 15:09:58 +02:00
parent d7fa47b49b
commit 2891848ce4
4 changed files with 148 additions and 11 deletions

View File

@ -10,6 +10,86 @@
* @{ * @{
*/ */
/**
* Control entity operation access.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity to check access to.
* @param string $operation
* The operation that is to be performed on $entity.
* @param \Drupal\Core\Session\AccountInterface $account
* The account trying to access the entity.
* @param string $langcode
* The code of the language $entity is accessed in.
*
* @return bool|null
* A boolean to explicitly allow or deny access, or NULL to neither allow nor
* deny access.
*
* @see \Drupal\Core\Entity\EntityAccessController
*/
function hook_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account, $langcode) {
return NULL;
}
/**
* Control entity operation access for a specific entity type.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity to check access to.
* @param string $operation
* The operation that is to be performed on $entity.
* @param \Drupal\Core\Session\AccountInterface $account
* The account trying to access the entity.
* @param string $langcode
* The code of the language $entity is accessed in.
*
* @return bool|null
* A boolean to explicitly allow or deny access, or NULL to neither allow nor
* deny access.
*
* @see \Drupal\Core\Entity\EntityAccessController
*/
function hook_ENTITY_TYPE_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account, $langcode) {
return NULL;
}
/**
* Control entity create access.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The account trying to access the entity.
* @param string $langcode
* The code of the language $entity is accessed in.
*
* @return bool|null
* A boolean to explicitly allow or deny access, or NULL to neither allow nor
* deny access.
*
* @see \Drupal\Core\Entity\EntityAccessController
*/
function hook_entity_create_access(\Drupal\Core\Session\AccountInterface $account, $langcode) {
return NULL;
}
/**
* Control entity create access for a specific entity type.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The account trying to access the entity.
* @param string $langcode
* The code of the language $entity is accessed in.
*
* @return bool|null
* A boolean to explicitly allow or deny access, or NULL to neither allow nor
* deny access.
*
* @see \Drupal\Core\Entity\EntityAccessController
*/
function hook_ENTITY_TYPE_create_access(\Drupal\Core\Session\AccountInterface $account, $langcode) {
return NULL;
}
/** /**
* Add to entity type definitions. * Add to entity type definitions.
* *

View File

@ -44,7 +44,7 @@ class EntityAccessController implements EntityAccessControllerInterface {
* The entity type of the access controller instance. * The entity type of the access controller instance.
*/ */
public function __construct($entity_type) { public function __construct($entity_type) {
$this->entity_type = $entity_type; $this->entityType = $entity_type;
} }
/** /**
@ -58,15 +58,19 @@ class EntityAccessController implements EntityAccessControllerInterface {
return $access; return $access;
} }
// Invoke hook_entity_access(), hook results take precedence over overridden // Invoke hook_entity_access() and hook_ENTITY_TYPE_access(). Hook results
// implementations of EntityAccessController::checkAccess(). Entities // take precedence over overridden implementations of
// that have checks that need to be done before the hook is invoked should // EntityAccessController::checkAccess(). Entities that have checks that
// do so by overridding this method. // need to be done before the hook is invoked should do so by overriding
// this method.
// We grant access to the entity if both of these conditions are met: // We grant access to the entity if both of these conditions are met:
// - No modules say to deny access. // - No modules say to deny access.
// - At least one module says to grant access. // - At least one module says to grant access.
$access = $this->moduleHandler->invokeAll($entity->entityType() . '_access', array($entity, $operation, $account, $langcode)); $access = array_merge(
$this->moduleHandler->invokeAll('entity_access', array($entity, $operation, $account, $langcode)),
$this->moduleHandler->invokeAll($entity->entityType() . '_access', array($entity, $operation, $account, $langcode))
);
if (($return = $this->processAccessHookResults($access)) === NULL) { if (($return = $this->processAccessHookResults($access)) === NULL) {
// No module had an opinion about the access, so let's the access // No module had an opinion about the access, so let's the access
@ -196,15 +200,19 @@ class EntityAccessController implements EntityAccessControllerInterface {
return $access; return $access;
} }
// Invoke hook_entity_access(), hook results take precedence over overridden // Invoke hook_entity_create_access() and hook_ENTITY_TYPE_create_access().
// implementations of EntityAccessController::checkAccess(). Entities // Hook results take precedence over overridden implementations of
// that have checks that need to be done before the hook is invoked should // EntityAccessController::checkAccess(). Entities that have checks that
// do so by overridding this method. // need to be done before the hook is invoked should do so by overriding
// this method.
// We grant access to the entity if both of these conditions are met: // We grant access to the entity if both of these conditions are met:
// - No modules say to deny access. // - No modules say to deny access.
// - At least one module says to grant access. // - At least one module says to grant access.
$access = $this->moduleHandler->invokeAll($this->entity_type . '_create_access', array($account, $context['langcode'])); $access = array_merge(
$this->moduleHandler->invokeAll('entity_create_access', array($account, $context['langcode'])),
$this->moduleHandler->invokeAll($this->entityType . '_create_access', array($account, $context['langcode']))
);
if (($return = $this->processAccessHookResults($access)) === NULL) { if (($return = $this->processAccessHookResults($access)) === NULL) {
// No module had an opinion about the access, so let's the access // No module had an opinion about the access, so let's the access

View File

@ -135,4 +135,24 @@ class EntityAccessTest extends EntityUnitTestBase {
'view' => TRUE, 'view' => TRUE,
), $translation); ), $translation);
} }
/**
* Tests hook invocations.
*/
protected function testHooks() {
$state = $this->container->get('state');
$entity = entity_create('entity_test', array(
'name' => 'test',
));
// Test hook_entity_create_access() and hook_ENTITY_TYPE_create_access().
$entity->access('create');
$this->assertEqual($state->get('entity_test_entity_create_access'), TRUE);
$this->assertEqual($state->get('entity_test_entity_test_create_access'), TRUE);
// Test hook_entity_access() and hook_ENTITY_TYPE_access().
$entity->access('view');
$this->assertEqual($state->get('entity_test_entity_access'), TRUE);
$this->assertEqual($state->get('entity_test_entity_test_access'), TRUE);
}
} }

View File

@ -6,6 +6,7 @@
*/ */
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\entity\Entity\EntityFormDisplay; use Drupal\entity\Entity\EntityFormDisplay;
use Drupal\field\Entity\Field; use Drupal\field\Entity\Field;
use Drupal\field\Entity\FieldInstance; use Drupal\field\Entity\FieldInstance;
@ -529,3 +530,31 @@ function entity_test_entity_prepare_view($entity_type, array $entities, array $d
} }
} }
} }
/**
* Implements hook_entity_access().
*/
function entity_test_entity_access(EntityInterface $entity, $operation, AccountInterface $account, $langcode) {
\Drupal::state()->set('entity_test_entity_access', TRUE);
}
/**
* Implements hook_ENTITY_TYPE_access().
*/
function entity_test_entity_test_access(EntityInterface $entity, $operation, AccountInterface $account, $langcode) {
\Drupal::state()->set('entity_test_entity_test_access', TRUE);
}
/**
* Implements hook_entity_create_access().
*/
function entity_test_entity_create_access(AccountInterface $account, $langcode) {
\Drupal::state()->set('entity_test_entity_create_access', TRUE);
}
/**
* Implements hook_ENTITY_TYPE_create_access().
*/
function entity_test_entity_test_create_access(AccountInterface $account, $langcode) {
\Drupal::state()->set('entity_test_entity_test_create_access', TRUE);
}