Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / symfony / validator / Mapping / Loader / YamlFileLoader.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\Validator\Mapping\Loader;
13
14 use Symfony\Component\Validator\Mapping\ClassMetadata;
15 use Symfony\Component\Yaml\Exception\ParseException;
16 use Symfony\Component\Yaml\Parser as YamlParser;
17 use Symfony\Component\Yaml\Yaml;
18
19 /**
20  * Loads validation metadata from a YAML file.
21  *
22  * @author Bernhard Schussek <bschussek@gmail.com>
23  */
24 class YamlFileLoader extends FileLoader
25 {
26     /**
27      * An array of YAML class descriptions.
28      *
29      * @var array
30      */
31     protected $classes = null;
32
33     /**
34      * Caches the used YAML parser.
35      *
36      * @var YamlParser
37      */
38     private $yamlParser;
39
40     /**
41      * {@inheritdoc}
42      */
43     public function loadClassMetadata(ClassMetadata $metadata)
44     {
45         if (null === $this->classes) {
46             $this->loadClassesFromYaml();
47         }
48
49         if (isset($this->classes[$metadata->getClassName()])) {
50             $classDescription = $this->classes[$metadata->getClassName()];
51
52             $this->loadClassMetadataFromYaml($metadata, $classDescription);
53
54             return true;
55         }
56
57         return false;
58     }
59
60     /**
61      * Return the names of the classes mapped in this file.
62      *
63      * @return string[] The classes names
64      */
65     public function getMappedClasses()
66     {
67         if (null === $this->classes) {
68             $this->loadClassesFromYaml();
69         }
70
71         return array_keys($this->classes);
72     }
73
74     /**
75      * Parses a collection of YAML nodes.
76      *
77      * @param array $nodes The YAML nodes
78      *
79      * @return array An array of values or Constraint instances
80      */
81     protected function parseNodes(array $nodes)
82     {
83         $values = array();
84
85         foreach ($nodes as $name => $childNodes) {
86             if (is_numeric($name) && \is_array($childNodes) && 1 === \count($childNodes)) {
87                 $options = current($childNodes);
88
89                 if (\is_array($options)) {
90                     $options = $this->parseNodes($options);
91                 }
92
93                 $values[] = $this->newConstraint(key($childNodes), $options);
94             } else {
95                 if (\is_array($childNodes)) {
96                     $childNodes = $this->parseNodes($childNodes);
97                 }
98
99                 $values[$name] = $childNodes;
100             }
101         }
102
103         return $values;
104     }
105
106     /**
107      * Loads the YAML class descriptions from the given file.
108      *
109      * @param string $path The path of the YAML file
110      *
111      * @return array The class descriptions
112      *
113      * @throws \InvalidArgumentException If the file could not be loaded or did
114      *                                   not contain a YAML array
115      */
116     private function parseFile($path)
117     {
118         $prevErrorHandler = set_error_handler(function ($level, $message, $script, $line) use ($path, &$prevErrorHandler) {
119             $message = E_USER_DEPRECATED === $level ? preg_replace('/ on line \d+/', ' in "'.$path.'"$0', $message) : $message;
120
121             return $prevErrorHandler ? $prevErrorHandler($level, $message, $script, $line) : false;
122         });
123
124         try {
125             $classes = $this->yamlParser->parseFile($path, Yaml::PARSE_CONSTANT);
126         } catch (ParseException $e) {
127             throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e);
128         } finally {
129             restore_error_handler();
130         }
131
132         // empty file
133         if (null === $classes) {
134             return array();
135         }
136
137         // not an array
138         if (!\is_array($classes)) {
139             throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $this->file));
140         }
141
142         return $classes;
143     }
144
145     private function loadClassesFromYaml()
146     {
147         if (null === $this->yamlParser) {
148             $this->yamlParser = new YamlParser();
149         }
150
151         $this->classes = $this->parseFile($this->file);
152
153         if (isset($this->classes['namespaces'])) {
154             foreach ($this->classes['namespaces'] as $alias => $namespace) {
155                 $this->addNamespaceAlias($alias, $namespace);
156             }
157
158             unset($this->classes['namespaces']);
159         }
160     }
161
162     private function loadClassMetadataFromYaml(ClassMetadata $metadata, array $classDescription)
163     {
164         if (isset($classDescription['group_sequence_provider'])) {
165             $metadata->setGroupSequenceProvider(
166                 (bool) $classDescription['group_sequence_provider']
167             );
168         }
169
170         if (isset($classDescription['group_sequence'])) {
171             $metadata->setGroupSequence($classDescription['group_sequence']);
172         }
173
174         if (isset($classDescription['constraints']) && \is_array($classDescription['constraints'])) {
175             foreach ($this->parseNodes($classDescription['constraints']) as $constraint) {
176                 $metadata->addConstraint($constraint);
177             }
178         }
179
180         if (isset($classDescription['properties']) && \is_array($classDescription['properties'])) {
181             foreach ($classDescription['properties'] as $property => $constraints) {
182                 if (null !== $constraints) {
183                     foreach ($this->parseNodes($constraints) as $constraint) {
184                         $metadata->addPropertyConstraint($property, $constraint);
185                     }
186                 }
187             }
188         }
189
190         if (isset($classDescription['getters']) && \is_array($classDescription['getters'])) {
191             foreach ($classDescription['getters'] as $getter => $constraints) {
192                 if (null !== $constraints) {
193                     foreach ($this->parseNodes($constraints) as $constraint) {
194                         $metadata->addGetterConstraint($getter, $constraint);
195                     }
196                 }
197             }
198         }
199     }
200 }