mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
412 lines
9.4 KiB
PHP
412 lines
9.4 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Chill\MainBundle\Entity\Workflow;
|
|
|
|
use Chill\MainBundle\Entity\User;
|
|
use DateTimeImmutable;
|
|
use Doctrine\Common\Collections\ArrayCollection;
|
|
use Doctrine\Common\Collections\Collection;
|
|
use Doctrine\ORM\Mapping as ORM;
|
|
use Symfony\Component\Validator\Constraints as Assert;
|
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
|
use function count;
|
|
use function in_array;
|
|
|
|
/**
|
|
* @ORM\Entity
|
|
* @ORM\Table("chill_main_workflow_entity_step")
|
|
*/
|
|
class EntityWorkflowStep
|
|
{
|
|
/**
|
|
* @ORM\Column(type="text", nullable=false)
|
|
*/
|
|
private string $accessKey;
|
|
|
|
/**
|
|
* @ORM\Column(type="text", options={"default": ""})
|
|
*/
|
|
private string $comment = '';
|
|
|
|
/**
|
|
* @ORM\Column(type="text")
|
|
*/
|
|
private ?string $currentStep = '';
|
|
|
|
/**
|
|
* @ORM\Column(type="json")
|
|
*/
|
|
private array $destEmail = [];
|
|
|
|
/**
|
|
* @ORM\ManyToMany(targetEntity=User::class)
|
|
* @ORM\JoinTable(name="chill_main_workflow_entity_step_user")
|
|
*/
|
|
private Collection $destUser;
|
|
|
|
/**
|
|
* @ORM\ManyToMany(targetEntity=User::class)
|
|
* @ORM\JoinTable(name="chill_main_workflow_entity_step_user_by_accesskey")
|
|
*/
|
|
private Collection $destUserByAccessKey;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(targetEntity=EntityWorkflow::class, inversedBy="steps")
|
|
*/
|
|
private ?EntityWorkflow $entityWorkflow = null;
|
|
|
|
/**
|
|
* @ORM\Column(type="boolean", options={"default": false})
|
|
*/
|
|
private bool $freezeAfter = false;
|
|
|
|
/**
|
|
* @ORM\Id
|
|
* @ORM\GeneratedValue
|
|
* @ORM\Column(type="integer")
|
|
*/
|
|
private ?int $id = null;
|
|
|
|
/**
|
|
* @ORM\Column(type="boolean", options={"default": false})
|
|
*/
|
|
private bool $isFinal = false;
|
|
|
|
/**
|
|
* filled by @see{EntityWorkflow::getStepsChained}.
|
|
*/
|
|
private ?EntityWorkflowStep $next = null;
|
|
|
|
/**
|
|
* filled by @see{EntityWorkflow::getStepsChained}.
|
|
*/
|
|
private ?EntityWorkflowStep $previous = null;
|
|
|
|
/**
|
|
* @ORM\Column(type="text", nullable=true, options={"default": null})
|
|
*/
|
|
private ?string $transitionAfter = null;
|
|
|
|
/**
|
|
* @ORM\Column(type="datetime_immutable", nullable=true, options={"default": null})
|
|
*/
|
|
private ?DateTimeImmutable $transitionAt = null;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(targetEntity=User::class)
|
|
* @ORM\JoinColumn(nullable=true)
|
|
*/
|
|
private ?User $transitionBy = null;
|
|
|
|
/**
|
|
* @ORM\Column(type="text", nullable=true)
|
|
*/
|
|
private ?string $transitionByEmail = null;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->destUser = new ArrayCollection();
|
|
$this->destUserByAccessKey = new ArrayCollection();
|
|
$this->accessKey = bin2hex(openssl_random_pseudo_bytes(32));
|
|
}
|
|
|
|
public function addDestEmail(string $email): self
|
|
{
|
|
if (!in_array($email, $this->destEmail, true)) {
|
|
$this->destEmail[] = $email;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function addDestUser(User $user): self
|
|
{
|
|
if (!$this->destUser->contains($user)) {
|
|
$this->destUser[] = $user;
|
|
$this->getEntityWorkflow()
|
|
->addSubscriberToFinal($user)
|
|
->addSubscriberToStep($user);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function addDestUserByAccessKey(User $user): self
|
|
{
|
|
if (!$this->destUserByAccessKey->contains($user) && !$this->destUser->contains($user)) {
|
|
$this->destUserByAccessKey[] = $user;
|
|
$this->getEntityWorkflow()
|
|
->addSubscriberToFinal($user)
|
|
->addSubscriberToStep($user);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getAccessKey(): string
|
|
{
|
|
return $this->accessKey;
|
|
}
|
|
|
|
/**
|
|
* get all the users which are allowed to apply a transition: those added manually, and
|
|
* those added automatically bu using an access key.
|
|
*/
|
|
public function getAllDestUser(): Collection
|
|
{
|
|
return new ArrayCollection(
|
|
[
|
|
...$this->getDestUser()->toArray(),
|
|
...$this->getDestUserByAccessKey()->toArray(),
|
|
]
|
|
);
|
|
}
|
|
|
|
public function getComment(): string
|
|
{
|
|
return $this->comment;
|
|
}
|
|
|
|
public function getCurrentStep(): ?string
|
|
{
|
|
return $this->currentStep;
|
|
}
|
|
|
|
public function getDestEmail(): array
|
|
{
|
|
return $this->destEmail;
|
|
}
|
|
|
|
/**
|
|
* get dest users added by the creator.
|
|
*
|
|
* You should **not** rely on this method to get all users which are able to
|
|
* apply a transition on this step. Use @see{EntityWorkflowStep::getAllDestUser} instead.
|
|
*/
|
|
public function getDestUser(): Collection
|
|
{
|
|
return $this->destUser;
|
|
}
|
|
|
|
public function getDestUserByAccessKey(): Collection
|
|
{
|
|
return $this->destUserByAccessKey;
|
|
}
|
|
|
|
public function getEntityWorkflow(): ?EntityWorkflow
|
|
{
|
|
return $this->entityWorkflow;
|
|
}
|
|
|
|
public function getId(): ?int
|
|
{
|
|
return $this->id;
|
|
}
|
|
|
|
public function getNext(): ?EntityWorkflowStep
|
|
{
|
|
return $this->next;
|
|
}
|
|
|
|
public function getPrevious(): ?EntityWorkflowStep
|
|
{
|
|
return $this->previous;
|
|
}
|
|
|
|
public function getTransitionAfter(): ?string
|
|
{
|
|
return $this->transitionAfter;
|
|
}
|
|
|
|
public function getTransitionAt(): ?DateTimeImmutable
|
|
{
|
|
return $this->transitionAt;
|
|
}
|
|
|
|
public function getTransitionBy(): ?User
|
|
{
|
|
return $this->transitionBy;
|
|
}
|
|
|
|
public function getTransitionByEmail(): ?string
|
|
{
|
|
return $this->transitionByEmail;
|
|
}
|
|
|
|
public function isFinal(): bool
|
|
{
|
|
return $this->isFinal;
|
|
}
|
|
|
|
public function isFreezeAfter(): bool
|
|
{
|
|
return $this->freezeAfter;
|
|
}
|
|
|
|
public function isWaitingForTransition(): bool
|
|
{
|
|
if (null !== $this->transitionAfter) {
|
|
return false;
|
|
}
|
|
|
|
if ($this->isFinal()) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function removeDestEmail(string $email): self
|
|
{
|
|
$this->destEmail = array_filter($this->destEmail, static function (string $existing) use ($email) {
|
|
return $email !== $existing;
|
|
});
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function removeDestUser(User $user): self
|
|
{
|
|
$this->destUser->removeElement($user);
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function removeDestUserByAccessKey(User $user): self
|
|
{
|
|
$this->destUserByAccessKey->removeElement($user);
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setComment(?string $comment): EntityWorkflowStep
|
|
{
|
|
$this->comment = (string) $comment;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setCurrentStep(?string $currentStep): EntityWorkflowStep
|
|
{
|
|
$this->currentStep = $currentStep;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setDestEmail(array $destEmail): EntityWorkflowStep
|
|
{
|
|
$this->destEmail = $destEmail;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @internal use @see(EntityWorkflow::addStep} instead
|
|
*/
|
|
public function setEntityWorkflow(?EntityWorkflow $entityWorkflow): EntityWorkflowStep
|
|
{
|
|
$this->entityWorkflow = $entityWorkflow;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setFreezeAfter(bool $freezeAfter): EntityWorkflowStep
|
|
{
|
|
$this->freezeAfter = $freezeAfter;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setIsFinal(bool $isFinal): EntityWorkflowStep
|
|
{
|
|
$this->isFinal = $isFinal;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return EntityWorkflowStep
|
|
*
|
|
* @internal
|
|
*/
|
|
public function setNext(?EntityWorkflowStep $next): self
|
|
{
|
|
$this->next = $next;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return EntityWorkflowStep
|
|
*
|
|
* @internal
|
|
*/
|
|
public function setPrevious(?EntityWorkflowStep $previous): self
|
|
{
|
|
$this->previous = $previous;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setTransitionAfter(?string $transitionAfter): EntityWorkflowStep
|
|
{
|
|
$this->transitionAfter = $transitionAfter;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setTransitionAt(?DateTimeImmutable $transitionAt): EntityWorkflowStep
|
|
{
|
|
$this->transitionAt = $transitionAt;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setTransitionBy(?User $transitionBy): EntityWorkflowStep
|
|
{
|
|
$this->transitionBy = $transitionBy;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setTransitionByEmail(?string $transitionByEmail): EntityWorkflowStep
|
|
{
|
|
$this->transitionByEmail = $transitionByEmail;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @Assert\Callback
|
|
*
|
|
* @param mixed $payload
|
|
*/
|
|
public function validateOnCreation(ExecutionContextInterface $context, $payload): void
|
|
{
|
|
return;
|
|
|
|
if ($this->isFinalizeAfter()) {
|
|
if (0 !== count($this->getDestUser())) {
|
|
$context->buildViolation('workflow.No dest users when the workflow is finalized')
|
|
->atPath('finalizeAfter')
|
|
->addViolation();
|
|
}
|
|
} else {
|
|
if (0 === count($this->getDestUser())) {
|
|
$context->buildViolation('workflow.The next step must count at least one dest')
|
|
->atPath('finalizeAfter')
|
|
->addViolation();
|
|
}
|
|
}
|
|
}
|
|
}
|