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