Initial Commit
This commit is contained in:
48
dependencies/symfony/translation/Dumper/CsvFileDumper.php
vendored
Normal file
48
dependencies/symfony/translation/Dumper/CsvFileDumper.php
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
/**
|
||||
* CsvFileDumper generates a csv formatted string representation of a message catalogue.
|
||||
*
|
||||
* @author Stealth35
|
||||
*/
|
||||
class CsvFileDumper extends \Symfony\Component\Translation\Dumper\FileDumper
|
||||
{
|
||||
private string $delimiter = ';';
|
||||
private string $enclosure = '"';
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) : string
|
||||
{
|
||||
$handle = \fopen('php://memory', 'r+');
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
\fputcsv($handle, [$source, $target], $this->delimiter, $this->enclosure);
|
||||
}
|
||||
\rewind($handle);
|
||||
$output = \stream_get_contents($handle);
|
||||
\fclose($handle);
|
||||
return $output;
|
||||
}
|
||||
/**
|
||||
* Sets the delimiter and escape character for CSV.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCsvControl(string $delimiter = ';', string $enclosure = '"')
|
||||
{
|
||||
$this->delimiter = $delimiter;
|
||||
$this->enclosure = $enclosure;
|
||||
}
|
||||
protected function getExtension() : string
|
||||
{
|
||||
return 'csv';
|
||||
}
|
||||
}
|
30
dependencies/symfony/translation/Dumper/DumperInterface.php
vendored
Normal file
30
dependencies/symfony/translation/Dumper/DumperInterface.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
/**
|
||||
* DumperInterface is the interface implemented by all translation dumpers.
|
||||
* There is no common option.
|
||||
*
|
||||
* @author Michel Salib <michelsalib@hotmail.com>
|
||||
*/
|
||||
interface DumperInterface
|
||||
{
|
||||
/**
|
||||
* Dumps the message catalogue.
|
||||
*
|
||||
* @param array $options Options that are used by the dumper
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dump(MessageCatalogue $messages, array $options = []);
|
||||
}
|
93
dependencies/symfony/translation/Dumper/FileDumper.php
vendored
Normal file
93
dependencies/symfony/translation/Dumper/FileDumper.php
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Translation\Exception\RuntimeException;
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
/**
|
||||
* FileDumper is an implementation of DumperInterface that dump a message catalogue to file(s).
|
||||
*
|
||||
* Options:
|
||||
* - path (mandatory): the directory where the files should be saved
|
||||
*
|
||||
* @author Michel Salib <michelsalib@hotmail.com>
|
||||
*/
|
||||
abstract class FileDumper implements \Symfony\Component\Translation\Dumper\DumperInterface
|
||||
{
|
||||
/**
|
||||
* A template for the relative paths to files.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $relativePathTemplate = '%domain%.%locale%.%extension%';
|
||||
/**
|
||||
* Sets the template for the relative paths to files.
|
||||
*
|
||||
* @param string $relativePathTemplate A template for the relative paths to files
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setRelativePathTemplate(string $relativePathTemplate)
|
||||
{
|
||||
$this->relativePathTemplate = $relativePathTemplate;
|
||||
}
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function dump(MessageCatalogue $messages, array $options = [])
|
||||
{
|
||||
if (!\array_key_exists('path', $options)) {
|
||||
throw new InvalidArgumentException('The file dumper needs a path option.');
|
||||
}
|
||||
// save a file for each domain
|
||||
foreach ($messages->getDomains() as $domain) {
|
||||
$fullpath = $options['path'] . '/' . $this->getRelativePath($domain, $messages->getLocale());
|
||||
if (!\file_exists($fullpath)) {
|
||||
$directory = \dirname($fullpath);
|
||||
if (!\file_exists($directory) && !@\mkdir($directory, 0777, \true)) {
|
||||
throw new RuntimeException(\sprintf('Unable to create directory "%s".', $directory));
|
||||
}
|
||||
}
|
||||
$intlDomain = $domain . MessageCatalogue::INTL_DOMAIN_SUFFIX;
|
||||
$intlMessages = $messages->all($intlDomain);
|
||||
if ($intlMessages) {
|
||||
$intlPath = $options['path'] . '/' . $this->getRelativePath($intlDomain, $messages->getLocale());
|
||||
\file_put_contents($intlPath, $this->formatCatalogue($messages, $intlDomain, $options));
|
||||
$messages->replace([], $intlDomain);
|
||||
try {
|
||||
if ($messages->all($domain)) {
|
||||
\file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
|
||||
}
|
||||
continue;
|
||||
} finally {
|
||||
$messages->replace($intlMessages, $intlDomain);
|
||||
}
|
||||
}
|
||||
\file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Transforms a domain of a message catalogue to its string representation.
|
||||
*/
|
||||
public abstract function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) : string;
|
||||
/**
|
||||
* Gets the file extension of the dumper.
|
||||
*/
|
||||
protected abstract function getExtension() : string;
|
||||
/**
|
||||
* Gets the relative file path using the template.
|
||||
*/
|
||||
private function getRelativePath(string $domain, string $locale) : string
|
||||
{
|
||||
return \strtr($this->relativePathTemplate, ['%domain%' => $domain, '%locale%' => $locale, '%extension%' => $this->getExtension()]);
|
||||
}
|
||||
}
|
96
dependencies/symfony/translation/Dumper/IcuResFileDumper.php
vendored
Normal file
96
dependencies/symfony/translation/Dumper/IcuResFileDumper.php
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
/**
|
||||
* IcuResDumper generates an ICU ResourceBundle formatted string representation of a message catalogue.
|
||||
*
|
||||
* @author Stealth35
|
||||
*/
|
||||
class IcuResFileDumper extends \Symfony\Component\Translation\Dumper\FileDumper
|
||||
{
|
||||
protected $relativePathTemplate = '%domain%/%locale%.%extension%';
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) : string
|
||||
{
|
||||
$data = $indexes = $resources = '';
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$indexes .= \pack('v', \strlen($data) + 28);
|
||||
$data .= $source . "\x00";
|
||||
}
|
||||
$data .= $this->writePadding($data);
|
||||
$keyTop = $this->getPosition($data);
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$resources .= \pack('V', $this->getPosition($data));
|
||||
$data .= \pack('V', \strlen($target)) . \mb_convert_encoding($target . "\x00", 'UTF-16LE', 'UTF-8') . $this->writePadding($data);
|
||||
}
|
||||
$resOffset = $this->getPosition($data);
|
||||
$data .= \pack('v', \count($messages->all($domain))) . $indexes . $this->writePadding($data) . $resources;
|
||||
$bundleTop = $this->getPosition($data);
|
||||
$root = \pack(
|
||||
'V7',
|
||||
$resOffset + (2 << 28),
|
||||
// Resource Offset + Resource Type
|
||||
6,
|
||||
// Index length
|
||||
$keyTop,
|
||||
// Index keys top
|
||||
$bundleTop,
|
||||
// Index resources top
|
||||
$bundleTop,
|
||||
// Index bundle top
|
||||
\count($messages->all($domain)),
|
||||
// Index max table length
|
||||
0
|
||||
);
|
||||
$header = \pack(
|
||||
'vC2v4C12@32',
|
||||
32,
|
||||
// Header size
|
||||
0xda,
|
||||
0x27,
|
||||
// Magic number 1 and 2
|
||||
20,
|
||||
0,
|
||||
0,
|
||||
2,
|
||||
// Rest of the header, ..., Size of a char
|
||||
0x52,
|
||||
0x65,
|
||||
0x73,
|
||||
0x42,
|
||||
// Data format identifier
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
// Data version
|
||||
1,
|
||||
4,
|
||||
0,
|
||||
0
|
||||
);
|
||||
return $header . $root . $data;
|
||||
}
|
||||
private function writePadding(string $data) : ?string
|
||||
{
|
||||
$padding = \strlen($data) % 4;
|
||||
return $padding ? \str_repeat("\xaa", 4 - $padding) : null;
|
||||
}
|
||||
private function getPosition(string $data) : float|int
|
||||
{
|
||||
return (\strlen($data) + 28) / 4;
|
||||
}
|
||||
protected function getExtension() : string
|
||||
{
|
||||
return 'res';
|
||||
}
|
||||
}
|
34
dependencies/symfony/translation/Dumper/IniFileDumper.php
vendored
Normal file
34
dependencies/symfony/translation/Dumper/IniFileDumper.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
/**
|
||||
* IniFileDumper generates an ini formatted string representation of a message catalogue.
|
||||
*
|
||||
* @author Stealth35
|
||||
*/
|
||||
class IniFileDumper extends \Symfony\Component\Translation\Dumper\FileDumper
|
||||
{
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) : string
|
||||
{
|
||||
$output = '';
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$escapeTarget = \str_replace('"', '\\"', $target);
|
||||
$output .= $source . '="' . $escapeTarget . "\"\n";
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
protected function getExtension() : string
|
||||
{
|
||||
return 'ini';
|
||||
}
|
||||
}
|
30
dependencies/symfony/translation/Dumper/JsonFileDumper.php
vendored
Normal file
30
dependencies/symfony/translation/Dumper/JsonFileDumper.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
/**
|
||||
* JsonFileDumper generates an json formatted string representation of a message catalogue.
|
||||
*
|
||||
* @author singles
|
||||
*/
|
||||
class JsonFileDumper extends \Symfony\Component\Translation\Dumper\FileDumper
|
||||
{
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) : string
|
||||
{
|
||||
$flags = $options['json_encoding'] ?? \JSON_PRETTY_PRINT;
|
||||
return \json_encode($messages->all($domain), $flags);
|
||||
}
|
||||
protected function getExtension() : string
|
||||
{
|
||||
return 'json';
|
||||
}
|
||||
}
|
51
dependencies/symfony/translation/Dumper/MoFileDumper.php
vendored
Normal file
51
dependencies/symfony/translation/Dumper/MoFileDumper.php
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\Loader\MoFileLoader;
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
/**
|
||||
* MoFileDumper generates a gettext formatted string representation of a message catalogue.
|
||||
*
|
||||
* @author Stealth35
|
||||
*/
|
||||
class MoFileDumper extends \Symfony\Component\Translation\Dumper\FileDumper
|
||||
{
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) : string
|
||||
{
|
||||
$sources = $targets = $sourceOffsets = $targetOffsets = '';
|
||||
$offsets = [];
|
||||
$size = 0;
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$offsets[] = \array_map('strlen', [$sources, $source, $targets, $target]);
|
||||
$sources .= "\x00" . $source;
|
||||
$targets .= "\x00" . $target;
|
||||
++$size;
|
||||
}
|
||||
$header = ['magicNumber' => MoFileLoader::MO_LITTLE_ENDIAN_MAGIC, 'formatRevision' => 0, 'count' => $size, 'offsetId' => MoFileLoader::MO_HEADER_SIZE, 'offsetTranslated' => MoFileLoader::MO_HEADER_SIZE + 8 * $size, 'sizeHashes' => 0, 'offsetHashes' => MoFileLoader::MO_HEADER_SIZE + 16 * $size];
|
||||
$sourcesSize = \strlen($sources);
|
||||
$sourcesStart = $header['offsetHashes'] + 1;
|
||||
foreach ($offsets as $offset) {
|
||||
$sourceOffsets .= $this->writeLong($offset[1]) . $this->writeLong($offset[0] + $sourcesStart);
|
||||
$targetOffsets .= $this->writeLong($offset[3]) . $this->writeLong($offset[2] + $sourcesStart + $sourcesSize);
|
||||
}
|
||||
$output = \implode('', \array_map($this->writeLong(...), $header)) . $sourceOffsets . $targetOffsets . $sources . $targets;
|
||||
return $output;
|
||||
}
|
||||
protected function getExtension() : string
|
||||
{
|
||||
return 'mo';
|
||||
}
|
||||
private function writeLong(mixed $str) : string
|
||||
{
|
||||
return \pack('V*', $str);
|
||||
}
|
||||
}
|
29
dependencies/symfony/translation/Dumper/PhpFileDumper.php
vendored
Normal file
29
dependencies/symfony/translation/Dumper/PhpFileDumper.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
/**
|
||||
* PhpFileDumper generates PHP files from a message catalogue.
|
||||
*
|
||||
* @author Michel Salib <michelsalib@hotmail.com>
|
||||
*/
|
||||
class PhpFileDumper extends \Symfony\Component\Translation\Dumper\FileDumper
|
||||
{
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) : string
|
||||
{
|
||||
return "<?php\n\nreturn " . \var_export($messages->all($domain), \true) . ";\n";
|
||||
}
|
||||
protected function getExtension() : string
|
||||
{
|
||||
return 'php';
|
||||
}
|
||||
}
|
115
dependencies/symfony/translation/Dumper/PoFileDumper.php
vendored
Normal file
115
dependencies/symfony/translation/Dumper/PoFileDumper.php
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
/**
|
||||
* PoFileDumper generates a gettext formatted string representation of a message catalogue.
|
||||
*
|
||||
* @author Stealth35
|
||||
*/
|
||||
class PoFileDumper extends \Symfony\Component\Translation\Dumper\FileDumper
|
||||
{
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) : string
|
||||
{
|
||||
$output = 'msgid ""' . "\n";
|
||||
$output .= 'msgstr ""' . "\n";
|
||||
$output .= '"Content-Type: text/plain; charset=UTF-8\\n"' . "\n";
|
||||
$output .= '"Content-Transfer-Encoding: 8bit\\n"' . "\n";
|
||||
$output .= '"Language: ' . $messages->getLocale() . '\\n"' . "\n";
|
||||
$output .= "\n";
|
||||
$newLine = \false;
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
if ($newLine) {
|
||||
$output .= "\n";
|
||||
} else {
|
||||
$newLine = \true;
|
||||
}
|
||||
$metadata = $messages->getMetadata($source, $domain);
|
||||
if (isset($metadata['comments'])) {
|
||||
$output .= $this->formatComments($metadata['comments']);
|
||||
}
|
||||
if (isset($metadata['flags'])) {
|
||||
$output .= $this->formatComments(\implode(',', (array) $metadata['flags']), ',');
|
||||
}
|
||||
if (isset($metadata['sources'])) {
|
||||
$output .= $this->formatComments(\implode(' ', (array) $metadata['sources']), ':');
|
||||
}
|
||||
$sourceRules = $this->getStandardRules($source);
|
||||
$targetRules = $this->getStandardRules($target);
|
||||
if (2 == \count($sourceRules) && [] !== $targetRules) {
|
||||
$output .= \sprintf('msgid "%s"' . "\n", $this->escape($sourceRules[0]));
|
||||
$output .= \sprintf('msgid_plural "%s"' . "\n", $this->escape($sourceRules[1]));
|
||||
foreach ($targetRules as $i => $targetRule) {
|
||||
$output .= \sprintf('msgstr[%d] "%s"' . "\n", $i, $this->escape($targetRule));
|
||||
}
|
||||
} else {
|
||||
$output .= \sprintf('msgid "%s"' . "\n", $this->escape($source));
|
||||
$output .= \sprintf('msgstr "%s"' . "\n", $this->escape($target));
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
private function getStandardRules(string $id) : array
|
||||
{
|
||||
// Partly copied from TranslatorTrait::trans.
|
||||
$parts = [];
|
||||
if (\preg_match('/^\\|++$/', $id)) {
|
||||
$parts = \explode('|', $id);
|
||||
} elseif (\preg_match_all('/(?:\\|\\||[^\\|])++/', $id, $matches)) {
|
||||
$parts = $matches[0];
|
||||
}
|
||||
$intervalRegexp = <<<'EOF'
|
||||
/^(?P<interval>
|
||||
({\s*
|
||||
(\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*)
|
||||
\s*})
|
||||
|
||||
|
|
||||
|
||||
(?P<left_delimiter>[\[\]])
|
||||
\s*
|
||||
(?P<left>-Inf|\-?\d+(\.\d+)?)
|
||||
\s*,\s*
|
||||
(?P<right>\+?Inf|\-?\d+(\.\d+)?)
|
||||
\s*
|
||||
(?P<right_delimiter>[\[\]])
|
||||
)\s*(?P<message>.*?)$/xs
|
||||
EOF;
|
||||
$standardRules = [];
|
||||
foreach ($parts as $part) {
|
||||
$part = \trim(\str_replace('||', '|', $part));
|
||||
if (\preg_match($intervalRegexp, $part)) {
|
||||
// Explicit rule is not a standard rule.
|
||||
return [];
|
||||
} else {
|
||||
$standardRules[] = $part;
|
||||
}
|
||||
}
|
||||
return $standardRules;
|
||||
}
|
||||
protected function getExtension() : string
|
||||
{
|
||||
return 'po';
|
||||
}
|
||||
private function escape(string $str) : string
|
||||
{
|
||||
return \addcslashes($str, "\x00..\x1f\"\\");
|
||||
}
|
||||
private function formatComments(string|array $comments, string $prefix = '') : ?string
|
||||
{
|
||||
$output = null;
|
||||
foreach ((array) $comments as $comment) {
|
||||
$output .= \sprintf('#%s %s' . "\n", $prefix, $comment);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
50
dependencies/symfony/translation/Dumper/QtFileDumper.php
vendored
Normal file
50
dependencies/symfony/translation/Dumper/QtFileDumper.php
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
/**
|
||||
* QtFileDumper generates ts files from a message catalogue.
|
||||
*
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class QtFileDumper extends \Symfony\Component\Translation\Dumper\FileDumper
|
||||
{
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) : string
|
||||
{
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
$dom->formatOutput = \true;
|
||||
$ts = $dom->appendChild($dom->createElement('TS'));
|
||||
$context = $ts->appendChild($dom->createElement('context'));
|
||||
$context->appendChild($dom->createElement('name', $domain));
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$message = $context->appendChild($dom->createElement('message'));
|
||||
$metadata = $messages->getMetadata($source, $domain);
|
||||
if (isset($metadata['sources'])) {
|
||||
foreach ((array) $metadata['sources'] as $location) {
|
||||
$loc = \explode(':', $location, 2);
|
||||
$location = $message->appendChild($dom->createElement('location'));
|
||||
$location->setAttribute('filename', $loc[0]);
|
||||
if (isset($loc[1])) {
|
||||
$location->setAttribute('line', $loc[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$message->appendChild($dom->createElement('source', $source));
|
||||
$message->appendChild($dom->createElement('translation', $target));
|
||||
}
|
||||
return $dom->saveXML();
|
||||
}
|
||||
protected function getExtension() : string
|
||||
{
|
||||
return 'ts';
|
||||
}
|
||||
}
|
180
dependencies/symfony/translation/Dumper/XliffFileDumper.php
vendored
Normal file
180
dependencies/symfony/translation/Dumper/XliffFileDumper.php
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
/**
|
||||
* XliffFileDumper generates xliff files from a message catalogue.
|
||||
*
|
||||
* @author Michel Salib <michelsalib@hotmail.com>
|
||||
*/
|
||||
class XliffFileDumper extends \Symfony\Component\Translation\Dumper\FileDumper
|
||||
{
|
||||
public function __construct(private string $extension = 'xlf')
|
||||
{
|
||||
}
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) : string
|
||||
{
|
||||
$xliffVersion = '1.2';
|
||||
if (\array_key_exists('xliff_version', $options)) {
|
||||
$xliffVersion = $options['xliff_version'];
|
||||
}
|
||||
if (\array_key_exists('default_locale', $options)) {
|
||||
$defaultLocale = $options['default_locale'];
|
||||
} else {
|
||||
$defaultLocale = \Locale::getDefault();
|
||||
}
|
||||
if ('1.2' === $xliffVersion) {
|
||||
return $this->dumpXliff1($defaultLocale, $messages, $domain, $options);
|
||||
}
|
||||
if ('2.0' === $xliffVersion) {
|
||||
return $this->dumpXliff2($defaultLocale, $messages, $domain);
|
||||
}
|
||||
throw new InvalidArgumentException(\sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
|
||||
}
|
||||
protected function getExtension() : string
|
||||
{
|
||||
return $this->extension;
|
||||
}
|
||||
private function dumpXliff1(string $defaultLocale, MessageCatalogue $messages, ?string $domain, array $options = []) : string
|
||||
{
|
||||
$toolInfo = ['tool-id' => 'symfony', 'tool-name' => 'Symfony'];
|
||||
if (\array_key_exists('tool_info', $options)) {
|
||||
$toolInfo = \array_merge($toolInfo, $options['tool_info']);
|
||||
}
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
$dom->formatOutput = \true;
|
||||
$xliff = $dom->appendChild($dom->createElement('xliff'));
|
||||
$xliff->setAttribute('version', '1.2');
|
||||
$xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
|
||||
$xliffFile = $xliff->appendChild($dom->createElement('file'));
|
||||
$xliffFile->setAttribute('source-language', \str_replace('_', '-', $defaultLocale));
|
||||
$xliffFile->setAttribute('target-language', \str_replace('_', '-', $messages->getLocale()));
|
||||
$xliffFile->setAttribute('datatype', 'plaintext');
|
||||
$xliffFile->setAttribute('original', 'file.ext');
|
||||
$xliffHead = $xliffFile->appendChild($dom->createElement('header'));
|
||||
$xliffTool = $xliffHead->appendChild($dom->createElement('tool'));
|
||||
foreach ($toolInfo as $id => $value) {
|
||||
$xliffTool->setAttribute($id, $value);
|
||||
}
|
||||
if ($catalogueMetadata = $messages->getCatalogueMetadata('', $domain) ?? []) {
|
||||
$xliffPropGroup = $xliffHead->appendChild($dom->createElement('prop-group'));
|
||||
foreach ($catalogueMetadata as $key => $value) {
|
||||
$xliffProp = $xliffPropGroup->appendChild($dom->createElement('prop'));
|
||||
$xliffProp->setAttribute('prop-type', $key);
|
||||
$xliffProp->appendChild($dom->createTextNode($value));
|
||||
}
|
||||
}
|
||||
$xliffBody = $xliffFile->appendChild($dom->createElement('body'));
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$translation = $dom->createElement('trans-unit');
|
||||
$translation->setAttribute('id', \strtr(\substr(\base64_encode(\hash('sha256', $source, \true)), 0, 7), '/+', '._'));
|
||||
$translation->setAttribute('resname', $source);
|
||||
$s = $translation->appendChild($dom->createElement('source'));
|
||||
$s->appendChild($dom->createTextNode($source));
|
||||
// Does the target contain characters requiring a CDATA section?
|
||||
$text = 1 === \preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
|
||||
$targetElement = $dom->createElement('target');
|
||||
$metadata = $messages->getMetadata($source, $domain);
|
||||
if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
|
||||
foreach ($metadata['target-attributes'] as $name => $value) {
|
||||
$targetElement->setAttribute($name, $value);
|
||||
}
|
||||
}
|
||||
$t = $translation->appendChild($targetElement);
|
||||
$t->appendChild($text);
|
||||
if ($this->hasMetadataArrayInfo('notes', $metadata)) {
|
||||
foreach ($metadata['notes'] as $note) {
|
||||
if (!isset($note['content'])) {
|
||||
continue;
|
||||
}
|
||||
$n = $translation->appendChild($dom->createElement('note'));
|
||||
$n->appendChild($dom->createTextNode($note['content']));
|
||||
if (isset($note['priority'])) {
|
||||
$n->setAttribute('priority', $note['priority']);
|
||||
}
|
||||
if (isset($note['from'])) {
|
||||
$n->setAttribute('from', $note['from']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$xliffBody->appendChild($translation);
|
||||
}
|
||||
return $dom->saveXML();
|
||||
}
|
||||
private function dumpXliff2(string $defaultLocale, MessageCatalogue $messages, ?string $domain) : string
|
||||
{
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
$dom->formatOutput = \true;
|
||||
$xliff = $dom->appendChild($dom->createElement('xliff'));
|
||||
$xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:2.0');
|
||||
$xliff->setAttribute('version', '2.0');
|
||||
$xliff->setAttribute('srcLang', \str_replace('_', '-', $defaultLocale));
|
||||
$xliff->setAttribute('trgLang', \str_replace('_', '-', $messages->getLocale()));
|
||||
$xliffFile = $xliff->appendChild($dom->createElement('file'));
|
||||
if (\str_ends_with($domain, MessageCatalogue::INTL_DOMAIN_SUFFIX)) {
|
||||
$xliffFile->setAttribute('id', \substr($domain, 0, -\strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX)) . '.' . $messages->getLocale());
|
||||
} else {
|
||||
$xliffFile->setAttribute('id', $domain . '.' . $messages->getLocale());
|
||||
}
|
||||
if ($catalogueMetadata = $messages->getCatalogueMetadata('', $domain) ?? []) {
|
||||
$xliff->setAttribute('xmlns:m', 'urn:oasis:names:tc:xliff:metadata:2.0');
|
||||
$xliffMetadata = $xliffFile->appendChild($dom->createElement('m:metadata'));
|
||||
foreach ($catalogueMetadata as $key => $value) {
|
||||
$xliffMeta = $xliffMetadata->appendChild($dom->createElement('prop'));
|
||||
$xliffMeta->setAttribute('type', $key);
|
||||
$xliffMeta->appendChild($dom->createTextNode($value));
|
||||
}
|
||||
}
|
||||
foreach ($messages->all($domain) as $source => $target) {
|
||||
$translation = $dom->createElement('unit');
|
||||
$translation->setAttribute('id', \strtr(\substr(\base64_encode(\hash('sha256', $source, \true)), 0, 7), '/+', '._'));
|
||||
if (\strlen($source) <= 80) {
|
||||
$translation->setAttribute('name', $source);
|
||||
}
|
||||
$metadata = $messages->getMetadata($source, $domain);
|
||||
// Add notes section
|
||||
if ($this->hasMetadataArrayInfo('notes', $metadata)) {
|
||||
$notesElement = $dom->createElement('notes');
|
||||
foreach ($metadata['notes'] as $note) {
|
||||
$n = $dom->createElement('note');
|
||||
$n->appendChild($dom->createTextNode($note['content'] ?? ''));
|
||||
unset($note['content']);
|
||||
foreach ($note as $name => $value) {
|
||||
$n->setAttribute($name, $value);
|
||||
}
|
||||
$notesElement->appendChild($n);
|
||||
}
|
||||
$translation->appendChild($notesElement);
|
||||
}
|
||||
$segment = $translation->appendChild($dom->createElement('segment'));
|
||||
$s = $segment->appendChild($dom->createElement('source'));
|
||||
$s->appendChild($dom->createTextNode($source));
|
||||
// Does the target contain characters requiring a CDATA section?
|
||||
$text = 1 === \preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
|
||||
$targetElement = $dom->createElement('target');
|
||||
if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
|
||||
foreach ($metadata['target-attributes'] as $name => $value) {
|
||||
$targetElement->setAttribute($name, $value);
|
||||
}
|
||||
}
|
||||
$t = $segment->appendChild($targetElement);
|
||||
$t->appendChild($text);
|
||||
$xliffFile->appendChild($translation);
|
||||
}
|
||||
return $dom->saveXML();
|
||||
}
|
||||
private function hasMetadataArrayInfo(string $key, array $metadata = null) : bool
|
||||
{
|
||||
return \is_iterable($metadata[$key] ?? null);
|
||||
}
|
||||
}
|
47
dependencies/symfony/translation/Dumper/YamlFileDumper.php
vendored
Normal file
47
dependencies/symfony/translation/Dumper/YamlFileDumper.php
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Symfony\Component\Translation\Dumper;
|
||||
|
||||
use Symfony\Component\Translation\Exception\LogicException;
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
use Symfony\Component\Translation\Util\ArrayConverter;
|
||||
use WP_Ultimo\Dependencies\Symfony\Component\Yaml\Yaml;
|
||||
/**
|
||||
* YamlFileDumper generates yaml files from a message catalogue.
|
||||
*
|
||||
* @author Michel Salib <michelsalib@hotmail.com>
|
||||
*/
|
||||
class YamlFileDumper extends \Symfony\Component\Translation\Dumper\FileDumper
|
||||
{
|
||||
private string $extension;
|
||||
public function __construct(string $extension = 'yml')
|
||||
{
|
||||
$this->extension = $extension;
|
||||
}
|
||||
public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []) : string
|
||||
{
|
||||
if (!\class_exists(Yaml::class)) {
|
||||
throw new LogicException('Dumping translations in the YAML format requires the Symfony Yaml component.');
|
||||
}
|
||||
$data = $messages->all($domain);
|
||||
if (isset($options['as_tree']) && $options['as_tree']) {
|
||||
$data = ArrayConverter::expandToTree($data);
|
||||
}
|
||||
if (isset($options['inline']) && ($inline = (int) $options['inline']) > 0) {
|
||||
return Yaml::dump($data, $inline);
|
||||
}
|
||||
return Yaml::dump($data);
|
||||
}
|
||||
protected function getExtension() : string
|
||||
{
|
||||
return $this->extension;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user