31c3f8e0161fc26737633856847ecbbac1be7fc0
[yaffs-website] / vendor / symfony / config / Definition / Dumper / YamlReferenceDumper.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\Config\Definition\Dumper;
13
14 use Symfony\Component\Config\Definition\ConfigurationInterface;
15 use Symfony\Component\Config\Definition\NodeInterface;
16 use Symfony\Component\Config\Definition\ArrayNode;
17 use Symfony\Component\Config\Definition\EnumNode;
18 use Symfony\Component\Config\Definition\PrototypedArrayNode;
19 use Symfony\Component\Yaml\Inline;
20
21 /**
22  * Dumps a Yaml reference configuration for the given configuration/node instance.
23  *
24  * @author Kevin Bond <kevinbond@gmail.com>
25  */
26 class YamlReferenceDumper
27 {
28     private $reference;
29
30     public function dump(ConfigurationInterface $configuration)
31     {
32         return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree());
33     }
34
35     public function dumpNode(NodeInterface $node)
36     {
37         $this->reference = '';
38         $this->writeNode($node);
39         $ref = $this->reference;
40         $this->reference = null;
41
42         return $ref;
43     }
44
45     /**
46      * @param NodeInterface $node
47      * @param int           $depth
48      */
49     private function writeNode(NodeInterface $node, $depth = 0)
50     {
51         $comments = array();
52         $default = '';
53         $defaultArray = null;
54         $children = null;
55         $example = $node->getExample();
56
57         // defaults
58         if ($node instanceof ArrayNode) {
59             $children = $node->getChildren();
60
61             if ($node instanceof PrototypedArrayNode) {
62                 $prototype = $node->getPrototype();
63
64                 if ($prototype instanceof ArrayNode) {
65                     $children = $prototype->getChildren();
66                 }
67
68                 // check for attribute as key
69                 if ($key = $node->getKeyAttribute()) {
70                     $keyNodeClass = 'Symfony\Component\Config\Definition\\'.($prototype instanceof ArrayNode ? 'ArrayNode' : 'ScalarNode');
71                     $keyNode = new $keyNodeClass($key, $node);
72
73                     $info = 'Prototype';
74                     if (null !== $prototype->getInfo()) {
75                         $info .= ': '.$prototype->getInfo();
76                     }
77                     $keyNode->setInfo($info);
78
79                     // add children
80                     foreach ($children as $childNode) {
81                         $keyNode->addChild($childNode);
82                     }
83                     $children = array($key => $keyNode);
84                 }
85             }
86
87             if (!$children) {
88                 if ($node->hasDefaultValue() && count($defaultArray = $node->getDefaultValue())) {
89                     $default = '';
90                 } elseif (!is_array($example)) {
91                     $default = '[]';
92                 }
93             }
94         } elseif ($node instanceof EnumNode) {
95             $comments[] = 'One of '.implode('; ', array_map('json_encode', $node->getValues()));
96             $default = $node->hasDefaultValue() ? Inline::dump($node->getDefaultValue()) : '~';
97         } else {
98             $default = '~';
99
100             if ($node->hasDefaultValue()) {
101                 $default = $node->getDefaultValue();
102
103                 if (is_array($default)) {
104                     if (count($defaultArray = $node->getDefaultValue())) {
105                         $default = '';
106                     } elseif (!is_array($example)) {
107                         $default = '[]';
108                     }
109                 } else {
110                     $default = Inline::dump($default);
111                 }
112             }
113         }
114
115         // required?
116         if ($node->isRequired()) {
117             $comments[] = 'Required';
118         }
119
120         // example
121         if ($example && !is_array($example)) {
122             $comments[] = 'Example: '.$example;
123         }
124
125         $default = (string) $default != '' ? ' '.$default : '';
126         $comments = count($comments) ? '# '.implode(', ', $comments) : '';
127
128         $text = rtrim(sprintf('%-21s%s %s', $node->getName().':', $default, $comments), ' ');
129
130         if ($info = $node->getInfo()) {
131             $this->writeLine('');
132             // indenting multi-line info
133             $info = str_replace("\n", sprintf("\n%".($depth * 4).'s# ', ' '), $info);
134             $this->writeLine('# '.$info, $depth * 4);
135         }
136
137         $this->writeLine($text, $depth * 4);
138
139         // output defaults
140         if ($defaultArray) {
141             $this->writeLine('');
142
143             $message = count($defaultArray) > 1 ? 'Defaults' : 'Default';
144
145             $this->writeLine('# '.$message.':', $depth * 4 + 4);
146
147             $this->writeArray($defaultArray, $depth + 1);
148         }
149
150         if (is_array($example)) {
151             $this->writeLine('');
152
153             $message = count($example) > 1 ? 'Examples' : 'Example';
154
155             $this->writeLine('# '.$message.':', $depth * 4 + 4);
156
157             $this->writeArray($example, $depth + 1);
158         }
159
160         if ($children) {
161             foreach ($children as $childNode) {
162                 $this->writeNode($childNode, $depth + 1);
163             }
164         }
165     }
166
167     /**
168      * Outputs a single config reference line.
169      *
170      * @param string $text
171      * @param int    $indent
172      */
173     private function writeLine($text, $indent = 0)
174     {
175         $indent = strlen($text) + $indent;
176         $format = '%'.$indent.'s';
177
178         $this->reference .= sprintf($format, $text)."\n";
179     }
180
181     private function writeArray(array $array, $depth)
182     {
183         $isIndexed = array_values($array) === $array;
184
185         foreach ($array as $key => $value) {
186             if (is_array($value)) {
187                 $val = '';
188             } else {
189                 $val = $value;
190             }
191
192             if ($isIndexed) {
193                 $this->writeLine('- '.$val, $depth * 4);
194             } else {
195                 $this->writeLine(sprintf('%-20s %s', $key.':', $val), $depth * 4);
196             }
197
198             if (is_array($value)) {
199                 $this->writeArray($value, $depth + 1);
200             }
201         }
202     }
203 }