Add import_categories and imports load in XML

nouveau fichier: core/lib/Thelia/Config/Resources/import.xml
	modifié:         core/lib/Thelia/Controller/Admin/ImportExportController.php
	modifié:         core/lib/Thelia/Core/DependencyInjection/Loader/XmlFileLoader.php
	modifié:         core/lib/Thelia/Core/DependencyInjection/Loader/schema/dic/config/thelia-1.0.xsd
	nouveau fichier: core/lib/Thelia/ImportExport/Import/ProductStockImport.php
	renommé:         core/lib/Thelia/ImportExport/Both/NewsletterImportExport.php -> core/lib/Thelia/ImportExport/ImportHandler.php
	supprimé:        core/lib/Thelia/ImportExport/ImportHandlerInterface.php
	modifié:         core/lib/Thelia/Model/Import.php
	modifié:         core/lib/Thelia/Model/ImportCategory.php
This commit is contained in:
Benjamin Perche
2014-07-15 16:47:57 +02:00
parent 7a312e9093
commit d8cb1e173b
9 changed files with 381 additions and 63 deletions

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<config xmlns="http://thelia.net/schema/dic/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd">
<import_categories>
<import_category id="thelia.import.products">
<title locale="fr_FR">Produits</title>
<title locale="en_US">Products</title>
</import_category>
</import_categories>
<imports>
<import id="thelia.import.stock" class="Thelia\ImportExport\Import\ProductStockImport" category_id="thelia.import.products">
<import_descriptive locale="fr_FR">
<title>Importez votre stock</title>
</import_descriptive>
<import_descriptive locale="en_US">
<title>Import your stock</title>
</import_descriptive>
</import>
</imports>
</config>

View File

@@ -39,7 +39,6 @@ class ImportExportController extends BaseAdminController
public function hydrate()
{
$this->archiveBuilderManager = $this->container->get("thelia.manager.archive_builder_manager");
$this->formatterManager = $this->container->get("thelia.manager.formatter_manager");
}

View File

@@ -27,12 +27,19 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Loader\FileLoader;
use Thelia\Core\Translation\Translator;
use Thelia\ImportExport\ExportHandler;
use Thelia\ImportExport\ImportHandler;
use Thelia\Model\Export;
use Thelia\Model\ExportCategory;
use Thelia\Model\ExportCategoryQuery;
use Thelia\Model\ExportQuery;
use Thelia\Model\Import;
use Thelia\Model\ImportCategory;
use Thelia\Model\ImportCategoryQuery;
use Thelia\Model\ImportQuery;
use Thelia\Model\Map\ExportCategoryTableMap;
use Thelia\Model\Map\ExportTableMap;
use Thelia\Model\Map\ImportCategoryTableMap;
use Thelia\Model\Map\ImportTableMap;
/**
*
@@ -76,6 +83,10 @@ class XmlFileLoader extends FileLoader
$this->parseExportCategories($xml);
$this->parseExports($xml);
$this->parseImportCategories($xml);
$this->parseImports($xml);
}
protected function parseCommands(SimpleXMLElement $xml)
@@ -440,6 +451,157 @@ class XmlFileLoader extends FileLoader
}
}
protected function parseImportCategories(SimpleXMLElement $xml)
{
if (false === $importCategories = $xml->xpath('//config:import_categories/config:import_category')) {
return;
}
$con = Propel::getWriteConnection(ImportCategoryTableMap::DATABASE_NAME);
$con->beginTransaction();
try {
/** @var SimpleXMLElement $importCategory */
foreach ($importCategories as $importCategory) {
$id = (string) $importCategory->getAttributeAsPhp("id");
$importCategoryModel = ImportCategoryQuery::create()->findOneByRef($id);
if ($importCategoryModel === null) {
$importCategoryModel = new ImportCategory();
$importCategoryModel
->setRef($id)
->setPositionToLast()
->save($con)
;
}
/** @var SimpleXMLElement $child */
foreach ($importCategory->children() as $child) {
$locale = (string) $child->getAttributeAsPhp("locale");
$value = (string) $child;
$importCategoryModel
->setLocale($locale)
->setTitle($value)
->save($con);
;
}
}
$con->commit();
} catch (\Exception $e) {
$con->rollBack();
throw $e;
}
}
protected function parseImports(SimpleXMLElement $xml)
{
if (false === $imports = $xml->xpath('//config:imports/config:import')) {
return;
}
$con = Propel::getWriteConnection(ImportTableMap::DATABASE_NAME);
$con->beginTransaction();
try {
/** @var SimpleXMLElement $import */
foreach ($imports as $import) {
$id = (string) $import->getAttributeAsPhp("id");
$class = (string) $import->getAttributeAsPhp("class");
$categoryRef = (string) $import->getAttributeAsPhp("category_id");
if (!class_exists($class)) {
throw new \ErrorException(
Translator::getInstance()->trans(
"The class \"%class\" doesn't exist",
[
"%class" => $class
]
)
);
}
$classInstance = new $class($this->container);
if (!$classInstance instanceof ImportHandler) {
throw new \ErrorException(
Translator::getInstance()->trans(
"The class \"%class\" must extend %baseClass",
[
"%class" => $class,
"%baseClass" => "Thelia\\ImportImport\\ImportHandler",
]
)
);
}
$category = ImportCategoryQuery::create()->findOneByRef($categoryRef);
if (null === $category) {
throw new \ErrorException(
Translator::getInstance()->trans(
"The import category \"%category\" doesn't exist",
[
"%category" => $categoryRef
]
)
);
}
$importModel = ImportQuery::create()->findOneByRef($id);
if (null === $importModel) {
$importModel = new Import();
$importModel
->setRef($id)
->setPositionToLast()
;
}
$importModel
->setImportCategory($category)
->setHandleClass($class)
->save($con)
;
/** @var SimpleXMLElement $descriptive */
foreach ($import->children() as $descriptive) {
$locale = $descriptive->getAttributeAsPhp("locale");
$title = null;
$description = null;
/** @var SimpleXMLElement $row */
foreach ($descriptive->children() as $row) {
switch ($row->getName()) {
case "title":
$title = (string) $row;
break;
case "description":
$description = (string) $row;
break;
}
}
$importModel
->setLocale($locale)
->setTitle($title)
->setDescription($description)
->save($con)
;
}
}
$con->commit();
} catch (\Exception $e) {
$con->rollBack();
throw $e;
}
}
/**
* Parses a XML file.
*

View File

@@ -19,6 +19,8 @@
<xsd:element name="routing" type="routing" />
<xsd:element name="export_categories" type="export_categories" />
<xsd:element name="exports" type="exports" />
<xsd:element name="import_categories" type="import_categories" />
<xsd:element name="imports" type="imports" />
</xsd:choice>
</xsd:complexType>
@@ -230,7 +232,7 @@
<xsd:complexType name="export_category_title">
<xsd:simpleContent>
<xsd:extension id="title" base="xsd:string">
<xsd:extension base="xsd:string">
<xsd:attribute name="locale" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:simpleContent>
@@ -261,4 +263,51 @@
<xsd:attribute name="locale" type="xsd:string" use="required" />
</xsd:complexType>
<xsd:complexType name="import_categories">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="import_category" type="import_category"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="import_category">
<xsd:choice maxOccurs="unbounded" minOccurs="1">
<xsd:element name="title" type="import_category_title" />
</xsd:choice>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="import_category_title">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="locale" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="imports">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="import" type="import"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="import">
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element name="import_descriptive" type="import_descriptive" />
</xsd:choice>
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="class" type="xsd:string" use="required"/>
<xsd:attribute name="category_id" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="import_descriptive">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element name="title" type="xsd:string" />
<xsd:element minOccurs="0" maxOccurs="1" name="description" type="xsd:string" />
</xsd:sequence>
<xsd:attribute name="locale" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:schema>

View File

@@ -0,0 +1,85 @@
<?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\ImportExport\Import;
use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Core\FileFormat\Formatting\FormatterData;
use Thelia\Core\Translation\Translator;
use Thelia\ImportExport\Export\ExportType;
use Thelia\ImportExport\ImportHandler;
use Thelia\Model\ProductSaleElementsQuery;
/**
* Class ProductStockImport
* @package Thelia\ImportExport\Import
* @author Benjamin Perche <bperche@openstudio.fr>
*/
class ProductStockImport extends ImportHandler
{
/**
* @param \Thelia\Core\FileFormat\Formatting\FormatterData
* @return string|array error messages
*
* The method does the import routine from a FormatterData
*/
public function retrieveFromFormatterData(FormatterData $data)
{
$errors = [];
$translator = Translator::getInstance();
$collection = new ObjectCollection();
while (false !== $row = $data->popRow()) {
$obj = ProductSaleElementsQuery::create()->findOneByRef($row["ref"]);
if ($obj === null) {
$errors += [
$translator->trans(
"The product sale elements reference %ref doesn't exist",
[
"%ref" => $row["ref"]
]
)
];
} else {
$collection->append($obj->setQuantity($row["stock"]));
}
}
$collection->save();
return $errors;
}
/**
* @return string|array
*
* Define all the type of import/formatters that this can handle
* return a string if it handle a single type ( specific exports ),
* or an array if multiple.
*
* Thelia types are defined in \Thelia\ImportExport\Export\ExportType
*
* example:
* return array(
* ExportType::EXPORT_TABLE,
* ExportType::EXPORT_UNBOUNDED,
* );
*/
public function getHandledType()
{
return array(
ExportType::EXPORT_TABLE,
ExportType::EXPORT_UNBOUNDED,
);
}
}

View File

@@ -10,18 +10,16 @@
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\ImportExport\Both;
namespace Thelia\ImportExport;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Thelia\Core\FileFormat\Formatting\FormatterData;
use Thelia\ImportExport\ExportHandler;
use Thelia\ImportExport\ImportHandlerInterface;
/**
* Class NewsletterImportExport
* @package Thelia\ImportExport\Both
* Class ImportHandler
* @package Thelia\ImportExport
* @author Benjamin Perche <bperche@openstudio.fr>
*/
class NewsletterImportExport implements ExportHandler, ImportHandlerInterface
abstract class ImportHandler
{
protected $container;
@@ -30,29 +28,32 @@ class NewsletterImportExport implements ExportHandler, ImportHandlerInterface
*
* Dependency injection: load the container to be able to get parameters and services
*/
public function __construct(ContainerInterface $container)
{
public function __construct(ContainerInterface $container) {
$this->container = $container;
}
/**
* @return \Thelia\Core\FileFormat\Formatting\FormatterData
* @param \Thelia\Core\FileFormat\Formatting\FormatterData
* @return string|array error messages
*
* The method builds
* The method does the import routine from a FormatterData
*/
public function buildFormatterData()
{
// TODO: Implement buildFormatterData() method.
}
abstract public function retrieveFromFormatterData(FormatterData $data);
/**
* @return \Thelia\Core\FileFormat\Formatting\FormatterData
* @return string|array
*
* The method builds
* Define all the type of import/formatters that this can handle
* return a string if it handle a single type ( specific exports ),
* or an array if multiple.
*
* Thelia types are defined in \Thelia\ImportExport\Export\ExportType
*
* example:
* return array(
* ExportType::EXPORT_TABLE,
* ExportType::EXPORT_UNBOUNDED,
* );
*/
public function importFromFormatterData(FormatterData $data)
{
// TODO: Implement importFromFormatterData() method.
}
abstract public function getHandledType();
}

View File

@@ -1,37 +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\ImportExport;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Thelia\Core\FileFormat\Formatting\FormatterData;
/**
* Interface ImportHandlerInterface
* @package Thelia\ImportExport
* @author Benjamin Perche <bperche@openstudio.fr>
*/
interface ImportHandlerInterface
{
/**
* @param ContainerInterface $container
*
* Dependency injection: load the container to be able to get parameters and services
*/
public function __construct(ContainerInterface $container);
/**
* @return \Thelia\Core\FileFormat\Formatting\FormatterData
*
* The method builds
*/
public function importFromFormatterData(FormatterData $data);
}

View File

@@ -5,6 +5,7 @@ namespace Thelia\Model;
use Propel\Runtime\ActiveQuery\Criteria;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Thelia\ImportExport\ExportHandler;
use Thelia\ImportExport\ImportHandler;
use Thelia\Model\Base\Import as BaseImport;
use Thelia\Model\Map\ImportTableMap;
@@ -74,6 +75,24 @@ class Import extends BaseImport
$this->setPosition($position)->save();
}
public function setPositionToLast()
{
$max = ImportQuery::create()
->orderByPosition(Criteria::DESC)
->select(ImportTableMap::POSITION)
->findOne()
;
if (null === $max) {
$this->setPosition(1);
} else {
$this->setPosition($max+1);
}
return $this;
}
public function getHandleClassInstance(ContainerInterface $container)
{
$class = $this->getHandleClass();
@@ -89,12 +108,12 @@ class Import extends BaseImport
$instance = new $class($container);
if (!$class instanceof ExportHandler) {
if (!$class instanceof ImportHandler) {
throw new \ErrorException(
"The class \"%class\" must implement %interface",
[
"%class" => $class,
"%interface" => "\\Thelia\\ImportExport\\ExportHandler",
"%interface" => "\\Thelia\\ImportExport\\ImportHandler",
]
);
}

View File

@@ -28,7 +28,7 @@ class ImportCategory extends BaseImportCategory
public function downPosition()
{
$max = CategoryQuery::create()
$max = ImportCategoryQuery::create()
->orderByPosition(Criteria::DESC)
->select(ImportCategoryTableMap::POSITION)
->findOne()
@@ -70,4 +70,21 @@ class ImportCategory extends BaseImportCategory
$this->setPosition($position)->save();
}
public function setPositionToLast()
{
$max = ImportCategoryQuery::create()
->orderByPosition(Criteria::DESC)
->select(ImportCategoryTableMap::POSITION)
->findOne()
;
if (null === $max) {
$this->setPosition(1);
} else {
$this->setPosition($max+1);
}
return $this;
}
}