adva-8.x-1.0-rc9/src/Plugin/adva/OverridingAccessConsumer.php
src/Plugin/adva/OverridingAccessConsumer.php
<?php
namespace Drupal\adva\Plugin\adva;
use Drupal\adva\AccessStorage;
use Drupal\adva\AdvancedAccessEntityAccessControlHandler;
use Drupal\adva\Batch\ConsumerAccessRebuildBatchInterface;
use Drupal\adva\Entity\AccessConsumerInterface as AccessConsumerEntityInterface;
use Drupal\adva\Plugin\adva\Manager\AccessProviderManagerInterface;
use Drupal\adva\Plugin\QueueWorker\RebuildAccessRecordsQueueWorker;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Extends access consumer defintion to override the entity's access handler.
*/
class OverridingAccessConsumer extends AccessConsumer implements OverridingAccessConsumerInterface {
use DependencySerializationTrait;
use MessengerTrait;
use StringTranslationTrait;
/**
* Access Storage Service.
*
* @var \Drupal\adva\AccessStorage
*/
protected $accessStorage;
/**
* The Entity Type Manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The Queue Factory service.
*
* @var \Drupal\Core\Queue\QueueFactory
*/
protected $queueFactory;
/**
* Init Access Consumer instance.
*
* @param array $configuration
* Plugin configuration.
* @param string $plugin_id
* Unique plugin id.
* @param array|mixed $plugin_definition
* Plugin instance definition.
* @param \Drupal\adva\Plugin\adva\Manager\AccessProviderManagerInterface $provider_manager
* Access Provider plugin manager.
* @param \Drupal\adva\AccessStorage $access_storage
* Access Storage service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The Entity Type Manager service.
* @param \Drupal\Core\Queue\QueueFactory $queue_factory
* The Queue Factory service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, AccessProviderManagerInterface $provider_manager, AccessStorage $access_storage, EntityTypeManagerInterface $entity_type_manager, QueueFactory $queue_factory) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $provider_manager, $access_storage);
$this->accessStorage = $access_storage;
$this->entityTypeManager = $entity_type_manager;
$this->queueFactory = $queue_factory;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get("plugin.manager.adva.provider"),
$container->get("adva.access_storage"),
$container->get('entity_type.manager'),
$container->get('queue')
);
}
/**
* {@inheritdoc}
*/
public function onChange(AccessConsumerEntityInterface $config) {
// Queue the entity type's access records for rebuilding.
$this->queue();
}
/**
* {@inheritdoc}
*/
public function overrideAccessControlHandler(EntityTypeInterface $entityType) {
$_class = $entityType->getHandlerClass("access");
if (!$_class) {
throw new InvalidPluginDefinitionException($entityType, sprintf('The "%s" entity type did not specify a %s handler.', $entityType, $entityType));
}
$entityType->setHandlerClass(AdvancedAccessEntityAccessControlHandler::LEGACY_HANDLER_ID, $_class);
// Override Access Class to use the AdvancedAccess Handler.
$entityType->setAccessClass('\Drupal\adva\AdvancedAccessEntityAccessControlHandler');
}
/**
* {@inheritdoc}
*/
public function rebuildRequired() {
$queue = $this
->queueFactory
->get(RebuildAccessRecordsQueueWorker::BASE_QUEUE_ID . ':' . $this->getEntityTypeId());
return (bool) $queue->numberOfItems();
}
/**
* Rebuild the access records.
*
* @param bool $batch_mode
* If false, all records will be requeued.
*
* @deprecated Use
* \Drupal\adva\Plugin\adva\OverridingAccessConsumer::queue() instead.
*/
public function rebuildCache($batch_mode = FALSE) {
@trigger_error(__METHOD__ . '() is deprecated in adva:1.1 and is removed from adva:2.0. Instead, you should use call queue instead.', E_USER_DEPRECATED);
if (!$batch_mode) {
// Queue the rebuilding of access records.
$this->queue();
}
/** @var ConsumerAccessRebuildBatchInterface $rebuild_batch */
$rebuild_batch = \Drupal::service('adva.batch.consumer_access_rebuild');
$rebuild_batch->createBatch($this);
}
/**
* {@inheritdoc}
*/
public function queue(?array $entity_ids = NULL) {
$entity_type_id = $this->getEntityTypeId();
$entity_type = $this
->entityTypeManager
->getDefinition($entity_type_id);
// Clear the entity type's access records.
$this
->accessStorage
->clearRecords($entity_type_id, $entity_ids);
// Get the entity type's queue.
$queue = $this
->queueFactory
->get(RebuildAccessRecordsQueueWorker::BASE_QUEUE_ID . ':' . $entity_type_id);
// If no entity ids were provided, we're completely rebuilding this entity
// type's access records.
if (empty($entity_ids)) {
// Remove any items currently queued for this entity type.
$queue->deleteQueue();
}
// If the entity type has no enabled providers, there is nothing to queue,
// so exit.
if (empty($this->getAccessProviderIds())) {
$this->messenger()
->addMessage($this->t('Access records have been cleared for the %label entity type.', [
'%label' => $entity_type->getLabel(),
]));
return;
}
// The the entity type's storage.
$entityStorage = $this
->entityTypeManager
->getStorage($entity_type_id);
// If no entity ids were provided, get all entity ids for the entity type.
if (empty($entity_ids)) {
$entity_query = $entityStorage->getQuery();
// Disable access checking since all entries must be processed even if the
// user does not have access.
$entity_query->accessCheck(FALSE);
$entity_ids = $entity_query->execute();
}
// Reset the entity cache.
$entityStorage->resetCache($entity_ids);
// Queue the rebuilding of access records for the entities.
foreach ($entity_ids as $entity_id) {
$item = new \stdClass();
$item->entity_type_id = $entity_type_id;
$item->entity_id = $entity_id;
$queue->createItem($item);
}
$this->messenger()
->addMessage($this->t('Access records have been cleared and queued for the %label entity type.', [
'%label' => $this
->entityTypeManager
->getDefinition($entity_type_id)
->getLabel(),
]));
}
}
