Spaces:
No application file
No application file
| namespace Mautic\LeadBundle\Controller; | |
| use Doctrine\Persistence\ManagerRegistry; | |
| use Mautic\CoreBundle\Controller\FormController; | |
| use Mautic\CoreBundle\Factory\MauticFactory; | |
| use Mautic\CoreBundle\Factory\ModelFactory; | |
| use Mautic\CoreBundle\Helper\CoreParametersHelper; | |
| use Mautic\CoreBundle\Helper\CsvHelper; | |
| use Mautic\CoreBundle\Helper\UserHelper; | |
| use Mautic\CoreBundle\Security\Permissions\CorePermissions; | |
| use Mautic\CoreBundle\Service\FlashBag; | |
| use Mautic\CoreBundle\Translation\Translator; | |
| use Mautic\FormBundle\Helper\FormFieldHelper; | |
| use Mautic\LeadBundle\Entity\Import; | |
| use Mautic\LeadBundle\Event\ImportInitEvent; | |
| use Mautic\LeadBundle\Event\ImportMappingEvent; | |
| use Mautic\LeadBundle\Event\ImportValidateEvent; | |
| use Mautic\LeadBundle\Form\Type\LeadImportFieldType; | |
| use Mautic\LeadBundle\Form\Type\LeadImportType; | |
| use Mautic\LeadBundle\Helper\Progress; | |
| use Mautic\LeadBundle\LeadEvents; | |
| use Mautic\LeadBundle\Model\ImportModel; | |
| use Psr\Log\LoggerInterface; | |
| use Psr\Log\LogLevel; | |
| use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |
| use Symfony\Component\Filesystem\Filesystem; | |
| use Symfony\Component\Form\Exception\LogicException; | |
| use Symfony\Component\Form\Form; | |
| use Symfony\Component\Form\FormError; | |
| use Symfony\Component\Form\FormFactoryInterface; | |
| use Symfony\Component\Form\FormInterface; | |
| use Symfony\Component\HttpFoundation\File\Exception\FileException; | |
| use Symfony\Component\HttpFoundation\JsonResponse; | |
| use Symfony\Component\HttpFoundation\RedirectResponse; | |
| use Symfony\Component\HttpFoundation\Request; | |
| use Symfony\Component\HttpFoundation\RequestStack; | |
| use Symfony\Component\HttpFoundation\Response; | |
| use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |
| use Symfony\Component\Security\Core\Exception\AccessDeniedException; | |
| class ImportController extends FormController | |
| { | |
| // Steps of the import | |
| public const STEP_UPLOAD_CSV = 1; | |
| public const STEP_MATCH_FIELDS = 2; | |
| public const STEP_PROGRESS_BAR = 3; | |
| public const STEP_IMPORT_FROM_CSV = 4; | |
| private \Symfony\Component\HttpFoundation\Session\SessionInterface $session; | |
| private ImportModel $importModel; | |
| public function __construct( | |
| FormFactoryInterface $formFactory, | |
| FormFieldHelper $fieldHelper, | |
| private LoggerInterface $logger, | |
| ManagerRegistry $doctrine, | |
| MauticFactory $factory, | |
| ModelFactory $modelFactory, | |
| UserHelper $userHelper, | |
| CoreParametersHelper $coreParametersHelper, | |
| EventDispatcherInterface $dispatcher, | |
| Translator $translator, | |
| FlashBag $flashBag, | |
| RequestStack $requestStack, | |
| CorePermissions $security | |
| ) { | |
| /** @var ImportModel $model */ | |
| $model = $modelFactory->getModel($this->getModelName()); | |
| $this->session = $requestStack->getMainRequest()->getSession(); | |
| $this->importModel = $model; | |
| parent::__construct($formFactory, $fieldHelper, $doctrine, $factory, $modelFactory, $userHelper, $coreParametersHelper, $dispatcher, $translator, $flashBag, $requestStack, $security); | |
| } | |
| /** | |
| * @param int $page | |
| * | |
| * @return JsonResponse|RedirectResponse | |
| */ | |
| public function indexAction(Request $request, $page = 1): Response | |
| { | |
| $initEvent = $this->dispatchImportOnInit(); | |
| $this->session->set('mautic.import.object', $initEvent->objectSingular); | |
| return $this->indexStandard($request, $page); | |
| } | |
| /** | |
| * Get items for index list. | |
| * | |
| * @param int $start | |
| * @param int $limit | |
| * @param mixed[] $filter | |
| * @param string $orderBy | |
| * @param string $orderByDir | |
| * @param mixed[] $args | |
| */ | |
| protected function getIndexItems($start, $limit, $filter, $orderBy, $orderByDir, array $args = []): array | |
| { | |
| $object = $this->session->get('mautic.import.object'); | |
| $filter['force'][] = [ | |
| 'column' => $this->importModel->getRepository()->getTableAlias().'.object', | |
| 'expr' => 'eq', | |
| 'value' => $object, | |
| ]; | |
| $items = $this->importModel->getEntities( | |
| array_merge( | |
| [ | |
| 'start' => $start, | |
| 'limit' => $limit, | |
| 'filter' => $filter, | |
| 'orderBy' => $orderBy, | |
| 'orderByDir' => $orderByDir, | |
| ], | |
| $args | |
| ) | |
| ); | |
| $count = count($items); | |
| return [$count, $items]; | |
| } | |
| /** | |
| * @param int $objectId | |
| * | |
| * @return array|JsonResponse|RedirectResponse|Response | |
| */ | |
| public function viewAction(Request $request, $objectId) | |
| { | |
| return $this->viewStandard($request, $objectId, 'import', 'lead'); | |
| } | |
| /** | |
| * Cancel and unpublish the import during manual import. | |
| * | |
| * @return JsonResponse|RedirectResponse | |
| */ | |
| public function cancelAction(Request $request): Response | |
| { | |
| $initEvent = $this->dispatchImportOnInit(); | |
| $object = $initEvent->objectSingular; | |
| $fullPath = $this->getFullCsvPath($object); | |
| $import = $this->importModel->getEntity($this->session->get('mautic.lead.import.id', null)); | |
| if ($import && $import->getId()) { | |
| $import->setStatus($import::STOPPED) | |
| ->setIsPublished(false); | |
| $this->importModel->saveEntity($import); | |
| } | |
| $this->resetImport($object); | |
| $this->removeImportFile($fullPath); | |
| $this->logger->log(LogLevel::INFO, "Import for file {$fullPath} was canceled."); | |
| return $this->indexAction($request); | |
| } | |
| /** | |
| * Schedules manual import to background queue. | |
| */ | |
| public function queueAction(Request $request): Response | |
| { | |
| $initEvent = $this->dispatchImportOnInit(); | |
| $object = $initEvent->objectSingular; | |
| $fullPath = $this->getFullCsvPath($object); | |
| $import = $this->importModel->getEntity($this->session->get('mautic.lead.import.id', null)); | |
| if ($import) { | |
| $import->setStatus($import::QUEUED); | |
| $this->importModel->saveEntity($import); | |
| } | |
| $this->resetImport($object); | |
| $this->logger->log(LogLevel::INFO, "Import for file {$fullPath} moved to be processed in the background."); | |
| return $this->indexAction($request); | |
| } | |
| /** | |
| * @param int $objectId | |
| * @param bool $ignorePost | |
| */ | |
| public function newAction(Request $request, $objectId = 0, $ignorePost = false): Response | |
| { | |
| $dispatcher = $this->dispatcher; | |
| try { | |
| $initEvent = $this->dispatchImportOnInit(); | |
| } catch (AccessDeniedException $e) { | |
| return $this->accessDenied(); | |
| } | |
| if (!$initEvent->objectSupported) { | |
| return $this->notFound(); | |
| } | |
| $object = $initEvent->objectSingular; | |
| $this->session->set('mautic.import.object', $object); | |
| // Move the file to cache and rename it | |
| $forceStop = $request->get('cancel', false); | |
| $step = ($forceStop) ? self::STEP_UPLOAD_CSV : $this->session->get('mautic.'.$object.'.import.step', self::STEP_UPLOAD_CSV); | |
| $fileName = $this->getImportFileName($object); | |
| $importDir = $this->getImportDirName(); | |
| $fullPath = $this->getFullCsvPath($object); | |
| $fs = new Filesystem(); | |
| $complete = false; | |
| if (!file_exists($fullPath) && self::STEP_UPLOAD_CSV !== $step) { | |
| // Force step one if the file doesn't exist | |
| $this->logger->log(LogLevel::WARNING, "File {$fullPath} does not exist anymore. Reseting import to step STEP_UPLOAD_CSV."); | |
| $this->addFlashMessage('mautic.import.file.missing', ['%file%' => $this->getImportFileName($object)], FlashBag::LEVEL_ERROR); | |
| $step = self::STEP_UPLOAD_CSV; | |
| $this->session->set('mautic.'.$object.'.import.step', self::STEP_UPLOAD_CSV); | |
| } | |
| $progress = (new Progress())->bindArray($this->session->get('mautic.'.$object.'.import.progress', [0, 0])); | |
| $import = $this->importModel->getEntity(); | |
| $action = $this->generateUrl('mautic_import_action', ['object' => $request->get('object'), 'objectAction' => 'new']); | |
| switch ($step) { | |
| case self::STEP_UPLOAD_CSV: | |
| if ($forceStop) { | |
| $this->resetImport($object); | |
| $this->removeImportFile($fullPath); | |
| $this->logger->log(LogLevel::WARNING, "Import for file {$fullPath} was force-stopped."); | |
| } | |
| $form = $this->formFactory->create(LeadImportType::class, [], ['action' => $action]); | |
| break; | |
| case self::STEP_MATCH_FIELDS: | |
| $mappingEvent = $dispatcher->dispatch( | |
| new ImportMappingEvent($request->get('object')), | |
| LeadEvents::IMPORT_ON_FIELD_MAPPING | |
| ); | |
| try { | |
| $form = $this->formFactory->create( | |
| LeadImportFieldType::class, | |
| [], | |
| [ | |
| 'object' => $object, | |
| 'action' => $action, | |
| 'all_fields' => $mappingEvent->fields, | |
| 'import_fields' => $this->session->get('mautic.'.$object.'.import.importfields', []), | |
| 'line_count_limit' => $this->getLineCountLimit(), | |
| ] | |
| ); | |
| } catch (LogicException $e) { | |
| $this->resetImport($object); | |
| $this->removeImportFile($fullPath); | |
| $this->logger->log(LogLevel::INFO, "Import for file {$fullPath} failed with: {$e->getMessage()}."); | |
| return $this->newAction($request, 0, true); | |
| } | |
| break; | |
| case self::STEP_PROGRESS_BAR: | |
| // Just show the progress form | |
| $this->session->set('mautic.'.$object.'.import.step', self::STEP_IMPORT_FROM_CSV); | |
| break; | |
| case self::STEP_IMPORT_FROM_CSV: | |
| ignore_user_abort(true); | |
| $inProgress = $this->session->get('mautic.'.$object.'.import.inprogress', false); | |
| $checks = $this->session->get('mautic.'.$object.'.import.progresschecks', 1); | |
| if (!$inProgress || $checks > 5) { | |
| $this->session->set('mautic.'.$object.'.import.inprogress', true); | |
| $this->session->set('mautic.'.$object.'.import.progresschecks', 1); | |
| $import = $this->importModel->getEntity($this->session->get('mautic.'.$object.'.import.id', null)); | |
| if (!$import->getDateStarted()) { | |
| $import->setDateStarted(new \DateTime()); | |
| } | |
| $this->importModel->process($import, $progress); | |
| // Clear in progress | |
| if ($progress->isFinished()) { | |
| $import->setStatus($import::IMPORTED) | |
| ->setDateEnded(new \DateTime()); | |
| $this->resetImport($object); | |
| $this->removeImportFile($fullPath); | |
| $complete = true; | |
| } else { | |
| $complete = false; | |
| $this->session->set('mautic.'.$object.'.import.inprogress', false); | |
| $this->session->set('mautic.'.$object.'.import.progress', $progress->toArray()); | |
| } | |
| $this->importModel->saveEntity($import); | |
| break; | |
| } else { | |
| ++$checks; | |
| $this->session->set('mautic.'.$object.'.import.progresschecks', $checks); | |
| } | |
| } | |
| // /Check for a submitted form and process it | |
| if (!$ignorePost && 'POST' === $request->getMethod()) { | |
| if (!isset($form) || $this->isFormCancelled($form)) { | |
| $this->resetImport($object); | |
| $this->removeImportFile($fullPath); | |
| $reason = isset($form) ? 'the form is empty' : 'the form was canceled'; | |
| $this->logger->log(LogLevel::WARNING, "Import for file {$fullPath} was aborted because {$reason}."); | |
| return $this->newAction($request, 0, true); | |
| } | |
| $valid = $this->isFormValid($form); | |
| switch ($step) { | |
| case self::STEP_UPLOAD_CSV: | |
| if ($valid) { | |
| if (file_exists($fullPath)) { | |
| unlink($fullPath); | |
| } | |
| $fileData = $form['file']->getData(); | |
| if (!empty($fileData)) { | |
| $errorMessage = null; | |
| $errorParameters = []; | |
| try { | |
| // Create the import dir recursively | |
| $fs->mkdir($importDir); | |
| $fileData->move($importDir, $fileName); | |
| $file = new \SplFileObject($fullPath); | |
| $config = $form->getData(); | |
| unset($config['file']); | |
| unset($config['start']); | |
| foreach ($config as $key => &$c) { | |
| $c = htmlspecialchars_decode($c); | |
| if ('batchlimit' == $key) { | |
| $c = (int) $c; | |
| } | |
| } | |
| $this->session->set('mautic.'.$object.'.import.config', $config); | |
| if (false !== $file) { | |
| // Get the headers for matching | |
| $headers = $file->fgetcsv($config['delimiter'], $config['enclosure'], $config['escape']); | |
| // Get the number of lines so we can track progress | |
| $file->seek(PHP_INT_MAX); | |
| $linecount = $file->key(); | |
| if (!empty($headers) && is_array($headers)) { | |
| $headers = CsvHelper::sanitizeHeaders($headers); | |
| $this->session->set('mautic.'.$object.'.import.headers', $headers); | |
| $this->session->set('mautic.'.$object.'.import.step', self::STEP_MATCH_FIELDS); | |
| $this->session->set('mautic.'.$object.'.import.importfields', CsvHelper::convertHeadersIntoFields($headers)); | |
| $this->session->set('mautic.'.$object.'.import.progress', [0, $linecount]); | |
| $this->session->set('mautic.'.$object.'.import.original.file', $fileData->getClientOriginalName()); | |
| return $this->newAction($request, 0, true); | |
| } | |
| } | |
| } catch (FileException $e) { | |
| if (str_contains($e->getMessage(), 'upload_max_filesize')) { | |
| $errorMessage = 'mautic.lead.import.filetoolarge'; | |
| $errorParameters = [ | |
| '%upload_max_filesize%' => ini_get('upload_max_filesize'), | |
| ]; | |
| } else { | |
| $errorMessage = 'mautic.lead.import.filenotreadable'; | |
| } | |
| } catch (\Exception) { | |
| $errorMessage = 'mautic.lead.import.filenotreadable'; | |
| } finally { | |
| if (!is_null($errorMessage)) { | |
| $form->addError( | |
| new FormError( | |
| $this->translator->trans($errorMessage, $errorParameters, 'validators') | |
| ) | |
| ); | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case self::STEP_MATCH_FIELDS: | |
| $validateEvent = new ImportValidateEvent($request->get('object'), $form); | |
| $dispatcher->dispatch($validateEvent, LeadEvents::IMPORT_ON_VALIDATE); | |
| if ($validateEvent->hasErrors()) { | |
| break; | |
| } | |
| $matchedFields = $validateEvent->getMatchedFields(); | |
| if (empty($matchedFields)) { | |
| $this->resetImport($object); | |
| $this->removeImportFile($fullPath); | |
| $this->logger->log(LogLevel::WARNING, "Import for file {$fullPath} was aborted as there were no matched files found."); | |
| return $this->newAction($request, 0, true); | |
| } | |
| /** @var Import $import */ | |
| $import = $this->importModel->getEntity(); | |
| $import->setMatchedFields($matchedFields) | |
| ->setObject($object) | |
| ->setDir($importDir) | |
| ->setLineCount($this->getLineCount($object)) | |
| ->setFile($fileName) | |
| ->setOriginalFile($this->session->get('mautic.'.$object.'.import.original.file')) | |
| ->setDefault('owner', $validateEvent->getOwnerId()) | |
| ->setDefault('list', $validateEvent->getList()) | |
| ->setDefault('tags', $validateEvent->getTags()) | |
| ->setDefault('skip_if_exists', $validateEvent->getSkipIfExists()) | |
| ->setHeaders($this->session->get('mautic.'.$object.'.import.headers')) | |
| ->setParserConfig($this->session->get('mautic.'.$object.'.import.config')); | |
| // In case the user chose to import in browser | |
| if ($this->importInBrowser($form, $object)) { | |
| $import->setStatus($import::MANUAL); | |
| $this->session->set('mautic.'.$object.'.import.step', self::STEP_PROGRESS_BAR); | |
| } | |
| $this->importModel->saveEntity($import); | |
| $this->session->set('mautic.'.$object.'.import.id', $import->getId()); | |
| // In case the user decided to queue the import | |
| if ($this->importInCli($form, $object)) { | |
| $this->addFlashMessage('mautic.lead.batch.import.created'); | |
| $this->resetImport($object); | |
| return $this->indexAction($request); | |
| } | |
| return $this->newAction($request, 0, true); | |
| default: | |
| // Done or something wrong | |
| $this->resetImport($object); | |
| $this->removeImportFile($fullPath); | |
| $this->logger->log(LogLevel::ERROR, "Import for file {$fullPath} was aborted for unknown step of '{$step}'"); | |
| break; | |
| } | |
| } | |
| if (self::STEP_UPLOAD_CSV === $step || self::STEP_MATCH_FIELDS === $step) { | |
| $contentTemplate = '@MauticLead/Import/new.html.twig'; | |
| $viewParameters = [ | |
| 'form' => $form->createView(), | |
| 'objectName' => $initEvent->objectName, | |
| ]; | |
| } else { | |
| $contentTemplate = '@MauticLead/Import/progress.html.twig'; | |
| $viewParameters = [ | |
| 'progress' => $progress, | |
| 'import' => $import, | |
| 'complete' => $complete, | |
| 'failedRows' => $this->importModel->getFailedRows($import->getId(), $import->getObject()), | |
| 'objectName' => $initEvent->objectName, | |
| 'indexRoute' => $initEvent->indexRoute, | |
| 'indexRouteParams' => $initEvent->indexRouteParams, | |
| ]; | |
| } | |
| if (!$complete && $request->query->has('importbatch')) { | |
| // Ajax request to batch process so just return ajax response unless complete | |
| $response = new JsonResponse(['success' => 1, 'ignore_wdt' => 1]); | |
| } else { | |
| $viewParameters['step'] = $step; | |
| $response = $this->delegateView( | |
| [ | |
| 'viewParameters' => $viewParameters, | |
| 'contentTemplate' => $contentTemplate, | |
| 'passthroughVars' => [ | |
| 'activeLink' => $initEvent->activeLink, | |
| 'mauticContent' => 'leadImport', | |
| 'route' => $this->generateUrl( | |
| 'mautic_import_action', | |
| [ | |
| 'object' => $initEvent->routeObjectName, | |
| 'objectAction' => 'new', | |
| ] | |
| ), | |
| 'step' => $step, | |
| 'progress' => $progress, | |
| ], | |
| ] | |
| ); | |
| } | |
| // For uploading file Keep-Alive should not be used. | |
| $response->headers->set('Connection', 'close'); | |
| return $response; | |
| } | |
| /** | |
| * Returns line count from the session. | |
| * | |
| * @param string $object | |
| * | |
| * @return int | |
| */ | |
| protected function getLineCount($object) | |
| { | |
| $progress = $this->session->get('mautic.'.$object.'.import.progress', [0, 0]); | |
| return $progress[1] ?? 0; | |
| } | |
| /** | |
| * Decide whether the import will be processed in client's browser. | |
| * | |
| * @param FormInterface<mixed> $form | |
| * @param string $object | |
| */ | |
| protected function importInBrowser(FormInterface $form, $object): bool | |
| { | |
| $browserImportLimit = $this->getLineCountLimit(); | |
| if ($browserImportLimit && $this->getLineCount($object) < $browserImportLimit) { | |
| return true; | |
| } elseif (!$browserImportLimit && $this->getFormButton($form, ['buttons', 'save'])->isClicked()) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| protected function getLineCountLimit() | |
| { | |
| return $this->coreParametersHelper->get('background_import_if_more_rows_than', 0); | |
| } | |
| /** | |
| * Decide whether the import will be queued to be processed by the CLI command in the background. | |
| * | |
| * @param FormInterface<mixed> $form | |
| * @param string $object | |
| */ | |
| protected function importInCli(FormInterface $form, $object): bool | |
| { | |
| $browserImportLimit = $this->getLineCountLimit(); | |
| if ($browserImportLimit && $this->getLineCount($object) >= $browserImportLimit) { | |
| return true; | |
| } elseif (!$browserImportLimit && $this->getFormButton($form, ['buttons', 'apply'])->isClicked()) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| /** | |
| * Generates import directory path. | |
| */ | |
| protected function getImportDirName(): string | |
| { | |
| return $this->importModel->getImportDir(); | |
| } | |
| /** | |
| * Generates unique import directory name inside the cache dir if not stored in the session. | |
| * If it exists in the session, returns that one. | |
| * | |
| * @param string $object | |
| * | |
| * @return string | |
| */ | |
| protected function getImportFileName($object) | |
| { | |
| // Return the dir path from session if exists | |
| if ($fileName = $this->session->get('mautic.'.$object.'.import.file')) { | |
| return $fileName; | |
| } | |
| $fileName = $this->importModel->getUniqueFileName(); | |
| // Set the dir path to session | |
| $this->session->set('mautic.'.$object.'.import.file', $fileName); | |
| return $fileName; | |
| } | |
| /** | |
| * Return full absolute path to the CSV file. | |
| * | |
| * @param string $object | |
| */ | |
| protected function getFullCsvPath($object): string | |
| { | |
| return $this->getImportDirName().'/'.$this->getImportFileName($object); | |
| } | |
| private function resetImport(string $object): void | |
| { | |
| $this->session->set('mautic.'.$object.'.import.headers', []); | |
| $this->session->set('mautic.'.$object.'.import.file', null); | |
| $this->session->set('mautic.'.$object.'.import.step', self::STEP_UPLOAD_CSV); | |
| $this->session->set('mautic.'.$object.'.import.progress', [0, 0]); | |
| $this->session->set('mautic.'.$object.'.import.inprogress', false); | |
| $this->session->set('mautic.'.$object.'.import.importfields', []); | |
| $this->session->set('mautic.'.$object.'.import.original.file', null); | |
| $this->session->set('mautic.'.$object.'.import.id', null); | |
| } | |
| private function removeImportFile(string $filepath): void | |
| { | |
| if (file_exists($filepath) && is_readable($filepath)) { | |
| unlink($filepath); | |
| $this->logger->log(LogLevel::WARNING, "File {$filepath} was removed."); | |
| } | |
| } | |
| /** | |
| * @return mixed[] | |
| */ | |
| public function getViewArguments(array $args, $action): array | |
| { | |
| switch ($action) { | |
| case 'view': | |
| /** @var Import $entity */ | |
| $entity = $args['entity']; | |
| $args['viewParameters'] = array_merge( | |
| $args['viewParameters'], | |
| [ | |
| 'failedRows' => $this->importModel->getFailedRows($entity->getId(), $entity->getObject()), | |
| 'importedRowsChart' => $entity->getDateStarted() ? $this->importModel->getImportedRowsLineChartData( | |
| 'i', | |
| $entity->getDateStarted(), | |
| $entity->getDateEnded() ?: $entity->getDateModified(), | |
| null, | |
| [ | |
| 'object_id' => $entity->getId(), | |
| ] | |
| ) : [], | |
| ] | |
| ); | |
| break; | |
| } | |
| return $args; | |
| } | |
| /** | |
| * Support non-index pages such as modal forms. | |
| */ | |
| protected function generateUrl(string $route, array $parameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): string | |
| { | |
| if (!isset($parameters['object'])) { | |
| $request = $this->getCurrentRequest(); | |
| \assert(null !== $request); | |
| $parameters['object'] = $request->get('object', 'contacts'); | |
| } | |
| return parent::generateUrl($route, $parameters, $referenceType); | |
| } | |
| protected function getModelName(): string | |
| { | |
| return 'lead.import'; | |
| } | |
| protected function getSessionBase($objectId = null): string | |
| { | |
| $initEvent = $this->dispatchImportOnInit(); | |
| $object = $initEvent->objectSingular; | |
| return $object.'.import'.(($objectId) ? '.'.$objectId : ''); | |
| } | |
| protected function getPermissionBase() | |
| { | |
| return $this->getModel($this->getModelName())->getPermissionBase(); | |
| } | |
| protected function getRouteBase(): string | |
| { | |
| return 'import'; | |
| } | |
| protected function getTemplateBase(): string | |
| { | |
| return '@MauticLead/Import'; | |
| } | |
| /** | |
| * Provide the name of the column which is used for default ordering. | |
| */ | |
| protected function getDefaultOrderColumn(): string | |
| { | |
| return 'dateAdded'; | |
| } | |
| /** | |
| * Provide the direction for default ordering. | |
| */ | |
| protected function getDefaultOrderDirection(): string | |
| { | |
| return 'DESC'; | |
| } | |
| private function dispatchImportOnInit(): ImportInitEvent | |
| { | |
| $request = $this->getCurrentRequest(); | |
| \assert(null !== $request); | |
| $event = new ImportInitEvent($request->get('object')); | |
| $this->dispatcher->dispatch($event, LeadEvents::IMPORT_ON_INITIALIZE); | |
| return $event; | |
| } | |
| } | |