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:
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -116,7 +116,9 @@ class CSVFormatter extends AbstractFormatter
|
||||
ksort($row);
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$string .= $this->formatField($row[$key]);
|
||||
if (array_key_exists($key, $row)) {
|
||||
$string .= $this->formatField($row[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$string = substr($string,0, -$delimiterLength) . $this->lineReturn;
|
||||
|
||||
303
core/lib/Thelia/ImportExport/Export/Type/ContentExport.php
Normal file
303
core/lib/Thelia/ImportExport/Export/Type/ContentExport.php
Normal 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;
|
||||
}
|
||||
}
|
||||
138
core/lib/Thelia/Tests/ImportExport/Export/ContentExportTest.php
Normal file
138
core/lib/Thelia/Tests/ImportExport/Export/ContentExportTest.php
Normal 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"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user