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.
*

View File

@ -44,7 +44,7 @@ class EntityAccessController implements EntityAccessControllerInterface {
* The entity type of the access controller instance.
*/
public function __construct($entity_type) {
$this->entity_type = $entity_type;
$this->entityType = $entity_type;
}
/**
@ -58,15 +58,19 @@ class EntityAccessController implements EntityAccessControllerInterface {
return $access;
}
// Invoke hook_entity_access(), hook results take precedence over overridden
// implementations of EntityAccessController::checkAccess(). Entities
// that have checks that need to be done before the hook is invoked should
// do so by overridding this method.
// Invoke hook_entity_access() and hook_ENTITY_TYPE_access(). Hook results
// take precedence over overridden implementations of
// EntityAccessController::checkAccess(). Entities that have checks that
// 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:
// - No modules say to deny 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) {
// No module had an opinion about the access, so let's the access
@ -196,15 +200,19 @@ class EntityAccessController implements EntityAccessControllerInterface {
return $access;
}
// Invoke hook_entity_access(), hook results take precedence over overridden
// implementations of EntityAccessController::checkAccess(). Entities
// that have checks that need to be done before the hook is invoked should
// do so by overridding this method.
// Invoke hook_entity_create_access() and hook_ENTITY_TYPE_create_access().
// Hook results take precedence over overridden implementations of
// EntityAccessController::checkAccess(). Entities that have checks that
// 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:
// - No modules say to deny 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) {
// 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,
), $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\Session\AccountInterface;
use Drupal\entity\Entity\EntityFormDisplay;
use Drupal\field\Entity\Field;
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);
}