[ Index ] |
PHP Cross Reference of phpBB-3.1.12-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12 namespace Symfony\Component\Config\Definition\Builder; 13 14 use Symfony\Component\Config\Definition\ArrayNode; 15 use Symfony\Component\Config\Definition\PrototypedArrayNode; 16 use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException; 17 18 /** 19 * This class provides a fluent interface for defining an array node. 20 * 21 * @author Johannes M. Schmitt <schmittjoh@gmail.com> 22 */ 23 class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinitionInterface 24 { 25 protected $performDeepMerging; 26 protected $ignoreExtraKeys; 27 protected $children; 28 protected $prototype; 29 protected $atLeastOne; 30 protected $allowNewKeys; 31 protected $key; 32 protected $removeKeyItem; 33 protected $addDefaults; 34 protected $addDefaultChildren; 35 protected $nodeBuilder; 36 protected $normalizeKeys; 37 38 /** 39 * {@inheritdoc} 40 */ 41 public function __construct($name, NodeParentInterface $parent = null) 42 { 43 parent::__construct($name, $parent); 44 45 $this->children = array(); 46 $this->addDefaults = false; 47 $this->addDefaultChildren = false; 48 $this->allowNewKeys = true; 49 $this->atLeastOne = false; 50 $this->allowEmptyValue = true; 51 $this->performDeepMerging = true; 52 $this->nullEquivalent = array(); 53 $this->trueEquivalent = array(); 54 $this->normalizeKeys = true; 55 } 56 57 /** 58 * Sets a custom children builder. 59 * 60 * @param NodeBuilder $builder A custom NodeBuilder 61 */ 62 public function setBuilder(NodeBuilder $builder) 63 { 64 $this->nodeBuilder = $builder; 65 } 66 67 /** 68 * Returns a builder to add children nodes. 69 * 70 * @return NodeBuilder 71 */ 72 public function children() 73 { 74 return $this->getNodeBuilder(); 75 } 76 77 /** 78 * Sets a prototype for child nodes. 79 * 80 * @param string $type the type of node 81 * 82 * @return NodeDefinition 83 */ 84 public function prototype($type) 85 { 86 return $this->prototype = $this->getNodeBuilder()->node(null, $type)->setParent($this); 87 } 88 89 /** 90 * Adds the default value if the node is not set in the configuration. 91 * 92 * This method is applicable to concrete nodes only (not to prototype nodes). 93 * If this function has been called and the node is not set during the finalization 94 * phase, it's default value will be derived from its children default values. 95 * 96 * @return ArrayNodeDefinition 97 */ 98 public function addDefaultsIfNotSet() 99 { 100 $this->addDefaults = true; 101 102 return $this; 103 } 104 105 /** 106 * Adds children with a default value when none are defined. 107 * 108 * @param int|string|array|null $children The number of children|The child name|The children names to be added 109 * 110 * This method is applicable to prototype nodes only. 111 * 112 * @return ArrayNodeDefinition 113 */ 114 public function addDefaultChildrenIfNoneSet($children = null) 115 { 116 $this->addDefaultChildren = $children; 117 118 return $this; 119 } 120 121 /** 122 * Requires the node to have at least one element. 123 * 124 * This method is applicable to prototype nodes only. 125 * 126 * @return ArrayNodeDefinition 127 */ 128 public function requiresAtLeastOneElement() 129 { 130 $this->atLeastOne = true; 131 132 return $this; 133 } 134 135 /** 136 * Disallows adding news keys in a subsequent configuration. 137 * 138 * If used all keys have to be defined in the same configuration file. 139 * 140 * @return ArrayNodeDefinition 141 */ 142 public function disallowNewKeysInSubsequentConfigs() 143 { 144 $this->allowNewKeys = false; 145 146 return $this; 147 } 148 149 /** 150 * Sets a normalization rule for XML configurations. 151 * 152 * @param string $singular The key to remap 153 * @param string $plural The plural of the key for irregular plurals 154 * 155 * @return ArrayNodeDefinition 156 */ 157 public function fixXmlConfig($singular, $plural = null) 158 { 159 $this->normalization()->remap($singular, $plural); 160 161 return $this; 162 } 163 164 /** 165 * Sets the attribute which value is to be used as key. 166 * 167 * This is useful when you have an indexed array that should be an 168 * associative array. You can select an item from within the array 169 * to be the key of the particular item. For example, if "id" is the 170 * "key", then: 171 * 172 * array( 173 * array('id' => 'my_name', 'foo' => 'bar'), 174 * ); 175 * 176 * becomes 177 * 178 * array( 179 * 'my_name' => array('foo' => 'bar'), 180 * ); 181 * 182 * If you'd like "'id' => 'my_name'" to still be present in the resulting 183 * array, then you can set the second argument of this method to false. 184 * 185 * This method is applicable to prototype nodes only. 186 * 187 * @param string $name The name of the key 188 * @param bool $removeKeyItem Whether or not the key item should be removed. 189 * 190 * @return ArrayNodeDefinition 191 */ 192 public function useAttributeAsKey($name, $removeKeyItem = true) 193 { 194 $this->key = $name; 195 $this->removeKeyItem = $removeKeyItem; 196 197 return $this; 198 } 199 200 /** 201 * Sets whether the node can be unset. 202 * 203 * @param bool $allow 204 * 205 * @return ArrayNodeDefinition 206 */ 207 public function canBeUnset($allow = true) 208 { 209 $this->merge()->allowUnset($allow); 210 211 return $this; 212 } 213 214 /** 215 * Adds an "enabled" boolean to enable the current section. 216 * 217 * By default, the section is disabled. If any configuration is specified then 218 * the node will be automatically enabled: 219 * 220 * enableableArrayNode: {enabled: true, ...} # The config is enabled & default values get overridden 221 * enableableArrayNode: ~ # The config is enabled & use the default values 222 * enableableArrayNode: true # The config is enabled & use the default values 223 * enableableArrayNode: {other: value, ...} # The config is enabled & default values get overridden 224 * enableableArrayNode: {enabled: false, ...} # The config is disabled 225 * enableableArrayNode: false # The config is disabled 226 * 227 * @return ArrayNodeDefinition 228 */ 229 public function canBeEnabled() 230 { 231 $this 232 ->addDefaultsIfNotSet() 233 ->treatFalseLike(array('enabled' => false)) 234 ->treatTrueLike(array('enabled' => true)) 235 ->treatNullLike(array('enabled' => true)) 236 ->beforeNormalization() 237 ->ifArray() 238 ->then(function ($v) { 239 $v['enabled'] = isset($v['enabled']) ? $v['enabled'] : true; 240 241 return $v; 242 }) 243 ->end() 244 ->children() 245 ->booleanNode('enabled') 246 ->defaultFalse() 247 ; 248 249 return $this; 250 } 251 252 /** 253 * Adds an "enabled" boolean to enable the current section. 254 * 255 * By default, the section is enabled. 256 * 257 * @return ArrayNodeDefinition 258 */ 259 public function canBeDisabled() 260 { 261 $this 262 ->addDefaultsIfNotSet() 263 ->treatFalseLike(array('enabled' => false)) 264 ->treatTrueLike(array('enabled' => true)) 265 ->treatNullLike(array('enabled' => true)) 266 ->children() 267 ->booleanNode('enabled') 268 ->defaultTrue() 269 ; 270 271 return $this; 272 } 273 274 /** 275 * Disables the deep merging of the node. 276 * 277 * @return ArrayNodeDefinition 278 */ 279 public function performNoDeepMerging() 280 { 281 $this->performDeepMerging = false; 282 283 return $this; 284 } 285 286 /** 287 * Allows extra config keys to be specified under an array without 288 * throwing an exception. 289 * 290 * Those config values are simply ignored and removed from the 291 * resulting array. This should be used only in special cases where 292 * you want to send an entire configuration array through a special 293 * tree that processes only part of the array. 294 * 295 * @return ArrayNodeDefinition 296 */ 297 public function ignoreExtraKeys() 298 { 299 $this->ignoreExtraKeys = true; 300 301 return $this; 302 } 303 304 /** 305 * Sets key normalization. 306 * 307 * @param bool $bool Whether to enable key normalization 308 * 309 * @return ArrayNodeDefinition 310 */ 311 public function normalizeKeys($bool) 312 { 313 $this->normalizeKeys = (bool) $bool; 314 315 return $this; 316 } 317 318 /** 319 * Appends a node definition. 320 * 321 * $node = new ArrayNodeDefinition() 322 * ->children() 323 * ->scalarNode('foo')->end() 324 * ->scalarNode('baz')->end() 325 * ->end() 326 * ->append($this->getBarNodeDefinition()) 327 * ; 328 * 329 * @param NodeDefinition $node A NodeDefinition instance 330 * 331 * @return ArrayNodeDefinition This node 332 */ 333 public function append(NodeDefinition $node) 334 { 335 $this->children[$node->name] = $node->setParent($this); 336 337 return $this; 338 } 339 340 /** 341 * Returns a node builder to be used to add children and prototype. 342 * 343 * @return NodeBuilder The node builder 344 */ 345 protected function getNodeBuilder() 346 { 347 if (null === $this->nodeBuilder) { 348 $this->nodeBuilder = new NodeBuilder(); 349 } 350 351 return $this->nodeBuilder->setParent($this); 352 } 353 354 /** 355 * {@inheritdoc} 356 */ 357 protected function createNode() 358 { 359 if (null === $this->prototype) { 360 $node = new ArrayNode($this->name, $this->parent); 361 362 $this->validateConcreteNode($node); 363 364 $node->setAddIfNotSet($this->addDefaults); 365 366 foreach ($this->children as $child) { 367 $child->parent = $node; 368 $node->addChild($child->getNode()); 369 } 370 } else { 371 $node = new PrototypedArrayNode($this->name, $this->parent); 372 373 $this->validatePrototypeNode($node); 374 375 if (null !== $this->key) { 376 $node->setKeyAttribute($this->key, $this->removeKeyItem); 377 } 378 379 if (true === $this->atLeastOne) { 380 $node->setMinNumberOfElements(1); 381 } 382 383 if ($this->default) { 384 $node->setDefaultValue($this->defaultValue); 385 } 386 387 if (false !== $this->addDefaultChildren) { 388 $node->setAddChildrenIfNoneSet($this->addDefaultChildren); 389 if ($this->prototype instanceof static && null === $this->prototype->prototype) { 390 $this->prototype->addDefaultsIfNotSet(); 391 } 392 } 393 394 $this->prototype->parent = $node; 395 $node->setPrototype($this->prototype->getNode()); 396 } 397 398 $node->setAllowNewKeys($this->allowNewKeys); 399 $node->addEquivalentValue(null, $this->nullEquivalent); 400 $node->addEquivalentValue(true, $this->trueEquivalent); 401 $node->addEquivalentValue(false, $this->falseEquivalent); 402 $node->setPerformDeepMerging($this->performDeepMerging); 403 $node->setRequired($this->required); 404 $node->setIgnoreExtraKeys($this->ignoreExtraKeys); 405 $node->setNormalizeKeys($this->normalizeKeys); 406 407 if (null !== $this->normalization) { 408 $node->setNormalizationClosures($this->normalization->before); 409 $node->setXmlRemappings($this->normalization->remappings); 410 } 411 412 if (null !== $this->merge) { 413 $node->setAllowOverwrite($this->merge->allowOverwrite); 414 $node->setAllowFalse($this->merge->allowFalse); 415 } 416 417 if (null !== $this->validation) { 418 $node->setFinalValidationClosures($this->validation->rules); 419 } 420 421 return $node; 422 } 423 424 /** 425 * Validate the configuration of a concrete node. 426 * 427 * @param ArrayNode $node The related node 428 * 429 * @throws InvalidDefinitionException 430 */ 431 protected function validateConcreteNode(ArrayNode $node) 432 { 433 $path = $node->getPath(); 434 435 if (null !== $this->key) { 436 throw new InvalidDefinitionException( 437 sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s"', $path) 438 ); 439 } 440 441 if (true === $this->atLeastOne) { 442 throw new InvalidDefinitionException( 443 sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s"', $path) 444 ); 445 } 446 447 if ($this->default) { 448 throw new InvalidDefinitionException( 449 sprintf('->defaultValue() is not applicable to concrete nodes at path "%s"', $path) 450 ); 451 } 452 453 if (false !== $this->addDefaultChildren) { 454 throw new InvalidDefinitionException( 455 sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s"', $path) 456 ); 457 } 458 } 459 460 /** 461 * Validate the configuration of a prototype node. 462 * 463 * @param PrototypedArrayNode $node The related node 464 * 465 * @throws InvalidDefinitionException 466 */ 467 protected function validatePrototypeNode(PrototypedArrayNode $node) 468 { 469 $path = $node->getPath(); 470 471 if ($this->addDefaults) { 472 throw new InvalidDefinitionException( 473 sprintf('->addDefaultsIfNotSet() is not applicable to prototype nodes at path "%s"', $path) 474 ); 475 } 476 477 if (false !== $this->addDefaultChildren) { 478 if ($this->default) { 479 throw new InvalidDefinitionException( 480 sprintf('A default value and default children might not be used together at path "%s"', $path) 481 ); 482 } 483 484 if (null !== $this->key && (null === $this->addDefaultChildren || is_int($this->addDefaultChildren) && $this->addDefaultChildren > 0)) { 485 throw new InvalidDefinitionException( 486 sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s"', $path) 487 ); 488 } 489 490 if (null === $this->key && (is_string($this->addDefaultChildren) || is_array($this->addDefaultChildren))) { 491 throw new InvalidDefinitionException( 492 sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s"', $path) 493 ); 494 } 495 } 496 } 497 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |