Issues (3627)

bundles/LeadBundle/Controller/ImportController.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\LeadBundle\Controller;
13
14
use Mautic\CoreBundle\Controller\FormController;
15
use Mautic\CoreBundle\Helper\CsvHelper;
16
use Mautic\LeadBundle\Entity\Import;
17
use Mautic\LeadBundle\Form\Type\LeadImportFieldType;
18
use Mautic\LeadBundle\Form\Type\LeadImportType;
19
use Mautic\LeadBundle\Helper\Progress;
20
use Symfony\Component\Filesystem\Filesystem;
21
use Symfony\Component\Form\Exception\LogicException;
22
use Symfony\Component\Form\Form;
23
use Symfony\Component\Form\FormError;
24
use Symfony\Component\HttpFoundation\File\Exception\FileException;
25
use Symfony\Component\HttpFoundation\JsonResponse;
26
use Symfony\Component\HttpFoundation\Response;
27
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
28
29
class ImportController extends FormController
30
{
31
    // Steps of the import
32
    const STEP_UPLOAD_CSV      = 1;
33
    const STEP_MATCH_FIELDS    = 2;
34
    const STEP_PROGRESS_BAR    = 3;
35
    const STEP_IMPORT_FROM_CSV = 4;
36
37
    /**
38
     * @param int $page
39
     *
40
     * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
41
     */
42
    public function indexAction($page = 1)
43
    {
44
        $this->get('session')->set('mautic.import.object', $this->getObjectFromRequest());
45
46
        return $this->indexStandard($page);
47
    }
48
49
    /**
50
     * Get items for index list.
51
     *
52
     * @param $start
53
     * @param $limit
54
     * @param $filter
55
     * @param $orderBy
56
     * @param $orderByDir
57
     * @param $args
58
     *
59
     * @return array
60
     */
61
    protected function getIndexItems($start, $limit, $filter, $orderBy, $orderByDir, array $args = [])
62
    {
63
        $object = $this->get('session')->get('mautic.import.object');
64
        $model  = $this->getModel($this->getModelName());
65
66
        $filter['force'][] = [
67
            'column' => $model->getRepository()->getTableAlias().'.object',
68
            'expr'   => 'eq',
69
            'value'  => $object,
70
        ];
71
72
        $items = $model->getEntities(
73
            array_merge(
74
                [
75
                    'start'      => $start,
76
                    'limit'      => $limit,
77
                    'filter'     => $filter,
78
                    'orderBy'    => $orderBy,
79
                    'orderByDir' => $orderByDir,
80
                ],
81
                $args
82
            )
83
        );
84
85
        $count = count($items);
86
87
        return [$count, $items];
88
    }
89
90
    /**
91
     * @param $objectId
92
     *
93
     * @return array|\Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
94
     */
95
    public function viewAction($objectId)
96
    {
97
        return $this->viewStandard($objectId, 'import', 'lead');
98
    }
99
100
    /**
101
     * Cancel and unpublish the import during manual import.
102
     *
103
     * @param $objectId
104
     *
105
     * @return array|\Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
106
     */
107
    public function cancelAction($objectId)
108
    {
109
        $session     = $this->get('session');
110
        $fullPath    = $this->getFullCsvPath();
111
        $importModel = $this->getModel($this->getModelName());
112
        $import      = $importModel->getEntity($session->get('mautic.lead.import.id', null));
113
114
        if ($import && $import->getId()) {
115
            $import->setStatus($import::STOPPED)
116
                ->setIsPublished(false);
117
            $importModel->saveEntity($import);
118
        }
119
120
        $this->resetImport($fullPath);
121
122
        return $this->indexAction();
123
    }
124
125
    /**
126
     * Schedules manual import to background queue.
127
     *
128
     * @param $objectId
129
     *
130
     * @return array|\Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
131
     */
132
    public function queueAction($objectId)
133
    {
134
        $session     = $this->get('session');
135
        $fullPath    = $this->getFullCsvPath();
136
        $importModel = $this->getModel($this->getModelName());
137
        $import      = $importModel->getEntity($session->get('mautic.lead.import.id', null));
138
139
        if ($import) {
140
            $import->setStatus($import::QUEUED);
141
            $importModel->saveEntity($import);
142
        }
143
144
        $this->resetImport($fullPath, false);
145
146
        return $this->indexAction();
147
    }
148
149
    /**
150
     * @param int  $objectId
151
     * @param bool $ignorePost
152
     *
153
     * @return JsonResponse|\Symfony\Component\HttpFoundation\Response
154
     */
155
    public function newAction($objectId = 0, $ignorePost = false)
156
    {
157
        //Auto detect line endings for the file to work around MS DOS vs Unix new line characters
158
        ini_set('auto_detect_line_endings', true);
159
160
        $object = $this->getObjectFromRequest();
161
162
        $this->get('session')->set('mautic.import.object', $object);
163
164
        /** @var \Mautic\LeadBundle\Model\ImportModel $importModel */
165
        $importModel = $this->getModel($this->getModelName());
166
167
        $session = $this->get('session');
168
169
        if (!$this->get('mautic.security')->isGranted('lead:imports:create')) {
170
            return $this->accessDenied();
171
        }
172
173
        // Move the file to cache and rename it
174
        $forceStop = $this->request->get('cancel', false);
175
        $step      = ($forceStop) ? 1 : $session->get('mautic.'.$object.'.import.step', self::STEP_UPLOAD_CSV);
176
        $fileName  = $this->getImportFileName();
177
        $importDir = $this->getImportDirName();
178
        $fullPath  = $this->getFullCsvPath();
179
        $fs        = new Filesystem();
180
        $complete  = false;
181
182
        if (!file_exists($fullPath)) {
183
            // Force step one if the file doesn't exist
184
            $step = 1;
185
            $session->set('mautic.'.$object.'.import.step', self::STEP_UPLOAD_CSV);
186
        }
187
188
        $progress = (new Progress())->bindArray($session->get('mautic.'.$object.'.import.progress', [0, 0]));
189
        $import   = $importModel->getEntity();
190
        $action   = $this->generateUrl('mautic_import_action', ['object' => $this->request->get('object'), 'objectAction' => 'new']);
191
192
        switch ($step) {
193
            case self::STEP_UPLOAD_CSV:
194
195
                if ($forceStop) {
196
                    $this->resetImport($fullPath);
197
                }
198
199
                $form = $this->get('form.factory')->create(LeadImportType::class, [], ['action' => $action]);
200
                break;
201
            case self::STEP_MATCH_FIELDS:
202
203
                /** @var \Mautic\LeadBundle\Model\FieldModel $fieldModel */
204
                $fieldModel    = $this->getModel('lead.field');
205
                $leadFields    = $fieldModel->getFieldList(false, false);
206
                $importFields  = $session->get('mautic.'.$object.'.import.importfields', []);
207
                $companyFields = $fieldModel->getFieldList(false, false, ['isPublished' => true, 'object' => 'company']);
208
209
                try {
210
                    $form = $this->get('form.factory')->create(
211
                        LeadImportFieldType::class,
212
                        [],
213
                        [
214
                            'object'           => $object,
215
                            'action'           => $action,
216
                            'lead_fields'      => $leadFields,
217
                            'company_fields'   => $companyFields,
218
                            'import_fields'    => $importFields,
219
                            'line_count_limit' => $this->getLineCountLimit(),
220
                        ]
221
                    );
222
                } catch (LogicException $e) {
223
                    $this->resetImport($fullPath);
224
225
                    return $this->newAction(0, true);
226
                }
227
228
                break;
229
            case self::STEP_PROGRESS_BAR:
230
                // Just show the progress form
231
                $session->set('mautic.'.$object.'.import.step', self::STEP_IMPORT_FROM_CSV);
232
                break;
233
234
            case self::STEP_IMPORT_FROM_CSV:
235
                ignore_user_abort(true);
236
237
                $inProgress = $session->get('mautic.'.$object.'.import.inprogress', false);
238
                $checks     = $session->get('mautic.'.$object.'.import.progresschecks', 1);
239
                if (true || !$inProgress || $checks > 5) {
240
                    $session->set('mautic.'.$object.'.import.inprogress', true);
241
                    $session->set('mautic.'.$object.'.import.progresschecks', 1);
242
243
                    $import = $importModel->getEntity($session->get('mautic.'.$object.'.import.id', null));
244
245
                    if (!$import->getDateStarted()) {
246
                        $import->setDateStarted(new \DateTime());
247
                    }
248
249
                    $importModel->process($import, $progress);
250
251
                    // Clear in progress
252
                    if ($progress->isFinished()) {
253
                        $import->setStatus($import::IMPORTED)
254
                            ->setDateEnded(new \DateTime());
255
                        $this->resetImport($fullPath);
256
                        $complete = true;
257
                    } else {
258
                        $complete = false;
259
                        $session->set('mautic.'.$object.'.import.inprogress', false);
260
                        $session->set('mautic.'.$object.'.import.progress', $progress->toArray());
261
                    }
262
263
                    $importModel->saveEntity($import);
264
265
                    break;
266
                } else {
267
                    ++$checks;
268
                    $session->set('mautic.'.$object.'.import.progresschecks', $checks);
269
                }
270
        }
271
272
        ///Check for a submitted form and process it
273
        if (!$ignorePost && 'POST' == $this->request->getMethod()) {
274
            if (isset($form) && !$this->isFormCancelled($form)) {
275
                $valid = $this->isFormValid($form);
276
                switch ($step) {
277
                    case self::STEP_UPLOAD_CSV:
278
                        if ($valid) {
279
                            if (file_exists($fullPath)) {
280
                                unlink($fullPath);
281
                            }
282
283
                            $fileData = $form['file']->getData();
284
                            if (!empty($fileData)) {
285
                                $errorMessage    = null;
286
                                $errorParameters = [];
287
                                try {
288
                                    // Create the import dir recursively
289
                                    $fs->mkdir($importDir);
290
291
                                    $fileData->move($importDir, $fileName);
292
293
                                    $file = new \SplFileObject($fullPath);
294
295
                                    $config = $form->getData();
296
                                    unset($config['file']);
297
                                    unset($config['start']);
298
299
                                    foreach ($config as $key => &$c) {
300
                                        $c = htmlspecialchars_decode($c);
301
302
                                        if ('batchlimit' == $key) {
303
                                            $c = (int) $c;
304
                                        }
305
                                    }
306
307
                                    $session->set('mautic.'.$object.'.import.config', $config);
308
309
                                    if (false !== $file) {
310
                                        // Get the headers for matching
311
                                        $headers = $file->fgetcsv($config['delimiter'], $config['enclosure'], $config['escape']);
312
313
                                        // Get the number of lines so we can track progress
314
                                        $file->seek(PHP_INT_MAX);
315
                                        $linecount = $file->key();
316
317
                                        if (!empty($headers) && is_array($headers)) {
318
                                            $headers = CsvHelper::sanitizeHeaders($headers);
319
320
                                            $session->set('mautic.'.$object.'.import.headers', $headers);
321
                                            $session->set('mautic.'.$object.'.import.step', self::STEP_MATCH_FIELDS);
322
                                            $session->set('mautic.'.$object.'.import.importfields', CsvHelper::convertHeadersIntoFields($headers));
323
                                            $session->set('mautic.'.$object.'.import.progress', [0, $linecount]);
324
                                            $session->set('mautic.'.$object.'.import.original.file', $fileData->getClientOriginalName());
325
326
                                            return $this->newAction(0, true);
327
                                        }
328
                                    }
329
                                } catch (FileException $e) {
330
                                    if (false !== strpos($e->getMessage(), 'upload_max_filesize')) {
331
                                        $errorMessage    = 'mautic.lead.import.filetoolarge';
332
                                        $errorParameters = [
333
                                            '%upload_max_filesize%' => ini_get('upload_max_filesize'),
334
                                        ];
335
                                    } else {
336
                                        $errorMessage = 'mautic.lead.import.filenotreadable';
337
                                    }
338
                                } catch (\Exception $e) {
339
                                    $errorMessage = 'mautic.lead.import.filenotreadable';
340
                                } finally {
341
                                    if (!is_null($errorMessage)) {
342
                                        $form->addError(
343
                                            new FormError(
344
                                                $this->get('translator')->trans($errorMessage, $errorParameters, 'validators')
345
                                            )
346
                                        );
347
                                    }
348
                                }
349
                            }
350
                        }
351
                        break;
352
                    case self::STEP_MATCH_FIELDS:
353
                        // Save matched fields
354
                        $matchedFields = $form->getData();
355
356
                        if (empty($matchedFields)) {
357
                            $this->resetImport($fullPath);
358
359
                            return $this->newAction(0, true);
360
                        }
361
362
                        $owner = $matchedFields['owner'];
363
                        unset($matchedFields['owner']);
364
365
                        $list = null;
366
                        if (array_key_exists('list', $matchedFields)) {
367
                            $list = $matchedFields['list'];
368
                            unset($matchedFields['list']);
369
                        }
370
371
                        $tags = [];
372
                        if (array_key_exists('tags', $matchedFields)) {
373
                            $tagCollection = $matchedFields['tags'];
374
                            $tags          = [];
375
                            foreach ($tagCollection as $tag) {
376
                                $tags[] = $tag->getTag();
377
                            }
378
                            unset($matchedFields['tags']);
379
                        }
380
381
                        foreach ($matchedFields as $k => $f) {
382
                            if (empty($f)) {
383
                                unset($matchedFields[$k]);
384
                            } else {
385
                                $matchedFields[$k] = trim($matchedFields[$k]);
386
                            }
387
                        }
388
389
                        if (empty($matchedFields)) {
390
                            $form->addError(
391
                                new FormError(
392
                                    $this->get('translator')->trans('mautic.lead.import.matchfields', [], 'validators')
393
                                )
394
                            );
395
                        } else {
396
                            $defaultOwner = ($owner) ? $owner->getId() : null;
397
398
                            /** @var \Mautic\LeadBundle\Entity\Import $import */
399
                            $import = $importModel->getEntity();
400
401
                            $import->setMatchedFields($matchedFields)
402
                                ->setObject($object)
403
                                ->setDir($importDir)
404
                                ->setLineCount($this->getLineCount())
405
                                ->setFile($fileName)
406
                                ->setOriginalFile($session->get('mautic.'.$object.'.import.original.file'))
407
                                ->setDefault('owner', $defaultOwner)
408
                                ->setDefault('list', $list)
409
                                ->setDefault('tags', $tags)
410
                                ->setHeaders($session->get('mautic.'.$object.'.import.headers'))
411
                                ->setParserConfig($session->get('mautic.'.$object.'.import.config'));
412
413
                            // In case the user chose to import in browser
414
                            if ($this->importInBrowser($form)) {
415
                                $import->setStatus($import::MANUAL);
416
417
                                $session->set('mautic.'.$object.'.import.step', self::STEP_PROGRESS_BAR);
418
                            }
419
420
                            $importModel->saveEntity($import);
421
422
                            $session->set('mautic.'.$object.'.import.id', $import->getId());
423
424
                            // In case the user decided to queue the import
425
                            if ($this->importInCli($form)) {
426
                                $this->addFlash('mautic.'.$object.'.batch.import.created');
427
                                $this->resetImport($fullPath, false);
428
429
                                return $this->indexAction();
430
                            }
431
432
                            return $this->newAction(0, true);
433
                        }
434
                        break;
435
436
                    default:
437
                        // Done or something wrong
438
439
                        $this->resetImport($fullPath);
440
441
                        break;
442
                }
443
            } else {
444
                $this->resetImport($fullPath);
445
446
                return $this->newAction(0, true);
447
            }
448
        }
449
450
        if (self::STEP_UPLOAD_CSV === $step || self::STEP_MATCH_FIELDS === $step) {
451
            $contentTemplate = 'MauticLeadBundle:Import:new.html.php';
452
            $viewParameters  = ['form' => $form->createView()];
453
        } else {
454
            $contentTemplate = 'MauticLeadBundle:Import:progress.html.php';
455
            $viewParameters  = [
456
                'progress'   => $progress,
457
                'import'     => $import,
458
                'complete'   => $complete,
459
                'failedRows' => $importModel->getFailedRows($import->getId()),
460
            ];
461
        }
462
463
        if (!$complete && $this->request->query->has('importbatch')) {
464
            // Ajax request to batch process so just return ajax response unless complete
465
466
            return new JsonResponse(['success' => 1, 'ignore_wdt' => 1]);
467
        } else {
468
            $activeLink = 'lead' === $object ? '#mautic_contact_index' : '#mautic_company_index';
469
470
            return $this->delegateView(
471
                [
472
                    'viewParameters'  => $viewParameters,
473
                    'contentTemplate' => $contentTemplate,
474
                    'passthroughVars' => [
475
                        'activeLink'    => $activeLink,
476
                        'mauticContent' => 'leadImport',
477
                        'route'         => $this->generateUrl(
478
                            'mautic_import_action',
479
                            [
480
                                'object'       => 'lead' === $object ? 'contacts' : 'companies',
481
                                'objectAction' => 'new',
482
                            ]
483
                        ),
484
                        'step'     => $step,
485
                        'progress' => $progress,
486
                    ],
487
                ]
488
            );
489
        }
490
    }
491
492
    /**
493
     * Returns line count from the session.
494
     *
495
     * @return int
496
     */
497
    protected function getLineCount()
498
    {
499
        $object = $this->getObjectFromRequest();
500
501
        $progress = $this->get('session')->get('mautic.'.$object.'.import.progress', [0, 0]);
502
503
        return isset($progress[1]) ? $progress[1] : 0;
504
    }
505
506
    /**
507
     * Decide whether the import will be processed in client's browser.
508
     *
509
     * @return bool
510
     */
511
    protected function importInBrowser(Form $form)
512
    {
513
        $browserImportLimit = $this->getLineCountLimit();
514
515
        if ($browserImportLimit && $this->getLineCount() < $browserImportLimit) {
516
            return true;
517
        } elseif (!$browserImportLimit && $form->get('buttons')->get('save')->isClicked()) {
518
            return true;
519
        }
520
521
        return false;
522
    }
523
524
    protected function getLineCountLimit()
525
    {
526
        return $this->get('mautic.helper.core_parameters')->get('background_import_if_more_rows_than', 0);
527
    }
528
529
    /**
530
     * Decide whether the import will be queued to be processed by the CLI command in the background.
531
     *
532
     * @return bool
533
     */
534
    protected function importInCli(Form $form)
535
    {
536
        $browserImportLimit = $this->getLineCountLimit();
537
538
        if ($browserImportLimit && $this->getLineCount() >= $browserImportLimit) {
539
            return true;
540
        } elseif (!$browserImportLimit && $form->get('buttons')->get('apply')->isClicked()) {
541
            return true;
542
        }
543
544
        return false;
545
    }
546
547
    /**
548
     * Generates import directory path.
549
     *
550
     * @return string
551
     */
552
    protected function getImportDirName()
553
    {
554
        /** @var \Mautic\LeadBundle\Model\ImportModel $importModel */
555
        $importModel = $this->getModel('lead.import');
556
557
        return $importModel->getImportDir();
558
    }
559
560
    /**
561
     * Generates unique import directory name inside the cache dir if not stored in the session.
562
     * If it exists in the session, returns that one.
563
     *
564
     * @return string
565
     */
566
    protected function getImportFileName()
567
    {
568
        $session = $this->get('session');
569
        $object  = $this->getObjectFromRequest();
570
571
        // Return the dir path from session if exists
572
        if ($fileName = $session->get('mautic.'.$object.'.import.file')) {
573
            return $fileName;
574
        }
575
576
        /** @var \Mautic\LeadBundle\Model\ImportModel $importModel */
577
        $importModel = $this->getModel('lead.import');
578
        $fileName    = $importModel->getUniqueFileName();
579
580
        // Set the dir path to session
581
        $session->set('mautic.'.$object.'.import.file', $fileName);
582
583
        return $fileName;
584
    }
585
586
    /**
587
     * Return full absolute path to the CSV file.
588
     *
589
     * @return string
590
     */
591
    protected function getFullCsvPath()
592
    {
593
        return $this->getImportDirName().'/'.$this->getImportFileName();
594
    }
595
596
    /**
597
     * @param $filepath
598
     */
599
    private function resetImport($filepath, $removeCsv = true)
600
    {
601
        $object  = $this->getObjectFromRequest();
602
        $session = $this->get('session');
603
        $session->set('mautic.'.$object.'.import.headers', []);
604
        $session->set('mautic.'.$object.'.import.file', null);
605
        $session->set('mautic.'.$object.'.import.step', self::STEP_UPLOAD_CSV);
606
        $session->set('mautic.'.$object.'.import.progress', [0, 0]);
607
        $session->set('mautic.'.$object.'.import.inprogress', false);
608
        $session->set('mautic.'.$object.'.import.importfields', []);
609
        $session->set('mautic.'.$object.'.import.original.file', null);
610
        $session->set('mautic.'.$object.'.import.id', null);
611
612
        if ($removeCsv && file_exists($filepath) && is_readable($filepath)) {
613
            unlink($filepath);
614
        }
615
    }
616
617
    /**
618
     * @param $action
619
     *
620
     * @return array
621
     */
622
    public function getViewArguments(array $args, $action)
623
    {
624
        switch ($action) {
625
            case 'view':
626
                /** @var Import $entity */
627
                $entity = $args['entity'];
628
629
                /** @var \Mautic\LeadBundle\Model\ImportModel $model */
630
                $model = $this->getModel($this->getModelName());
631
632
                $args['viewParameters'] = array_merge(
633
                    $args['viewParameters'],
634
                    [
635
                        'failedRows'        => $model->getFailedRows($entity->getId()),
636
                        'importedRowsChart' => $entity->getDateStarted() ? $model->getImportedRowsLineChartData(
637
                            'i',
638
                            $entity->getDateStarted(),
639
                            $entity->getDateEnded() ? $entity->getDateEnded() : $entity->getDateModified(),
640
                            null,
641
                            [
642
                                'object_id' => $entity->getId(),
643
                            ]
644
                        ) : [],
645
                    ]
646
                );
647
648
                break;
649
        }
650
651
        return $args;
652
    }
653
654
    /**
655
     * Support non-index pages such as modal forms.
656
     *
657
     * @param string $route
658
     * @param array  $parameters
659
     * @param int    $referenceType
660
     *
661
     * @return bool|string
662
     */
663
    public function generateUrl($route, $parameters = [], $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
664
    {
665
        if (!isset($parameters['object'])) {
666
            $parameters['object'] = $this->request->get('object', 'contacts');
667
        }
668
669
        return parent::generateUrl($route, $parameters, $referenceType);
670
    }
671
672
    protected function getObjectFromRequest()
673
    {
674
        $objectInRequest = $this->request->get('object');
675
676
        switch ($objectInRequest) {
677
            case 'companies':
678
                return 'company';
679
            case 'contacts':
680
            default:
681
                return 'lead';
682
        }
683
    }
684
685
    /**
686
     * {@inheritdoc}
687
     */
688
    protected function getModelName()
689
    {
690
        return 'lead.import';
691
    }
692
693
    /***
694
     * @param null $objectId
695
     *
696
     * @return string
697
     */
698
    protected function getSessionBase($objectId = null)
699
    {
700
        $object = $this->getObjectFromRequest();
701
702
        return $object.'.import'.(($objectId) ? '.'.$objectId : '');
0 ignored issues
show
$objectId is of type null, thus it always evaluated to false.
Loading history...
703
    }
704
705
    /**
706
     * {@inheritdoc}
707
     */
708
    protected function getPermissionBase()
709
    {
710
        return $this->getModel($this->getModelName())->getPermissionBase();
711
    }
712
713
    /**
714
     * {@inheritdoc}
715
     */
716
    protected function getRouteBase()
717
    {
718
        return 'import';
719
    }
720
721
    /**
722
     * {@inheritdoc}
723
     *
724
     * @return string
725
     */
726
    protected function getTemplateBase()
727
    {
728
        return 'MauticLeadBundle:Import';
729
    }
730
731
    /**
732
     * Provide the name of the column which is used for default ordering.
733
     *
734
     * @return string
735
     */
736
    protected function getDefaultOrderColumn()
737
    {
738
        return 'dateAdded';
739
    }
740
741
    /**
742
     * Provide the direction for default ordering.
743
     *
744
     * @return string
745
     */
746
    protected function getDefaultOrderDirection()
747
    {
748
        return 'DESC';
749
    }
750
}
751