NodeBuilder.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien.potencier@symfony-project.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 config tree.
  13. *
  14. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  15. */
  16. class NodeBuilder
  17. {
  18. /************
  19. * READ-ONLY
  20. ************/
  21. public $name;
  22. public $type;
  23. public $key;
  24. public $parent;
  25. public $children;
  26. public $prototype;
  27. public $normalization;
  28. public $validation;
  29. public $merge;
  30. public $finalization;
  31. public $defaultValue;
  32. public $default;
  33. public $addDefaults;
  34. public $required;
  35. public $atLeastOne;
  36. public $allowNewKeys;
  37. public $allowEmptyValue;
  38. public $nullEquivalent;
  39. public $trueEquivalent;
  40. public $falseEquivalent;
  41. public $performDeepMerging;
  42. public $allowUnnamedChildren;
  43. /**
  44. * Constructor
  45. *
  46. * @param string $name the name of the node
  47. * @param string $type The type of the node
  48. * @param NodeBuilder $parent
  49. */
  50. public function __construct($name, $type, $parent = null)
  51. {
  52. $this->name = $name;
  53. $this->type = $type;
  54. $this->parent = $parent;
  55. $this->default = false;
  56. $this->required = false;
  57. $this->addDefaults = false;
  58. $this->allowNewKeys = true;
  59. $this->atLeastOne = false;
  60. $this->allowEmptyValue = true;
  61. $this->children = array();
  62. $this->performDeepMerging = true;
  63. $this->allowUnnamedChildren = false;
  64. if ('boolean' === $type) {
  65. $this->nullEquivalent = true;
  66. } else if ('array' === $type) {
  67. $this->nullEquivalent = array();
  68. }
  69. if ('array' === $type) {
  70. $this->trueEquivalent = array();
  71. } else {
  72. $this->trueEquivalent = true;
  73. }
  74. $this->falseEquivalent = false;
  75. }
  76. /****************************
  77. * FLUID INTERFACE
  78. ****************************/
  79. /**
  80. * Creates a child node.
  81. *
  82. * @param string $name The name of the node
  83. * @param string $type The type of the node
  84. *
  85. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder The builder of the child node
  86. */
  87. public function node($name, $type)
  88. {
  89. $node = new static($name, $type, $this);
  90. return $this->children[$name] = $node;
  91. }
  92. /**
  93. * Creates a child array node
  94. *
  95. * @param string $name The name of the node
  96. *
  97. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder The builder of the child node
  98. */
  99. public function arrayNode($name)
  100. {
  101. return $this->node($name, 'array');
  102. }
  103. /**
  104. * Creates a child scalar node.
  105. *
  106. * @param string $name the name of the node
  107. *
  108. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder The builder of the child node
  109. */
  110. public function scalarNode($name)
  111. {
  112. return $this->node($name, 'scalar');
  113. }
  114. /**
  115. * Creates a child boolean node.
  116. *
  117. * @param string $name The name of the node
  118. *
  119. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder The builder of the child node
  120. */
  121. public function booleanNode($name)
  122. {
  123. return $this->node($name, 'boolean');
  124. }
  125. /**
  126. * Sets the default value.
  127. *
  128. * @param mixed $value The default value
  129. *
  130. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  131. */
  132. public function defaultValue($value)
  133. {
  134. $this->default = true;
  135. $this->defaultValue = $value;
  136. return $this;
  137. }
  138. /**
  139. * Sets the node as required.
  140. *
  141. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  142. */
  143. public function isRequired()
  144. {
  145. $this->required = true;
  146. return $this;
  147. }
  148. /**
  149. * Requires the node to have at least one element.
  150. *
  151. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  152. */
  153. public function requiresAtLeastOneElement()
  154. {
  155. $this->atLeastOne = true;
  156. return $this;
  157. }
  158. /**
  159. * Sets the equivalent value used when the node contains null.
  160. *
  161. * @param mixed $value
  162. *
  163. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  164. */
  165. public function treatNullLike($value)
  166. {
  167. $this->nullEquivalent = $value;
  168. return $this;
  169. }
  170. /**
  171. * Sets the equivalent value used when the node contains true.
  172. *
  173. * @param mixed $value
  174. *
  175. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  176. */
  177. public function treatTrueLike($value)
  178. {
  179. $this->trueEquivalent = $value;
  180. return $this;
  181. }
  182. /**
  183. * Sets the equivalent value used when the node contains false.
  184. *
  185. * @param mixed $value
  186. *
  187. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  188. */
  189. public function treatFalseLike($value)
  190. {
  191. $this->falseEquivalent = $value;
  192. return $this;
  193. }
  194. /**
  195. * Sets null as the default value.
  196. *
  197. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  198. */
  199. public function defaultNull()
  200. {
  201. return $this->defaultValue(null);
  202. }
  203. /**
  204. * Sets true as the default value.
  205. *
  206. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  207. */
  208. public function defaultTrue()
  209. {
  210. return $this->defaultValue(true);
  211. }
  212. /**
  213. * Sets false as the default value.
  214. *
  215. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  216. */
  217. public function defaultFalse()
  218. {
  219. return $this->defaultValue(false);
  220. }
  221. /**
  222. * Adds the default value if the node is not set in the configuration.
  223. *
  224. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  225. */
  226. public function addDefaultsIfNotSet()
  227. {
  228. $this->addDefaults = true;
  229. return $this;
  230. }
  231. /**
  232. * Disallows adding news keys in a subsequent configuration.
  233. *
  234. * If used all keys have to be defined in the same configuration file.
  235. *
  236. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  237. */
  238. public function disallowNewKeysInSubsequentConfigs()
  239. {
  240. $this->allowNewKeys = false;
  241. return $this;
  242. }
  243. /**
  244. * Gets the builder for normalization rules.
  245. *
  246. * @return Symfony\Component\Config\Definition\Builder\NormalizationBuilder
  247. */
  248. protected function normalization()
  249. {
  250. if (null === $this->normalization) {
  251. $this->normalization = new NormalizationBuilder($this);
  252. }
  253. return $this->normalization;
  254. }
  255. /**
  256. * Sets an expression to run before the normalization.
  257. *
  258. * @return Symfony\Component\Config\Definition\Builder\ExprBuilder
  259. */
  260. public function beforeNormalization()
  261. {
  262. return $this->normalization()->before();
  263. }
  264. /**
  265. * Sets a normalization rule for XML configurations.
  266. *
  267. * @param string $singular The key to remap
  268. * @param string $plural The plural of the key for irregular plurals
  269. *
  270. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  271. */
  272. public function fixXmlConfig($singular, $plural = null)
  273. {
  274. $this->normalization()->remap($singular, $plural);
  275. return $this;
  276. }
  277. /**
  278. * Sets an attribute to use as key.
  279. *
  280. * @param string $name
  281. *
  282. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  283. */
  284. public function useAttributeAsKey($name)
  285. {
  286. $this->key = $name;
  287. return $this;
  288. }
  289. /**
  290. * Gets the builder for merging rules.
  291. *
  292. * @return Symfony\Component\Config\Definition\Builder\MergeBuilder
  293. */
  294. protected function merge()
  295. {
  296. if (null === $this->merge) {
  297. $this->merge = new MergeBuilder($this);
  298. }
  299. return $this->merge;
  300. }
  301. /**
  302. * Sets whether the node can be overwritten.
  303. *
  304. * @param boolean $deny Whether the overwritting is forbidden or not
  305. *
  306. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  307. */
  308. public function cannotBeOverwritten($deny = true)
  309. {
  310. $this->merge()->denyOverwrite($deny);
  311. return $this;
  312. }
  313. /**
  314. * Denies the node value being empty.
  315. *
  316. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  317. */
  318. public function cannotBeEmpty()
  319. {
  320. $this->allowEmptyValue = false;
  321. return $this;
  322. }
  323. /**
  324. * Sets whether the node can be unset.
  325. *
  326. * @param boolean $allow
  327. *
  328. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  329. */
  330. public function canBeUnset($allow = true)
  331. {
  332. $this->merge()->allowUnset($allow);
  333. return $this;
  334. }
  335. /**
  336. * Sets a prototype for child nodes.
  337. *
  338. * @param string $type the type of node
  339. *
  340. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  341. */
  342. public function prototype($type)
  343. {
  344. return $this->prototype = new static(null, $type, $this);
  345. }
  346. /**
  347. * Disables the deep merging of the node.
  348. *
  349. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  350. */
  351. public function performNoDeepMerging()
  352. {
  353. $this->performDeepMerging = false;
  354. return $this;
  355. }
  356. /**
  357. * Gets the builder for validation rules.
  358. *
  359. * @return Symfony\Component\Config\Definition\Builder\ValidationBuilder
  360. */
  361. protected function validation()
  362. {
  363. if (null === $this->validation) {
  364. $this->validation = new ValidationBuilder($this);
  365. }
  366. return $this->validation;
  367. }
  368. /**
  369. * Sets an expression to run for the validation.
  370. *
  371. * The expression receives the value of the node and must return it. It can
  372. * modify it.
  373. * An exception should be thrown when the node is not valid.
  374. *
  375. * @return Symfony\Component\Config\Definition\Builder\ExprBuilder
  376. */
  377. public function validate()
  378. {
  379. return $this->validation()->rule();
  380. }
  381. /**
  382. * Returns the parent node.
  383. *
  384. * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
  385. */
  386. public function end()
  387. {
  388. return $this->parent;
  389. }
  390. /**
  391. * Allows child values not represented by a node.
  392. *
  393. * An example would be an "options" array node, where its children
  394. * could be any key of any form. In this case, no children are placed
  395. * on the node, but child values must be allowed.
  396. *
  397. * @return Symfony\Component\DependencyInjection\Configuration\Builder\NodeBuilder
  398. */
  399. public function allowUnnamedChildren()
  400. {
  401. $this->allowUnnamedChildren = true;
  402. return $this;
  403. }
  404. }