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);
}
}
