Version 1
[yaffs-website] / vendor / symfony / validator / Mapping / Loader / YamlFileLoader.php
diff --git a/vendor/symfony/validator/Mapping/Loader/YamlFileLoader.php b/vendor/symfony/validator/Mapping/Loader/YamlFileLoader.php
new file mode 100644 (file)
index 0000000..1621283
--- /dev/null
@@ -0,0 +1,178 @@
+<?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\Validator\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Parser as YamlParser;
+
+/**
+ * Loads validation metadata from a YAML file.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class YamlFileLoader extends FileLoader
+{
+    /**
+     * An array of YAML class descriptions.
+     *
+     * @var array
+     */
+    protected $classes = null;
+
+    /**
+     * Caches the used YAML parser.
+     *
+     * @var YamlParser
+     */
+    private $yamlParser;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadClassMetadata(ClassMetadata $metadata)
+    {
+        if (null === $this->classes) {
+            if (null === $this->yamlParser) {
+                $this->yamlParser = new YamlParser();
+            }
+
+            $this->classes = $this->parseFile($this->file);
+
+            if (isset($this->classes['namespaces'])) {
+                foreach ($this->classes['namespaces'] as $alias => $namespace) {
+                    $this->addNamespaceAlias($alias, $namespace);
+                }
+
+                unset($this->classes['namespaces']);
+            }
+        }
+
+        if (isset($this->classes[$metadata->getClassName()])) {
+            $classDescription = $this->classes[$metadata->getClassName()];
+
+            $this->loadClassMetadataFromYaml($metadata, $classDescription);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parses a collection of YAML nodes.
+     *
+     * @param array $nodes The YAML nodes
+     *
+     * @return array An array of values or Constraint instances
+     */
+    protected function parseNodes(array $nodes)
+    {
+        $values = array();
+
+        foreach ($nodes as $name => $childNodes) {
+            if (is_numeric($name) && is_array($childNodes) && 1 === count($childNodes)) {
+                $options = current($childNodes);
+
+                if (is_array($options)) {
+                    $options = $this->parseNodes($options);
+                }
+
+                $values[] = $this->newConstraint(key($childNodes), $options);
+            } else {
+                if (is_array($childNodes)) {
+                    $childNodes = $this->parseNodes($childNodes);
+                }
+
+                $values[$name] = $childNodes;
+            }
+        }
+
+        return $values;
+    }
+
+    /**
+     * Loads the YAML class descriptions from the given file.
+     *
+     * @param string $path The path of the YAML file
+     *
+     * @return array The class descriptions
+     *
+     * @throws \InvalidArgumentException If the file could not be loaded or did
+     *                                   not contain a YAML array
+     */
+    private function parseFile($path)
+    {
+        try {
+            $classes = $this->yamlParser->parse(file_get_contents($path));
+        } catch (ParseException $e) {
+            throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e);
+        }
+
+        // empty file
+        if (null === $classes) {
+            return array();
+        }
+
+        // not an array
+        if (!is_array($classes)) {
+            throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $this->file));
+        }
+
+        return $classes;
+    }
+
+    /**
+     * Loads the validation metadata from the given YAML class description.
+     *
+     * @param ClassMetadata $metadata         The metadata to load
+     * @param array         $classDescription The YAML class description
+     */
+    private function loadClassMetadataFromYaml(ClassMetadata $metadata, array $classDescription)
+    {
+        if (isset($classDescription['group_sequence_provider'])) {
+            $metadata->setGroupSequenceProvider(
+                (bool) $classDescription['group_sequence_provider']
+            );
+        }
+
+        if (isset($classDescription['group_sequence'])) {
+            $metadata->setGroupSequence($classDescription['group_sequence']);
+        }
+
+        if (isset($classDescription['constraints']) && is_array($classDescription['constraints'])) {
+            foreach ($this->parseNodes($classDescription['constraints']) as $constraint) {
+                $metadata->addConstraint($constraint);
+            }
+        }
+
+        if (isset($classDescription['properties']) && is_array($classDescription['properties'])) {
+            foreach ($classDescription['properties'] as $property => $constraints) {
+                if (null !== $constraints) {
+                    foreach ($this->parseNodes($constraints) as $constraint) {
+                        $metadata->addPropertyConstraint($property, $constraint);
+                    }
+                }
+            }
+        }
+
+        if (isset($classDescription['getters']) && is_array($classDescription['getters'])) {
+            foreach ($classDescription['getters'] as $getter => $constraints) {
+                if (null !== $constraints) {
+                    foreach ($this->parseNodes($constraints) as $constraint) {
+                        $metadata->addGetterConstraint($getter, $constraint);
+                    }
+                }
+            }
+        }
+    }
+}