8000 [Translation] add options 'as_tree', 'inline' to YamlFileDumper to du… · symfony/symfony@3c9bca7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3c9bca7

Browse files
committed
[Translation] add options 'as_tree', 'inline' to YamlFileDumper to dump messages as tree instead of simple li 8000 st.
Dump messages as tree based on '.' character as a delimeter in path. For example this rray('foo.bar' => 'value') will be converted to array('foo' => array('bar' => 'value')). Correctly process cases like this ['foo.bar' => 'test1', 'foo' => 'test2'].
1 parent c16930f commit 3c9bca7

File tree

8 files changed

+245
-6
lines changed

8 files changed

+245
-6
lines changed

src/Symfony/Component/Translation/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
2.8.0
5+
-----
6+
7+
* added options 'as_tree', 'inline' to YamlFileDumper
8+
49
2.7.0
510
-----
611

src/Symfony/Component/Translation/Dumper/FileDumper.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,26 @@ public function dump(MessageCatalogue $messages, $options = array())
8282
}
8383
}
8484
// save file
85-
file_put_contents($fullpath, $this->format($messages, $domain));
85+
file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
8686
}
8787
}
8888

89+
/**
90+
* Transforms a domain of a message catalogue to its string representat 8000 ion.
91+
*
92+
* This function is provided for backward compatibility.
93+
*
94+
* @param MessageCatalogue $messages
95+
* @param string $domain
96+
* @param array $options
97+
*
98+
* @return string representation
99+
*/
100+
protected function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
101+
{
102+
return $this->format($messages, $domain);
103+
}
104+
89105
/**
90106
* Transforms a domain of a message catalogue to its string representation.
91107
*

src/Symfony/Component/Translation/Dumper/YamlFileDumper.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Translation\MessageCatalogue;
1515
use Symfony\Component\Yaml\Yaml;
16+
use Symfony\Component\Translation\Util\ArrayConverter;
1617

1718
/**
1819
* YamlFileDumper generates yaml files from a message catalogue.
@@ -24,9 +25,19 @@ class YamlFileDumper extends FileDumper
2425
/**
2526
* {@inheritdoc}
2627
*/
27-
protected function format(MessageCatalogue $messages, $domain)
28+
protected function formatCatalogue(MessageCatalogue $messages, $domain, array $options = array())
2829
{
29-
return Yaml::dump($messages->all($domain));
30+
$data = $messages->all($domain);
31+
32+
if (i A3E2 sset($options['as_tree']) && $options['as_tree']) {
33+
$data = ArrayConverter::expandToTree($data);
34+
}
35+
36+
if (isset($options['inline']) && ($inline = (int) $options['inline']) > 0) {
37+
return Yaml::dump($data, $inline);
38+
}
39+
40+
return Yaml::dump($data);
3041
}
3142

3243
/**
@@ -36,4 +47,12 @@ protected function getExtension()
3647
{
3748
return 'yml';
3849
}
50+
51+
/**
52+
* {@inheritdoc}
53+
*/
54+
protected function format(MessageCatalogue $messages, $domain)
55+
{
56+
return $this->formatCatalogue($messages, $domain);
57+
}
3958
}

src/Symfony/Component/Translation/Tests/Dumper/YamlFileDumperTest.php

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,38 @@
1616

1717
class YamlFileDumperTest extends \PHPUnit_Framework_TestCase
1818
{
19-
public function testDump()
19+
public function testTreeDump()
2020
{
2121
$catalogue = new MessageCatalogue('en');
22-
$catalogue->add(array('foo' => 'bar'));
22+
$catalogue->add(
23+
array(
24+
'foo.bar1' => 'value1',
25+
'foo.bar2' => 'value2',
26+
));
27+
28+
$tempDir = sys_get_temp_dir();
29+
$dumper = new YamlFileDumper();
30+
$dumper->dump($catalogue, array('path' => $tempDir, 'as_tree' => true, 'inline' => 999));
31+
32+
$this->assertEquals(file_get_contents(__DIR__.'/../fixtures/messages.yml'), file_get_contents($tempDir.'/messages.en.yml'));
33+
34+
unlink($tempDir.'/messages.en.yml');
35+
}
36+
37+
public function testLinearDump()
38+
{
39+
$catalogue = new MessageCatalogue('en');
40+
$catalogue->add(
41+
array(
42+
'foo.bar1' => 'value1',
43+
'foo.bar2' => 'value2',
44+
));
2345

2446
$tempDir = sys_get_temp_dir();
2547
$dumper = new YamlFileDumper();
2648
$dumper->dump($catalogue, array('path' => $tempDir));
2749

28-
$this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.yml'), file_get_contents($tempDir.'/messages.en.yml'));
50+
$this->assertEquals(file_get_contents(__DIR__.'/../fixtures/messages_linear.yml'), file_get_contents($tempDir.'/messages.en.yml'));
2951

3052
unlink($tempDir.'/messages.en.yml');
3153
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation\Tests\Util;
13+
14+
use Symfony\Component\Translation\Util\ArrayConverter;
15+
16+
class ArrayConverterTest extends \PHPUnit_Framework_TestCase
17+
{
18+
/**
19+
* @dataProvider messsagesData
20+
*/
21+
public function testDump($input, $expectedOutput)
22+
{
23+
$this->assertEquals($expectedOutput, ArrayConverter::expandToTree($input));
24+
}
25+
26+
public function messsagesData()
27+
{
28+
return array(
29+
array(
30+
// input
31+
array(
32+
'foo1' => 'bar',
33+
'foo.bar' => 'value',
34+
),
35+
// expected output
36+
array(
37+
'foo1' => 'bar',
38+
'foo' => array('bar' => 'value'),
39+
),
40+
),
41+
array(
42+
// input
43+
array(
44+
'foo.bar' => 'value1',
45+
'foo.bar.test' => 'value2',
46+
),
47+
// expected output
48+
array(
49+
'foo' => array(
50+
'bar' => 'value1',
51+
'bar.test' => 'value2',
52+
),
53+
),
54+
),
55+
array(
56+
// input
57+
array(
58+
'foo.level2.level3.level4' => 'value1',
59+
'foo.level2' => 'value2',
60+
'foo.bar' => 'value3',
61+
),
62+
// expected output
63+
array(
64+
'foo' => array(
65+
'level2' => 'value2',
66+
'level2.level3.level4' => 'value1',
67+
'bar' => 'value3',
68+
),
69+
),
70+
),
71+
);
72+
}
73+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
foo:
2+
bar1: value1
3+
bar2: value2
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
foo.bar1: value1
2+
foo.bar2: value2
Lines changed: 99 additions & 0 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation\Util;
13+
14+
/**
15+
* ArrayConverter generates tree like structure from a message catalogue.
16+
* e.g. this
17+
* 'foo.bar1' => 'test1',
18+
* 'foo.bar2' => 'test2'
19+
* converts to follows:
20+
* foo:
21+
* bar1: test1
22+
* bar2: test2.
23+
*
24+
* @author Gennady Telegin <gtelegin@gmail.com>
25+
*/
26+
class ArrayConverter
27+
{
28+
/**
29+
* Converts linear messages array to tree-like array.
30+
* For example this rray('foo.bar' => 'value') will be converted to array('foo' => array('bar' => 'value')).
31+
*
32+
* @param array $messages Linear messages array
33+
*
34+
* @return array Tree-like messages array
35+
*/
36+
public static function expandToTree(array $messages)
37+
{
38+
$tree = array();
39+
40+
foreach ($messages as $id => $value) {
41+
$referenceToElement = &self::getElementByPath($tree, explode('.', $id));
42+
43+
$referenceToElement = $value;
44+
45+
unset($referenceToElement);
46+
}
47+
48+
return $tree;
49+
}
50+
51+
private static function &getElementByPath(array &$tree, array $parts)
52+
{
53+
$elem = &$tree;
54+
$parentOfElem = null;
55+
56+
foreach ($parts as $i => $part) {
57+
if (isset($elem[$part]) && is_string($elem[$part])) {
58+
/* Process next case:
59+
* 'foo': 'test1',
60+
* 'foo.bar': 'test2'
61+
*
62+
* $tree['foo'] was string before we found array {bar: test2}.
63+
* Treat new element as string too, e.g. add $tree['foo.bar'] = 'test2';
64+
*/
65+
$elem = &$elem[ implode('.', array_slice($parts, $i)) ];
66+
break;
67+
}
68+
$parentOfElem = &$elem;
69+
$elem = &$elem[$part];
70+
}
71+
72+
if (is_array($elem) && count($elem) > 0 && $parentOfElem) {
73+
/* Process next case:
74+
* 'foo.bar': 'test1'
75+
* 'foo': 'test2'
76+
*
77+
* $tree['foo'] was array = {bar: 'test1'} before we found string constant `foo`.
78+
* Cancel treating $tree['foo'] as array and cancel back it expansion,
79+
* e.g. make it $tree['foo.bar'] = 'test1' again.
80+
*/
81+
self::cancelExpand($parentOfElem, $part, $elem);
82+
}
83+
84+
return $elem;
85+
}
86+
87+
private static function cancelExpand(array &$tree, $prefix, array $node)
88+
{
89+
$prefix .= '.';
90+
91+
foreach ($node as $id => $value) {
92+
if (is_string($value)) {
93+
$tree[$prefix.$id] = $value;
94+
} else {
95+
self::cancelExpand($tree, $prefix.$id, $value);
96+
}
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)
0