mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-28 13:06:13 +00:00
78 lines
3.0 KiB
PHP
78 lines
3.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
|
|
namespace Chill\MainBundle\Service\Workflow;
|
|
|
|
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Component\Clock\ClockInterface;
|
|
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
|
|
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
|
|
use Symfony\Component\Workflow\Registry;
|
|
|
|
#[AsMessageHandler]
|
|
class CancelStaleWorkflowHandler
|
|
{
|
|
public const string KEEP_INTERVAL = 'P90D';
|
|
|
|
public function __construct(private readonly EntityWorkflowRepository $workflowRepository, private readonly Registry $registry, private readonly EntityManagerInterface $em, private readonly LoggerInterface $logger, private readonly ClockInterface $clock) {}
|
|
|
|
public function __invoke(CancelStaleWorkflowMessage $message): void
|
|
{
|
|
$workflowId = $message->getWorkflowId();
|
|
|
|
$olderThanDate = $this->clock->now()->sub(new \DateInterval(self::KEEP_INTERVAL));
|
|
$staleWorkflows = $this->workflowRepository->findWorkflowsWithoutFinalStepAndOlderThan($olderThanDate);
|
|
|
|
$workflow = $this->workflowRepository->find($workflowId);
|
|
|
|
if (in_array($workflow, $staleWorkflows, true)) {
|
|
$this->logger->alert('Workflow has transitioned in the meantime.', [$workflowId]);
|
|
return;
|
|
}
|
|
|
|
if (null === $workflow) {
|
|
$this->logger->alert('Workflow was not found!', [$workflowId]);
|
|
return;
|
|
}
|
|
|
|
$workflowComponent = $this->registry->get($workflow, $workflow->getWorkflowName());
|
|
$metadataStore = $workflowComponent->getMetadataStore();
|
|
$transitions = $workflowComponent->getEnabledTransitions($workflow);
|
|
$steps = $workflow->getSteps();
|
|
|
|
$transitionApplied = false;
|
|
|
|
if (1 === count($steps)) {
|
|
$this->em->remove($workflow->getCurrentStep());
|
|
$this->em->remove($workflow);
|
|
} else {
|
|
foreach ($transitions as $transition) {
|
|
$isFinal = $metadataStore->getMetadata('isFinal', $transition);
|
|
$isFinalPositive = $metadataStore->getMetadata('isFinalPositive', $transition);
|
|
|
|
if ($isFinal && !$isFinalPositive) {
|
|
$workflowComponent->apply($workflow, $transition->getName());
|
|
$this->logger->info('EntityWorkflow has been cancelled automatically.', [$workflowId]);
|
|
$transitionApplied = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$transitionApplied) {
|
|
$this->logger->error('No valid transition found for EntityWorkflow %d.', [$workflowId]);
|
|
throw new UnrecoverableMessageHandlingException(sprintf('No valid transition found for EntityWorkflow %d.', $workflowId));
|
|
}
|
|
}
|
|
}
|
|
}
|