vendor/ibexa/form-builder/src/lib/Event/Subscriber/HandleFormSubmission.php line 93

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\FormBuilder\Event\Subscriber;
  8. use Ibexa\Contracts\Core\Repository\Values\Content\Content;
  9. use Ibexa\Contracts\Core\Repository\Values\Content\Field;
  10. use Ibexa\Contracts\FormBuilder\FormSubmission\FormSubmissionServiceInterface;
  11. use Ibexa\Core\MVC\Symfony\Event\PreContentViewEvent;
  12. use Ibexa\Core\MVC\Symfony\MVCEvents;
  13. use Ibexa\Core\MVC\Symfony\View\ContentView;
  14. use Ibexa\FormBuilder\Event\FormActionEvent;
  15. use Ibexa\FormBuilder\Event\FormEvents;
  16. use Ibexa\FormBuilder\Event\FormSubmitEvent;
  17. use Ibexa\FormBuilder\FieldType\Type;
  18. use Ibexa\FormBuilder\FormSubmission\Notification\NotificationSenderInterface;
  19. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  20. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  21. use Symfony\Component\HttpFoundation\RequestStack;
  22. class HandleFormSubmission implements EventSubscriberInterface
  23. {
  24. /** @var \Symfony\Component\HttpFoundation\RequestStack */
  25. private $requestStack;
  26. /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface */
  27. private $eventDispatcher;
  28. /** @var \Ibexa\Contracts\FormBuilder\FormSubmission\FormSubmissionServiceInterface */
  29. private $formSubmissionService;
  30. /** @var \Ibexa\FormBuilder\FieldType\Type */
  31. private $formFieldType;
  32. /** @var \Ibexa\FormBuilder\FormSubmission\Notification\NotificationSenderInterface */
  33. private $notificationSender;
  34. /**
  35. * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
  36. * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher
  37. * @param \Ibexa\Contracts\FormBuilder\FormSubmission\FormSubmissionServiceInterface $formSubmissionService
  38. * @param \Ibexa\FormBuilder\FieldType\Type $formFieldType
  39. * @param \Ibexa\FormBuilder\FormSubmission\Notification\NotificationSenderInterface $emailNotificationSender
  40. */
  41. public function __construct(
  42. RequestStack $requestStack,
  43. EventDispatcherInterface $eventDispatcher,
  44. FormSubmissionServiceInterface $formSubmissionService,
  45. Type $formFieldType,
  46. NotificationSenderInterface $emailNotificationSender
  47. ) {
  48. $this->requestStack = $requestStack;
  49. $this->eventDispatcher = $eventDispatcher;
  50. $this->formSubmissionService = $formSubmissionService;
  51. $this->formFieldType = $formFieldType;
  52. $this->notificationSender = $emailNotificationSender;
  53. }
  54. /**
  55. * Returns an array of event names this subscriber wants to listen to.
  56. *
  57. * The array keys are event names and the value can be:
  58. *
  59. * * The method name to call (priority defaults to 0)
  60. * * An array composed of the method name to call and the priority
  61. * * An array of arrays composed of the method names to call and respective
  62. * priorities, or 0 if unset
  63. *
  64. * For instance:
  65. *
  66. * * array('eventName' => 'methodName')
  67. * * array('eventName' => array('methodName', $priority))
  68. * * array('eventName' => array(array('methodName1', $priority), array('methodName2')))
  69. *
  70. * @return array The event names to listen to
  71. */
  72. public static function getSubscribedEvents()
  73. {
  74. return [
  75. MVCEvents::PRE_CONTENT_VIEW => 'handleFormSubmission',
  76. ];
  77. }
  78. /**
  79. * @throws \Ibexa\FormBuilder\Exception\FormFieldNotFoundException
  80. * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
  81. */
  82. public function handleFormSubmission(PreContentViewEvent $event)
  83. {
  84. $contentView = $event->getContentView();
  85. if (!$contentView instanceof ContentView) {
  86. return;
  87. }
  88. $content = $contentView->getContent();
  89. $formField = $this->getFormFieldType($content);
  90. if (empty($formField)) {
  91. return;
  92. }
  93. /** @var \Ibexa\FormBuilder\FieldType\Value $formFieldValue */
  94. $formFieldValue = $formField->getValue();
  95. if (empty($formFieldValue->getForm())) {
  96. return;
  97. }
  98. $mainRequest = $this->requestStack->getMainRequest();
  99. /** @var \Symfony\Component\Form\Form $form */
  100. $form = $formFieldValue->getForm();
  101. $form->handleRequest($mainRequest);
  102. if (!$form->isSubmitted() || !$form->isValid()) {
  103. return;
  104. }
  105. $data = $form->getData();
  106. $formValue = $formFieldValue->getFormValue();
  107. $event = new FormSubmitEvent(
  108. $contentView,
  109. $formValue,
  110. $data,
  111. );
  112. $this->eventDispatcher->dispatch($event, FormEvents::FORM_SUBMIT);
  113. $this->eventDispatcher->dispatch($event, FormEvents::getSubmitContentEventName($content->id));
  114. $data = $event->getData();
  115. $values = [];
  116. foreach ($data['fields'] as $id => $value) {
  117. $field = $formValue->getFieldById((string)$id);
  118. $values[] = [
  119. 'id' => $id,
  120. 'identifier' => $field->getIdentifier(),
  121. 'name' => $field->getName(),
  122. 'value' => $value,
  123. ];
  124. }
  125. $formRequestAttributeKey = $form->getName() . '_submitted';
  126. $isFormAlreadySubmitted = $mainRequest->attributes->get($formRequestAttributeKey, false);
  127. if (!$isFormAlreadySubmitted) {
  128. $mainRequest->attributes->set($formRequestAttributeKey, true);
  129. $submission = $this->formSubmissionService->create(
  130. $content->contentInfo,
  131. $data['languageCode'],
  132. $formValue,
  133. $values
  134. );
  135. }
  136. $clickedButton = $form->getClickedButton();
  137. if (empty($clickedButton)) {
  138. return;
  139. }
  140. $field = $formValue->getFieldById($clickedButton->getName());
  141. $actionAttribute = $field->getAttribute('action');
  142. $actionName = null;
  143. if ($actionAttribute->getValue()) {
  144. $action = json_decode(
  145. $actionAttribute->getValue(),
  146. true,
  147. 2,
  148. JSON_OBJECT_AS_ARRAY
  149. );
  150. $actionName = $action['action'] ?? null;
  151. }
  152. if (empty($actionName)) {
  153. return;
  154. }
  155. $formActionEvent = new FormActionEvent(
  156. $contentView,
  157. $formValue,
  158. $actionName,
  159. $action[$actionName] ?? null
  160. );
  161. $this->eventDispatcher->dispatch($formActionEvent, FormEvents::getSubmitActionEventName($actionName));
  162. if (!$isFormAlreadySubmitted) {
  163. $this->notificationSender->sendNotification($content, $formValue, $submission, $field);
  164. }
  165. }
  166. /**
  167. * @param \Ibexa\Contracts\Core\Repository\Values\Content\Content|null $content
  168. *
  169. * @return \Ibexa\Contracts\Core\Repository\Values\Content\Field|null
  170. */
  171. protected function getFormFieldType(?Content $content): ?Field
  172. {
  173. if (empty($content)) {
  174. return null;
  175. }
  176. foreach ($content->getFieldsByLanguage() as $field) {
  177. if ($field->fieldTypeIdentifier === $this->formFieldType->getFieldTypeIdentifier()) {
  178. return $field;
  179. }
  180. }
  181. return null;
  182. }
  183. }
  184. class_alias(HandleFormSubmission::class, 'EzSystems\EzPlatformFormBuilder\Event\Subscriber\HandleFormSubmission');