Add content export

modifié:         core/lib/Thelia/Config/Resources/export.xml
	modifié:         core/lib/Thelia/Core/FileFormat/Archive/ArchiveBuilder/TarArchiveBuilder.php
	modifié:         core/lib/Thelia/Core/FileFormat/Archive/ArchiveBuilder/TarGzArchiveBuilder.php
	modifié:         core/lib/Thelia/Core/FileFormat/Archive/ArchiveBuilder/ZipArchiveBuilder.php
	modifié:         core/lib/Thelia/Core/FileFormat/Formatting/Formatter/CSVFormatter.php
	nouveau fichier: core/lib/Thelia/ImportExport/Export/Type/ContentExport.php
	nouveau fichier: core/lib/Thelia/Tests/ImportExport/Export/ContentExportTest.php
This commit is contained in:
Benjamin Perche
2014-07-28 16:26:58 +02:00
parent c208d8bb19
commit 40605c1893
7 changed files with 481 additions and 8 deletions

View File

@@ -13,6 +13,10 @@
<title locale="en_US">Products</title>
<title locale="fr_FR">Produits</title>
</export_category>
<export_category id="thelia.export.content">
<title locale="en_US">Content</title>
<title locale="fr_FR">Contenu</title>
</export_category>
</export_categories>
<exports>
@@ -64,5 +68,20 @@
</description>
</export_descriptive>
</export>
<export id="thelia.export.content" class="Thelia\ImportExport\Export\Type\ContentExport" category_id="thelia.export.content">
<export_descriptive locale="en_US">
<title>Contents and folder</title>
<description>
Export your contents and their related folders
</description>
</export_descriptive>
<export_descriptive locale="fr_FR">
<title>Contenus et dossiers</title>
<description>
Exportez vos contenus et les dossiers associés
</description>
</export_descriptive>
</export>
</exports>
</config>

View File

@@ -72,8 +72,14 @@ class TarArchiveBuilder extends AbstractArchiveBuilder
*/
public function addFile($filePath, $directoryInArchive = "/", $name = null, $isOnline = false)
{
if (!empty($name)) {
$directoryInArchive .= DS . dirname($name);
}
if (empty($name) || !is_scalar($name)) {
$name = basename($filePath);
} else {
$name = basename($name);
}
/**

View File

@@ -34,14 +34,10 @@ class TarGzArchiveBuilder extends TarArchiveBuilder
return "tar.gz";
}
public function setEnvironment($environment)
protected function compressionEntryPoint()
{
parent::setEnvironment($environment);
$this->previousFile = $this->cacheFile;
if ($this->compression != \Phar::GZ) {
$this->tar = $this->tar->compress(\Phar::BZ2, $this->getExtension());
$this->tar = $this->tar->compress(\Phar::GZ, $this->getExtension());
}
$this->compression = \Phar::GZ;

View File

@@ -74,6 +74,10 @@ class ZipArchiveBuilder extends AbstractArchiveBuilder
*/
public function addFile($filePath, $directoryInArchive = null, $name = null, $isOnline = false)
{
if (!empty($name)) {
$directoryInArchive .= DS . dirname($name) ;
}
$directoryInArchive = $this->formatDirectoryPath($directoryInArchive);
/**
@@ -86,6 +90,8 @@ class ZipArchiveBuilder extends AbstractArchiveBuilder
if (empty($name) || !is_scalar($name)) {
$name = basename($filePath);
} else {
$name = basename($name);
}
/**
@@ -178,7 +184,10 @@ class ZipArchiveBuilder extends AbstractArchiveBuilder
$directoryInArchive = $this->formatDirectoryPath($directoryPath);
if (!empty($directoryInArchive)) {
if (!$this->zip->addEmptyDir($directoryInArchive)) {
$this->zip->addEmptyDir($directoryInArchive);
$this->commit();
if (!$this->hasDirectory($directoryInArchive)) {
throw new \ErrorException(
$this->translator->trans(
"The directory %dir has not been created in the archive",

View File

@@ -116,8 +116,10 @@ class CSVFormatter extends AbstractFormatter
ksort($row);
foreach ($keys as $key) {
if (array_key_exists($key, $row)) {
$string .= $this->formatField($row[$key]);
}
}
$string = substr($string,0, -$delimiterLength) . $this->lineReturn;
}

View File

@@ -0,0 +1,303 @@
<?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\Export\Type;
use Propel\Runtime\ActiveQuery\Criteria;
use Propel\Runtime\ActiveQuery\Join;
use Propel\Runtime\ActiveQuery\ModelCriteria;
use Thelia\Core\FileFormat\FormatType;
use Thelia\Core\Template\Element\BaseLoop;
use Thelia\ImportExport\Export\DocumentsExportInterface;
use Thelia\ImportExport\Export\ExportHandler;
use Thelia\ImportExport\Export\ImagesExportInterface;
use Thelia\Model\Content;
use Thelia\Model\ContentDocumentI18nQuery;
use Thelia\Model\ContentDocumentQuery;
use Thelia\Model\ContentImageQuery;
use Thelia\Model\ContentQuery;
use Thelia\Model\FolderDocumentQuery;
use Thelia\Model\FolderImageQuery;
use Thelia\Model\Lang;
use Thelia\Model\Map\ContentDocumentTableMap;
use Thelia\Model\Map\ContentI18nTableMap;
use Thelia\Model\Map\ContentTableMap;
use Thelia\Model\Map\FolderDocumentTableMap;
use Thelia\Model\Map\FolderI18nTableMap;
use Thelia\Model\Map\FolderImageTableMap;
use Thelia\Model\Map\FolderTableMap;
use Thelia\Model\Map\RewritingUrlTableMap;
/**
* Class ContentExport
* @package Thelia\ImportExport\Export\Type
* @author Benjamin Perche <bperche@openstudio.fr>
*/
class ContentExport extends ExportHandler implements
ImagesExportInterface,
DocumentsExportInterface
{
const DIRECTORY_NAME = "content";
/**
* @return string|array
*
* Define all the type of 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\Core\FileFormat\FormatType
*
* example:
* return array(
* FormatType::TABLE,
* FormatType::UNBOUNDED,
* );
*/
public function getHandledTypes()
{
return array(
FormatType::TABLE,
FormatType::UNBOUNDED,
);
}
/**
* @param Lang $lang
* @return ModelCriteria|array|BaseLoop
*/
public function buildDataSet(Lang $lang)
{
$locale = $lang->getLocale();
$contentI18nJoin = new Join(ContentTableMap::ID, ContentI18nTableMap::ID, Criteria::LEFT_JOIN);
$folderI18nJoin = new Join(FolderTableMap::ID, FolderI18nTableMap::ID, Criteria::LEFT_JOIN);
$urlJoin = new Join(ContentTableMap::ID, RewritingUrlTableMap::VIEW_ID, Criteria::LEFT_JOIN);
$query = ContentQuery::create()
->_if($this->isImageExport())
->useContentImageQuery("content_image_join", Criteria::LEFT_JOIN)
->addAsColumn("content_IMAGES", "GROUP_CONCAT(DISTINCT `content_image_join`.FILE)")
->endUse()
->_endif()
->_if($this->isDocumentExport())
->useContentDocumentQuery()
->addAsColumn("content_DOCUMENTS", "GROUP_CONCAT(DISTINCT ".ContentDocumentTableMap::FILE.")")
->endUse()
->_endif()
->useContentFolderQuery(null, Criteria::LEFT_JOIN)
->useFolderQuery(null, Criteria::LEFT_JOIN)
->_if($this->isDocumentExport())
->useFolderDocumentQuery()
->addAsColumn("folder_DOCUMENTS", "GROUP_CONCAT(DISTINCT ".FolderDocumentTableMap::FILE.")")
->endUse()
->_endif()
->_if($this->isImageExport())
->useFolderImageQuery(null, Criteria::LEFT_JOIN)
->addAsColumn("folder_IMAGES", "GROUP_CONCAT(DISTINCT ".FolderImageTableMap::FILE.")")
->endUse()
->_endif()
->addJoinObject($folderI18nJoin, "folder_i18n_join")
->addJoinCondition("folder_i18n_join", FolderI18nTableMap::LOCALE . "=" . $this->real_escape($locale))
->addAsColumn("folder_TITLE", FolderI18nTableMap::TITLE)
->addAsColumn("folder_ID", FolderTableMap::ID)
->endUse()
->endUse()
->addJoinObject($contentI18nJoin, "content_i18n_join")
->addJoinCondition("content_i18n_join", ContentI18nTableMap::LOCALE . "=" . $this->real_escape($locale))
->addAsColumn("content_TITLE", ContentI18nTableMap::TITLE)
->addAsColumn("content_CHAPO", ContentI18nTableMap::CHAPO)
->addAsColumn("content_DESCRIPTION", ContentI18nTableMap::DESCRIPTION)
->addAsColumn("content_CONCLUSION", ContentI18nTableMap::POSTSCRIPTUM)
->addAsColumn("content_seo_TITLE", ContentI18nTableMap::META_TITLE)
->addAsColumn("content_seo_DESCRIPTION", ContentI18nTableMap::META_DESCRIPTION)
->addAsColumn("content_seo_KEYWORDS", ContentI18nTableMap::META_KEYWORDS)
->addJoinObject($urlJoin, "url_rewriting_join")
->addJoinCondition(
"url_rewriting_join",
RewritingUrlTableMap::VIEW . "=" .
$this->real_escape((new Content())->getRewrittenUrlViewName())
)
->addJoinCondition(
"url_rewriting_join",
RewritingUrlTableMap::VIEW_LOCALE . "=" . $this->real_escape($locale)
)
->addAsColumn("url_URL", RewritingUrlTableMap::URL)
->select([
ContentTableMap::ID,
ContentTableMap::VISIBLE,
"content_TITLE",
"content_CHAPO",
"content_DESCRIPTION",
"content_CONCLUSION",
"content_seo_TITLE",
"content_seo_DESCRIPTION",
"content_seo_KEYWORDS",
"url_URL",
"folder_TITLE",
"folder_ID",
])
->groupBy(ContentTableMap::ID)
->groupBy("folder_ID")
;
/**
* @var ContentQuery $query
*/
if ($this->isDocumentExport()) {
$query->select($query->getSelect() + [
"folder_DOCUMENTS",
"content_DOCUMENTS",
]);
}
/**
* @var ContentQuery $query
*/
if ($this->isImageExport()) {
$query->select($query->getSelect() + [
"folder_IMAGES",
"content_IMAGES",
]);
}
$dataSet = $query
->find()
->toArray()
;
$previous = null;
foreach ($dataSet as &$line) {
if ($previous === null || $previous !== $line[ContentTableMap::ID]) {
$previous = $line[ContentTableMap::ID];
} else {
/**
* Do not repeat content values
*/
$line["content_TITLE"] = "";
$line["content_VISIBLE"] = "";
$line["content_CHAPO"] = "";
$line["content_DESCRIPTION"] = "";
$line["content_CONCLUSION"] = "";
$line["content_seo_TITLE"] = "";
$line["content_seo_DESCRIPTION"] = "";
$line["content_seo_KEYWORDS"] = "";
$line["url_URL"] = "";
$line["content_IMAGES"] = "";
$line["content_DOCUMENTS"] = "";
if (isset($line["content_IMAGES"])) {
$line["content_IMAGES"] = "";
}
if (isset($line["content_DOCUMENTS"])) {
$line["content_IMAGES"] = "";
}
}
}
return $dataSet;
}
protected function getDefaultOrder()
{
return [
"id",
"title",
"chapo",
"description",
"conclusion",
"visible",
"seo_title",
"seo_description",
"seo_keywords",
"url",
"folder_id",
"folder_title",
];
}
protected function getAliases()
{
return [
ContentTableMap::ID => "id",
ContentTableMap::VISIBLE => "visible",
"content_TITLE" => "title",
"content_CHAPO" => "chapo",
"content_DESCRIPTION" => "description",
"content_CONCLUSION" => "conclusion",
"content_seo_TITLE" => "seo_title",
"content_seo_DESCRIPTION" => "seo_description",
"content_seo_KEYWORDS" => "seo_keywords",
"url_URL" => "url",
"folder_TITLE" => "folder_title",
"folder_ID" => "folder_id",
];
}
/**
* @return array
*
* return an array with the paths to the documents to include in the archive
*/
public function getDocumentsPaths()
{
$documentPaths = [];
$folderDocuments = FolderDocumentQuery::create()
->find();
/** @var \Thelia\Model\FolderDocument $folderDocument */
foreach ($folderDocuments as $folderDocument) {
$this->addFileToArray($folderDocument, $documentPaths);
}
$contentDocuments = ContentDocumentQuery::create()
->find();
/** @var \Thelia\Model\ContentDocument $contentDocument */
foreach ($contentDocuments as $contentDocument) {
$this->addFileToArray($contentDocument, $documentPaths);
}
return $documentPaths;
}
/**
* @return array
*
* return an array with the paths to the images to include in the archive
*/
public function getImagesPaths()
{
$imagePaths = [];
$folderImages = FolderImageQuery::create()
->find();
/** @var \Thelia\Model\FolderDocument $folderImage */
foreach ($folderImages as $folderImage) {
$this->addFileToArray($folderImage, $imagePaths);
}
$contentImages = ContentImageQuery::create()
->find();
/** @var \Thelia\Model\ContentImage $contentImage */
foreach ($contentImages as $contentImage) {
$this->addFileToArray($contentImage, $imagePaths);
}
return $imagePaths;
}
}

View File

@@ -0,0 +1,138 @@
<?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\Tests\ImportExport\Export;
use Symfony\Component\DependencyInjection\Container;
use Thelia\Core\Translation\Translator;
use Thelia\ImportExport\Export\Type\ContentExport;
use Thelia\Model\ContentFolderQuery;
use Thelia\Model\ContentImageQuery;
use Thelia\Model\ContentQuery;
use Thelia\Model\FolderImageQuery;
use Thelia\Model\FolderQuery;
use Thelia\Model\Lang;
use Thelia\Model\Map\ContentImageTableMap;
use Thelia\Model\Map\FolderImageTableMap;
use Thelia\Model\Map\FolderTableMap;
/**
* Class ContentExportTest
* @package Thelia\Tests\ImportExport\Export
* @author Benjamin Perche <bperche@openstudio.fr>
*/
class ContentExportTest extends \PHPUnit_Framework_TestCase
{
protected $lang;
/** @var ContentExport */
protected $handler;
public function setUp()
{
new Translator(new Container());
$this->lang = Lang::getDefaultLanguage();
$this->handler = new ContentExport(new Container());
}
public function testQuery()
{
$data = $this->handler->buildData($this->lang)->getData();
$max = count($data);
if ($max > 50) {
$max = 50;
}
for ($i = 0; $i < $max;) {
$content = ContentQuery::create()->findPk($data[$i]["id"]);
$this->assertNotNull($content);
$this->assertEquals($content->getTitle(), $data[$i]["title"]);
$this->assertEquals($content->getDescription(), $data[$i]["description"]);
$this->assertEquals($content->getChapo(), $data[$i]["chapo"]);
$this->assertEquals($content->getPostscriptum(), $data[$i]["conclusion"]);
$this->assertEquals($content->getMetaTitle(), $data[$i]["seo_title"]);
$this->assertEquals($content->getMetaDescription(), $data[$i]["seo_description"]);
$this->assertEquals($content->getMetaKeywords(), $data[$i]["seo_keywords"]);
do {
if (null !== $data[$i]["folder_id"]) {
$folder = FolderQuery::create()->findPk($data[$i]["folder_id"]);
$this->assertNotNull($folder);
$contentFolder = ContentFolderQuery::create()
->filterByContent($content)
->filterByFolder($folder)
->findOne()
;
$this->assertNotNull($contentFolder);
$this->assertEquals(
$folder->getTitle(),
$data[$i]["folder_title"]
);
}
} while (
isset($data[++$i]["id"]) &&
$data[$i-1]["id"] === $data[$i]["id"] &&
++$max
);
}
}
public function testQueryImages()
{
$data = $this->handler
->setImageExport(true)
->buildData($this->lang)
->getData()
;
$max = count($data);
if ($max > 50) {
$max = 50;
}
for ($i = 0; $i < $max; ++$i) {
$images = ContentImageQuery::create()
->filterByContentId($data[$i]["id"])
->select(ContentImageTableMap::FILE)
->find()
->toArray()
;
$imagesString = implode(",", $images);
$this->assertEquals($imagesString, $data[$i]["content_images"]);
$folderImages = FolderImageQuery::create()
->useFolderQuery()
->useContentFolderQuery()
->filterByContentId($data[$i]["id"])
->endUse()
->endUse()
->select(FolderImageTableMap::FILE)
->find()
->toArray()
;
$folderImages = implode(",", $folderImages);
$this->assertEquals($folderImages, $data[$i]["folder_images"]);
}
}
}