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