Refactor ImportController::import method

modifié:         core/lib/Thelia/Controller/Admin/ImportController.php
This commit is contained in:
Benjamin Perche
2014-07-18 14:20:38 +02:00
parent b6c9a7dab4
commit 4c165bc5d5

View File

@@ -13,7 +13,11 @@
namespace Thelia\Controller\Admin; namespace Thelia\Controller\Admin;
use Thelia\Core\Event\ImportExport as ImportExportEvent; use Thelia\Core\Event\ImportExport as ImportExportEvent;
use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\FileFormat\Archive\AbstractArchiveBuilder;
use Thelia\Core\FileFormat\Archive\ArchiveBuilderManager;
use Thelia\Core\FileFormat\Archive\ArchiveBuilderManagerTrait; use Thelia\Core\FileFormat\Archive\ArchiveBuilderManagerTrait;
use Thelia\Core\FileFormat\Formatting\AbstractFormatter;
use Thelia\Core\FileFormat\Formatting\FormatterManager;
use Thelia\Core\FileFormat\Formatting\FormatterManagerTrait; use Thelia\Core\FileFormat\Formatting\FormatterManagerTrait;
use Thelia\Core\HttpFoundation\Response; use Thelia\Core\HttpFoundation\Response;
use Thelia\Core\Security\AccessManager; use Thelia\Core\Security\AccessManager;
@@ -22,6 +26,7 @@ use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Loop\Import as ImportLoop; use Thelia\Core\Template\Loop\Import as ImportLoop;
use Thelia\Form\Exception\FormValidationException; use Thelia\Form\Exception\FormValidationException;
use Thelia\Form\ImportForm; use Thelia\Form\ImportForm;
use Thelia\ImportExport\Import\ImportHandler;
use Thelia\Model\ImportCategoryQuery; use Thelia\Model\ImportCategoryQuery;
use Thelia\Model\ImportQuery; use Thelia\Model\ImportQuery;
@@ -61,6 +66,7 @@ class ImportController extends BaseAdminController
$archiveBuilderManager = $this->getArchiveBuilderManager($this->container); $archiveBuilderManager = $this->getArchiveBuilderManager($this->container);
$formatterManager = $this->getFormatterManager($this->container); $formatterManager = $this->getFormatterManager($this->container);
$handler = $import->getHandleClassInstance($this->container);
/** /**
* Get needed services * Get needed services
@@ -80,96 +86,32 @@ class ImportController extends BaseAdminController
* We have to check the extension manually because of composed file formats as tar.gz or tar.bz2 * We have to check the extension manually because of composed file formats as tar.gz or tar.bz2
*/ */
$name = $file->getClientOriginalName(); $name = $file->getClientOriginalName();
$nameLength = strlen($name);
$tools = $this->retrieveFormatTools(
$name,
$handler,
$formatterManager,
$archiveBuilderManager
);
$handler = $import->getHandleClassInstance($this->container); /** @var AbstractArchiveBuilder $archiveBuilder */
$types = $handler->getHandledTypes(); $archiveBuilder = $tools["archive_builder"];
$formats = /** @var AbstractFormatter $formatter */
$formatterManager->getExtensionsByTypes($types, true) + $formatter = $tools["formatter"];
$archiveBuilderManager->getExtensions(true)
;
$uploadFormat = null;
/** @var \Thelia\Core\FileFormat\Formatting\AbstractFormatter $formatter */
$formatter = null;
/** @var \Thelia\Core\FileFormat\Archive\AbstractArchiveBuilder $archiveBuilder */
$archiveBuilder = null;
foreach ($formats as $objectName => $format) {
$formatLength = strlen($format);
$formatExtension = substr($name, -$formatLength);
if ($nameLength >= $formatLength && $formatExtension === $format) {
$uploadFormat = $format;
try {
$formatter = $formatterManager->get($objectName);
} catch(\OutOfBoundsException $e) {}
try {
$archiveBuilder = $archiveBuilderManager->get($objectName);
} catch(\OutOfBoundsException $e) {}
break;
}
}
$splitName = explode(".", $name);
$ext = "";
if (1 < $limit = count($splitName)) {
$ext = "." . $splitName[$limit-1];
}
if ($uploadFormat === null) {
throw new FormValidationException(
$this->getTranslator()->trans(
"The extension \"%ext\" is not allowed",
[
"%ext" => $ext
]
)
);
}
if ($archiveBuilder !== null) { if ($archiveBuilder !== null) {
/** /**
* If the file is an archive * If the file is an archive, load it and try to find the file.
*/ */
$archiveBuilder = $archiveBuilder->loadArchive($file->getPathname()); $archiveBuilder = $archiveBuilder->loadArchive($file->getPathname());
$content = null;
/** $content = $this->getFileContentInArchive(
* Check expected file names for each formatter $archiveBuilder,
*/ $formatterManager,
$tools["types"]
$fileNames = []; );
/** @var \Thelia\Core\FileFormat\Formatting\AbstractFormatter $formatter */
foreach ($formatterManager->getFormattersByTypes($types) as $formatter) {
$fileName = $formatter::FILENAME . "." . $formatter->getExtension();
$fileNames[] = $fileName;
if ($archiveBuilder->hasFile($fileName)) {
$content = $archiveBuilder->getFileContent($fileName);
break;
}
}
if ($content === null) {
throw new \ErrorException(
$this->getTranslator()->trans(
"Your archive must contain one of these file and doesn't: %files",
[
"%files" => implode(", ", $fileNames),
]
)
);
}
} elseif ($formatter !== null) { } elseif ($formatter !== null) {
/** /**
* If the file isn't an archive * If the file isn't an archive
@@ -182,36 +124,21 @@ class ImportController extends BaseAdminController
"There's a problem, the extension \"%ext\" has been found, ". "There's a problem, the extension \"%ext\" has been found, ".
"but has no formatters nor archive builder", "but has no formatters nor archive builder",
[ [
"%ext" => $ext "%ext" => $tools["extension"],
] ]
) )
); );
} }
$event = new ImportExportEvent($formatter, $handler, null, $archiveBuilder); /**
$event->setContent($content); * Process the import: dispatch events, format the file content and let the handler do it's job.
*/
$this->dispatch(TheliaEvents::IMPORT_AFTER_DECODE, $event); $successMessage = $this->processImport(
$content,
$data = $formatter->decode($event->getContent()); $handler,
$formatter,
$event->setContent(null)->setData($data); $archiveBuilder
$this->dispatch(TheliaEvents::IMPORT_AFTER_DECODE, $event); );
$errors = $handler->retrieveFromFormatterData($data);
if (!empty($errors)) {
throw new \Exception(
$this->getTranslator()->trans(
"Errors occurred while importing the file: %errors",
[
"%errors" => implode(", ", $errors),
]
)
);
}
$successMessage = $this->getTranslator()->trans("Import successfully done");
} catch(FormValidationException $e) { } catch(FormValidationException $e) {
$errorMessage = $this->createStandardFormValidationErrorMessage($e); $errorMessage = $this->createStandardFormValidationErrorMessage($e);
@@ -235,6 +162,149 @@ class ImportController extends BaseAdminController
return $this->importView($id); return $this->importView($id);
} }
protected function getFileContentInArchive(
AbstractArchiveBuilder $archiveBuilder,
FormatterManager $formatterManager,
array $types
) {
$content = null;
/**
* Check expected file names for each formatter
*/
$fileNames = [];
/** @var \Thelia\Core\FileFormat\Formatting\AbstractFormatter $formatter */
foreach ($formatterManager->getFormattersByTypes($types) as $formatter) {
$fileName = $formatter::FILENAME . "." . $formatter->getExtension();
$fileNames[] = $fileName;
if ($archiveBuilder->hasFile($fileName)) {
$content = $archiveBuilder->getFileContent($fileName);
break;
}
}
if ($content === null) {
throw new \ErrorException(
$this->getTranslator()->trans(
"Your archive must contain one of these file and doesn't: %files",
[
"%files" => implode(", ", $fileNames),
]
)
);
}
return $content;
}
protected function retrieveFormatTools(
$fileName,
ImportHandler $handler,
FormatterManager $formatterManager,
ArchiveBuilderManager $archiveBuilderManager
) {
$nameLength = strlen($fileName);
$types = $handler->getHandledTypes();
$formats =
$formatterManager->getExtensionsByTypes($types, true) +
$archiveBuilderManager->getExtensions(true)
;
$uploadFormat = null;
/** @var \Thelia\Core\FileFormat\Formatting\AbstractFormatter $formatter */
$formatter = null;
/** @var \Thelia\Core\FileFormat\Archive\AbstractArchiveBuilder $archiveBuilder */
$archiveBuilder = null;
foreach ($formats as $objectName => $format) {
$formatLength = strlen($format);
$formatExtension = substr($fileName, -$formatLength);
if ($nameLength >= $formatLength && $formatExtension === $format) {
$uploadFormat = $format;
try {
$formatter = $formatterManager->get($objectName);
} catch(\OutOfBoundsException $e) {}
try {
$archiveBuilder = $archiveBuilderManager->get($objectName);
} catch(\OutOfBoundsException $e) {}
break;
}
}
$this->checkFileExtension($fileName, $uploadFormat);
return array(
"formatter" => $formatter,
"archive_builder" => $archiveBuilder,
"extension" => $uploadFormat,
"types" => $types,
);
}
protected function checkFileExtension($fileName, $uploadFormat)
{
$splitName = explode(".", $fileName);
$ext = "";
if (1 < $limit = count($splitName)) {
$ext = "." . $splitName[$limit-1];
}
if ($uploadFormat === null) {
throw new FormValidationException(
$this->getTranslator()->trans(
"The extension \"%ext\" is not allowed",
[
"%ext" => $ext
]
)
);
}
}
protected function processImport(
$content,
ImportHandler $handler,
AbstractFormatter $formatter = null,
AbstractArchiveBuilder $archiveBuilder = null
) {
$event = new ImportExportEvent($formatter, $handler, null, $archiveBuilder);
$event->setContent($content);
$this->dispatch(TheliaEvents::IMPORT_AFTER_DECODE, $event);
$data = $formatter->decode($event->getContent());
$event->setContent(null)->setData($data);
$this->dispatch(TheliaEvents::IMPORT_AFTER_DECODE, $event);
$errors = $handler->retrieveFromFormatterData($data);
if (!empty($errors)) {
throw new \Exception(
$this->getTranslator()->trans(
"Errors occurred while importing the file: %errors",
[
"%errors" => implode(", ", $errors),
]
)
);
}
return $this->getTranslator()->trans("Import successfully done");
}
/** /**
* @param integer $id * @param integer $id
@@ -304,7 +374,7 @@ class ImportController extends BaseAdminController
* Inject them in smarty * Inject them in smarty
*/ */
$parserContext $parserContext
->set( "ALLOWED_MIME_TYPES", implode(",", $mimeTypes)) ->set("ALLOWED_MIME_TYPES", implode(",", $mimeTypes))
->set("ALLOWED_EXTENSIONS", implode(", ", $formats)) ->set("ALLOWED_EXTENSIONS", implode(", ", $formats))
; ;