<?php
namespace Cms\CoreBundle\Entity;
use Cms\TenantBundle\Entity\TenantedEntity;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping as ORM;
use Reinder83\BinaryFlags\Bits;
/**
* Class OneRosterJob
* @package Cms\CoreBundle\Entity
*
* @ORM\Entity(
* repositoryClass = "Cms\CoreBundle\Doctrine\OneRosterJobRepository"
* )
* @ORM\Table(
* name = "cms__one_roster__job",
* )
*/
class OneRosterJob extends TenantedEntity
{
const PHASES = [
'init' => self::PHASES__INIT,
'stash' => self::PHASES__STASH,
'fix' => self::PHASES__FIX,
'prepare' => self::PHASES__PREPARE,
'process' => self::PHASES__PROCESS,
'link' => self::PHASES__LINK,
'tweak' => self::PHASES__TWEAK,
'tidy' => self::PHASES__TIDY,
];
const PHASES__INIT = Bits::BIT_1;
const PHASES__STASH = Bits::BIT_2;
const PHASES__FIX = Bits::BIT_3;
const PHASES__PREPARE = Bits::BIT_4;
const PHASES__PROCESS = Bits::BIT_5;
const PHASES__LINK = Bits::BIT_6;
const PHASES__TWEAK = Bits::BIT_7;
const PHASES__TIDY = Bits::BIT_8;
const STATUSES__READY = 0;
const STATUSES__RUNNING = Bits::BIT_1;
const STATUSES__COMPLETE = Bits::BIT_2;
const STATUSES__ERROR = ~0;
/**
* @var OneRosterSync|null
*
* @ORM\ManyToOne(
* targetEntity = "Cms\CoreBundle\Entity\OneRosterSync",
* inversedBy = "jobs",
* )
* @ORM\JoinColumn(
* name = "sync",
* referencedColumnName = "id",
* nullable = false,
* onDelete = "CASCADE",
* )
*/
protected ?OneRosterSync $sync = null;
/**
* @var Collection|OneRosterLog[]
*
* @ORM\OneToMany(
* targetEntity = "Cms\CoreBundle\Entity\OneRosterLog",
* mappedBy = "job",
* fetch = "EXTRA_LAZY",
* )
* @ORM\OrderBy({
* "createdAt" = "DESC",
* })
*/
protected Collection $logs;
/**
* @var int
*
* @ORM\Column(
* type = "integer",
* nullable = false,
* options = {
* "default" = self::STATUSES__READY,
* },
* )
*/
protected int $status = self::STATUSES__READY;
/**
* @var int
*
* @ORM\Column(
* type = "integer",
* nullable = false,
* options = {
* "default" = 0,
* },
* )
*/
protected int $startPhase = 0;
/**
* @var int
*
* @ORM\Column(
* type = "integer",
* nullable = false,
* options = {
* "default" = 0,
* },
* )
*/
protected int $phasesReady = 0;
/**
* @var int
*
* @ORM\Column(
* type = "integer",
* nullable = false,
* options = {
* "default" = 0,
* },
* )
*/
protected int $phasesRunning = 0;
/**
* @var int
*
* @ORM\Column(
* type = "integer",
* nullable = false,
* options = {
* "default" = 0,
* },
* )
*/
protected int $phasesComplete = 0;
/**
* @var DateTime|null
*
* @ORM\Column(
* type = "datetime",
* nullable = true,
* )
*/
protected ?DateTime $firstActivityAt = null;
/**
* @var DateTime|null
*
* @ORM\Column(
* type = "datetime",
* nullable = true,
* )
*/
protected ?DateTime $lastActivityAt = null;
/**
* Used to track progress of the syncing process.
* This number reflects the number of outstanding MQ messages that are related to this sync.
* This number should ALWAYS be updated atomically via methods like bulk UPDATE queries.
*
* @var int
*
* @ORM\Column(
* type = "integer",
* nullable = false,
* options = {
* "default" = 0,
* },
* )
*/
protected int $semaphore = 0;
/**
* @var array
*
* @ORM\Column(
* type = "json",
* nullable = true,
* )
*/
protected array $error = [];
/**
* @var Collection|AbstractOneRosterEntity[]
*
* @ORM\OneToMany(
* targetEntity = AbstractOneRosterEntity::class,
* mappedBy = "job",
* )
*/
protected Collection $oneRosterEntities;
/**
*
*/
public function __construct()
{
$this->logs = new ArrayCollection();
}
/**
* @return OneRosterSync
*/
public function getSync(): OneRosterSync
{
return $this->sync;
}
/**
* @param OneRosterSync $sync
* @return $this
*/
public function setSync(OneRosterSync $sync): self
{
$this->sync = $sync;
return $this;
}
/**
* @return int
*/
public function getStartPhase(): int
{
return $this->startPhase;
}
/**
* @return string|null
*/
public function getStartPhaseName(): ?string
{
if ( ! $this->startPhase) {
return null;
}
return array_search($this->startPhase, self::PHASES);
}
/**
* @param int $startPhase
* @return $this
*/
public function setStartPhase(int $startPhase): self
{
$this->startPhase = $startPhase;
return $this;
}
/**
* @return int
*/
public function getPhasesReady(): int
{
return $this->phasesReady;
}
/**
* @return int
*/
public function getPhasesRunning(): int
{
return $this->phasesRunning;
}
/**
* @return int
*/
public function getPhasesComplete(): int
{
return $this->phasesComplete;
}
/**
* @return int|null
*/
public function getCurrentPhase(): ?int
{
foreach (array_reverse(self::PHASES) as $phase) {
if (($this->getPhasesRunning() & $phase) === $phase) {
return $phase;
}
}
return null;
}
/**
* @return DateTime|null
*/
public function getFirstActivityAt(): ?DateTime
{
return $this->firstActivityAt;
}
/**
* @return DateTime|null
*/
public function getLastActivityAt(): ?DateTime
{
return $this->lastActivityAt;
}
/**
* @return int
*/
public function getSemaphore(): int
{
return $this->semaphore;
}
/**
* @return string
*/
public function getIdentifier(): string
{
return implode('::', [
$this->getSync()->getId(),
$this->getId()
]);
}
/**
* @param Criteria|null $criteria
* @return Collection|OneRosterLog[]
*/
public function getLogs(?Criteria $criteria = null): Collection
{
if ( ! $this->logs instanceof Collection) {
$this->logs = new ArrayCollection();
}
if ( ! empty($criteria)) {
return $this->logs->matching($criteria);
}
return $this->logs;
}
/**
* @param Criteria|null $criteria
* @return int
*/
public function countLogs(?Criteria $criteria = null): int
{
return $this->getLogs($criteria)->count();
}
/**
* @return int
*/
public function getStatus(): int
{
return $this->status;
}
/**
* @param int $status
* @return bool
*/
public function isStatus(int $status): bool
{
if ($status === 0) {
return ($this->getStatus() === $status);
} else if ($status > 0) {
if ($this->getStatus() < 0) {
return false;
}
return (($this->getStatus() & $status) === $status);
} else {
if ($this->getStatus() > 0) {
return false;
}
return ((~$this->getStatus() & ~$status) === ~$status);
}
}
/**
* @param int $status
* @return $this
*/
public function setStatus(int $status): self
{
$this->status = $status;
return $this;
}
/**
* @return bool
*/
public function isReady(): bool
{
return $this->isStatus(self::STATUSES__READY);
}
/**
* @return bool
*/
public function isRunning(): bool
{
return $this->isStatus(self::STATUSES__RUNNING);
}
/**
* @return bool
*/
public function isComplete(): bool
{
return $this->isStatus(self::STATUSES__COMPLETE);
}
/**
* @return bool
*/
public function isError(): bool
{
return ($this->getStatus() < 0);
}
/**
* @return array
*/
public function getError(): array
{
return $this->error;
}
/**
* @param array $error
* @return $this
*/
public function setError(array $error): self
{
$this->error = $error;
return $this;
}
/**
* @return Collection
*/
public function getOneRosterEntities(): Collection
{
return $this->oneRosterEntities;
}
/**
* @param Collection $oneRosterEntities
* @return self
*/
public function setOneRosterEntities(Collection $oneRosterEntities): self
{
$this->oneRosterEntities = $oneRosterEntities;
return $this;
}
}