comparison vendor/symfony/validator/Mapping/Loader/XmlFileLoader.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 129ea1e6d783
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
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\Config\Util\XmlUtils;
15 use Symfony\Component\Validator\Exception\MappingException;
16 use Symfony\Component\Validator\Mapping\ClassMetadata;
17
18 /**
19 * Loads validation metadata from an XML file.
20 *
21 * @author Bernhard Schussek <bschussek@gmail.com>
22 */
23 class XmlFileLoader extends FileLoader
24 {
25 /**
26 * The XML nodes of the mapping file.
27 *
28 * @var \SimpleXMLElement[]|null
29 */
30 protected $classes;
31
32 /**
33 * {@inheritdoc}
34 */
35 public function loadClassMetadata(ClassMetadata $metadata)
36 {
37 if (null === $this->classes) {
38 $this->loadClassesFromXml();
39 }
40
41 if (isset($this->classes[$metadata->getClassName()])) {
42 $classDescription = $this->classes[$metadata->getClassName()];
43
44 $this->loadClassMetadataFromXml($metadata, $classDescription);
45
46 return true;
47 }
48
49 return false;
50 }
51
52 /**
53 * Return the names of the classes mapped in this file.
54 *
55 * @return string[] The classes names
56 */
57 public function getMappedClasses()
58 {
59 if (null === $this->classes) {
60 $this->loadClassesFromXml();
61 }
62
63 return array_keys($this->classes);
64 }
65
66 /**
67 * Parses a collection of "constraint" XML nodes.
68 *
69 * @param \SimpleXMLElement $nodes The XML nodes
70 *
71 * @return array The Constraint instances
72 */
73 protected function parseConstraints(\SimpleXMLElement $nodes)
74 {
75 $constraints = array();
76
77 foreach ($nodes as $node) {
78 if (count($node) > 0) {
79 if (count($node->value) > 0) {
80 $options = $this->parseValues($node->value);
81 } elseif (count($node->constraint) > 0) {
82 $options = $this->parseConstraints($node->constraint);
83 } elseif (count($node->option) > 0) {
84 $options = $this->parseOptions($node->option);
85 } else {
86 $options = array();
87 }
88 } elseif (strlen((string) $node) > 0) {
89 $options = XmlUtils::phpize(trim($node));
90 } else {
91 $options = null;
92 }
93
94 $constraints[] = $this->newConstraint((string) $node['name'], $options);
95 }
96
97 return $constraints;
98 }
99
100 /**
101 * Parses a collection of "value" XML nodes.
102 *
103 * @param \SimpleXMLElement $nodes The XML nodes
104 *
105 * @return array The values
106 */
107 protected function parseValues(\SimpleXMLElement $nodes)
108 {
109 $values = array();
110
111 foreach ($nodes as $node) {
112 if (count($node) > 0) {
113 if (count($node->value) > 0) {
114 $value = $this->parseValues($node->value);
115 } elseif (count($node->constraint) > 0) {
116 $value = $this->parseConstraints($node->constraint);
117 } else {
118 $value = array();
119 }
120 } else {
121 $value = trim($node);
122 }
123
124 if (isset($node['key'])) {
125 $values[(string) $node['key']] = $value;
126 } else {
127 $values[] = $value;
128 }
129 }
130
131 return $values;
132 }
133
134 /**
135 * Parses a collection of "option" XML nodes.
136 *
137 * @param \SimpleXMLElement $nodes The XML nodes
138 *
139 * @return array The options
140 */
141 protected function parseOptions(\SimpleXMLElement $nodes)
142 {
143 $options = array();
144
145 foreach ($nodes as $node) {
146 if (count($node) > 0) {
147 if (count($node->value) > 0) {
148 $value = $this->parseValues($node->value);
149 } elseif (count($node->constraint) > 0) {
150 $value = $this->parseConstraints($node->constraint);
151 } else {
152 $value = array();
153 }
154 } else {
155 $value = XmlUtils::phpize($node);
156 if (is_string($value)) {
157 $value = trim($value);
158 }
159 }
160
161 $options[(string) $node['name']] = $value;
162 }
163
164 return $options;
165 }
166
167 /**
168 * Loads the XML class descriptions from the given file.
169 *
170 * @param string $path The path of the XML file
171 *
172 * @return \SimpleXMLElement The class descriptions
173 *
174 * @throws MappingException If the file could not be loaded
175 */
176 protected function parseFile($path)
177 {
178 try {
179 $dom = XmlUtils::loadFile($path, __DIR__.'/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd');
180 } catch (\Exception $e) {
181 throw new MappingException($e->getMessage(), $e->getCode(), $e);
182 }
183
184 return simplexml_import_dom($dom);
185 }
186
187 private function loadClassesFromXml()
188 {
189 // This method may throw an exception. Do not modify the class'
190 // state before it completes
191 $xml = $this->parseFile($this->file);
192
193 $this->classes = array();
194
195 foreach ($xml->namespace as $namespace) {
196 $this->addNamespaceAlias((string) $namespace['prefix'], trim((string) $namespace));
197 }
198
199 foreach ($xml->class as $class) {
200 $this->classes[(string) $class['name']] = $class;
201 }
202 }
203
204 private function loadClassMetadataFromXml(ClassMetadata $metadata, \SimpleXMLElement $classDescription)
205 {
206 if (count($classDescription->{'group-sequence-provider'}) > 0) {
207 $metadata->setGroupSequenceProvider(true);
208 }
209
210 foreach ($classDescription->{'group-sequence'} as $groupSequence) {
211 if (count($groupSequence->value) > 0) {
212 $metadata->setGroupSequence($this->parseValues($groupSequence[0]->value));
213 }
214 }
215
216 foreach ($this->parseConstraints($classDescription->constraint) as $constraint) {
217 $metadata->addConstraint($constraint);
218 }
219
220 foreach ($classDescription->property as $property) {
221 foreach ($this->parseConstraints($property->constraint) as $constraint) {
222 $metadata->addPropertyConstraint((string) $property['name'], $constraint);
223 }
224 }
225
226 foreach ($classDescription->getter as $getter) {
227 foreach ($this->parseConstraints($getter->constraint) as $constraint) {
228 $metadata->addGetterConstraint((string) $getter['property'], $constraint);
229 }
230 }
231 }
232 }