NodeBuilder.php 5.2 KB

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