vendor/symfony/symfony/src/Symfony/Component/Config/Definition/BaseNode.php line 309

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.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;
  11. use Symfony\Component\Config\Definition\Exception\Exception;
  12. use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
  13. use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
  14. use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
  15. /**
  16.  * The base node class.
  17.  *
  18.  * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  19.  */
  20. abstract class BaseNode implements NodeInterface
  21. {
  22.     protected $name;
  23.     protected $parent;
  24.     protected $normalizationClosures = [];
  25.     protected $finalValidationClosures = [];
  26.     protected $allowOverwrite true;
  27.     protected $required false;
  28.     protected $deprecationMessage null;
  29.     protected $equivalentValues = [];
  30.     protected $attributes = [];
  31.     /**
  32.      * @param string|null        $name   The name of the node
  33.      * @param NodeInterface|null $parent The parent of this node
  34.      *
  35.      * @throws \InvalidArgumentException if the name contains a period
  36.      */
  37.     public function __construct($nameNodeInterface $parent null)
  38.     {
  39.         if (false !== strpos($name = (string) $name'.')) {
  40.             throw new \InvalidArgumentException('The name must not contain ".".');
  41.         }
  42.         $this->name $name;
  43.         $this->parent $parent;
  44.     }
  45.     public function setAttribute($key$value)
  46.     {
  47.         $this->attributes[$key] = $value;
  48.     }
  49.     public function getAttribute($key$default null)
  50.     {
  51.         return isset($this->attributes[$key]) ? $this->attributes[$key] : $default;
  52.     }
  53.     public function hasAttribute($key)
  54.     {
  55.         return isset($this->attributes[$key]);
  56.     }
  57.     public function getAttributes()
  58.     {
  59.         return $this->attributes;
  60.     }
  61.     public function setAttributes(array $attributes)
  62.     {
  63.         $this->attributes $attributes;
  64.     }
  65.     public function removeAttribute($key)
  66.     {
  67.         unset($this->attributes[$key]);
  68.     }
  69.     /**
  70.      * Sets an info message.
  71.      *
  72.      * @param string $info
  73.      */
  74.     public function setInfo($info)
  75.     {
  76.         $this->setAttribute('info'$info);
  77.     }
  78.     /**
  79.      * Returns info message.
  80.      *
  81.      * @return string The info text
  82.      */
  83.     public function getInfo()
  84.     {
  85.         return $this->getAttribute('info');
  86.     }
  87.     /**
  88.      * Sets the example configuration for this node.
  89.      *
  90.      * @param string|array $example
  91.      */
  92.     public function setExample($example)
  93.     {
  94.         $this->setAttribute('example'$example);
  95.     }
  96.     /**
  97.      * Retrieves the example configuration for this node.
  98.      *
  99.      * @return string|array The example
  100.      */
  101.     public function getExample()
  102.     {
  103.         return $this->getAttribute('example');
  104.     }
  105.     /**
  106.      * Adds an equivalent value.
  107.      *
  108.      * @param mixed $originalValue
  109.      * @param mixed $equivalentValue
  110.      */
  111.     public function addEquivalentValue($originalValue$equivalentValue)
  112.     {
  113.         $this->equivalentValues[] = [$originalValue$equivalentValue];
  114.     }
  115.     /**
  116.      * Set this node as required.
  117.      *
  118.      * @param bool $boolean Required node
  119.      */
  120.     public function setRequired($boolean)
  121.     {
  122.         $this->required = (bool) $boolean;
  123.     }
  124.     /**
  125.      * Sets this node as deprecated.
  126.      *
  127.      * You can use %node% and %path% placeholders in your message to display,
  128.      * respectively, the node name and its complete path.
  129.      *
  130.      * @param string|null $message Deprecated message
  131.      */
  132.     public function setDeprecated($message)
  133.     {
  134.         $this->deprecationMessage $message;
  135.     }
  136.     /**
  137.      * Sets if this node can be overridden.
  138.      *
  139.      * @param bool $allow
  140.      */
  141.     public function setAllowOverwrite($allow)
  142.     {
  143.         $this->allowOverwrite = (bool) $allow;
  144.     }
  145.     /**
  146.      * Sets the closures used for normalization.
  147.      *
  148.      * @param \Closure[] $closures An array of Closures used for normalization
  149.      */
  150.     public function setNormalizationClosures(array $closures)
  151.     {
  152.         $this->normalizationClosures $closures;
  153.     }
  154.     /**
  155.      * Sets the closures used for final validation.
  156.      *
  157.      * @param \Closure[] $closures An array of Closures used for final validation
  158.      */
  159.     public function setFinalValidationClosures(array $closures)
  160.     {
  161.         $this->finalValidationClosures $closures;
  162.     }
  163.     /**
  164.      * {@inheritdoc}
  165.      */
  166.     public function isRequired()
  167.     {
  168.         return $this->required;
  169.     }
  170.     /**
  171.      * Checks if this node is deprecated.
  172.      *
  173.      * @return bool
  174.      */
  175.     public function isDeprecated()
  176.     {
  177.         return null !== $this->deprecationMessage;
  178.     }
  179.     /**
  180.      * Returns the deprecated message.
  181.      *
  182.      * @param string $node the configuration node name
  183.      * @param string $path the path of the node
  184.      *
  185.      * @return string
  186.      */
  187.     public function getDeprecationMessage($node$path)
  188.     {
  189.         return strtr($this->deprecationMessage, ['%node%' => $node'%path%' => $path]);
  190.     }
  191.     /**
  192.      * {@inheritdoc}
  193.      */
  194.     public function getName()
  195.     {
  196.         return $this->name;
  197.     }
  198.     /**
  199.      * {@inheritdoc}
  200.      */
  201.     public function getPath()
  202.     {
  203.         $path $this->name;
  204.         if (null !== $this->parent) {
  205.             $path $this->parent->getPath().'.'.$path;
  206.         }
  207.         return $path;
  208.     }
  209.     /**
  210.      * {@inheritdoc}
  211.      */
  212.     final public function merge($leftSide$rightSide)
  213.     {
  214.         if (!$this->allowOverwrite) {
  215.             throw new ForbiddenOverwriteException(sprintf('Configuration path "%s" cannot be overwritten. You have to define all options for this path, and any of its sub-paths in one configuration section.'$this->getPath()));
  216.         }
  217.         $this->validateType($leftSide);
  218.         $this->validateType($rightSide);
  219.         return $this->mergeValues($leftSide$rightSide);
  220.     }
  221.     /**
  222.      * {@inheritdoc}
  223.      */
  224.     final public function normalize($value)
  225.     {
  226.         $value $this->preNormalize($value);
  227.         // run custom normalization closures
  228.         foreach ($this->normalizationClosures as $closure) {
  229.             $value $closure($value);
  230.         }
  231.         // replace value with their equivalent
  232.         foreach ($this->equivalentValues as $data) {
  233.             if ($data[0] === $value) {
  234.                 $value $data[1];
  235.             }
  236.         }
  237.         // validate type
  238.         $this->validateType($value);
  239.         // normalize value
  240.         return $this->normalizeValue($value);
  241.     }
  242.     /**
  243.      * Normalizes the value before any other normalization is applied.
  244.      *
  245.      * @param $value
  246.      *
  247.      * @return The normalized array value
  248.      */
  249.     protected function preNormalize($value)
  250.     {
  251.         return $value;
  252.     }
  253.     /**
  254.      * Returns parent node for this node.
  255.      *
  256.      * @return NodeInterface|null
  257.      */
  258.     public function getParent()
  259.     {
  260.         return $this->parent;
  261.     }
  262.     /**
  263.      * {@inheritdoc}
  264.      */
  265.     final public function finalize($value)
  266.     {
  267.         $this->validateType($value);
  268.         $value $this->finalizeValue($value);
  269.         // Perform validation on the final value if a closure has been set.
  270.         // The closure is also allowed to return another value.
  271.         foreach ($this->finalValidationClosures as $closure) {
  272.             try {
  273.                 $value $closure($value);
  274.             } catch (Exception $e) {
  275.                 throw $e;
  276.             } catch (\Exception $e) {
  277.                 throw new InvalidConfigurationException(sprintf('Invalid configuration for path "%s": %s'$this->getPath(), $e->getMessage()), $e->getCode(), $e);
  278.             }
  279.         }
  280.         return $value;
  281.     }
  282.     /**
  283.      * Validates the type of a Node.
  284.      *
  285.      * @param mixed $value The value to validate
  286.      *
  287.      * @throws InvalidTypeException when the value is invalid
  288.      */
  289.     abstract protected function validateType($value);
  290.     /**
  291.      * Normalizes the value.
  292.      *
  293.      * @param mixed $value The value to normalize
  294.      *
  295.      * @return mixed The normalized value
  296.      */
  297.     abstract protected function normalizeValue($value);
  298.     /**
  299.      * Merges two values together.
  300.      *
  301.      * @param mixed $leftSide
  302.      * @param mixed $rightSide
  303.      *
  304.      * @return mixed The merged value
  305.      */
  306.     abstract protected function mergeValues($leftSide$rightSide);
  307.     /**
  308.      * Finalizes a value.
  309.      *
  310.      * @param mixed $value The value to finalize
  311.      *
  312.      * @return mixed The finalized value
  313.      */
  314.     abstract protected function finalizeValue($value);
  315. }