NodeBuilder.php 5.7 KB

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