chill-bundles/src/Bundle/ChillMainBundle/Workflow/Validator/TransitionHasDestUserIfRequiredValidator.php
Julien Fastré 7913a377c8
Move the logic to check if dest users are required to a dedicated constraint
- Create a dedicated constraint to check if the destUsers are required by the applied transition.
- Apply on WorkflowTransitionContextDTO and, if required, use the built-in constraints
- create tests
2024-10-04 13:41:20 +02:00

80 lines
2.7 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\Workflow\Validator;
use Chill\MainBundle\Workflow\WorkflowTransitionContextDTO;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Exception\UnexpectedValueException;
use Symfony\Component\Workflow\Registry;
final class TransitionHasDestUserIfRequiredValidator extends ConstraintValidator
{
public function __construct(private readonly Registry $registry) {}
public function validate($value, Constraint $constraint)
{
if (!$constraint instanceof TransitionHasDestUserIfRequired) {
throw new UnexpectedTypeException($constraint, TransitionHasDestUserIfRequired::class);
}
if (!$value instanceof WorkflowTransitionContextDTO) {
throw new UnexpectedValueException($value, WorkflowTransitionContextDTO::class);
}
if (null === $value->transition) {
return;
}
$workflow = $this->registry->get($value->entityWorkflow, $value->entityWorkflow->getWorkflowName());
$metadataStore = $workflow->getMetadataStore();
$destUsersRequired = false;
foreach ($value->transition->getTos() as $to) {
$metadata = $metadataStore->getPlaceMetadata($to);
// if the place are only 'isSentExternal' or 'isSignature' or 'final', then, we skip - a destUser is not required
if ($metadata['isSentExternal'] ?? false) {
continue;
}
if ($metadata['isSignature'] ?? false) {
continue;
}
if ($metadata['isFinal'] ?? false) {
continue;
}
// if there isn't any 'isSentExternal' or 'isSignature' or final, then we must have a destUser
$destUsersRequired = true;
}
if (!$destUsersRequired) {
if (0 < count($value->futureDestUsers)) {
$this->context->buildViolation($constraint->messageDestUserNotAuthorized)
->setCode($constraint->codeDestUserNotAuthorized)
->atPath('futureDestUsers')
->addViolation();
}
return;
}
if (0 === count($value->futureDestUsers)) {
$this->context->buildViolation($constraint->messageDestUserRequired)
->setCode($constraint->codeDestUserRequired)
->atPath('futureDestUsers')
->addViolation();
}
}
}