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

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <[email protected]>
  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 <[email protected]>
  19.  */
  20. abstract class BaseNode implements NodeInterface
  21. {
  22.     protected $name;
  23.     protected $parent;
  24.     protected $normalizationClosures = array();
  25.     protected $finalValidationClosures = array();
  26.     protected $allowOverwrite true;
  27.     protected $required false;
  28.     protected $deprecationMessage null;
  29.     protected $equivalentValues = array();
  30.     protected $attributes = array();
  31.     /**
  32.      * @param string        $name   The name of the node
  33.      * @param NodeInterface $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'.')) {
  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[] = array($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.      * Checks if this node is required.
  165.      *
  166.      * @return bool
  167.      */
  168.     public function isRequired()
  169.     {
  170.         return $this->required;
  171.     }
  172.     /**
  173.      * Checks if this node is deprecated.
  174.      *
  175.      * @return bool
  176.      */
  177.     public function isDeprecated()
  178.     {
  179.         return null !== $this->deprecationMessage;
  180.     }
  181.     /**
  182.      * Returns the deprecated message.
  183.      *
  184.      * @param string $node the configuration node name
  185.      * @param string $path the path of the node
  186.      *
  187.      * @return string
  188.      */
  189.     public function getDeprecationMessage($node$path)
  190.     {
  191.         return strtr($this->deprecationMessage, array('%node%' => $node'%path%' => $path));
  192.     }
  193.     /**
  194.      * Returns the name of this node.
  195.      *
  196.      * @return string The Node's name
  197.      */
  198.     public function getName()
  199.     {
  200.         return $this->name;
  201.     }
  202.     /**
  203.      * Retrieves the path of this node.
  204.      *
  205.      * @return string The Node's path
  206.      */
  207.     public function getPath()
  208.     {
  209.         $path $this->name;
  210.         if (null !== $this->parent) {
  211.             $path $this->parent->getPath().'.'.$path;
  212.         }
  213.         return $path;
  214.     }
  215.     /**
  216.      * Merges two values together.
  217.      *
  218.      * @param mixed $leftSide
  219.      * @param mixed $rightSide
  220.      *
  221.      * @return mixed The merged value
  222.      *
  223.      * @throws ForbiddenOverwriteException
  224.      */
  225.     final public function merge($leftSide$rightSide)
  226.     {
  227.         if (!$this->allowOverwrite) {
  228.             throw new ForbiddenOverwriteException(sprintf(
  229.                 'Configuration path "%s" cannot be overwritten. You have to '
  230.                .'define all options for this path, and any of its sub-paths in '
  231.                .'one configuration section.',
  232.                 $this->getPath()
  233.             ));
  234.         }
  235.         $this->validateType($leftSide);
  236.         $this->validateType($rightSide);
  237.         return $this->mergeValues($leftSide$rightSide);
  238.     }
  239.     /**
  240.      * Normalizes a value, applying all normalization closures.
  241.      *
  242.      * @param mixed $value Value to normalize
  243.      *
  244.      * @return mixed The normalized value
  245.      */
  246.     final public function normalize($value)
  247.     {
  248.         $value $this->preNormalize($value);
  249.         // run custom normalization closures
  250.         foreach ($this->normalizationClosures as $closure) {
  251.             $value $closure($value);
  252.         }
  253.         // replace value with their equivalent
  254.         foreach ($this->equivalentValues as $data) {
  255.             if ($data[0] === $value) {
  256.                 $value $data[1];
  257.             }
  258.         }
  259.         // validate type
  260.         $this->validateType($value);
  261.         // normalize value
  262.         return $this->normalizeValue($value);
  263.     }
  264.     /**
  265.      * Normalizes the value before any other normalization is applied.
  266.      *
  267.      * @param $value
  268.      *
  269.      * @return $value The normalized array value
  270.      */
  271.     protected function preNormalize($value)
  272.     {
  273.         return $value;
  274.     }
  275.     /**
  276.      * Returns parent node for this node.
  277.      *
  278.      * @return NodeInterface|null
  279.      */
  280.     public function getParent()
  281.     {
  282.         return $this->parent;
  283.     }
  284.     /**
  285.      * Finalizes a value, applying all finalization closures.
  286.      *
  287.      * @param mixed $value The value to finalize
  288.      *
  289.      * @return mixed The finalized value
  290.      *
  291.      * @throws Exception
  292.      * @throws InvalidConfigurationException
  293.      */
  294.     final public function finalize($value)
  295.     {
  296.         $this->validateType($value);
  297.         $value $this->finalizeValue($value);
  298.         // Perform validation on the final value if a closure has been set.
  299.         // The closure is also allowed to return another value.
  300.         foreach ($this->finalValidationClosures as $closure) {
  301.             try {
  302.                 $value $closure($value);
  303.             } catch (Exception $e) {
  304.                 throw $e;
  305.             } catch (\Exception $e) {
  306.                 throw new InvalidConfigurationException(sprintf('Invalid configuration for path "%s": %s'$this->getPath(), $e->getMessage()), $e->getCode(), $e);
  307.             }
  308.         }
  309.         return $value;
  310.     }
  311.     /**
  312.      * Validates the type of a Node.
  313.      *
  314.      * @param mixed $value The value to validate
  315.      *
  316.      * @throws InvalidTypeException when the value is invalid
  317.      */
  318.     abstract protected function validateType($value);
  319.     /**
  320.      * Normalizes the value.
  321.      *
  322.      * @param mixed $value The value to normalize
  323.      *
  324.      * @return mixed The normalized value
  325.      */
  326.     abstract protected function normalizeValue($value);
  327.     /**
  328.      * Merges two values together.
  329.      *
  330.      * @param mixed $leftSide
  331.      * @param mixed $rightSide
  332.      *
  333.      * @return mixed The merged value
  334.      */
  335.     abstract protected function mergeValues($leftSide$rightSide);
  336.     /**
  337.      * Finalizes a value.
  338.      *
  339.      * @param mixed $value The value to finalize
  340.      *
  341.      * @return mixed The finalized value
  342.      */
  343.     abstract protected function finalizeValue($value);
  344. }