[Translation][Extractor] Allow extracting an array of files besides extracting a directory
This commit is contained in:
parent
1a4d7d7e48
commit
9d6596c69b
@ -7,6 +7,7 @@ CHANGELOG
|
||||
* added LogoutUrlExtension (provides `logout_url` and `logout_path`)
|
||||
* added an HttpFoundation extension (provides the `absolute_url` and the `relative_path` functions)
|
||||
* added AssetExtension (provides the `asset` and `asset_version` functions)
|
||||
* Added possibility to extract translation messages from a file or files besides extracting from a directory
|
||||
|
||||
2.5.0
|
||||
-----
|
||||
|
@ -0,0 +1 @@
|
||||
<h1>{{ 'Hi!'|trans }}</h1>
|
@ -83,4 +83,42 @@ class TwigExtractorTest extends \PHPUnit_Framework_TestCase
|
||||
$extractor = new TwigExtractor($twig);
|
||||
$extractor->extract(__DIR__.'/../Fixtures', new MessageCatalogue('en'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider resourceProvider
|
||||
*/
|
||||
public function testExtractWithFiles($resource)
|
||||
{
|
||||
$loader = new \Twig_Loader_Array(array());
|
||||
$twig = new \Twig_Environment($loader, array(
|
||||
'strict_variables' => true,
|
||||
'debug' => true,
|
||||
'cache' => false,
|
||||
'autoescape' => false,
|
||||
));
|
||||
$twig->addExtension(new TranslationExtension($this->getMock('Symfony\Component\Translation\TranslatorInterface')));
|
||||
|
||||
$extractor = new TwigExtractor($twig);
|
||||
$catalogue = new MessageCatalogue('en');
|
||||
$extractor->extract($resource, $catalogue);
|
||||
|
||||
$this->assertTrue($catalogue->has('Hi!', 'messages'));
|
||||
$this->assertEquals('Hi!', $catalogue->get('Hi!', 'messages'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function resourceProvider()
|
||||
{
|
||||
$directory = __DIR__.'/../Fixtures/extractor/';
|
||||
|
||||
return array(
|
||||
array($directory.'with_translations.html.twig'),
|
||||
array(array($directory.'with_translations.html.twig')),
|
||||
array(array(new \SplFileInfo($directory.'with_translations.html.twig'))),
|
||||
array(new \ArrayObject(array($directory.'with_translations.html.twig'))),
|
||||
array(new \ArrayObject(array(new \SplFileInfo($directory.'with_translations.html.twig')))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Bridge\Twig\Translation;
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Translation\Extractor\AbstractFileExtractor;
|
||||
use Symfony\Component\Translation\Extractor\ExtractorInterface;
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
|
||||
@ -21,7 +22,7 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
* @author Michel Salib <michelsalib@hotmail.com>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class TwigExtractor implements ExtractorInterface
|
||||
class TwigExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
{
|
||||
/**
|
||||
* Default domain for found messages.
|
||||
@ -52,11 +53,9 @@ class TwigExtractor implements ExtractorInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function extract($directory, MessageCatalogue $catalogue)
|
||||
public function extract($resource, MessageCatalogue $catalogue)
|
||||
{
|
||||
// load any existing translation files
|
||||
$finder = new Finder();
|
||||
$files = $finder->files()->name('*.twig')->sortByName()->in($directory);
|
||||
$files = $this->extractFiles($resource);
|
||||
foreach ($files as $file) {
|
||||
try {
|
||||
$this->extractTemplate(file_get_contents($file->getPathname()), $catalogue);
|
||||
@ -89,4 +88,26 @@ class TwigExtractor implements ExtractorInterface
|
||||
|
||||
$visitor->disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function canBeExtracted($file)
|
||||
{
|
||||
return $this->isFile($file) && 'twig' === pathinfo($file, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $directory
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function extractFromDirectory($directory)
|
||||
{
|
||||
$finder = new Finder();
|
||||
|
||||
return $finder->files()->name('*.twig')->in($directory);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
"symfony/intl": "~2.3|~3.0.0",
|
||||
"symfony/routing": "~2.2|~3.0.0",
|
||||
"symfony/templating": "~2.1|~3.0.0",
|
||||
"symfony/translation": "~2.2|~3.0.0",
|
||||
"symfony/translation": "~2.7|~3.0.0",
|
||||
"symfony/yaml": "~2.0,>=2.0.5|~3.0.0",
|
||||
"symfony/security": "~2.6|~3.0.0",
|
||||
"symfony/stopwatch": "~2.2|~3.0.0",
|
||||
|
@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
2.7.0
|
||||
-----
|
||||
|
||||
* Added possibility to extract translation messages from a file or files besides extracting from a directory
|
||||
|
||||
2.6.0
|
||||
-----
|
||||
|
||||
|
@ -17,7 +17,12 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
|
||||
class PhpExtractorTest extends TestCase
|
||||
{
|
||||
public function testExtraction()
|
||||
/**
|
||||
* @dataProvider resourcesProvider
|
||||
*
|
||||
* @param array|string $resource
|
||||
*/
|
||||
public function testExtraction($resource)
|
||||
{
|
||||
// Arrange
|
||||
$extractor = new PhpExtractor();
|
||||
@ -25,7 +30,7 @@ class PhpExtractorTest extends TestCase
|
||||
$catalogue = new MessageCatalogue('en');
|
||||
|
||||
// Act
|
||||
$extractor->extract(__DIR__.'/../Fixtures/Resources/views/', $catalogue);
|
||||
$extractor->extract($resource, $catalogue);
|
||||
|
||||
$expectedHeredoc = <<<EOF
|
||||
heredoc key with whitespace and escaped \$\n sequences
|
||||
@ -50,4 +55,28 @@ EOF;
|
||||
|
||||
$this->assertEquals($expectedCatalogue, $actualCatalogue);
|
||||
}
|
||||
|
||||
public function resourcesProvider()
|
||||
{
|
||||
$directory = __DIR__.'/../Fixtures/Resources/views/';
|
||||
$splFiles = array();
|
||||
foreach (new \DirectoryIterator($directory) as $fileInfo) {
|
||||
if ($fileInfo->isDot()) {
|
||||
continue;
|
||||
}
|
||||
if ('translation.html.php' === $fileInfo->getBasename()) {
|
||||
$phpFile = $fileInfo->getPathname();
|
||||
}
|
||||
$splFiles[] = $fileInfo->getFileInfo();
|
||||
}
|
||||
|
||||
return array(
|
||||
array($directory),
|
||||
array($phpFile),
|
||||
array(glob($directory.'*')),
|
||||
array($splFiles),
|
||||
array(new \ArrayObject(glob($directory.'*'))),
|
||||
array(new \ArrayObject($splFiles)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Bundle\FrameworkBundle\Translation;
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Translation\Extractor\AbstractFileExtractor;
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
use Symfony\Component\Translation\Extractor\ExtractorInterface;
|
||||
|
||||
@ -20,7 +21,7 @@ use Symfony\Component\Translation\Extractor\ExtractorInterface;
|
||||
*
|
||||
* @author Michel Salib <michelsalib@hotmail.com>
|
||||
*/
|
||||
class PhpExtractor implements ExtractorInterface
|
||||
class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
|
||||
{
|
||||
const MESSAGE_TOKEN = 300;
|
||||
|
||||
@ -54,11 +55,9 @@ class PhpExtractor implements ExtractorInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function extract($directory, MessageCatalogue $catalog)
|
||||
public function extract($resource, MessageCatalogue $catalog)
|
||||
{
|
||||
// load any existing translation files
|
||||
$finder = new Finder();
|
||||
$files = $finder->files()->name('*.php')->in($directory);
|
||||
$files = $this->extractFiles($resource);
|
||||
foreach ($files as $file) {
|
||||
$this->parseTokens(token_get_all(file_get_contents($file)), $catalog);
|
||||
}
|
||||
@ -174,4 +173,28 @@ class PhpExtractor implements ExtractorInterface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function canBeExtracted($file)
|
||||
{
|
||||
return $this->isFile($file) && 'php' === pathinfo($file, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $directory
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function extractFromDirectory($directory)
|
||||
{
|
||||
$finder = new Finder();
|
||||
|
||||
return $finder->files()->name('*.php')->in($directory);
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
"symfony/security-csrf": "~2.6|~3.0.0",
|
||||
"symfony/stopwatch": "~2.3|~3.0.0",
|
||||
"symfony/templating": "~2.1|~3.0.0",
|
||||
"symfony/translation": "~2.6|~3.0.0",
|
||||
"symfony/translation": "~2.7|~3.0.0",
|
||||
"doctrine/annotations": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -0,0 +1,83 @@
|
||||
<?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\Extractor;
|
||||
|
||||
/**
|
||||
* Base class used by classes that extract translation messages from files.
|
||||
*
|
||||
* @author Marcos D. Sánchez <marcosdsanchez@gmail.com>
|
||||
*/
|
||||
abstract class AbstractFileExtractor
|
||||
{
|
||||
/**
|
||||
* @param string|array $resource files, a file or a directory
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function extractFiles($resource)
|
||||
{
|
||||
if (is_array($resource) || $resource instanceof \Traversable) {
|
||||
$files = array();
|
||||
foreach ($resource as $file) {
|
||||
if ($this->canBeExtracted($file)) {
|
||||
$files[] = $this->toSplFileInfo($file);
|
||||
}
|
||||
}
|
||||
} elseif (is_file($resource)) {
|
||||
$files = $this->canBeExtracted($resource) ? array($this->toSplFileInfo($resource)) : array();
|
||||
} else {
|
||||
$files = $this->extractFromDirectory($resource);
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return \SplFileInfo
|
||||
*/
|
||||
private function toSplFileInfo($file)
|
||||
{
|
||||
return ($file instanceof \SplFileInfo) ? $file : new \SplFileInfo($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isFile($file)
|
||||
{
|
||||
if (!is_file($file)) {
|
||||
throw new \InvalidArgumentException(sprintf('The "%s" file does not exist.', $file));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function canBeExtracted($file);
|
||||
|
||||
/**
|
||||
* @param string|array $resource files, a file or a directory
|
||||
*
|
||||
* @return array files to be extracted
|
||||
*/
|
||||
abstract protected function extractFromDirectory($resource);
|
||||
}
|
@ -14,7 +14,7 @@ namespace Symfony\Component\Translation\Extractor;
|
||||
use Symfony\Component\Translation\MessageCatalogue;
|
||||
|
||||
/**
|
||||
* Extracts translation messages from a template directory to the catalogue.
|
||||
* Extracts translation messages from a directory or files to the catalogue.
|
||||
* New found messages are injected to the catalogue using the prefix.
|
||||
*
|
||||
* @author Michel Salib <michelsalib@hotmail.com>
|
||||
@ -22,12 +22,12 @@ use Symfony\Component\Translation\MessageCatalogue;
|
||||
interface ExtractorInterface
|
||||
{
|
||||
/**
|
||||
* Extracts translation messages from a template directory to the catalogue.
|
||||
* Extracts translation messages from files, a file or a directory to the catalogue.
|
||||
*
|
||||
* @param string $directory The path to look into
|
||||
* @param string|array $resource files, a file or a directory
|
||||
* @param MessageCatalogue $catalogue The catalogue
|
||||
*/
|
||||
public function extract($directory, MessageCatalogue $catalogue);
|
||||
public function extract($resource, MessageCatalogue $catalogue);
|
||||
|
||||
/**
|
||||
* Sets the prefix that should be used for new found messages.
|
||||
|
Reference in New Issue
Block a user