Issues (3627)

PluginBundle/Controller/PluginController.php (1 issue)

1
<?php
2
3
/*
4
 * @copyright   2014 Mautic Contributors. All rights reserved
5
 * @author      Mautic
6
 *
7
 * @link        http://mautic.org
8
 *
9
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
10
 */
11
12
namespace Mautic\PluginBundle\Controller;
13
14
use Mautic\CoreBundle\Controller\FormController;
15
use Mautic\CoreBundle\Helper\InputHelper;
16
use Mautic\PluginBundle\Event\PluginIntegrationAuthRedirectEvent;
17
use Mautic\PluginBundle\Event\PluginIntegrationEvent;
18
use Mautic\PluginBundle\Form\Type\DetailsType;
19
use Mautic\PluginBundle\Integration\AbstractIntegration;
20
use Mautic\PluginBundle\Model\PluginModel;
21
use Mautic\PluginBundle\PluginEvents;
22
use Symfony\Component\Form\FormError;
23
use Symfony\Component\HttpFoundation\JsonResponse;
24
use Symfony\Component\HttpFoundation\RedirectResponse;
25
use Symfony\Component\HttpFoundation\Response;
26
27
/**
28
 * Class PluginController.
29
 */
30
class PluginController extends FormController
31
{
32
    /**
33
     * @return JsonResponse|Response
34
     */
35
    public function indexAction()
36
    {
37
        if (!$this->get('mautic.security')->isGranted('plugin:plugins:manage')) {
38
            return $this->accessDenied();
39
        }
40
41
        /** @var \Mautic\PluginBundle\Model\PluginModel $pluginModel */
42
        $pluginModel = $this->getModel('plugin');
43
44
        // List of plugins for filter and to show as a single integration
45
        $plugins = $pluginModel->getEntities(
46
            [
47
                'filter' => [
48
                    'force' => [
49
                        [
50
                            'column' => 'p.isMissing',
51
                            'expr'   => 'eq',
52
                            'value'  => 0,
53
                        ],
54
                    ],
55
                ],
56
                'hydration_mode' => 'hydrate_array',
57
            ]
58
        );
59
60
        $session      = $this->get('session');
61
        $pluginFilter = $this->request->get('plugin', $session->get('mautic.integrations.filter', ''));
62
63
        $session->set('mautic.integrations.filter', $pluginFilter);
64
65
        /** @var \Mautic\PluginBundle\Helper\IntegrationHelper $integrationHelper */
66
        $integrationHelper  = $this->factory->getHelper('integration');
67
        $integrationObjects = $integrationHelper->getIntegrationObjects(null, null, true);
68
        $integrations       = $foundPlugins       = [];
69
70
        foreach ($integrationObjects as $name => $object) {
71
            $settings = $object->getIntegrationSettings();
72
            $plugin   = $settings->getPlugin();
73
            $pluginId = $plugin ? $plugin->getId() : $name;
74
            if (isset($plugins[$pluginId]) || $pluginId === $name) {
75
                $integrations[$name] = [
76
                    'name'     => $object->getName(),
77
                    'display'  => $object->getDisplayName(),
78
                    'icon'     => $integrationHelper->getIconPath($object),
79
                    'enabled'  => $settings->isPublished(),
80
                    'plugin'   => $pluginId,
81
                    'isBundle' => false,
82
                ];
83
            }
84
85
            $foundPlugins[$pluginId] = true;
86
        }
87
88
        $nonIntegrationPlugins = array_diff_key($plugins, $foundPlugins);
89
        foreach ($nonIntegrationPlugins as $plugin) {
90
            $integrations[$plugin['name']] = [
91
                'name'        => $plugin['bundle'],
92
                'display'     => $plugin['name'],
93
                'icon'        => $integrationHelper->getIconPath($plugin),
94
                'enabled'     => true,
95
                'plugin'      => $plugin['id'],
96
                'description' => $plugin['description'],
97
                'isBundle'    => true,
98
            ];
99
        }
100
101
        //sort by name
102
        uksort(
103
            $integrations,
104
            function ($a, $b) {
105
                return strnatcasecmp($a, $b);
106
            }
107
        );
108
109
        $tmpl = $this->request->isXmlHttpRequest() ? $this->request->get('tmpl', 'index') : 'index';
110
111
        if (!empty($pluginFilter)) {
112
            foreach ($plugins as $plugin) {
113
                if ($plugin['id'] == $pluginFilter) {
114
                    $pluginName = $plugin['name'];
115
                    $pluginId   = $plugin['id'];
116
                    break;
117
                }
118
            }
119
        }
120
121
        return $this->delegateView(
122
            [
123
                'viewParameters' => [
124
                    'items'        => $integrations,
125
                    'tmpl'         => $tmpl,
126
                    'pluginFilter' => ($pluginFilter) ? ['id' => $pluginId, 'name' => $pluginName] : false,
127
                    'plugins'      => $plugins,
128
                ],
129
                'contentTemplate' => 'MauticPluginBundle:Integration:grid.html.php',
130
                'passthroughVars' => [
131
                    'activeLink'    => '#mautic_plugin_index',
132
                    'mauticContent' => 'integration',
133
                    'route'         => $this->generateUrl('mautic_plugin_index'),
134
                ],
135
            ]
136
        );
137
    }
138
139
    /**
140
     * @param string $name
141
     *
142
     * @return JsonResponse|Response
143
     */
144
    public function configAction($name, $activeTab = 'details-container', $page = 1)
145
    {
146
        if (!$this->get('mautic.security')->isGranted('plugin:plugins:manage')) {
147
            return $this->accessDenied();
148
        }
149
        if (!empty($this->request->get('activeTab'))) {
150
            $activeTab = $this->request->get('activeTab');
151
        }
152
153
        $session   = $this->get('session');
154
155
        $integrationDetailsPost = $this->request->request->get('integration_details', [], true);
0 ignored issues
show
The call to Symfony\Component\HttpFo...ion\ParameterBag::get() has too many arguments starting with true. ( Ignorable by Annotation )

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

155
        /** @scrutinizer ignore-call */ 
156
        $integrationDetailsPost = $this->request->request->get('integration_details', [], true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
156
        $authorize              = empty($integrationDetailsPost['in_auth']) ? false : true;
157
158
        /** @var \Mautic\PluginBundle\Helper\IntegrationHelper $integrationHelper */
159
        $integrationHelper = $this->factory->getHelper('integration');
160
        /** @var AbstractIntegration $integrationObject */
161
        $integrationObject = $integrationHelper->getIntegrationObject($name);
162
163
        // Verify that the requested integration exists
164
        if (empty($integrationObject)) {
165
            throw $this->createNotFoundException($this->get('translator')->trans('mautic.core.url.error.404'));
166
        }
167
168
        $object = ('leadFieldsContainer' === $activeTab) ? 'lead' : 'company';
169
        $limit  = $this->coreParametersHelper->get('default_pagelimit');
170
        $start  = (1 === $page) ? 0 : (($page - 1) * $limit);
171
        if ($start < 0) {
172
            $start = 0;
173
        }
174
        $session->set('mautic.plugin.'.$name.'.'.$object.'.start', $start);
175
        $session->set('mautic.plugin.'.$name.'.'.$object.'.page', $page);
176
177
        /** @var PluginModel $pluginModel */
178
        $pluginModel   = $this->getModel('plugin');
179
        $leadFields    = $pluginModel->getLeadFields();
180
        $companyFields = $pluginModel->getCompanyFields();
181
        /** @var \Mautic\PluginBundle\Integration\AbstractIntegration $integrationObject */
182
        $entity = $integrationObject->getIntegrationSettings();
183
184
        $form = $this->createForm(
185
            DetailsType::class,
186
            $entity,
187
            [
188
                'integration'        => $entity->getName(),
189
                'lead_fields'        => $leadFields,
190
                'company_fields'     => $companyFields,
191
                'integration_object' => $integrationObject,
192
                'action'             => $this->generateUrl('mautic_plugin_config', ['name' => $name]),
193
            ]
194
        );
195
196
        if ('POST' == $this->request->getMethod()) {
197
            $valid = false;
198
            if (!$cancelled = $this->isFormCancelled($form)) {
199
                $currentKeys            = $integrationObject->getDecryptedApiKeys($entity);
200
                $currentFeatureSettings = $entity->getFeatureSettings();
201
                $valid                  = $this->isFormValid($form);
202
203
                if ($authorize || $valid) {
204
                    $em          = $this->get('doctrine.orm.entity_manager');
205
                    $integration = $entity->getName();
206
207
                    if (isset($form['apiKeys'])) {
208
                        $keys = $form['apiKeys']->getData();
209
210
                        // Prevent merged keys
211
                        $secretKeys = $integrationObject->getSecretKeys();
212
                        foreach ($secretKeys as $secretKey) {
213
                            if (empty($keys[$secretKey]) && !empty($currentKeys[$secretKey])) {
214
                                $keys[$secretKey] = $currentKeys[$secretKey];
215
                            }
216
                        }
217
                        $integrationObject->encryptAndSetApiKeys($keys, $entity);
218
                    }
219
220
                    if (!$authorize) {
221
                        $features = $entity->getSupportedFeatures();
222
                        if (in_array('public_profile', $features) || in_array('push_lead', $features)) {
223
                            // Ungroup the fields
224
                            $mauticLeadFields = [];
225
                            foreach ($leadFields as $groupFields) {
226
                                $mauticLeadFields = array_merge($mauticLeadFields, $groupFields);
227
                            }
228
                            $mauticCompanyFields = [];
229
                            foreach ($companyFields as $groupFields) {
230
                                $mauticCompanyFields = array_merge($mauticCompanyFields, $groupFields);
231
                            }
232
233
                            if ($missing = $integrationObject->cleanUpFields($entity, $mauticLeadFields, $mauticCompanyFields)) {
234
                                if ($entity->getIsPublished()) {
235
                                    // Only fail validation if the integration is enabled
236
                                    if (!empty($missing['leadFields'])) {
237
                                        $valid = false;
238
239
                                        $form->get('featureSettings')->get('leadFields')->addError(
240
                                            new FormError(
241
                                                $this->get('translator')->trans('mautic.plugin.field.required_mapping_missing', [], 'validators')
242
                                            )
243
                                        );
244
                                    }
245
246
                                    if (!empty($missing['companyFields'])) {
247
                                        $valid = false;
248
249
                                        $form->get('featureSettings')->get('companyFields')->addError(
250
                                            new FormError(
251
                                                $this->get('translator')->trans('mautic.plugin.field.required_mapping_missing', [], 'validators')
252
                                            )
253
                                        );
254
                                    }
255
                                }
256
                            }
257
                        }
258
                    } else {
259
                        //make sure they aren't overwritten because of API connection issues
260
                        $entity->setFeatureSettings($currentFeatureSettings);
261
                    }
262
263
                    if ($valid || $authorize) {
264
                        $dispatcher = $this->get('event_dispatcher');
265
                        $this->get('logger')->info('Dispatching integration config save event.');
266
                        if ($dispatcher->hasListeners(PluginEvents::PLUGIN_ON_INTEGRATION_CONFIG_SAVE)) {
267
                            $this->get('logger')->info('Event dispatcher has integration config save listeners.');
268
                            $event = new PluginIntegrationEvent($integrationObject);
269
270
                            $dispatcher->dispatch(PluginEvents::PLUGIN_ON_INTEGRATION_CONFIG_SAVE, $event);
271
272
                            $entity = $event->getEntity();
273
                        }
274
275
                        $em->persist($entity);
276
                        $em->flush();
277
                    }
278
279
                    if ($authorize) {
280
                        //redirect to the oauth URL
281
                        /** @var \Mautic\PluginBundle\Integration\AbstractIntegration $integrationObject */
282
                        $event = $this->dispatcher->dispatch(
283
                            PluginEvents::PLUGIN_ON_INTEGRATION_AUTH_REDIRECT,
284
                            new PluginIntegrationAuthRedirectEvent(
285
                                $integrationObject,
286
                                $integrationObject->getAuthLoginUrl()
287
                            )
288
                        );
289
                        $oauthUrl = $event->getAuthUrl();
290
291
                        return new JsonResponse(
292
                            [
293
                                'integration'         => $integration,
294
                                'authUrl'             => $oauthUrl,
295
                                'authorize'           => 1,
296
                                'popupBlockerMessage' => $this->translator->trans('mautic.core.popupblocked'),
297
                            ]
298
                        );
299
                    }
300
                }
301
            }
302
303
            if (($cancelled || ($valid && !$this->isFormApplied($form))) && !$authorize) {
304
                // Close the modal and return back to the list view
305
                return new JsonResponse(
306
                    [
307
                        'closeModal'    => 1,
308
                        'enabled'       => $entity->getIsPublished(),
309
                        'name'          => $integrationObject->getName(),
310
                        'mauticContent' => 'integrationConfig',
311
                        'sidebar'       => $this->get('templating')->render('MauticCoreBundle:LeftPanel:index.html.php'),
312
                    ]
313
                );
314
            }
315
        }
316
317
        $template    = $integrationObject->getFormTemplate();
318
        $objectTheme = $integrationObject->getFormTheme();
319
        $default     = 'MauticPluginBundle:FormTheme\Integration';
320
        $themes      = [$default];
321
        if (is_array($objectTheme)) {
322
            $themes = array_merge($themes, $objectTheme);
323
        } elseif ($objectTheme !== $default) {
324
            $themes[] = $objectTheme;
325
        }
326
327
        $formSettings = $integrationObject->getFormSettings();
328
        $callbackUrl  = !empty($formSettings['requires_callback']) ? $integrationObject->getAuthCallbackUrl() : '';
329
330
        $formNotes    = [];
331
        $noteSections = ['authorization', 'features', 'feature_settings', 'custom'];
332
        foreach ($noteSections as $section) {
333
            if ('custom' === $section) {
334
                $formNotes[$section] = $integrationObject->getFormNotes($section);
335
            } else {
336
                list($specialInstructions, $alertType) = $integrationObject->getFormNotes($section);
337
338
                if (!empty($specialInstructions)) {
339
                    $formNotes[$section] = [
340
                        'note' => $specialInstructions,
341
                        'type' => $alertType,
342
                    ];
343
                }
344
            }
345
        }
346
347
        return $this->delegateView(
348
            [
349
                'viewParameters' => [
350
                    'form'         => $this->setFormTheme($form, $template, $themes),
351
                    'description'  => $integrationObject->getDescription(),
352
                    'formSettings' => $formSettings,
353
                    'formNotes'    => $formNotes,
354
                    'callbackUrl'  => $callbackUrl,
355
                    'activeTab'    => $activeTab,
356
                ],
357
                'contentTemplate' => $template,
358
                'passthroughVars' => [
359
                    'activeLink'    => '#mautic_plugin_index',
360
                    'mauticContent' => 'integrationConfig',
361
                    'route'         => false,
362
                    'sidebar'       => $this->get('templating')->render('MauticCoreBundle:LeftPanel:index.html.php'),
363
                ],
364
            ]
365
        );
366
    }
367
368
    /**
369
     * @param $name
370
     *
371
     * @return array|JsonResponse|RedirectResponse|Response
372
     */
373
    public function infoAction($name)
374
    {
375
        if (!$this->get('mautic.security')->isGranted('plugin:plugins:manage')) {
376
            return $this->accessDenied();
377
        }
378
379
        /** @var \Mautic\PluginBundle\Model\PluginModel $pluginModel */
380
        $pluginModel = $this->getModel('plugin');
381
382
        $bundle = $pluginModel->getRepository()->findOneBy(
383
            [
384
                'bundle' => InputHelper::clean($name),
385
            ]
386
        );
387
388
        if (!$bundle) {
389
            return $this->accessDenied();
390
        }
391
392
        /** @var \Mautic\PluginBundle\Helper\IntegrationHelper $integrationHelper */
393
        $integrationHelper = $this->factory->getHelper('integration');
394
395
        $bundle->splitDescriptions();
396
397
        return $this->delegateView(
398
            [
399
                'viewParameters' => [
400
                    'bundle' => $bundle,
401
                    'icon'   => $integrationHelper->getIconPath($bundle),
402
                ],
403
                'contentTemplate' => 'MauticPluginBundle:Integration:info.html.php',
404
                'passthroughVars' => [
405
                    'activeLink'    => '#mautic_plugin_index',
406
                    'mauticContent' => 'integration',
407
                    'route'         => false,
408
                ],
409
            ]
410
        );
411
    }
412
413
    /**
414
     * Scans the addon bundles directly and loads bundles which are not registered to the database.
415
     *
416
     * @return JsonResponse
417
     */
418
    public function reloadAction()
419
    {
420
        if (!$this->get('mautic.security')->isGranted('plugin:plugins:manage')) {
421
            return $this->accessDenied();
422
        }
423
424
        $this->addFlash(
425
            $this->get('mautic.plugin.facade.reload')->reloadPlugins()
426
        );
427
428
        $viewParameters = [
429
            'page' => $this->get('session')->get('mautic.plugin.page'),
430
        ];
431
432
        // Refresh the index contents
433
        return $this->postActionRedirect(
434
            [
435
                'returnUrl'       => $this->generateUrl('mautic_plugin_index', $viewParameters),
436
                'viewParameters'  => $viewParameters,
437
                'contentTemplate' => 'MauticPluginBundle:Plugin:index',
438
                'passthroughVars' => [
439
                    'activeLink'    => '#mautic_plugin_index',
440
                    'mauticContent' => 'plugin',
441
                ],
442
            ]
443
        );
444
    }
445
}
446