Issues (3627)

IntegrationsBundle/Controller/ConfigController.php (12 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * @copyright   2018 Mautic, Inc. All rights reserved
7
 * @author      Mautic, Inc.
8
 *
9
 * @link        https://mautic.com
10
 *
11
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
12
 */
13
14
namespace Mautic\IntegrationsBundle\Controller;
15
16
use Mautic\CoreBundle\Controller\AbstractFormController;
17
use Mautic\IntegrationsBundle\Event\ConfigSaveEvent;
18
use Mautic\IntegrationsBundle\Event\FormLoadEvent;
19
use Mautic\IntegrationsBundle\Exception\IntegrationNotFoundException;
20
use Mautic\IntegrationsBundle\Form\Type\IntegrationConfigType;
21
use Mautic\IntegrationsBundle\Helper\ConfigIntegrationsHelper;
22
use Mautic\IntegrationsBundle\Helper\FieldMergerHelper;
23
use Mautic\IntegrationsBundle\Helper\FieldValidationHelper;
24
use Mautic\IntegrationsBundle\Integration\BasicIntegration;
25
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormAuthInterface;
26
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormAuthorizeButtonInterface;
27
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormCallbackInterface;
28
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormFeatureSettingsInterface;
29
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormFeaturesInterface;
30
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormInterface;
31
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormSyncInterface;
32
use Mautic\IntegrationsBundle\IntegrationEvents;
33
use Mautic\PluginBundle\Entity\Integration;
34
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
35
use Symfony\Component\Form\Form;
36
use Symfony\Component\HttpFoundation\JsonResponse;
37
use Symfony\Component\HttpFoundation\RedirectResponse;
38
use Symfony\Component\HttpFoundation\Request;
39
use Symfony\Component\HttpFoundation\Response;
40
use Symfony\Component\HttpFoundation\Session\Session;
41
42
class ConfigController extends AbstractFormController
43
{
44
    /**
45
     * @var Request
46
     */
47
    protected $request;
48
49
    /**
50
     * @var Form
51
     */
52
    private $form;
53
54
    /**
55
     * @var BasicIntegration|ConfigFormInterface
56
     */
57
    private $integrationObject;
58
59
    /**
60
     * @var Integration
61
     */
62
    private $integrationConfiguration;
63
64
    /**
65
     * @var ConfigIntegrationsHelper
66
     */
67
    private $integrationsHelper;
68
69
    /**
70
     * @return array|JsonResponse|RedirectResponse|Response
71
     */
72
    public function editAction(Request $request, string $integration)
73
    {
74
        // Check ACL
75
        if (!$this->get('mautic.security')->isGranted('plugin:plugins:manage')) {
76
            return $this->accessDenied();
77
        }
78
79
        // Find the integration
80
        /* @var ConfigIntegrationsHelper $integrationsHelper */
81
        $this->integrationsHelper = $this->get('mautic.integrations.helper.config_integrations');
82
83
        try {
84
            $this->integrationObject        = $this->integrationsHelper->getIntegration($integration);
85
            $this->integrationConfiguration = $this->integrationObject->getIntegrationConfiguration();
86
        } catch (IntegrationNotFoundException $exception) {
87
            return $this->notFound();
88
        }
89
90
        $dispatcher = $this->get('event_dispatcher');
91
        $event      = new FormLoadEvent($this->integrationConfiguration);
92
        $dispatcher->dispatch(IntegrationEvents::INTEGRATION_CONFIG_FORM_LOAD, $event);
93
94
        // Set the request for private methods
95
        $this->request = $request;
96
97
        // Create the form
98
        $this->form = $this->getForm();
99
100
        if (Request::METHOD_POST === $request->getMethod()) {
101
            return $this->submitForm();
102
        }
103
104
        // Clear the session of previously stored fields in case it got stuck
105
        /** @var Session $session */
106
        $session = $this->get('session');
107
        $session->remove("$integration-fields");
108
109
        return $this->showForm();
110
    }
111
112
    /**
113
     * @return JsonResponse|Response
114
     */
115
    private function submitForm()
116
    {
117
        if ($this->isFormCancelled($this->form)) {
118
            return $this->closeForm();
119
        }
120
121
        // Dispatch event prior to saving the Integration
122
        /** @var EventDispatcherInterface $eventDispatcher */
123
        $eventDispatcher = $this->get('event_dispatcher');
124
        $configEvent     = new ConfigSaveEvent($this->integrationConfiguration);
125
        $eventDispatcher->dispatch(IntegrationEvents::INTEGRATION_CONFIG_BEFORE_SAVE, $configEvent);
126
127
        // Get the fields before the form binds partial data due to pagination
128
        $settings      = $this->integrationConfiguration->getFeatureSettings();
129
        $fieldMappings = $settings['sync']['fieldMappings'] ?? [];
130
131
        // Submit the form
132
        $this->form->handleRequest($this->request);
133
        if ($this->integrationObject instanceof ConfigFormSyncInterface) {
134
            $integration   = $this->integrationObject->getName();
135
            $settings      = $this->integrationConfiguration->getFeatureSettings();
136
            $session       = $this->get('session');
137
            $updatedFields = $session->get("$integration-fields", []);
138
139
            $fieldMerger = new FieldMergerHelper($this->integrationObject, $fieldMappings);
140
141
            foreach ($updatedFields as $object => $fields) {
142
                $fieldMerger->mergeSyncFieldMapping($object, $fields);
143
            }
144
145
            $settings['sync']['fieldMappings'] = $fieldMerger->getFieldMappings();
146
147
            /** @var FieldValidationHelper $fieldValidator */
148
            $fieldValidator = $this->get('mautic.integrations.helper.field_validator');
149
            $fieldValidator->validateRequiredFields($this->form, $this->integrationObject, $settings['sync']['fieldMappings']);
150
151
            $this->integrationConfiguration->setFeatureSettings($settings);
152
        }
153
154
        // Show the form if there are errors
155
        if (!$this->form->isValid()) {
156
            return $this->showForm();
157
        }
158
159
        // Save the integration configuration
160
        $this->integrationsHelper->saveIntegrationConfiguration($this->integrationConfiguration);
161
162
        // Dispatch after save event
163
        $eventDispatcher->dispatch(IntegrationEvents::INTEGRATION_CONFIG_AFTER_SAVE, $configEvent);
164
165
        // Show the form if the apply button was clicked
166
        if ($this->isFormApplied($this->form)) {
167
            // Regenerate the form
168
            $this->resetFieldsInSession();
169
            $this->form = $this->getForm();
170
171
            return $this->showForm();
172
        }
173
174
        // Otherwise close the modal
175
        return $this->closeForm();
176
    }
177
178
    /**
179
     * @return Form
180
     */
181
    private function getForm()
182
    {
183
        return $this->get('form.factory')->create(
184
            $this->integrationObject->getConfigFormName() ?: IntegrationConfigType::class,
185
            $this->integrationConfiguration,
186
            [
187
                'action'      => $this->generateUrl('mautic_integration_config', ['integration' => $this->integrationObject->getName()]),
188
                'integration' => $this->integrationObject->getName(),
189
            ]
190
        );
191
    }
192
193
    /**
194
     * @return JsonResponse|Response
195
     */
196
    private function showForm()
197
    {
198
        $integrationObject = $this->integrationObject;
199
        $form              = $this->setFormTheme($this->form, 'IntegrationsBundle:Config:form.html.php');
200
        $formHelper        = $this->get('templating.helper.form');
201
202
        $showFeaturesTab =
203
            $integrationObject instanceof ConfigFormFeaturesInterface ||
204
            $integrationObject instanceof ConfigFormSyncInterface ||
205
            $integrationObject instanceof ConfigFormFeatureSettingsInterface;
206
207
        $hasFeatureErrors = (
208
                $integrationObject instanceof ConfigFormFeatureSettingsInterface &&
209
                $formHelper->containsErrors($form['featureSettings']['integration'])
210
            ) || (
211
                isset($form['featureSettings']['sync']['integration']) &&
212
                $formHelper->containsErrors($form['featureSettings']['sync']['integration'])
213
            );
214
215
        $hasAuthErrors = $integrationObject instanceof ConfigFormAuthInterface && $formHelper->containsErrors($form['apiKeys']);
216
217
        $useSyncFeatures = $integrationObject instanceof ConfigFormSyncInterface;
218
219
        $useFeatureSettings = $integrationObject instanceof ConfigFormFeatureSettingsInterface;
220
221
        $useAuthorizationUrl = $integrationObject instanceof ConfigFormAuthorizeButtonInterface;
222
223
        $callbackUrl = $integrationObject instanceof ConfigFormCallbackInterface ?
224
            $integrationObject->getRedirectUri()
0 ignored issues
show
The method getRedirectUri() does not exist on Mautic\IntegrationsBundl...ConfigFormAuthInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

224
            $integrationObject->/** @scrutinizer ignore-call */ 
225
                                getRedirectUri()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method getRedirectUri() does not exist on Mautic\IntegrationsBundl...eatureSettingsInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

224
            $integrationObject->/** @scrutinizer ignore-call */ 
225
                                getRedirectUri()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method getRedirectUri() does not exist on Mautic\IntegrationsBundl...ces\ConfigFormInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

224
            $integrationObject->/** @scrutinizer ignore-call */ 
225
                                getRedirectUri()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method getRedirectUri() does not exist on Mautic\IntegrationsBundl...igFormFeaturesInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

224
            $integrationObject->/** @scrutinizer ignore-call */ 
225
                                getRedirectUri()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method getRedirectUri() does not exist on Mautic\IntegrationsBundl...igFormCallbackInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

224
            $integrationObject->/** @scrutinizer ignore-call */ 
225
                                getRedirectUri()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method getRedirectUri() does not exist on Mautic\IntegrationsBundl...ConfigFormSyncInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

224
            $integrationObject->/** @scrutinizer ignore-call */ 
225
                                getRedirectUri()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method getRedirectUri() does not exist on Mautic\IntegrationsBundl...ration\BasicIntegration. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

224
            $integrationObject->/** @scrutinizer ignore-call */ 
225
                                getRedirectUri()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
225
            : false;
226
227
        return $this->delegateView(
228
            [
229
                'viewParameters'  => [
230
                    'integrationObject'   => $integrationObject,
231
                    'form'                => $form,
232
                    'activeTab'           => $this->request->get('activeTab'),
233
                    'showFeaturesTab'     => $showFeaturesTab,
234
                    'hasFeatureErrors'    => $hasFeatureErrors,
235
                    'hasAuthErrors'       => $hasAuthErrors,
236
                    'useSyncFeatures'     => $useSyncFeatures,
237
                    'useFeatureSettings'  => $useFeatureSettings,
238
                    'useAuthorizationUrl' => $useAuthorizationUrl,
239
                    'callbackUrl'         => $callbackUrl,
240
                ],
241
                'contentTemplate' => $integrationObject->getConfigFormContentTemplate()
0 ignored issues
show
The method getConfigFormContentTemplate() does not exist on Mautic\IntegrationsBundl...ConfigFormAuthInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

241
                'contentTemplate' => $integrationObject->/** @scrutinizer ignore-call */ getConfigFormContentTemplate()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method getConfigFormContentTemplate() does not exist on Mautic\IntegrationsBundl...ConfigFormSyncInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

241
                'contentTemplate' => $integrationObject->/** @scrutinizer ignore-call */ getConfigFormContentTemplate()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method getConfigFormContentTemplate() does not exist on Mautic\IntegrationsBundl...eatureSettingsInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

241
                'contentTemplate' => $integrationObject->/** @scrutinizer ignore-call */ getConfigFormContentTemplate()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method getConfigFormContentTemplate() does not exist on Mautic\IntegrationsBundl...ration\BasicIntegration. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

241
                'contentTemplate' => $integrationObject->/** @scrutinizer ignore-call */ getConfigFormContentTemplate()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
The method getConfigFormContentTemplate() does not exist on Mautic\IntegrationsBundl...igFormFeaturesInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

241
                'contentTemplate' => $integrationObject->/** @scrutinizer ignore-call */ getConfigFormContentTemplate()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
242
                    ?: 'IntegrationsBundle:Config:form.html.php',
243
                'passthroughVars' => [
244
                    'activeLink'    => '#mautic_plugin_index',
245
                    'mauticContent' => 'integrationsConfig',
246
                    'route'         => false,
247
                ],
248
            ]
249
        );
250
    }
251
252
    /**
253
     * @return JsonResponse
254
     */
255
    private function closeForm()
256
    {
257
        $this->resetFieldsInSession();
258
259
        $response = [
260
            'closeModal'    => 1,
261
            'enabled'       => $this->integrationConfiguration->getIsPublished(),
262
            'name'          => $this->integrationConfiguration->getName(),
263
            'mauticContent' => 'integrationsConfig',
264
        ];
265
266
        if ($this->integrationObject instanceof ConfigFormAuthorizeButtonInterface) {
267
            $response['authUrl'] = $this->integrationObject->getAuthorizationUrl();
268
        }
269
270
        return new JsonResponse($response);
271
    }
272
273
    private function resetFieldsInSession(): void
274
    {
275
        /** @var Session $session */
276
        $session = $this->get('session');
277
        $session->remove("{$this->integrationObject->getName()}-fields");
278
    }
279
}
280