annotate vendor/symfony/validator/Mapping/Loader/XmlFileLoader.php @ 19:fa3358dc1485 tip

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