Refactor ImportExportController into two logical controllers

modifié:         core/lib/Thelia/Config/Resources/routing/admin.xml
	renommé:         core/lib/Thelia/Controller/Admin/ImportExportController.php -> core/lib/Thelia/Controller/Admin/ExportController.php
	nouveau fichier: core/lib/Thelia/Controller/Admin/ImportController.php
	modifié:         core/lib/Thelia/Core/DependencyInjection/Loader/XmlFileLoader.php
	nouveau fichier: core/lib/Thelia/Core/FileFormat/Archive/ArchiveBuilderManagerTrait.php
	nouveau fichier: core/lib/Thelia/Core/FileFormat/Formatting/FormatterManagerTrait.php
This commit is contained in:
Benjamin Perche
2014-07-17 14:43:44 +02:00
parent 03f1eb97e0
commit 069d2a07d9
7 changed files with 761 additions and 601 deletions

View File

@@ -1158,7 +1158,7 @@
<default key="_controller">Thelia\Controller\Admin\TranslationsController::updateAction</default> <default key="_controller">Thelia\Controller\Admin\TranslationsController::updateAction</default>
</route> </route>
<!-- import and export management --> <!-- export management -->
<route id="export.list" path="/admin/export"> <route id="export.list" path="/admin/export">
<default key="_controller">Thelia\Controller\Admin\ExportController::indexAction</default> <default key="_controller">Thelia\Controller\Admin\ExportController::indexAction</default>
@@ -1189,28 +1189,55 @@
</route> </route>
<route id="export.action" path="/admin/export/{id}" methods="post"> <route id="export.action" path="/admin/export/{id}" methods="post">
<default key="_controller">Thelia\Controller\Admin\ImportExportController::export</default> <default key="_controller">Thelia\Controller\Admin\ExportController::export</default>
<requirement key="id">\d+</requirement> <requirement key="id">\d+</requirement>
</route> </route>
<route id="export.view" path="/admin/export/{id}" methods="get"> <route id="export.view" path="/admin/export/{id}" methods="get">
<default key="_controller">Thelia\Controller\Admin\ImportExportController::exportView</default> <default key="_controller">Thelia\Controller\Admin\ExportController::exportView</default>
<requirement key="id">\d+</requirement> <requirement key="id">\d+</requirement>
</route> </route>
<!-- import management -->
<route id="import.list" path="/admin/import">
<default key="_controller">Thelia\Controller\Admin\ImportController::indexAction</default>
</route>
<route id="import.position" path="/admin/import/position/{action}/{id}">
<default key="_controller">Thelia\Controller\Admin\ImportController::changePosition</default>
<requirement key="action">up|down</requirement>
<requirement key="id">\d+</requirement>
</route>
<route id="import.position.update" path="/admin/import/position/update/{id}/{value}">
<default key="_controller">Thelia\Controller\Admin\ImportController::updatePosition</default>
<requirement key="id">\d+</requirement>
<requirement key="value">\d+</requirement>
</route>
<route id="import.category.position" path="/admin/import/position/category/{action}/{id}">
<default key="_controller">Thelia\Controller\Admin\ImportController::changeCategoryPosition</default>
<requirement key="action">up|down</requirement>
<requirement key="id">\d+</requirement>
</route>
<route id="import.category.position.update" path="/admin/import/position/category/update/{id}/{value}">
<default key="_controller">Thelia\Controller\Admin\ImportController::updateCategoryPosition</default>
<requirement key="id">\d+</requirement>
<requirement key="value">\d+</requirement>
</route>
<route id="import.action" path="/admin/import/{id}" methods="post"> <route id="import.action" path="/admin/import/{id}" methods="post">
<default key="_controller">Thelia\Controller\Admin\ImportExportController::import</default> <default key="_controller">Thelia\Controller\Admin\ImportController::import</default>
<requirement key="id">\d+</requirement> <requirement key="id">\d+</requirement>
</route> </route>
<route id="import.view" path="/admin/import/{id}" methods="get"> <route id="import.view" path="/admin/import/{id}" methods="get">
<default key="_controller">Thelia\Controller\Admin\ImportExportController::importView</default> <default key="_controller">Thelia\Controller\Admin\ImportController::importView</default>
<requirement key="id">\d+</requirement> <requirement key="id">\d+</requirement>
</route> </route>
<!-- Routes to the Brands controller --> <!-- Routes to the Brands controller -->
<route id="admin.brand.default" path="/admin/brand"> <route id="admin.brand.default" path="/admin/brand">

View File

@@ -12,9 +12,22 @@
namespace Thelia\Controller\Admin; namespace Thelia\Controller\Admin;
use Thelia\Core\FileFormat\Archive\ArchiveBuilderManagerTrait;
use Thelia\Core\FileFormat\Formatting\FormatterManagerTrait;
use Thelia\Core\Security\AccessManager; use Thelia\Core\Security\AccessManager;
use Thelia\Core\Security\Resource\AdminResources; use Thelia\Core\Security\Resource\AdminResources;
use Thelia\Core\Translation\Translator; use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Loop\Export as ExportLoop;
use Thelia\Core\Event\ImportExport as ImportExportEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\FileFormat\Archive\AbstractArchiveBuilder;
use Thelia\Core\FileFormat\Formatting\AbstractFormatter;
use Thelia\Core\HttpFoundation\Response;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Form\ExportForm;
use Thelia\ImportExport\Export\DocumentsExportInterface;
use Thelia\ImportExport\Export\ExportHandler;
use Thelia\ImportExport\Export\ImagesExportInterface;
use Thelia\Model\ExportCategoryQuery; use Thelia\Model\ExportCategoryQuery;
use Thelia\Model\ExportQuery; use Thelia\Model\ExportQuery;
@@ -25,6 +38,9 @@ use Thelia\Model\ExportQuery;
*/ */
class ExportController extends BaseAdminController class ExportController extends BaseAdminController
{ {
use ArchiveBuilderManagerTrait;
use FormatterManagerTrait;
public function indexAction() public function indexAction()
{ {
if (null !== $response = $this->checkAuth([AdminResources::EXPORT], [], [AccessManager::VIEW])) { if (null !== $response = $this->checkAuth([AdminResources::EXPORT], [], [AccessManager::VIEW])) {
@@ -36,6 +52,249 @@ class ExportController extends BaseAdminController
return $this->render('export'); return $this->render('export');
} }
/**
* @param integer $id
* @return Response
*
* This method is called when the route /admin/export/{id}
* is called with a POST request.
*/
public function export($id)
{
if (null === $export = $this->getExport($id)) {
return $this->render("404");
}
/**
* Get needed services
*/
$archiveBuilderManager = $this->getArchiveBuilderManager($this->container);
$formatterManager = $this->getFormatterManager($this->container);
/**
* Get the archive builders
*/
$archiveBuilders = [];
foreach ($archiveBuilderManager->getNames() as $archiveBuilder) {
$archiveBuilders[$archiveBuilder] = $archiveBuilder;
}
/**
* Define and validate the form
*/
$form = new ExportForm($this->getRequest());
$errorMessage = null;
try {
$boundForm = $this->validateForm($form);
$archiveBuilder = null;
/**
* Get the formatter and the archive builder if we have to compress the file(s)
*/
/** @var \Thelia\Core\FileFormat\Formatting\AbstractFormatter $formatter */
$formatter = $formatterManager->get(
$boundForm->get("formatter")->getData()
);
if ($boundForm->get("do_compress")->getData()) {
/** @var \Thelia\Core\FileFormat\Archive\ArchiveBuilderInterface $archiveBuilder */
$archiveBuilder = $archiveBuilderManager->get(
$boundForm->get("archive_builder")->getData()
);
}
/**
* Return the generated Response
*/
return $this->processExport(
$formatter,
$export->getHandleClassInstance($this->container),
$archiveBuilder,
$boundForm->get("images")->getData(),
$boundForm->get("documents")->getData()
);
} catch (FormValidationException $e) {
$errorMessage = $this->createStandardFormValidationErrorMessage($e);
} catch (\Exception $e) {
$errorMessage = $e->getMessage();
}
/**
* If has an error, display it
*/
if (null !== $errorMessage) {
$form->setErrorMessage($errorMessage);
$this->getParserContext()
->addForm($form)
->setGeneralError($errorMessage)
;
}
return $this->exportView($id);
}
/**
* @param AbstractFormatter $formatter
* @param ExportHandler $handler
* @param AbstractArchiveBuilder $archiveBuilder
* @param bool $includeImages
* @param bool $includeDocuments
* @return Response
*
* Processes an export by returning a response with the export's content.
*/
protected function processExport(
AbstractFormatter $formatter,
ExportHandler $handler,
AbstractArchiveBuilder $archiveBuilder = null,
$includeImages = false,
$includeDocuments = false
) {
/**
* Build an event containing the formatter and the handler.
* Used for specific configuration (e.g: XML node names)
*/
$data = $handler->buildFormatterData();
$event = new ImportExportEvent($formatter, $handler , $data);
$filename = $formatter::FILENAME . "." . $formatter->getExtension();
if ($archiveBuilder === null) {
$this->dispatch(TheliaEvents::BEFORE_EXPORT, $event);
$formattedContent = $formatter->encode($data);
return new Response(
$formattedContent,
200,
[
"Content-Type" => $formatter->getMimeType(),
"Content-Disposition" =>
"attachment; filename=\"" . $filename . "\"",
]
);
} else {
$event->setArchiveBuilder($archiveBuilder);
$this->dispatch(TheliaEvents::BEFORE_EXPORT, $event);
$formattedContent = $formatter->encode($data);
if ($includeImages && $handler instanceof ImagesExportInterface) {
$this->processExportImages($handler, $archiveBuilder);
}
if ($includeDocuments && $handler instanceof DocumentsExportInterface) {
$this->processExportDocuments($handler, $archiveBuilder);
}
$archiveBuilder->addFileFromString(
$formattedContent, $filename
);
return $archiveBuilder->buildArchiveResponse($formatter::FILENAME);
}
}
/**
* @param ImagesExportInterface $handler
* @param AbstractArchiveBuilder $archiveBuilder
*
* Procedure that add images in the export's archive
*/
protected function processExportImages(ImagesExportInterface $handler, AbstractArchiveBuilder $archiveBuilder)
{
foreach ($handler->getImagesPaths() as $name => $documentPath) {
$archiveBuilder->addFile(
$documentPath,
$handler::IMAGES_DIRECTORY,
is_integer($name) ? null : $name
);
}
}
/**
* @param DocumentsExportInterface $handler
* @param AbstractArchiveBuilder $archiveBuilder
*
* Procedure that add documents in the export's archive
*/
protected function processExportDocuments(DocumentsExportInterface $handler, AbstractArchiveBuilder $archiveBuilder)
{
foreach ($handler->getDocumentsPaths() as $name => $documentPath) {
$archiveBuilder->addFile(
$documentPath,
$handler::DOCUMENTS_DIRECTORY,
is_integer($name) ? null : $name
);
}
}
/**
* @param integer $id
* @return Response
*
* This method is called when the route /admin/export/{id}
* is called with a GET request.
*
* It returns a modal view if the request is an AJAX one,
* otherwise it generates a "normal" back-office page
*/
public function exportView($id)
{
if (null === $export = $this->getExport($id)) {
return $this->render("404");
}
/**
* Use the loop to inject the same vars in Smarty
*/
$loop = new ExportLoop($this->container);
$loop->initializeArgs([
"export" => $export->getId()
]);
$query = $loop->buildModelCriteria();
$result= $query->find();
$results = $loop->parseResults(
new LoopResult($result)
);
$parserContext = $this->getParserContext();
/** @var \Thelia\Core\Template\Element\LoopResultRow $row */
foreach ($results as $row) {
foreach ($row->getVarVal() as $name=>$value) {
$parserContext->set($name, $value);
}
}
/**
* Inject conditions in smarty,
* It is used to display or not the checkboxes "Include images"
* and "Include documents"
*/
$this->getParserContext()
->set("HAS_IMAGES", $export->hasImages($this->container))
->set("HAS_DOCUMENTS", $export->hasDocuments($this->container))
;
/** Then render the form */
if ($this->getRequest()->isXmlHttpRequest()) {
return $this->render("ajax/export-modal");
} else {
return $this->render("export-page");
}
}
public function changePosition($action, $id) public function changePosition($action, $id)
{ {
if (null !== $response = $this->checkAuth([AdminResources::EXPORT], [], [AccessManager::UPDATE])) { if (null !== $response = $this->checkAuth([AdminResources::EXPORT], [], [AccessManager::UPDATE])) {
@@ -129,7 +388,7 @@ class ExportController extends BaseAdminController
if (null === $export) { if (null === $export) {
throw new \ErrorException( throw new \ErrorException(
Translator::getInstance()->trans( $this->getTranslator()->trans(
"There is no id \"%id\" in the exports", "There is no id \"%id\" in the exports",
[ [
"%id" => $id "%id" => $id
@@ -147,7 +406,7 @@ class ExportController extends BaseAdminController
if (null === $category) { if (null === $category) {
throw new \ErrorException( throw new \ErrorException(
Translator::getInstance()->trans( $this->getTranslator()->trans(
"There is no id \"%id\" in the export categories", "There is no id \"%id\" in the export categories",
[ [
"%id" => $id "%id" => $id

View File

@@ -0,0 +1,402 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Controller\Admin;
use Thelia\Core\FileFormat\Archive\ArchiveBuilderManagerTrait;
use Thelia\Core\FileFormat\Formatting\FormatterManagerTrait;
use Thelia\Core\HttpFoundation\Response;
use Thelia\Core\Security\AccessManager;
use Thelia\Core\Security\Resource\AdminResources;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Loop\Import as ImportLoop;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Form\ImportForm;
use Thelia\Model\ImportCategoryQuery;
use Thelia\Model\ImportQuery;
/**
* Class ImportController
* @package Thelia\Controller\Admin
* @author Benjamin Perche <bperche@openstudio.fr>
*/
class ImportController extends BaseAdminController
{
use FormatterManagerTrait;
use ArchiveBuilderManagerTrait;
public function indexAction()
{
if (null !== $response = $this->checkAuth([AdminResources::IMPORT], [], [AccessManager::VIEW])) {
return $response;
}
$this->setOrders();
return $this->render('import');
}
/**
* @param integer $id
* @return Response
*
* This method is called when the route /admin/import/{id}
* is called with a POST request.
*/
public function import($id)
{
if (null === $import = $this->getImport($id)) {
return $this->render("404");
}
$archiveBuilderManager = $this->getArchiveBuilderManager($this->container);
$formatterManager = $this->getFormatterManager($this->container);
/**
* Get needed services
*/
$form = new ImportForm($this->getRequest());
$errorMessage = null;
$successMessage = null;
try {
$boundForm = $this->validateForm($form);
/** @var \Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $boundForm->get("file_upload")->getData();
/**
* We have to check the extension manually because of composed file formats as tar.gz or tar.bz2
*/
$name = $file->getClientOriginalName();
$nameLength = strlen($name);
$handler = $import->getHandleClassInstance($this->container);
$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 $format) {
$formatLength = strlen($format);
if ($nameLength >= $formatLength && substr($name, -$formatLength) === $formatLength) {
$uploadFormat = $format;
$flip = array_flip($format);
try {
$formatter = $formatterManager->get($flip[$format]);
} catch(\OutOfBoundsException $e) {}
try {
$archiveBuilder = $archiveBuilderManager->get($flip[$format]);
} 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 the file is an archive
*/
$archiveBuilder->loadArchive($file->getPathname());
$content = null;
/**
* TODO: HANDLE
*/
} elseif ($formatter !== null) {
/**
* If the file isn't
*/
$content = file_get_contents($file->getPathname());
} else {
throw new \ErrorException(
$this->getTranslator()->trans(
"There's a problem, the extension \"%ext\" has been found, ".
"but has no formatters nor archive builder",
[
"%ext" => $ext
]
)
);
}
$data = $formatter->decode($content);
// Dispatch event
$handler->retrieveFromFormatterData($data);
$successMessage = $this->getTranslator()->trans("Import successfully done");
} catch(FormValidationException $e) {
$errorMessage = $this->createStandardFormValidationErrorMessage($e);
} catch(\Exception $e) {
$errorMessage = $e->getMessage();
}
if ($successMessage !== null) {
$this->getParserContext()->set("success_message", $successMessage);
}
if ($errorMessage !== null) {
$form->setErrorMessage($errorMessage);
$this->getParserContext()
->addForm($form)
->setGeneralError($errorMessage)
;
}
return $this->importView($id);
}
/**
* @param integer $id
* @return Response
*
* This method is called when the route /admin/import/{id}
* is called with a GET request.
*
* It returns a modal view if the request is an AJAX one,
* otherwise it generates a "normal" back-office page
*/
public function importView($id)
{
if (null === $import = $this->getImport($id)) {
return $this->render("404");
}
/**
* Use the loop to inject the same vars in Smarty
*/
$loop = new ImportLoop($this->container);
$loop->initializeArgs([
"export" => $import->getId()
]);
$query = $loop->buildModelCriteria();
$result= $query->find();
$results = $loop->parseResults(
new LoopResult($result)
);
$parserContext = $this->getParserContext();
/** @var \Thelia\Core\Template\Element\LoopResultRow $row */
foreach ($results as $row) {
foreach ($row->getVarVal() as $name=>$value) {
$parserContext->set($name, $value);
}
}
/**
* Get allowed formats
*/
/** @var \Thelia\ImportExport\AbstractHandler $handler */
$handler = $import->getHandleClassInstance($this->container);
$types = $handler->getHandledTypes();
$formatterManager = $this->getFormatterManager($this->container);
$archiveBuilderManager = $this->getArchiveBuilderManager($this->container);
$formats =
$formatterManager->getExtensionsByTypes($types, true) +
$archiveBuilderManager->getExtensions(true)
;
/**
* Get allowed mime types (used for the "Search a file" window
*/
$mimeTypes =
$formatterManager->getMimeTypesByTypes($types) +
$archiveBuilderManager->getMimeTypes()
;
/**
* Inject them in smarty
*/
$parserContext
->set( "ALLOWED_MIME_TYPES", implode(",", $mimeTypes))
->set("ALLOWED_EXTENSIONS", implode(", ", $formats))
;
/** Then render the form */
if ($this->getRequest()->isXmlHttpRequest()) {
return $this->render("ajax/import-modal");
} else {
return $this->render("import-page");
}
}
protected function setOrders($category = null, $import = null)
{
if ($category === null) {
$category = $this->getRequest()->query->get("category_order", "manual");
}
if ($import === null) {
$import = $this->getRequest()->query->get("import_order", "manual");
}
$this->getParserContext()
->set("category_order", $category)
;
$this->getParserContext()
->set("import_order", $import)
;
}
public function changePosition($action, $id)
{
if (null !== $response = $this->checkAuth([AdminResources::IMPORT], [], [AccessManager::UPDATE])) {
return $response;
}
$import = $this->getImport($id);
if ($action === "up") {
$import->upPosition();
} elseif ($action === "down") {
$import->downPosition();
}
$this->setOrders(null, "manual");
return $this->render('import');
}
public function updatePosition($id, $value)
{
if (null !== $response = $this->checkAuth([AdminResources::IMPORT], [], [AccessManager::UPDATE])) {
return $response;
}
$import = $this->getImport($id);
$import->updatePosition($value);
$this->setOrders(null, "manual");
return $this->render('import');
}
public function changeCategoryPosition($action, $id)
{
if (null !== $response = $this->checkAuth([AdminResources::IMPORT], [], [AccessManager::UPDATE])) {
return $response;
}
$category = $this->getCategory($id);
if ($action === "up") {
$category->upPosition();
} elseif ($action === "down") {
$category->downPosition();
}
$this->setOrders("manual");
return $this->render('import');
}
public function updateCategoryPosition($id, $value)
{
if (null !== $response = $this->checkAuth([AdminResources::IMPORT], [], [AccessManager::UPDATE])) {
return $response;
}
$category = $this->getCategory($id);
$category->updatePosition($value);
$this->setOrders("manual");
return $this->render('import');
}
protected function getImport($id)
{
$import = ImportQuery::create()->findPk($id);
if (null === $import) {
throw new \ErrorException(
$this->getTranslator()->trans(
"There is no id \"%id\" in the imports",
[
"%id" => $id
]
)
);
}
return $import;
}
protected function getCategory($id)
{
$category = ImportCategoryQuery::create()->findPk($id);
if (null === $category) {
throw new \ErrorException(
$this->getTranslator()->trans(
"There is no id \"%id\" in the import categories",
[
"%id" => $id
]
)
);
}
return $category;
}
}

View File

@@ -1,554 +0,0 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Controller\Admin;
use Thelia\Core\Event\ImportExport as ImportExportEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\FileFormat\Archive\AbstractArchiveBuilder;
use Thelia\Core\FileFormat\Formatting\AbstractFormatter;
use Thelia\Core\HttpFoundation\Response;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Loop\ArchiveBuilder;
use Thelia\Core\Template\Loop\Export as ExportLoop;
use Thelia\Core\Template\Loop\Import as ImportLoop;
use Thelia\Core\Translation\Translator;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Form\ExportForm;
use Thelia\Form\ImportForm;
use Thelia\ImportExport\AbstractHandler;
use Thelia\ImportExport\Export\DocumentsExportInterface;
use Thelia\ImportExport\Export\ExportHandler;
use Thelia\ImportExport\Export\ImagesExportInterface;
use Thelia\Model\ExportQuery;
use Thelia\Model\ImportQuery;
/**
* Class ImportExportController
* @package Thelia\Controller\Admin
* @author Benjamin Perche <bperche@openstudio.fr>
*/
class ImportExportController extends BaseAdminController
{
/** @var \Thelia\Core\FileFormat\Archive\ArchiveBuilderManager */
protected $archiveBuilderManager;
/** @var \Thelia\Core\FileFormat\Formatting\FormatterManager */
protected $formatterManager;
public function hydrate()
{
$this->archiveBuilderManager = $this->container->get("thelia.manager.archive_builder_manager");
$this->formatterManager = $this->container->get("thelia.manager.formatter_manager");
}
/**
* @param integer $id
* @return Response
*
* This method is called when the route /admin/import/{id}
* is called with a POST request.
*/
public function import($id)
{
if (null === $import = $this->getImport($id)) {
return $this->render("404");
}
/**
* Get needed services
*/
$this->hydrate();
$form = new ImportForm($this->getRequest());
$errorMessage = null;
$successMessage = null;
try {
$boundForm = $this->validateForm($form);
/** @var \Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $boundForm->get("file_upload")->getData();
/**
* We have to check the extension manually because of composed file formats as tar.gz or tar.bz2
*/
$name = $file->getClientOriginalName();
$nameLength = strlen($name);
$handler = $import->getHandleClassInstance($this->container);
$types = $handler->getHandledTypes();
$formats =
$this->formatterManager->getExtensionsByTypes($types, true) +
$this->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 $format) {
$formatLength = strlen($format);
if ($nameLength >= $formatLength && substr($name, -$formatLength) === $formatLength) {
$uploadFormat = $format;
$flip = array_flip($format);
try {
$formatter = $this->formatterManager->get($flip[$format]);
} catch(\OutOfBoundsException $e) {}
try {
$archiveBuilder = $this->archiveBuilderManager->get($flip[$format]);
} 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 the file is an archive
*/
$archiveBuilder->loadArchive($file->getPathname());
$content = null;
/**
* TODO: HANDLE
*/
} elseif ($formatter !== null) {
/**
* If the file isn't
*/
$content = file_get_contents($file->getPathname());
} else {
throw new \ErrorException(
$this->getTranslator()->trans(
"There's a problem, the extension \"%ext\" has been found, ".
"but has no formatters nor archive builder",
[
"%ext" => $ext
]
)
);
}
$data = $formatter->decode($content);
// Dispatch event
$handler->retrieveFromFormatterData($data);
$successMessage = $this->getTranslator()->trans("Import successfully done");
} catch(FormValidationException $e) {
$errorMessage = $this->createStandardFormValidationErrorMessage($e);
} catch(\Exception $e) {
$errorMessage = $e->getMessage();
}
if ($successMessage !== null) {
$this->getParserContext()->set("success_message", $successMessage);
}
if ($errorMessage !== null) {
$form->setErrorMessage($errorMessage);
$this->getParserContext()
->addForm($form)
->setGeneralError($errorMessage)
;
}
return $this->importView($id);
}
/**
* @param integer $id
* @return Response
*
* This method is called when the route /admin/export/{id}
* is called with a POST request.
*/
public function export($id)
{
if (null === $export = $this->getExport($id)) {
return $this->render("404");
}
/**
* Get needed services
*/
$this->hydrate();
/**
* Get the archive builders
*/
$archiveBuilders = [];
foreach ($this->archiveBuilderManager->getNames() as $archiveBuilder) {
$archiveBuilders[$archiveBuilder] = $archiveBuilder;
}
/**
* Define and validate the form
*/
$form = new ExportForm($this->getRequest());
$errorMessage = null;
try {
$boundForm = $this->validateForm($form);
$archiveBuilder = null;
/**
* Get the formatter and the archive builder if we have to compress the file(s)
*/
/** @var \Thelia\Core\FileFormat\Formatting\AbstractFormatter $formatter */
$formatter = $this->formatterManager->get(
$boundForm->get("formatter")->getData()
);
if ($boundForm->get("do_compress")->getData()) {
/** @var \Thelia\Core\FileFormat\Archive\ArchiveBuilderInterface $archiveBuilder */
$archiveBuilder = $this->archiveBuilderManager->get(
$boundForm->get("archive_builder")->getData()
);
}
/**
* Return the generated Response
*/
return $this->processExport(
$formatter,
$export->getHandleClassInstance($this->container),
$archiveBuilder,
$boundForm->get("images")->getData(),
$boundForm->get("documents")->getData()
);
} catch (FormValidationException $e) {
$errorMessage = $this->createStandardFormValidationErrorMessage($e);
} catch (\Exception $e) {
$errorMessage = $e->getMessage();
}
/**
* If has an error, display it
*/
if (null !== $errorMessage) {
$form->setErrorMessage($errorMessage);
$this->getParserContext()
->addForm($form)
->setGeneralError($errorMessage)
;
}
return $this->exportView($id);
}
/**
* @param AbstractFormatter $formatter
* @param ExportHandler $handler
* @param AbstractArchiveBuilder $archiveBuilder
* @param bool $includeImages
* @param bool $includeDocuments
* @return Response
*
* Processes an export by returning a response with the export's content.
*/
protected function processExport(
AbstractFormatter $formatter,
ExportHandler $handler,
AbstractArchiveBuilder $archiveBuilder = null,
$includeImages = false,
$includeDocuments = false
) {
/**
* Build an event containing the formatter and the handler.
* Used for specific configuration (e.g: XML node names)
*/
$data = $handler->buildFormatterData();
$event = new ImportExportEvent($formatter, $handler , $data);
$filename = $formatter::FILENAME . "." . $formatter->getExtension();
if ($archiveBuilder === null) {
$this->dispatch(TheliaEvents::BEFORE_EXPORT, $event);
$formattedContent = $formatter->encode($data);
return new Response(
$formattedContent,
200,
[
"Content-Type" => $formatter->getMimeType(),
"Content-Disposition" =>
"attachment; filename=\"" . $filename . "\"",
]
);
} else {
$event->setArchiveBuilder($archiveBuilder);
$this->dispatch(TheliaEvents::BEFORE_EXPORT, $event);
$formattedContent = $formatter->encode($data);
if ($includeImages && $handler instanceof ImagesExportInterface) {
$this->processExportImages($handler, $archiveBuilder);
}
if ($includeDocuments && $handler instanceof DocumentsExportInterface) {
$this->processExportDocuments($handler, $archiveBuilder);
}
$archiveBuilder->addFileFromString(
$formattedContent, $filename
);
return $archiveBuilder->buildArchiveResponse($formatter::FILENAME);
}
}
/**
* @param ImagesExportInterface $handler
* @param AbstractArchiveBuilder $archiveBuilder
*
* Procedure that add images in the export's archive
*/
protected function processExportImages(ImagesExportInterface $handler, AbstractArchiveBuilder $archiveBuilder)
{
foreach ($handler->getImagesPaths() as $name => $documentPath) {
$archiveBuilder->addFile(
$documentPath,
$handler::IMAGES_DIRECTORY,
is_integer($name) ? null : $name
);
}
}
/**
* @param DocumentsExportInterface $handler
* @param AbstractArchiveBuilder $archiveBuilder
*
* Procedure that add documents in the export's archive
*/
protected function processExportDocuments(DocumentsExportInterface $handler, AbstractArchiveBuilder $archiveBuilder)
{
foreach ($handler->getDocumentsPaths() as $name => $documentPath) {
$archiveBuilder->addFile(
$documentPath,
$handler::DOCUMENTS_DIRECTORY,
is_integer($name) ? null : $name
);
}
}
/**
* @param integer $id
* @return Response
*
* This method is called when the route /admin/import/{id}
* is called with a GET request.
*
* It returns a modal view if the request is an AJAX one,
* otherwise it generates a "normal" back-office page
*/
public function importView($id)
{
if (null === $import = $this->getImport($id)) {
return $this->render("404");
}
/**
* Use the loop to inject the same vars in Smarty
*/
$loop = new ImportLoop($this->container);
$loop->initializeArgs([
"export" => $import->getId()
]);
$query = $loop->buildModelCriteria();
$result= $query->find();
$results = $loop->parseResults(
new LoopResult($result)
);
$parserContext = $this->getParserContext();
/** @var \Thelia\Core\Template\Element\LoopResultRow $row */
foreach ($results as $row) {
foreach ($row->getVarVal() as $name=>$value) {
$parserContext->set($name, $value);
}
}
/**
* Get allowed formats
*/
/** @var \Thelia\ImportExport\AbstractHandler $handler */
$this->hydrate();
$handler = $import->getHandleClassInstance($this->container);
$types = $handler->getHandledTypes();
$formats =
$this->formatterManager->getExtensionsByTypes($types, true) +
$this->archiveBuilderManager->getExtensions(true)
;
/**
* Get allowed mime types (used for the "Search a file" window
*/
$mimeTypes =
$this->formatterManager->getMimeTypesByTypes($types) +
$this->archiveBuilderManager->getMimeTypes()
;
/**
* Inject them in smarty
*/
$parserContext
->set( "ALLOWED_MIME_TYPES", implode(",", $mimeTypes))
->set("ALLOWED_EXTENSIONS", implode(", ", $formats))
;
/** Then render the form */
if ($this->getRequest()->isXmlHttpRequest()) {
return $this->render("ajax/import-modal");
} else {
return $this->render("import-page");
}
}
/**
* @param integer $id
* @return Response
*
* This method is called when the route /admin/export/{id}
* is called with a GET request.
*
* It returns a modal view if the request is an AJAX one,
* otherwise it generates a "normal" back-office page
*/
public function exportView($id)
{
if (null === $export = $this->getExport($id)) {
return $this->render("404");
}
/**
* Use the loop to inject the same vars in Smarty
*/
$loop = new ExportLoop($this->container);
$loop->initializeArgs([
"export" => $export->getId()
]);
$query = $loop->buildModelCriteria();
$result= $query->find();
$results = $loop->parseResults(
new LoopResult($result)
);
$parserContext = $this->getParserContext();
/** @var \Thelia\Core\Template\Element\LoopResultRow $row */
foreach ($results as $row) {
foreach ($row->getVarVal() as $name=>$value) {
$parserContext->set($name, $value);
}
}
/**
* Inject conditions in smarty,
* It is used to display or not the checkboxes "Include images"
* and "Include documents"
*/
$this->getParserContext()
->set("HAS_IMAGES", $export->hasImages($this->container))
->set("HAS_DOCUMENTS", $export->hasDocuments($this->container))
;
/** Then render the form */
if ($this->getRequest()->isXmlHttpRequest()) {
return $this->render("ajax/export-modal");
} else {
return $this->render("export-page");
}
}
/**
* @param $id
* @return array|mixed|\Thelia\Model\Export
*
* This method is a shortcut to get an export model
*/
protected function getExport($id)
{
$export = ExportQuery::create()
->findPk($id)
;
return $export;
}
/**
* @param $id
* @return array|mixed|\Thelia\Model\Import
*
* This method is a shortcut to get an import model
*/
protected function getImport($id)
{
$export = ImportQuery::create()
->findPk($id)
;
return $export;
}
}

View File

@@ -311,7 +311,6 @@ class XmlFileLoader extends FileLoader
$con->beginTransaction(); $con->beginTransaction();
try { try {
$refs = [];
/** @var SimpleXMLElement $exportCategory */ /** @var SimpleXMLElement $exportCategory */
foreach ($exportCategories as $exportCategory) { foreach ($exportCategories as $exportCategory) {
$id = (string) $exportCategory->getAttributeAsPhp("id"); $id = (string) $exportCategory->getAttributeAsPhp("id");
@@ -338,16 +337,8 @@ class XmlFileLoader extends FileLoader
->save($con); ->save($con);
; ;
} }
$refs[] = $id;
} }
ExportCategoryQuery::create()
->filterByRef($refs, Criteria::NOT_IN)
->find()
->delete()
;
$con->commit(); $con->commit();
} catch (\Exception $e) { } catch (\Exception $e) {
$con->rollBack(); $con->rollBack();
@@ -366,7 +357,6 @@ class XmlFileLoader extends FileLoader
$con->beginTransaction(); $con->beginTransaction();
try { try {
$refs = [];
/** @var SimpleXMLElement $export */ /** @var SimpleXMLElement $export */
foreach ($exports as $export) { foreach ($exports as $export) {
@@ -453,16 +443,8 @@ class XmlFileLoader extends FileLoader
->save($con) ->save($con)
; ;
} }
$refs[] = $id;
} }
ExportQuery::create()
->filterByRef($refs, Criteria::NOT_IN)
->find()
->delete()
;
$con->commit(); $con->commit();
} catch (\Exception $e) { } catch (\Exception $e) {
$con->rollBack(); $con->rollBack();
@@ -481,7 +463,6 @@ class XmlFileLoader extends FileLoader
$con->beginTransaction(); $con->beginTransaction();
try { try {
$refs = [];
/** @var SimpleXMLElement $importCategory */ /** @var SimpleXMLElement $importCategory */
foreach ($importCategories as $importCategory) { foreach ($importCategories as $importCategory) {
@@ -510,15 +491,8 @@ class XmlFileLoader extends FileLoader
; ;
} }
$refs[] = $id;
} }
ImportCategoryQuery::create()
->filterByRef($refs, Criteria::NOT_IN)
->find()
->delete()
;
$con->commit(); $con->commit();
} catch (\Exception $e) { } catch (\Exception $e) {
$con->rollBack(); $con->rollBack();
@@ -537,8 +511,6 @@ class XmlFileLoader extends FileLoader
$con->beginTransaction(); $con->beginTransaction();
try { try {
$refs = [];
/** @var SimpleXMLElement $import */ /** @var SimpleXMLElement $import */
foreach ($imports as $import) { foreach ($imports as $import) {
$id = (string) $import->getAttributeAsPhp("id"); $id = (string) $import->getAttributeAsPhp("id");
@@ -624,16 +596,8 @@ class XmlFileLoader extends FileLoader
->save($con) ->save($con)
; ;
} }
$refs[] = $id;
} }
ImportQuery::create()
->filterByRef($refs, Criteria::NOT_IN)
->find()
->delete()
;
$con->commit(); $con->commit();
} catch (\Exception $e) { } catch (\Exception $e) {
$con->rollBack(); $con->rollBack();

View File

@@ -0,0 +1,31 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Core\FileFormat\Archive;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Trait ArchiveBuilderManagerTrait
* @package Thelia\Core\FileFormat\Archive
* @author Benjamin Perche <bperche@openstudio.fr>
*/
trait ArchiveBuilderManagerTrait
{
/**
* @param ContainerInterface $container
* @return \Thelia\Core\FileFormat\Archive\ArchiveBuilderManager
*/
public function getArchiveBuilderManager(ContainerInterface $container)
{
return $container->get("thelia.manager.archive_builder_manager");
}
}

View File

@@ -0,0 +1,31 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Core\FileFormat\Formatting;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Trait FormatterManagerTrait
* @package Thelia\Core\FileFormat\Formatter
* @author Benjamin Perche <bperche@openstudio.fr>
*/
trait FormatterManagerTrait
{
/**
* @param ContainerInterface $container
* @return \Thelia\Core\FileFormat\Formatting\FormatterManager
*/
public function getFormatterManager(ContainerInterface $container)
{
return $container->get("thelia.manager.formatter_manager");
}
}