summaryrefslogtreecommitdiffstats
path: root/vendor/symfony/config/Symfony
diff options
context:
space:
mode:
authorStefan Suhren <suhren.stefan@fh-swf.de>2015-05-05 19:34:39 +0200
committerStefan Suhren <suhren.stefan@fh-swf.de>2015-05-05 19:34:39 +0200
commit705c4cb50eea66585cc95c7314001fce9dd197cd (patch)
tree4a448f4e30b117e12306b643121f49da15e6376b /vendor/symfony/config/Symfony
downloadCatalog-705c4cb50eea66585cc95c7314001fce9dd197cd.tar.gz
Catalog-705c4cb50eea66585cc95c7314001fce9dd197cd.zip
Initial commit
Diffstat (limited to 'vendor/symfony/config/Symfony')
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/.gitignore3
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/CHANGELOG.md21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/ConfigCache.php126
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/ArrayNode.php393
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/BaseNode.php360
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/BooleanNode.php42
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php489
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php42
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php58
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ExprBuilder.php238
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php32
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php32
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/MergeBuilder.php72
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeBuilder.php245
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeDefinition.php343
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php67
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php61
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php26
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php32
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/TreeBuilder.php63
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php51
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php64
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/ConfigurationInterface.php27
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php300
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php198
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/EnumNode.php58
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php22
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/Exception.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php22
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php49
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php22
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/FloatNode.php43
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/IntegerNode.php38
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/NodeInterface.php88
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/NumericNode.php55
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/Processor.php97
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/PrototypeNodeInterface.php27
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/PrototypedArrayNode.php331
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/ReferenceDumper.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/ScalarNode.php49
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Definition/VariableNode.php119
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php27
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderLoadException.php100
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/FileLocator.php95
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/FileLocatorInterface.php31
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/LICENSE19
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/DelegatingLoader.php55
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/FileLoader.php124
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/Loader.php78
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/LoaderInterface.php54
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolver.php75
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolverInterface.php30
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/README.md17
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Resource/DirectoryResource.php99
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Resource/FileResource.php75
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Resource/ResourceInterface.php43
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/ConfigCacheTest.php138
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php160
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php60
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php207
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php46
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php215
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php94
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php93
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php126
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php80
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php67
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php41
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FinalizationTest.php73
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php64
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php61
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/MergeTest.php195
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/NormalizationTest.php229
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php180
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php79
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Exception/FileLoaderLoadExceptionTest.php83
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/FileLocatorTest.php119
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml0
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php21
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php34
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php18
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php71
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml3
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml2
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml2
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd9
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml3
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/foo.xml0
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php83
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php106
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php56
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderTest.php117
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php152
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Resource/FileResourceTest.php61
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php197
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/Util/XmlUtils.php238
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/composer.json35
-rw-r--r--vendor/symfony/config/Symfony/Component/Config/phpunit.xml.dist28
101 files changed, 9078 insertions, 0 deletions
diff --git a/vendor/symfony/config/Symfony/Component/Config/.gitignore b/vendor/symfony/config/Symfony/Component/Config/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/vendor/symfony/config/Symfony/Component/Config/CHANGELOG.md b/vendor/symfony/config/Symfony/Component/Config/CHANGELOG.md
new file mode 100644
index 0000000..59b30a3
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/CHANGELOG.md
@@ -0,0 +1,21 @@
+CHANGELOG
+=========
+
+2.2.0
+-----
+
+ * added ArrayNodeDefinition::canBeEnabled() and ArrayNodeDefinition::canBeDisabled()
+ to ease configuration when some sections are respectively disabled / enabled
+ by default.
+ * added a `normalizeKeys()` method for array nodes (to avoid key normalization)
+ * added numerical type handling for config definitions
+ * added convenience methods for optional configuration sections to ArrayNodeDefinition
+ * added a utils class for XML manipulations
+
+2.1.0
+-----
+
+ * added a way to add documentation on configuration
+ * implemented `Serializable` on resources
+ * LoaderResolverInterface is now used instead of LoaderResolver for type
+ hinting
diff --git a/vendor/symfony/config/Symfony/Component/Config/ConfigCache.php b/vendor/symfony/config/Symfony/Component/Config/ConfigCache.php
new file mode 100644
index 0000000..ebf107f
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/ConfigCache.php
@@ -0,0 +1,126 @@
+<?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;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+use Symfony\Component\Filesystem\Exception\IOException;
+use Symfony\Component\Filesystem\Filesystem;
+
+/**
+ * ConfigCache manages PHP cache files.
+ *
+ * When debug is enabled, it knows when to flush the cache
+ * thanks to an array of ResourceInterface instances.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ConfigCache
+{
+ private $debug;
+ private $file;
+
+ /**
+ * Constructor.
+ *
+ * @param string $file The absolute cache path
+ * @param bool $debug Whether debugging is enabled or not
+ */
+ public function __construct($file, $debug)
+ {
+ $this->file = $file;
+ $this->debug = (bool) $debug;
+ }
+
+ /**
+ * Gets the cache file path.
+ *
+ * @return string The cache file path
+ */
+ public function __toString()
+ {
+ return $this->file;
+ }
+
+ /**
+ * Checks if the cache is still fresh.
+ *
+ * This method always returns true when debug is off and the
+ * cache file exists.
+ *
+ * @return bool true if the cache is fresh, false otherwise
+ */
+ public function isFresh()
+ {
+ if (!is_file($this->file)) {
+ return false;
+ }
+
+ if (!$this->debug) {
+ return true;
+ }
+
+ $metadata = $this->getMetaFile();
+ if (!is_file($metadata)) {
+ return false;
+ }
+
+ $time = filemtime($this->file);
+ $meta = unserialize(file_get_contents($metadata));
+ foreach ($meta as $resource) {
+ if (!$resource->isFresh($time)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Writes cache.
+ *
+ * @param string $content The content to write in the cache
+ * @param ResourceInterface[] $metadata An array of ResourceInterface instances
+ *
+ * @throws \RuntimeException When cache file can't be written
+ */
+ public function write($content, array $metadata = null)
+ {
+ $mode = 0666;
+ $umask = umask();
+ $filesystem = new Filesystem();
+ $filesystem->dumpFile($this->file, $content, null);
+ try {
+ $filesystem->chmod($this->file, $mode, $umask);
+ } catch (IOException $e) {
+ // discard chmod failure (some filesystem may not support it)
+ }
+
+ if (null !== $metadata && true === $this->debug) {
+ $filesystem->dumpFile($this->getMetaFile(), serialize($metadata), null);
+ try {
+ $filesystem->chmod($this->getMetaFile(), $mode, $umask);
+ } catch (IOException $e) {
+ // discard chmod failure (some filesystem may not support it)
+ }
+ }
+ }
+
+ /**
+ * Gets the meta file path.
+ *
+ * @return string The meta file path
+ */
+ private function getMetaFile()
+ {
+ return $this->file.'.meta';
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/ArrayNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/ArrayNode.php
new file mode 100644
index 0000000..5deb472
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/ArrayNode.php
@@ -0,0 +1,393 @@
+<?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\InvalidConfigurationException;
+use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
+use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
+
+/**
+ * Represents an Array node in the config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ArrayNode extends BaseNode implements PrototypeNodeInterface
+{
+ protected $xmlRemappings = array();
+ protected $children = array();
+ protected $allowFalse = false;
+ protected $allowNewKeys = true;
+ protected $addIfNotSet = false;
+ protected $performDeepMerging = true;
+ protected $ignoreExtraKeys = false;
+ protected $normalizeKeys = true;
+
+ public function setNormalizeKeys($normalizeKeys)
+ {
+ $this->normalizeKeys = (bool) $normalizeKeys;
+ }
+
+ /**
+ * Normalizes keys between the different configuration formats.
+ *
+ * Namely, you mostly have foo_bar in YAML while you have foo-bar in XML.
+ * After running this method, all keys are normalized to foo_bar.
+ *
+ * If you have a mixed key like foo-bar_moo, it will not be altered.
+ * The key will also not be altered if the target key already exists.
+ *
+ * @param mixed $value
+ *
+ * @return array The value with normalized keys
+ */
+ protected function preNormalize($value)
+ {
+ if (!$this->normalizeKeys || !is_array($value)) {
+ return $value;
+ }
+
+ foreach ($value as $k => $v) {
+ if (false !== strpos($k, '-') && false === strpos($k, '_') && !array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) {
+ $value[$normalizedKey] = $v;
+ unset($value[$k]);
+ }
+ }
+
+ return $value;
+ }
+
+ /**
+ * Retrieves the children of this node.
+ *
+ * @return array The children
+ */
+ public function getChildren()
+ {
+ return $this->children;
+ }
+
+ /**
+ * Sets the xml remappings that should be performed.
+ *
+ * @param array $remappings an array of the form array(array(string, string))
+ */
+ public function setXmlRemappings(array $remappings)
+ {
+ $this->xmlRemappings = $remappings;
+ }
+
+ /**
+ * Gets the xml remappings that should be performed.
+ *
+ * @return array $remappings an array of the form array(array(string, string))
+ */
+ public function getXmlRemappings()
+ {
+ return $this->xmlRemappings;
+ }
+
+ /**
+ * Sets whether to add default values for this array if it has not been
+ * defined in any of the configuration files.
+ *
+ * @param bool $boolean
+ */
+ public function setAddIfNotSet($boolean)
+ {
+ $this->addIfNotSet = (bool) $boolean;
+ }
+
+ /**
+ * Sets whether false is allowed as value indicating that the array should be unset.
+ *
+ * @param bool $allow
+ */
+ public function setAllowFalse($allow)
+ {
+ $this->allowFalse = (bool) $allow;
+ }
+
+ /**
+ * Sets whether new keys can be defined in subsequent configurations.
+ *
+ * @param bool $allow
+ */
+ public function setAllowNewKeys($allow)
+ {
+ $this->allowNewKeys = (bool) $allow;
+ }
+
+ /**
+ * Sets if deep merging should occur.
+ *
+ * @param bool $boolean
+ */
+ public function setPerformDeepMerging($boolean)
+ {
+ $this->performDeepMerging = (bool) $boolean;
+ }
+
+ /**
+ * Whether extra keys should just be ignore without an exception.
+ *
+ * @param bool $boolean To allow extra keys
+ */
+ public function setIgnoreExtraKeys($boolean)
+ {
+ $this->ignoreExtraKeys = (bool) $boolean;
+ }
+
+ /**
+ * Sets the node Name.
+ *
+ * @param string $name The node's name
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Checks if the node has a default value.
+ *
+ * @return bool
+ */
+ public function hasDefaultValue()
+ {
+ return $this->addIfNotSet;
+ }
+
+ /**
+ * Retrieves the default value.
+ *
+ * @return array The default value
+ *
+ * @throws \RuntimeException if the node has no default value
+ */
+ public function getDefaultValue()
+ {
+ if (!$this->hasDefaultValue()) {
+ throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath()));
+ }
+
+ $defaults = array();
+ foreach ($this->children as $name => $child) {
+ if ($child->hasDefaultValue()) {
+ $defaults[$name] = $child->getDefaultValue();
+ }
+ }
+
+ return $defaults;
+ }
+
+ /**
+ * Adds a child node.
+ *
+ * @param NodeInterface $node The child node to add
+ *
+ * @throws \InvalidArgumentException when the child node has no name
+ * @throws \InvalidArgumentException when the child node's name is not unique
+ */
+ public function addChild(NodeInterface $node)
+ {
+ $name = $node->getName();
+ if (!strlen($name)) {
+ throw new \InvalidArgumentException('Child nodes must be named.');
+ }
+ if (isset($this->children[$name])) {
+ throw new \InvalidArgumentException(sprintf('A child node named "%s" already exists.', $name));
+ }
+
+ $this->children[$name] = $node;
+ }
+
+ /**
+ * Finalizes the value of this node.
+ *
+ * @param mixed $value
+ *
+ * @return mixed The finalised value
+ *
+ * @throws UnsetKeyException
+ * @throws InvalidConfigurationException if the node doesn't have enough children
+ */
+ protected function finalizeValue($value)
+ {
+ if (false === $value) {
+ $msg = sprintf('Unsetting key for path "%s", value: %s', $this->getPath(), json_encode($value));
+ throw new UnsetKeyException($msg);
+ }
+
+ foreach ($this->children as $name => $child) {
+ if (!array_key_exists($name, $value)) {
+ if ($child->isRequired()) {
+ $msg = sprintf('The child node "%s" at path "%s" must be configured.', $name, $this->getPath());
+ $ex = new InvalidConfigurationException($msg);
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ if ($child->hasDefaultValue()) {
+ $value[$name] = $child->getDefaultValue();
+ }
+
+ continue;
+ }
+
+ try {
+ $value[$name] = $child->finalize($value[$name]);
+ } catch (UnsetKeyException $unset) {
+ unset($value[$name]);
+ }
+ }
+
+ return $value;
+ }
+
+ /**
+ * Validates the type of the value.
+ *
+ * @param mixed $value
+ *
+ * @throws InvalidTypeException
+ */
+ protected function validateType($value)
+ {
+ if (!is_array($value) && (!$this->allowFalse || false !== $value)) {
+ $ex = new InvalidTypeException(sprintf(
+ 'Invalid type for path "%s". Expected array, but got %s',
+ $this->getPath(),
+ gettype($value)
+ ));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+
+ /**
+ * Normalizes the value.
+ *
+ * @param mixed $value The value to normalize
+ *
+ * @return mixed The normalized value
+ *
+ * @throws InvalidConfigurationException
+ */
+ protected function normalizeValue($value)
+ {
+ if (false === $value) {
+ return $value;
+ }
+
+ $value = $this->remapXml($value);
+
+ $normalized = array();
+ foreach ($value as $name => $val) {
+ if (isset($this->children[$name])) {
+ $normalized[$name] = $this->children[$name]->normalize($val);
+ unset($value[$name]);
+ }
+ }
+
+ // if extra fields are present, throw exception
+ if (count($value) && !$this->ignoreExtraKeys) {
+ $msg = sprintf('Unrecognized option%s "%s" under "%s"', 1 === count($value) ? '' : 's', implode(', ', array_keys($value)), $this->getPath());
+ $ex = new InvalidConfigurationException($msg);
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ return $normalized;
+ }
+
+ /**
+ * Remaps multiple singular values to a single plural value.
+ *
+ * @param array $value The source values
+ *
+ * @return array The remapped values
+ */
+ protected function remapXml($value)
+ {
+ foreach ($this->xmlRemappings as $transformation) {
+ list($singular, $plural) = $transformation;
+
+ if (!isset($value[$singular])) {
+ continue;
+ }
+
+ $value[$plural] = Processor::normalizeConfig($value, $singular, $plural);
+ unset($value[$singular]);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Merges values together.
+ *
+ * @param mixed $leftSide The left side to merge.
+ * @param mixed $rightSide The right side to merge.
+ *
+ * @return mixed The merged values
+ *
+ * @throws InvalidConfigurationException
+ * @throws \RuntimeException
+ */
+ protected function mergeValues($leftSide, $rightSide)
+ {
+ if (false === $rightSide) {
+ // if this is still false after the last config has been merged the
+ // finalization pass will take care of removing this key entirely
+ return false;
+ }
+
+ if (false === $leftSide || !$this->performDeepMerging) {
+ return $rightSide;
+ }
+
+ foreach ($rightSide as $k => $v) {
+ // no conflict
+ if (!array_key_exists($k, $leftSide)) {
+ if (!$this->allowNewKeys) {
+ $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()
+ ));
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ $leftSide[$k] = $v;
+ continue;
+ }
+
+ if (!isset($this->children[$k])) {
+ throw new \RuntimeException('merge() expects a normalized config array.');
+ }
+
+ $leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v);
+ }
+
+ return $leftSide;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/BaseNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/BaseNode.php
new file mode 100644
index 0000000..afccc1c
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/BaseNode.php
@@ -0,0 +1,360 @@
+<?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();
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the node
+ * @param NodeInterface $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, '.')) {
+ 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;
+ }
+
+ /**
+ * Checks if this node is required.
+ *
+ * @return bool
+ */
+ public function isRequired()
+ {
+ return $this->required;
+ }
+
+ /**
+ * Returns the name of this node.
+ *
+ * @return string The Node's name.
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Retrieves the path of this node.
+ *
+ * @return string The Node's path
+ */
+ public function getPath()
+ {
+ $path = $this->name;
+
+ if (null !== $this->parent) {
+ $path = $this->parent->getPath().'.'.$path;
+ }
+
+ return $path;
+ }
+
+ /**
+ * Merges two values together.
+ *
+ * @param mixed $leftSide
+ * @param mixed $rightSide
+ *
+ * @return mixed The merged value
+ *
+ * @throws ForbiddenOverwriteException
+ */
+ 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);
+ }
+
+ /**
+ * Normalizes a value, applying all normalization closures.
+ *
+ * @param mixed $value Value to normalize.
+ *
+ * @return mixed The normalized value.
+ */
+ 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 $value 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;
+ }
+
+ /**
+ * Finalizes a value, applying all finalization closures.
+ *
+ * @param mixed $value The value to finalize
+ *
+ * @return mixed The finalized value
+ *
+ * @throws Exception
+ * @throws InvalidConfigurationException
+ */
+ 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 $correctEx) {
+ throw $correctEx;
+ } catch (\Exception $invalid) {
+ throw new InvalidConfigurationException(sprintf(
+ 'Invalid configuration for path "%s": %s',
+ $this->getPath(),
+ $invalid->getMessage()
+ ), $invalid->getCode(), $invalid);
+ }
+ }
+
+ 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);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/BooleanNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/BooleanNode.php
new file mode 100644
index 0000000..df06b30
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/BooleanNode.php
@@ -0,0 +1,42 @@
+<?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\InvalidTypeException;
+
+/**
+ * This node represents a Boolean value in the config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class BooleanNode extends ScalarNode
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function validateType($value)
+ {
+ if (!is_bool($value)) {
+ $ex = new InvalidTypeException(sprintf(
+ 'Invalid type for path "%s". Expected boolean, but got %s.',
+ $this->getPath(),
+ gettype($value)
+ ));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php
new file mode 100644
index 0000000..c64b2ec
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php
@@ -0,0 +1,489 @@
+<?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\Builder;
+
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\PrototypedArrayNode;
+use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
+
+/**
+ * This class provides a fluent interface for defining an array node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinitionInterface
+{
+ protected $performDeepMerging = true;
+ protected $ignoreExtraKeys = false;
+ protected $children = array();
+ protected $prototype;
+ protected $atLeastOne = false;
+ protected $allowNewKeys = true;
+ protected $key;
+ protected $removeKeyItem;
+ protected $addDefaults = false;
+ protected $addDefaultChildren = false;
+ protected $nodeBuilder;
+ protected $normalizeKeys = true;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct($name, NodeParentInterface $parent = null)
+ {
+ parent::__construct($name, $parent);
+
+ $this->nullEquivalent = array();
+ $this->trueEquivalent = array();
+ }
+
+ /**
+ * Sets a custom children builder.
+ *
+ * @param NodeBuilder $builder A custom NodeBuilder
+ */
+ public function setBuilder(NodeBuilder $builder)
+ {
+ $this->nodeBuilder = $builder;
+ }
+
+ /**
+ * Returns a builder to add children nodes.
+ *
+ * @return NodeBuilder
+ */
+ public function children()
+ {
+ return $this->getNodeBuilder();
+ }
+
+ /**
+ * Sets a prototype for child nodes.
+ *
+ * @param string $type the type of node
+ *
+ * @return NodeDefinition
+ */
+ public function prototype($type)
+ {
+ return $this->prototype = $this->getNodeBuilder()->node(null, $type)->setParent($this);
+ }
+
+ /**
+ * Adds the default value if the node is not set in the configuration.
+ *
+ * This method is applicable to concrete nodes only (not to prototype nodes).
+ * If this function has been called and the node is not set during the finalization
+ * phase, it's default value will be derived from its children default values.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function addDefaultsIfNotSet()
+ {
+ $this->addDefaults = true;
+
+ return $this;
+ }
+
+ /**
+ * Adds children with a default value when none are defined.
+ *
+ * @param int|string|array|null $children The number of children|The child name|The children names to be added
+ *
+ * This method is applicable to prototype nodes only.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function addDefaultChildrenIfNoneSet($children = null)
+ {
+ $this->addDefaultChildren = $children;
+
+ return $this;
+ }
+
+ /**
+ * Requires the node to have at least one element.
+ *
+ * This method is applicable to prototype nodes only.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function requiresAtLeastOneElement()
+ {
+ $this->atLeastOne = true;
+
+ return $this;
+ }
+
+ /**
+ * Disallows adding news keys in a subsequent configuration.
+ *
+ * If used all keys have to be defined in the same configuration file.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function disallowNewKeysInSubsequentConfigs()
+ {
+ $this->allowNewKeys = false;
+
+ return $this;
+ }
+
+ /**
+ * Sets a normalization rule for XML configurations.
+ *
+ * @param string $singular The key to remap
+ * @param string $plural The plural of the key for irregular plurals
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function fixXmlConfig($singular, $plural = null)
+ {
+ $this->normalization()->remap($singular, $plural);
+
+ return $this;
+ }
+
+ /**
+ * Sets the attribute which value is to be used as key.
+ *
+ * This is useful when you have an indexed array that should be an
+ * associative array. You can select an item from within the array
+ * to be the key of the particular item. For example, if "id" is the
+ * "key", then:
+ *
+ * array(
+ * array('id' => 'my_name', 'foo' => 'bar'),
+ * );
+ *
+ * becomes
+ *
+ * array(
+ * 'my_name' => array('foo' => 'bar'),
+ * );
+ *
+ * If you'd like "'id' => 'my_name'" to still be present in the resulting
+ * array, then you can set the second argument of this method to false.
+ *
+ * This method is applicable to prototype nodes only.
+ *
+ * @param string $name The name of the key
+ * @param bool $removeKeyItem Whether or not the key item should be removed.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function useAttributeAsKey($name, $removeKeyItem = true)
+ {
+ $this->key = $name;
+ $this->removeKeyItem = $removeKeyItem;
+
+ return $this;
+ }
+
+ /**
+ * Sets whether the node can be unset.
+ *
+ * @param bool $allow
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function canBeUnset($allow = true)
+ {
+ $this->merge()->allowUnset($allow);
+
+ return $this;
+ }
+
+ /**
+ * Adds an "enabled" boolean to enable the current section.
+ *
+ * By default, the section is disabled. If any configuration is specified then
+ * the node will be automatically enabled:
+ *
+ * enableableArrayNode: {enabled: true, ...} # The config is enabled & default values get overridden
+ * enableableArrayNode: ~ # The config is enabled & use the default values
+ * enableableArrayNode: true # The config is enabled & use the default values
+ * enableableArrayNode: {other: value, ...} # The config is enabled & default values get overridden
+ * enableableArrayNode: {enabled: false, ...} # The config is disabled
+ * enableableArrayNode: false # The config is disabled
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function canBeEnabled()
+ {
+ $this
+ ->addDefaultsIfNotSet()
+ ->treatFalseLike(array('enabled' => false))
+ ->treatTrueLike(array('enabled' => true))
+ ->treatNullLike(array('enabled' => true))
+ ->beforeNormalization()
+ ->ifArray()
+ ->then(function ($v) {
+ $v['enabled'] = isset($v['enabled']) ? $v['enabled'] : true;
+
+ return $v;
+ })
+ ->end()
+ ->children()
+ ->booleanNode('enabled')
+ ->defaultFalse()
+ ;
+
+ return $this;
+ }
+
+ /**
+ * Adds an "enabled" boolean to enable the current section.
+ *
+ * By default, the section is enabled.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function canBeDisabled()
+ {
+ $this
+ ->addDefaultsIfNotSet()
+ ->treatFalseLike(array('enabled' => false))
+ ->treatTrueLike(array('enabled' => true))
+ ->treatNullLike(array('enabled' => true))
+ ->children()
+ ->booleanNode('enabled')
+ ->defaultTrue()
+ ;
+
+ return $this;
+ }
+
+ /**
+ * Disables the deep merging of the node.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function performNoDeepMerging()
+ {
+ $this->performDeepMerging = false;
+
+ return $this;
+ }
+
+ /**
+ * Allows extra config keys to be specified under an array without
+ * throwing an exception.
+ *
+ * Those config values are simply ignored and removed from the
+ * resulting array. This should be used only in special cases where
+ * you want to send an entire configuration array through a special
+ * tree that processes only part of the array.
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function ignoreExtraKeys()
+ {
+ $this->ignoreExtraKeys = true;
+
+ return $this;
+ }
+
+ /**
+ * Sets key normalization.
+ *
+ * @param bool $bool Whether to enable key normalization
+ *
+ * @return ArrayNodeDefinition
+ */
+ public function normalizeKeys($bool)
+ {
+ $this->normalizeKeys = (bool) $bool;
+
+ return $this;
+ }
+
+ /**
+ * Appends a node definition.
+ *
+ * $node = new ArrayNodeDefinition()
+ * ->children()
+ * ->scalarNode('foo')->end()
+ * ->scalarNode('baz')->end()
+ * ->end()
+ * ->append($this->getBarNodeDefinition())
+ * ;
+ *
+ * @param NodeDefinition $node A NodeDefinition instance
+ *
+ * @return ArrayNodeDefinition This node
+ */
+ public function append(NodeDefinition $node)
+ {
+ $this->children[$node->name] = $node->setParent($this);
+
+ return $this;
+ }
+
+ /**
+ * Returns a node builder to be used to add children and prototype.
+ *
+ * @return NodeBuilder The node builder
+ */
+ protected function getNodeBuilder()
+ {
+ if (null === $this->nodeBuilder) {
+ $this->nodeBuilder = new NodeBuilder();
+ }
+
+ return $this->nodeBuilder->setParent($this);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function createNode()
+ {
+ if (null === $this->prototype) {
+ $node = new ArrayNode($this->name, $this->parent);
+
+ $this->validateConcreteNode($node);
+
+ $node->setAddIfNotSet($this->addDefaults);
+
+ foreach ($this->children as $child) {
+ $child->parent = $node;
+ $node->addChild($child->getNode());
+ }
+ } else {
+ $node = new PrototypedArrayNode($this->name, $this->parent);
+
+ $this->validatePrototypeNode($node);
+
+ if (null !== $this->key) {
+ $node->setKeyAttribute($this->key, $this->removeKeyItem);
+ }
+
+ if (true === $this->atLeastOne) {
+ $node->setMinNumberOfElements(1);
+ }
+
+ if ($this->default) {
+ $node->setDefaultValue($this->defaultValue);
+ }
+
+ if (false !== $this->addDefaultChildren) {
+ $node->setAddChildrenIfNoneSet($this->addDefaultChildren);
+ if ($this->prototype instanceof static && null === $this->prototype->prototype) {
+ $this->prototype->addDefaultsIfNotSet();
+ }
+ }
+
+ $this->prototype->parent = $node;
+ $node->setPrototype($this->prototype->getNode());
+ }
+
+ $node->setAllowNewKeys($this->allowNewKeys);
+ $node->addEquivalentValue(null, $this->nullEquivalent);
+ $node->addEquivalentValue(true, $this->trueEquivalent);
+ $node->addEquivalentValue(false, $this->falseEquivalent);
+ $node->setPerformDeepMerging($this->performDeepMerging);
+ $node->setRequired($this->required);
+ $node->setIgnoreExtraKeys($this->ignoreExtraKeys);
+ $node->setNormalizeKeys($this->normalizeKeys);
+
+ if (null !== $this->normalization) {
+ $node->setNormalizationClosures($this->normalization->before);
+ $node->setXmlRemappings($this->normalization->remappings);
+ }
+
+ if (null !== $this->merge) {
+ $node->setAllowOverwrite($this->merge->allowOverwrite);
+ $node->setAllowFalse($this->merge->allowFalse);
+ }
+
+ if (null !== $this->validation) {
+ $node->setFinalValidationClosures($this->validation->rules);
+ }
+
+ return $node;
+ }
+
+ /**
+ * Validate the configuration of a concrete node.
+ *
+ * @param ArrayNode $node The related node
+ *
+ * @throws InvalidDefinitionException
+ */
+ protected function validateConcreteNode(ArrayNode $node)
+ {
+ $path = $node->getPath();
+
+ if (null !== $this->key) {
+ throw new InvalidDefinitionException(
+ sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s"', $path)
+ );
+ }
+
+ if (true === $this->atLeastOne) {
+ throw new InvalidDefinitionException(
+ sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s"', $path)
+ );
+ }
+
+ if ($this->default) {
+ throw new InvalidDefinitionException(
+ sprintf('->defaultValue() is not applicable to concrete nodes at path "%s"', $path)
+ );
+ }
+
+ if (false !== $this->addDefaultChildren) {
+ throw new InvalidDefinitionException(
+ sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s"', $path)
+ );
+ }
+ }
+
+ /**
+ * Validate the configuration of a prototype node.
+ *
+ * @param PrototypedArrayNode $node The related node
+ *
+ * @throws InvalidDefinitionException
+ */
+ protected function validatePrototypeNode(PrototypedArrayNode $node)
+ {
+ $path = $node->getPath();
+
+ if ($this->addDefaults) {
+ throw new InvalidDefinitionException(
+ sprintf('->addDefaultsIfNotSet() is not applicable to prototype nodes at path "%s"', $path)
+ );
+ }
+
+ if (false !== $this->addDefaultChildren) {
+ if ($this->default) {
+ throw new InvalidDefinitionException(
+ sprintf('A default value and default children might not be used together at path "%s"', $path)
+ );
+ }
+
+ if (null !== $this->key && (null === $this->addDefaultChildren || is_int($this->addDefaultChildren) && $this->addDefaultChildren > 0)) {
+ throw new InvalidDefinitionException(
+ sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s"', $path)
+ );
+ }
+
+ if (null === $this->key && (is_string($this->addDefaultChildren) || is_array($this->addDefaultChildren))) {
+ throw new InvalidDefinitionException(
+ sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s"', $path)
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php
new file mode 100644
index 0000000..db7ebc2
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php
@@ -0,0 +1,42 @@
+<?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\Builder;
+
+use Symfony\Component\Config\Definition\BooleanNode;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class BooleanNodeDefinition extends ScalarNodeDefinition
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct($name, NodeParentInterface $parent = null)
+ {
+ parent::__construct($name, $parent);
+
+ $this->nullEquivalent = true;
+ }
+
+ /**
+ * Instantiate a Node.
+ *
+ * @return BooleanNode The node
+ */
+ protected function instantiateNode()
+ {
+ return new BooleanNode($this->name, $this->parent);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php
new file mode 100644
index 0000000..dc25fcb
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php
@@ -0,0 +1,58 @@
+<?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\Builder;
+
+use Symfony\Component\Config\Definition\EnumNode;
+
+/**
+ * Enum Node Definition.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class EnumNodeDefinition extends ScalarNodeDefinition
+{
+ private $values;
+
+ /**
+ * @param array $values
+ *
+ * @return EnumNodeDefinition|$this
+ */
+ public function values(array $values)
+ {
+ $values = array_unique($values);
+
+ if (count($values) <= 1) {
+ throw new \InvalidArgumentException('->values() must be called with at least two distinct values.');
+ }
+
+ $this->values = $values;
+
+ return $this;
+ }
+
+ /**
+ * Instantiate a Node.
+ *
+ * @return EnumNode The node
+ *
+ * @throws \RuntimeException
+ */
+ protected function instantiateNode()
+ {
+ if (null === $this->values) {
+ throw new \RuntimeException('You must call ->values() on enum nodes.');
+ }
+
+ return new EnumNode($this->name, $this->parent, $this->values);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ExprBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ExprBuilder.php
new file mode 100644
index 0000000..7887f2d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ExprBuilder.php
@@ -0,0 +1,238 @@
+<?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\Builder;
+
+use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
+
+/**
+ * This class builds an if expression.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class ExprBuilder
+{
+ protected $node;
+ public $ifPart;
+ public $thenPart;
+
+ /**
+ * Constructor.
+ *
+ * @param NodeDefinition $node The related node
+ */
+ public function __construct(NodeDefinition $node)
+ {
+ $this->node = $node;
+ }
+
+ /**
+ * Marks the expression as being always used.
+ *
+ * @param \Closure $then
+ *
+ * @return ExprBuilder
+ */
+ public function always(\Closure $then = null)
+ {
+ $this->ifPart = function ($v) { return true; };
+
+ if (null !== $then) {
+ $this->thenPart = $then;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sets a closure to use as tests.
+ *
+ * The default one tests if the value is true.
+ *
+ * @param \Closure $closure
+ *
+ * @return ExprBuilder
+ */
+ public function ifTrue(\Closure $closure = null)
+ {
+ if (null === $closure) {
+ $closure = function ($v) { return true === $v; };
+ }
+
+ $this->ifPart = $closure;
+
+ return $this;
+ }
+
+ /**
+ * Tests if the value is a string.
+ *
+ * @return ExprBuilder
+ */
+ public function ifString()
+ {
+ $this->ifPart = function ($v) { return is_string($v); };
+
+ return $this;
+ }
+
+ /**
+ * Tests if the value is null.
+ *
+ * @return ExprBuilder
+ */
+ public function ifNull()
+ {
+ $this->ifPart = function ($v) { return null === $v; };
+
+ return $this;
+ }
+
+ /**
+ * Tests if the value is an array.
+ *
+ * @return ExprBuilder
+ */
+ public function ifArray()
+ {
+ $this->ifPart = function ($v) { return is_array($v); };
+
+ return $this;
+ }
+
+ /**
+ * Tests if the value is in an array.
+ *
+ * @param array $array
+ *
+ * @return ExprBuilder
+ */
+ public function ifInArray(array $array)
+ {
+ $this->ifPart = function ($v) use ($array) { return in_array($v, $array, true); };
+
+ return $this;
+ }
+
+ /**
+ * Tests if the value is not in an array.
+ *
+ * @param array $array
+ *
+ * @return ExprBuilder
+ */
+ public function ifNotInArray(array $array)
+ {
+ $this->ifPart = function ($v) use ($array) { return !in_array($v, $array, true); };
+
+ return $this;
+ }
+
+ /**
+ * Sets the closure to run if the test pass.
+ *
+ * @param \Closure $closure
+ *
+ * @return ExprBuilder
+ */
+ public function then(\Closure $closure)
+ {
+ $this->thenPart = $closure;
+
+ return $this;
+ }
+
+ /**
+ * Sets a closure returning an empty array.
+ *
+ * @return ExprBuilder
+ */
+ public function thenEmptyArray()
+ {
+ $this->thenPart = function ($v) { return array(); };
+
+ return $this;
+ }
+
+ /**
+ * Sets a closure marking the value as invalid at validation time.
+ *
+ * if you want to add the value of the node in your message just use a %s placeholder.
+ *
+ * @param string $message
+ *
+ * @return ExprBuilder
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function thenInvalid($message)
+ {
+ $this->thenPart = function ($v) use ($message) {throw new \InvalidArgumentException(sprintf($message, json_encode($v))); };
+
+ return $this;
+ }
+
+ /**
+ * Sets a closure unsetting this key of the array at validation time.
+ *
+ * @return ExprBuilder
+ *
+ * @throws UnsetKeyException
+ */
+ public function thenUnset()
+ {
+ $this->thenPart = function ($v) { throw new UnsetKeyException('Unsetting key'); };
+
+ return $this;
+ }
+
+ /**
+ * Returns the related node.
+ *
+ * @return NodeDefinition
+ *
+ * @throws \RuntimeException
+ */
+ public function end()
+ {
+ if (null === $this->ifPart) {
+ throw new \RuntimeException('You must specify an if part.');
+ }
+ if (null === $this->thenPart) {
+ throw new \RuntimeException('You must specify a then part.');
+ }
+
+ return $this->node;
+ }
+
+ /**
+ * Builds the expressions.
+ *
+ * @param ExprBuilder[] $expressions An array of ExprBuilder instances to build
+ *
+ * @return array
+ */
+ public static function buildExpressions(array $expressions)
+ {
+ foreach ($expressions as $k => $expr) {
+ if ($expr instanceof ExprBuilder) {
+ $if = $expr->ifPart;
+ $then = $expr->thenPart;
+ $expressions[$k] = function ($v) use ($if, $then) {
+ return $if($v) ? $then($v) : $v;
+ };
+ }
+ }
+
+ return $expressions;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php
new file mode 100644
index 0000000..c0bed46
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/FloatNodeDefinition.php
@@ -0,0 +1,32 @@
+<?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\Builder;
+
+use Symfony\Component\Config\Definition\FloatNode;
+
+/**
+ * This class provides a fluent interface for defining a float node.
+ *
+ * @author Jeanmonod David <david.jeanmonod@gmail.com>
+ */
+class FloatNodeDefinition extends NumericNodeDefinition
+{
+ /**
+ * Instantiates a Node.
+ *
+ * @return FloatNode The node
+ */
+ protected function instantiateNode()
+ {
+ return new FloatNode($this->name, $this->parent, $this->min, $this->max);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php
new file mode 100644
index 0000000..f6c3c14
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/IntegerNodeDefinition.php
@@ -0,0 +1,32 @@
+<?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\Builder;
+
+use Symfony\Component\Config\Definition\IntegerNode;
+
+/**
+ * This class provides a fluent interface for defining an integer node.
+ *
+ * @author Jeanmonod David <david.jeanmonod@gmail.com>
+ */
+class IntegerNodeDefinition extends NumericNodeDefinition
+{
+ /**
+ * Instantiates a Node.
+ *
+ * @return IntegerNode The node
+ */
+ protected function instantiateNode()
+ {
+ return new IntegerNode($this->name, $this->parent, $this->min, $this->max);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/MergeBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/MergeBuilder.php
new file mode 100644
index 0000000..f908a49
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/MergeBuilder.php
@@ -0,0 +1,72 @@
+<?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\Builder;
+
+/**
+ * This class builds merge conditions.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class MergeBuilder
+{
+ protected $node;
+ public $allowFalse = false;
+ public $allowOverwrite = true;
+
+ /**
+ * Constructor.
+ *
+ * @param NodeDefinition $node The related node
+ */
+ public function __construct(NodeDefinition $node)
+ {
+ $this->node = $node;
+ }
+
+ /**
+ * Sets whether the node can be unset.
+ *
+ * @param bool $allow
+ *
+ * @return MergeBuilder
+ */
+ public function allowUnset($allow = true)
+ {
+ $this->allowFalse = $allow;
+
+ return $this;
+ }
+
+ /**
+ * Sets whether the node can be overwritten.
+ *
+ * @param bool $deny Whether the overwriting is forbidden or not
+ *
+ * @return MergeBuilder
+ */
+ public function denyOverwrite($deny = true)
+ {
+ $this->allowOverwrite = !$deny;
+
+ return $this;
+ }
+
+ /**
+ * Returns the related node.
+ *
+ * @return NodeDefinition
+ */
+ public function end()
+ {
+ return $this->node;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeBuilder.php
new file mode 100644
index 0000000..b2b6336
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeBuilder.php
@@ -0,0 +1,245 @@
+<?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\Builder;
+
+/**
+ * This class provides a fluent interface for building a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class NodeBuilder implements NodeParentInterface
+{
+ protected $parent;
+ protected $nodeMapping;
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ $this->nodeMapping = array(
+ 'variable' => __NAMESPACE__.'\\VariableNodeDefinition',
+ 'scalar' => __NAMESPACE__.'\\ScalarNodeDefinition',
+ 'boolean' => __NAMESPACE__.'\\BooleanNodeDefinition',
+ 'integer' => __NAMESPACE__.'\\IntegerNodeDefinition',
+ 'float' => __NAMESPACE__.'\\FloatNodeDefinition',
+ 'array' => __NAMESPACE__.'\\ArrayNodeDefinition',
+ 'enum' => __NAMESPACE__.'\\EnumNodeDefinition',
+ );
+ }
+
+ /**
+ * Set the parent node.
+ *
+ * @param ParentNodeDefinitionInterface $parent The parent node
+ *
+ * @return NodeBuilder This node builder
+ */
+ public function setParent(ParentNodeDefinitionInterface $parent = null)
+ {
+ $this->parent = $parent;
+
+ return $this;
+ }
+
+ /**
+ * Creates a child array node.
+ *
+ * @param string $name The name of the node
+ *
+ * @return ArrayNodeDefinition The child node
+ */
+ public function arrayNode($name)
+ {
+ return $this->node($name, 'array');
+ }
+
+ /**
+ * Creates a child scalar node.
+ *
+ * @param string $name the name of the node
+ *
+ * @return ScalarNodeDefinition The child node
+ */
+ public function scalarNode($name)
+ {
+ return $this->node($name, 'scalar');
+ }
+
+ /**
+ * Creates a child Boolean node.
+ *
+ * @param string $name The name of the node
+ *
+ * @return BooleanNodeDefinition The child node
+ */
+ public function booleanNode($name)
+ {
+ return $this->node($name, 'boolean');
+ }
+
+ /**
+ * Creates a child integer node.
+ *
+ * @param string $name the name of the node
+ *
+ * @return IntegerNodeDefinition The child node
+ */
+ public function integerNode($name)
+ {
+ return $this->node($name, 'integer');
+ }
+
+ /**
+ * Creates a child float node.
+ *
+ * @param string $name the name of the node
+ *
+ * @return FloatNodeDefinition The child node
+ */
+ public function floatNode($name)
+ {
+ return $this->node($name, 'float');
+ }
+
+ /**
+ * Creates a child EnumNode.
+ *
+ * @param string $name
+ *
+ * @return EnumNodeDefinition
+ */
+ public function enumNode($name)
+ {
+ return $this->node($name, 'enum');
+ }
+
+ /**
+ * Creates a child variable node.
+ *
+ * @param string $name The name of the node
+ *
+ * @return VariableNodeDefinition The builder of the child node
+ */
+ public function variableNode($name)
+ {
+ return $this->node($name, 'variable');
+ }
+
+ /**
+ * Returns the parent node.
+ *
+ * @return ParentNodeDefinitionInterface The parent node
+ */
+ public function end()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Creates a child node.
+ *
+ * @param string $name The name of the node
+ * @param string $type The type of the node
+ *
+ * @return NodeDefinition The child node
+ *
+ * @throws \RuntimeException When the node type is not registered
+ * @throws \RuntimeException When the node class is not found
+ */
+ public function node($name, $type)
+ {
+ $class = $this->getNodeClass($type);
+
+ $node = new $class($name);
+
+ $this->append($node);
+
+ return $node;
+ }
+
+ /**
+ * Appends a node definition.
+ *
+ * Usage:
+ *
+ * $node = new ArrayNodeDefinition('name')
+ * ->children()
+ * ->scalarNode('foo')->end()
+ * ->scalarNode('baz')->end()
+ * ->append($this->getBarNodeDefinition())
+ * ->end()
+ * ;
+ *
+ * @param NodeDefinition $node
+ *
+ * @return NodeBuilder This node builder
+ */
+ public function append(NodeDefinition $node)
+ {
+ if ($node instanceof ParentNodeDefinitionInterface) {
+ $builder = clone $this;
+ $builder->setParent(null);
+ $node->setBuilder($builder);
+ }
+
+ if (null !== $this->parent) {
+ $this->parent->append($node);
+ // Make this builder the node parent to allow for a fluid interface
+ $node->setParent($this);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds or overrides a node Type.
+ *
+ * @param string $type The name of the type
+ * @param string $class The fully qualified name the node definition class
+ *
+ * @return NodeBuilder This node builder
+ */
+ public function setNodeClass($type, $class)
+ {
+ $this->nodeMapping[strtolower($type)] = $class;
+
+ return $this;
+ }
+
+ /**
+ * Returns the class name of the node definition.
+ *
+ * @param string $type The node type
+ *
+ * @return string The node definition class name
+ *
+ * @throws \RuntimeException When the node type is not registered
+ * @throws \RuntimeException When the node class is not found
+ */
+ protected function getNodeClass($type)
+ {
+ $type = strtolower($type);
+
+ if (!isset($this->nodeMapping[$type])) {
+ throw new \RuntimeException(sprintf('The node type "%s" is not registered.', $type));
+ }
+
+ $class = $this->nodeMapping[$type];
+
+ if (!class_exists($class)) {
+ throw new \RuntimeException(sprintf('The node class "%s" does not exist.', $class));
+ }
+
+ return $class;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeDefinition.php
new file mode 100644
index 0000000..f7f84bc
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeDefinition.php
@@ -0,0 +1,343 @@
+<?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\Builder;
+
+use Symfony\Component\Config\Definition\NodeInterface;
+use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+abstract class NodeDefinition implements NodeParentInterface
+{
+ protected $name;
+ protected $normalization;
+ protected $validation;
+ protected $defaultValue;
+ protected $default = false;
+ protected $required = false;
+ protected $merge;
+ protected $allowEmptyValue = true;
+ protected $nullEquivalent;
+ protected $trueEquivalent = true;
+ protected $falseEquivalent = false;
+
+ /**
+ * @var NodeParentInterface|null
+ */
+ protected $parent;
+ protected $attributes = array();
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the node
+ * @param NodeParentInterface|null $parent The parent
+ */
+ public function __construct($name, NodeParentInterface $parent = null)
+ {
+ $this->parent = $parent;
+ $this->name = $name;
+ }
+
+ /**
+ * Sets the parent node.
+ *
+ * @param NodeParentInterface $parent The parent
+ *
+ * @return NodeDefinition|$this
+ */
+ public function setParent(NodeParentInterface $parent)
+ {
+ $this->parent = $parent;
+
+ return $this;
+ }
+
+ /**
+ * Sets info message.
+ *
+ * @param string $info The info text
+ *
+ * @return NodeDefinition|$this
+ */
+ public function info($info)
+ {
+ return $this->attribute('info', $info);
+ }
+
+ /**
+ * Sets example configuration.
+ *
+ * @param string|array $example
+ *
+ * @return NodeDefinition|$this
+ */
+ public function example($example)
+ {
+ return $this->attribute('example', $example);
+ }
+
+ /**
+ * Sets an attribute on the node.
+ *
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return NodeDefinition|$this
+ */
+ public function attribute($key, $value)
+ {
+ $this->attributes[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Returns the parent node.
+ *
+ * @return NodeParentInterface|null The builder of the parent node
+ */
+ public function end()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Creates the node.
+ *
+ * @param bool $forceRootNode Whether to force this node as the root node
+ *
+ * @return NodeInterface
+ */
+ public function getNode($forceRootNode = false)
+ {
+ if ($forceRootNode) {
+ $this->parent = null;
+ }
+
+ if (null !== $this->normalization) {
+ $this->normalization->before = ExprBuilder::buildExpressions($this->normalization->before);
+ }
+
+ if (null !== $this->validation) {
+ $this->validation->rules = ExprBuilder::buildExpressions($this->validation->rules);
+ }
+
+ $node = $this->createNode();
+ $node->setAttributes($this->attributes);
+
+ return $node;
+ }
+
+ /**
+ * Sets the default value.
+ *
+ * @param mixed $value The default value
+ *
+ * @return NodeDefinition|$this
+ */
+ public function defaultValue($value)
+ {
+ $this->default = true;
+ $this->defaultValue = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets the node as required.
+ *
+ * @return NodeDefinition|$this
+ */
+ public function isRequired()
+ {
+ $this->required = true;
+
+ return $this;
+ }
+
+ /**
+ * Sets the equivalent value used when the node contains null.
+ *
+ * @param mixed $value
+ *
+ * @return NodeDefinition|$this
+ */
+ public function treatNullLike($value)
+ {
+ $this->nullEquivalent = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets the equivalent value used when the node contains true.
+ *
+ * @param mixed $value
+ *
+ * @return NodeDefinition|$this
+ */
+ public function treatTrueLike($value)
+ {
+ $this->trueEquivalent = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets the equivalent value used when the node contains false.
+ *
+ * @param mixed $value
+ *
+ * @return NodeDefinition|$this
+ */
+ public function treatFalseLike($value)
+ {
+ $this->falseEquivalent = $value;
+
+ return $this;
+ }
+
+ /**
+ * Sets null as the default value.
+ *
+ * @return NodeDefinition|$this
+ */
+ public function defaultNull()
+ {
+ return $this->defaultValue(null);
+ }
+
+ /**
+ * Sets true as the default value.
+ *
+ * @return NodeDefinition|$this
+ */
+ public function defaultTrue()
+ {
+ return $this->defaultValue(true);
+ }
+
+ /**
+ * Sets false as the default value.
+ *
+ * @return NodeDefinition|$this
+ */
+ public function defaultFalse()
+ {
+ return $this->defaultValue(false);
+ }
+
+ /**
+ * Sets an expression to run before the normalization.
+ *
+ * @return ExprBuilder
+ */
+ public function beforeNormalization()
+ {
+ return $this->normalization()->before();
+ }
+
+ /**
+ * Denies the node value being empty.
+ *
+ * @return NodeDefinition|$this
+ */
+ public function cannotBeEmpty()
+ {
+ $this->allowEmptyValue = false;
+
+ return $this;
+ }
+
+ /**
+ * Sets an expression to run for the validation.
+ *
+ * The expression receives the value of the node and must return it. It can
+ * modify it.
+ * An exception should be thrown when the node is not valid.
+ *
+ * @return ExprBuilder
+ */
+ public function validate()
+ {
+ return $this->validation()->rule();
+ }
+
+ /**
+ * Sets whether the node can be overwritten.
+ *
+ * @param bool $deny Whether the overwriting is forbidden or not
+ *
+ * @return NodeDefinition|$this
+ */
+ public function cannotBeOverwritten($deny = true)
+ {
+ $this->merge()->denyOverwrite($deny);
+
+ return $this;
+ }
+
+ /**
+ * Gets the builder for validation rules.
+ *
+ * @return ValidationBuilder
+ */
+ protected function validation()
+ {
+ if (null === $this->validation) {
+ $this->validation = new ValidationBuilder($this);
+ }
+
+ return $this->validation;
+ }
+
+ /**
+ * Gets the builder for merging rules.
+ *
+ * @return MergeBuilder
+ */
+ protected function merge()
+ {
+ if (null === $this->merge) {
+ $this->merge = new MergeBuilder($this);
+ }
+
+ return $this->merge;
+ }
+
+ /**
+ * Gets the builder for normalization rules.
+ *
+ * @return NormalizationBuilder
+ */
+ protected function normalization()
+ {
+ if (null === $this->normalization) {
+ $this->normalization = new NormalizationBuilder($this);
+ }
+
+ return $this->normalization;
+ }
+
+ /**
+ * Instantiate and configure the node according to this definition.
+ *
+ * @return NodeInterface $node The node instance
+ *
+ * @throws InvalidDefinitionException When the definition is invalid
+ */
+ abstract protected function createNode();
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php
new file mode 100644
index 0000000..305e993
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php
@@ -0,0 +1,21 @@
+<?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\Builder;
+
+/**
+ * An interface that must be implemented by all node parents.
+ *
+ * @author Victor Berchet <victor@suumit.com>
+ */
+interface NodeParentInterface
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php
new file mode 100644
index 0000000..748c9f2
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php
@@ -0,0 +1,67 @@
+<?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\Builder;
+
+/**
+ * This class builds normalization conditions.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class NormalizationBuilder
+{
+ protected $node;
+ public $before = array();
+ public $remappings = array();
+
+ /**
+ * Constructor.
+ *
+ * @param NodeDefinition $node The related node
+ */
+ public function __construct(NodeDefinition $node)
+ {
+ $this->node = $node;
+ }
+
+ /**
+ * Registers a key to remap to its plural form.
+ *
+ * @param string $key The key to remap
+ * @param string $plural The plural of the key in case of irregular plural
+ *
+ * @return NormalizationBuilder
+ */
+ public function remap($key, $plural = null)
+ {
+ $this->remappings[] = array($key, null === $plural ? $key.'s' : $plural);
+
+ return $this;
+ }
+
+ /**
+ * Registers a closure to run before the normalization or an expression builder to build it if null is provided.
+ *
+ * @param \Closure $closure
+ *
+ * @return ExprBuilder|NormalizationBuilder
+ */
+ public function before(\Closure $closure = null)
+ {
+ if (null !== $closure) {
+ $this->before[] = $closure;
+
+ return $this;
+ }
+
+ return $this->before[] = new ExprBuilder($this->node);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php
new file mode 100644
index 0000000..ddd716d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/NumericNodeDefinition.php
@@ -0,0 +1,61 @@
+<?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\Builder;
+
+/**
+ * Abstract class that contains common code of integer and float node definitions.
+ *
+ * @author David Jeanmonod <david.jeanmonod@gmail.com>
+ */
+abstract class NumericNodeDefinition extends ScalarNodeDefinition
+{
+ protected $min;
+ protected $max;
+
+ /**
+ * Ensures that the value is smaller than the given reference.
+ *
+ * @param mixed $max
+ *
+ * @return NumericNodeDefinition
+ *
+ * @throws \InvalidArgumentException when the constraint is inconsistent
+ */
+ public function max($max)
+ {
+ if (isset($this->min) && $this->min > $max) {
+ throw new \InvalidArgumentException(sprintf('You cannot define a max(%s) as you already have a min(%s)', $max, $this->min));
+ }
+ $this->max = $max;
+
+ return $this;
+ }
+
+ /**
+ * Ensures that the value is bigger than the given reference.
+ *
+ * @param mixed $min
+ *
+ * @return NumericNodeDefinition
+ *
+ * @throws \InvalidArgumentException when the constraint is inconsistent
+ */
+ public function min($min)
+ {
+ if (isset($this->max) && $this->max < $min) {
+ throw new \InvalidArgumentException(sprintf('You cannot define a min(%s) as you already have a max(%s)', $min, $this->max));
+ }
+ $this->min = $min;
+
+ return $this;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php
new file mode 100644
index 0000000..575495b
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php
@@ -0,0 +1,26 @@
+<?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\Builder;
+
+/**
+ * An interface that must be implemented by nodes which can have children.
+ *
+ * @author Victor Berchet <victor@suumit.com>
+ */
+interface ParentNodeDefinitionInterface
+{
+ public function children();
+
+ public function append(NodeDefinition $node);
+
+ public function setBuilder(NodeBuilder $builder);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php
new file mode 100644
index 0000000..6170555
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php
@@ -0,0 +1,32 @@
+<?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\Builder;
+
+use Symfony\Component\Config\Definition\ScalarNode;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ScalarNodeDefinition extends VariableNodeDefinition
+{
+ /**
+ * Instantiate a Node.
+ *
+ * @return ScalarNode The node
+ */
+ protected function instantiateNode()
+ {
+ return new ScalarNode($this->name, $this->parent);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/TreeBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/TreeBuilder.php
new file mode 100644
index 0000000..5d02848
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/TreeBuilder.php
@@ -0,0 +1,63 @@
+<?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\Builder;
+
+use Symfony\Component\Config\Definition\NodeInterface;
+
+/**
+ * This is the entry class for building a config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class TreeBuilder implements NodeParentInterface
+{
+ protected $tree;
+ protected $root;
+ protected $builder;
+
+ /**
+ * Creates the root node.
+ *
+ * @param string $name The name of the root node
+ * @param string $type The type of the root node
+ * @param NodeBuilder $builder A custom node builder instance
+ *
+ * @return ArrayNodeDefinition|NodeDefinition The root node (as an ArrayNodeDefinition when the type is 'array')
+ *
+ * @throws \RuntimeException When the node type is not supported
+ */
+ public function root($name, $type = 'array', NodeBuilder $builder = null)
+ {
+ $builder = $builder ?: new NodeBuilder();
+
+ return $this->root = $builder->node($name, $type)->setParent($this);
+ }
+
+ /**
+ * Builds the tree.
+ *
+ * @return NodeInterface
+ *
+ * @throws \RuntimeException
+ */
+ public function buildTree()
+ {
+ if (null === $this->root) {
+ throw new \RuntimeException('The configuration tree has no root node.');
+ }
+ if (null !== $this->tree) {
+ return $this->tree;
+ }
+
+ return $this->tree = $this->root->getNode(true);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php
new file mode 100644
index 0000000..e885823
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php
@@ -0,0 +1,51 @@
+<?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\Builder;
+
+/**
+ * This class builds validation conditions.
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class ValidationBuilder
+{
+ protected $node;
+ public $rules = array();
+
+ /**
+ * Constructor.
+ *
+ * @param NodeDefinition $node The related node
+ */
+ public function __construct(NodeDefinition $node)
+ {
+ $this->node = $node;
+ }
+
+ /**
+ * Registers a closure to run as normalization or an expression builder to build it if null is provided.
+ *
+ * @param \Closure $closure
+ *
+ * @return ExprBuilder|ValidationBuilder
+ */
+ public function rule(\Closure $closure = null)
+ {
+ if (null !== $closure) {
+ $this->rules[] = $closure;
+
+ return $this;
+ }
+
+ return $this->rules[] = new ExprBuilder($this->node);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php
new file mode 100644
index 0000000..a46b7ea
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php
@@ -0,0 +1,64 @@
+<?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\Builder;
+
+use Symfony\Component\Config\Definition\VariableNode;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class VariableNodeDefinition extends NodeDefinition
+{
+ /**
+ * Instantiate a Node.
+ *
+ * @return VariableNode The node
+ */
+ protected function instantiateNode()
+ {
+ return new VariableNode($this->name, $this->parent);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function createNode()
+ {
+ $node = $this->instantiateNode();
+
+ if (null !== $this->normalization) {
+ $node->setNormalizationClosures($this->normalization->before);
+ }
+
+ if (null !== $this->merge) {
+ $node->setAllowOverwrite($this->merge->allowOverwrite);
+ }
+
+ if (true === $this->default) {
+ $node->setDefaultValue($this->defaultValue);
+ }
+
+ $node->setAllowEmptyValue($this->allowEmptyValue);
+ $node->addEquivalentValue(null, $this->nullEquivalent);
+ $node->addEquivalentValue(true, $this->trueEquivalent);
+ $node->addEquivalentValue(false, $this->falseEquivalent);
+ $node->setRequired($this->required);
+
+ if (null !== $this->validation) {
+ $node->setFinalValidationClosures($this->validation->rules);
+ }
+
+ return $node;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/ConfigurationInterface.php b/vendor/symfony/config/Symfony/Component/Config/Definition/ConfigurationInterface.php
new file mode 100644
index 0000000..d6456ed
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/ConfigurationInterface.php
@@ -0,0 +1,27 @@
+<?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;
+
+/**
+ * Configuration interface.
+ *
+ * @author Victor Berchet <victor@suumit.com>
+ */
+interface ConfigurationInterface
+{
+ /**
+ * Generates the configuration tree builder.
+ *
+ * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder
+ */
+ public function getConfigTreeBuilder();
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php
new file mode 100644
index 0000000..ab56a92
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/XmlReferenceDumper.php
@@ -0,0 +1,300 @@
+<?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\Dumper;
+
+use Symfony\Component\Config\Definition\ConfigurationInterface;
+use Symfony\Component\Config\Definition\NodeInterface;
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\EnumNode;
+use Symfony\Component\Config\Definition\PrototypedArrayNode;
+
+/**
+ * Dumps a XML reference configuration for the given configuration/node instance.
+ *
+ * @author Wouter J <waldio.webdesign@gmail.com>
+ */
+class XmlReferenceDumper
+{
+ private $reference;
+
+ public function dump(ConfigurationInterface $configuration, $namespace = null)
+ {
+ return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree(), $namespace);
+ }
+
+ public function dumpNode(NodeInterface $node, $namespace = null)
+ {
+ $this->reference = '';
+ $this->writeNode($node, 0, true, $namespace);
+ $ref = $this->reference;
+ $this->reference = null;
+
+ return $ref;
+ }
+
+ /**
+ * @param NodeInterface $node
+ * @param int $depth
+ * @param bool $root If the node is the root node
+ * @param string $namespace The namespace of the node
+ */
+ private function writeNode(NodeInterface $node, $depth = 0, $root = false, $namespace = null)
+ {
+ $rootName = ($root ? 'config' : $node->getName());
+ $rootNamespace = ($namespace ?: ($root ? 'http://example.org/schema/dic/'.$node->getName() : null));
+
+ // xml remapping
+ if ($node->getParent()) {
+ $remapping = array_filter($node->getParent()->getXmlRemappings(), function ($mapping) use ($rootName) {
+ return $rootName === $mapping[1];
+ });
+
+ if (count($remapping)) {
+ list($singular) = current($remapping);
+ $rootName = $singular;
+ }
+ }
+ $rootName = str_replace('_', '-', $rootName);
+
+ $rootAttributes = array();
+ $rootAttributeComments = array();
+ $rootChildren = array();
+ $rootComments = array();
+
+ if ($node instanceof ArrayNode) {
+ $children = $node->getChildren();
+
+ // comments about the root node
+ if ($rootInfo = $node->getInfo()) {
+ $rootComments[] = $rootInfo;
+ }
+
+ if ($rootNamespace) {
+ $rootComments[] = 'Namespace: '.$rootNamespace;
+ }
+
+ // render prototyped nodes
+ if ($node instanceof PrototypedArrayNode) {
+ array_unshift($rootComments, 'prototype');
+
+ if ($key = $node->getKeyAttribute()) {
+ $rootAttributes[$key] = str_replace('-', ' ', $rootName).' '.$key;
+ }
+
+ $prototype = $node->getPrototype();
+
+ if ($prototype instanceof ArrayNode) {
+ $children = $prototype->getChildren();
+ } else {
+ if ($prototype->hasDefaultValue()) {
+ $prototypeValue = $prototype->getDefaultValue();
+ } else {
+ switch (get_class($prototype)) {
+ case 'Symfony\Component\Config\Definition\ScalarNode':
+ $prototypeValue = 'scalar value';
+ break;
+
+ case 'Symfony\Component\Config\Definition\FloatNode':
+ case 'Symfony\Component\Config\Definition\IntegerNode':
+ $prototypeValue = 'numeric value';
+ break;
+
+ case 'Symfony\Component\Config\Definition\BooleanNode':
+ $prototypeValue = 'true|false';
+ break;
+
+ case 'Symfony\Component\Config\Definition\EnumNode':
+ $prototypeValue = implode('|', array_map('json_encode', $prototype->getValues()));
+ break;
+
+ default:
+ $prototypeValue = 'value';
+ }
+ }
+ }
+ }
+
+ // get attributes and elements
+ foreach ($children as $child) {
+ if (!$child instanceof ArrayNode) {
+ // get attributes
+
+ // metadata
+ $name = str_replace('_', '-', $child->getName());
+ $value = '%%%%not_defined%%%%'; // use a string which isn't used in the normal world
+
+ // comments
+ $comments = array();
+ if ($info = $child->getInfo()) {
+ $comments[] = $info;
+ }
+
+ if ($example = $child->getExample()) {
+ $comments[] = 'Example: '.$example;
+ }
+
+ if ($child->isRequired()) {
+ $comments[] = 'Required';
+ }
+
+ if ($child instanceof EnumNode) {
+ $comments[] = 'One of '.implode('; ', array_map('json_encode', $child->getValues()));
+ }
+
+ if (count($comments)) {
+ $rootAttributeComments[$name] = implode(";\n", $comments);
+ }
+
+ // default values
+ if ($child->hasDefaultValue()) {
+ $value = $child->getDefaultValue();
+ }
+
+ // append attribute
+ $rootAttributes[$name] = $value;
+ } else {
+ // get elements
+ $rootChildren[] = $child;
+ }
+ }
+ }
+
+ // render comments
+
+ // root node comment
+ if (count($rootComments)) {
+ foreach ($rootComments as $comment) {
+ $this->writeLine('<!-- '.$comment.' -->', $depth);
+ }
+ }
+
+ // attribute comments
+ if (count($rootAttributeComments)) {
+ foreach ($rootAttributeComments as $attrName => $comment) {
+ $commentDepth = $depth + 4 + strlen($attrName) + 2;
+ $commentLines = explode("\n", $comment);
+ $multiline = (count($commentLines) > 1);
+ $comment = implode(PHP_EOL.str_repeat(' ', $commentDepth), $commentLines);
+
+ if ($multiline) {
+ $this->writeLine('<!--', $depth);
+ $this->writeLine($attrName.': '.$comment, $depth + 4);
+ $this->writeLine('-->', $depth);
+ } else {
+ $this->writeLine('<!-- '.$attrName.': '.$comment.' -->', $depth);
+ }
+ }
+ }
+
+ // render start tag + attributes
+ $rootIsVariablePrototype = isset($prototypeValue);
+ $rootIsEmptyTag = (0 === count($rootChildren) && !$rootIsVariablePrototype);
+ $rootOpenTag = '<'.$rootName;
+ if (1 >= ($attributesCount = count($rootAttributes))) {
+ if (1 === $attributesCount) {
+ $rootOpenTag .= sprintf(' %s="%s"', current(array_keys($rootAttributes)), $this->writeValue(current($rootAttributes)));
+ }
+
+ $rootOpenTag .= $rootIsEmptyTag ? ' />' : '>';
+
+ if ($rootIsVariablePrototype) {
+ $rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
+ }
+
+ $this->writeLine($rootOpenTag, $depth);
+ } else {
+ $this->writeLine($rootOpenTag, $depth);
+
+ $i = 1;
+
+ foreach ($rootAttributes as $attrName => $attrValue) {
+ $attr = sprintf('%s="%s"', $attrName, $this->writeValue($attrValue));
+
+ $this->writeLine($attr, $depth + 4);
+
+ if ($attributesCount === $i++) {
+ $this->writeLine($rootIsEmptyTag ? '/>' : '>', $depth);
+
+ if ($rootIsVariablePrototype) {
+ $rootOpenTag .= $prototypeValue.'</'.$rootName.'>';
+ }
+ }
+ }
+ }
+
+ // render children tags
+ foreach ($rootChildren as $child) {
+ $this->writeLine('');
+ $this->writeNode($child, $depth + 4);
+ }
+
+ // render end tag
+ if (!$rootIsEmptyTag && !$rootIsVariablePrototype) {
+ $this->writeLine('');
+
+ $rootEndTag = '</'.$rootName.'>';
+ $this->writeLine($rootEndTag, $depth);
+ }
+ }
+
+ /**
+ * Outputs a single config reference line
+ *
+ * @param string $text
+ * @param int $indent
+ */
+ private function writeLine($text, $indent = 0)
+ {
+ $indent = strlen($text) + $indent;
+ $format = '%'.$indent.'s';
+
+ $this->reference .= sprintf($format, $text)."\n";
+ }
+
+ /**
+ * Renders the string conversion of the value.
+ *
+ * @param mixed $value
+ *
+ * @return string
+ */
+ private function writeValue($value)
+ {
+ if ('%%%%not_defined%%%%' === $value) {
+ return '';
+ }
+
+ if (is_string($value) || is_numeric($value)) {
+ return $value;
+ }
+
+ if (false === $value) {
+ return 'false';
+ }
+
+ if (true === $value) {
+ return 'true';
+ }
+
+ if (null === $value) {
+ return 'null';
+ }
+
+ if (empty($value)) {
+ return '';
+ }
+
+ if (is_array($value)) {
+ return implode(',', $value);
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php
new file mode 100644
index 0000000..a7cd448
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php
@@ -0,0 +1,198 @@
+<?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\Dumper;
+
+use Symfony\Component\Config\Definition\ConfigurationInterface;
+use Symfony\Component\Config\Definition\NodeInterface;
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\EnumNode;
+use Symfony\Component\Config\Definition\PrototypedArrayNode;
+use Symfony\Component\Yaml\Inline;
+
+/**
+ * Dumps a Yaml reference configuration for the given configuration/node instance.
+ *
+ * @author Kevin Bond <kevinbond@gmail.com>
+ */
+class YamlReferenceDumper
+{
+ private $reference;
+
+ public function dump(ConfigurationInterface $configuration)
+ {
+ return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree());
+ }
+
+ public function dumpNode(NodeInterface $node)
+ {
+ $this->reference = '';
+ $this->writeNode($node);
+ $ref = $this->reference;
+ $this->reference = null;
+
+ return $ref;
+ }
+
+ /**
+ * @param NodeInterface $node
+ * @param int $depth
+ */
+ private function writeNode(NodeInterface $node, $depth = 0)
+ {
+ $comments = array();
+ $default = '';
+ $defaultArray = null;
+ $children = null;
+ $example = $node->getExample();
+
+ // defaults
+ if ($node instanceof ArrayNode) {
+ $children = $node->getChildren();
+
+ if ($node instanceof PrototypedArrayNode) {
+ $prototype = $node->getPrototype();
+
+ if ($prototype instanceof ArrayNode) {
+ $children = $prototype->getChildren();
+ }
+
+ // check for attribute as key
+ if ($key = $node->getKeyAttribute()) {
+ $keyNodeClass = 'Symfony\Component\Config\Definition\\'.($prototype instanceof ArrayNode ? 'ArrayNode' : 'ScalarNode');
+ $keyNode = new $keyNodeClass($key, $node);
+ $keyNode->setInfo('Prototype');
+
+ // add children
+ foreach ($children as $childNode) {
+ $keyNode->addChild($childNode);
+ }
+ $children = array($key => $keyNode);
+ }
+ }
+
+ if (!$children) {
+ if ($node->hasDefaultValue() && count($defaultArray = $node->getDefaultValue())) {
+ $default = '';
+ } elseif (!is_array($example)) {
+ $default = '[]';
+ }
+ }
+ } elseif ($node instanceof EnumNode) {
+ $comments[] = 'One of '.implode('; ', array_map('json_encode', $node->getValues()));
+ $default = '~';
+ } else {
+ $default = '~';
+
+ if ($node->hasDefaultValue()) {
+ $default = $node->getDefaultValue();
+
+ if (is_array($default)) {
+ if (count($defaultArray = $node->getDefaultValue())) {
+ $default = '';
+ } elseif (!is_array($example)) {
+ $default = '[]';
+ }
+ } else {
+ $default = Inline::dump($default);
+ }
+ }
+ }
+
+ // required?
+ if ($node->isRequired()) {
+ $comments[] = 'Required';
+ }
+
+ // example
+ if ($example && !is_array($example)) {
+ $comments[] = 'Example: '.$example;
+ }
+
+ $default = (string) $default != '' ? ' '.$default : '';
+ $comments = count($comments) ? '# '.implode(', ', $comments) : '';
+
+ $text = rtrim(sprintf('%-20s %s %s', $node->getName().':', $default, $comments), ' ');
+
+ if ($info = $node->getInfo()) {
+ $this->writeLine('');
+ // indenting multi-line info
+ $info = str_replace("\n", sprintf("\n%".($depth * 4)."s# ", ' '), $info);
+ $this->writeLine('# '.$info, $depth * 4);
+ }
+
+ $this->writeLine($text, $depth * 4);
+
+ // output defaults
+ if ($defaultArray) {
+ $this->writeLine('');
+
+ $message = count($defaultArray) > 1 ? 'Defaults' : 'Default';
+
+ $this->writeLine('# '.$message.':', $depth * 4 + 4);
+
+ $this->writeArray($defaultArray, $depth + 1);
+ }
+
+ if (is_array($example)) {
+ $this->writeLine('');
+
+ $message = count($example) > 1 ? 'Examples' : 'Example';
+
+ $this->writeLine('# '.$message.':', $depth * 4 + 4);
+
+ $this->writeArray($example, $depth + 1);
+ }
+
+ if ($children) {
+ foreach ($children as $childNode) {
+ $this->writeNode($childNode, $depth + 1);
+ }
+ }
+ }
+
+ /**
+ * Outputs a single config reference line
+ *
+ * @param string $text
+ * @param int $indent
+ */
+ private function writeLine($text, $indent = 0)
+ {
+ $indent = strlen($text) + $indent;
+ $format = '%'.$indent.'s';
+
+ $this->reference .= sprintf($format, $text)."\n";
+ }
+
+ private function writeArray(array $array, $depth)
+ {
+ $isIndexed = array_values($array) === $array;
+
+ foreach ($array as $key => $value) {
+ if (is_array($value)) {
+ $val = '';
+ } else {
+ $val = $value;
+ }
+
+ if ($isIndexed) {
+ $this->writeLine('- '.$val, $depth * 4);
+ } else {
+ $this->writeLine(sprintf('%-20s %s', $key.':', $val), $depth * 4);
+ }
+
+ if (is_array($value)) {
+ $this->writeArray($value, $depth + 1);
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/EnumNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/EnumNode.php
new file mode 100644
index 0000000..224871a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/EnumNode.php
@@ -0,0 +1,58 @@
+<?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\InvalidConfigurationException;
+
+/**
+ * Node which only allows a finite set of values.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class EnumNode extends ScalarNode
+{
+ private $values;
+
+ public function __construct($name, NodeInterface $parent = null, array $values = array())
+ {
+ $values = array_unique($values);
+ if (count($values) <= 1) {
+ throw new \InvalidArgumentException('$values must contain at least two distinct elements.');
+ }
+
+ parent::__construct($name, $parent);
+ $this->values = $values;
+ }
+
+ public function getValues()
+ {
+ return $this->values;
+ }
+
+ protected function finalizeValue($value)
+ {
+ $value = parent::finalizeValue($value);
+
+ if (!in_array($value, $this->values, true)) {
+ $ex = new InvalidConfigurationException(sprintf(
+ 'The value %s is not allowed for path "%s". Permissible values: %s',
+ json_encode($value),
+ $this->getPath(),
+ implode(', ', array_map('json_encode', $this->values))));
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ return $value;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php
new file mode 100644
index 0000000..48dd932
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php
@@ -0,0 +1,22 @@
+<?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\Exception;
+
+/**
+ * This exception is thrown whenever the key of an array is not unique. This can
+ * only be the case if the configuration is coming from an XML file.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class DuplicateKeyException extends InvalidConfigurationException
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/Exception.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/Exception.php
new file mode 100644
index 0000000..8933a49
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/Exception.php
@@ -0,0 +1,21 @@
+<?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\Exception;
+
+/**
+ * Base exception for all configuration exceptions.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class Exception extends \RuntimeException
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php
new file mode 100644
index 0000000..726c07f
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php
@@ -0,0 +1,22 @@
+<?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\Exception;
+
+/**
+ * This exception is thrown when a configuration path is overwritten from a
+ * subsequent configuration file, but the entry node specifically forbids this.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ForbiddenOverwriteException extends InvalidConfigurationException
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php
new file mode 100644
index 0000000..3dbc57b
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php
@@ -0,0 +1,49 @@
+<?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\Exception;
+
+/**
+ * A very general exception which can be thrown whenever non of the more specific
+ * exceptions is suitable.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class InvalidConfigurationException extends Exception
+{
+ private $path;
+ private $containsHints = false;
+
+ public function setPath($path)
+ {
+ $this->path = $path;
+ }
+
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Adds extra information that is suffixed to the original exception message.
+ *
+ * @param string $hint
+ */
+ public function addHint($hint)
+ {
+ if (!$this->containsHints) {
+ $this->message .= "\nHint: ".$hint;
+ $this->containsHints = true;
+ } else {
+ $this->message .= ', '.$hint;
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php
new file mode 100644
index 0000000..98310da
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php
@@ -0,0 +1,21 @@
+<?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\Exception;
+
+/**
+ * Thrown when an error is detected in a node Definition.
+ *
+ * @author Victor Berchet <victor.berchet@suumit.com>
+ */
+class InvalidDefinitionException extends Exception
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php
new file mode 100644
index 0000000..d7ca8c9
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php
@@ -0,0 +1,21 @@
+<?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\Exception;
+
+/**
+ * This exception is thrown if an invalid type is encountered.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class InvalidTypeException extends InvalidConfigurationException
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php
new file mode 100644
index 0000000..863181a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php
@@ -0,0 +1,22 @@
+<?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\Exception;
+
+/**
+ * This exception is usually not encountered by the end-user, but only used
+ * internally to signal the parent scope to unset a key.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class UnsetKeyException extends Exception
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/FloatNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/FloatNode.php
new file mode 100644
index 0000000..5e1af17
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/FloatNode.php
@@ -0,0 +1,43 @@
+<?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\InvalidTypeException;
+
+/**
+ * This node represents a float value in the config tree.
+ *
+ * @author Jeanmonod David <david.jeanmonod@gmail.com>
+ */
+class FloatNode extends NumericNode
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function validateType($value)
+ {
+ // Integers are also accepted, we just cast them
+ if (is_int($value)) {
+ $value = (float) $value;
+ }
+
+ if (!is_float($value)) {
+ $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected float, but got %s.', $this->getPath(), gettype($value)));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/IntegerNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/IntegerNode.php
new file mode 100644
index 0000000..ba23070
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/IntegerNode.php
@@ -0,0 +1,38 @@
+<?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\InvalidTypeException;
+
+/**
+ * This node represents an integer value in the config tree.
+ *
+ * @author Jeanmonod David <david.jeanmonod@gmail.com>
+ */
+class IntegerNode extends NumericNode
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function validateType($value)
+ {
+ if (!is_int($value)) {
+ $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected int, but got %s.', $this->getPath(), gettype($value)));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/NodeInterface.php b/vendor/symfony/config/Symfony/Component/Config/Definition/NodeInterface.php
new file mode 100644
index 0000000..b9bddc4
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/NodeInterface.php
@@ -0,0 +1,88 @@
+<?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;
+
+/**
+ * Common Interface among all nodes.
+ *
+ * In most cases, it is better to inherit from BaseNode instead of implementing
+ * this interface yourself.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface NodeInterface
+{
+ /**
+ * Returns the name of the node.
+ *
+ * @return string The name of the node
+ */
+ public function getName();
+
+ /**
+ * Returns the path of the node.
+ *
+ * @return string The node path
+ */
+ public function getPath();
+
+ /**
+ * Returns true when the node is required.
+ *
+ * @return bool If the node is required
+ */
+ public function isRequired();
+
+ /**
+ * Returns true when the node has a default value.
+ *
+ * @return bool If the node has a default value
+ */
+ public function hasDefaultValue();
+
+ /**
+ * Returns the default value of the node.
+ *
+ * @return mixed The default value
+ *
+ * @throws \RuntimeException if the node has no default value
+ */
+ public function getDefaultValue();
+
+ /**
+ * Normalizes the supplied value.
+ *
+ * @param mixed $value The value to normalize
+ *
+ * @return mixed The normalized value
+ */
+ public function normalize($value);
+
+ /**
+ * Merges two values together.
+ *
+ * @param mixed $leftSide
+ * @param mixed $rightSide
+ *
+ * @return mixed The merged values
+ */
+ public function merge($leftSide, $rightSide);
+
+ /**
+ * Finalizes a value.
+ *
+ * @param mixed $value The value to finalize
+ *
+ * @return mixed The finalized value
+ */
+ public function finalize($value);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/NumericNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/NumericNode.php
new file mode 100644
index 0000000..2304ad9
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/NumericNode.php
@@ -0,0 +1,55 @@
+<?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\InvalidConfigurationException;
+
+/**
+ * This node represents a numeric value in the config tree.
+ *
+ * @author David Jeanmonod <david.jeanmonod@gmail.com>
+ */
+class NumericNode extends ScalarNode
+{
+ protected $min;
+ protected $max;
+
+ public function __construct($name, NodeInterface $parent = null, $min = null, $max = null)
+ {
+ parent::__construct($name, $parent);
+ $this->min = $min;
+ $this->max = $max;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function finalizeValue($value)
+ {
+ $value = parent::finalizeValue($value);
+
+ $errorMsg = null;
+ if (isset($this->min) && $value < $this->min) {
+ $errorMsg = sprintf('The value %s is too small for path "%s". Should be greater than or equal to %s', $value, $this->getPath(), $this->min);
+ }
+ if (isset($this->max) && $value > $this->max) {
+ $errorMsg = sprintf('The value %s is too big for path "%s". Should be less than or equal to %s', $value, $this->getPath(), $this->max);
+ }
+ if (isset($errorMsg)) {
+ $ex = new InvalidConfigurationException($errorMsg);
+ $ex->setPath($this->getPath());
+ throw $ex;
+ }
+
+ return $value;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/Processor.php b/vendor/symfony/config/Symfony/Component/Config/Definition/Processor.php
new file mode 100644
index 0000000..025e693
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/Processor.php
@@ -0,0 +1,97 @@
+<?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;
+
+/**
+ * This class is the entry point for config normalization/merging/finalization.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class Processor
+{
+ /**
+ * Processes an array of configurations.
+ *
+ * @param NodeInterface $configTree The node tree describing the configuration
+ * @param array $configs An array of configuration items to process
+ *
+ * @return array The processed configuration
+ */
+ public function process(NodeInterface $configTree, array $configs)
+ {
+ $currentConfig = array();
+ foreach ($configs as $config) {
+ $config = $configTree->normalize($config);
+ $currentConfig = $configTree->merge($currentConfig, $config);
+ }
+
+ return $configTree->finalize($currentConfig);
+ }
+
+ /**
+ * Processes an array of configurations.
+ *
+ * @param ConfigurationInterface $configuration The configuration class
+ * @param array $configs An array of configuration items to process
+ *
+ * @return array The processed configuration
+ */
+ public function processConfiguration(ConfigurationInterface $configuration, array $configs)
+ {
+ return $this->process($configuration->getConfigTreeBuilder()->buildTree(), $configs);
+ }
+
+ /**
+ * Normalizes a configuration entry.
+ *
+ * This method returns a normalize configuration array for a given key
+ * to remove the differences due to the original format (YAML and XML mainly).
+ *
+ * Here is an example.
+ *
+ * The configuration in XML:
+ *
+ * <twig:extension>twig.extension.foo</twig:extension>
+ * <twig:extension>twig.extension.bar</twig:extension>
+ *
+ * And the same configuration in YAML:
+ *
+ * extensions: ['twig.extension.foo', 'twig.extension.bar']
+ *
+ * @param array $config A config array
+ * @param string $key The key to normalize
+ * @param string $plural The plural form of the key if it is irregular
+ *
+ * @return array
+ */
+ public static function normalizeConfig($config, $key, $plural = null)
+ {
+ if (null === $plural) {
+ $plural = $key.'s';
+ }
+
+ if (isset($config[$plural])) {
+ return $config[$plural];
+ }
+
+ if (isset($config[$key])) {
+ if (is_string($config[$key]) || !is_int(key($config[$key]))) {
+ // only one
+ return array($config[$key]);
+ }
+
+ return $config[$key];
+ }
+
+ return array();
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypeNodeInterface.php b/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypeNodeInterface.php
new file mode 100644
index 0000000..8bbb84d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypeNodeInterface.php
@@ -0,0 +1,27 @@
+<?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;
+
+/**
+ * This interface must be implemented by nodes which can be used as prototypes.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface PrototypeNodeInterface extends NodeInterface
+{
+ /**
+ * Sets the name of the node.
+ *
+ * @param string $name The name of the node
+ */
+ public function setName($name);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypedArrayNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypedArrayNode.php
new file mode 100644
index 0000000..0a03d36
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/PrototypedArrayNode.php
@@ -0,0 +1,331 @@
+<?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\InvalidConfigurationException;
+use Symfony\Component\Config\Definition\Exception\DuplicateKeyException;
+use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
+use Symfony\Component\Config\Definition\Exception\Exception;
+
+/**
+ * Represents a prototyped Array node in the config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class PrototypedArrayNode extends ArrayNode
+{
+ protected $prototype;
+ protected $keyAttribute;
+ protected $removeKeyAttribute = false;
+ protected $minNumberOfElements = 0;
+ protected $defaultValue = array();
+ protected $defaultChildren;
+
+ /**
+ * Sets the minimum number of elements that a prototype based node must
+ * contain. By default this is zero, meaning no elements.
+ *
+ * @param int $number
+ */
+ public function setMinNumberOfElements($number)
+ {
+ $this->minNumberOfElements = $number;
+ }
+
+ /**
+ * Sets the attribute which value is to be used as key.
+ *
+ * This is useful when you have an indexed array that should be an
+ * associative array. You can select an item from within the array
+ * to be the key of the particular item. For example, if "id" is the
+ * "key", then:
+ *
+ * array(
+ * array('id' => 'my_name', 'foo' => 'bar'),
+ * );
+ *
+ * becomes
+ *
+ * array(
+ * 'my_name' => array('foo' => 'bar'),
+ * );
+ *
+ * If you'd like "'id' => 'my_name'" to still be present in the resulting
+ * array, then you can set the second argument of this method to false.
+ *
+ * @param string $attribute The name of the attribute which value is to be used as a key
+ * @param bool $remove Whether or not to remove the key
+ */
+ public function setKeyAttribute($attribute, $remove = true)
+ {
+ $this->keyAttribute = $attribute;
+ $this->removeKeyAttribute = $remove;
+ }
+
+ /**
+ * Retrieves the name of the attribute which value should be used as key.
+ *
+ * @return string The name of the attribute
+ */
+ public function getKeyAttribute()
+ {
+ return $this->keyAttribute;
+ }
+
+ /**
+ * Sets the default value of this node.
+ *
+ * @param string $value
+ *
+ * @throws \InvalidArgumentException if the default value is not an array
+ */
+ public function setDefaultValue($value)
+ {
+ if (!is_array($value)) {
+ throw new \InvalidArgumentException($this->getPath().': the default value of an array node has to be an array.');
+ }
+
+ $this->defaultValue = $value;
+ }
+
+ /**
+ * Checks if the node has a default value.
+ *
+ * @return bool
+ */
+ public function hasDefaultValue()
+ {
+ return true;
+ }
+
+ /**
+ * Adds default children when none are set.
+ *
+ * @param int|string|array|null $children The number of children|The child name|The children names to be added
+ */
+ public function setAddChildrenIfNoneSet($children = array('defaults'))
+ {
+ if (null === $children) {
+ $this->defaultChildren = array('defaults');
+ } else {
+ $this->defaultChildren = is_int($children) && $children > 0 ? range(1, $children) : (array) $children;
+ }
+ }
+
+ /**
+ * Retrieves the default value.
+ *
+ * The default value could be either explicited or derived from the prototype
+ * default value.
+ *
+ * @return array The default value
+ */
+ public function getDefaultValue()
+ {
+ if (null !== $this->defaultChildren) {
+ $default = $this->prototype->hasDefaultValue() ? $this->prototype->getDefaultValue() : array();
+ $defaults = array();
+ foreach (array_values($this->defaultChildren) as $i => $name) {
+ $defaults[null === $this->keyAttribute ? $i : $name] = $default;
+ }
+
+ return $defaults;
+ }
+
+ return $this->defaultValue;
+ }
+
+ /**
+ * Sets the node prototype.
+ *
+ * @param PrototypeNodeInterface $node
+ */
+ public function setPrototype(PrototypeNodeInterface $node)
+ {
+ $this->prototype = $node;
+ }
+
+ /**
+ * Retrieves the prototype.
+ *
+ * @return PrototypeNodeInterface The prototype
+ */
+ public function getPrototype()
+ {
+ return $this->prototype;
+ }
+
+ /**
+ * Disable adding concrete children for prototyped nodes.
+ *
+ * @param NodeInterface $node The child node to add
+ *
+ * @throws Exception
+ */
+ public function addChild(NodeInterface $node)
+ {
+ throw new Exception('A prototyped array node can not have concrete children.');
+ }
+
+ /**
+ * Finalizes the value of this node.
+ *
+ * @param mixed $value
+ *
+ * @return mixed The finalized value
+ *
+ * @throws UnsetKeyException
+ * @throws InvalidConfigurationException if the node doesn't have enough children
+ */
+ protected function finalizeValue($value)
+ {
+ if (false === $value) {
+ $msg = sprintf('Unsetting key for path "%s", value: %s', $this->getPath(), json_encode($value));
+ throw new UnsetKeyException($msg);
+ }
+
+ foreach ($value as $k => $v) {
+ $this->prototype->setName($k);
+ try {
+ $value[$k] = $this->prototype->finalize($v);
+ } catch (UnsetKeyException $unset) {
+ unset($value[$k]);
+ }
+ }
+
+ if (count($value) < $this->minNumberOfElements) {
+ $msg = sprintf('The path "%s" should have at least %d element(s) defined.', $this->getPath(), $this->minNumberOfElements);
+ $ex = new InvalidConfigurationException($msg);
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ return $value;
+ }
+
+ /**
+ * Normalizes the value.
+ *
+ * @param mixed $value The value to normalize
+ *
+ * @return mixed The normalized value
+ *
+ * @throws InvalidConfigurationException
+ * @throws DuplicateKeyException
+ */
+ protected function normalizeValue($value)
+ {
+ if (false === $value) {
+ return $value;
+ }
+
+ $value = $this->remapXml($value);
+
+ $isAssoc = array_keys($value) !== range(0, count($value) - 1);
+ $normalized = array();
+ foreach ($value as $k => $v) {
+ if (null !== $this->keyAttribute && is_array($v)) {
+ if (!isset($v[$this->keyAttribute]) && is_int($k) && !$isAssoc) {
+ $msg = sprintf('The attribute "%s" must be set for path "%s".', $this->keyAttribute, $this->getPath());
+ $ex = new InvalidConfigurationException($msg);
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ } elseif (isset($v[$this->keyAttribute])) {
+ $k = $v[$this->keyAttribute];
+
+ // remove the key attribute when required
+ if ($this->removeKeyAttribute) {
+ unset($v[$this->keyAttribute]);
+ }
+
+ // if only "value" is left
+ if (1 == count($v) && isset($v['value'])) {
+ $v = $v['value'];
+ }
+ }
+
+ if (array_key_exists($k, $normalized)) {
+ $msg = sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath());
+ $ex = new DuplicateKeyException($msg);
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+
+ $this->prototype->setName($k);
+ if (null !== $this->keyAttribute || $isAssoc) {
+ $normalized[$k] = $this->prototype->normalize($v);
+ } else {
+ $normalized[] = $this->prototype->normalize($v);
+ }
+ }
+
+ return $normalized;
+ }
+
+ /**
+ * Merges values together.
+ *
+ * @param mixed $leftSide The left side to merge.
+ * @param mixed $rightSide The right side to merge.
+ *
+ * @return mixed The merged values
+ *
+ * @throws InvalidConfigurationException
+ * @throws \RuntimeException
+ */
+ protected function mergeValues($leftSide, $rightSide)
+ {
+ if (false === $rightSide) {
+ // if this is still false after the last config has been merged the
+ // finalization pass will take care of removing this key entirely
+ return false;
+ }
+
+ if (false === $leftSide || !$this->performDeepMerging) {
+ return $rightSide;
+ }
+
+ foreach ($rightSide as $k => $v) {
+ // prototype, and key is irrelevant, so simply append the element
+ if (null === $this->keyAttribute) {
+ $leftSide[] = $v;
+ continue;
+ }
+
+ // no conflict
+ if (!array_key_exists($k, $leftSide)) {
+ if (!$this->allowNewKeys) {
+ $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.',
+ $this->getPath()
+ ));
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ $leftSide[$k] = $v;
+ continue;
+ }
+
+ $this->prototype->setName($k);
+ $leftSide[$k] = $this->prototype->merge($leftSide[$k], $v);
+ }
+
+ return $leftSide;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/ReferenceDumper.php b/vendor/symfony/config/Symfony/Component/Config/Definition/ReferenceDumper.php
new file mode 100644
index 0000000..7fe336d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/ReferenceDumper.php
@@ -0,0 +1,21 @@
+<?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\Dumper\YamlReferenceDumper;
+
+/**
+ * @deprecated Deprecated since version 2.4, to be removed in 3.0. Use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper instead.
+ */
+class ReferenceDumper extends YamlReferenceDumper
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/ScalarNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/ScalarNode.php
new file mode 100644
index 0000000..854c265
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/ScalarNode.php
@@ -0,0 +1,49 @@
+<?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\InvalidTypeException;
+
+/**
+ * This node represents a scalar value in the config tree.
+ *
+ * The following values are considered scalars:
+ * * booleans
+ * * strings
+ * * null
+ * * integers
+ * * floats
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ScalarNode extends VariableNode
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function validateType($value)
+ {
+ if (!is_scalar($value) && null !== $value) {
+ $ex = new InvalidTypeException(sprintf(
+ 'Invalid type for path "%s". Expected scalar, but got %s.',
+ $this->getPath(),
+ gettype($value)
+ ));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Definition/VariableNode.php b/vendor/symfony/config/Symfony/Component/Config/Definition/VariableNode.php
new file mode 100644
index 0000000..2ab7a45
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Definition/VariableNode.php
@@ -0,0 +1,119 @@
+<?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\InvalidConfigurationException;
+
+/**
+ * This node represents a value of variable type in the config tree.
+ *
+ * This node is intended for values of arbitrary type.
+ * Any PHP type is accepted as a value.
+ *
+ * @author Jeremy Mikola <jmikola@gmail.com>
+ */
+class VariableNode extends BaseNode implements PrototypeNodeInterface
+{
+ protected $defaultValueSet = false;
+ protected $defaultValue;
+ protected $allowEmptyValue = true;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDefaultValue($value)
+ {
+ $this->defaultValueSet = true;
+ $this->defaultValue = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasDefaultValue()
+ {
+ return $this->defaultValueSet;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultValue()
+ {
+ $v = $this->defaultValue;
+
+ return $v instanceof \Closure ? $v() : $v;
+ }
+
+ /**
+ * Sets if this node is allowed to have an empty value.
+ *
+ * @param bool $boolean True if this entity will accept empty values.
+ */
+ public function setAllowEmptyValue($boolean)
+ {
+ $this->allowEmptyValue = (bool) $boolean;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function validateType($value)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function finalizeValue($value)
+ {
+ if (!$this->allowEmptyValue && empty($value)) {
+ $ex = new InvalidConfigurationException(sprintf(
+ 'The path "%s" cannot contain an empty value, but got %s.',
+ $this->getPath(),
+ json_encode($value)
+ ));
+ if ($hint = $this->getInfo()) {
+ $ex->addHint($hint);
+ }
+ $ex->setPath($this->getPath());
+
+ throw $ex;
+ }
+
+ return $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function normalizeValue($value)
+ {
+ return $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function mergeValues($leftSide, $rightSide)
+ {
+ return $rightSide;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php b/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php
new file mode 100644
index 0000000..6a3b01c
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php
@@ -0,0 +1,27 @@
+<?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\Exception;
+
+/**
+ * Exception class for when a circular reference is detected when importing resources.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FileLoaderImportCircularReferenceException extends FileLoaderLoadException
+{
+ public function __construct(array $resources, $code = null, $previous = null)
+ {
+ $message = sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]);
+
+ \Exception::__construct($message, $code, $previous);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderLoadException.php b/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderLoadException.php
new file mode 100644
index 0000000..ec825e3
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Exception/FileLoaderLoadException.php
@@ -0,0 +1,100 @@
+<?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\Exception;
+
+/**
+ * Exception class for when a resource cannot be loaded or imported.
+ *
+ * @author Ryan Weaver <ryan@thatsquality.com>
+ */
+class FileLoaderLoadException extends \Exception
+{
+ /**
+ * @param string $resource The resource that could not be imported
+ * @param string $sourceResource The original resource importing the new resource
+ * @param int $code The error code
+ * @param \Exception $previous A previous exception
+ */
+ public function __construct($resource, $sourceResource = null, $code = null, $previous = null)
+ {
+ $message = '';
+ if ($previous) {
+ // Include the previous exception, to help the user see what might be the underlying cause
+
+ // Trim the trailing period of the previous message. We only want 1 period remove so no rtrim...
+ if ('.' === substr($previous->getMessage(), -1)) {
+ $trimmedMessage = substr($previous->getMessage(), 0, -1);
+ $message .= sprintf('%s', $trimmedMessage).' in ';
+ } else {
+ $message .= sprintf('%s', $previous->getMessage()).' in ';
+ }
+ $message .= $resource.' ';
+
+ // show tweaked trace to complete the human readable sentence
+ if (null === $sourceResource) {
+ $message .= sprintf('(which is loaded in resource "%s")', $this->varToString($resource));
+ } else {
+ $message .= sprintf('(which is being imported from "%s")', $this->varToString($sourceResource));
+ }
+ $message .= '.';
+
+ // if there's no previous message, present it the default way
+ } elseif (null === $sourceResource) {
+ $message .= sprintf('Cannot load resource "%s".', $this->varToString($resource));
+ } else {
+ $message .= sprintf('Cannot import resource "%s" from "%s".', $this->varToString($resource), $this->varToString($sourceResource));
+ }
+
+ // Is the resource located inside a bundle?
+ if ('@' === $resource[0]) {
+ $parts = explode(DIRECTORY_SEPARATOR, $resource);
+ $bundle = substr($parts[0], 1);
+ $message .= ' '.sprintf('Make sure the "%s" bundle is correctly registered and loaded in the application kernel class.', $bundle);
+ }
+
+ parent::__construct($message, $code, $previous);
+ }
+
+ protected function varToString($var)
+ {
+ if (is_object($var)) {
+ return sprintf('Object(%s)', get_class($var));
+ }
+
+ if (is_array($var)) {
+ $a = array();
+ foreach ($var as $k => $v) {
+ $a[] = sprintf('%s => %s', $k, $this->varToString($v));
+ }
+
+ return sprintf('Array(%s)', implode(', ', $a));
+ }
+
+ if (is_resource($var)) {
+ return sprintf('Resource(%s)', get_resource_type($var));
+ }
+
+ if (null === $var) {
+ return 'null';
+ }
+
+ if (false === $var) {
+ return 'false';
+ }
+
+ if (true === $var) {
+ return 'true';
+ }
+
+ return (string) $var;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/FileLocator.php b/vendor/symfony/config/Symfony/Component/Config/FileLocator.php
new file mode 100644
index 0000000..71bb5ab
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/FileLocator.php
@@ -0,0 +1,95 @@
+<?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;
+
+/**
+ * FileLocator uses an array of pre-defined paths to find files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FileLocator implements FileLocatorInterface
+{
+ protected $paths;
+
+ /**
+ * Constructor.
+ *
+ * @param string|array $paths A path or an array of paths where to look for resources
+ */
+ public function __construct($paths = array())
+ {
+ $this->paths = (array) $paths;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function locate($name, $currentPath = null, $first = true)
+ {
+ if ('' == $name) {
+ throw new \InvalidArgumentException('An empty file name is not valid to be located.');
+ }
+
+ if ($this->isAbsolutePath($name)) {
+ if (!file_exists($name)) {
+ throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $name));
+ }
+
+ return $name;
+ }
+
+ $filepaths = array();
+ if (null !== $currentPath && file_exists($file = $currentPath.DIRECTORY_SEPARATOR.$name)) {
+ if (true === $first) {
+ return $file;
+ }
+ $filepaths[] = $file;
+ }
+
+ foreach ($this->paths as $path) {
+ if (file_exists($file = $path.DIRECTORY_SEPARATOR.$name)) {
+ if (true === $first) {
+ return $file;
+ }
+ $filepaths[] = $file;
+ }
+ }
+
+ if (!$filepaths) {
+ throw new \InvalidArgumentException(sprintf('The file "%s" does not exist (in: %s%s).', $name, null !== $currentPath ? $currentPath.', ' : '', implode(', ', $this->paths)));
+ }
+
+ return array_values(array_unique($filepaths));
+ }
+
+ /**
+ * Returns whether the file path is an absolute path.
+ *
+ * @param string $file A file path
+ *
+ * @return bool
+ */
+ private function isAbsolutePath($file)
+ {
+ if ($file[0] === '/' || $file[0] === '\\'
+ || (strlen($file) > 3 && ctype_alpha($file[0])
+ && $file[1] === ':'
+ && ($file[2] === '\\' || $file[2] === '/')
+ )
+ || null !== parse_url($file, PHP_URL_SCHEME)
+ ) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/FileLocatorInterface.php b/vendor/symfony/config/Symfony/Component/Config/FileLocatorInterface.php
new file mode 100644
index 0000000..6605798
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/FileLocatorInterface.php
@@ -0,0 +1,31 @@
+<?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;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface FileLocatorInterface
+{
+ /**
+ * Returns a full path for a given file name.
+ *
+ * @param string $name The file name to locate
+ * @param string|null $currentPath The current path
+ * @param bool $first Whether to return the first occurrence or an array of filenames
+ *
+ * @return string|array The full path to the file or an array of file paths
+ *
+ * @throws \InvalidArgumentException When file is not found
+ */
+ public function locate($name, $currentPath = null, $first = true);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/LICENSE b/vendor/symfony/config/Symfony/Component/Config/LICENSE
new file mode 100644
index 0000000..43028bc
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2015 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/symfony/config/Symfony/Component/Config/Loader/DelegatingLoader.php b/vendor/symfony/config/Symfony/Component/Config/Loader/DelegatingLoader.php
new file mode 100644
index 0000000..3097878
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/DelegatingLoader.php
@@ -0,0 +1,55 @@
+<?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\Loader;
+
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+
+/**
+ * DelegatingLoader delegates loading to other loaders using a loader resolver.
+ *
+ * This loader acts as an array of LoaderInterface objects - each having
+ * a chance to load a given resource (handled by the resolver)
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DelegatingLoader extends Loader
+{
+ /**
+ * Constructor.
+ *
+ * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance
+ */
+ public function __construct(LoaderResolverInterface $resolver)
+ {
+ $this->resolver = $resolver;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load($resource, $type = null)
+ {
+ if (false === $loader = $this->resolver->resolve($resource, $type)) {
+ throw new FileLoaderLoadException($resource);
+ }
+
+ return $loader->load($resource, $type);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports($resource, $type = null)
+ {
+ return false !== $this->resolver->resolve($resource, $type);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Loader/FileLoader.php b/vendor/symfony/config/Symfony/Component/Config/Loader/FileLoader.php
new file mode 100644
index 0000000..21e4c47
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/FileLoader.php
@@ -0,0 +1,124 @@
+<?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\Loader;
+
+use Symfony\Component\Config\FileLocatorInterface;
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException;
+
+/**
+ * FileLoader is the abstract class used by all built-in loaders that are file based.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class FileLoader extends Loader
+{
+ /**
+ * @var array
+ */
+ protected static $loading = array();
+
+ /**
+ * @var FileLocatorInterface
+ */
+ protected $locator;
+
+ private $currentDir;
+
+ /**
+ * Constructor.
+ *
+ * @param FileLocatorInterface $locator A FileLocatorInterface instance
+ */
+ public function __construct(FileLocatorInterface $locator)
+ {
+ $this->locator = $locator;
+ }
+
+ /**
+ * Sets the current directory.
+ *
+ * @param string $dir
+ */
+ public function setCurrentDir($dir)
+ {
+ $this->currentDir = $dir;
+ }
+
+ /**
+ * Returns the file locator used by this loader.
+ *
+ * @return FileLocatorInterface
+ */
+ public function getLocator()
+ {
+ return $this->locator;
+ }
+
+ /**
+ * Imports a resource.
+ *
+ * @param mixed $resource A Resource
+ * @param string|null $type The resource type or null if unknown
+ * @param bool $ignoreErrors Whether to ignore import errors or not
+ * @param string|null $sourceResource The original resource importing the new resource
+ *
+ * @return mixed
+ *
+ * @throws FileLoaderLoadException
+ * @throws FileLoaderImportCircularReferenceException
+ */
+ public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
+ {
+ try {
+ $loader = $this->resolve($resource, $type);
+
+ if ($loader instanceof FileLoader && null !== $this->currentDir) {
+ // we fallback to the current locator to keep BC
+ // as some some loaders do not call the parent __construct()
+ // @deprecated should be removed in 3.0
+ $locator = $loader->getLocator() ?: $this->locator;
+ $resource = $locator->locate($resource, $this->currentDir, false);
+ }
+
+ $resources = is_array($resource) ? $resource : array($resource);
+ for ($i = 0; $i < $resourcesCount = count($resources); $i++) {
+ if (isset(self::$loading[$resources[$i]])) {
+ if ($i == $resourcesCount - 1) {
+ throw new FileLoaderImportCircularReferenceException(array_keys(self::$loading));
+ }
+ } else {
+ $resource = $resources[$i];
+ break;
+ }
+ }
+ self::$loading[$resource] = true;
+
+ $ret = $loader->load($resource, $type);
+
+ unset(self::$loading[$resource]);
+
+ return $ret;
+ } catch (FileLoaderImportCircularReferenceException $e) {
+ throw $e;
+ } catch (\Exception $e) {
+ if (!$ignoreErrors) {
+ // prevent embedded imports from nesting multiple exceptions
+ if ($e instanceof FileLoaderLoadException) {
+ throw $e;
+ }
+
+ throw new FileLoaderLoadException($resource, $sourceResource, null, $e);
+ }
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Loader/Loader.php b/vendor/symfony/config/Symfony/Component/Config/Loader/Loader.php
new file mode 100644
index 0000000..de4e127
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/Loader.php
@@ -0,0 +1,78 @@
+<?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\Loader;
+
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+
+/**
+ * Loader is the abstract class used by all built-in loaders.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class Loader implements LoaderInterface
+{
+ protected $resolver;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getResolver()
+ {
+ return $this->resolver;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setResolver(LoaderResolverInterface $resolver)
+ {
+ $this->resolver = $resolver;
+ }
+
+ /**
+ * Imports a resource.
+ *
+ * @param mixed $resource A resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @return mixed
+ */
+ public function import($resource, $type = null)
+ {
+ return $this->resolve($resource, $type)->load($resource, $type);
+ }
+
+ /**
+ * Finds a loader able to load an imported resource.
+ *
+ * @param mixed $resource A resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @return LoaderInterface A LoaderInterface instance
+ *
+ * @throws FileLoaderLoadException If no loader is found
+ */
+ public function resolve($resource, $type = null)
+ {
+ if ($this->supports($resource, $type)) {
+ return $this;
+ }
+
+ $loader = null === $this->resolver ? false : $this->resolver->resolve($resource, $type);
+
+ if (false === $loader) {
+ throw new FileLoaderLoadException($resource);
+ }
+
+ return $loader;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderInterface.php b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderInterface.php
new file mode 100644
index 0000000..dd0a85a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderInterface.php
@@ -0,0 +1,54 @@
+<?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\Loader;
+
+/**
+ * LoaderInterface is the interface implemented by all loader classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface LoaderInterface
+{
+ /**
+ * Loads a resource.
+ *
+ * @param mixed $resource The resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @throws \Exception If something went wrong
+ */
+ public function load($resource, $type = null);
+
+ /**
+ * Returns whether this class supports the given resource.
+ *
+ * @param mixed $resource A resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @return bool True if this class supports the given resource, false otherwise
+ */
+ public function supports($resource, $type = null);
+
+ /**
+ * Gets the loader resolver.
+ *
+ * @return LoaderResolverInterface A LoaderResolverInterface instance
+ */
+ public function getResolver();
+
+ /**
+ * Sets the loader resolver.
+ *
+ * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance
+ */
+ public function setResolver(LoaderResolverInterface $resolver);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolver.php b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolver.php
new file mode 100644
index 0000000..dc6846d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolver.php
@@ -0,0 +1,75 @@
+<?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\Loader;
+
+/**
+ * LoaderResolver selects a loader for a given resource.
+ *
+ * A resource can be anything (e.g. a full path to a config file or a Closure).
+ * Each loader determines whether it can load a resource and how.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class LoaderResolver implements LoaderResolverInterface
+{
+ /**
+ * @var LoaderInterface[] An array of LoaderInterface objects
+ */
+ private $loaders = array();
+
+ /**
+ * Constructor.
+ *
+ * @param LoaderInterface[] $loaders An array of loaders
+ */
+ public function __construct(array $loaders = array())
+ {
+ foreach ($loaders as $loader) {
+ $this->addLoader($loader);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function resolve($resource, $type = null)
+ {
+ foreach ($this->loaders as $loader) {
+ if ($loader->supports($resource, $type)) {
+ return $loader;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Adds a loader.
+ *
+ * @param LoaderInterface $loader A LoaderInterface instance
+ */
+ public function addLoader(LoaderInterface $loader)
+ {
+ $this->loaders[] = $loader;
+ $loader->setResolver($this);
+ }
+
+ /**
+ * Returns the registered loaders.
+ *
+ * @return LoaderInterface[] An array of LoaderInterface instances
+ */
+ public function getLoaders()
+ {
+ return $this->loaders;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolverInterface.php b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolverInterface.php
new file mode 100644
index 0000000..40f1a1a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Loader/LoaderResolverInterface.php
@@ -0,0 +1,30 @@
+<?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\Loader;
+
+/**
+ * LoaderResolverInterface selects a loader for a given resource.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface LoaderResolverInterface
+{
+ /**
+ * Returns a loader able to load the resource.
+ *
+ * @param mixed $resource A resource
+ * @param string|null $type The resource type or null if unknown
+ *
+ * @return LoaderInterface|false The loader or false if none is able to load the resource
+ */
+ public function resolve($resource, $type = null);
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/README.md b/vendor/symfony/config/Symfony/Component/Config/README.md
new file mode 100644
index 0000000..690d7d7
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/README.md
@@ -0,0 +1,17 @@
+Config Component
+================
+
+Config provides the infrastructure for loading configurations from different
+data sources and optionally monitoring these data sources for changes. There
+are additional tools for validating, normalizing and handling of defaults that
+can optionally be used to convert from different formats to arrays.
+
+Resources
+---------
+
+You can run the unit tests with the following command:
+
+ $ cd path/to/Symfony/Component/Config/
+ $ composer install
+ $ phpunit
+
diff --git a/vendor/symfony/config/Symfony/Component/Config/Resource/DirectoryResource.php b/vendor/symfony/config/Symfony/Component/Config/Resource/DirectoryResource.php
new file mode 100644
index 0000000..515fb5c
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Resource/DirectoryResource.php
@@ -0,0 +1,99 @@
+<?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\Resource;
+
+/**
+ * DirectoryResource represents a resources stored in a subdirectory tree.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DirectoryResource implements ResourceInterface, \Serializable
+{
+ private $resource;
+ private $pattern;
+
+ /**
+ * Constructor.
+ *
+ * @param string $resource The file path to the resource
+ * @param string|null $pattern A pattern to restrict monitored files
+ */
+ public function __construct($resource, $pattern = null)
+ {
+ $this->resource = $resource;
+ $this->pattern = $pattern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __toString()
+ {
+ return (string) $this->resource;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getResource()
+ {
+ return $this->resource;
+ }
+
+ /**
+ * Returns the pattern to restrict monitored files.
+ *
+ * @return string|null
+ */
+ public function getPattern()
+ {
+ return $this->pattern;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isFresh($timestamp)
+ {
+ if (!is_dir($this->resource)) {
+ return false;
+ }
+
+ $newestMTime = filemtime($this->resource);
+ foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) {
+ // if regex filtering is enabled only check matching files
+ if ($this->pattern && $file->isFile() && !preg_match($this->pattern, $file->getBasename())) {
+ continue;
+ }
+
+ // always monitor directories for changes, except the .. entries
+ // (otherwise deleted files wouldn't get detected)
+ if ($file->isDir() && '/..' === substr($file, -3)) {
+ continue;
+ }
+
+ $newestMTime = max($file->getMTime(), $newestMTime);
+ }
+
+ return $newestMTime < $timestamp;
+ }
+
+ public function serialize()
+ {
+ return serialize(array($this->resource, $this->pattern));
+ }
+
+ public function unserialize($serialized)
+ {
+ list($this->resource, $this->pattern) = unserialize($serialized);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Resource/FileResource.php b/vendor/symfony/config/Symfony/Component/Config/Resource/FileResource.php
new file mode 100644
index 0000000..4c00ae4
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Resource/FileResource.php
@@ -0,0 +1,75 @@
+<?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\Resource;
+
+/**
+ * FileResource represents a resource stored on the filesystem.
+ *
+ * The resource can be a file or a directory.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FileResource implements ResourceInterface, \Serializable
+{
+ /**
+ * @var string|false
+ */
+ private $resource;
+
+ /**
+ * Constructor.
+ *
+ * @param string $resource The file path to the resource
+ */
+ public function __construct($resource)
+ {
+ $this->resource = realpath($resource);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __toString()
+ {
+ return (string) $this->resource;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getResource()
+ {
+ return $this->resource;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isFresh($timestamp)
+ {
+ if (false === $this->resource || !file_exists($this->resource)) {
+ return false;
+ }
+
+ return filemtime($this->resource) <= $timestamp;
+ }
+
+ public function serialize()
+ {
+ return serialize($this->resource);
+ }
+
+ public function unserialize($serialized)
+ {
+ $this->resource = unserialize($serialized);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Resource/ResourceInterface.php b/vendor/symfony/config/Symfony/Component/Config/Resource/ResourceInterface.php
new file mode 100644
index 0000000..db03d12
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Resource/ResourceInterface.php
@@ -0,0 +1,43 @@
+<?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\Resource;
+
+/**
+ * ResourceInterface is the interface that must be implemented by all Resource classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface ResourceInterface
+{
+ /**
+ * Returns a string representation of the Resource.
+ *
+ * @return string A string representation of the Resource
+ */
+ public function __toString();
+
+ /**
+ * Returns true if the resource has not been updated since the given timestamp.
+ *
+ * @param int $timestamp The last time the resource was loaded
+ *
+ * @return bool True if the resource has not been updated, false otherwise
+ */
+ public function isFresh($timestamp);
+
+ /**
+ * Returns the tied resource.
+ *
+ * @return mixed The resource
+ */
+ public function getResource();
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/ConfigCacheTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/ConfigCacheTest.php
new file mode 100644
index 0000000..8271885
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/ConfigCacheTest.php
@@ -0,0 +1,138 @@
+<?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\Tests;
+
+use Symfony\Component\Config\ConfigCache;
+use Symfony\Component\Config\Resource\FileResource;
+
+class ConfigCacheTest extends \PHPUnit_Framework_TestCase
+{
+ private $resourceFile = null;
+
+ private $cacheFile = null;
+
+ private $metaFile = null;
+
+ protected function setUp()
+ {
+ $this->resourceFile = tempnam(sys_get_temp_dir(), '_resource');
+ $this->cacheFile = tempnam(sys_get_temp_dir(), 'config_');
+ $this->metaFile = $this->cacheFile.'.meta';
+
+ $this->makeCacheFresh();
+ $this->generateMetaFile();
+ }
+
+ protected function tearDown()
+ {
+ $files = array($this->cacheFile, $this->metaFile, $this->resourceFile);
+
+ foreach ($files as $file) {
+ if (file_exists($file)) {
+ unlink($file);
+ }
+ }
+ }
+
+ public function testToString()
+ {
+ $cache = new ConfigCache($this->cacheFile, true);
+
+ $this->assertSame($this->cacheFile, (string) $cache);
+ }
+
+ public function testCacheIsNotFreshIfFileDoesNotExist()
+ {
+ unlink($this->cacheFile);
+
+ $cache = new ConfigCache($this->cacheFile, false);
+
+ $this->assertFalse($cache->isFresh());
+ }
+
+ public function testCacheIsAlwaysFreshIfFileExistsWithDebugDisabled()
+ {
+ $this->makeCacheStale();
+
+ $cache = new ConfigCache($this->cacheFile, false);
+
+ $this->assertTrue($cache->isFresh());
+ }
+
+ public function testCacheIsNotFreshWithoutMetaFile()
+ {
+ unlink($this->metaFile);
+
+ $cache = new ConfigCache($this->cacheFile, true);
+
+ $this->assertFalse($cache->isFresh());
+ }
+
+ public function testCacheIsFreshIfResourceIsFresh()
+ {
+ $cache = new ConfigCache($this->cacheFile, true);
+
+ $this->assertTrue($cache->isFresh());
+ }
+
+ public function testCacheIsNotFreshIfOneOfTheResourcesIsNotFresh()
+ {
+ $this->makeCacheStale();
+
+ $cache = new ConfigCache($this->cacheFile, true);
+
+ $this->assertFalse($cache->isFresh());
+ }
+
+ public function testWriteDumpsFile()
+ {
+ unlink($this->cacheFile);
+ unlink($this->metaFile);
+
+ $cache = new ConfigCache($this->cacheFile, false);
+ $cache->write('FOOBAR');
+
+ $this->assertFileExists($this->cacheFile, 'Cache file is created');
+ $this->assertSame('FOOBAR', file_get_contents($this->cacheFile));
+ $this->assertFileNotExists($this->metaFile, 'Meta file is not created');
+ }
+
+ public function testWriteDumpsMetaFileWithDebugEnabled()
+ {
+ unlink($this->cacheFile);
+ unlink($this->metaFile);
+
+ $metadata = array(new FileResource($this->resourceFile));
+
+ $cache = new ConfigCache($this->cacheFile, true);
+ $cache->write('FOOBAR', $metadata);
+
+ $this->assertFileExists($this->cacheFile, 'Cache file is created');
+ $this->assertFileExists($this->metaFile, 'Meta file is created');
+ $this->assertSame(serialize($metadata), file_get_contents($this->metaFile));
+ }
+
+ private function makeCacheFresh()
+ {
+ touch($this->resourceFile, filemtime($this->cacheFile) - 3600);
+ }
+
+ private function makeCacheStale()
+ {
+ touch($this->cacheFile, filemtime($this->resourceFile) - 3600);
+ }
+
+ private function generateMetaFile()
+ {
+ file_put_contents($this->metaFile, serialize(array(new FileResource($this->resourceFile))));
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php
new file mode 100644
index 0000000..291c2fd
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php
@@ -0,0 +1,160 @@
+<?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\Tests\Definition;
+
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\ScalarNode;
+
+class ArrayNodeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
+ */
+ public function testNormalizeThrowsExceptionWhenFalseIsNotAllowed()
+ {
+ $node = new ArrayNode('root');
+ $node->normalize(false);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage Unrecognized option "foo" under "root"
+ */
+ public function testExceptionThrownOnUnrecognizedChild()
+ {
+ $node = new ArrayNode('root');
+ $node->normalize(array('foo' => 'bar'));
+ }
+
+ /**
+ * Tests that no exception is thrown for an unrecognized child if the
+ * ignoreExtraKeys option is set to true.
+ *
+ * Related to testExceptionThrownOnUnrecognizedChild
+ */
+ public function testIgnoreExtraKeysNoException()
+ {
+ $node = new ArrayNode('roo');
+ $node->setIgnoreExtraKeys(true);
+
+ $node->normalize(array('foo' => 'bar'));
+ $this->assertTrue(true, 'No exception was thrown when setIgnoreExtraKeys is true');
+ }
+
+ /**
+ * @dataProvider getPreNormalizationTests
+ */
+ public function testPreNormalize($denormalized, $normalized)
+ {
+ $node = new ArrayNode('foo');
+
+ $r = new \ReflectionMethod($node, 'preNormalize');
+ $r->setAccessible(true);
+
+ $this->assertSame($normalized, $r->invoke($node, $denormalized));
+ }
+
+ public function getPreNormalizationTests()
+ {
+ return array(
+ array(
+ array('foo-bar' => 'foo'),
+ array('foo_bar' => 'foo'),
+ ),
+ array(
+ array('foo-bar_moo' => 'foo'),
+ array('foo-bar_moo' => 'foo'),
+ ),
+ array(
+ array('foo-bar' => null, 'foo_bar' => 'foo'),
+ array('foo-bar' => null, 'foo_bar' => 'foo'),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider getZeroNamedNodeExamplesData
+ */
+ public function testNodeNameCanBeZero($denormalized, $normalized)
+ {
+ $zeroNode = new ArrayNode(0);
+ $zeroNode->addChild(new ScalarNode('name'));
+ $fiveNode = new ArrayNode(5);
+ $fiveNode->addChild(new ScalarNode(0));
+ $fiveNode->addChild(new ScalarNode('new_key'));
+ $rootNode = new ArrayNode('root');
+ $rootNode->addChild($zeroNode);
+ $rootNode->addChild($fiveNode);
+ $rootNode->addChild(new ScalarNode('string_key'));
+ $r = new \ReflectionMethod($rootNode, 'normalizeValue');
+ $r->setAccessible(true);
+
+ $this->assertSame($normalized, $r->invoke($rootNode, $denormalized));
+ }
+
+ public function getZeroNamedNodeExamplesData()
+ {
+ return array(
+ array(
+ array(
+ 0 => array(
+ 'name' => 'something',
+ ),
+ 5 => array(
+ 0 => 'this won\'t work too',
+ 'new_key' => 'some other value',
+ ),
+ 'string_key' => 'just value',
+ ),
+ array(
+ 0 => array(
+ 'name' => 'something',
+ ),
+ 5 => array(
+ 0 => 'this won\'t work too',
+ 'new_key' => 'some other value',
+ ),
+ 'string_key' => 'just value',
+ ),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider getPreNormalizedNormalizedOrderedData
+ */
+ public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $normalized)
+ {
+ $scalar1 = new ScalarNode('1');
+ $scalar2 = new ScalarNode('2');
+ $scalar3 = new ScalarNode('3');
+ $node = new ArrayNode('foo');
+ $node->addChild($scalar1);
+ $node->addChild($scalar3);
+ $node->addChild($scalar2);
+
+ $r = new \ReflectionMethod($node, 'normalizeValue');
+ $r->setAccessible(true);
+
+ $this->assertSame($normalized, $r->invoke($node, $prenormalized));
+ }
+
+ public function getPreNormalizedNormalizedOrderedData()
+ {
+ return array(
+ array(
+ array('2' => 'two', '1' => 'one', '3' => 'three'),
+ array('2' => 'two', '1' => 'one', '3' => 'three'),
+ ),
+ );
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php
new file mode 100644
index 0000000..0753d64
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php
@@ -0,0 +1,60 @@
+<?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\Tests\Definition;
+
+use Symfony\Component\Config\Definition\BooleanNode;
+
+class BooleanNodeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testNormalize($value)
+ {
+ $node = new BooleanNode('test');
+ $this->assertSame($value, $node->normalize($value));
+ }
+
+ public function getValidValues()
+ {
+ return array(
+ array(false),
+ array(true),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
+ */
+ public function testNormalizeThrowsExceptionOnInvalidValues($value)
+ {
+ $node = new BooleanNode('test');
+ $node->normalize($value);
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array(null),
+ array(''),
+ array('foo'),
+ array(0),
+ array(1),
+ array(0.0),
+ array(0.1),
+ array(array()),
+ array(array('foo' => 'bar')),
+ array(new \stdClass()),
+ );
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php
new file mode 100644
index 0000000..e75ed34
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php
@@ -0,0 +1,207 @@
+<?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\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\Config\Definition\Processor;
+use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
+use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
+
+class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
+{
+ public function testAppendingSomeNode()
+ {
+ $parent = new ArrayNodeDefinition('root');
+ $child = new ScalarNodeDefinition('child');
+
+ $parent
+ ->children()
+ ->scalarNode('foo')->end()
+ ->scalarNode('bar')->end()
+ ->end()
+ ->append($child);
+
+ $this->assertCount(3, $this->getField($parent, 'children'));
+ $this->assertTrue(in_array($child, $this->getField($parent, 'children')));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
+ * @dataProvider providePrototypeNodeSpecificCalls
+ */
+ public function testPrototypeNodeSpecificOption($method, $args)
+ {
+ $node = new ArrayNodeDefinition('root');
+
+ call_user_func_array(array($node, $method), $args);
+
+ $node->getNode();
+ }
+
+ public function providePrototypeNodeSpecificCalls()
+ {
+ return array(
+ array('defaultValue', array(array())),
+ array('addDefaultChildrenIfNoneSet', array()),
+ array('requiresAtLeastOneElement', array()),
+ array('useAttributeAsKey', array('foo')),
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
+ */
+ public function testConcreteNodeSpecificOption()
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->addDefaultsIfNotSet()
+ ->prototype('array')
+ ;
+ $node->getNode();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
+ */
+ public function testPrototypeNodesCantHaveADefaultValueWhenUsingDefaultChildren()
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->defaultValue(array())
+ ->addDefaultChildrenIfNoneSet('foo')
+ ->prototype('array')
+ ;
+ $node->getNode();
+ }
+
+ public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren()
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->addDefaultChildrenIfNoneSet()
+ ->prototype('array')
+ ;
+ $tree = $node->getNode();
+ $this->assertEquals(array(array()), $tree->getDefaultValue());
+ }
+
+ /**
+ * @dataProvider providePrototypedArrayNodeDefaults
+ */
+ public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrAsKey, $shouldThrowWhenNotUsingAttrAsKey, $defaults)
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->addDefaultChildrenIfNoneSet($args)
+ ->prototype('array')
+ ;
+
+ try {
+ $tree = $node->getNode();
+ $this->assertFalse($shouldThrowWhenNotUsingAttrAsKey);
+ $this->assertEquals($defaults, $tree->getDefaultValue());
+ } catch (InvalidDefinitionException $e) {
+ $this->assertTrue($shouldThrowWhenNotUsingAttrAsKey);
+ }
+
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->useAttributeAsKey('attr')
+ ->addDefaultChildrenIfNoneSet($args)
+ ->prototype('array')
+ ;
+
+ try {
+ $tree = $node->getNode();
+ $this->assertFalse($shouldThrowWhenUsingAttrAsKey);
+ $this->assertEquals($defaults, $tree->getDefaultValue());
+ } catch (InvalidDefinitionException $e) {
+ $this->assertTrue($shouldThrowWhenUsingAttrAsKey);
+ }
+ }
+
+ public function providePrototypedArrayNodeDefaults()
+ {
+ return array(
+ array(null, true, false, array(array())),
+ array(2, true, false, array(array(), array())),
+ array('2', false, true, array('2' => array())),
+ array('foo', false, true, array('foo' => array())),
+ array(array('foo'), false, true, array('foo' => array())),
+ array(array('foo', 'bar'), false, true, array('foo' => array(), 'bar' => array())),
+ );
+ }
+
+ public function testNestedPrototypedArrayNodes()
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->addDefaultChildrenIfNoneSet()
+ ->prototype('array')
+ ->prototype('array')
+ ;
+ $node->getNode();
+ }
+
+ public function testEnabledNodeDefaults()
+ {
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->canBeEnabled()
+ ->children()
+ ->scalarNode('foo')->defaultValue('bar')->end()
+ ;
+
+ $this->assertEquals(array('enabled' => false, 'foo' => 'bar'), $node->getNode()->getDefaultValue());
+ }
+
+ /**
+ * @dataProvider getEnableableNodeFixtures
+ */
+ public function testTrueEnableEnabledNode($expected, $config, $message)
+ {
+ $processor = new Processor();
+ $node = new ArrayNodeDefinition('root');
+ $node
+ ->canBeEnabled()
+ ->children()
+ ->scalarNode('foo')->defaultValue('bar')->end()
+ ;
+
+ $this->assertEquals(
+ $expected,
+ $processor->process($node->getNode(), $config),
+ $message
+ );
+ }
+
+ public function getEnableableNodeFixtures()
+ {
+ return array(
+ array(array('enabled' => true, 'foo' => 'bar'), array(true), 'true enables an enableable node'),
+ array(array('enabled' => true, 'foo' => 'bar'), array(null), 'null enables an enableable node'),
+ array(array('enabled' => true, 'foo' => 'bar'), array(array('enabled' => true)), 'An enableable node can be enabled'),
+ array(array('enabled' => true, 'foo' => 'baz'), array(array('foo' => 'baz')), 'any configuration enables an enableable node'),
+ array(array('enabled' => false, 'foo' => 'baz'), array(array('foo' => 'baz', 'enabled' => false)), 'An enableable node can be disabled'),
+ array(array('enabled' => false, 'foo' => 'bar'), array(false), 'false disables an enableable node'),
+ );
+ }
+
+ protected function getField($object, $field)
+ {
+ $reflection = new \ReflectionProperty($object, $field);
+ $reflection->setAccessible(true);
+
+ return $reflection->getValue($object);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php
new file mode 100644
index 0000000..69f7fcf
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/EnumNodeDefinitionTest.php
@@ -0,0 +1,46 @@
+<?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\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\EnumNodeDefinition;
+
+class EnumNodeDefinitionTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage ->values() must be called with at least two distinct values.
+ */
+ public function testNoDistinctValues()
+ {
+ $def = new EnumNodeDefinition('foo');
+ $def->values(array('foo', 'foo'));
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ * @expectedExceptionMessage You must call ->values() on enum nodes.
+ */
+ public function testNoValuesPassed()
+ {
+ $def = new EnumNodeDefinition('foo');
+ $def->getNode();
+ }
+
+ public function testGetNode()
+ {
+ $def = new EnumNodeDefinition('foo');
+ $def->values(array('foo', 'bar'));
+
+ $node = $def->getNode();
+ $this->assertEquals(array('foo', 'bar'), $node->getValues());
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php
new file mode 100644
index 0000000..147bf13
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/ExprBuilderTest.php
@@ -0,0 +1,215 @@
+<?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\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+
+class ExprBuilderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testAlwaysExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->always($this->returnClosure('new_value'))
+ ->end();
+
+ $this->assertFinalizedValueIs('new_value', $test);
+ }
+
+ public function testIfTrueExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifTrue()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test, array('key' => true));
+
+ $test = $this->getTestBuilder()
+ ->ifTrue(function ($v) { return true; })
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test);
+
+ $test = $this->getTestBuilder()
+ ->ifTrue(function ($v) { return false; })
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('value', $test);
+ }
+
+ public function testIfStringExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifString()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test);
+
+ $test = $this->getTestBuilder()
+ ->ifString()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs(45, $test, array('key' => 45));
+ }
+
+ public function testIfNullExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifNull()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test, array('key' => null));
+
+ $test = $this->getTestBuilder()
+ ->ifNull()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('value', $test);
+ }
+
+ public function testIfArrayExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifArray()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test, array('key' => array()));
+
+ $test = $this->getTestBuilder()
+ ->ifArray()
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('value', $test);
+ }
+
+ public function testIfInArrayExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifInArray(array('foo', 'bar', 'value'))
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test);
+
+ $test = $this->getTestBuilder()
+ ->ifInArray(array('foo', 'bar'))
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('value', $test);
+ }
+
+ public function testIfNotInArrayExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifNotInArray(array('foo', 'bar'))
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test);
+
+ $test = $this->getTestBuilder()
+ ->ifNotInArray(array('foo', 'bar', 'value_from_config'))
+ ->then($this->returnClosure('new_value'))
+ ->end();
+ $this->assertFinalizedValueIs('new_value', $test);
+ }
+
+ public function testThenEmptyArrayExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifString()
+ ->thenEmptyArray()
+ ->end();
+ $this->assertFinalizedValueIs(array(), $test);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ */
+ public function testThenInvalid()
+ {
+ $test = $this->getTestBuilder()
+ ->ifString()
+ ->thenInvalid('Invalid value')
+ ->end();
+ $this->finalizeTestBuilder($test);
+ }
+
+ public function testThenUnsetExpression()
+ {
+ $test = $this->getTestBuilder()
+ ->ifString()
+ ->thenUnset()
+ ->end();
+ $this->assertEquals(array(), $this->finalizeTestBuilder($test));
+ }
+
+ /**
+ * Create a test treebuilder with a variable node, and init the validation.
+ *
+ * @return TreeBuilder
+ */
+ protected function getTestBuilder()
+ {
+ $builder = new TreeBuilder();
+
+ return $builder
+ ->root('test')
+ ->children()
+ ->variableNode('key')
+ ->validate()
+ ;
+ }
+
+ /**
+ * Close the validation process and finalize with the given config.
+ *
+ * @param TreeBuilder $testBuilder The tree builder to finalize
+ * @param array $config The config you want to use for the finalization, if nothing provided
+ * a simple array('key'=>'value') will be used
+ *
+ * @return array The finalized config values
+ */
+ protected function finalizeTestBuilder($testBuilder, $config = null)
+ {
+ return $testBuilder
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ->finalize(null === $config ? array('key' => 'value') : $config)
+ ;
+ }
+
+ /**
+ * Return a closure that will return the given value.
+ *
+ * @param mixed $val The value that the closure must return
+ *
+ * @return \Closure
+ */
+ protected function returnClosure($val)
+ {
+ return function ($v) use ($val) {
+ return $val;
+ };
+ }
+
+ /**
+ * Assert that the given test builder, will return the given value.
+ *
+ * @param mixed $value The value to test
+ * @param TreeBuilder $treeBuilder The tree builder to finalize
+ * @param mixed $config The config values that new to be finalized
+ */
+ protected function assertFinalizedValueIs($value, $treeBuilder, $config = null)
+ {
+ $this->assertEquals(array('key' => $value), $this->finalizeTestBuilder($treeBuilder, $config));
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php
new file mode 100644
index 0000000..22c399c
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php
@@ -0,0 +1,94 @@
+<?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\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder;
+use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition;
+
+class NodeBuilderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testThrowsAnExceptionWhenTryingToCreateANonRegisteredNodeType()
+ {
+ $builder = new BaseNodeBuilder();
+ $builder->node('', 'foobar');
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testThrowsAnExceptionWhenTheNodeClassIsNotFound()
+ {
+ $builder = new BaseNodeBuilder();
+ $builder
+ ->setNodeClass('noclasstype', '\\foo\\bar\\noclass')
+ ->node('', 'noclasstype');
+ }
+
+ public function testAddingANewNodeType()
+ {
+ $class = __NAMESPACE__.'\\SomeNodeDefinition';
+
+ $builder = new BaseNodeBuilder();
+ $node = $builder
+ ->setNodeClass('newtype', $class)
+ ->node('', 'newtype');
+
+ $this->assertInstanceOf($class, $node);
+ }
+
+ public function testOverridingAnExistingNodeType()
+ {
+ $class = __NAMESPACE__.'\\SomeNodeDefinition';
+
+ $builder = new BaseNodeBuilder();
+ $node = $builder
+ ->setNodeClass('variable', $class)
+ ->node('', 'variable');
+
+ $this->assertInstanceOf($class, $node);
+ }
+
+ public function testNodeTypesAreNotCaseSensitive()
+ {
+ $builder = new BaseNodeBuilder();
+
+ $node1 = $builder->node('', 'VaRiAbLe');
+ $node2 = $builder->node('', 'variable');
+
+ $this->assertInstanceOf(get_class($node1), $node2);
+
+ $builder->setNodeClass('CuStOm', __NAMESPACE__.'\\SomeNodeDefinition');
+
+ $node1 = $builder->node('', 'CUSTOM');
+ $node2 = $builder->node('', 'custom');
+
+ $this->assertInstanceOf(get_class($node1), $node2);
+ }
+
+ public function testNumericNodeCreation()
+ {
+ $builder = new BaseNodeBuilder();
+
+ $node = $builder->integerNode('foo')->min(3)->max(5);
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition', $node);
+
+ $node = $builder->floatNode('bar')->min(3.0)->max(5.0);
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\FloatNodeDefinition', $node);
+ }
+}
+
+class SomeNodeDefinition extends BaseVariableNodeDefinition
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php
new file mode 100644
index 0000000..cf0813a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/NumericNodeDefinitionTest.php
@@ -0,0 +1,93 @@
+<?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\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition as NumericNodeDefinition;
+use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition;
+use Symfony\Component\Config\Definition\Builder\FloatNodeDefinition;
+
+class NumericNodeDefinitionTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage You cannot define a min(4) as you already have a max(3)
+ */
+ public function testIncoherentMinAssertion()
+ {
+ $def = new NumericNodeDefinition('foo');
+ $def->max(3)->min(4);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage You cannot define a max(2) as you already have a min(3)
+ */
+ public function testIncoherentMaxAssertion()
+ {
+ $node = new NumericNodeDefinition('foo');
+ $node->min(3)->max(2);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The value 4 is too small for path "foo". Should be greater than or equal to 5
+ */
+ public function testIntegerMinAssertion()
+ {
+ $def = new IntegerNodeDefinition('foo');
+ $def->min(5)->getNode()->finalize(4);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The value 4 is too big for path "foo". Should be less than or equal to 3
+ */
+ public function testIntegerMaxAssertion()
+ {
+ $def = new IntegerNodeDefinition('foo');
+ $def->max(3)->getNode()->finalize(4);
+ }
+
+ public function testIntegerValidMinMaxAssertion()
+ {
+ $def = new IntegerNodeDefinition('foo');
+ $node = $def->min(3)->max(7)->getNode();
+ $this->assertEquals(4, $node->finalize(4));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The value 400 is too small for path "foo". Should be greater than or equal to 500
+ */
+ public function testFloatMinAssertion()
+ {
+ $def = new FloatNodeDefinition('foo');
+ $def->min(5E2)->getNode()->finalize(4e2);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The value 4.3 is too big for path "foo". Should be less than or equal to 0.3
+ */
+ public function testFloatMaxAssertion()
+ {
+ $def = new FloatNodeDefinition('foo');
+ $def->max(0.3)->getNode()->finalize(4.3);
+ }
+
+ public function testFloatValidMinMaxAssertion()
+ {
+ $def = new FloatNodeDefinition('foo');
+ $node = $def->min(3.0)->max(7e2)->getNode();
+ $this->assertEquals(4.5, $node->finalize(4.5));
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php
new file mode 100644
index 0000000..00e27c6
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php
@@ -0,0 +1,126 @@
+<?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\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder as CustomNodeBuilder;
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+
+require __DIR__.'/../../Fixtures/Builder/NodeBuilder.php';
+require __DIR__.'/../../Fixtures/Builder/BarNodeDefinition.php';
+require __DIR__.'/../../Fixtures/Builder/VariableNodeDefinition.php';
+
+class TreeBuilderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testUsingACustomNodeBuilder()
+ {
+ $builder = new TreeBuilder();
+ $root = $builder->root('custom', 'array', new CustomNodeBuilder());
+
+ $nodeBuilder = $root->children();
+
+ $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder', $nodeBuilder);
+
+ $nodeBuilder = $nodeBuilder->arrayNode('deeper')->children();
+
+ $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder', $nodeBuilder);
+ }
+
+ public function testOverrideABuiltInNodeType()
+ {
+ $builder = new TreeBuilder();
+ $root = $builder->root('override', 'array', new CustomNodeBuilder());
+
+ $definition = $root->children()->variableNode('variable');
+
+ $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\VariableNodeDefinition', $definition);
+ }
+
+ public function testAddANodeType()
+ {
+ $builder = new TreeBuilder();
+ $root = $builder->root('override', 'array', new CustomNodeBuilder());
+
+ $definition = $root->children()->barNode('variable');
+
+ $this->assertInstanceOf('Symfony\Component\Config\Tests\Definition\Builder\BarNodeDefinition', $definition);
+ }
+
+ public function testCreateABuiltInNodeTypeWithACustomNodeBuilder()
+ {
+ $builder = new TreeBuilder();
+ $root = $builder->root('builtin', 'array', new CustomNodeBuilder());
+
+ $definition = $root->children()->booleanNode('boolean');
+
+ $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition', $definition);
+ }
+
+ public function testPrototypedArrayNodeUseTheCustomNodeBuilder()
+ {
+ $builder = new TreeBuilder();
+ $root = $builder->root('override', 'array', new CustomNodeBuilder());
+
+ $root->prototype('bar')->end();
+ }
+
+ public function testAnExtendedNodeBuilderGetsPropagatedToTheChildren()
+ {
+ $builder = new TreeBuilder();
+
+ $builder->root('propagation')
+ ->children()
+ ->setNodeClass('extended', 'Symfony\Component\Config\Tests\Definition\Builder\VariableNodeDefinition')
+ ->node('foo', 'extended')->end()
+ ->arrayNode('child')
+ ->children()
+ ->node('foo', 'extended')
+ ->end()
+ ->end()
+ ->end()
+ ->end();
+ }
+
+ public function testDefinitionInfoGetsTransferredToNode()
+ {
+ $builder = new TreeBuilder();
+
+ $builder->root('test')->info('root info')
+ ->children()
+ ->node('child', 'variable')->info('child info')->defaultValue('default')
+ ->end()
+ ->end();
+
+ $tree = $builder->buildTree();
+ $children = $tree->getChildren();
+
+ $this->assertEquals('root info', $tree->getInfo());
+ $this->assertEquals('child info', $children['child']->getInfo());
+ }
+
+ public function testDefinitionExampleGetsTransferredToNode()
+ {
+ $builder = new TreeBuilder();
+
+ $builder->root('test')
+ ->example(array('key' => 'value'))
+ ->children()
+ ->node('child', 'variable')->info('child info')->defaultValue('default')->example('example')
+ ->end()
+ ->end();
+
+ $tree = $builder->buildTree();
+ $children = $tree->getChildren();
+
+ $this->assertTrue(is_array($tree->getExample()));
+ $this->assertEquals('example', $children['child']->getExample());
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php
new file mode 100644
index 0000000..ab6bdaa
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php
@@ -0,0 +1,80 @@
+<?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\Tests\Definition\Dumper;
+
+use Symfony\Component\Config\Definition\Dumper\XmlReferenceDumper;
+use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration;
+
+class XmlReferenceDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDumper()
+ {
+ $configuration = new ExampleConfiguration();
+
+ $dumper = new XmlReferenceDumper();
+ $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration));
+ }
+
+ public function testNamespaceDumper()
+ {
+ $configuration = new ExampleConfiguration();
+
+ $dumper = new XmlReferenceDumper();
+ $this->assertEquals(str_replace('http://example.org/schema/dic/acme_root', 'http://symfony.com/schema/dic/symfony', $this->getConfigurationAsString()), $dumper->dump($configuration, 'http://symfony.com/schema/dic/symfony'));
+ }
+
+ private function getConfigurationAsString()
+ {
+ return <<<EOL
+<!-- Namespace: http://example.org/schema/dic/acme_root -->
+<!-- scalar-required: Required -->
+<!-- enum: One of "this"; "that" -->
+<config
+ boolean="true"
+ scalar-empty=""
+ scalar-null="null"
+ scalar-true="true"
+ scalar-false="false"
+ scalar-default="default"
+ scalar-array-empty=""
+ scalar-array-defaults="elem1,elem2"
+ scalar-required=""
+ enum=""
+>
+
+ <!-- some info -->
+ <!--
+ child3: this is a long
+ multi-line info text
+ which should be indented;
+ Example: example setting
+ -->
+ <array
+ child1=""
+ child2=""
+ child3=""
+ />
+
+ <!-- prototype -->
+ <parameter name="parameter name">scalar value</parameter>
+
+ <!-- prototype -->
+ <connection
+ user=""
+ pass=""
+ />
+
+</config>
+
+EOL;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php
new file mode 100644
index 0000000..4775235
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php
@@ -0,0 +1,67 @@
+<?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\Tests\Definition\Dumper;
+
+use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper;
+use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration;
+
+class YamlReferenceDumperTest extends \PHPUnit_Framework_TestCase
+{
+ public function testDumper()
+ {
+ $configuration = new ExampleConfiguration();
+
+ $dumper = new YamlReferenceDumper();
+
+ $this->markTestIncomplete('The Yaml Dumper currently does not support prototyped arrays');
+ $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration));
+ }
+
+ private function getConfigurationAsString()
+ {
+ return <<<EOL
+acme_root:
+ boolean: true
+ scalar_empty: ~
+ scalar_null: ~
+ scalar_true: true
+ scalar_false: false
+ scalar_default: default
+ scalar_array_empty: []
+ scalar_array_defaults:
+
+ # Defaults:
+ - elem1
+ - elem2
+ scalar_required: ~ # Required
+ enum: ~ # One of "this"; "that"
+
+ # some info
+ array:
+ child1: ~
+ child2: ~
+
+ # this is a long
+ # multi-line info text
+ # which should be indented
+ child3: ~ # Example: example setting
+ parameters:
+
+ # Prototype
+ name: ~
+ connections:
+ # Prototype
+ - { user: ~, pass: ~ }
+
+EOL;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php
new file mode 100644
index 0000000..2b84de6
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/EnumNodeTest.php
@@ -0,0 +1,41 @@
+<?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\Tests\Definition;
+
+use Symfony\Component\Config\Definition\EnumNode;
+
+class EnumNodeTest extends \PHPUnit_Framework_TestCase
+{
+ public function testFinalizeValue()
+ {
+ $node = new EnumNode('foo', null, array('foo', 'bar'));
+ $this->assertSame('foo', $node->finalize('foo'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testConstructionWithOneValue()
+ {
+ new EnumNode('foo', null, array('foo', 'foo'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The value "foobar" is not allowed for path "foo". Permissible values: "foo", "bar"
+ */
+ public function testFinalizeWithInvalidValue()
+ {
+ $node = new EnumNode('foo', null, array('foo', 'bar'));
+ $node->finalize('foobar');
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FinalizationTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FinalizationTest.php
new file mode 100644
index 0000000..19fc347
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FinalizationTest.php
@@ -0,0 +1,73 @@
+<?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\Tests\Definition;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\Processor;
+use Symfony\Component\Config\Definition\NodeInterface;
+
+class FinalizationTest extends \PHPUnit_Framework_TestCase
+{
+ public function testUnsetKeyWithDeepHierarchy()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('config', 'array')
+ ->children()
+ ->node('level1', 'array')
+ ->canBeUnset()
+ ->children()
+ ->node('level2', 'array')
+ ->canBeUnset()
+ ->children()
+ ->node('somevalue', 'scalar')->end()
+ ->node('anothervalue', 'scalar')->end()
+ ->end()
+ ->end()
+ ->node('level1_scalar', 'scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $a = array(
+ 'level1' => array(
+ 'level2' => array(
+ 'somevalue' => 'foo',
+ 'anothervalue' => 'bar',
+ ),
+ 'level1_scalar' => 'foo',
+ ),
+ );
+
+ $b = array(
+ 'level1' => array(
+ 'level2' => false,
+ ),
+ );
+
+ $this->assertEquals(array(
+ 'level1' => array(
+ 'level1_scalar' => 'foo',
+ ),
+ ), $this->process($tree, array($a, $b)));
+ }
+
+ protected function process(NodeInterface $tree, array $configs)
+ {
+ $processor = new Processor();
+
+ return $processor->process($tree, $configs);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php
new file mode 100644
index 0000000..4f308ca
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/FloatNodeTest.php
@@ -0,0 +1,64 @@
+<?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\Tests\Definition;
+
+use Symfony\Component\Config\Definition\FloatNode;
+
+class FloatNodeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testNormalize($value)
+ {
+ $node = new FloatNode('test');
+ $this->assertSame($value, $node->normalize($value));
+ }
+
+ public function getValidValues()
+ {
+ return array(
+ array(1798.0),
+ array(-678.987),
+ array(12.56E45),
+ array(0.0),
+ // Integer are accepted too, they will be cast
+ array(17),
+ array(-10),
+ array(0),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
+ */
+ public function testNormalizeThrowsExceptionOnInvalidValues($value)
+ {
+ $node = new FloatNode('test');
+ $node->normalize($value);
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array(null),
+ array(''),
+ array('foo'),
+ array(true),
+ array(false),
+ array(array()),
+ array(array('foo' => 'bar')),
+ array(new \stdClass()),
+ );
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php
new file mode 100644
index 0000000..1527db7
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/IntegerNodeTest.php
@@ -0,0 +1,61 @@
+<?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\Tests\Definition;
+
+use Symfony\Component\Config\Definition\IntegerNode;
+
+class IntegerNodeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testNormalize($value)
+ {
+ $node = new IntegerNode('test');
+ $this->assertSame($value, $node->normalize($value));
+ }
+
+ public function getValidValues()
+ {
+ return array(
+ array(1798),
+ array(-678),
+ array(0),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
+ */
+ public function testNormalizeThrowsExceptionOnInvalidValues($value)
+ {
+ $node = new IntegerNode('test');
+ $node->normalize($value);
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array(null),
+ array(''),
+ array('foo'),
+ array(true),
+ array(false),
+ array(0.0),
+ array(0.1),
+ array(array()),
+ array(array('foo' => 'bar')),
+ array(new \stdClass()),
+ );
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/MergeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/MergeTest.php
new file mode 100644
index 0000000..08ddc32
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/MergeTest.php
@@ -0,0 +1,195 @@
+<?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\Tests\Definition;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+
+class MergeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException
+ */
+ public function testForbiddenOverwrite()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root', 'array')
+ ->children()
+ ->node('foo', 'scalar')
+ ->cannotBeOverwritten()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $a = array(
+ 'foo' => 'bar',
+ );
+
+ $b = array(
+ 'foo' => 'moo',
+ );
+
+ $tree->merge($a, $b);
+ }
+
+ public function testUnsetKey()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root', 'array')
+ ->children()
+ ->node('foo', 'scalar')->end()
+ ->node('bar', 'scalar')->end()
+ ->node('unsettable', 'array')
+ ->canBeUnset()
+ ->children()
+ ->node('foo', 'scalar')->end()
+ ->node('bar', 'scalar')->end()
+ ->end()
+ ->end()
+ ->node('unsetted', 'array')
+ ->canBeUnset()
+ ->prototype('scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $a = array(
+ 'foo' => 'bar',
+ 'unsettable' => array(
+ 'foo' => 'a',
+ 'bar' => 'b',
+ ),
+ 'unsetted' => false,
+ );
+
+ $b = array(
+ 'foo' => 'moo',
+ 'bar' => 'b',
+ 'unsettable' => false,
+ 'unsetted' => array('a', 'b'),
+ );
+
+ $this->assertEquals(array(
+ 'foo' => 'moo',
+ 'bar' => 'b',
+ 'unsettable' => false,
+ 'unsetted' => array('a', 'b'),
+ ), $tree->merge($a, $b));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ */
+ public function testDoesNotAllowNewKeysInSubsequentConfigs()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('config', 'array')
+ ->children()
+ ->node('test', 'array')
+ ->disallowNewKeysInSubsequentConfigs()
+ ->useAttributeAsKey('key')
+ ->prototype('array')
+ ->children()
+ ->node('value', 'scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree();
+
+ $a = array(
+ 'test' => array(
+ 'a' => array('value' => 'foo'),
+ ),
+ );
+
+ $b = array(
+ 'test' => array(
+ 'b' => array('value' => 'foo'),
+ ),
+ );
+
+ $tree->merge($a, $b);
+ }
+
+ public function testPerformsNoDeepMerging()
+ {
+ $tb = new TreeBuilder();
+
+ $tree = $tb
+ ->root('config', 'array')
+ ->children()
+ ->node('no_deep_merging', 'array')
+ ->performNoDeepMerging()
+ ->children()
+ ->node('foo', 'scalar')->end()
+ ->node('bar', 'scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $a = array(
+ 'no_deep_merging' => array(
+ 'foo' => 'a',
+ 'bar' => 'b',
+ ),
+ );
+
+ $b = array(
+ 'no_deep_merging' => array(
+ 'c' => 'd',
+ ),
+ );
+
+ $this->assertEquals(array(
+ 'no_deep_merging' => array(
+ 'c' => 'd',
+ ),
+ ), $tree->merge($a, $b));
+ }
+
+ public function testPrototypeWithoutAKeyAttribute()
+ {
+ $tb = new TreeBuilder();
+
+ $tree = $tb
+ ->root('config', 'array')
+ ->children()
+ ->arrayNode('append_elements')
+ ->prototype('scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $a = array(
+ 'append_elements' => array('a', 'b'),
+ );
+
+ $b = array(
+ 'append_elements' => array('c', 'd'),
+ );
+
+ $this->assertEquals(array('append_elements' => array('a', 'b', 'c', 'd')), $tree->merge($a, $b));
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/NormalizationTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/NormalizationTest.php
new file mode 100644
index 0000000..a896f96
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/NormalizationTest.php
@@ -0,0 +1,229 @@
+<?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\Tests\Definition;
+
+use Symfony\Component\Config\Definition\NodeInterface;
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+
+class NormalizationTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getEncoderTests
+ */
+ public function testNormalizeEncoders($denormalized)
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root_name', 'array')
+ ->fixXmlConfig('encoder')
+ ->children()
+ ->node('encoders', 'array')
+ ->useAttributeAsKey('class')
+ ->prototype('array')
+ ->beforeNormalization()->ifString()->then(function ($v) { return array('algorithm' => $v); })->end()
+ ->children()
+ ->node('algorithm', 'scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $normalized = array(
+ 'encoders' => array(
+ 'foo' => array('algorithm' => 'plaintext'),
+ ),
+ );
+
+ $this->assertNormalized($tree, $denormalized, $normalized);
+ }
+
+ public function getEncoderTests()
+ {
+ $configs = array();
+
+ // XML
+ $configs[] = array(
+ 'encoder' => array(
+ array('class' => 'foo', 'algorithm' => 'plaintext'),
+ ),
+ );
+
+ // XML when only one element of this type
+ $configs[] = array(
+ 'encoder' => array('class' => 'foo', 'algorithm' => 'plaintext'),
+ );
+
+ // YAML/PHP
+ $configs[] = array(
+ 'encoders' => array(
+ array('class' => 'foo', 'algorithm' => 'plaintext'),
+ ),
+ );
+
+ // YAML/PHP
+ $configs[] = array(
+ 'encoders' => array(
+ 'foo' => 'plaintext',
+ ),
+ );
+
+ // YAML/PHP
+ $configs[] = array(
+ 'encoders' => array(
+ 'foo' => array('algorithm' => 'plaintext'),
+ ),
+ );
+
+ return array_map(function ($v) {
+ return array($v);
+ }, $configs);
+ }
+
+ /**
+ * @dataProvider getAnonymousKeysTests
+ */
+ public function testAnonymousKeysArray($denormalized)
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root', 'array')
+ ->children()
+ ->node('logout', 'array')
+ ->fixXmlConfig('handler')
+ ->children()
+ ->node('handlers', 'array')
+ ->prototype('scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $normalized = array('logout' => array('handlers' => array('a', 'b', 'c')));
+
+ $this->assertNormalized($tree, $denormalized, $normalized);
+ }
+
+ public function getAnonymousKeysTests()
+ {
+ $configs = array();
+
+ $configs[] = array(
+ 'logout' => array(
+ 'handlers' => array('a', 'b', 'c'),
+ ),
+ );
+
+ $configs[] = array(
+ 'logout' => array(
+ 'handler' => array('a', 'b', 'c'),
+ ),
+ );
+
+ return array_map(function ($v) { return array($v); }, $configs);
+ }
+
+ /**
+ * @dataProvider getNumericKeysTests
+ */
+ public function testNumericKeysAsAttributes($denormalized)
+ {
+ $normalized = array(
+ 'thing' => array(42 => array('foo', 'bar'), 1337 => array('baz', 'qux')),
+ );
+
+ $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, $normalized);
+ }
+
+ public function getNumericKeysTests()
+ {
+ $configs = array();
+
+ $configs[] = array(
+ 'thing' => array(
+ 42 => array('foo', 'bar'), 1337 => array('baz', 'qux'),
+ ),
+ );
+
+ $configs[] = array(
+ 'thing' => array(
+ array('foo', 'bar', 'id' => 42), array('baz', 'qux', 'id' => 1337),
+ ),
+ );
+
+ return array_map(function ($v) { return array($v); }, $configs);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ * @expectedExceptionMessage The attribute "id" must be set for path "root.thing".
+ */
+ public function testNonAssociativeArrayThrowsExceptionIfAttributeNotSet()
+ {
+ $denormalized = array(
+ 'thing' => array(
+ array('foo', 'bar'), array('baz', 'qux'),
+ ),
+ );
+
+ $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, array());
+ }
+
+ public function testAssociativeArrayPreserveKeys()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root', 'array')
+ ->prototype('array')
+ ->children()
+ ->node('foo', 'scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ $data = array('first' => array('foo' => 'bar'));
+
+ $this->assertNormalized($tree, $data, $data);
+ }
+
+ public static function assertNormalized(NodeInterface $tree, $denormalized, $normalized)
+ {
+ self::assertSame($normalized, $tree->normalize($denormalized));
+ }
+
+ private function getNumericKeysTestTree()
+ {
+ $tb = new TreeBuilder();
+ $tree = $tb
+ ->root('root', 'array')
+ ->children()
+ ->node('thing', 'array')
+ ->useAttributeAsKey('id')
+ ->prototype('array')
+ ->prototype('scalar')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ->buildTree()
+ ;
+
+ return $tree;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php
new file mode 100644
index 0000000..c343fcf
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php
@@ -0,0 +1,180 @@
+<?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\Tests\Definition;
+
+use Symfony\Component\Config\Definition\PrototypedArrayNode;
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\ScalarNode;
+
+class PrototypedArrayNodeTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetDefaultValueReturnsAnEmptyArrayForPrototypes()
+ {
+ $node = new PrototypedArrayNode('root');
+ $prototype = new ArrayNode(null, $node);
+ $node->setPrototype($prototype);
+ $this->assertEmpty($node->getDefaultValue());
+ }
+
+ public function testGetDefaultValueReturnsDefaultValueForPrototypes()
+ {
+ $node = new PrototypedArrayNode('root');
+ $prototype = new ArrayNode(null, $node);
+ $node->setPrototype($prototype);
+ $node->setDefaultValue(array('test'));
+ $this->assertEquals(array('test'), $node->getDefaultValue());
+ }
+
+ // a remapped key (e.g. "mapping" -> "mappings") should be unset after being used
+ public function testRemappedKeysAreUnset()
+ {
+ $node = new ArrayNode('root');
+ $mappingsNode = new PrototypedArrayNode('mappings');
+ $node->addChild($mappingsNode);
+
+ // each item under mappings is just a scalar
+ $prototype = new ScalarNode(null, $mappingsNode);
+ $mappingsNode->setPrototype($prototype);
+
+ $remappings = array();
+ $remappings[] = array('mapping', 'mappings');
+ $node->setXmlRemappings($remappings);
+
+ $normalized = $node->normalize(array('mapping' => array('foo', 'bar')));
+ $this->assertEquals(array('mappings' => array('foo', 'bar')), $normalized);
+ }
+
+ /**
+ * Tests that when a key attribute is mapped, that key is removed from the array.
+ *
+ * <things>
+ * <option id="option1" value="foo">
+ * <option id="option2" value="bar">
+ * </things>
+ *
+ * The above should finally be mapped to an array that looks like this
+ * (because "id" is the key attribute).
+ *
+ * array(
+ * 'things' => array(
+ * 'option1' => 'foo',
+ * 'option2' => 'bar',
+ * )
+ * )
+ */
+ public function testMappedAttributeKeyIsRemoved()
+ {
+ $node = new PrototypedArrayNode('root');
+ $node->setKeyAttribute('id', true);
+
+ // each item under the root is an array, with one scalar item
+ $prototype = new ArrayNode(null, $node);
+ $prototype->addChild(new ScalarNode('foo'));
+ $node->setPrototype($prototype);
+
+ $children = array();
+ $children[] = array('id' => 'item_name', 'foo' => 'bar');
+ $normalized = $node->normalize($children);
+
+ $expected = array();
+ $expected['item_name'] = array('foo' => 'bar');
+ $this->assertEquals($expected, $normalized);
+ }
+
+ /**
+ * Tests the opposite of the testMappedAttributeKeyIsRemoved because
+ * the removal can be toggled with an option.
+ */
+ public function testMappedAttributeKeyNotRemoved()
+ {
+ $node = new PrototypedArrayNode('root');
+ $node->setKeyAttribute('id', false);
+
+ // each item under the root is an array, with two scalar items
+ $prototype = new ArrayNode(null, $node);
+ $prototype->addChild(new ScalarNode('foo'));
+ $prototype->addChild(new ScalarNode('id')); // the key attribute will remain
+ $node->setPrototype($prototype);
+
+ $children = array();
+ $children[] = array('id' => 'item_name', 'foo' => 'bar');
+ $normalized = $node->normalize($children);
+
+ $expected = array();
+ $expected['item_name'] = array('id' => 'item_name', 'foo' => 'bar');
+ $this->assertEquals($expected, $normalized);
+ }
+
+ public function testAddDefaultChildren()
+ {
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setAddChildrenIfNoneSet();
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setKeyAttribute('foobar');
+ $node->setAddChildrenIfNoneSet();
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array('defaults' => array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setKeyAttribute('foobar');
+ $node->setAddChildrenIfNoneSet('defaultkey');
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setKeyAttribute('foobar');
+ $node->setAddChildrenIfNoneSet(array('defaultkey'));
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setKeyAttribute('foobar');
+ $node->setAddChildrenIfNoneSet(array('dk1', 'dk2'));
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array('dk1' => array('foo' => 'bar'), 'dk2' => array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setAddChildrenIfNoneSet(array(5, 6));
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array(0 => array('foo' => 'bar'), 1 => array('foo' => 'bar')), $node->getDefaultValue());
+
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setAddChildrenIfNoneSet(2);
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array(array('foo' => 'bar'), array('foo' => 'bar')), $node->getDefaultValue());
+ }
+
+ public function testDefaultChildrenWinsOverDefaultValue()
+ {
+ $node = $this->getPrototypeNodeWithDefaultChildren();
+ $node->setAddChildrenIfNoneSet();
+ $node->setDefaultValue(array('bar' => 'foo'));
+ $this->assertTrue($node->hasDefaultValue());
+ $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());
+ }
+
+ protected function getPrototypeNodeWithDefaultChildren()
+ {
+ $node = new PrototypedArrayNode('root');
+ $prototype = new ArrayNode(null, $node);
+ $child = new ScalarNode('foo');
+ $child->setDefaultValue('bar');
+ $prototype->addChild($child);
+ $prototype->setAddIfNotSet(true);
+ $node->setPrototype($prototype);
+
+ return $node;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php
new file mode 100644
index 0000000..a798410
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php
@@ -0,0 +1,79 @@
+<?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\Tests\Definition;
+
+use Symfony\Component\Config\Definition\ScalarNode;
+
+class ScalarNodeTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getValidValues
+ */
+ public function testNormalize($value)
+ {
+ $node = new ScalarNode('test');
+ $this->assertSame($value, $node->normalize($value));
+ }
+
+ public function getValidValues()
+ {
+ return array(
+ array(false),
+ array(true),
+ array(null),
+ array(''),
+ array('foo'),
+ array(0),
+ array(1),
+ array(0.0),
+ array(0.1),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidValues
+ * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
+ */
+ public function testNormalizeThrowsExceptionOnInvalidValues($value)
+ {
+ $node = new ScalarNode('test');
+ $node->normalize($value);
+ }
+
+ public function getInvalidValues()
+ {
+ return array(
+ array(array()),
+ array(array('foo' => 'bar')),
+ array(new \stdClass()),
+ );
+ }
+
+ public function testNormalizeThrowsExceptionWithoutHint()
+ {
+ $node = new ScalarNode('test');
+
+ $this->setExpectedException('Symfony\Component\Config\Definition\Exception\InvalidTypeException', 'Invalid type for path "test". Expected scalar, but got array.');
+
+ $node->normalize(array());
+ }
+
+ public function testNormalizeThrowsExceptionWithErrorMessage()
+ {
+ $node = new ScalarNode('test');
+ $node->setInfo('"the test value"');
+
+ $this->setExpectedException('Symfony\Component\Config\Definition\Exception\InvalidTypeException', "Invalid type for path \"test\". Expected scalar, but got array.\nHint: \"the test value\"");
+
+ $node->normalize(array());
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Exception/FileLoaderLoadExceptionTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Exception/FileLoaderLoadExceptionTest.php
new file mode 100644
index 0000000..4d91535
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Exception/FileLoaderLoadExceptionTest.php
@@ -0,0 +1,83 @@
+<?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\Tests\Exception;
+
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+
+class FileLoaderLoadExceptionTest extends \PHPUnit_Framework_TestCase
+{
+ public function testMessageCannotLoadResource()
+ {
+ $exception = new FileLoaderLoadException('resource', null);
+ $this->assertEquals('Cannot load resource "resource".', $exception->getMessage());
+ }
+
+ public function testMessageCannotImportResourceFromSource()
+ {
+ $exception = new FileLoaderLoadException('resource', 'sourceResource');
+ $this->assertEquals('Cannot import resource "resource" from "sourceResource".', $exception->getMessage());
+ }
+
+ public function testMessageCannotImportBundleResource()
+ {
+ $exception = new FileLoaderLoadException('@resource', 'sourceResource');
+ $this->assertEquals(
+ 'Cannot import resource "@resource" from "sourceResource". '.
+ 'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class.',
+ $exception->getMessage()
+ );
+ }
+
+ public function testMessageHasPreviousErrorWithDotAndUnableToLoad()
+ {
+ $exception = new FileLoaderLoadException(
+ 'resource',
+ null,
+ null,
+ new \Exception('There was a previous error with an ending dot.')
+ );
+ $this->assertEquals(
+ 'There was a previous error with an ending dot in resource (which is loaded in resource "resource").',
+ $exception->getMessage()
+ );
+ }
+
+ public function testMessageHasPreviousErrorWithoutDotAndUnableToLoad()
+ {
+ $exception = new FileLoaderLoadException(
+ 'resource',
+ null,
+ null,
+ new \Exception('There was a previous error with no ending dot')
+ );
+ $this->assertEquals(
+ 'There was a previous error with no ending dot in resource (which is loaded in resource "resource").',
+ $exception->getMessage()
+ );
+ }
+
+ public function testMessageHasPreviousErrorAndUnableToLoadBundle()
+ {
+ $exception = new FileLoaderLoadException(
+ '@resource',
+ null,
+ null,
+ new \Exception('There was a previous error with an ending dot.')
+ );
+ $this->assertEquals(
+ 'There was a previous error with an ending dot in @resource '.
+ '(which is loaded in resource "@resource"). '.
+ 'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class.',
+ $exception->getMessage()
+ );
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/FileLocatorTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/FileLocatorTest.php
new file mode 100644
index 0000000..d479f25
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/FileLocatorTest.php
@@ -0,0 +1,119 @@
+<?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\Tests;
+
+use Symfony\Component\Config\FileLocator;
+
+class FileLocatorTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getIsAbsolutePathTests
+ */
+ public function testIsAbsolutePath($path)
+ {
+ $loader = new FileLocator(array());
+ $r = new \ReflectionObject($loader);
+ $m = $r->getMethod('isAbsolutePath');
+ $m->setAccessible(true);
+
+ $this->assertTrue($m->invoke($loader, $path), '->isAbsolutePath() returns true for an absolute path');
+ }
+
+ public function getIsAbsolutePathTests()
+ {
+ return array(
+ array('/foo.xml'),
+ array('c:\\\\foo.xml'),
+ array('c:/foo.xml'),
+ array('\\server\\foo.xml'),
+ array('https://server/foo.xml'),
+ array('phar://server/foo.xml'),
+ );
+ }
+
+ public function testLocate()
+ {
+ $loader = new FileLocator(__DIR__.'/Fixtures');
+
+ $this->assertEquals(
+ __DIR__.DIRECTORY_SEPARATOR.'FileLocatorTest.php',
+ $loader->locate('FileLocatorTest.php', __DIR__),
+ '->locate() returns the absolute filename if the file exists in the given path'
+ );
+
+ $this->assertEquals(
+ __DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml',
+ $loader->locate('foo.xml', __DIR__),
+ '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor'
+ );
+
+ $this->assertEquals(
+ __DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml',
+ $loader->locate(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__),
+ '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor'
+ );
+
+ $loader = new FileLocator(array(__DIR__.'/Fixtures', __DIR__.'/Fixtures/Again'));
+
+ $this->assertEquals(
+ array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
+ $loader->locate('foo.xml', __DIR__, false),
+ '->locate() returns an array of absolute filenames'
+ );
+
+ $this->assertEquals(
+ array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
+ $loader->locate('foo.xml', __DIR__.'/Fixtures', false),
+ '->locate() returns an array of absolute filenames'
+ );
+
+ $loader = new FileLocator(__DIR__.'/Fixtures/Again');
+
+ $this->assertEquals(
+ array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
+ $loader->locate('foo.xml', __DIR__.'/Fixtures', false),
+ '->locate() returns an array of absolute filenames'
+ );
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The file "foobar.xml" does not exist
+ */
+ public function testLocateThrowsAnExceptionIfTheFileDoesNotExists()
+ {
+ $loader = new FileLocator(array(__DIR__.'/Fixtures'));
+
+ $loader->locate('foobar.xml', __DIR__);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testLocateThrowsAnExceptionIfTheFileDoesNotExistsInAbsolutePath()
+ {
+ $loader = new FileLocator(array(__DIR__.'/Fixtures'));
+
+ $loader->locate(__DIR__.'/Fixtures/foobar.xml', __DIR__);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage An empty file name is not valid to be located.
+ */
+ public function testLocateEmpty()
+ {
+ $loader = new FileLocator(array(__DIR__.'/Fixtures'));
+
+ $loader->locate(null, __DIR__);
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php
new file mode 100644
index 0000000..47701c1
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php
@@ -0,0 +1,21 @@
+<?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\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\NodeDefinition;
+
+class BarNodeDefinition extends NodeDefinition
+{
+ protected function createNode()
+ {
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php
new file mode 100644
index 0000000..aa59863
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php
@@ -0,0 +1,34 @@
+<?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\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder;
+
+class NodeBuilder extends BaseNodeBuilder
+{
+ public function barNode($name)
+ {
+ return $this->node($name, 'bar');
+ }
+
+ protected function getNodeClass($type)
+ {
+ switch ($type) {
+ case 'variable':
+ return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition';
+ case 'bar':
+ return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition';
+ default:
+ return parent::getNodeClass($type);
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php
new file mode 100644
index 0000000..1017880
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php
@@ -0,0 +1,18 @@
+<?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\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition;
+
+class VariableNodeDefinition extends BaseVariableNodeDefinition
+{
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php
new file mode 100644
index 0000000..df43e8b
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php
@@ -0,0 +1,71 @@
+<?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\Tests\Fixtures\Configuration;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\ConfigurationInterface;
+
+class ExampleConfiguration implements ConfigurationInterface
+{
+ public function getConfigTreeBuilder()
+ {
+ $treeBuilder = new TreeBuilder();
+ $rootNode = $treeBuilder->root('acme_root');
+
+ $rootNode
+ ->fixXmlConfig('parameter')
+ ->fixXmlConfig('connection')
+ ->children()
+ ->booleanNode('boolean')->defaultTrue()->end()
+ ->scalarNode('scalar_empty')->end()
+ ->scalarNode('scalar_null')->defaultNull()->end()
+ ->scalarNode('scalar_true')->defaultTrue()->end()
+ ->scalarNode('scalar_false')->defaultFalse()->end()
+ ->scalarNode('scalar_default')->defaultValue('default')->end()
+ ->scalarNode('scalar_array_empty')->defaultValue(array())->end()
+ ->scalarNode('scalar_array_defaults')->defaultValue(array('elem1', 'elem2'))->end()
+ ->scalarNode('scalar_required')->isRequired()->end()
+ ->enumNode('enum')->values(array('this', 'that'))->end()
+ ->arrayNode('array')
+ ->info('some info')
+ ->canBeUnset()
+ ->children()
+ ->scalarNode('child1')->end()
+ ->scalarNode('child2')->end()
+ ->scalarNode('child3')
+ ->info(
+ "this is a long\n".
+ "multi-line info text\n".
+ 'which should be indented'
+ )
+ ->example('example setting')
+ ->end()
+ ->end()
+ ->end()
+ ->arrayNode('parameters')
+ ->useAttributeAsKey('name')
+ ->prototype('scalar')->end()
+ ->end()
+ ->arrayNode('connections')
+ ->prototype('array')
+ ->children()
+ ->scalarNode('user')->end()
+ ->scalarNode('pass')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->end()
+ ;
+
+ return $treeBuilder;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml
new file mode 100644
index 0000000..4c25228
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE scan [<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource={{ resource }}">]>
+<scan></scan>
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml
new file mode 100644
index 0000000..a07af9f
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml
new file mode 100644
index 0000000..e2725a2
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root2 xmlns="http://example.com/schema" />
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd
new file mode 100644
index 0000000..e56820f
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsd:schema xmlns="http://example.com/schema"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://example.com/schema"
+ elementFormDefault="qualified">
+
+ <xsd:element name="root" />
+</xsd:schema>
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml
new file mode 100644
index 0000000..a96bb38
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root xmlns="http://example.com/schema">
+</root>
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/foo.xml b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/foo.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Fixtures/foo.xml
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php
new file mode 100644
index 0000000..7641e24
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php
@@ -0,0 +1,83 @@
+<?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\Tests\Loader;
+
+use Symfony\Component\Config\Loader\LoaderResolver;
+use Symfony\Component\Config\Loader\DelegatingLoader;
+
+class DelegatingLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Symfony\Component\Config\Loader\DelegatingLoader::__construct
+ */
+ public function testConstructor()
+ {
+ $loader = new DelegatingLoader($resolver = new LoaderResolver());
+ $this->assertTrue(true, '__construct() takes a loader resolver as its first argument');
+ }
+
+ /**
+ * @covers Symfony\Component\Config\Loader\DelegatingLoader::getResolver
+ * @covers Symfony\Component\Config\Loader\DelegatingLoader::setResolver
+ */
+ public function testGetSetResolver()
+ {
+ $resolver = new LoaderResolver();
+ $loader = new DelegatingLoader($resolver);
+ $this->assertSame($resolver, $loader->getResolver(), '->getResolver() gets the resolver loader');
+ $loader->setResolver($resolver = new LoaderResolver());
+ $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader');
+ }
+
+ /**
+ * @covers Symfony\Component\Config\Loader\DelegatingLoader::supports
+ */
+ public function testSupports()
+ {
+ $loader1 = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $loader1->expects($this->once())->method('supports')->will($this->returnValue(true));
+ $loader = new DelegatingLoader(new LoaderResolver(array($loader1)));
+ $this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable');
+
+ $loader1 = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $loader1->expects($this->once())->method('supports')->will($this->returnValue(false));
+ $loader = new DelegatingLoader(new LoaderResolver(array($loader1)));
+ $this->assertFalse($loader->supports('foo.foo'), '->supports() returns false if the resource is not loadable');
+ }
+
+ /**
+ * @covers Symfony\Component\Config\Loader\DelegatingLoader::load
+ */
+ public function testLoad()
+ {
+ $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $loader->expects($this->once())->method('supports')->will($this->returnValue(true));
+ $loader->expects($this->once())->method('load');
+ $resolver = new LoaderResolver(array($loader));
+ $loader = new DelegatingLoader($resolver);
+
+ $loader->load('foo');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Exception\FileLoaderLoadException
+ */
+ public function testLoadThrowsAnExceptionIfTheResourceCannotBeLoaded()
+ {
+ $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $loader->expects($this->once())->method('supports')->will($this->returnValue(false));
+ $resolver = new LoaderResolver(array($loader));
+ $loader = new DelegatingLoader($resolver);
+
+ $loader->load('foo');
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php
new file mode 100644
index 0000000..1442e94
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php
@@ -0,0 +1,106 @@
+<?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\Tests\Loader;
+
+use Symfony\Component\Config\Loader\FileLoader;
+use Symfony\Component\Config\Loader\LoaderResolver;
+
+class FileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Symfony\Component\Config\Loader\FileLoader
+ */
+ public function testImportWithFileLocatorDelegation()
+ {
+ $locatorMock = $this->getMock('Symfony\Component\Config\FileLocatorInterface');
+
+ $locatorMockForAdditionalLoader = $this->getMock('Symfony\Component\Config\FileLocatorInterface');
+ $locatorMockForAdditionalLoader->expects($this->any())->method('locate')->will($this->onConsecutiveCalls(
+ array('path/to/file1'), // Default
+ array('path/to/file1', 'path/to/file2'), // First is imported
+ array('path/to/file1', 'path/to/file2'), // Second is imported
+ array('path/to/file1'), // Exception
+ array('path/to/file1', 'path/to/file2') // Exception
+ ));
+
+ $fileLoader = new TestFileLoader($locatorMock);
+ $fileLoader->setSupports(false);
+ $fileLoader->setCurrentDir('.');
+
+ $additionalLoader = new TestFileLoader($locatorMockForAdditionalLoader);
+ $additionalLoader->setCurrentDir('.');
+
+ $fileLoader->setResolver($loaderResolver = new LoaderResolver(array($fileLoader, $additionalLoader)));
+
+ // Default case
+ $this->assertSame('path/to/file1', $fileLoader->import('my_resource'));
+
+ // Check first file is imported if not already loading
+ $this->assertSame('path/to/file1', $fileLoader->import('my_resource'));
+
+ // Check second file is imported if first is already loading
+ $fileLoader->addLoading('path/to/file1');
+ $this->assertSame('path/to/file2', $fileLoader->import('my_resource'));
+
+ // Check exception throws if first (and only available) file is already loading
+ try {
+ $fileLoader->import('my_resource');
+ $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
+ }
+
+ // Check exception throws if all files are already loading
+ try {
+ $fileLoader->addLoading('path/to/file2');
+ $fileLoader->import('my_resource');
+ $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading');
+ }
+ }
+}
+
+class TestFileLoader extends FileLoader
+{
+ private $supports = true;
+
+ public function load($resource, $type = null)
+ {
+ return $resource;
+ }
+
+ public function supports($resource, $type = null)
+ {
+ return $this->supports;
+ }
+
+ public function addLoading($resource)
+ {
+ self::$loading[$resource] = true;
+ }
+
+ public function removeLoading($resource)
+ {
+ unset(self::$loading[$resource]);
+ }
+
+ public function clearLoading()
+ {
+ self::$loading = array();
+ }
+
+ public function setSupports($supports)
+ {
+ $this->supports = $supports;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php
new file mode 100644
index 0000000..8ee276b
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php
@@ -0,0 +1,56 @@
+<?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\Tests\Loader;
+
+use Symfony\Component\Config\Loader\LoaderResolver;
+
+class LoaderResolverTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Symfony\Component\Config\Loader\LoaderResolver::__construct
+ */
+ public function testConstructor()
+ {
+ $resolver = new LoaderResolver(array(
+ $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface'),
+ ));
+
+ $this->assertEquals(array($loader), $resolver->getLoaders(), '__construct() takes an array of loaders as its first argument');
+ }
+
+ /**
+ * @covers Symfony\Component\Config\Loader\LoaderResolver::resolve
+ */
+ public function testResolve()
+ {
+ $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $resolver = new LoaderResolver(array($loader));
+ $this->assertFalse($resolver->resolve('foo.foo'), '->resolve() returns false if no loader is able to load the resource');
+
+ $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $loader->expects($this->once())->method('supports')->will($this->returnValue(true));
+ $resolver = new LoaderResolver(array($loader));
+ $this->assertEquals($loader, $resolver->resolve(function () {}), '->resolve() returns the loader for the given resource');
+ }
+
+ /**
+ * @covers Symfony\Component\Config\Loader\LoaderResolver::getLoaders
+ * @covers Symfony\Component\Config\Loader\LoaderResolver::addLoader
+ */
+ public function testLoaders()
+ {
+ $resolver = new LoaderResolver();
+ $resolver->addLoader($loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface'));
+
+ $this->assertEquals(array($loader), $resolver->getLoaders(), 'addLoader() adds a loader');
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderTest.php
new file mode 100644
index 0000000..e938a4b
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Loader/LoaderTest.php
@@ -0,0 +1,117 @@
+<?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\Tests\Loader;
+
+use Symfony\Component\Config\Loader\Loader;
+
+class LoaderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetSetResolver()
+ {
+ $resolver = $this->getMock('Symfony\Component\Config\Loader\LoaderResolverInterface');
+
+ $loader = new ProjectLoader1();
+ $loader->setResolver($resolver);
+
+ $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader');
+ }
+
+ public function testResolve()
+ {
+ $resolvedLoader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+
+ $resolver = $this->getMock('Symfony\Component\Config\Loader\LoaderResolverInterface');
+ $resolver->expects($this->once())
+ ->method('resolve')
+ ->with('foo.xml')
+ ->will($this->returnValue($resolvedLoader));
+
+ $loader = new ProjectLoader1();
+ $loader->setResolver($resolver);
+
+ $this->assertSame($loader, $loader->resolve('foo.foo'), '->resolve() finds a loader');
+ $this->assertSame($resolvedLoader, $loader->resolve('foo.xml'), '->resolve() finds a loader');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Config\Exception\FileLoaderLoadException
+ */
+ public function testResolveWhenResolverCannotFindLoader()
+ {
+ $resolver = $this->getMock('Symfony\Component\Config\Loader\LoaderResolverInterface');
+ $resolver->expects($this->once())
+ ->method('resolve')
+ ->with('FOOBAR')
+ ->will($this->returnValue(false));
+
+ $loader = new ProjectLoader1();
+ $loader->setResolver($resolver);
+
+ $loader->resolve('FOOBAR');
+ }
+
+ public function testImport()
+ {
+ $resolvedLoader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $resolvedLoader->expects($this->once())
+ ->method('load')
+ ->with('foo')
+ ->will($this->returnValue('yes'));
+
+ $resolver = $this->getMock('Symfony\Component\Config\Loader\LoaderResolverInterface');
+ $resolver->expects($this->once())
+ ->method('resolve')
+ ->with('foo')
+ ->will($this->returnValue($resolvedLoader));
+
+ $loader = new ProjectLoader1();
+ $loader->setResolver($resolver);
+
+ $this->assertEquals('yes', $loader->import('foo'));
+ }
+
+ public function testImportWithType()
+ {
+ $resolvedLoader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+ $resolvedLoader->expects($this->once())
+ ->method('load')
+ ->with('foo', 'bar')
+ ->will($this->returnValue('yes'));
+
+ $resolver = $this->getMock('Symfony\Component\Config\Loader\LoaderResolverInterface');
+ $resolver->expects($this->once())
+ ->method('resolve')
+ ->with('foo', 'bar')
+ ->will($this->returnValue($resolvedLoader));
+
+ $loader = new ProjectLoader1();
+ $loader->setResolver($resolver);
+
+ $this->assertEquals('yes', $loader->import('foo', 'bar'));
+ }
+}
+
+class ProjectLoader1 extends Loader
+{
+ public function load($resource, $type = null)
+ {
+ }
+
+ public function supports($resource, $type = null)
+ {
+ return is_string($resource) && 'foo' === pathinfo($resource, PATHINFO_EXTENSION);
+ }
+
+ public function getType()
+ {
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php
new file mode 100644
index 0000000..d78e0cf
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php
@@ -0,0 +1,152 @@
+<?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\Tests\Resource;
+
+use Symfony\Component\Config\Resource\DirectoryResource;
+
+class DirectoryResourceTest extends \PHPUnit_Framework_TestCase
+{
+ protected $directory;
+
+ protected function setUp()
+ {
+ $this->directory = sys_get_temp_dir().'/symfonyDirectoryIterator';
+ if (!file_exists($this->directory)) {
+ mkdir($this->directory);
+ }
+ touch($this->directory.'/tmp.xml');
+ }
+
+ protected function tearDown()
+ {
+ if (!is_dir($this->directory)) {
+ return;
+ }
+ $this->removeDirectory($this->directory);
+ }
+
+ protected function removeDirectory($directory)
+ {
+ $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory), \RecursiveIteratorIterator::CHILD_FIRST);
+ foreach ($iterator as $path) {
+ if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) {
+ continue;
+ }
+ if ($path->isDir()) {
+ rmdir($path->__toString());
+ } else {
+ unlink($path->__toString());
+ }
+ }
+ rmdir($directory);
+ }
+
+ public function testGetResource()
+ {
+ $resource = new DirectoryResource($this->directory);
+ $this->assertSame($this->directory, $resource->getResource(), '->getResource() returns the path to the resource');
+ $this->assertSame($this->directory, (string) $resource, '->__toString() returns the path to the resource');
+ }
+
+ public function testGetPattern()
+ {
+ $resource = new DirectoryResource('foo', 'bar');
+ $this->assertEquals('bar', $resource->getPattern());
+ }
+
+ public function testIsFresh()
+ {
+ $resource = new DirectoryResource($this->directory);
+ $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed');
+ $this->assertFalse($resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated');
+
+ $resource = new DirectoryResource('/____foo/foobar'.rand(1, 999999));
+ $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist');
+ }
+
+ public function testIsFreshUpdateFile()
+ {
+ $resource = new DirectoryResource($this->directory);
+ touch($this->directory.'/tmp.xml', time() + 20);
+ $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an existing file is modified');
+ }
+
+ public function testIsFreshNewFile()
+ {
+ $resource = new DirectoryResource($this->directory);
+ touch($this->directory.'/new.xml', time() + 20);
+ $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file is added');
+ }
+
+ public function testIsFreshDeleteFile()
+ {
+ $resource = new DirectoryResource($this->directory);
+ unlink($this->directory.'/tmp.xml');
+ $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if an existing file is removed');
+ }
+
+ public function testIsFreshDeleteDirectory()
+ {
+ $resource = new DirectoryResource($this->directory);
+ $this->removeDirectory($this->directory);
+ $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the whole resource is removed');
+ }
+
+ public function testIsFreshCreateFileInSubdirectory()
+ {
+ $subdirectory = $this->directory.'/subdirectory';
+ mkdir($subdirectory);
+
+ $resource = new DirectoryResource($this->directory);
+ $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if an unmodified subdirectory exists');
+
+ touch($subdirectory.'/newfile.xml', time() + 20);
+ $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file in a subdirectory is added');
+ }
+
+ public function testIsFreshModifySubdirectory()
+ {
+ $resource = new DirectoryResource($this->directory);
+
+ $subdirectory = $this->directory.'/subdirectory';
+ mkdir($subdirectory);
+ touch($subdirectory, time() + 20);
+
+ $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a subdirectory is modified (e.g. a file gets deleted)');
+ }
+
+ public function testFilterRegexListNoMatch()
+ {
+ $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');
+
+ touch($this->directory.'/new.bar', time() + 20);
+ $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file not matching the filter regex is created');
+ }
+
+ public function testFilterRegexListMatch()
+ {
+ $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');
+
+ touch($this->directory.'/new.xml', time() + 20);
+ $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an new file matching the filter regex is created ');
+ }
+
+ public function testSerializeUnserialize()
+ {
+ $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');
+
+ $unserialized = unserialize(serialize($resource));
+
+ $this->assertSame($this->directory, $resource->getResource());
+ $this->assertSame('/\.(foo|xml)$/', $resource->getPattern());
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/FileResourceTest.php
new file mode 100644
index 0000000..d152806
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Resource/FileResourceTest.php
@@ -0,0 +1,61 @@
+<?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\Tests\Resource;
+
+use Symfony\Component\Config\Resource\FileResource;
+
+class FileResourceTest extends \PHPUnit_Framework_TestCase
+{
+ protected $resource;
+ protected $file;
+ protected $time;
+
+ protected function setUp()
+ {
+ $this->file = realpath(sys_get_temp_dir()).'/tmp.xml';
+ $this->time = time();
+ touch($this->file, $this->time);
+ $this->resource = new FileResource($this->file);
+ }
+
+ protected function tearDown()
+ {
+ unlink($this->file);
+ }
+
+ public function testGetResource()
+ {
+ $this->assertSame(realpath($this->file), $this->resource->getResource(), '->getResource() returns the path to the resource');
+ }
+
+ public function testToString()
+ {
+ $this->assertSame(realpath($this->file), (string) $this->resource);
+ }
+
+ public function testIsFresh()
+ {
+ $this->assertTrue($this->resource->isFresh($this->time), '->isFresh() returns true if the resource has not changed in same second');
+ $this->assertTrue($this->resource->isFresh($this->time + 10), '->isFresh() returns true if the resource has not changed');
+ $this->assertFalse($this->resource->isFresh($this->time - 86400), '->isFresh() returns false if the resource has been updated');
+
+ $resource = new FileResource('/____foo/foobar'.rand(1, 999999));
+ $this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource does not exist');
+ }
+
+ public function testSerializeUnserialize()
+ {
+ $unserialized = unserialize(serialize($this->resource));
+
+ $this->assertSame(realpath($this->file), $this->resource->getResource());
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php b/vendor/symfony/config/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php
new file mode 100644
index 0000000..f9d3d14
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php
@@ -0,0 +1,197 @@
+<?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\Tests\Loader;
+
+use Symfony\Component\Config\Util\XmlUtils;
+
+class XmlUtilsTest extends \PHPUnit_Framework_TestCase
+{
+ public function testLoadFile()
+ {
+ $fixtures = __DIR__.'/../Fixtures/Util/';
+
+ try {
+ XmlUtils::loadFile($fixtures.'invalid.xml');
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertContains('ERROR 77', $e->getMessage());
+ }
+
+ try {
+ XmlUtils::loadFile($fixtures.'document_type.xml');
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertContains('Document types are not allowed', $e->getMessage());
+ }
+
+ try {
+ XmlUtils::loadFile($fixtures.'invalid_schema.xml', $fixtures.'schema.xsd');
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertContains('ERROR 1845', $e->getMessage());
+ }
+
+ try {
+ XmlUtils::loadFile($fixtures.'invalid_schema.xml', 'invalid_callback_or_file');
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertContains('XSD file or callable', $e->getMessage());
+ }
+
+ $mock = $this->getMock(__NAMESPACE__.'\Validator');
+ $mock->expects($this->exactly(2))->method('validate')->will($this->onConsecutiveCalls(false, true));
+
+ try {
+ XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate'));
+ $this->fail();
+ } catch (\InvalidArgumentException $e) {
+ $this->assertContains('is not valid', $e->getMessage());
+ }
+
+ $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate')));
+ $this->assertSame(array(), libxml_get_errors());
+ }
+
+ public function testLoadFileWithInternalErrorsEnabled()
+ {
+ libxml_use_internal_errors(true);
+
+ $this->assertSame(array(), libxml_get_errors());
+ $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/invalid_schema.xml'));
+ $this->assertSame(array(), libxml_get_errors());
+ }
+
+ /**
+ * @dataProvider getDataForConvertDomToArray
+ */
+ public function testConvertDomToArray($expected, $xml, $root = false, $checkPrefix = true)
+ {
+ $dom = new \DOMDocument();
+ $dom->loadXML($root ? $xml : '<root>'.$xml.'</root>');
+
+ $this->assertSame($expected, XmlUtils::convertDomElementToArray($dom->documentElement, $checkPrefix));
+ }
+
+ public function getDataForConvertDomToArray()
+ {
+ return array(
+ array(null, ''),
+ array('bar', 'bar'),
+ array(array('bar' => 'foobar'), '<foo bar="foobar" />', true),
+ array(array('foo' => null), '<foo />'),
+ array(array('foo' => 'bar'), '<foo>bar</foo>'),
+ array(array('foo' => array('foo' => 'bar')), '<foo foo="bar"/>'),
+ array(array('foo' => array('foo' => 0)), '<foo><foo>0</foo></foo>'),
+ array(array('foo' => array('foo' => 'bar')), '<foo><foo>bar</foo></foo>'),
+ array(array('foo' => array('foo' => 'bar', 'value' => 'text')), '<foo foo="bar">text</foo>'),
+ array(array('foo' => array('attr' => 'bar', 'foo' => 'text')), '<foo attr="bar"><foo>text</foo></foo>'),
+ array(array('foo' => array('bar', 'text')), '<foo>bar</foo><foo>text</foo>'),
+ array(array('foo' => array(array('foo' => 'bar'), array('foo' => 'text'))), '<foo foo="bar"/><foo foo="text" />'),
+ array(array('foo' => array('foo' => array('bar', 'text'))), '<foo foo="bar"><foo>text</foo></foo>'),
+ array(array('foo' => 'bar'), '<foo><!-- Comment -->bar</foo>'),
+ array(array('foo' => 'text'), '<foo xmlns:h="http://www.example.org/bar" h:bar="bar">text</foo>'),
+ array(array('foo' => array('bar' => 'bar', 'value' => 'text')), '<foo xmlns:h="http://www.example.org/bar" h:bar="bar">text</foo>', false, false),
+ array(array('attr' => 1, 'b' => 'hello'), '<foo:a xmlns:foo="http://www.example.org/foo" xmlns:h="http://www.example.org/bar" attr="1" h:bar="bar"><foo:b>hello</foo:b><h:c>2</h:c></foo:a>', true),
+ );
+ }
+
+ /**
+ * @dataProvider getDataForPhpize
+ */
+ public function testPhpize($expected, $value)
+ {
+ $this->assertSame($expected, XmlUtils::phpize($value));
+ }
+
+ public function getDataForPhpize()
+ {
+ return array(
+ array('', ''),
+ array(null, 'null'),
+ array(true, 'true'),
+ array(false, 'false'),
+ array(null, 'Null'),
+ array(true, 'True'),
+ array(false, 'False'),
+ array(0, '0'),
+ array(1, '1'),
+ array(-1, '-1'),
+ array(0777, '0777'),
+ array(255, '0xFF'),
+ array(100.0, '1e2'),
+ array(-120.0, '-1.2E2'),
+ array(-10100.1, '-10100.1'),
+ array('-10,100.1', '-10,100.1'),
+ array('1234 5678 9101 1121 3141', '1234 5678 9101 1121 3141'),
+ array('1,2,3,4', '1,2,3,4'),
+ array('11,22,33,44', '11,22,33,44'),
+ array('11,222,333,4', '11,222,333,4'),
+ array('1,222,333,444', '1,222,333,444'),
+ array('11,222,333,444', '11,222,333,444'),
+ array('111,222,333,444', '111,222,333,444'),
+ array('1111,2222,3333,4444,5555', '1111,2222,3333,4444,5555'),
+ array('foo', 'foo'),
+ array(6, '0b0110'),
+ );
+ }
+
+ public function testLoadEmptyXmlFile()
+ {
+ $file = __DIR__.'/../Fixtures/foo.xml';
+ $this->setExpectedException('InvalidArgumentException', 'File '.$file.' does not contain valid XML, it is empty.');
+ XmlUtils::loadFile($file);
+ }
+
+ // test for issue https://github.com/symfony/symfony/issues/9731
+ public function testLoadWrongEmptyXMLWithErrorHandler()
+ {
+ $originalDisableEntities = libxml_disable_entity_loader(false);
+ $errorReporting = error_reporting(-1);
+
+ set_error_handler(function ($errno, $errstr) {
+ throw new \Exception($errstr, $errno);
+ });
+
+ $file = __DIR__.'/../Fixtures/foo.xml';
+ try {
+ try {
+ XmlUtils::loadFile($file);
+ $this->fail('An exception should have been raised');
+ } catch (\InvalidArgumentException $e) {
+ $this->assertEquals(sprintf('File %s does not contain valid XML, it is empty.', $file), $e->getMessage());
+ }
+ } catch (\Exception $e) {
+ restore_error_handler();
+ error_reporting($errorReporting);
+
+ throw $e;
+ }
+
+ restore_error_handler();
+ error_reporting($errorReporting);
+
+ $disableEntities = libxml_disable_entity_loader(true);
+ libxml_disable_entity_loader($disableEntities);
+
+ libxml_disable_entity_loader($originalDisableEntities);
+
+ $this->assertFalse($disableEntities);
+
+ // should not throw an exception
+ XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/valid.xml', __DIR__.'/../Fixtures/Util/schema.xsd');
+ }
+}
+
+interface Validator
+{
+ public function validate();
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/Util/XmlUtils.php b/vendor/symfony/config/Symfony/Component/Config/Util/XmlUtils.php
new file mode 100644
index 0000000..2ef881d
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/Util/XmlUtils.php
@@ -0,0 +1,238 @@
+<?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\Util;
+
+/**
+ * XMLUtils is a bunch of utility methods to XML operations.
+ *
+ * This class contains static methods only and is not meant to be instantiated.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Martin HasoĊˆ <martin.hason@gmail.com>
+ */
+class XmlUtils
+{
+ /**
+ * This class should not be instantiated.
+ */
+ private function __construct()
+ {
+ }
+
+ /**
+ * Loads an XML file.
+ *
+ * @param string $file An XML file path
+ * @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation
+ *
+ * @return \DOMDocument
+ *
+ * @throws \InvalidArgumentException When loading of XML file returns error
+ */
+ public static function loadFile($file, $schemaOrCallable = null)
+ {
+ $content = @file_get_contents($file);
+ if ('' === trim($content)) {
+ throw new \InvalidArgumentException(sprintf('File %s does not contain valid XML, it is empty.', $file));
+ }
+
+ $internalErrors = libxml_use_internal_errors(true);
+ $disableEntities = libxml_disable_entity_loader(true);
+ libxml_clear_errors();
+
+ $dom = new \DOMDocument();
+ $dom->validateOnParse = true;
+ if (!$dom->loadXML($content, LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) {
+ libxml_disable_entity_loader($disableEntities);
+
+ throw new \InvalidArgumentException(implode("\n", static::getXmlErrors($internalErrors)));
+ }
+
+ $dom->normalizeDocument();
+
+ libxml_use_internal_errors($internalErrors);
+ libxml_disable_entity_loader($disableEntities);
+
+ foreach ($dom->childNodes as $child) {
+ if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
+ throw new \InvalidArgumentException('Document types are not allowed.');
+ }
+ }
+
+ if (null !== $schemaOrCallable) {
+ $internalErrors = libxml_use_internal_errors(true);
+ libxml_clear_errors();
+
+ $e = null;
+ if (is_callable($schemaOrCallable)) {
+ try {
+ $valid = call_user_func($schemaOrCallable, $dom, $internalErrors);
+ } catch (\Exception $e) {
+ $valid = false;
+ }
+ } elseif (!is_array($schemaOrCallable) && is_file((string) $schemaOrCallable)) {
+ $schemaSource = file_get_contents((string) $schemaOrCallable);
+ $valid = @$dom->schemaValidateSource($schemaSource);
+ } else {
+ libxml_use_internal_errors($internalErrors);
+
+ throw new \InvalidArgumentException('The schemaOrCallable argument has to be a valid path to XSD file or callable.');
+ }
+
+ if (!$valid) {
+ $messages = static::getXmlErrors($internalErrors);
+ if (empty($messages)) {
+ $messages = array(sprintf('The XML file "%s" is not valid.', $file));
+ }
+ throw new \InvalidArgumentException(implode("\n", $messages), 0, $e);
+ }
+ }
+
+ libxml_clear_errors();
+ libxml_use_internal_errors($internalErrors);
+
+ return $dom;
+ }
+
+ /**
+ * Converts a \DomElement object to a PHP array.
+ *
+ * The following rules applies during the conversion:
+ *
+ * * Each tag is converted to a key value or an array
+ * if there is more than one "value"
+ *
+ * * The content of a tag is set under a "value" key (<foo>bar</foo>)
+ * if the tag also has some nested tags
+ *
+ * * The attributes are converted to keys (<foo foo="bar"/>)
+ *
+ * * The nested-tags are converted to keys (<foo><foo>bar</foo></foo>)
+ *
+ * @param \DomElement $element A \DomElement instance
+ * @param bool $checkPrefix Check prefix in an element or an attribute name
+ *
+ * @return array A PHP array
+ */
+ public static function convertDomElementToArray(\DomElement $element, $checkPrefix = true)
+ {
+ $prefix = (string) $element->prefix;
+ $empty = true;
+ $config = array();
+ foreach ($element->attributes as $name => $node) {
+ if ($checkPrefix && !in_array((string) $node->prefix, array('', $prefix), true)) {
+ continue;
+ }
+ $config[$name] = static::phpize($node->value);
+ $empty = false;
+ }
+
+ $nodeValue = false;
+ foreach ($element->childNodes as $node) {
+ if ($node instanceof \DOMText) {
+ if ('' !== trim($node->nodeValue)) {
+ $nodeValue = trim($node->nodeValue);
+ $empty = false;
+ }
+ } elseif ($checkPrefix && $prefix != (string) $node->prefix) {
+ continue;
+ } elseif (!$node instanceof \DOMComment) {
+ $value = static::convertDomElementToArray($node, $checkPrefix);
+
+ $key = $node->localName;
+ if (isset($config[$key])) {
+ if (!is_array($config[$key]) || !is_int(key($config[$key]))) {
+ $config[$key] = array($config[$key]);
+ }
+ $config[$key][] = $value;
+ } else {
+ $config[$key] = $value;
+ }
+
+ $empty = false;
+ }
+ }
+
+ if (false !== $nodeValue) {
+ $value = static::phpize($nodeValue);
+ if (count($config)) {
+ $config['value'] = $value;
+ } else {
+ $config = $value;
+ }
+ }
+
+ return !$empty ? $config : null;
+ }
+
+ /**
+ * Converts an xml value to a PHP type.
+ *
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ public static function phpize($value)
+ {
+ $value = (string) $value;
+ $lowercaseValue = strtolower($value);
+
+ switch (true) {
+ case 'null' === $lowercaseValue:
+ return;
+ case ctype_digit($value):
+ $raw = $value;
+ $cast = (int) $value;
+
+ return '0' == $value[0] ? octdec($value) : (((string) $raw === (string) $cast) ? $cast : $raw);
+ case isset($value[1]) && '-' === $value[0] && ctype_digit(substr($value, 1)):
+ $raw = $value;
+ $cast = intval($value);
+
+ return '0' == $value[1] ? octdec($value) : (((string) $raw === (string) $cast) ? $cast : $raw);
+ case 'true' === $lowercaseValue:
+ return true;
+ case 'false' === $lowercaseValue:
+ return false;
+ case isset($value[1]) && '0b' == $value[0].$value[1]:
+ return bindec($value);
+ case is_numeric($value):
+ return '0x' === $value[0].$value[1] ? hexdec($value) : (float) $value;
+ case preg_match('/^0x[0-9a-f]++$/i', $value):
+ return hexdec($value);
+ case preg_match('/^(-|\+)?[0-9]+(\.[0-9]+)?$/', $value):
+ return (float) $value;
+ default:
+ return $value;
+ }
+ }
+
+ protected static function getXmlErrors($internalErrors)
+ {
+ $errors = array();
+ foreach (libxml_get_errors() as $error) {
+ $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
+ LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
+ $error->code,
+ trim($error->message),
+ $error->file ?: 'n/a',
+ $error->line,
+ $error->column
+ );
+ }
+
+ libxml_clear_errors();
+ libxml_use_internal_errors($internalErrors);
+
+ return $errors;
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/composer.json b/vendor/symfony/config/Symfony/Component/Config/composer.json
new file mode 100644
index 0000000..3b2542a
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/composer.json
@@ -0,0 +1,35 @@
+{
+ "name": "symfony/config",
+ "type": "library",
+ "description": "Symfony Config Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3",
+ "symfony/filesystem": "~2.3"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "autoload": {
+ "psr-0": { "Symfony\\Component\\Config\\": "" }
+ },
+ "target-dir": "Symfony/Component/Config",
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ }
+}
diff --git a/vendor/symfony/config/Symfony/Component/Config/phpunit.xml.dist b/vendor/symfony/config/Symfony/Component/Config/phpunit.xml.dist
new file mode 100644
index 0000000..2156534
--- /dev/null
+++ b/vendor/symfony/config/Symfony/Component/Config/phpunit.xml.dist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+ <testsuites>
+ <testsuite name="Symfony Config Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Resources</directory>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>