contacts_events-8.x-1.x-dev/src/Plugin/QueueWorker/CloneEventQueueWorker.php
src/Plugin/QueueWorker/CloneEventQueueWorker.php
<?php
namespace Drupal\contacts_events\Plugin\QueueWorker;
use Drupal\contacts_events\Entity\EventInterface;
use Drupal\contacts_events\Event\CloneEvent;
use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Queue\QueueInterface;
use Drupal\Core\Queue\QueueWorkerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Queue worker for cloning events.
*
* @QueueWorker(
* id = "contacts_events_clone",
* title = @Translation("Clone event"),
* cron = {"time" = 30}
* )
*/
class CloneEventQueueWorker extends QueueWorkerBase implements ContainerFactoryPluginInterface {
/**
* The clone queue.
*
* @var \Drupal\Core\Queue\QueueInterface
*/
protected $queue;
/**
* The event entity storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $eventStorage;
/**
* The class resolver.
*
* @var \Drupal\Core\DependencyInjection\ClassResolverInterface
*/
protected $classResolver;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, QueueInterface $queue, EntityStorageInterface $event_storage, ClassResolverInterface $class_resolver) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->queue = $queue;
$this->eventStorage = $event_storage;
$this->classResolver = $class_resolver;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('queue')->get('contacts_events_clone'),
$container->get('entity_type.manager')->getStorage('contacts_event'),
$container->get('class_resolver'),
);
}
/**
* {@inheritdoc}
*/
public function processItem($clone_event) {
if (!($clone_event instanceof CloneEvent)) {
throw new \InvalidArgumentException('Queue data must be a ' . CloneEvent::class);
}
// Ensure we have our event.
/** @var \Drupal\contacts_events\Entity\EventInterface $event */
$event = $this->eventStorage->load($clone_event->getEvent());
if (!$event) {
return;
}
// Return early if the cloning is finished.
if ($clone_event->getProgress() === 100) {
$this->updateEventStatus($event, $clone_event);
return;
}
// Ensure we have our source event.
/** @var \Drupal\contacts_events\Entity\EventInterface $source */
$source = $this->eventStorage->load($clone_event->getSourceEvent());
if (!$source) {
return;
}
// Get the operation.
$operation = $clone_event->getCurrentOperation();
$class = $this->classResolver->getInstanceFromDefinition($operation[0]);
// Run the operation.
$progress = $class->{$operation[1]}(
$event,
$source,
$clone_event->getSandbox(),
);
// Update if the step is completed.
if ($progress === NULL || $progress >= 100) {
$clone_event->markOperationComplete();
$progress = NULL;
}
// Store the status/progress back on the event.
$this->updateEventStatus($event, $clone_event, $progress);
// If the clone is not complete, re-queue the clone.
if ($clone_event->getStatus() === CloneEvent::STATUS_IN_PROGRESS) {
$this->queue->createItem($clone_event);
}
}
/**
* Update the status and progress of the clone on the event.
*
* @param \Drupal\contacts_events\Entity\EventInterface $event
* The new event.
* @param \Drupal\contacts_events\Event\CloneEvent $clone_event
* The event clone event.
* @param int|null $progress
* Optional progress of the current step as an integer between 0 and 100.
*/
protected function updateEventStatus(EventInterface $event, CloneEvent $clone_event, ?int $progress = NULL): void {
$event
->setSetting('clone.status', $clone_event->getStatus())
->setSetting('clone.progress', $clone_event->getProgress($progress))
->save();
}
}
