forked from GNUsocial/gnu-social
		
	
		
			
				
	
	
		
			326 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			326 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| /*
 | |
|  * This file is part of the Symfony package.
 | |
|  *
 | |
|  * (c) Fabien Potencier <fabien@symfony.com>
 | |
|  *
 | |
|  * For the full copyright and license information, please view the LICENSE
 | |
|  * file that was distributed with this source code.
 | |
|  */
 | |
| 
 | |
| namespace Symfony\Component\Config\Definition;
 | |
| 
 | |
| use Symfony\Component\Config\Definition\Exception\Exception;
 | |
| use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
 | |
| use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
 | |
| use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
 | |
| 
 | |
| /**
 | |
|  * The base node class.
 | |
|  *
 | |
|  * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 | |
|  */
 | |
| abstract class BaseNode implements NodeInterface
 | |
| {
 | |
|     protected $name;
 | |
|     protected $parent;
 | |
|     protected $normalizationClosures = array();
 | |
|     protected $finalValidationClosures = array();
 | |
|     protected $allowOverwrite = true;
 | |
|     protected $required = false;
 | |
|     protected $equivalentValues = array();
 | |
|     protected $attributes = array();
 | |
| 
 | |
|     /**
 | |
|      * @param string|null        $name   The name of the node
 | |
|      * @param NodeInterface|null $parent The parent of this node
 | |
|      *
 | |
|      * @throws \InvalidArgumentException if the name contains a period
 | |
|      */
 | |
|     public function __construct($name, NodeInterface $parent = null)
 | |
|     {
 | |
|         if (false !== strpos($name = (string) $name, '.')) {
 | |
|             throw new \InvalidArgumentException('The name must not contain ".".');
 | |
|         }
 | |
| 
 | |
|         $this->name = $name;
 | |
|         $this->parent = $parent;
 | |
|     }
 | |
| 
 | |
|     public function setAttribute($key, $value)
 | |
|     {
 | |
|         $this->attributes[$key] = $value;
 | |
|     }
 | |
| 
 | |
|     public function getAttribute($key, $default = null)
 | |
|     {
 | |
|         return isset($this->attributes[$key]) ? $this->attributes[$key] : $default;
 | |
|     }
 | |
| 
 | |
|     public function hasAttribute($key)
 | |
|     {
 | |
|         return isset($this->attributes[$key]);
 | |
|     }
 | |
| 
 | |
|     public function getAttributes()
 | |
|     {
 | |
|         return $this->attributes;
 | |
|     }
 | |
| 
 | |
|     public function setAttributes(array $attributes)
 | |
|     {
 | |
|         $this->attributes = $attributes;
 | |
|     }
 | |
| 
 | |
|     public function removeAttribute($key)
 | |
|     {
 | |
|         unset($this->attributes[$key]);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Sets an info message.
 | |
|      *
 | |
|      * @param string $info
 | |
|      */
 | |
|     public function setInfo($info)
 | |
|     {
 | |
|         $this->setAttribute('info', $info);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Returns info message.
 | |
|      *
 | |
|      * @return string The info text
 | |
|      */
 | |
|     public function getInfo()
 | |
|     {
 | |
|         return $this->getAttribute('info');
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Sets the example configuration for this node.
 | |
|      *
 | |
|      * @param string|array $example
 | |
|      */
 | |
|     public function setExample($example)
 | |
|     {
 | |
|         $this->setAttribute('example', $example);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Retrieves the example configuration for this node.
 | |
|      *
 | |
|      * @return string|array The example
 | |
|      */
 | |
|     public function getExample()
 | |
|     {
 | |
|         return $this->getAttribute('example');
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Adds an equivalent value.
 | |
|      *
 | |
|      * @param mixed $originalValue
 | |
|      * @param mixed $equivalentValue
 | |
|      */
 | |
|     public function addEquivalentValue($originalValue, $equivalentValue)
 | |
|     {
 | |
|         $this->equivalentValues[] = array($originalValue, $equivalentValue);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set this node as required.
 | |
|      *
 | |
|      * @param bool $boolean Required node
 | |
|      */
 | |
|     public function setRequired($boolean)
 | |
|     {
 | |
|         $this->required = (bool) $boolean;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Sets if this node can be overridden.
 | |
|      *
 | |
|      * @param bool $allow
 | |
|      */
 | |
|     public function setAllowOverwrite($allow)
 | |
|     {
 | |
|         $this->allowOverwrite = (bool) $allow;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Sets the closures used for normalization.
 | |
|      *
 | |
|      * @param \Closure[] $closures An array of Closures used for normalization
 | |
|      */
 | |
|     public function setNormalizationClosures(array $closures)
 | |
|     {
 | |
|         $this->normalizationClosures = $closures;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Sets the closures used for final validation.
 | |
|      *
 | |
|      * @param \Closure[] $closures An array of Closures used for final validation
 | |
|      */
 | |
|     public function setFinalValidationClosures(array $closures)
 | |
|     {
 | |
|         $this->finalValidationClosures = $closures;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function isRequired()
 | |
|     {
 | |
|         return $this->required;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function getName()
 | |
|     {
 | |
|         return $this->name;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     public function getPath()
 | |
|     {
 | |
|         $path = $this->name;
 | |
| 
 | |
|         if (null !== $this->parent) {
 | |
|             $path = $this->parent->getPath().'.'.$path;
 | |
|         }
 | |
| 
 | |
|         return $path;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     final public function merge($leftSide, $rightSide)
 | |
|     {
 | |
|         if (!$this->allowOverwrite) {
 | |
|             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()));
 | |
|         }
 | |
| 
 | |
|         $this->validateType($leftSide);
 | |
|         $this->validateType($rightSide);
 | |
| 
 | |
|         return $this->mergeValues($leftSide, $rightSide);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     final public function normalize($value)
 | |
|     {
 | |
|         $value = $this->preNormalize($value);
 | |
| 
 | |
|         // run custom normalization closures
 | |
|         foreach ($this->normalizationClosures as $closure) {
 | |
|             $value = $closure($value);
 | |
|         }
 | |
| 
 | |
|         // replace value with their equivalent
 | |
|         foreach ($this->equivalentValues as $data) {
 | |
|             if ($data[0] === $value) {
 | |
|                 $value = $data[1];
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // validate type
 | |
|         $this->validateType($value);
 | |
| 
 | |
|         // normalize value
 | |
|         return $this->normalizeValue($value);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Normalizes the value before any other normalization is applied.
 | |
|      *
 | |
|      * @param $value
 | |
|      *
 | |
|      * @return The normalized array value
 | |
|      */
 | |
|     protected function preNormalize($value)
 | |
|     {
 | |
|         return $value;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Returns parent node for this node.
 | |
|      *
 | |
|      * @return NodeInterface|null
 | |
|      */
 | |
|     public function getParent()
 | |
|     {
 | |
|         return $this->parent;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * {@inheritdoc}
 | |
|      */
 | |
|     final public function finalize($value)
 | |
|     {
 | |
|         $this->validateType($value);
 | |
| 
 | |
|         $value = $this->finalizeValue($value);
 | |
| 
 | |
|         // Perform validation on the final value if a closure has been set.
 | |
|         // The closure is also allowed to return another value.
 | |
|         foreach ($this->finalValidationClosures as $closure) {
 | |
|             try {
 | |
|                 $value = $closure($value);
 | |
|             } catch (Exception $e) {
 | |
|                 throw $e;
 | |
|             } catch (\Exception $e) {
 | |
|                 throw new InvalidConfigurationException(sprintf('Invalid configuration for path "%s": %s', $this->getPath(), $e->getMessage()), $e->getCode(), $e);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return $value;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Validates the type of a Node.
 | |
|      *
 | |
|      * @param mixed $value The value to validate
 | |
|      *
 | |
|      * @throws InvalidTypeException when the value is invalid
 | |
|      */
 | |
|     abstract protected function validateType($value);
 | |
| 
 | |
|     /**
 | |
|      * Normalizes the value.
 | |
|      *
 | |
|      * @param mixed $value The value to normalize
 | |
|      *
 | |
|      * @return mixed The normalized value
 | |
|      */
 | |
|     abstract protected function normalizeValue($value);
 | |
| 
 | |
|     /**
 | |
|      * Merges two values together.
 | |
|      *
 | |
|      * @param mixed $leftSide
 | |
|      * @param mixed $rightSide
 | |
|      *
 | |
|      * @return mixed The merged value
 | |
|      */
 | |
|     abstract protected function mergeValues($leftSide, $rightSide);
 | |
| 
 | |
|     /**
 | |
|      * Finalizes a value.
 | |
|      *
 | |
|      * @param mixed $value The value to finalize
 | |
|      *
 | |
|      * @return mixed The finalized value
 | |
|      */
 | |
|     abstract protected function finalizeValue($value);
 | |
| }
 |