Working import stock

modifié:         core/lib/Thelia/Controller/Admin/ExportController.php
	modifié:         core/lib/Thelia/Controller/Admin/ImportController.php
	modifié:         core/lib/Thelia/Core/Event/ImportExport.php
	modifié:         core/lib/Thelia/Core/Event/TheliaEvents.php
	modifié:         core/lib/Thelia/Core/FileFormat/Formatting/AbstractFormatter.php
	modifié:         core/lib/Thelia/Core/FileFormat/Formatting/Formatter/JsonFormatter.php
	modifié:         core/lib/Thelia/Core/FileFormat/Formatting/FormatterData.php
	modifié:         core/lib/Thelia/ImportExport/Import/Type/ProductStockImport.php
	modifié:         templates/backOffice/default/ajax/import-modal.html
	modifié:         templates/backOffice/default/import-page.html
This commit is contained in:
Benjamin Perche
2014-07-17 17:00:53 +02:00
parent 069d2a07d9
commit cb75c13716
10 changed files with 131 additions and 50 deletions

View File

@@ -166,12 +166,14 @@ class ExportController extends BaseAdminController
$filename = $formatter::FILENAME . "." . $formatter->getExtension(); $filename = $formatter::FILENAME . "." . $formatter->getExtension();
if ($archiveBuilder === null) { if ($archiveBuilder === null) {
$this->dispatch(TheliaEvents::BEFORE_EXPORT, $event); $this->dispatch(TheliaEvents::EXPORT_BEFORE_ENCODE, $event);
$formattedContent = $formatter->encode($data); $formattedContent = $formatter->encode($data);
$this->dispatch(TheliaEvents::EXPORT_AFTER_ENCODE, $event->setContent($formattedContent));
return new Response( return new Response(
$formattedContent, $event->getContent(),
200, 200,
[ [
"Content-Type" => $formatter->getMimeType(), "Content-Type" => $formatter->getMimeType(),
@@ -181,10 +183,12 @@ class ExportController extends BaseAdminController
); );
} else { } else {
$event->setArchiveBuilder($archiveBuilder); $event->setArchiveBuilder($archiveBuilder);
$this->dispatch(TheliaEvents::BEFORE_EXPORT, $event); $this->dispatch(TheliaEvents::EXPORT_BEFORE_ENCODE, $event);
$formattedContent = $formatter->encode($data); $formattedContent = $formatter->encode($data);
$this->dispatch(TheliaEvents::EXPORT_AFTER_ENCODE, $event->setContent($formattedContent));
if ($includeImages && $handler instanceof ImagesExportInterface) { if ($includeImages && $handler instanceof ImagesExportInterface) {
$this->processExportImages($handler, $archiveBuilder); $this->processExportImages($handler, $archiveBuilder);
} }
@@ -194,7 +198,7 @@ class ExportController extends BaseAdminController
} }
$archiveBuilder->addFileFromString( $archiveBuilder->addFileFromString(
$formattedContent, $filename $event->getContent(), $filename
); );
return $archiveBuilder->buildArchiveResponse($formatter::FILENAME); return $archiveBuilder->buildArchiveResponse($formatter::FILENAME);

View File

@@ -11,6 +11,8 @@
/*************************************************************************************/ /*************************************************************************************/
namespace Thelia\Controller\Admin; namespace Thelia\Controller\Admin;
use Thelia\Core\Event\ImportExport as ImportExportEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\FileFormat\Archive\ArchiveBuilderManagerTrait; use Thelia\Core\FileFormat\Archive\ArchiveBuilderManagerTrait;
use Thelia\Core\FileFormat\Formatting\FormatterManagerTrait; use Thelia\Core\FileFormat\Formatting\FormatterManagerTrait;
use Thelia\Core\HttpFoundation\Response; use Thelia\Core\HttpFoundation\Response;
@@ -97,19 +99,20 @@ class ImportController extends BaseAdminController
/** @var \Thelia\Core\FileFormat\Archive\AbstractArchiveBuilder $archiveBuilder */ /** @var \Thelia\Core\FileFormat\Archive\AbstractArchiveBuilder $archiveBuilder */
$archiveBuilder = null; $archiveBuilder = null;
foreach ($formats as $format) { foreach ($formats as $objectName => $format) {
$formatLength = strlen($format); $formatLength = strlen($format);
if ($nameLength >= $formatLength && substr($name, -$formatLength) === $formatLength) { $formatExtension = substr($name, -$formatLength);
if ($nameLength >= $formatLength && $formatExtension === $format) {
$uploadFormat = $format; $uploadFormat = $format;
$flip = array_flip($format);
try { try {
$formatter = $formatterManager->get($flip[$format]); $formatter = $formatterManager->get($objectName);
} catch(\OutOfBoundsException $e) {} } catch(\OutOfBoundsException $e) {}
try { try {
$archiveBuilder = $archiveBuilderManager->get($flip[$format]); $archiveBuilder = $archiveBuilderManager->get($objectName);
} catch(\OutOfBoundsException $e) {} } catch(\OutOfBoundsException $e) {}
break; break;
@@ -124,8 +127,6 @@ class ImportController extends BaseAdminController
} }
if ($uploadFormat === null) { if ($uploadFormat === null) {
throw new FormValidationException( throw new FormValidationException(
$this->getTranslator()->trans( $this->getTranslator()->trans(
"The extension \"%ext\" is not allowed", "The extension \"%ext\" is not allowed",
@@ -144,14 +145,35 @@ class ImportController extends BaseAdminController
$content = null; $content = null;
/** /**
* TODO: HANDLE * 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),
]
)
);
}
} elseif ($formatter !== null) { } elseif ($formatter !== null) {
/** /**
* If the file isn't * If the file isn't an archive
*/ */
$content = file_get_contents($file->getPathname()); $content = file_get_contents($file->getPathname());
} else { } else {
@@ -166,11 +188,28 @@ class ImportController extends BaseAdminController
); );
} }
$event = new ImportExportEvent($formatter, $handler, null, $archiveBuilder);
$event->setContent($content);
$this->dispatch(TheliaEvents::IMPORT_AFTER_DECODE, $event);
$data = $formatter->decode($content); $data = $formatter->decode($content);
// Dispatch event $event->setContent(null)->setData($data);
$this->dispatch(TheliaEvents::IMPORT_AFTER_DECODE, $event);
$handler->retrieveFromFormatterData($data); $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"); $successMessage = $this->getTranslator()->trans("Import successfully done");

View File

@@ -11,10 +11,10 @@
/*************************************************************************************/ /*************************************************************************************/
namespace Thelia\Core\Event; namespace Thelia\Core\Event;
use Thelia\Core\Event\ActionEvent;
use Thelia\Core\FileFormat\Archive\AbstractArchiveBuilder; use Thelia\Core\FileFormat\Archive\AbstractArchiveBuilder;
use Thelia\Core\FileFormat\Formatting\AbstractFormatter; use Thelia\Core\FileFormat\Formatting\AbstractFormatter;
use Thelia\Core\FileFormat\Formatting\FormatterData; use Thelia\Core\FileFormat\Formatting\FormatterData;
use Thelia\ImportExport\AbstractHandler;
use Thelia\ImportExport\Export\ExportHandler; use Thelia\ImportExport\Export\ExportHandler;
/** /**
@@ -24,7 +24,7 @@ use Thelia\ImportExport\Export\ExportHandler;
*/ */
class ImportExport extends ActionEvent class ImportExport extends ActionEvent
{ {
/** @var \Thelia\ImportExport\Export\ExportHandler */ /** @var \Thelia\ImportExport\AbstractHandler */
protected $handler; protected $handler;
/** @var \Thelia\Core\FileFormat\Formatting\AbstractFormatter */ /** @var \Thelia\Core\FileFormat\Formatting\AbstractFormatter */
@@ -36,10 +36,13 @@ class ImportExport extends ActionEvent
/** @var \Thelia\Core\FileFormat\Archive\AbstractArchiveBuilder */ /** @var \Thelia\Core\FileFormat\Archive\AbstractArchiveBuilder */
protected $archiveBuilder; protected $archiveBuilder;
/** @var mixed */
protected $content;
public function __construct( public function __construct(
AbstractFormatter $formatter, AbstractFormatter $formatter = null,
\Thelia\ImportExport\Export\ExportHandler $handler, AbstractHandler $handler = null,
FormatterData $data, FormatterData $data = null,
AbstractArchiveBuilder $archiveBuilder = null AbstractArchiveBuilder $archiveBuilder = null
) { ) {
$this->archiveBuilder = $archiveBuilder; $this->archiveBuilder = $archiveBuilder;
@@ -123,4 +126,25 @@ class ImportExport extends ActionEvent
{ {
return $this->data; return $this->data;
} }
/**
* @param $content
* @return $this
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* @return mixed
*/
public function getContent()
{
return $this->content;
}
} }

View File

@@ -769,5 +769,9 @@ final class TheliaEvents
// -- Export ---------------------------------------------- // -- Export ----------------------------------------------
const BEFORE_EXPORT = "Thelia.before.export"; const EXPORT_BEFORE_ENCODE = "Thelia.export.encode.before";
const EXPORT_AFTER_ENCODE = "Thelia.export.encode.after";
const IMPORT_BEFORE_DECODE = "Thelia.import.decode.before";
const IMPORT_AFTER_DECODE = "Thelia.import.decode.after";
} }

View File

@@ -22,7 +22,7 @@ use Thelia\Log\Tlog;
*/ */
abstract class AbstractFormatter implements FormatInterface, FormatterInterface abstract class AbstractFormatter implements FormatInterface, FormatterInterface
{ {
const FILENAME = "export"; const FILENAME = "data";
/** @var \Thelia\Core\Translation\Translator */ /** @var \Thelia\Core\Translation\Translator */
protected $translator; protected $translator;

View File

@@ -83,7 +83,7 @@ class JsonFormatter extends AbstractFormatter
*/ */
public function decode($rawData) public function decode($rawData)
{ {
return (new FormatterData($this->getAliases()))->setData( return (new FormatterData())->setData(
json_decode($rawData, true) json_decode($rawData, true)
); );
} }

View File

@@ -172,13 +172,9 @@ class FormatterData
* @param int $index * @param int $index
* @return array|bool * @return array|bool
*/ */
public function popRow($index = 0) public function popRow()
{ {
$row = $this->getRow($index); $row = array_pop($this->data);
if (false !== $row) {
unset($this->data[$index]);
}
return $row; return $row;
} }

View File

@@ -35,27 +35,24 @@ class ProductStockImport extends ImportHandler
{ {
$errors = []; $errors = [];
$translator = Translator::getInstance(); $translator = Translator::getInstance();
$collection = new ObjectCollection();
while (false !== $row = $data->popRow()) { while (null !== $row = $data->popRow()) {
$obj = ProductSaleElementsQuery::create()->findOneByRef($row["ref"]); $obj = ProductSaleElementsQuery::create()->findOneByRef($row["ref"]);
if ($obj === null) { if ($obj === null) {
$errors += [ $errorMessage = $translator->trans(
$translator->trans( "The product sale element reference %ref doesn't exist",
"The product sale elements reference %ref doesn't exist", [
[ "%ref" => $row["ref"]
"%ref" => $row["ref"] ]
] );
)
]; $errors[] = $errorMessage ;
} else { } else {
$collection->append($obj->setQuantity($row["stock"])); $obj->setQuantity($row["stock"])->save();
} }
} }
$collection->save();
return $errors; return $errors;
} }

View File

@@ -1,5 +1,6 @@
{form name="thelia.import"} {form name="thelia.import"}
<form action="{$URL}" method="post" {form_enctype form=$form}> <form action="{$URL}" method="post" {form_enctype form=$form}>
{form_hidden_fields form=$form}
<div class="modal fade" id="real-import-modal" tabindex="-1" role="dialog" aria-labelledby="import-modal-label" aria-hidden="true"> <div class="modal fade" id="real-import-modal" tabindex="-1" role="dialog" aria-labelledby="import-modal-label" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
@@ -8,10 +9,14 @@
<h4 class="modal-title" id="import-modal-label">Import: {$TITLE}</h4> <h4 class="modal-title" id="import-modal-label">Import: {$TITLE}</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
{custom_render_form_field form=$form field="file_upload"} {form_field form=$form field="file_upload"}
<label form="{$label_attr.for}">
{$label}
</label>
<input type="file" required aria-required="true" name="{$name}" id="{$label_attr.for}" accept="{$ALLOWED_MIME_TYPES}"/> <input type="file" required aria-required="true" name="{$name}" id="{$label_attr.for}" accept="{$ALLOWED_MIME_TYPES}"/>
<div class="small">Accepted formats: {$ALLOWED_EXTENSIONS}</div> <div class="small">Accepted formats: {$ALLOWED_EXTENSIONS}</div>
{/custom_render_form_field} {/form_field}
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" class="btn btn-primary" title="{intl l="Import this file"}">{intl l="Import this file"}</button> <button type="submit" class="btn btn-primary" title="{intl l="Import this file"}">{intl l="Import this file"}</button>

View File

@@ -30,6 +30,14 @@
</div> </div>
{/if} {/if}
{if $success_message}
<div class="row">
<div class="col-md-12">
<div class="alert alert-success">{$success_message}</div>
</div>
</div>
{/if}
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="general-block-decorator"> <div class="general-block-decorator">
@@ -39,13 +47,17 @@
</div> </div>
<form action="{$URL}" method="post" {form_enctype form=$form}> <form action="{$URL}" method="post" {form_enctype form=$form}>
{custom_render_form_field form=$form field="file_upload"} {form_hidden_fields form=$form}
<input type="file" required aria-required="true" name="{$name}" id="{$label_attr.for}" accept="{$ALLOWED_MIME_TYPES}"/> {form_field form=$form field="file_upload"}
<div class="small">Accepted formats: {$ALLOWED_EXTENSIONS}</div> <label for="{$label_attr.for}">
{/custom_render_form_field} {$label}
</label>
<button type="submit" class="btn btn-primary" title="{intl l="Import this file"}">{intl l="Import this file"}</button> <input type="file" required aria-required="true" name="{$name}" id="{$label_attr.for}" accept="{$ALLOWED_MIME_TYPES}"/>
<div class="small">Accepted formats: {$ALLOWED_EXTENSIONS}</div>
{/form_field}
<button type="submit" class="btn btn-primary" title="{intl l="Import this file"}">{intl l="Import this file"}</button>
</form> </form>
</div> </div>
</div> </div>