contacts_events-8.x-1.x-dev/src/Event/CloneEvent.php
src/Event/CloneEvent.php
<?php namespace Drupal\contacts_events\Event; use Drupal\contacts_events\Entity\EventInterface; use Symfony\Component\EventDispatcher\Event; /** * The event object for cloning events. */ class CloneEvent extends Event { /** * Clone status - pending. * * The initial status until the queue has been populated. */ const STATUS_PENDING = 'pending'; /** * Clone status - in progress. * * Indicated that the queue has been generated and will be execute on cron. */ const STATUS_IN_PROGRESS = 'in_progress'; /** * Clone status - completed. * * Cloning has been finished. */ const STATUS_COMPLETED = 'completed'; /** * The event entity ID. * * @var int */ protected $event; /** * The source event entity ID. * * @var int */ protected $sourceEvent; /** * The status of the clone process. * * @var string */ protected $status = self::STATUS_PENDING; /** * An array of operations to call. * * Values are arrays containing the following: * - Service name of fully qualified class the operation exists on. * - Name of the method to call. * - The operation description. * * @var array */ protected $operations = []; /** * An array of completed operations. * * @var array */ protected $completedOperations = []; /** * The sandbox for the current operation. * * @var array */ protected $sandbox = []; /** * Construct the clone event. * * @param \Drupal\contacts_events\Entity\EventInterface|int $event * The event entity or ID. * @param \Drupal\contacts_events\Entity\EventInterface|int $source_event * The source event entity or ID. */ public function __construct($event, $source_event) { $this->event = $event instanceof EventInterface ? $event->id() : $event; $this->sourceEvent = $source_event instanceof EventInterface ? $source_event->id() : $source_event; } /** * Get the event ID. * * @return int * The event ID. */ public function getEvent(): int { return $this->event; } /** * Get the source event ID. * * @return int * The source event ID. */ public function getSourceEvent(): int { return $this->sourceEvent; } /** * Get the current status. * * @return string * One of the STATUS_* constants. */ public function getStatus(): string { return $this->status; } /** * Update the status of the event. * * @return $this */ protected function updateStatus() { if ($this->status === self::STATUS_IN_PROGRESS && empty($this->operations)) { $this->status = self::STATUS_COMPLETED; } return $this; } /** * Add an operation for the clone queue worker. * * @param string $service_or_class * The service name or fully qualified class. * @param string $method * The method to call. * @param string|\Drupal\Core\StringTranslation\TranslatableMarkup $description * The description of the operation. * * @return $this */ public function addOperation(string $service_or_class, string $method, $description) { if ($this->status !== self::STATUS_PENDING) { throw new \RuntimeException('Cannot add operations to an in progress clone.'); } $this->operations[] = [$service_or_class, $method, $description]; return $this; } /** * Get the current operation. * * @return array * The operation array. * * @see CloneEvent::$operations */ public function getCurrentOperation(): array { // If the status is pending, mark it as in progress. if ($this->status === self::STATUS_PENDING) { $this->status = self::STATUS_IN_PROGRESS; } // Get the current operation. return reset($this->operations); } /** * Get the sandbox for the current operation. * * @return array * The sandbox data. */ public function &getSandbox(): array { return $this->sandbox; } /** * Mark the current operation as completed. * * @return $this */ public function markOperationComplete() { $this->completedOperations[] = array_shift($this->operations); $this->sandbox = []; $this->updateStatus(); return $this; } /** * Get the current progress of the clone. * * @return int * The progress as a percentage. */ public function getProgress(?int $operation_progress = NULL): int { // If there are no pending operations, we have finished (100%). $pending = count($this->operations); if ($pending === 0) { return 100; } // Get the number of operations. $completed = count($this->completedOperations); $total = $completed + $pending; $progress = $completed / $total * 100; // If we have an operation progress, add that in. if ($operation_progress) { $progress += $operation_progress / $total; } // Floor and return. return floor($progress); } }