AjaxController   B
last analyzed

Complexity

Total Complexity 51

Size/Duplication

Total Lines 313
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 160
c 0
b 0
f 0
dl 0
loc 313
rs 7.92
wmc 51

9 Methods

Rating   Name   Duplication   Size   Complexity  
A sendTestEmailAction() 0 27 3
B getEmailCountStatsAction() 0 44 10
B sendBatchAction() 0 40 8
A getAbTestFormAction() 0 10 1
A generatePlaintTextAction() 0 16 1
A getBuilderTokens() 0 6 1
A getAttachmentsSizeAction() 0 11 2
B testMonitoredEmailServerConnectionAction() 0 34 8
F testEmailServerConnectionAction() 0 74 17

How to fix   Complexity   

Complex Class

Complex classes like AjaxController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AjaxController, and based on these observations, apply Extract Interface, too.

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\EmailBundle\Controller;
13
14
use Mautic\CoreBundle\Controller\AjaxController as CommonAjaxController;
15
use Mautic\CoreBundle\Controller\AjaxLookupControllerTrait;
16
use Mautic\CoreBundle\Controller\VariantAjaxControllerTrait;
17
use Mautic\CoreBundle\Translation\Translator;
18
use Mautic\EmailBundle\Helper\MailHelper;
19
use Mautic\EmailBundle\Helper\PlainTextHelper;
20
use Mautic\EmailBundle\Model\EmailModel;
21
use Mautic\PageBundle\Form\Type\AbTestPropertiesType;
22
use Symfony\Component\HttpFoundation\JsonResponse;
23
use Symfony\Component\HttpFoundation\Request;
24
25
class AjaxController extends CommonAjaxController
26
{
27
    use VariantAjaxControllerTrait;
28
    use AjaxLookupControllerTrait;
0 ignored issues
show
Bug introduced by
The trait Mautic\CoreBundle\Contro...axLookupControllerTrait requires the property $query which is not provided by Mautic\EmailBundle\Controller\AjaxController.
Loading history...
29
30
    /**
31
     * @return \Symfony\Component\HttpFoundation\JsonResponse
32
     */
33
    protected function getAbTestFormAction(Request $request)
34
    {
35
        return $this->getAbTestForm(
36
            $request,
37
            'email',
38
            AbTestPropertiesType::class,
39
            'email_abtest_settings',
40
            'emailform',
41
            'MauticEmailBundle:AbTest:form.html.php',
42
            ['MauticEmailBundle:AbTest:form.html.php', 'MauticEmailBundle:FormTheme\Email']
43
        );
44
    }
45
46
    /**
47
     * @return \Symfony\Component\HttpFoundation\JsonResponse
48
     */
49
    public function sendBatchAction(Request $request)
50
    {
51
        $dataArray = ['success' => 0];
52
53
        /** @var \Mautic\EmailBundle\Model\EmailModel $model */
54
        $model    = $this->getModel('email');
55
        $objectId = $request->request->get('id', 0);
56
        $pending  = $request->request->get('pending', 0);
57
        $limit    = $request->request->get('batchlimit', 100);
58
59
        if ($objectId && $entity = $model->getEntity($objectId)) {
60
            $dataArray['success'] = 1;
61
            $session              = $this->container->get('session');
62
            $progress             = $session->get('mautic.email.send.progress', [0, (int) $pending]);
63
            $stats                = $session->get('mautic.email.send.stats', ['sent' => 0, 'failed' => 0, 'failedRecipients' => []]);
64
            $inProgress           = $session->get('mautic.email.send.active', false);
65
66
            if ($pending && !$inProgress && $entity->isPublished()) {
67
                $session->set('mautic.email.send.active', true);
68
                list($batchSentCount, $batchFailedCount, $batchFailedRecipients) = $model->sendEmailToLists($entity, null, $limit);
69
70
                $progress[0] += ($batchSentCount + $batchFailedCount);
71
                $stats['sent'] += $batchSentCount;
72
                $stats['failed'] += $batchFailedCount;
73
74
                foreach ($batchFailedRecipients as $emails) {
75
                    $stats['failedRecipients'] = $stats['failedRecipients'] + $emails;
76
                }
77
78
                $session->set('mautic.email.send.progress', $progress);
79
                $session->set('mautic.email.send.stats', $stats);
80
                $session->set('mautic.email.send.active', false);
81
            }
82
83
            $dataArray['percent']  = ($progress[1]) ? ceil(($progress[0] / $progress[1]) * 100) : 100;
84
            $dataArray['progress'] = $progress;
85
            $dataArray['stats']    = $stats;
86
        }
87
88
        return $this->sendJsonResponse($dataArray);
89
    }
90
91
    /**
92
     * Called by parent::getBuilderTokensAction().
93
     *
94
     * @param $query
95
     *
96
     * @return array
97
     */
98
    protected function getBuilderTokens($query)
99
    {
100
        /** @var \Mautic\EmailBundle\Model\EmailModel $model */
101
        $model = $this->getModel('email');
102
103
        return $model->getBuilderComponents(null, ['tokens'], $query, false);
104
    }
105
106
    /**
107
     * @return \Symfony\Component\HttpFoundation\JsonResponse
108
     */
109
    protected function generatePlaintTextAction(Request $request)
110
    {
111
        $custom = $request->request->get('custom');
112
        $id     = $request->request->get('id');
0 ignored issues
show
Unused Code introduced by
The assignment to $id is dead and can be removed.
Loading history...
113
114
        $parser = new PlainTextHelper(
115
            [
116
                'base_url' => $request->getSchemeAndHttpHost().$request->getBasePath(),
117
            ]
118
        );
119
120
        $dataArray = [
121
            'text' => $parser->setHtml($custom)->getText(),
122
        ];
123
124
        return $this->sendJsonResponse($dataArray);
125
    }
126
127
    /**
128
     * @return \Symfony\Component\HttpFoundation\JsonResponse
129
     */
130
    protected function getAttachmentsSizeAction(Request $request)
131
    {
132
        $assets = $request->get('assets', [], true);
0 ignored issues
show
Unused Code introduced by
The call to Symfony\Component\HttpFoundation\Request::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

132
        /** @scrutinizer ignore-call */ 
133
        $assets = $request->get('assets', [], 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...
133
        $size   = 0;
134
        if ($assets) {
135
            /** @var \Mautic\AssetBundle\Model\AssetModel $assetModel */
136
            $assetModel = $this->getModel('asset');
137
            $size       = $assetModel->getTotalFilesize($assets);
138
        }
139
140
        return $this->sendJsonResponse(['size' => $size]);
141
    }
142
143
    /**
144
     * Tests monitored email connection settings.
145
     *
146
     * @return JsonResponse
147
     */
148
    protected function testMonitoredEmailServerConnectionAction(Request $request)
149
    {
150
        $dataArray = ['success' => 0, 'message' => ''];
151
152
        if ($this->user->isAdmin()) {
153
            $settings = $request->request->all();
154
155
            if (empty($settings['password'])) {
156
                $existingMonitoredSettings = $this->coreParametersHelper->get('monitored_email');
157
                if (is_array($existingMonitoredSettings) && (!empty($existingMonitoredSettings[$settings['mailbox']]['password']))) {
158
                    $settings['password'] = $existingMonitoredSettings[$settings['mailbox']]['password'];
159
                }
160
            }
161
162
            /** @var \Mautic\EmailBundle\MonitoredEmail\Mailbox $helper */
163
            $helper = $this->factory->getHelper('mailbox');
164
165
            try {
166
                $helper->setMailboxSettings($settings, false);
0 ignored issues
show
Unused Code introduced by
The call to Mautic\EmailBundle\Monit...x::setMailboxSettings() has too many arguments starting with false. ( Ignorable by Annotation )

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

166
                $helper->/** @scrutinizer ignore-call */ 
167
                         setMailboxSettings($settings, false);

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...
167
                $folders = $helper->getListingFolders('');
0 ignored issues
show
Unused Code introduced by
The call to Mautic\EmailBundle\Monit...ox::getListingFolders() has too many arguments starting with ''. ( Ignorable by Annotation )

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

167
                /** @scrutinizer ignore-call */ 
168
                $folders = $helper->getListingFolders('');

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...
168
                if (!empty($folders)) {
169
                    $dataArray['folders'] = '';
170
                    foreach ($folders as $folder) {
171
                        $dataArray['folders'] .= "<option value=\"$folder\">$folder</option>\n";
172
                    }
173
                }
174
                $dataArray['success'] = 1;
175
                $dataArray['message'] = $this->translator->trans('mautic.core.success');
176
            } catch (\Exception $e) {
177
                $dataArray['message'] = $this->translator->trans($e->getMessage());
178
            }
179
        }
180
181
        return $this->sendJsonResponse($dataArray);
182
    }
183
184
    /**
185
     * Tests mail transport settings.
186
     *
187
     * @return JsonResponse
188
     */
189
    protected function testEmailServerConnectionAction(Request $request)
190
    {
191
        $dataArray = ['success' => 0, 'message' => ''];
192
        $user      = $this->get('mautic.helper.user')->getUser();
193
194
        if ($user->isAdmin()) {
195
            $settings = $request->request->all();
196
197
            $transport = $settings['transport'];
198
199
            switch ($transport) {
200
                case 'gmail':
201
                    $mailer = new \Swift_SmtpTransport('smtp.gmail.com', 465, 'ssl');
202
                    break;
203
                case 'smtp':
204
                    $mailer = new \Swift_SmtpTransport($settings['host'], $settings['port'], $settings['encryption']);
205
                    break;
206
                default:
207
                    if ($this->container->has($transport)) {
208
                        $mailer = $this->container->get($transport);
209
210
                        if ('mautic.transport.amazon' == $transport) {
211
                            $amazonHost = $mailer->buildHost($settings['amazon_region'], $settings['amazon_other_region']);
212
                            $mailer->setHost($amazonHost, $settings['port']);
213
                        }
214
215
                        if ('mautic.transport.amazon_api' == $transport) {
216
                            $mailer->setRegion($settings['amazon_region'], $settings['amazon_other_region']);
217
                        }
218
                    }
219
            }
220
221
            if (method_exists($mailer, 'setMauticFactory')) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $mailer does not seem to be defined for all execution paths leading up to this point.
Loading history...
222
                $mailer->setMauticFactory($this->factory);
223
            }
224
225
            if (!empty($mailer)) {
226
                try {
227
                    if (method_exists($mailer, 'setApiKey')) {
228
                        if (empty($settings['api_key'])) {
229
                            $settings['api_key'] = $this->get('mautic.helper.core_parameters')->get('mailer_api_key');
230
                        }
231
                        $mailer->setApiKey($settings['api_key']);
232
                    }
233
                } catch (\Exception $exception) {
234
                    // Transport had magic method defined and threw an exception
235
                }
236
237
                try {
238
                    if (is_callable([$mailer, 'setUsername']) && is_callable([$mailer, 'setPassword'])) {
239
                        if (empty($settings['password'])) {
240
                            $settings['password'] = $this->get('mautic.helper.core_parameters')->get('mailer_password');
241
                        }
242
                        $mailer->setUsername($settings['user']);
243
                        $mailer->setPassword($settings['password']);
244
                    }
245
                } catch (\Exception $exception) {
246
                    // Transport had magic method defined and threw an exception
247
                }
248
249
                $logger = new \Swift_Plugins_Loggers_ArrayLogger();
250
                $mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($logger));
251
252
                try {
253
                    $mailer->start();
254
                    $dataArray['success'] = 1;
255
                    $dataArray['message'] = $this->get('translator')->trans('mautic.core.success');
256
                } catch (\Exception $e) {
257
                    $dataArray['message'] = $e->getMessage().'<br />'.$logger->dump();
258
                }
259
            }
260
        }
261
262
        return $this->sendJsonResponse($dataArray);
263
    }
264
265
    protected function sendTestEmailAction(Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

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

265
    protected function sendTestEmailAction(/** @scrutinizer ignore-unused */ Request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
266
    {
267
        /** @var MailHelper $mailer */
268
        $mailer = $this->get('mautic.helper.mailer');
269
        /** @var Translator $translator */
270
        $translator = $this->get('translator');
271
272
        $mailer->setSubject($translator->trans('mautic.email.config.mailer.transport.test_send.subject'));
273
        $mailer->setBody($translator->trans('mautic.email.config.mailer.transport.test_send.body'));
274
275
        $user         = $this->get('mautic.helper.user')->getUser();
276
        $userFullName = trim($user->getFirstName().' '.$user->getLastName());
277
        if (empty($userFullName)) {
278
            $userFullName = null;
279
        }
280
        $mailer->setTo([$user->getEmail() => $userFullName]);
281
282
        $success = 1;
283
        $message = $translator->trans('mautic.core.success');
284
        if (!$mailer->send(true)) {
285
            $success   = 0;
286
            $errors    = $mailer->getErrors();
287
            unset($errors['failures']);
288
            $message = implode('; ', $errors);
289
        }
290
291
        return $this->sendJsonResponse(['success' => $success, 'message' => $message]);
292
    }
293
294
    protected function getEmailCountStatsAction(Request $request)
295
    {
296
        /** @var EmailModel $model */
297
        $model = $this->getModel('email');
298
299
        $id  = $request->get('id');
300
        $ids = $request->get('ids');
301
302
        // Support for legacy calls
303
        if (!$ids && $id) {
304
            $ids = [$id];
305
        }
306
307
        $data = [];
308
        foreach ($ids as $id) {
309
            if ($email = $model->getEntity($id)) {
310
                $pending = $model->getPendingLeads($email, null, true);
311
                $queued  = $model->getQueuedCounts($email);
312
313
                $data[] = [
314
                    'id'          => $id,
315
                    'pending'     => 'list' === $email->getEmailType() && $pending ? $this->translator->trans(
316
                        'mautic.email.stat.leadcount',
317
                        ['%count%' => $pending]
318
                    ) : 0,
319
                    'queued'      => ($queued) ? $this->translator->trans('mautic.email.stat.queued', ['%count%' => $queued]) : 0,
320
                    'sentCount'   => $this->translator->trans('mautic.email.stat.sentcount', ['%count%' => $email->getSentCount(true)]),
321
                    'readCount'   => $this->translator->trans('mautic.email.stat.readcount', ['%count%' => $email->getReadCount(true)]),
322
                    'readPercent' => $this->translator->trans('mautic.email.stat.readpercent', ['%count%' => $email->getReadPercentage(true)]),
323
                ];
324
            }
325
        }
326
327
        // Support for legacy calls
328
        if ($request->get('id') && !empty($data[0])) {
329
            $data = $data[0];
330
        } else {
331
            $data = [
332
                'success' => 1,
333
                'stats'   => $data,
334
            ];
335
        }
336
337
        return new JsonResponse($data);
338
    }
339
}
340