b98e7ce826e4a0339154397ea71d9c50c4ff842d
[yaffs-website] / vendor / symfony / translation / Util / ArrayConverter.php
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 }