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

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