vendor/pimcore/pimcore/lib/Workflow/EventSubscriber/NotesSubscriber.php line 54

  1. <?php
  2. declare(strict_types=1);
  3. /**
  4.  * Pimcore
  5.  *
  6.  * This source file is available under two different licenses:
  7.  * - GNU General Public License version 3 (GPLv3)
  8.  * - Pimcore Commercial License (PCL)
  9.  * Full copyright and license information is available in
  10.  * LICENSE.md which is distributed with this source code.
  11.  *
  12.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  13.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  14.  */
  15. namespace Pimcore\Workflow\EventSubscriber;
  16. use Pimcore\Event\Workflow\GlobalActionEvent;
  17. use Pimcore\Event\WorkflowEvents;
  18. use Pimcore\Model\Element\ElementInterface;
  19. use Pimcore\Model\Element\ValidationException;
  20. use Pimcore\Workflow;
  21. use Pimcore\Workflow\Transition;
  22. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  23. use Symfony\Component\Workflow\Event\Event;
  24. use Symfony\Contracts\Translation\TranslatorInterface;
  25. /**
  26.  * @internal
  27.  */
  28. class NotesSubscriber implements EventSubscriberInterface
  29. {
  30.     const ADDITIONAL_DATA_NOTES_COMMENT 'notes';
  31.     const ADDITIONAL_DATA_NOTES_ADDITIONAL_FIELDS 'additional';
  32.     private TranslatorInterface $translator;
  33.     private bool $enabled true;
  34.     private array $additionalData = [];
  35.     public function __construct(TranslatorInterface $translator)
  36.     {
  37.         $this->translator $translator;
  38.     }
  39.     /**
  40.      * @param Event $event
  41.      *
  42.      * @throws ValidationException
  43.      */
  44.     public function onWorkflowEnter(Event $event): void
  45.     {
  46.         if (!$this->checkEvent($event)) {
  47.             return;
  48.         }
  49.         /** @var ElementInterface $subject */
  50.         $subject $event->getSubject();
  51.         /** @var Transition $transition */
  52.         $transition $event->getTransition();
  53.         $this->handleNotesPreWorkflow($transition$subject);
  54.     }
  55.     public function onWorkflowCompleted(Event $event): void
  56.     {
  57.         if (!$this->checkEvent($event)) {
  58.             return;
  59.         }
  60.         /** @var ElementInterface $subject */
  61.         $subject $event->getSubject();
  62.         /** @var Transition $transition */
  63.         $transition $event->getTransition();
  64.         $this->handleNotesPostWorkflow($transition$subject);
  65.     }
  66.     /**
  67.      * @param GlobalActionEvent $event
  68.      *
  69.      * @throws ValidationException
  70.      */
  71.     public function onPreGlobalAction(GlobalActionEvent $event): void
  72.     {
  73.         if (!$this->checkGlobalActionEvent($event)) {
  74.             return;
  75.         }
  76.         $subject $event->getSubject();
  77.         $globalAction $event->getGlobalAction();
  78.         $this->handleNotesPreWorkflow($globalAction$subject);
  79.     }
  80.     public function onPostGlobalAction(GlobalActionEvent $event): void
  81.     {
  82.         if (!$this->checkGlobalActionEvent($event)) {
  83.             return;
  84.         }
  85.         $subject $event->getSubject();
  86.         $globalAction $event->getGlobalAction();
  87.         $this->handleNotesPostWorkflow($globalAction$subject);
  88.     }
  89.     /**
  90.      * @throws ValidationException
  91.      */
  92.     private function handleNotesPreWorkflow(Workflow\Notes\NotesAwareInterface $notesAwareElementInterface $subject): void
  93.     {
  94.         if (($setterFn $notesAware->getNotesCommentSetterFn()) && ($notes $this->getNotesComment())) {
  95.             $subject->$setterFn($notes);
  96.         }
  97.         foreach ($notesAware->getNotesAdditionalFields() as $additionalFieldConfig) {
  98.             $data $this->getAdditionalDataForField($additionalFieldConfig);
  99.             //check required
  100.             if ($additionalFieldConfig['required'] && empty($data)) {
  101.                 $label = isset($additionalFieldConfig['title']) && strlen($additionalFieldConfig['title']) > 0
  102.                     $additionalFieldConfig['title']
  103.                     : $additionalFieldConfig['name'];
  104.                 throw new ValidationException(
  105.                     $this->translator->trans('workflow_notes_requred_field_message', [$label], 'admin')
  106.                 );
  107.             }
  108.             //work out whether or not to set the value directly to the object or to add it to the note data
  109.             if (!empty($additionalFieldConfig['setterFn'])) {
  110.                 $setterFn $additionalFieldConfig['setterFn'];
  111.                 $subject->$setterFn($this->getAdditionalDataForField($additionalFieldConfig));
  112.             }
  113.         }
  114.     }
  115.     private function handleNotesPostWorkflow(Workflow\Notes\NotesAwareInterface $notesAwareElementInterface $subject): void
  116.     {
  117.         $additionalFieldsData = [];
  118.         foreach ($notesAware->getNotesAdditionalFields() as $additionalFieldConfig) {
  119.             /**
  120.              * Additional Field example
  121.              * [
  122.             'name' => 'dateLastContacted',
  123.             'fieldType' => 'date',
  124.             'label' => 'Date of Conversation',
  125.             'required' => true,
  126.             'setterFn' => ''
  127.             ]
  128.              */
  129.             //work out whether or not to set the value directly to the object or to add it to the note data
  130.             if (empty($additionalFieldConfig['setterFn'])) {
  131.                 $additionalFieldsData[] = Workflow\Service::createNoteData($additionalFieldConfig$this->getAdditionalDataForField($additionalFieldConfig));
  132.             }
  133.         }
  134.         Workflow\Service::createActionNote(
  135.             $subject,
  136.             $notesAware->getNotesType(),
  137.             $notesAware->getNotesTitle(),
  138.             $this->getNotesComment(),
  139.             $additionalFieldsData
  140.         );
  141.     }
  142.     /**
  143.      * check's if the event subscriber should be executed
  144.      */
  145.     private function checkEvent(Event $event): bool
  146.     {
  147.         return $this->isEnabled()
  148.                && $event->getTransition() instanceof Transition
  149.                && $event->getSubject() instanceof ElementInterface;
  150.     }
  151.     private function checkGlobalActionEvent(GlobalActionEvent $event): bool
  152.     {
  153.         return $this->isEnabled()
  154.                && $event->getSubject() instanceof ElementInterface;
  155.     }
  156.     public function isEnabled(): bool
  157.     {
  158.         return $this->enabled;
  159.     }
  160.     public function setEnabled(bool $enabled): void
  161.     {
  162.         $this->enabled $enabled;
  163.     }
  164.     public function getAdditionalData(): array
  165.     {
  166.         return $this->additionalData;
  167.     }
  168.     public function setAdditionalData(array $additionalData = []): void
  169.     {
  170.         $this->additionalData $additionalData;
  171.     }
  172.     /**
  173.      * @param array<string, mixed> $fieldConfig
  174.      */
  175.     private function getAdditionalDataForField(array $fieldConfig): mixed
  176.     {
  177.         $additional $this->getAdditionalFields();
  178.         $data $additional[$fieldConfig['name']];
  179.         if ($fieldConfig['fieldType'] === 'checkbox') {
  180.             return $data === 'true';
  181.         }
  182.         return $data;
  183.     }
  184.     private function getNotesComment(): string
  185.     {
  186.         return $this->additionalData[self::ADDITIONAL_DATA_NOTES_COMMENT] ?? '';
  187.     }
  188.     private function getAdditionalFields(): array
  189.     {
  190.         return $this->additionalData[self::ADDITIONAL_DATA_NOTES_ADDITIONAL_FIELDS] ?? [];
  191.     }
  192.     public static function getSubscribedEvents(): array
  193.     {
  194.         return [
  195.             'workflow.completed' => ['onWorkflowCompleted'1],
  196.             'workflow.enter' => 'onWorkflowEnter',
  197.             WorkflowEvents::PRE_GLOBAL_ACTION => 'onPreGlobalAction',
  198.             WorkflowEvents::POST_GLOBAL_ACTION => 'onPostGlobalAction',
  199.         ];
  200.     }
  201. }