adva-8.x-1.0-rc9/src/Batch/ConsumerAccessRebuildBatch.php
src/Batch/ConsumerAccessRebuildBatch.php
<?php
namespace Drupal\adva\Batch;
use Drupal\adva\Plugin\adva\OverridingAccessConsumerInterface;
use Drupal\adva\Plugin\QueueWorker\RebuildAccessRecordsQueueWorker;
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\Queue\QueueWorkerManagerInterface;
use Drupal\Core\Queue\SuspendQueueException;
use Drupal\Core\StringTranslation\StringTranslationTrait;
class ConsumerAccessRebuildBatch implements ConsumerAccessRebuildBatchInterface {
use DependencySerializationTrait;
use MessengerTrait;
use StringTranslationTrait;
public function __construct(
public EntityTypeManagerInterface $entityTypeManager,
public QueueFactory $queueFactory,
public QueueWorkerManagerInterface $queueManager
) {
// Do nothing.
}
/**
* {@inheritdoc}
*/
public function createBatch(OverridingAccessConsumerInterface $access_consumer) {
// If the entity type doesn't have any providers enabled to provide access
// records, exit.
if (empty($access_consumer->getAccessProviderIds())) {
return;
}
$entity_type = $this
->entityTypeManager
->getDefinition($access_consumer->getEntityTypeId());
$batch = [
'title' => $this->t('Rebuilding %entity_type Access Records', ['%entity_type' => $entity_type->getLabel()]),
'operations' => [
[
[$this, 'process'],
[$entity_type],
],
],
'finished' => [$this, 'finished'],
];
// Add the batch sets.
batch_set($batch);
}
public function process(EntityTypeInterface $entity_type, &$context) {
$queue_plugin_id = RebuildAccessRecordsQueueWorker::BASE_QUEUE_ID . ':' . $entity_type->id();
$queue = $this->queueFactory->get($queue_plugin_id);
$queue_worker = $this->queueManager->createInstance($queue_plugin_id);
// Pass the entity type to the finished function.
if (empty($context['results'])) {
$context['results']['entity_type'] = $entity_type;
}
// Initiate the sandbox if it hasn't already been done.
if (empty($context['sandbox'])) {
$context['sandbox']['processed'] = 0;
$context['sandbox']['count'] = $queue->numberOfItems();
}
// Process queued items in groups of ::REBUILD_ACCESS_RECORDS_LIMIT. Get the
// number of items from the queue so concurrent processes don't cause
// miscounts.
for ($i = 0; $queue->numberOfItems() && $i < static::REBUILD_ACCESS_RECORDS_LIMIT; ++$i) {
$item = $queue->claimItem();
if ($item) {
try {
$queue_worker->processItem($item->data);
$queue->deleteItem($item);
++$context['sandbox']['processed'];
}
catch (SuspendQueueException $e) {
// If there was an Exception thrown because of an error, release the
// item that the worker could not process.
$queue->releaseItem($item);
break;
}
}
else {
// Item is false if all items in the queue have active leases. Finish
// the batch and exit.
$context['finished'] = TRUE;
break;
}
}
// If the queue has any items in it, the batch is not complete.
$context['finished'] = $context['sandbox']['count'] ? $context['sandbox']['processed'] / $context['sandbox']['count'] : TRUE;
}
public function finished($success, $results, $operations) {
if ($success) {
$this->messenger()->addMessage($this->t('Access records have been rebuilt for the %entity_type entity type.', ['%entity_type' => $results['entity_type']->getLabel()]));
}
else {
$error_operation = reset($operations);
$t_args = [
'@operation' => $error_operation[0],
'@args' => print_r($error_operation[1], TRUE),
];
$this->messenger()->addMessage($this->t('An error occurred while processing @operation with arguments : @args', $t_args));
}
}
}
