src/EventSubscriber/WorkflowModalidadGuardSubscriber.php line 40

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Entity\Solicitud;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Component\Workflow\Event\GuardEvent;
  6. use Symfony\Component\Workflow\TransitionBlocker;
  7. /**
  8.  * Guard genérico de modalidad para workflows unificados.
  9.  *
  10.  * Lee el campo `modalidad` de la metadata de cada transición y lo compara
  11.  * con `Solicitud::getSolicitudTipo()->getId()`.
  12.  *
  13.  * - Si la transición NO declara `modalidad` → se permite siempre (backward compatible).
  14.  * - Si la transición declara `modalidad: [1]` y la solicitud es tipo 2 → se bloquea.
  15.  * - Funciona para TODOS los workflows que usen la convención `metadata.modalidad`.
  16.  *
  17.  * @see config/packages/workflow.yaml  — metadata.modalidad en places y transiciones
  18.  */
  19. class WorkflowModalidadGuardSubscriber implements EventSubscriberInterface
  20. {
  21.     /**
  22.      * {@inheritdoc}
  23.      */
  24.     public static function getSubscribedEvents(): array
  25.     {
  26.         // Escucha el guard de TODOS los workflows → reutilizable para futuros trámites
  27.         return [
  28.             'workflow.guard' => ['onWorkflowGuard', 0],
  29.         ];
  30.     }
  31.     /**
  32.      * Bloquea la transición si la modalidad de la solicitud no está permitida.
  33.      *
  34.      * @param GuardEvent $event Evento guard del workflow
  35.      */
  36.     public function onWorkflowGuard(GuardEvent $event): void
  37.     {
  38.         $subject = $event->getSubject();
  39.         if (!$subject instanceof Solicitud) {
  40.             return;
  41.         }
  42.         $transition = $event->getTransition();
  43.         $modalidadesPermitidas = $event->getMetadata('modalidad', $transition);
  44.         // Sin metadata de modalidad → la transición aplica para cualquier tipo
  45.         if (empty($modalidadesPermitidas)) {
  46.             return;
  47.         }
  48.         $solicitudTipo = $subject->getSolicitudTipo();
  49.         // Si la solicitud no tiene tipo asignado, no bloquear (permite flujo inicial)
  50.         if ($solicitudTipo === null) {
  51.             return;
  52.         }
  53.         $tipoId = (int) $solicitudTipo->getId();
  54.         if (!in_array($tipoId, (array) $modalidadesPermitidas, true)) {
  55.             $event->addTransitionBlocker(
  56.                 new TransitionBlocker(
  57.                     sprintf(
  58.                         'La transición "%s" no está disponible para la modalidad %d (permitidas: %s).',
  59.                         $transition->getName(),
  60.                         $tipoId,
  61.                         implode(', ', (array) $modalidadesPermitidas)
  62.                     ),
  63.                     'workflow_modalidad_guard.blocked'
  64.                 )
  65.             );
  66.         }
  67.     }
  68. }