Skip to content

Commit

Permalink
add xliff export for articles
Browse files Browse the repository at this point in the history
  • Loading branch information
wachterjohannes committed Aug 3, 2020
1 parent 966bc6d commit f7757ec
Show file tree
Hide file tree
Showing 8 changed files with 577 additions and 0 deletions.
84 changes: 84 additions & 0 deletions Command/ArticleExportCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\ArticleBundle\Command;

use Sulu\Bundle\ArticleBundle\Export\ArticleExportInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;

class ArticleExportCommand extends Command
{
protected static $defaultName = 'sulu:article:export';

/**
* @var ArticleExportInterface
*/
private $articleExporter;

public function __construct(ArticleExportInterface $articleExporter)
{
parent::__construct();

$this->articleExporter = $articleExporter;
}

protected function configure()
{
$this->addArgument('target', InputArgument::REQUIRED, 'export.xliff')
->addArgument('locale', InputArgument::REQUIRED)
->addOption('format', 'f', InputOption::VALUE_REQUIRED, '', '1.2.xliff')
->setDescription('Export Articles');
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$target = $input->getArgument('target');
if (0 === !\strpos($target, '/')) {
$target = \getcwd() . '/' . $target;
}
$locale = $input->getArgument('locale');
$format = $input->getOption('format');

$output->writeln([
'<info>Article Language Export</info>',
'<info>=======================</info>',
'',
'<info>Options</info>',
'Target: ' . $target,
'Locale: ' . $locale,
'Format: ' . $format,
'---------------',
'',
]);

$helper = $this->getHelper('question');
$question = new ConfirmationQuestion('<question>Continue with this options?(y/n)</question> ', false);

if (!$helper->ask($input, $output, $question)) {
$output->writeln('<error>Abort!</error>');

return 0;
}

$output->writeln('<info>Continue!</info>');

$file = $this->articleExporter->export($locale, $format, $output);

\file_put_contents($target, $file);

return 0;
}
}
202 changes: 202 additions & 0 deletions Export/ArticleExport.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
<?php

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\ArticleBundle\Export;

use Sulu\Bundle\ArticleBundle\Document\ArticleDocument;
use Sulu\Bundle\DocumentManagerBundle\Bridge\DocumentInspector;
use Sulu\Bundle\PageBundle\Content\Structure\ExcerptStructureExtension;
use Sulu\Component\Content\Compat\StructureManagerInterface;
use Sulu\Component\Content\Document\Extension\ExtensionContainer;
use Sulu\Component\Content\Extension\ExportExtensionInterface;
use Sulu\Component\Content\Extension\ExtensionManagerInterface;
use Sulu\Component\DocumentManager\Collection\QueryResultCollection;
use Sulu\Component\DocumentManager\DocumentManagerInterface;
use Sulu\Component\Export\Export;
use Sulu\Component\Export\Manager\ExportManagerInterface;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Twig\Environment;

class ArticleExport extends Export implements ArticleExportInterface
{
/**
* @var StructureManagerInterface
*/
protected $structureManager;

/**
* @var ExtensionManagerInterface
*/
protected $extensionManager;

/**
* @var OutputInterface
*/
private $output;

public function __construct(
Environment $templating,
DocumentManagerInterface $documentManager,
DocumentInspector $documentInspector,
StructureManagerInterface $structureManager,
ExtensionManagerInterface $extensionManager,
ExportManagerInterface $exportManager,
array $formatFilePaths
) {
parent::__construct($templating, $documentManager, $documentInspector, $exportManager, $formatFilePaths);

$this->structureManager = $structureManager;
$this->extensionManager = $extensionManager;
}

public function export(string $locale, string $format = '1.2.xliff', ?OutputInterface $output = null): string
{
$this->exportLocale = $locale;
$this->format = $format;
$this->output = $output;

if (!$this->output) {
$this->output = new NullOutput();
}

$this->output->writeln('<info>Loading Data…</info>');

$exportData = $this->getExportData($locale);

$this->output->writeln([
'',
'<info>Render Xliff…</info>',
]);

return $this->templating->render(
$this->getTemplate($this->format),
$exportData
);
}

public function getExportData(string $locale): array
{
/** @var ArticleDocument[] $documents */
$documents = $this->getDocuments($locale);

$progress = new ProgressBar($this->output, \count($documents));
$progress->start();

$documentData = [];
foreach ($documents as $key => $document) {
$contentData = $this->getContentData($document, $this->exportLocale);
$extensionData = $this->getExtensionData($document);
$settingData = $this->getSettingData($document);

$documentData[] = [
'uuid' => $document->getUuid(),
'locale' => $document->getLocale(),
'content' => $contentData,
'settings' => $settingData,
'extensions' => $extensionData,
];

$progress->advance();
}

$progress->finish();

return [
'locale' => $locale,
'format' => $this->format,
'documents' => $documentData,
];
}

protected function getExtensionData(ArticleDocument $document): array
{
$data = $document->getExtensionsData();
if ($data instanceof ExtensionContainer) {
$data = $data->toArray();
}

$extensionData = [];
foreach ($data as $extensionName => $extensionProperties) {
/** @var ExcerptStructureExtension $extension */
$extension = $this->extensionManager->getExtension($document->getStructureType(), $extensionName);

if ($extension instanceof ExportExtensionInterface) {
$extensionData[$extensionName] = $extension->export($extensionProperties, $this->format);
}
}

return $extensionData;
}

protected function getSettingData(ArticleDocument $document): array
{
if ($created = $document->getCreated()) {
$created = $created->format('c');
}

if ($changed = $document->getChanged()) {
$changed = $changed->format('c');
}

if ($published = $document->getPublished()) {
$published = $published->format('c');
}

if (($authored = $document->getAuthored()) && $authored instanceof \DateTime) {
$authored = $authored->format('c');
}

$settingOptions = [];
if ('1.2.xliff' === $this->format) {
$settingOptions = ['translate' => false];
}

return [
'structureType' => $this->createProperty('structureType', $document->getStructureType(), $settingOptions),
'published' => $this->createProperty('published', $published, $settingOptions),
'created' => $this->createProperty('created', $created, $settingOptions),
'changed' => $this->createProperty('changed', $changed, $settingOptions),
'creator' => $this->createProperty('creator', $document->getCreator(), $settingOptions),
'changer' => $this->createProperty('changer', $document->getChanger(), $settingOptions),
'locale' => $this->createProperty('locale', $document->getLocale(), $settingOptions),
'shadowLocale' => $this->createProperty('shadowLocale', $document->getShadowLocale(), $settingOptions),
'originalLocale' => $this->createProperty('originalLocale', $document->getOriginalLocale(), $settingOptions),
'routePath' => $this->createProperty('routePath', $document->getRoutePath(), $settingOptions),
'workflowStage' => $this->createProperty('workflowStage', $document->getWorkflowStage(), $settingOptions),
'path' => $this->createProperty('path', $document->getPath(), $settingOptions),
'mainWebspace' => $this->createProperty('mainWebspace', $document->getMainWebspace(), $settingOptions),
'additionalWebspaces' => $this->createProperty('additionalWebspaces', \json_encode($document->getAdditionalWebspaces()), $settingOptions),
'author' => $this->createProperty('author', $document->getAuthor(), $settingOptions),
'authored' => $this->createProperty('authored', $authored, $settingOptions),
];
}

protected function getDocuments(string $locale): QueryResultCollection
{
$query = $this->documentManager->createQuery(
'SELECT * FROM [nt:unstructured] AS a WHERE [jcr:mixinTypes] = "sulu:article"',
$locale
);

return $query->execute();
}

protected function getTemplate($format)
{
if (!isset($this->formatFilePaths[$format])) {
throw new \Exception(sprintf('No format "%s" configured for Snippet export', $format));
}

return $this->formatFilePaths[$format];
}
}
19 changes: 19 additions & 0 deletions Export/ArticleExportInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\ArticleBundle\Export;

use Symfony\Component\Console\Output\OutputInterface;

interface ArticleExportInterface
{
public function export(string $locale, string $format = '1.2.xliff', ?OutputInterface $output = null): string;
}
23 changes: 23 additions & 0 deletions Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="sulu_article.export.article.formats" type="collection">
<parameter key="1.2.xliff">@SuluArticle/Export/Article/1.2.xliff.twig</parameter>
</parameter>
</parameters>

<services>
<service id="sulu_article.reindex_command" class="Sulu\Bundle\ArticleBundle\Command\ReindexCommand">
<argument type="service" id="sulu_core.webspace.webspace_manager" />
Expand Down Expand Up @@ -454,5 +460,22 @@

<tag name="kernel.event_subscriber" />
</service>

<!-- Export -->
<service id="sulu_article.export.command" class="Sulu\Bundle\ArticleBundle\Command\ArticleExportCommand">
<argument type="service" id="sulu_article.export.exporter"/>

<tag name="console.command"/>
</service>

<service id="sulu_article.export.exporter" class="Sulu\Bundle\ArticleBundle\Export\ArticleExport">
<argument type="service" id="twig"/>
<argument type="service" id="sulu_document_manager.document_manager"/>
<argument type="service" id="sulu_document_manager.document_inspector"/>
<argument type="service" id="sulu.content.structure_manager"/>
<argument type="service" id="sulu_page.extension.manager"/>
<argument type="service" id="sulu_page.export.manager"/>
<argument>%sulu_article.export.article.formats%</argument>
</service>
</services>
</container>
42 changes: 42 additions & 0 deletions Resources/views/Export/Article/1.2.xliff.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{% extends "@SuluArticle/Export/Article/base.export.twig" %}

{% block main %}
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
{{ parent() }}
</xliff>
{% endblock main %}

{% block article %}
<file source-language="{{ document.locale }}" datatype="plaintext" original="{{ document.uuid }}">
<body>
{{- parent() -}}
</body>
</file>
{% endblock article %}

{# view #}
{%- block view -%}
{% apply spaceless %}
{% set attributes = '' %}
{% set target = '' %}
{%- if value is iterable -%}
{% set value = value|json_encode %}
{%- endif -%}
{%- if options.translate is defined and not options.translate -%}
{% set attributes = attributes ~ ' translate="no"' %}
{% set target = value %}
{%- endif -%}
{% if type == 'text_editor' %}
{% set attributes = attributes ~ ' datatype="html"' %}
{% endif %}
{% endapply %}
{% autoescape false %}

<!-- {{ name }}: {{ type }} -->
<trans-unit id="{{ sulu_content_type_export_counter() }}" resname="{{ name }}"{{ attributes }}>
<source>{{ sulu_content_type_export_escape(value) }}</source>
<target>{{ sulu_content_type_export_escape(target) }}</target>
</trans-unit>
{% endautoescape %}
{%- endblock view -%}
Loading

0 comments on commit f7757ec

Please sign in to comment.