[Intl] Fixed a few bugs in TextBundleWriter
This commit is contained in:
parent
a45e3da3e4
commit
7b4a35a844
|
@ -0,0 +1,25 @@
|
|||
<?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\Intl\Exception;
|
||||
|
||||
/**
|
||||
* Thrown when a method argument had an unexpected type.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class UnexpectedTypeException extends InvalidArgumentException
|
||||
{
|
||||
public function __construct($value, $expectedType)
|
||||
{
|
||||
parent::__construct(sprintf('Expected argument of type "%s", "%s" given', $expectedType, is_object($value) ? get_class($value) : gettype($value)));
|
||||
}
|
||||
}
|
|
@ -11,11 +11,14 @@
|
|||
|
||||
namespace Symfony\Component\Intl\ResourceBundle\Writer;
|
||||
|
||||
use Symfony\Component\Intl\Exception\UnexpectedTypeException;
|
||||
|
||||
/**
|
||||
* Writes .txt resource bundles.
|
||||
*
|
||||
* The resulting files can be converted to binary .res files using the
|
||||
* {@link \Symfony\Component\Intl\ResourceBundle\Transformer\BundleCompiler}.
|
||||
* The resulting files can be converted to binary .res files using a
|
||||
* {@link \Symfony\Component\Intl\ResourceBundle\Compiler\BundleCompilerInterface}
|
||||
* implementation.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
|
@ -28,11 +31,11 @@ class TextBundleWriter implements BundleWriterInterface
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write($path, $locale, $data)
|
||||
public function write($path, $locale, $data, $fallback = true)
|
||||
{
|
||||
$file = fopen($path.'/'.$locale.'.txt', 'w');
|
||||
|
||||
$this->writeResourceBundle($file, $locale, $data);
|
||||
$this->writeResourceBundle($file, $locale, $data, $fallback);
|
||||
|
||||
fclose($file);
|
||||
}
|
||||
|
@ -43,14 +46,16 @@ class TextBundleWriter implements BundleWriterInterface
|
|||
* @param resource $file The file handle to write to.
|
||||
* @param string $bundleName The name of the bundle.
|
||||
* @param mixed $value The value of the node.
|
||||
* @param bool $fallback Whether the resource bundle should be merged
|
||||
* with the fallback locale.
|
||||
*
|
||||
* @see http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt
|
||||
*/
|
||||
private function writeResourceBundle($file, $bundleName, $value)
|
||||
private function writeResourceBundle($file, $bundleName, $value, $fallback)
|
||||
{
|
||||
fwrite($file, $bundleName);
|
||||
|
||||
$this->writeTable($file, $value, 0);
|
||||
$this->writeTable($file, $value, 0, $fallback);
|
||||
|
||||
fwrite($file, "\n");
|
||||
}
|
||||
|
@ -74,16 +79,25 @@ class TextBundleWriter implements BundleWriterInterface
|
|||
return;
|
||||
}
|
||||
|
||||
if ($value instanceof \Traversable) {
|
||||
$value = iterator_to_array($value);
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
if (count($value) === count(array_filter($value, 'is_int'))) {
|
||||
$intValues = count($value) === count(array_filter($value, 'is_int'));
|
||||
|
||||
$keys = array_keys($value);
|
||||
|
||||
// check that the keys are 0-indexed and ascending
|
||||
$intKeys = $keys === range(0, count($keys) - 1);
|
||||
|
||||
if ($intValues && $intKeys) {
|
||||
$this->writeIntVector($file, $value, $indentation);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$keys = array_keys($value);
|
||||
|
||||
if (count($keys) === count(array_filter($keys, 'is_int'))) {
|
||||
if ($intKeys) {
|
||||
$this->writeArray($file, $value, $indentation);
|
||||
|
||||
return;
|
||||
|
@ -183,15 +197,34 @@ class TextBundleWriter implements BundleWriterInterface
|
|||
* Writes a "table" node.
|
||||
*
|
||||
* @param resource $file The file handle to write to.
|
||||
* @param array $value The value of the node.
|
||||
* @param array|\Traversable $value The value of the node.
|
||||
* @param int $indentation The number of levels to indent.
|
||||
* @param bool $fallback Whether the table should be merged
|
||||
* with the fallback locale.
|
||||
*
|
||||
* @throws UnexpectedTypeException When $value is not an array and not a
|
||||
* \Traversable instance.
|
||||
*/
|
||||
private function writeTable($file, array $value, $indentation)
|
||||
private function writeTable($file, $value, $indentation, $fallback = true)
|
||||
{
|
||||
if (!is_array($value) && !$value instanceof \Traversable) {
|
||||
throw new UnexpectedTypeException($value, 'array or \Traversable');
|
||||
}
|
||||
|
||||
if (!$fallback) {
|
||||
fwrite($file, ":table(nofallback)");
|
||||
}
|
||||
|
||||
fwrite($file, "{\n");
|
||||
|
||||
foreach ($value as $key => $entry) {
|
||||
fwrite($file, str_repeat(' ', $indentation + 1));
|
||||
|
||||
// escape colons, otherwise they are interpreted as resource types
|
||||
if (false !== strpos($key, ':') || false !== strpos($key, ' ')) {
|
||||
$key = '"'.$key.'"';
|
||||
}
|
||||
|
||||
fwrite($file, $key);
|
||||
|
||||
$this->writeResource($file, $entry, $indentation + 1);
|
||||
|
|
|
@ -14,6 +14,22 @@ en{
|
|||
2,
|
||||
3,
|
||||
}
|
||||
NotAnIntVector{
|
||||
0:int{0}
|
||||
2:int{1}
|
||||
1:int{2}
|
||||
3:int{3}
|
||||
}
|
||||
IntVectorWithStringKeys{
|
||||
a:int{0}
|
||||
b:int{1}
|
||||
c:int{2}
|
||||
}
|
||||
TableWithIntKeys{
|
||||
0:int{0}
|
||||
1:int{1}
|
||||
3:int{3}
|
||||
}
|
||||
FalseBoolean{"false"}
|
||||
TrueBoolean{"true"}
|
||||
Null{""}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
en_nofallback:table(nofallback){
|
||||
Entry{"Value"}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
escaped{
|
||||
"EntryWith:Colon"{"Value"}
|
||||
"Entry With Spaces"{"Value"}
|
||||
}
|
|
@ -54,6 +54,9 @@ class TextBundleWriterTest extends \PHPUnit_Framework_TestCase
|
|||
'Array' => array('foo', 'bar', array('Key' => 'value')),
|
||||
'Integer' => 5,
|
||||
'IntVector' => array(0, 1, 2, 3),
|
||||
'NotAnIntVector' => array(0 => 0, 2 => 1, 1 => 2, 3 => 3),
|
||||
'IntVectorWithStringKeys' => array('a' => 0, 'b' => 1, 'c' => 2),
|
||||
'TableWithIntKeys' => array(0 => 0, 1 => 1, 3 => 3),
|
||||
'FalseBoolean' => false,
|
||||
'TrueBoolean' => true,
|
||||
'Null' => null,
|
||||
|
@ -64,4 +67,49 @@ class TextBundleWriterTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
$this->assertFileEquals(__DIR__.'/Fixtures/en.txt', $this->directory.'/en.txt');
|
||||
}
|
||||
|
||||
public function testWriteTraversable()
|
||||
{
|
||||
$this->writer->write($this->directory, 'en', new \ArrayIterator(array(
|
||||
'Entry1' => new \ArrayIterator(array(
|
||||
'Array' => array('foo', 'bar', array('Key' => 'value')),
|
||||
'Integer' => 5,
|
||||
'IntVector' => array(0, 1, 2, 3),
|
||||
'NotAnIntVector' => array(0 => 0, 2 => 1, 1 => 2, 3 => 3),
|
||||
'IntVectorWithStringKeys' => array('a' => 0, 'b' => 1, 'c' => 2),
|
||||
'TableWithIntKeys' => array(0 => 0, 1 => 1, 3 => 3),
|
||||
'FalseBoolean' => false,
|
||||
'TrueBoolean' => true,
|
||||
'Null' => null,
|
||||
'Float' => 1.23,
|
||||
)),
|
||||
'Entry2' => 'String',
|
||||
)));
|
||||
|
||||
$this->assertFileEquals(__DIR__.'/Fixtures/en.txt', $this->directory.'/en.txt');
|
||||
}
|
||||
|
||||
public function testWriteNoFallback()
|
||||
{
|
||||
$data = array(
|
||||
'Entry' => 'Value'
|
||||
);
|
||||
|
||||
$this->writer->write($this->directory, 'en_nofallback', $data, $fallback = false);
|
||||
|
||||
$this->assertFileEquals(__DIR__.'/Fixtures/en_nofallback.txt', $this->directory.'/en_nofallback.txt');
|
||||
}
|
||||
|
||||
public function testEscapeKeysIfNecessary()
|
||||
{
|
||||
$this->writer->write($this->directory, 'escaped', array(
|
||||
// Keys with colons must be escaped, otherwise the part after the
|
||||
// colon is interpreted as resource type
|
||||
'EntryWith:Colon' => 'Value',
|
||||
// Keys with spaces must be escaped
|
||||
'Entry With Spaces' => 'Value',
|
||||
));
|
||||
|
||||
$this->assertFileEquals(__DIR__.'/Fixtures/escaped.txt', $this->directory.'/escaped.txt');
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue