Spaces:
No application file
No application file
| declare(strict_types=1); | |
| namespace Mautic\IntegrationsBundle\Controller; | |
| use Mautic\CoreBundle\Controller\AbstractFormController; | |
| use Mautic\CoreBundle\Twig\Extension\FormExtension; | |
| use Mautic\IntegrationsBundle\Event\ConfigAuthUrlEvent; | |
| use Mautic\IntegrationsBundle\Event\ConfigSaveEvent; | |
| use Mautic\IntegrationsBundle\Event\FormLoadEvent; | |
| use Mautic\IntegrationsBundle\Event\KeysSaveEvent; | |
| use Mautic\IntegrationsBundle\Exception\IntegrationNotFoundException; | |
| use Mautic\IntegrationsBundle\Form\Type\IntegrationConfigType; | |
| use Mautic\IntegrationsBundle\Helper\ConfigIntegrationsHelper; | |
| use Mautic\IntegrationsBundle\Helper\FieldMergerHelper; | |
| use Mautic\IntegrationsBundle\Helper\FieldValidationHelper; | |
| use Mautic\IntegrationsBundle\Integration\BasicIntegration; | |
| use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormAuthInterface; | |
| use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormAuthorizeButtonInterface; | |
| use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormCallbackInterface; | |
| use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormFeatureSettingsInterface; | |
| use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormFeaturesInterface; | |
| use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormInterface; | |
| use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormNotesInterface; | |
| use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormSyncInterface; | |
| use Mautic\IntegrationsBundle\IntegrationEvents; | |
| use Mautic\PluginBundle\Entity\Integration; | |
| use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |
| use Symfony\Component\Form\FormFactoryInterface; | |
| use Symfony\Component\Form\FormInterface; | |
| use Symfony\Component\HttpFoundation\JsonResponse; | |
| use Symfony\Component\HttpFoundation\RedirectResponse; | |
| use Symfony\Component\HttpFoundation\Request; | |
| use Symfony\Component\HttpFoundation\Response; | |
| use Symfony\Component\HttpFoundation\Session\Session; | |
| class ConfigController extends AbstractFormController | |
| { | |
| /** | |
| * @var BasicIntegration|ConfigFormInterface | |
| */ | |
| private $integrationObject; | |
| /** | |
| * @var Integration | |
| */ | |
| private $integrationConfiguration; | |
| /** | |
| * @return array|JsonResponse|RedirectResponse|Response | |
| */ | |
| public function editAction( | |
| Request $request, | |
| ConfigIntegrationsHelper $integrationsHelper, | |
| EventDispatcherInterface $dispatcher, | |
| FieldValidationHelper $fieldValidator, | |
| FormFactoryInterface $formFactory, | |
| FormExtension $formExtension, | |
| string $integration | |
| ) { | |
| // Check ACL | |
| if (!$this->security->isGranted('plugin:plugins:manage')) { | |
| return $this->accessDenied(); | |
| } | |
| try { | |
| $this->integrationObject = $integrationsHelper->getIntegration($integration); | |
| $this->integrationConfiguration = $this->integrationObject->getIntegrationConfiguration(); | |
| } catch (IntegrationNotFoundException) { | |
| return $this->notFound(); | |
| } | |
| $event = new FormLoadEvent($this->integrationConfiguration); | |
| $dispatcher->dispatch($event, IntegrationEvents::INTEGRATION_CONFIG_FORM_LOAD); | |
| // Create the form | |
| $form = $this->getForm($formFactory); | |
| if (Request::METHOD_POST === $request->getMethod()) { | |
| return $this->submitForm($request, $integrationsHelper, $fieldValidator, $dispatcher, $formFactory, $formExtension, $form); | |
| } | |
| // Clear the session of previously stored fields in case it got stuck | |
| /** @var Session $session */ | |
| $session = $request->getSession(); | |
| $session->remove("$integration-fields"); | |
| return $this->showForm($request, $form, $formExtension); | |
| } | |
| /** | |
| * @param FormInterface<mixed> $form | |
| */ | |
| private function submitForm( | |
| Request $request, | |
| ConfigIntegrationsHelper $integrationsHelper, | |
| FieldValidationHelper $fieldValidator, | |
| EventDispatcherInterface $eventDispatcher, | |
| FormFactoryInterface $formFactory, | |
| FormExtension $formExtension, | |
| FormInterface $form | |
| ): JsonResponse|Response { | |
| if ($this->isFormCancelled($form)) { | |
| return $this->closeForm($request); | |
| } | |
| // Get the fields before the form binds partial data due to pagination | |
| $settings = $this->integrationConfiguration->getFeatureSettings(); | |
| $fieldMappings = $settings['sync']['fieldMappings'] ?? []; | |
| $oldApiKeys = $this->integrationConfiguration->getApiKeys(); | |
| // Submit the form | |
| $form->handleRequest($request); | |
| $configEvent = new KeysSaveEvent($this->integrationConfiguration, $oldApiKeys); | |
| $this->dispatcher->dispatch($configEvent, IntegrationEvents::INTEGRATION_API_KEYS_BEFORE_SAVE); | |
| if ($this->integrationObject instanceof ConfigFormSyncInterface) { | |
| $integration = $this->integrationObject->getName(); | |
| $settings = $this->integrationConfiguration->getFeatureSettings(); | |
| $session = $request->getSession(); | |
| $updatedFields = $session->get("$integration-fields", []); | |
| $fieldMerger = new FieldMergerHelper($this->integrationObject, $fieldMappings); | |
| foreach ($updatedFields as $object => $fields) { | |
| $fieldMerger->mergeSyncFieldMapping($object, $fields); | |
| } | |
| $settings['sync']['fieldMappings'] = $fieldMerger->getFieldMappings(); | |
| $fieldValidator->validateRequiredFields($form, $this->integrationObject, $settings['sync']['fieldMappings']); | |
| $this->integrationConfiguration->setFeatureSettings($settings); | |
| } | |
| // Dispatch event prior to saving the Integration. Bundles/plugins may need to modify some field values before save | |
| $configEvent = new ConfigSaveEvent($this->integrationConfiguration); | |
| $eventDispatcher->dispatch($configEvent, IntegrationEvents::INTEGRATION_CONFIG_BEFORE_SAVE); | |
| // Show the form if there are errors and the plugin is published or the authorized button was clicked | |
| $integrationDetailsPost = $request->request->get('integration_details') ?? []; | |
| $authorize = !empty($integrationDetailsPost['in_auth']); | |
| if ($form->isSubmitted() && !$form->isValid() && ($this->integrationConfiguration->getIsPublished() || $authorize)) { | |
| return $this->showForm($request, $form, $formExtension); | |
| } | |
| // Save the integration configuration | |
| $integrationsHelper->saveIntegrationConfiguration($this->integrationConfiguration); | |
| // Dispatch after save event | |
| $eventDispatcher->dispatch($configEvent, IntegrationEvents::INTEGRATION_CONFIG_AFTER_SAVE); | |
| // Show the form if the apply button was clicked | |
| if ($this->isFormApplied($form)) { | |
| // Regenerate the form | |
| $this->resetFieldsInSession($request); | |
| $form = $this->getForm($formFactory); | |
| return $this->showForm($request, $form, $formExtension); | |
| } | |
| // Otherwise close the modal | |
| return $this->closeForm($request); | |
| } | |
| /** | |
| * @return FormInterface<mixed> | |
| */ | |
| private function getForm(FormFactoryInterface $formFactory) | |
| { | |
| return $formFactory->create( | |
| $this->integrationObject->getConfigFormName() ?: IntegrationConfigType::class, | |
| $this->integrationConfiguration, | |
| [ | |
| 'action' => $this->generateUrl('mautic_integration_config', ['integration' => $this->integrationObject->getName()]), | |
| 'integration' => $this->integrationObject->getName(), | |
| ] | |
| ); | |
| } | |
| /** | |
| * @param FormInterface<mixed> $form | |
| */ | |
| private function showForm(Request $request, FormInterface $form, FormExtension $formExtension): Response | |
| { | |
| $integrationObject = $this->integrationObject; | |
| $formView = $form->createView(); | |
| $showFeaturesTab = $integrationObject instanceof ConfigFormFeaturesInterface | |
| || $integrationObject instanceof ConfigFormSyncInterface | |
| || $integrationObject instanceof ConfigFormFeatureSettingsInterface; | |
| $hasFeatureErrors = ( | |
| $integrationObject instanceof ConfigFormFeatureSettingsInterface | |
| && $formExtension->containsErrors($formView['featureSettings']['integration']) | |
| ) || ( | |
| isset($formView['featureSettings']['sync']['integration']) | |
| && $formExtension->containsErrors($formView['featureSettings']['sync']['integration']) | |
| ); | |
| $hasAuthErrors = $integrationObject instanceof ConfigFormAuthInterface && $formExtension->containsErrors($formView['apiKeys']); | |
| $useSyncFeatures = $integrationObject instanceof ConfigFormSyncInterface; | |
| $useFeatureSettings = $integrationObject instanceof ConfigFormFeatureSettingsInterface; | |
| $useAuthorizationUrl = $integrationObject instanceof ConfigFormAuthorizeButtonInterface; | |
| $callbackUrl = $integrationObject instanceof ConfigFormCallbackInterface ? | |
| $integrationObject->getRedirectUri() | |
| : false; | |
| $useConfigFormNotes = $integrationObject instanceof ConfigFormNotesInterface; | |
| return $this->delegateView( | |
| [ | |
| 'viewParameters' => [ | |
| 'integrationObject' => $integrationObject, | |
| 'form' => $formView, | |
| 'activeTab' => $request->get('activeTab'), | |
| 'showFeaturesTab' => $showFeaturesTab, | |
| 'hasFeatureErrors' => $hasFeatureErrors, | |
| 'hasAuthErrors' => $hasAuthErrors, | |
| 'useSyncFeatures' => $useSyncFeatures, | |
| 'useFeatureSettings' => $useFeatureSettings, | |
| 'useAuthorizationUrl' => $useAuthorizationUrl, | |
| 'callbackUrl' => $callbackUrl, | |
| 'useConfigFormNotes' => $useConfigFormNotes, | |
| ], | |
| 'contentTemplate' => $integrationObject->getConfigFormContentTemplate() | |
| ?: '@Integrations/Config/form.html.twig', | |
| 'passthroughVars' => [ | |
| 'activeLink' => '#mautic_plugin_index', | |
| 'mauticContent' => 'integrationsConfig', | |
| 'route' => false, | |
| ], | |
| ] | |
| ); | |
| } | |
| private function closeForm(Request $request): JsonResponse | |
| { | |
| $this->resetFieldsInSession($request); | |
| $response = [ | |
| 'closeModal' => 1, | |
| 'enabled' => $this->integrationConfiguration->getIsPublished(), | |
| 'name' => $this->integrationConfiguration->getName(), | |
| 'mauticContent' => 'integrationsConfig', | |
| 'flashes' => $this->getFlashContent(), | |
| ]; | |
| if ($this->integrationObject instanceof ConfigFormAuthorizeButtonInterface) { | |
| // Dispatch event to allow listeners to extract information and/or manipulate the URL | |
| $authUrl = $this->integrationObject->getAuthorizationUrl(); | |
| $authUrlEvent = new ConfigAuthUrlEvent($this->integrationConfiguration, $authUrl); | |
| $this->dispatcher->dispatch($authUrlEvent, IntegrationEvents::INTEGRATION_CONFIG_ON_GENERATE_AUTH_URL); | |
| $response['authUrl'] = $authUrlEvent->getAuthUrl(); | |
| } | |
| return new JsonResponse($response); | |
| } | |
| private function resetFieldsInSession(Request $request): void | |
| { | |
| $session = $request->getSession(); | |
| $session->remove("{$this->integrationObject->getName()}-fields"); | |
| } | |
| } | |