Security update for Core, with self-updated composer
[yaffs-website] / vendor / symfony / validator / ValidatorBuilder.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;
13
14 use Doctrine\Common\Annotations\AnnotationReader;
15 use Doctrine\Common\Annotations\CachedReader;
16 use Doctrine\Common\Annotations\Reader;
17 use Doctrine\Common\Cache\ArrayCache;
18 use Symfony\Component\Translation\IdentityTranslator;
19 use Symfony\Component\Translation\TranslatorInterface;
20 use Symfony\Component\Validator\Context\ExecutionContextFactory;
21 use Symfony\Component\Validator\Exception\ValidatorException;
22 use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
23 use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
24 use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface;
25 use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
26 use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
27 use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
28 use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
29 use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader;
30 use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader;
31 use Symfony\Component\Validator\Validator\RecursiveValidator;
32
33 /**
34  * The default implementation of {@link ValidatorBuilderInterface}.
35  *
36  * @author Bernhard Schussek <bschussek@gmail.com>
37  */
38 class ValidatorBuilder implements ValidatorBuilderInterface
39 {
40     /**
41      * @var array
42      */
43     private $initializers = array();
44
45     /**
46      * @var array
47      */
48     private $xmlMappings = array();
49
50     /**
51      * @var array
52      */
53     private $yamlMappings = array();
54
55     /**
56      * @var array
57      */
58     private $methodMappings = array();
59
60     /**
61      * @var Reader|null
62      */
63     private $annotationReader;
64
65     /**
66      * @var MetadataFactoryInterface|null
67      */
68     private $metadataFactory;
69
70     /**
71      * @var ConstraintValidatorFactoryInterface|null
72      */
73     private $validatorFactory;
74
75     /**
76      * @var CacheInterface|null
77      */
78     private $metadataCache;
79
80     /**
81      * @var TranslatorInterface|null
82      */
83     private $translator;
84
85     /**
86      * @var null|string
87      */
88     private $translationDomain;
89
90     /**
91      * {@inheritdoc}
92      */
93     public function addObjectInitializer(ObjectInitializerInterface $initializer)
94     {
95         $this->initializers[] = $initializer;
96
97         return $this;
98     }
99
100     /**
101      * {@inheritdoc}
102      */
103     public function addObjectInitializers(array $initializers)
104     {
105         $this->initializers = array_merge($this->initializers, $initializers);
106
107         return $this;
108     }
109
110     /**
111      * {@inheritdoc}
112      */
113     public function addXmlMapping($path)
114     {
115         if (null !== $this->metadataFactory) {
116             throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
117         }
118
119         $this->xmlMappings[] = $path;
120
121         return $this;
122     }
123
124     /**
125      * {@inheritdoc}
126      */
127     public function addXmlMappings(array $paths)
128     {
129         if (null !== $this->metadataFactory) {
130             throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
131         }
132
133         $this->xmlMappings = array_merge($this->xmlMappings, $paths);
134
135         return $this;
136     }
137
138     /**
139      * {@inheritdoc}
140      */
141     public function addYamlMapping($path)
142     {
143         if (null !== $this->metadataFactory) {
144             throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
145         }
146
147         $this->yamlMappings[] = $path;
148
149         return $this;
150     }
151
152     /**
153      * {@inheritdoc}
154      */
155     public function addYamlMappings(array $paths)
156     {
157         if (null !== $this->metadataFactory) {
158             throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
159         }
160
161         $this->yamlMappings = array_merge($this->yamlMappings, $paths);
162
163         return $this;
164     }
165
166     /**
167      * {@inheritdoc}
168      */
169     public function addMethodMapping($methodName)
170     {
171         if (null !== $this->metadataFactory) {
172             throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
173         }
174
175         $this->methodMappings[] = $methodName;
176
177         return $this;
178     }
179
180     /**
181      * {@inheritdoc}
182      */
183     public function addMethodMappings(array $methodNames)
184     {
185         if (null !== $this->metadataFactory) {
186             throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
187         }
188
189         $this->methodMappings = array_merge($this->methodMappings, $methodNames);
190
191         return $this;
192     }
193
194     /**
195      * {@inheritdoc}
196      */
197     public function enableAnnotationMapping(Reader $annotationReader = null)
198     {
199         if (null !== $this->metadataFactory) {
200             throw new ValidatorException('You cannot enable annotation mapping after setting a custom metadata factory. Configure your metadata factory instead.');
201         }
202
203         if (null === $annotationReader) {
204             if (!class_exists('Doctrine\Common\Annotations\AnnotationReader') || !class_exists('Doctrine\Common\Cache\ArrayCache')) {
205                 throw new \RuntimeException('Enabling annotation based constraint mapping requires the packages doctrine/annotations and doctrine/cache to be installed.');
206             }
207
208             $annotationReader = new CachedReader(new AnnotationReader(), new ArrayCache());
209         }
210
211         $this->annotationReader = $annotationReader;
212
213         return $this;
214     }
215
216     /**
217      * {@inheritdoc}
218      */
219     public function disableAnnotationMapping()
220     {
221         $this->annotationReader = null;
222
223         return $this;
224     }
225
226     /**
227      * {@inheritdoc}
228      */
229     public function setMetadataFactory(MetadataFactoryInterface $metadataFactory)
230     {
231         if (count($this->xmlMappings) > 0 || count($this->yamlMappings) > 0 || count($this->methodMappings) > 0 || null !== $this->annotationReader) {
232             throw new ValidatorException('You cannot set a custom metadata factory after adding custom mappings. You should do either of both.');
233         }
234
235         $this->metadataFactory = $metadataFactory;
236
237         return $this;
238     }
239
240     /**
241      * {@inheritdoc}
242      */
243     public function setMetadataCache(CacheInterface $cache)
244     {
245         if (null !== $this->metadataFactory) {
246             throw new ValidatorException('You cannot set a custom metadata cache after setting a custom metadata factory. Configure your metadata factory instead.');
247         }
248
249         $this->metadataCache = $cache;
250
251         return $this;
252     }
253
254     /**
255      * {@inheritdoc}
256      */
257     public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory)
258     {
259         $this->validatorFactory = $validatorFactory;
260
261         return $this;
262     }
263
264     /**
265      * {@inheritdoc}
266      */
267     public function setTranslator(TranslatorInterface $translator)
268     {
269         $this->translator = $translator;
270
271         return $this;
272     }
273
274     /**
275      * {@inheritdoc}
276      */
277     public function setTranslationDomain($translationDomain)
278     {
279         $this->translationDomain = $translationDomain;
280
281         return $this;
282     }
283
284     /**
285      * @return LoaderInterface[]
286      */
287     public function getLoaders()
288     {
289         $loaders = array();
290
291         foreach ($this->xmlMappings as $xmlMapping) {
292             $loaders[] = new XmlFileLoader($xmlMapping);
293         }
294
295         foreach ($this->yamlMappings as $yamlMappings) {
296             $loaders[] = new YamlFileLoader($yamlMappings);
297         }
298
299         foreach ($this->methodMappings as $methodName) {
300             $loaders[] = new StaticMethodLoader($methodName);
301         }
302
303         if ($this->annotationReader) {
304             $loaders[] = new AnnotationLoader($this->annotationReader);
305         }
306
307         return $loaders;
308     }
309
310     /**
311      * {@inheritdoc}
312      */
313     public function getValidator()
314     {
315         $metadataFactory = $this->metadataFactory;
316
317         if (!$metadataFactory) {
318             $loaders = $this->getLoaders();
319             $loader = null;
320
321             if (count($loaders) > 1) {
322                 $loader = new LoaderChain($loaders);
323             } elseif (1 === count($loaders)) {
324                 $loader = $loaders[0];
325             }
326
327             $metadataFactory = new LazyLoadingMetadataFactory($loader, $this->metadataCache);
328         }
329
330         $validatorFactory = $this->validatorFactory ?: new ConstraintValidatorFactory();
331         $translator = $this->translator;
332
333         if (null === $translator) {
334             $translator = new IdentityTranslator();
335             // Force the locale to be 'en' when no translator is provided rather than relying on the Intl default locale
336             // This avoids depending on Intl or the stub implementation being available. It also ensures that Symfony
337             // validation messages are pluralized properly even when the default locale gets changed because they are in
338             // English.
339             $translator->setLocale('en');
340         }
341
342         $contextFactory = new ExecutionContextFactory($translator, $this->translationDomain);
343
344         return new RecursiveValidator($contextFactory, $metadataFactory, $validatorFactory, $this->initializers);
345     }
346 }