Merge branch 'signature-app/wp-706-no-forward-unless-signed' into 'signature-app-master'

Block transition if there is a pending signature for the entityWorkflow

See merge request Chill-Projet/chill-bundles!736
This commit is contained in:
2024-09-24 09:13:45 +00:00
7 changed files with 368 additions and 4 deletions

View File

@@ -0,0 +1,69 @@
<?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\Workflow\EventSubscriber;
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum;
use Chill\MainBundle\Security\Authorization\EntityWorkflowTransitionVoter;
use Chill\MainBundle\Templating\Entity\ChillEntityRenderManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Workflow\Event\GuardEvent;
use Symfony\Component\Workflow\TransitionBlocker;
/**
* Block the transition on EntityWorkflow if there is a still pending signature.
*/
final readonly class EntityWorkflowGuardUnsignedTransition implements EventSubscriberInterface
{
public function __construct(private ChillEntityRenderManagerInterface $chillEntityRenderManager, private Security $security) {}
public static function getSubscribedEvents(): array
{
return [
'workflow.guard' => [
['guardWaitingForSignature', 0],
],
];
}
public function guardWaitingForSignature(GuardEvent $event): void
{
$entityWorkflow = $event->getSubject();
if (!$entityWorkflow instanceof EntityWorkflow) {
return;
}
$transitionMetadata = $event->getWorkflow()->getMetadataStore()->getTransitionMetadata($event->getTransition());
if (false === ($transitionMetadata['isForward'] ?? true)) {
return;
}
foreach ($entityWorkflow->getCurrentStep()->getSignatures() as $signature) {
if (EntityWorkflowSignatureStateEnum::PENDING === $signature->getState()) {
if ($this->security->isGranted(EntityWorkflowTransitionVoter::APPLY_ALL_TRANSITIONS, $entityWorkflow)) {
continue;
}
$event->addTransitionBlocker(
new TransitionBlocker(
'workflow.blocked_waiting_for_pending_signer',
'2eabe9e6-79c2-11ef-986c-2ba376180859',
['signer' => $this->chillEntityRenderManager->renderString($signature->getSigner(), ['addAge' => false])]
)
);
}
}
}
}