Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\Serializer\Mapping\Loader; Chris@0: Chris@0: use Symfony\Component\Serializer\Exception\MappingException; Chris@0: use Symfony\Component\Serializer\Mapping\AttributeMetadata; Chris@0: use Symfony\Component\Serializer\Mapping\ClassMetadataInterface; Chris@0: use Symfony\Component\Yaml\Parser; Chris@0: Chris@0: /** Chris@0: * YAML File Loader. Chris@0: * Chris@0: * @author Kévin Dunglas Chris@0: */ Chris@0: class YamlFileLoader extends FileLoader Chris@0: { Chris@0: private $yamlParser; Chris@0: Chris@0: /** Chris@0: * An array of YAML class descriptions. Chris@0: * Chris@0: * @var array Chris@0: */ Chris@14: private $classes; Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function loadClassMetadata(ClassMetadataInterface $classMetadata) Chris@0: { Chris@0: if (null === $this->classes) { Chris@0: $this->classes = $this->getClassesFromYaml(); Chris@0: } Chris@0: Chris@0: if (!$this->classes) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: if (!isset($this->classes[$classMetadata->getName()])) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: $yaml = $this->classes[$classMetadata->getName()]; Chris@0: Chris@14: if (isset($yaml['attributes']) && \is_array($yaml['attributes'])) { Chris@0: $attributesMetadata = $classMetadata->getAttributesMetadata(); Chris@0: Chris@0: foreach ($yaml['attributes'] as $attribute => $data) { Chris@0: if (isset($attributesMetadata[$attribute])) { Chris@0: $attributeMetadata = $attributesMetadata[$attribute]; Chris@0: } else { Chris@0: $attributeMetadata = new AttributeMetadata($attribute); Chris@0: $classMetadata->addAttributeMetadata($attributeMetadata); Chris@0: } Chris@0: Chris@0: if (isset($data['groups'])) { Chris@14: if (!\is_array($data['groups'])) { Chris@0: throw new MappingException(sprintf('The "groups" key must be an array of strings in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName())); Chris@0: } Chris@0: Chris@0: foreach ($data['groups'] as $group) { Chris@14: if (!\is_string($group)) { Chris@0: throw new MappingException(sprintf('Group names must be strings in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName())); Chris@0: } Chris@0: Chris@0: $attributeMetadata->addGroup($group); Chris@0: } Chris@0: } Chris@0: Chris@0: if (isset($data['max_depth'])) { Chris@17: if (!\is_int($data['max_depth'])) { Chris@0: throw new MappingException(sprintf('The "max_depth" value must be an integer in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName())); Chris@0: } Chris@0: Chris@0: $attributeMetadata->setMaxDepth($data['max_depth']); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: return true; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Return the names of the classes mapped in this file. Chris@0: * Chris@0: * @return string[] The classes names Chris@0: */ Chris@0: public function getMappedClasses() Chris@0: { Chris@0: if (null === $this->classes) { Chris@0: $this->classes = $this->getClassesFromYaml(); Chris@0: } Chris@0: Chris@0: return array_keys($this->classes); Chris@0: } Chris@0: Chris@0: private function getClassesFromYaml() Chris@0: { Chris@0: if (!stream_is_local($this->file)) { Chris@0: throw new MappingException(sprintf('This is not a local file "%s".', $this->file)); Chris@0: } Chris@0: Chris@0: if (null === $this->yamlParser) { Chris@0: $this->yamlParser = new Parser(); Chris@0: } Chris@0: Chris@14: $classes = $this->yamlParser->parseFile($this->file); Chris@0: Chris@0: if (empty($classes)) { Chris@17: return []; Chris@0: } Chris@0: Chris@14: if (!\is_array($classes)) { Chris@0: throw new MappingException(sprintf('The file "%s" must contain a YAML array.', $this->file)); Chris@0: } Chris@0: Chris@0: return $classes; Chris@0: } Chris@0: }