vendor/ibexa/workflow/src/lib/Event/Subscriber/WorkflowGuardSubscriber.php line 50

Open in your IDE?
  1. <?php
  2. /**
  3. * @copyright Copyright (C) Ibexa AS. All rights reserved.
  4. * @license For full copyright and license information view LICENSE file distributed with this source code.
  5. */
  6. declare(strict_types=1);
  7. namespace Ibexa\Workflow\Event\Subscriber;
  8. use Ibexa\Contracts\Core\Repository\PermissionResolver;
  9. use Ibexa\Contracts\Core\Repository\Values\Content\Content;
  10. use Ibexa\Contracts\Core\Repository\Values\Content\ContentCreateStruct;
  11. use Ibexa\Contracts\Workflow\Registry\WorkflowRegistryInterface;
  12. use Ibexa\Workflow\Value\WorkflowTransition;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. use Symfony\Component\Workflow\Event\GuardEvent;
  15. class WorkflowGuardSubscriber implements EventSubscriberInterface
  16. {
  17. /** @var \Ibexa\Contracts\Core\Repository\PermissionResolver */
  18. private $permissionResolver;
  19. /** @var \Ibexa\Contracts\Workflow\Registry\WorkflowRegistryInterface */
  20. private $workflowRegistry;
  21. /**
  22. * @param \Ibexa\Contracts\Core\Repository\PermissionResolver $permissionResolver
  23. * @param \Ibexa\Contracts\Workflow\Registry\WorkflowRegistryInterface $workflowRegistry
  24. */
  25. public function __construct(
  26. PermissionResolver $permissionResolver,
  27. WorkflowRegistryInterface $workflowRegistry
  28. ) {
  29. $this->permissionResolver = $permissionResolver;
  30. $this->workflowRegistry = $workflowRegistry;
  31. }
  32. public static function getSubscribedEvents(): array
  33. {
  34. return [
  35. 'workflow.guard' => ['onTransition', 0],
  36. ];
  37. }
  38. /**
  39. * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
  40. * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
  41. */
  42. public function onTransition(GuardEvent $event): void
  43. {
  44. $workflowName = $event->getWorkflowName();
  45. $subject = $event->getSubject();
  46. // guard is not needed for workflows not based on our content model
  47. if (
  48. (!$subject instanceof Content && !$subject instanceof ContentCreateStruct)
  49. || !$this->workflowRegistry->hasWorkflow($workflowName)
  50. ) {
  51. return;
  52. }
  53. $workflow = $this->workflowRegistry->getSupportedWorkflow(
  54. $workflowName,
  55. $subject
  56. );
  57. $workflowTransition = new WorkflowTransition([
  58. 'workflow' => $workflow->getName(),
  59. 'transition' => $event->getTransition()->getName(),
  60. ]);
  61. $permissionTargets = array_merge(
  62. [$workflowTransition],
  63. $subject instanceof ContentCreateStruct ? $subject->getLocationStructs() : []
  64. );
  65. $user = $this->permissionResolver->getCurrentUserReference();
  66. $marking = $workflow->getMarkingStore()->getMarking($subject);
  67. $context = $marking->getContext() ?? [];
  68. if (
  69. $this->permissionResolver->canUser('workflow', 'change_stage', $subject, $permissionTargets)
  70. && (
  71. !empty($context['reviewerId']) && $context['reviewerId'] == $user->getUserId()
  72. || empty($context['reviewerId'])
  73. )
  74. ) {
  75. return;
  76. }
  77. $event->setBlocked(true);
  78. }
  79. }
  80. class_alias(WorkflowGuardSubscriber::class, 'EzSystems\EzPlatformWorkflow\Event\Subscriber\WorkflowGuardSubscriber');