2015-08-17 17:00:26 -07:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Validator\Mapping\Loader ;
use Symfony\Component\Validator\Mapping\ClassMetadata ;
2015-10-08 11:40:12 -07:00
use Symfony\Component\Yaml\Exception\ParseException ;
2015-08-17 17:00:26 -07:00
use Symfony\Component\Yaml\Parser as YamlParser ;
/**
* Loads validation metadata from a YAML file .
*
* @ author Bernhard Schussek < bschussek @ gmail . com >
*/
class YamlFileLoader extends FileLoader
{
/**
* An array of YAML class descriptions .
*
* @ var array
*/
protected $classes = null ;
/**
* Caches the used YAML parser .
*
* @ var YamlParser
*/
private $yamlParser ;
/**
* { @ inheritdoc }
*/
public function loadClassMetadata ( ClassMetadata $metadata )
{
if ( null === $this -> classes ) {
if ( null === $this -> yamlParser ) {
$this -> yamlParser = new YamlParser ();
}
2017-02-02 16:28:38 -08:00
$this -> classes = $this -> parseFile ( $this -> file );
2015-08-17 17:00:26 -07:00
if ( isset ( $this -> classes [ 'namespaces' ])) {
foreach ( $this -> classes [ 'namespaces' ] as $alias => $namespace ) {
$this -> addNamespaceAlias ( $alias , $namespace );
}
unset ( $this -> classes [ 'namespaces' ]);
}
}
if ( isset ( $this -> classes [ $metadata -> getClassName ()])) {
$classDescription = $this -> classes [ $metadata -> getClassName ()];
$this -> loadClassMetadataFromYaml ( $metadata , $classDescription );
return true ;
}
return false ;
}
/**
* Parses a collection of YAML nodes .
*
* @ param array $nodes The YAML nodes
*
* @ return array An array of values or Constraint instances
*/
protected function parseNodes ( array $nodes )
{
$values = array ();
foreach ( $nodes as $name => $childNodes ) {
if ( is_numeric ( $name ) && is_array ( $childNodes ) && 1 === count ( $childNodes )) {
$options = current ( $childNodes );
if ( is_array ( $options )) {
$options = $this -> parseNodes ( $options );
}
$values [] = $this -> newConstraint ( key ( $childNodes ), $options );
} else {
if ( is_array ( $childNodes )) {
$childNodes = $this -> parseNodes ( $childNodes );
}
$values [ $name ] = $childNodes ;
}
}
return $values ;
}
/**
* Loads the YAML class descriptions from the given file .
*
* @ param string $path The path of the YAML file
*
2017-02-02 16:28:38 -08:00
* @ return array The class descriptions
2015-08-17 17:00:26 -07:00
*
* @ throws \InvalidArgumentException If the file could not be loaded or did
* not contain a YAML array
*/
private function parseFile ( $path )
{
2015-10-08 11:40:12 -07:00
try {
$classes = $this -> yamlParser -> parse ( file_get_contents ( $path ));
} catch ( ParseException $e ) {
throw new \InvalidArgumentException ( sprintf ( 'The file "%s" does not contain valid YAML.' , $path ), 0 , $e );
}
2015-08-17 17:00:26 -07:00
// empty file
if ( null === $classes ) {
2017-02-02 16:28:38 -08:00
return array ();
2015-08-17 17:00:26 -07:00
}
// not an array
if ( ! is_array ( $classes )) {
throw new \InvalidArgumentException ( sprintf ( 'The file "%s" must contain a YAML array.' , $this -> file ));
}
return $classes ;
}
/**
* Loads the validation metadata from the given YAML class description .
*
* @ param ClassMetadata $metadata The metadata to load
* @ param array $classDescription The YAML class description
*/
private function loadClassMetadataFromYaml ( ClassMetadata $metadata , array $classDescription )
{
if ( isset ( $classDescription [ 'group_sequence_provider' ])) {
$metadata -> setGroupSequenceProvider (
( bool ) $classDescription [ 'group_sequence_provider' ]
);
}
if ( isset ( $classDescription [ 'group_sequence' ])) {
$metadata -> setGroupSequence ( $classDescription [ 'group_sequence' ]);
}
if ( isset ( $classDescription [ 'constraints' ]) && is_array ( $classDescription [ 'constraints' ])) {
foreach ( $this -> parseNodes ( $classDescription [ 'constraints' ]) as $constraint ) {
$metadata -> addConstraint ( $constraint );
}
}
if ( isset ( $classDescription [ 'properties' ]) && is_array ( $classDescription [ 'properties' ])) {
foreach ( $classDescription [ 'properties' ] as $property => $constraints ) {
if ( null !== $constraints ) {
foreach ( $this -> parseNodes ( $constraints ) as $constraint ) {
$metadata -> addPropertyConstraint ( $property , $constraint );
}
}
}
}
if ( isset ( $classDescription [ 'getters' ]) && is_array ( $classDescription [ 'getters' ])) {
foreach ( $classDescription [ 'getters' ] as $getter => $constraints ) {
if ( null !== $constraints ) {
foreach ( $this -> parseNodes ( $constraints ) as $constraint ) {
$metadata -> addGetterConstraint ( $getter , $constraint );
}
}
}
}
}
}