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

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