NodeBuilder.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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\Builder;
  11. /**
  12. * This class provides a fluent interface for building a node.
  13. *
  14. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  15. */
  16. class NodeBuilder implements NodeParentInterface
  17. {
  18. protected $parent;
  19. protected $nodeMapping;
  20. /**
  21. * Constructor.
  22. */
  23. public function __construct()
  24. {
  25. $this->nodeMapping = array(
  26. 'variable' => __NAMESPACE__.'\\VariableNodeDefinition',
  27. 'scalar' => __NAMESPACE__.'\\ScalarNodeDefinition',
  28. 'boolean' => __NAMESPACE__.'\\BooleanNodeDefinition',
  29. 'integer' => __NAMESPACE__.'\\IntegerNodeDefinition',
  30. 'float' => __NAMESPACE__.'\\FloatNodeDefinition',
  31. 'array' => __NAMESPACE__.'\\ArrayNodeDefinition',
  32. 'enum' => __NAMESPACE__.'\\EnumNodeDefinition',
  33. );
  34. }
  35. /**
  36. * Set the parent node.
  37. *
  38. * @param ParentNodeDefinitionInterface $parent The parent node
  39. *
  40. * @return $this
  41. */
  42. public function setParent(ParentNodeDefinitionInterface $parent = null)
  43. {
  44. $this->parent = $parent;
  45. return $this;
  46. }
  47. /**
  48. * Creates a child array node.
  49. *
  50. * @param string $name The name of the node
  51. *
  52. * @return ArrayNodeDefinition The child node
  53. */
  54. public function arrayNode($name)
  55. {
  56. return $this->node($name, 'array');
  57. }
  58. /**
  59. * Creates a child scalar node.
  60. *
  61. * @param string $name the name of the node
  62. *
  63. * @return ScalarNodeDefinition The child node
  64. */
  65. public function scalarNode($name)
  66. {
  67. return $this->node($name, 'scalar');
  68. }
  69. /**
  70. * Creates a child Boolean node.
  71. *
  72. * @param string $name The name of the node
  73. *
  74. * @return BooleanNodeDefinition The child node
  75. */
  76. public function booleanNode($name)
  77. {
  78. return $this->node($name, 'boolean');
  79. }
  80. /**
  81. * Creates a child integer node.
  82. *
  83. * @param string $name the name of the node
  84. *
  85. * @return IntegerNodeDefinition The child node
  86. */
  87. public function integerNode($name)
  88. {
  89. return $this->node($name, 'integer');
  90. }
  91. /**
  92. * Creates a child float node.
  93. *
  94. * @param string $name the name of the node
  95. *
  96. * @return FloatNodeDefinition The child node
  97. */
  98. public function floatNode($name)
  99. {
  100. return $this->node($name, 'float');
  101. }
  102. /**
  103. * Creates a child EnumNode.
  104. *
  105. * @param string $name
  106. *
  107. * @return EnumNodeDefinition
  108. */
  109. public function enumNode($name)
  110. {
  111. return $this->node($name, 'enum');
  112. }
  113. /**
  114. * Creates a child variable node.
  115. *
  116. * @param string $name The name of the node
  117. *
  118. * @return VariableNodeDefinition The builder of the child node
  119. */
  120. public function variableNode($name)
  121. {
  122. return $this->node($name, 'variable');
  123. }
  124. /**
  125. * Returns the parent node.
  126. *
  127. * @return ParentNodeDefinitionInterface|NodeDefinition The parent node
  128. */
  129. public function end()
  130. {
  131. return $this->parent;
  132. }
  133. /**
  134. * Creates a child node.
  135. *
  136. * @param string $name The name of the node
  137. * @param string $type The type of the node
  138. *
  139. * @return NodeDefinition The child node
  140. *
  141. * @throws \RuntimeException When the node type is not registered
  142. * @throws \RuntimeException When the node class is not found
  143. */
  144. public function node($name, $type)
  145. {
  146. $class = $this->getNodeClass($type);
  147. $node = new $class($name);
  148. $this->append($node);
  149. return $node;
  150. }
  151. /**
  152. * Appends a node definition.
  153. *
  154. * Usage:
  155. *
  156. * $node = new ArrayNodeDefinition('name')
  157. * ->children()
  158. * ->scalarNode('foo')->end()
  159. * ->scalarNode('baz')->end()
  160. * ->append($this->getBarNodeDefinition())
  161. * ->end()
  162. * ;
  163. *
  164. * @param NodeDefinition $node
  165. *
  166. * @return $this
  167. */
  168. public function append(NodeDefinition $node)
  169. {
  170. if ($node instanceof ParentNodeDefinitionInterface) {
  171. $builder = clone $this;
  172. $builder->setParent(null);
  173. $node->setBuilder($builder);
  174. }
  175. if (null !== $this->parent) {
  176. $this->parent->append($node);
  177. // Make this builder the node parent to allow for a fluid interface
  178. $node->setParent($this);
  179. }
  180. return $this;
  181. }
  182. /**
  183. * Adds or overrides a node Type.
  184. *
  185. * @param string $type The name of the type
  186. * @param string $class The fully qualified name the node definition class
  187. *
  188. * @return $this
  189. */
  190. public function setNodeClass($type, $class)
  191. {
  192. $this->nodeMapping[strtolower($type)] = $class;
  193. return $this;
  194. }
  195. /**
  196. * Returns the class name of the node definition.
  197. *
  198. * @param string $type The node type
  199. *
  200. * @return string The node definition class name
  201. *
  202. * @throws \RuntimeException When the node type is not registered
  203. * @throws \RuntimeException When the node class is not found
  204. */
  205. protected function getNodeClass($type)
  206. {
  207. $type = strtolower($type);
  208. if (!isset($this->nodeMapping[$type])) {
  209. throw new \RuntimeException(sprintf('The node type "%s" is not registered.', $type));
  210. }
  211. $class = $this->nodeMapping[$type];
  212. if (!class_exists($class)) {
  213. throw new \RuntimeException(sprintf('The node class "%s" does not exist.', $class));
  214. }
  215. return $class;
  216. }
  217. }