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