[ 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; 13 14 use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; 15 use Symfony\Component\Config\Definition\Exception\InvalidTypeException; 16 use Symfony\Component\Config\Definition\Exception\UnsetKeyException; 17 18 /** 19 * Represents an Array node in the config tree. 20 * 21 * @author Johannes M. Schmitt <schmittjoh@gmail.com> 22 */ 23 class ArrayNode extends BaseNode implements PrototypeNodeInterface 24 { 25 protected $xmlRemappings; 26 protected $children; 27 protected $allowFalse; 28 protected $allowNewKeys; 29 protected $addIfNotSet; 30 protected $performDeepMerging; 31 protected $ignoreExtraKeys; 32 protected $normalizeKeys; 33 34 /** 35 * Constructor. 36 * 37 * @param string $name The Node's name 38 * @param NodeInterface $parent The node parent 39 */ 40 public function __construct($name, NodeInterface $parent = null) 41 { 42 parent::__construct($name, $parent); 43 44 $this->children = array(); 45 $this->xmlRemappings = array(); 46 $this->removeKeyAttribute = true; 47 $this->allowFalse = false; 48 $this->addIfNotSet = false; 49 $this->allowNewKeys = true; 50 $this->performDeepMerging = true; 51 $this->normalizeKeys = true; 52 } 53 54 public function setNormalizeKeys($normalizeKeys) 55 { 56 $this->normalizeKeys = (bool) $normalizeKeys; 57 } 58 59 /** 60 * Normalizes keys between the different configuration formats. 61 * 62 * Namely, you mostly have foo_bar in YAML while you have foo-bar in XML. 63 * After running this method, all keys are normalized to foo_bar. 64 * 65 * If you have a mixed key like foo-bar_moo, it will not be altered. 66 * The key will also not be altered if the target key already exists. 67 * 68 * @param mixed $value 69 * 70 * @return array The value with normalized keys 71 */ 72 protected function preNormalize($value) 73 { 74 if (!$this->normalizeKeys || !is_array($value)) { 75 return $value; 76 } 77 78 $normalized = array(); 79 80 foreach ($value as $k => $v) { 81 if (false !== strpos($k, '-') && false === strpos($k, '_') && !array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) { 82 $normalized[$normalizedKey] = $v; 83 } else { 84 $normalized[$k] = $v; 85 } 86 } 87 88 return $normalized; 89 } 90 91 /** 92 * Retrieves the children of this node. 93 * 94 * @return array The children 95 */ 96 public function getChildren() 97 { 98 return $this->children; 99 } 100 101 /** 102 * Sets the xml remappings that should be performed. 103 * 104 * @param array $remappings an array of the form array(array(string, string)) 105 */ 106 public function setXmlRemappings(array $remappings) 107 { 108 $this->xmlRemappings = $remappings; 109 } 110 111 /** 112 * Sets whether to add default values for this array if it has not been 113 * defined in any of the configuration files. 114 * 115 * @param bool $boolean 116 */ 117 public function setAddIfNotSet($boolean) 118 { 119 $this->addIfNotSet = (bool) $boolean; 120 } 121 122 /** 123 * Sets whether false is allowed as value indicating that the array should be unset. 124 * 125 * @param bool $allow 126 */ 127 public function setAllowFalse($allow) 128 { 129 $this->allowFalse = (bool) $allow; 130 } 131 132 /** 133 * Sets whether new keys can be defined in subsequent configurations. 134 * 135 * @param bool $allow 136 */ 137 public function setAllowNewKeys($allow) 138 { 139 $this->allowNewKeys = (bool) $allow; 140 } 141 142 /** 143 * Sets if deep merging should occur. 144 * 145 * @param bool $boolean 146 */ 147 public function setPerformDeepMerging($boolean) 148 { 149 $this->performDeepMerging = (bool) $boolean; 150 } 151 152 /** 153 * Whether extra keys should just be ignore without an exception. 154 * 155 * @param bool $boolean To allow extra keys 156 */ 157 public function setIgnoreExtraKeys($boolean) 158 { 159 $this->ignoreExtraKeys = (bool) $boolean; 160 } 161 162 /** 163 * Sets the node Name. 164 * 165 * @param string $name The node's name 166 */ 167 public function setName($name) 168 { 169 $this->name = $name; 170 } 171 172 /** 173 * Checks if the node has a default value. 174 * 175 * @return bool 176 */ 177 public function hasDefaultValue() 178 { 179 return $this->addIfNotSet; 180 } 181 182 /** 183 * Retrieves the default value. 184 * 185 * @return array The default value 186 * 187 * @throws \RuntimeException if the node has no default value 188 */ 189 public function getDefaultValue() 190 { 191 if (!$this->hasDefaultValue()) { 192 throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath())); 193 } 194 195 $defaults = array(); 196 foreach ($this->children as $name => $child) { 197 if ($child->hasDefaultValue()) { 198 $defaults[$name] = $child->getDefaultValue(); 199 } 200 } 201 202 return $defaults; 203 } 204 205 /** 206 * Adds a child node. 207 * 208 * @param NodeInterface $node The child node to add 209 * 210 * @throws \InvalidArgumentException when the child node has no name 211 * @throws \InvalidArgumentException when the child node's name is not unique 212 */ 213 public function addChild(NodeInterface $node) 214 { 215 $name = $node->getName(); 216 if (!strlen($name)) { 217 throw new \InvalidArgumentException('Child nodes must be named.'); 218 } 219 if (isset($this->children[$name])) { 220 throw new \InvalidArgumentException(sprintf('A child node named "%s" already exists.', $name)); 221 } 222 223 $this->children[$name] = $node; 224 } 225 226 /** 227 * Finalizes the value of this node. 228 * 229 * @param mixed $value 230 * 231 * @return mixed The finalised value 232 * 233 * @throws UnsetKeyException 234 * @throws InvalidConfigurationException if the node doesn't have enough children 235 */ 236 protected function finalizeValue($value) 237 { 238 if (false === $value) { 239 $msg = sprintf('Unsetting key for path "%s", value: %s', $this->getPath(), json_encode($value)); 240 throw new UnsetKeyException($msg); 241 } 242 243 foreach ($this->children as $name => $child) { 244 if (!array_key_exists($name, $value)) { 245 if ($child->isRequired()) { 246 $msg = sprintf('The child node "%s" at path "%s" must be configured.', $name, $this->getPath()); 247 $ex = new InvalidConfigurationException($msg); 248 $ex->setPath($this->getPath()); 249 250 throw $ex; 251 } 252 253 if ($child->hasDefaultValue()) { 254 $value[$name] = $child->getDefaultValue(); 255 } 256 257 continue; 258 } 259 260 try { 261 $value[$name] = $child->finalize($value[$name]); 262 } catch (UnsetKeyException $e) { 263 unset($value[$name]); 264 } 265 } 266 267 return $value; 268 } 269 270 /** 271 * Validates the type of the value. 272 * 273 * @param mixed $value 274 * 275 * @throws InvalidTypeException 276 */ 277 protected function validateType($value) 278 { 279 if (!is_array($value) && (!$this->allowFalse || false !== $value)) { 280 $ex = new InvalidTypeException(sprintf( 281 'Invalid type for path "%s". Expected array, but got %s', 282 $this->getPath(), 283 gettype($value) 284 )); 285 $ex->setPath($this->getPath()); 286 287 throw $ex; 288 } 289 } 290 291 /** 292 * Normalizes the value. 293 * 294 * @param mixed $value The value to normalize 295 * 296 * @return mixed The normalized value 297 * 298 * @throws InvalidConfigurationException 299 */ 300 protected function normalizeValue($value) 301 { 302 if (false === $value) { 303 return $value; 304 } 305 306 $value = $this->remapXml($value); 307 308 $normalized = array(); 309 foreach ($value as $name => $val) { 310 if (isset($this->children[$name])) { 311 $normalized[$name] = $this->children[$name]->normalize($val); 312 unset($value[$name]); 313 } 314 } 315 316 // if extra fields are present, throw exception 317 if (count($value) && !$this->ignoreExtraKeys) { 318 $msg = sprintf('Unrecognized option%s "%s" under "%s"', 1 === count($value) ? '' : 's', implode(', ', array_keys($value)), $this->getPath()); 319 $ex = new InvalidConfigurationException($msg); 320 $ex->setPath($this->getPath()); 321 322 throw $ex; 323 } 324 325 return $normalized; 326 } 327 328 /** 329 * Remaps multiple singular values to a single plural value. 330 * 331 * @param array $value The source values 332 * 333 * @return array The remapped values 334 */ 335 protected function remapXml($value) 336 { 337 foreach ($this->xmlRemappings as $transformation) { 338 list($singular, $plural) = $transformation; 339 340 if (!isset($value[$singular])) { 341 continue; 342 } 343 344 $value[$plural] = Processor::normalizeConfig($value, $singular, $plural); 345 unset($value[$singular]); 346 } 347 348 return $value; 349 } 350 351 /** 352 * Merges values together. 353 * 354 * @param mixed $leftSide The left side to merge. 355 * @param mixed $rightSide The right side to merge. 356 * 357 * @return mixed The merged values 358 * 359 * @throws InvalidConfigurationException 360 * @throws \RuntimeException 361 */ 362 protected function mergeValues($leftSide, $rightSide) 363 { 364 if (false === $rightSide) { 365 // if this is still false after the last config has been merged the 366 // finalization pass will take care of removing this key entirely 367 return false; 368 } 369 370 if (false === $leftSide || !$this->performDeepMerging) { 371 return $rightSide; 372 } 373 374 foreach ($rightSide as $k => $v) { 375 // no conflict 376 if (!array_key_exists($k, $leftSide)) { 377 if (!$this->allowNewKeys) { 378 $ex = new InvalidConfigurationException(sprintf( 379 'You are not allowed to define new elements for path "%s". ' 380 .'Please define all elements for this path in one config file. ' 381 .'If you are trying to overwrite an element, make sure you redefine it ' 382 .'with the same name.', 383 $this->getPath() 384 )); 385 $ex->setPath($this->getPath()); 386 387 throw $ex; 388 } 389 390 $leftSide[$k] = $v; 391 continue; 392 } 393 394 if (!isset($this->children[$k])) { 395 throw new \RuntimeException('merge() expects a normalized config array.'); 396 } 397 398 $leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v); 399 } 400 401 return $leftSide; 402 } 403 }
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 |