Commit 4b77d4ea authored by Luhur Abdi Rizal's avatar Luhur Abdi Rizal
Browse files

Issue #3256387 by el7cosmos: Implements hook_entity_create_access

parent 6aa99525
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ use Drupal\core_event_dispatcher\Event\Entity\EntityBaseFieldInfoAlterEvent;
use Drupal\core_event_dispatcher\Event\Entity\EntityBaseFieldInfoEvent;
use Drupal\core_event_dispatcher\Event\Entity\EntityBuildDefaultsAlterEvent;
use Drupal\core_event_dispatcher\Event\Entity\EntityBundleFieldInfoAlterEvent;
use Drupal\core_event_dispatcher\Event\Entity\EntityCreateAccessEvent;
use Drupal\core_event_dispatcher\Event\Entity\EntityCreateEvent;
use Drupal\core_event_dispatcher\Event\Entity\EntityDeleteEvent;
use Drupal\core_event_dispatcher\Event\Entity\EntityExtraFieldInfoAlterEvent;
@@ -81,7 +82,6 @@ use Drupal\core_event_dispatcher\Event\Language\LanguageSwitchLinksAlterEvent;
// @todo hook_mail()
//
// Entity.
// @todo hook_entity_create_access()
// @todo hook_entity_view_mode_info_alter()
// @todo hook_entity_bundle_info()
// @todo hook_entity_bundle_info_alter()
@@ -301,6 +301,18 @@ function core_event_dispatcher_entity_access(EntityInterface $entity, string $op
  return $event->getAccessResult();
}

/**
 * Implements hook_entity_create_access().
 */
function core_event_dispatcher_entity_create_access(AccountInterface $account, array $context, string $entityBundle = NULL): AccessResultInterface {
  /** @var \Drupal\hook_event_dispatcher\Manager\HookEventDispatcherManagerInterface $manager */
  $manager = Drupal::service('hook_event_dispatcher.manager');
  $event = new EntityCreateAccessEvent($account, $context, $entityBundle);
  $manager->register($event);

  return $event->getAccessResult();
}

/**
 * Implements hook_entity_type_build().
 *
+69 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\core_event_dispatcher\Event\Entity;

use Drupal\Component\EventDispatcher\Event;
use Drupal\Core\Session\AccountInterface;
use Drupal\hook_event_dispatcher\Event\AccessEventInterface;
use Drupal\hook_event_dispatcher\Event\AccessEventTrait;
use Drupal\hook_event_dispatcher\Event\EventInterface;
use Drupal\hook_event_dispatcher\HookEventDispatcherInterface;

/**
 * Class EntityCreateAccessEvent.
 */
class EntityCreateAccessEvent extends Event implements EventInterface, AccessEventInterface {

  /**
   * An associative array of additional context values.
   *
   * @var array
   */
  protected $context;

  /**
   * The entity bundle name.
   *
   * @var string|null
   */
  protected $entityBundle;

  use AccessEventTrait;

  /**
   * EntityCreateAccessEvent constructor.
   */
  public function __construct(AccountInterface $account, array $context, string $entityBundle = NULL) {
    $this->account = $account;
    $this->context = $context;
    $this->entityBundle = $entityBundle;
  }

  /**
   * Gets additional context values.
   *
   * @return array
   *   An array of additional context values.
   */
  public function getContext(): array {
    return $this->context;
  }

  /**
   * Gets the entity bundle name.
   *
   * @return string|null
   *   The entity bundle name.
   */
  public function getEntityBundle(): ?string {
    return $this->entityBundle;
  }

  /**
   * {@inheritdoc}
   */
  public function getDispatcherType(): string {
    return HookEventDispatcherInterface::ENTITY_CREATE_ACCESS;
  }

}
+89 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\core_event_dispatcher\Kernel\Entity;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\core_event_dispatcher\Event\Entity\EntityCreateAccessEvent;
use Drupal\hook_event_dispatcher\HookEventDispatcherInterface;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\hook_event_dispatcher\Kernel\ListenerTrait;

/**
 * Class EntityCreateAccessEvent.
 *
 * @group hook_event_dispatcher
 * @group core_event_dispatcher
 *
 * @covers core_event_dispatcher_entity_create_access()
 * @covers \Drupal\core_event_dispatcher\Event\Entity\EntityCreateAccessEvent
 *
 * @see core_event_dispatcher_entity_create_access()
 */
class EntityCreateAccessEventTest extends KernelTestBase {

  use ListenerTrait;

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'user',
    'entity_test',
    'hook_event_dispatcher',
    'core_event_dispatcher',
  ];

  /**
   * The access result.
   *
   * @var \Drupal\Core\Access\AccessResultInterface
   */
  protected $accessResult;

  /**
   * Test EntityCreateAccessEvent.
   *
   * @dataProvider entityCreateAccessEventProvider
   *
   * @throws \Exception
   */
  public function testEntityCreateAccessEvent(AccessResultInterface $accessResult, bool $access): void {
    $this->listen(HookEventDispatcherInterface::ENTITY_CREATE_ACCESS, 'onEntityCreateAccess');

    $this->accessResult = $accessResult;

    $accessControlHandler = $this->container->get('entity_type.manager')->getAccessControlHandler('entity_test');
    $context = [
      'test' => TRUE,
    ];

    $this->assertEquals($access, $accessControlHandler->createAccess('test_bundle', NULL, $context));
  }

  /**
   * Callback for EntityCreateAccessEvent.
   *
   * @param \Drupal\core_event_dispatcher\Event\Entity\EntityCreateAccessEvent $event
   *   The event.
   */
  public function onEntityCreateAccess(EntityCreateAccessEvent $event): void {
    $context = $event->getContext();
    $this->assertNotEmpty($context['test']);
    $this->assertEquals('test_bundle', $event->getEntityBundle());

    $event->addAccessResult($this->accessResult);
  }

  /**
   * Data provider for testEntityCreateAccessEvent.
   */
  public function entityCreateAccessEventProvider(): array {
    return [
      [AccessResult::allowed(), TRUE],
      [AccessResult::forbidden(), FALSE],
      [AccessResult::neutral(), FALSE],
    ];
  }

}
+12 −0
Original line number Diff line number Diff line
@@ -122,6 +122,18 @@ interface HookEventDispatcherInterface {
   */
  public const ENTITY_ACCESS = self::PREFIX . 'entity.access';

  /**
   * Control entity create access.
   *
   * @Event
   *
   * @see core_event_dispatcher_entity_create_access()
   * @see hook_entity_create_access()
   *
   * @var string
   */
  public const ENTITY_CREATE_ACCESS = self::PREFIX . 'entity.create_access';

  /**
   * Acts when creating a new entity.
   *