PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/symfony/symfony/src/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php

https://gitlab.com/Isaki/le331.fr
PHP | 300 lines | 196 code | 56 blank | 48 comment | 41 complexity | 354c10e981d35d3eac1d5b3f31bff9a8 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Config\Definition\Dumper;
  11. use Symfony\Component\Config\Definition\ConfigurationInterface;
  12. use Symfony\Component\Config\Definition\NodeInterface;
  13. use Symfony\Component\Config\Definition\ArrayNode;
  14. use Symfony\Component\Config\Definition\EnumNode;
  15. use Symfony\Component\Config\Definition\PrototypedArrayNode;
  16. /**
  17. * Dumps a XML reference configuration for the given configuration/node instance.
  18. *
  19. * @author Wouter J <waldio.webdesign@gmail.com>
  20. */
  21. class XmlReferenceDumper
  22. {
  23. private $reference;
  24. public function dump(ConfigurationInterface $configuration, $namespace = null)
  25. {
  26. return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree(), $namespace);
  27. }
  28. public function dumpNode(NodeInterface $node, $namespace = null)
  29. {
  30. $this->reference = '';
  31. $this->writeNode($node, 0, true, $namespace);
  32. $ref = $this->reference;
  33. $this->reference = null;
  34. return $ref;
  35. }
  36. /**
  37. * @param NodeInterface $node
  38. * @param int $depth
  39. * @param bool $root If the node is the root node
  40. * @param string $namespace The namespace of the node
  41. */
  42. private function writeNode(NodeInterface $node, $depth = 0, $root = false, $namespace = null)
  43. {
  44. $rootName = ($root ? 'config' : $node->getName());
  45. $rootNamespace = ($namespace ?: ($root ? 'http://example.org/schema/dic/'.$node->getName() : null));
  46. // xml remapping
  47. if ($node->getParent()) {
  48. $remapping = array_filter($node->getParent()->getXmlRemappings(), function ($mapping) use ($rootName) {
  49. return $rootName === $mapping[1];
  50. });
  51. if (count($remapping)) {
  52. list($singular) = current($remapping);
  53. $rootName = $singular;
  54. }
  55. }
  56. $rootName = str_replace('_', '-', $rootName);
  57. $rootAttributes = array();
  58. $rootAttributeComments = array();
  59. $rootChildren = array();
  60. $rootComments = array();
  61. if ($node instanceof ArrayNode) {
  62. $children = $node->getChildren();
  63. // comments about the root node
  64. if ($rootInfo = $node->getInfo()) {
  65. $rootComments[] = $rootInfo;
  66. }
  67. if ($rootNamespace) {
  68. $rootComments[] = 'Namespace: '.$rootNamespace;
  69. }
  70. // render prototyped nodes
  71. if ($node instanceof PrototypedArrayNode) {
  72. array_unshift($rootComments, 'prototype');
  73. if ($key = $node->getKeyAttribute()) {
  74. $rootAttributes[$key] = str_replace('-', ' ', $rootName).' '.$key;
  75. }
  76. $prototype = $node->getPrototype();
  77. if ($prototype instanceof ArrayNode) {
  78. $children = $prototype->getChildren();
  79. } else {
  80. if ($prototype->hasDefaultValue()) {
  81. $prototypeValue = $prototype->getDefaultValue();
  82. } else {
  83. switch (get_class($prototype)) {
  84. case 'Symfony\Component\Config\Definition\ScalarNode':
  85. $prototypeValue = 'scalar value';
  86. break;
  87. case 'Symfony\Component\Config\Definition\FloatNode':
  88. case 'Symfony\Component\Config\Definition\IntegerNode':
  89. $prototypeValue = 'numeric value';
  90. break;
  91. case 'Symfony\Component\Config\Definition\BooleanNode':
  92. $prototypeValue = 'true|false';
  93. break;
  94. case 'Symfony\Component\Config\Definition\EnumNode':
  95. $prototypeValue = implode('|', array_map('json_encode', $prototype->getValues()));
  96. break;
  97. default:
  98. $prototypeValue = 'value';
  99. }
  100. }
  101. }
  102. }
  103. // get attributes and elements
  104. foreach ($children as $child) {
  105. if (!$child instanceof ArrayNode) {
  106. // get attributes
  107. // metadata
  108. $name = str_replace('_', '-', $child->getName());
  109. $value = '%%%%not_defined%%%%'; // use a string which isn't used in the normal world
  110. // comments
  111. $comments = array();
  112. if ($info = $child->getInfo()) {
  113. $comments[] = $info;
  114. }
  115. if ($example = $child->getExample()) {
  116. $comments[] = 'Example: '.$example;
  117. }
  118. if ($child->isRequired()) {
  119. $comments[] = 'Required';
  120. }
  121. if ($child instanceof EnumNode) {
  122. $comments[] = 'One of '.implode('; ', array_map('json_encode', $child->getValues()));
  123. }
  124. if (count($comments)) {
  125. $rootAttributeComments[$name] = implode(";\n", $comments);
  126. }
  127. // default values
  128. if ($child->hasDefaultValue()) {
  129. $value = $child->getDefaultValue();
  130. }
  131. // append attribute
  132. $rootAttributes[$name] = $value;
  133. } else {
  134. // get elements
  135. $rootChildren[] = $child;
  136. }
  137. }
  138. }
  139. // render comments
  140. // root node comment
  141. if (count($rootComments)) {
  142. foreach ($rootComments as $comment) {
  143. $this->writeLine('<!-- '.$comment.' -->', $depth);
  144. }
  145. }
  146. // attribute comments
  147. if (count($rootAttributeComments)) {
  148. foreach ($rootAttributeComments as $attrName => $comment) {
  149. $commentDepth = $depth + 4 + strlen($attrName) + 2;
  150. $commentLines = explode("\n", $comment);
  151. $multiline = (count($commentLines) > 1);
  152. $comment = implode(PHP_EOL.str_repeat(' ', $commentDepth), $commentLines);
  153. if ($multiline) {
  154. $this->writeLine('<!--', $depth);
  155. $this->writeLine($attrName.': '.$comment, $depth + 4);
  156. $this->writeLine('-->', $depth);
  157. } else {
  158. $this->writeLine('<!-- '.$attrName.': '.$comment.' -->', $depth);
  159. }
  160. }
  161. }
  162. // render start tag + attributes
  163. $rootIsVariablePrototype = isset($prototypeValue);
  164. $rootIsEmptyTag = (0 === count($rootChildren) && !$rootIsVariablePrototype);
  165. $rootOpenTag = '<'.$rootName;
  166. if (1 >= ($attributesCount = count($rootAttributes))) {
  167. if (1 === $attributesCount) {
  168. $rootOpenTag .= sprintf(' %s="%s"', current(array_keys($rootAttributes)), $this->writeValue(current($rootAttributes)));
  169. }
  170. $rootOpenTag .= $rootIsEmptyTag ? ' />' : '>';
  171. if ($rootIsVariablePrototype) {
  172. $rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
  173. }
  174. $this->writeLine($rootOpenTag, $depth);
  175. } else {
  176. $this->writeLine($rootOpenTag, $depth);
  177. $i = 1;
  178. foreach ($rootAttributes as $attrName => $attrValue) {
  179. $attr = sprintf('%s="%s"', $attrName, $this->writeValue($attrValue));
  180. $this->writeLine($attr, $depth + 4);
  181. if ($attributesCount === $i++) {
  182. $this->writeLine($rootIsEmptyTag ? '/>' : '>', $depth);
  183. if ($rootIsVariablePrototype) {
  184. $rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
  185. }
  186. }
  187. }
  188. }
  189. // render children tags
  190. foreach ($rootChildren as $child) {
  191. $this->writeLine('');
  192. $this->writeNode($child, $depth + 4);
  193. }
  194. // render end tag
  195. if (!$rootIsEmptyTag && !$rootIsVariablePrototype) {
  196. $this->writeLine('');
  197. $rootEndTag = '</'.$rootName.'>';
  198. $this->writeLine($rootEndTag, $depth);
  199. }
  200. }
  201. /**
  202. * Outputs a single config reference line.
  203. *
  204. * @param string $text
  205. * @param int $indent
  206. */
  207. private function writeLine($text, $indent = 0)
  208. {
  209. $indent = strlen($text) + $indent;
  210. $format = '%'.$indent.'s';
  211. $this->reference .= sprintf($format, $text).PHP_EOL;
  212. }
  213. /**
  214. * Renders the string conversion of the value.
  215. *
  216. * @param mixed $value
  217. *
  218. * @return string
  219. */
  220. private function writeValue($value)
  221. {
  222. if ('%%%%not_defined%%%%' === $value) {
  223. return '';
  224. }
  225. if (is_string($value) || is_numeric($value)) {
  226. return $value;
  227. }
  228. if (false === $value) {
  229. return 'false';
  230. }
  231. if (true === $value) {
  232. return 'true';
  233. }
  234. if (null === $value) {
  235. return 'null';
  236. }
  237. if (empty($value)) {
  238. return '';
  239. }
  240. if (is_array($value)) {
  241. return implode(',', $value);
  242. }
  243. }
  244. }