feature #13795 [Serializer] Refactoring of metadata (dunglas)
This PR was merged into the 2.7 branch.
Discussion
----------
[Serializer] Refactoring of metadata
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no (the metadata system will be introduced in 2.7)
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | n/a
| License | MIT
| Doc PR | n/a
* Add an interface for `ClassMetadata` and `ClassMetadataFactory`
* Add a new `AttributeMetadata` and the corresponding interface to ease add of future features (e.g. type support for deserialization) and to allow custom metadata implementations (e.g. description of an attribute for an hypermedia normalizer - my use case)
* Add tests for news features
* Add new tests for exsiting features
Commits
-------
8534505
[Serializer] Refactoring of metadata
This commit is contained in:
commit
ff70902dcb
@ -0,0 +1,94 @@
|
||||
<?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\Serializer\Mapping;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class AttributeMetadata implements AttributeMetadataInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @internal This property is public in order to reduce the size of the
|
||||
* class' serialized representation. Do not access it. Use
|
||||
* {@link getName()} instead.
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @internal This property is public in order to reduce the size of the
|
||||
* class' serialized representation. Do not access it. Use
|
||||
* {@link getGroups()} instead.
|
||||
*/
|
||||
public $groups = array();
|
||||
|
||||
/**
|
||||
* Constructs a metadata for the given attribute.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addGroup($group)
|
||||
{
|
||||
if (!in_array($group, $this->groups)) {
|
||||
$this->groups[] = $group;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getGroups()
|
||||
{
|
||||
return $this->groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function merge(AttributeMetadataInterface $attributeMetadata)
|
||||
{
|
||||
foreach ($attributeMetadata->getGroups() as $group) {
|
||||
$this->addGroup($group);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of the properties that should be serialized.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
return array('name', 'groups');
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
<?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\Serializer\Mapping;
|
||||
|
||||
/**
|
||||
* Stores metadata needed for serializing and deserializing attributes.
|
||||
*
|
||||
* Primarily, the metadata stores serialization groups.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface AttributeMetadataInterface
|
||||
{
|
||||
/**
|
||||
* Gets the attribute name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Adds this attribute to the given group.
|
||||
*
|
||||
* @param string $group
|
||||
*/
|
||||
public function addGroup($group);
|
||||
|
||||
/**
|
||||
* Gets groups of this attribute.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getGroups();
|
||||
|
||||
/**
|
||||
* Merges an {@see AttributeMetadataInterface} with in the current one.
|
||||
*
|
||||
* @param AttributeMetadataInterface $attributeMetadata
|
||||
*/
|
||||
public function merge(AttributeMetadataInterface $attributeMetadata);
|
||||
}
|
@ -12,31 +12,29 @@
|
||||
namespace Symfony\Component\Serializer\Mapping;
|
||||
|
||||
/**
|
||||
* Stores all metadata needed for serializing objects of specific class.
|
||||
*
|
||||
* Primarily, the metadata stores serialization groups.
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ClassMetadata
|
||||
class ClassMetadata implements ClassMetadataInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @internal This property is public in order to reduce the size of the
|
||||
* class' serialized representation. Do not access it. Use
|
||||
* {@link getClassName()} instead.
|
||||
* {@link getName()} instead.
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var AttributeMetadataInterface[]
|
||||
*
|
||||
* @internal This property is public in order to reduce the size of the
|
||||
* class' serialized representation. Do not access it. Use
|
||||
* {@link getGroups()} instead.
|
||||
* {@link getAttributesMetadata()} instead.
|
||||
*/
|
||||
public $attributesGroups = array();
|
||||
public $attributesMetadata = array();
|
||||
|
||||
/**
|
||||
* @var \ReflectionClass
|
||||
@ -54,66 +52,50 @@ class ClassMetadata
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the backing PHP class.
|
||||
*
|
||||
* @return string The name of the backing class.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getClassName()
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets serialization groups.
|
||||
*
|
||||
* @return array
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAttributesGroups()
|
||||
public function addAttributeMetadata(AttributeMetadataInterface $attributeMetadata)
|
||||
{
|
||||
return $this->attributesGroups;
|
||||
$this->attributesMetadata[$attributeMetadata->getName()] = $attributeMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an attribute to a serialization group
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string $group
|
||||
* @throws \InvalidArgumentException
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addAttributeGroup($attribute, $group)
|
||||
public function getAttributesMetadata()
|
||||
{
|
||||
if (!is_string($attribute) || !is_string($group)) {
|
||||
throw new \InvalidArgumentException('Arguments must be strings.');
|
||||
}
|
||||
|
||||
if (!isset($this->groups[$group]) || !in_array($attribute, $this->attributesGroups[$group])) {
|
||||
$this->attributesGroups[$group][] = $attribute;
|
||||
}
|
||||
return $this->attributesMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges attributes' groups.
|
||||
*
|
||||
* @param ClassMetadata $classMetadata
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function mergeAttributesGroups(ClassMetadata $classMetadata)
|
||||
public function merge(ClassMetadataInterface $classMetadata)
|
||||
{
|
||||
foreach ($classMetadata->getAttributesGroups() as $group => $attributes) {
|
||||
foreach ($attributes as $attribute) {
|
||||
$this->addAttributeGroup($attribute, $group);
|
||||
foreach ($classMetadata->getAttributesMetadata() as $attributeMetadata) {
|
||||
if (isset($this->attributesMetadata[$attributeMetadata->getName()])) {
|
||||
$this->attributesMetadata[$attributeMetadata->getName()]->merge($attributeMetadata);
|
||||
} else {
|
||||
$this->addAttributeMetadata($attributeMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ReflectionClass instance for this class.
|
||||
*
|
||||
* @return \ReflectionClass
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getReflectionClass()
|
||||
{
|
||||
if (!$this->reflClass) {
|
||||
$this->reflClass = new \ReflectionClass($this->getClassName());
|
||||
$this->reflClass = new \ReflectionClass($this->getName());
|
||||
}
|
||||
|
||||
return $this->reflClass;
|
||||
@ -128,7 +110,7 @@ class ClassMetadata
|
||||
{
|
||||
return array(
|
||||
'name',
|
||||
'attributesGroups',
|
||||
'attributes',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,57 @@
|
||||
<?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\Serializer\Mapping;
|
||||
|
||||
/**
|
||||
* Stores metadata needed for serializing and deserializing objects of specific class.
|
||||
*
|
||||
* Primarily, the metadata stores the list of attributes to serialize or deserialize.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface ClassMetadataInterface
|
||||
{
|
||||
/**
|
||||
* Returns the name of the backing PHP class.
|
||||
*
|
||||
* @return string The name of the backing class.
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Adds an {@link AttributeMetadataInterface}.
|
||||
*
|
||||
* @param AttributeMetadataInterface $attributeMetadata
|
||||
*/
|
||||
public function addAttributeMetadata(AttributeMetadataInterface $attributeMetadata);
|
||||
|
||||
/**
|
||||
* Gets the list of {@link AttributeMetadataInterface}.
|
||||
*
|
||||
* @return AttributeMetadataInterface[]
|
||||
*/
|
||||
public function getAttributesMetadata();
|
||||
|
||||
/**
|
||||
* Merges a {@link ClassMetadataInterface} in the current one.
|
||||
*
|
||||
* @param ClassMetadataInterface $classMetadata
|
||||
*/
|
||||
public function merge(ClassMetadataInterface $classMetadata);
|
||||
|
||||
/**
|
||||
* Returns a {@link \ReflectionClass} instance for this class.
|
||||
*
|
||||
* @return \ReflectionClass
|
||||
*/
|
||||
public function getReflectionClass();
|
||||
}
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Serializer\Mapping\Factory;
|
||||
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface;
|
||||
|
||||
@ -20,7 +21,7 @@ use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface;
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ClassMetadataFactory
|
||||
class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @var LoaderInterface
|
||||
@ -46,29 +47,13 @@ class ClassMetadataFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* If the method was called with the same class name (or an object of that
|
||||
* class) before, the same metadata instance is returned.
|
||||
*
|
||||
* If the factory was configured with a cache, this method will first look
|
||||
* for an existing metadata instance in the cache. If an existing instance
|
||||
* is found, it will be returned without further ado.
|
||||
*
|
||||
* Otherwise, a new metadata instance is created. If the factory was
|
||||
* configured with a loader, the metadata is passed to the
|
||||
* {@link LoaderInterface::loadClassMetadata()} method for further
|
||||
* configuration. At last, the new object is returned.
|
||||
*
|
||||
* @param string|object $value
|
||||
*
|
||||
* @return ClassMetadata
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadataFor($value)
|
||||
{
|
||||
$class = $this->getClass($value);
|
||||
if (!$class) {
|
||||
throw new \InvalidArgumentException(sprintf('Cannot create metadata for non-objects. Got: %s', gettype($value)));
|
||||
throw new InvalidArgumentException(sprintf('Cannot create metadata for non-objects. Got: "%s"', gettype($value)));
|
||||
}
|
||||
|
||||
if (isset($this->loadedClasses[$class])) {
|
||||
@ -80,40 +65,33 @@ class ClassMetadataFactory
|
||||
}
|
||||
|
||||
if (!class_exists($class) && !interface_exists($class)) {
|
||||
throw new \InvalidArgumentException(sprintf('The class or interface "%s" does not exist.', $class));
|
||||
throw new InvalidArgumentException(sprintf('The class or interface "%s" does not exist.', $class));
|
||||
}
|
||||
|
||||
$metadata = new ClassMetadata($class);
|
||||
$classMetadata = new ClassMetadata($class);
|
||||
$this->loader->loadClassMetadata($classMetadata);
|
||||
|
||||
$reflClass = $metadata->getReflectionClass();
|
||||
$reflectionClass = $classMetadata->getReflectionClass();
|
||||
|
||||
// Include groups from the parent class
|
||||
if ($parent = $reflClass->getParentClass()) {
|
||||
$metadata->mergeAttributesGroups($this->getMetadataFor($parent->name));
|
||||
// Include metadata from the parent class
|
||||
if ($parent = $reflectionClass->getParentClass()) {
|
||||
$classMetadata->merge($this->getMetadataFor($parent->name));
|
||||
}
|
||||
|
||||
// Include groups from all implemented interfaces
|
||||
foreach ($reflClass->getInterfaces() as $interface) {
|
||||
$metadata->mergeAttributesGroups($this->getMetadataFor($interface->name));
|
||||
}
|
||||
|
||||
if ($this->loader) {
|
||||
$this->loader->loadClassMetadata($metadata);
|
||||
// Include metadata from all implemented interfaces
|
||||
foreach ($reflectionClass->getInterfaces() as $interface) {
|
||||
$classMetadata->merge($this->getMetadataFor($interface->name));
|
||||
}
|
||||
|
||||
if ($this->cache) {
|
||||
$this->cache->save($class, $metadata);
|
||||
$this->cache->save($class, $classMetadata);
|
||||
}
|
||||
|
||||
return $this->loadedClasses[$class] = $metadata;
|
||||
return $this->loadedClasses[$class] = $classMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if class has metadata.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasMetadataFor($value)
|
||||
{
|
||||
|
@ -0,0 +1,53 @@
|
||||
<?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\Serializer\Mapping\Factory;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Returns a {@see ClassMetadataInterface}.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface ClassMetadataFactoryInterface
|
||||
{
|
||||
/**
|
||||
* If the method was called with the same class name (or an object of that
|
||||
* class) before, the same metadata instance is returned.
|
||||
*
|
||||
* If the factory was configured with a cache, this method will first look
|
||||
* for an existing metadata instance in the cache. If an existing instance
|
||||
* is found, it will be returned without further ado.
|
||||
*
|
||||
* Otherwise, a new metadata instance is created. If the factory was
|
||||
* configured with a loader, the metadata is passed to the
|
||||
* {@link LoaderInterface::loadClassMetadata()} method for further
|
||||
* configuration. At last, the new object is returned.
|
||||
*
|
||||
* @param string|object $value
|
||||
*
|
||||
* @return ClassMetadataInterface
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getMetadataFor($value);
|
||||
|
||||
/**
|
||||
* Checks if class has metadata.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasMetadataFor($value);
|
||||
}
|
@ -14,7 +14,8 @@ namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||
use Doctrine\Common\Annotations\Reader;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Annotation loader.
|
||||
@ -39,18 +40,25 @@ class AnnotationLoader implements LoaderInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadClassMetadata(ClassMetadata $metadata)
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata)
|
||||
{
|
||||
$reflClass = $metadata->getReflectionClass();
|
||||
$className = $reflClass->name;
|
||||
$reflectionClass = $classMetadata->getReflectionClass();
|
||||
$className = $reflectionClass->name;
|
||||
$loaded = false;
|
||||
|
||||
foreach ($reflClass->getProperties() as $property) {
|
||||
if ($property->getDeclaringClass()->name === $className) {
|
||||
$attributesMetadata = $classMetadata->getAttributesMetadata();
|
||||
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
if (!isset($attributeMetadata[$property->name])) {
|
||||
$attributesMetadata[$property->name] = new AttributeMetadata($property->name);
|
||||
$classMetadata->addAttributeMetadata($attributesMetadata[$property->name]);
|
||||
}
|
||||
|
||||
if ($property->getDeclaringClass()->name == $className) {
|
||||
foreach ($this->reader->getPropertyAnnotations($property) as $groups) {
|
||||
if ($groups instanceof Groups) {
|
||||
foreach ($groups->getGroups() as $group) {
|
||||
$metadata->addAttributeGroup($property->name, $group);
|
||||
$attributesMetadata[$property->name]->addGroup($group);
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,13 +67,22 @@ class AnnotationLoader implements LoaderInterface
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($reflClass->getMethods() as $method) {
|
||||
if ($method->getDeclaringClass()->name === $className) {
|
||||
foreach ($reflectionClass->getMethods() as $method) {
|
||||
if ($method->getDeclaringClass()->name == $className) {
|
||||
foreach ($this->reader->getMethodAnnotations($method) as $groups) {
|
||||
if ($groups instanceof Groups) {
|
||||
if (preg_match('/^(get|is)(.+)$/i', $method->name, $matches)) {
|
||||
$attributeName = lcfirst($matches[2]);
|
||||
|
||||
if (isset($attributesMetadata[$attributeName])) {
|
||||
$attributeMetadata = $attributesMetadata[$attributeName];
|
||||
} else {
|
||||
$attributesMetadata[$attributeName] = $attributeMetadata = new AttributeMetadata($attributeName);
|
||||
$classMetadata->addAttributeMetadata($attributeMetadata);
|
||||
}
|
||||
|
||||
foreach ($groups->getGroups() as $group) {
|
||||
$metadata->addAttributeGroup(lcfirst($matches[2]), $group);
|
||||
$attributeMetadata->addGroup($group);
|
||||
}
|
||||
} else {
|
||||
throw new MappingException(sprintf('Groups on "%s::%s" cannot be added. Groups can only be added on methods beginning with "get" or "is".', $className, $method->name));
|
||||
|
@ -13,8 +13,16 @@ namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
|
||||
/**
|
||||
* Base class for all file based loaders.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
abstract class FileLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
@ -22,8 +30,7 @@ abstract class FileLoader implements LoaderInterface
|
||||
*
|
||||
* @param string $file The mapping file to load
|
||||
*
|
||||
* @throws MappingException if the mapping file does not exist
|
||||
* @throws MappingException if the mapping file is not readable
|
||||
* @throws MappingException if the mapping file does not exist or is not readable
|
||||
*/
|
||||
public function __construct($file)
|
||||
{
|
||||
|
@ -12,24 +12,28 @@
|
||||
namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Calls multiple LoaderInterface instances in a chain
|
||||
* Calls multiple {@link LoaderInterface} instances in a chain.
|
||||
*
|
||||
* This class accepts multiple instances of LoaderInterface to be passed to the
|
||||
* constructor. When loadClassMetadata() is called, the same method is called
|
||||
* constructor. When {@link loadClassMetadata()} is called, the same method is called
|
||||
* in <em>all</em> of these loaders, regardless of whether any of them was
|
||||
* successful or not.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class LoaderChain implements LoaderInterface
|
||||
{
|
||||
protected $loaders;
|
||||
/**
|
||||
* @var LoaderInterface[]
|
||||
*/
|
||||
private $loaders;
|
||||
|
||||
/**
|
||||
* Accepts a list of LoaderInterface instances
|
||||
* Accepts a list of LoaderInterface instances.
|
||||
*
|
||||
* @param LoaderInterface[] $loaders An array of LoaderInterface instances
|
||||
*
|
||||
@ -49,7 +53,7 @@ class LoaderChain implements LoaderInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadClassMetadata(ClassMetadata $metadata)
|
||||
public function loadClassMetadata(ClassMetadataInterface $metadata)
|
||||
{
|
||||
$success = false;
|
||||
|
||||
|
@ -11,10 +11,10 @@
|
||||
|
||||
namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Loads class metadata.
|
||||
* Loads {@link ClassMetadataInterface}.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
@ -23,9 +23,9 @@ interface LoaderInterface
|
||||
/**
|
||||
* Load class metadata.
|
||||
*
|
||||
* @param ClassMetadata $metadata A metadata
|
||||
* @param ClassMetadataInterface $classMetadata A metadata
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function loadClassMetadata(ClassMetadata $metadata);
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata);
|
||||
}
|
||||
|
@ -13,7 +13,8 @@ namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||
|
||||
use Symfony\Component\Config\Util\XmlUtils;
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Loads XML mapping files.
|
||||
@ -23,7 +24,7 @@ use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
class XmlFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* An array of SimpleXMLElement instances.
|
||||
* An array of {@class \SimpleXMLElement} instances.
|
||||
*
|
||||
* @var \SimpleXMLElement[]|null
|
||||
*/
|
||||
@ -32,7 +33,7 @@ class XmlFileLoader extends FileLoader
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadClassMetadata(ClassMetadata $metadata)
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata)
|
||||
{
|
||||
if (null === $this->classes) {
|
||||
$this->classes = array();
|
||||
@ -43,12 +44,23 @@ class XmlFileLoader extends FileLoader
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->classes[$metadata->getClassName()])) {
|
||||
$xml = $this->classes[$metadata->getClassName()];
|
||||
$attributesMetadata = $classMetadata->getAttributesMetadata();
|
||||
|
||||
if (isset($this->classes[$classMetadata->getName()])) {
|
||||
$xml = $this->classes[$classMetadata->getName()];
|
||||
|
||||
foreach ($xml->attribute as $attribute) {
|
||||
$attributeName = (string) $attribute['name'];
|
||||
|
||||
if (isset($attributesMetadata[$attributeName])) {
|
||||
$attributeMetadata = $attributesMetadata[$attributeName];
|
||||
} else {
|
||||
$attributeMetadata = new AttributeMetadata($attributeName);
|
||||
$classMetadata->addAttributeMetadata($attributeMetadata);
|
||||
}
|
||||
|
||||
foreach ($attribute->group as $group) {
|
||||
$metadata->addAttributeGroup((string) $attribute['name'], (string) $group);
|
||||
$attributeMetadata->addGroup((string) $group);
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +71,7 @@ class XmlFileLoader extends FileLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a XML File.
|
||||
* Parses a XML File.
|
||||
*
|
||||
* @param string $file Path of file
|
||||
*
|
||||
|
@ -12,11 +12,12 @@
|
||||
namespace Symfony\Component\Serializer\Mapping\Loader;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
|
||||
/**
|
||||
* YAML File Loader
|
||||
* YAML File Loader.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
@ -34,7 +35,7 @@ class YamlFileLoader extends FileLoader
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadClassMetadata(ClassMetadata $metadata)
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata)
|
||||
{
|
||||
if (null === $this->classes) {
|
||||
if (!stream_is_local($this->file)) {
|
||||
@ -59,14 +60,22 @@ class YamlFileLoader extends FileLoader
|
||||
$this->classes = $classes;
|
||||
}
|
||||
|
||||
if (isset($this->classes[$metadata->getClassName()])) {
|
||||
$yaml = $this->classes[$metadata->getClassName()];
|
||||
if (isset($this->classes[$classMetadata->getName()])) {
|
||||
$yaml = $this->classes[$classMetadata->getName()];
|
||||
|
||||
if (isset($yaml['attributes']) && is_array($yaml['attributes'])) {
|
||||
$attributesMetadata = $classMetadata->getAttributesMetadata();
|
||||
foreach ($yaml['attributes'] as $attribute => $data) {
|
||||
if (isset($attributesMetadata[$attribute])) {
|
||||
$attributeMetadata = $attributesMetadata[$attribute];
|
||||
} else {
|
||||
$attributeMetadata = new AttributeMetadata($attribute);
|
||||
$classMetadata->addAttributeMetadata($attributeMetadata);
|
||||
}
|
||||
|
||||
if (isset($data['groups'])) {
|
||||
foreach ($data['groups'] as $group) {
|
||||
$metadata->addAttributeGroup($attribute, $group);
|
||||
$attributeMetadata->addGroup($group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ use Symfony\Component\Serializer\Exception\CircularReferenceException;
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Serializer\Exception\LogicException;
|
||||
use Symfony\Component\Serializer\Exception\RuntimeException;
|
||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
|
||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
|
||||
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
|
||||
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
||||
|
||||
@ -26,21 +27,42 @@ use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
||||
*/
|
||||
abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $circularReferenceLimit = 1;
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $circularReferenceHandler;
|
||||
/**
|
||||
* @var ClassMetadataFactoryInterface|null
|
||||
*/
|
||||
protected $classMetadataFactory;
|
||||
/**
|
||||
* @var NameConverterInterface|null
|
||||
*/
|
||||
protected $nameConverter;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $callbacks = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $ignoredAttributes = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $camelizedAttributes = array();
|
||||
|
||||
/**
|
||||
* Sets the {@link ClassMetadataFactory} to use.
|
||||
* Sets the {@link ClassMetadataFactoryInterface} to use.
|
||||
*
|
||||
* @param ClassMetadataFactory|null $classMetadataFactory
|
||||
* @param ClassMetadataFactoryInterface|null $classMetadataFactory
|
||||
* @param NameConverterInterface|null $nameConverter
|
||||
*/
|
||||
public function __construct(ClassMetadataFactory $classMetadataFactory = null, NameConverterInterface $nameConverter = null)
|
||||
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null)
|
||||
{
|
||||
$this->classMetadataFactory = $classMetadataFactory;
|
||||
$this->nameConverter = $nameConverter;
|
||||
@ -219,19 +241,21 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
|
||||
* Gets attributes to normalize using groups.
|
||||
*
|
||||
* @param string|object $classOrObject
|
||||
* @param array $context
|
||||
* @return array|bool
|
||||
* @param array $context
|
||||
* @param bool $attributesAsString If false, return an array of {@link AttributeMetadataInterface}
|
||||
*
|
||||
* @return string[]|AttributeMetadataInterface[]|bool
|
||||
*/
|
||||
protected function getAllowedAttributes($classOrObject, array $context)
|
||||
protected function getAllowedAttributes($classOrObject, array $context, $attributesAsString = false)
|
||||
{
|
||||
if (!$this->classMetadataFactory || !isset($context['groups']) || !is_array($context['groups'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$allowedAttributes = array();
|
||||
foreach ($this->classMetadataFactory->getMetadataFor($classOrObject)->getAttributesGroups() as $group => $attributes) {
|
||||
if (in_array($group, $context['groups'])) {
|
||||
$allowedAttributes = array_merge($allowedAttributes, $attributes);
|
||||
foreach ($this->classMetadataFactory->getMetadataFor($classOrObject)->getAttributesMetadata() as $attributeMetadata) {
|
||||
if (count(array_intersect($attributeMetadata->getGroups(), $context['groups']))) {
|
||||
$allowedAttributes[] = $attributesAsString ? $attributeMetadata->getName() : $attributeMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ class GetSetMethodNormalizer extends AbstractNormalizer
|
||||
|
||||
$reflectionObject = new \ReflectionObject($object);
|
||||
$reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC);
|
||||
$allowedAttributes = $this->getAllowedAttributes($object, $context);
|
||||
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
|
||||
|
||||
$attributes = array();
|
||||
foreach ($reflectionMethods as $method) {
|
||||
@ -97,7 +97,7 @@ class GetSetMethodNormalizer extends AbstractNormalizer
|
||||
*/
|
||||
public function denormalize($data, $class, $format = null, array $context = array())
|
||||
{
|
||||
$allowedAttributes = $this->getAllowedAttributes($class, $context);
|
||||
$allowedAttributes = $this->getAllowedAttributes($class, $context, true);
|
||||
$normalizedData = $this->prepareForDenormalization($data);
|
||||
|
||||
$reflectionClass = new \ReflectionClass($class);
|
||||
|
@ -46,7 +46,7 @@ class PropertyNormalizer extends AbstractNormalizer
|
||||
|
||||
$reflectionObject = new \ReflectionObject($object);
|
||||
$attributes = array();
|
||||
$allowedAttributes = $this->getAllowedAttributes($object, $context);
|
||||
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
|
||||
|
||||
foreach ($reflectionObject->getProperties() as $property) {
|
||||
if (in_array($property->name, $this->ignoredAttributes)) {
|
||||
@ -89,7 +89,7 @@ class PropertyNormalizer extends AbstractNormalizer
|
||||
*/
|
||||
public function denormalize($data, $class, $format = null, array $context = array())
|
||||
{
|
||||
$allowedAttributes = $this->getAllowedAttributes($class, $context);
|
||||
$allowedAttributes = $this->getAllowedAttributes($class, $context, true);
|
||||
$data = $this->prepareForDenormalization($data);
|
||||
|
||||
$reflectionClass = new \ReflectionClass($class);
|
||||
|
@ -0,0 +1,57 @@
|
||||
<?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\Serializer\Tests\Mapping;
|
||||
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class AttributeMetadataTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testInterface()
|
||||
{
|
||||
$attributeMetadata = new AttributeMetadata('name');
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface', $attributeMetadata);
|
||||
}
|
||||
|
||||
public function testGetName()
|
||||
{
|
||||
$attributeMetadata = new AttributeMetadata('name');
|
||||
$this->assertEquals('name', $attributeMetadata->getName());
|
||||
}
|
||||
|
||||
public function testGroups()
|
||||
{
|
||||
$attributeMetadata = new AttributeMetadata('group');
|
||||
$attributeMetadata->addGroup('a');
|
||||
$attributeMetadata->addGroup('a');
|
||||
$attributeMetadata->addGroup('b');
|
||||
|
||||
$this->assertEquals(array('a', 'b'), $attributeMetadata->getGroups());
|
||||
}
|
||||
|
||||
public function testMerge()
|
||||
{
|
||||
$attributeMetadata1 = new AttributeMetadata('a1');
|
||||
$attributeMetadata1->addGroup('a');
|
||||
$attributeMetadata1->addGroup('b');
|
||||
|
||||
$attributeMetadata2 = new AttributeMetadata('a2');
|
||||
$attributeMetadata2->addGroup('a');
|
||||
$attributeMetadata2->addGroup('c');
|
||||
|
||||
$attributeMetadata1->merge($attributeMetadata2);
|
||||
|
||||
$this->assertEquals(array('a', 'b', 'c'), $attributeMetadata1->getGroups());
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
<?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\Serializer\Tests\Mapping;
|
||||
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ClassMetadataTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testInterface()
|
||||
{
|
||||
$classMetadata = new ClassMetadata('name');
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\ClassMetadataInterface', $classMetadata);
|
||||
}
|
||||
|
||||
public function testAttributeMetadata()
|
||||
{
|
||||
$classMetadata = new ClassMetadata('c');
|
||||
|
||||
$a1 = $this->getMock('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface');
|
||||
$a1->method('getName')->willReturn('a1');
|
||||
|
||||
$a2 = $this->getMock('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface');
|
||||
$a2->method('getName')->willReturn('a2');
|
||||
|
||||
$classMetadata->addAttributeMetadata($a1);
|
||||
$classMetadata->addAttributeMetadata($a2);
|
||||
|
||||
$this->assertEquals(array('a1' => $a1, 'a2' => $a2), $classMetadata->getAttributesMetadata());
|
||||
}
|
||||
|
||||
public function testMerge()
|
||||
{
|
||||
$classMetadata1 = new ClassMetadata('c1');
|
||||
$classMetadata2 = new ClassMetadata('c2');
|
||||
|
||||
$ac1 = $this->getMock('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface');
|
||||
$ac1->method('getName')->willReturn('a1');
|
||||
$ac1->method('getGroups')->willReturn(array('a', 'b'));
|
||||
|
||||
$ac2 = $this->getMock('Symfony\Component\Serializer\Mapping\AttributeMetadataInterface');
|
||||
$ac2->method('getName')->willReturn('a1');
|
||||
$ac2->method('getGroups')->willReturn(array('b', 'c'));
|
||||
|
||||
$classMetadata1->addAttributeMetadata($ac1);
|
||||
$classMetadata2->addAttributeMetadata($ac2);
|
||||
|
||||
$classMetadata1->merge($classMetadata2);
|
||||
|
||||
$ac1->method('getGroups')->willReturn('a', 'b', 'c');
|
||||
|
||||
$this->assertEquals(array('a1' => $ac1), $classMetadata2->getAttributesMetadata());
|
||||
}
|
||||
}
|
@ -14,21 +14,26 @@ namespace Symfony\Component\Serializer\Tests\Mapping\Factory;
|
||||
use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
|
||||
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
|
||||
use Symfony\Component\Serializer\Mapping\Loader\LoaderChain;
|
||||
use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory;
|
||||
|
||||
require_once __DIR__.'/../../../Annotation/Groups.php';
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ClassMetadataFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testInterface()
|
||||
{
|
||||
$classMetadata = new ClassMetadataFactory(new LoaderChain(array()));
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory', $classMetadata);
|
||||
}
|
||||
|
||||
public function testGetMetadataFor()
|
||||
{
|
||||
$factory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
|
||||
$metadata = $factory->getMetadataFor('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
$classMetadata = $factory->getMetadataFor('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
|
||||
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(true, true), $metadata);
|
||||
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(true, true), $classMetadata);
|
||||
}
|
||||
|
||||
public function testHasMetadataFor()
|
||||
|
@ -16,42 +16,51 @@ use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
|
||||
use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory;
|
||||
|
||||
require_once __DIR__.'/../../../Annotation/Groups.php';
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class AnnotationLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var AnnotationLoader
|
||||
*/
|
||||
private $loader;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->loader = new AnnotationLoader(new AnnotationReader());
|
||||
}
|
||||
|
||||
public function testInterface()
|
||||
{
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\Loader\LoaderInterface', $this->loader);
|
||||
}
|
||||
|
||||
public function testLoadClassMetadataReturnsTrueIfSuccessful()
|
||||
{
|
||||
$loader = new AnnotationLoader(new AnnotationReader());
|
||||
$metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
$classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
|
||||
$this->assertTrue($loader->loadClassMetadata($metadata));
|
||||
$this->assertTrue($this->loader->loadClassMetadata($classMetadata));
|
||||
}
|
||||
|
||||
public function testLoadClassMetadata()
|
||||
{
|
||||
$loader = new AnnotationLoader(new AnnotationReader());
|
||||
$metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
$classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
$this->loader->loadClassMetadata($classMetadata);
|
||||
|
||||
$loader->loadClassMetadata($metadata);
|
||||
|
||||
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(), $metadata);
|
||||
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(), $classMetadata);
|
||||
}
|
||||
|
||||
public function testLoadClassMetadataAndMerge()
|
||||
{
|
||||
$loader = new AnnotationLoader(new AnnotationReader());
|
||||
$metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
$parentMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummyParent');
|
||||
$classMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
$parentClassMetadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummyParent');
|
||||
|
||||
$loader->loadClassMetadata($parentMetadata);
|
||||
$metadata->mergeAttributesGroups($parentMetadata);
|
||||
$this->loader->loadClassMetadata($parentClassMetadata);
|
||||
$classMetadata->merge($parentClassMetadata);
|
||||
|
||||
$loader->loadClassMetadata($metadata);
|
||||
$this->loader->loadClassMetadata($classMetadata);
|
||||
|
||||
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(true), $metadata);
|
||||
$this->assertEquals(TestClassMetadataFactory::createClassMetadata(true), $classMetadata);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,13 @@ use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory;
|
||||
*/
|
||||
class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var XmlFileLoader
|
||||
*/
|
||||
private $loader;
|
||||
/**
|
||||
* @var ClassMetadata
|
||||
*/
|
||||
private $metadata;
|
||||
|
||||
public function setUp()
|
||||
@ -29,6 +35,11 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
}
|
||||
|
||||
public function testInterface()
|
||||
{
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\Loader\LoaderInterface', $this->loader);
|
||||
}
|
||||
|
||||
public function testLoadClassMetadataReturnsTrueIfSuccessful()
|
||||
{
|
||||
$this->assertTrue($this->loader->loadClassMetadata($this->metadata));
|
||||
|
@ -20,7 +20,13 @@ use Symfony\Component\Serializer\Tests\Mapping\TestClassMetadataFactory;
|
||||
*/
|
||||
class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var YamlFileLoader
|
||||
*/
|
||||
private $loader;
|
||||
/**
|
||||
* @var ClassMetadata
|
||||
*/
|
||||
private $metadata;
|
||||
|
||||
public function setUp()
|
||||
@ -29,6 +35,11 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->metadata = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
}
|
||||
|
||||
public function testInterface()
|
||||
{
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Mapping\Loader\LoaderInterface', $this->loader);
|
||||
}
|
||||
|
||||
public function testLoadClassMetadataReturnsTrueIfSuccessful()
|
||||
{
|
||||
$this->assertTrue($this->loader->loadClassMetadata($this->metadata));
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Serializer\Tests\Mapping;
|
||||
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
|
||||
/**
|
||||
@ -22,22 +23,38 @@ class TestClassMetadataFactory
|
||||
{
|
||||
$expected = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
|
||||
$foo = new AttributeMetadata('foo');
|
||||
$foo->addGroup('a');
|
||||
$expected->addAttributeMetadata($foo);
|
||||
|
||||
$bar = new AttributeMetadata('bar');
|
||||
$bar->addGroup('b');
|
||||
$bar->addGroup('c');
|
||||
$expected->addAttributeMetadata($bar);
|
||||
|
||||
$fooBar = new AttributeMetadata('fooBar');
|
||||
$fooBar->addGroup('a');
|
||||
$fooBar->addGroup('b');
|
||||
$expected->addAttributeMetadata($fooBar);
|
||||
|
||||
$symfony = new AttributeMetadata('symfony');
|
||||
$expected->addAttributeMetadata($symfony);
|
||||
|
||||
if ($withParent) {
|
||||
$expected->addAttributeGroup('kevin', 'a');
|
||||
$expected->addAttributeGroup('coopTilleuls', 'a');
|
||||
$expected->addAttributeGroup('coopTilleuls', 'b');
|
||||
$kevin = new AttributeMetadata('kevin');
|
||||
$kevin->addGroup('a');
|
||||
$expected->addAttributeMetadata($kevin);
|
||||
|
||||
$coopTilleuls = new AttributeMetadata('coopTilleuls');
|
||||
$coopTilleuls->addGroup('a');
|
||||
$coopTilleuls->addGroup('b');
|
||||
$expected->addAttributeMetadata($coopTilleuls);
|
||||
}
|
||||
|
||||
if ($withInterface) {
|
||||
$expected->addAttributeGroup('symfony', 'a');
|
||||
$symfony->addGroup('a');
|
||||
}
|
||||
|
||||
$expected->addAttributeGroup('foo', 'a');
|
||||
$expected->addAttributeGroup('bar', 'b');
|
||||
$expected->addAttributeGroup('bar', 'c');
|
||||
$expected->addAttributeGroup('fooBar', 'a');
|
||||
$expected->addAttributeGroup('fooBar', 'b');
|
||||
|
||||
// load reflection class so that the comparison passes
|
||||
$expected->getReflectionClass();
|
||||
|
||||
@ -47,9 +64,15 @@ class TestClassMetadataFactory
|
||||
public static function createXmlCLassMetadata()
|
||||
{
|
||||
$expected = new ClassMetadata('Symfony\Component\Serializer\Tests\Fixtures\GroupDummy');
|
||||
$expected->addAttributeGroup('foo', 'group1');
|
||||
$expected->addAttributeGroup('foo', 'group2');
|
||||
$expected->addAttributeGroup('bar', 'group2');
|
||||
|
||||
$foo = new AttributeMetadata('foo');
|
||||
$foo->addGroup('group1');
|
||||
$foo->addGroup('group2');
|
||||
$expected->addAttributeMetadata($foo);
|
||||
|
||||
$bar = new AttributeMetadata('bar');
|
||||
$bar->addGroup('group2');
|
||||
$expected->addAttributeMetadata($bar);
|
||||
|
||||
return $expected;
|
||||
}
|
||||
|
@ -18,6 +18,12 @@ use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter
|
||||
*/
|
||||
class CamelCaseToSnakeCaseNameConverterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testInterface()
|
||||
{
|
||||
$attributeMetadata = new CamelCaseToSnakeCaseNameConverter();
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\NameConverter\NameConverterInterface', $attributeMetadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider attributeProvider
|
||||
*/
|
||||
|
@ -17,12 +17,23 @@ use Symfony\Component\Serializer\Serializer;
|
||||
|
||||
class CustomNormalizerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var CustomNormalizer
|
||||
*/
|
||||
private $normalizer;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->normalizer = new CustomNormalizer();
|
||||
$this->normalizer->setSerializer(new Serializer());
|
||||
}
|
||||
|
||||
public function testInterface()
|
||||
{
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\NormalizerInterface', $this->normalizer);
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\DenormalizerInterface', $this->normalizer);
|
||||
}
|
||||
|
||||
public function testSerialize()
|
||||
{
|
||||
$obj = new ScalarDummy();
|
||||
|
@ -40,6 +40,12 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
|
||||
$this->normalizer->setSerializer($this->serializer);
|
||||
}
|
||||
|
||||
public function testInterface()
|
||||
{
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\NormalizerInterface', $this->normalizer);
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\DenormalizerInterface', $this->normalizer);
|
||||
}
|
||||
|
||||
public function testNormalize()
|
||||
{
|
||||
$obj = new GetSetDummy();
|
||||
|
@ -22,6 +22,17 @@ use Symfony\Component\Serializer\Tests\Normalizer\TestDenormalizer;
|
||||
|
||||
class SerializerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testInterface()
|
||||
{
|
||||
$serializer = new Serializer();
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\SerializerInterface', $serializer);
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\NormalizerInterface', $serializer);
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Normalizer\DenormalizerInterface', $serializer);
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Encoder\EncoderInterface', $serializer);
|
||||
$this->assertInstanceOf('Symfony\Component\Serializer\Encoder\DecoderInterface', $serializer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
|
||||
*/
|
||||
|
Reference in New Issue
Block a user