Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a44bead

Browse files
dunglasfabpot
authored andcommitted
[Serializer] Add a MaxDepth option
1 parent caae21c commit a44bead

19 files changed

+505
-38
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Annotation;
13+
14+
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
15+
16+
/**
17+
* Annotation class for @MaxDepth().
18+
*
19+
* @Annotation
20+
* @Target({"PROPERTY", "METHOD"})
21+
*
22+
* @author Kévin Dunglas <[email protected]>
23+
*/
24+
class MaxDepth
25+
{
26+
/**
27+
* @var int
28+
*/
29+
private $maxDepth;
30+
31+
public function __construct(array $data)
32+
{
33+
if (!isset($data['value']) || !$data['value']) {
34+
throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" cannot be empty.', get_class($this)));
35+
}
36+
37+
if (!is_int($data['value']) || $data['value'] <= 0) {
38+
throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" must be a positive integer.', get_class($this)));
39+
}
40+
41+
$this->maxDepth = $data['value'];
42+
}
43+
44+
public function getMaxDepth()
45+
{
46+
return $this->maxDepth;
47+
}
48+
}

src/Symfony/Component/Serializer/Mapping/AttributeMetadata.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ class AttributeMetadata implements AttributeMetadataInterface
3636
*/
3737
public $groups = array();
3838

39+
/**
40+
* @var int|null
41+
*
42+
* @internal This property is public in order to reduce the size of the
43+
* class' serialized representation. Do not access it. Use
44+
* {@link getMaxDepth()} instead.
45+
*/
46+
public $maxDepth;
47+
3948
/**
4049
* Constructs a metadata for the given attribute.
4150
*
@@ -72,6 +81,22 @@ public function getGroups()
7281
return $this->groups;
7382
}
7483

84+
/**
85+
* {@inheritdoc}
86+
*/
87+
public function setMaxDepth($maxDepth)
88+
{
89+
$this->maxDepth = $maxDepth;
90+
}
91+
92+
/**
93+
* {@inheritdoc}
94+
*/
95+
public function getMaxDepth()
96+
{
97+
return $this->maxDepth;
98+
}
99+
75100
/**
76101
* {@inheritdoc}
77102
*/
@@ -80,6 +105,11 @@ public function merge(AttributeMetadataInterface $attributeMetadata)
80105
foreach ($attributeMetadata->getGroups() as $group) {
81106
$this->addGroup($group);
82107
}
108+
109+
// Overwrite only if not defined
110+
if (null === $this->maxDepth) {
111+
$this->maxDepth = $attributeMetadata->getMaxDepth();
112+
}
83113
}
84114

85115
/**
@@ -89,6 +119,6 @@ public function merge(AttributeMetadataInterface $attributeMetadata)
89119
*/
90120
public function __sleep()
91121
{
92-
return array('name', 'groups');
122+
return array('name', 'groups', 'maxDepth');
93123
}
94124
}

src/Symfony/Component/Serializer/Mapping/AttributeMetadataInterface.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ public function addGroup($group);
4343
*/
4444
public function getGroups();
4545

46+
/**
47+
* Sets the serialization max depth for this attribute.
48+
*
49+
* @param int|null $maxDepth
50+
*/
51+
public function setMaxDepth($maxDepth);
52+
53+
/**
54+
* Gets the serialization max depth for this attribute.
55+
*
56+
* @return int|null
57+
*/
58+
public function getMaxDepth();
59+
4660
/**
4761
* Merges an {@see AttributeMetadataInterface} with in the current one.
4862
*

src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Doctrine\Common\Annotations\Reader;
1515
use Symfony\Component\Serializer\Annotation\Groups;
16+
use Symfony\Component\Serializer\Annotation\MaxDepth;
1617
use Symfony\Component\Serializer\Exception\MappingException;
1718
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
1819
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
@@ -55,11 +56,13 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata)
5556
}
5657

5758
if ($property->getDeclaringClass()->name === $className) {
58-
foreach ($this->reader->getPropertyAnnotations($property) as $groups) {
59-
if ($groups instanceof Groups) {
60-
foreach ($groups->getGroups() as $group) {
59+
foreach ($this->reader->getPropertyAnnotations($property) as $annotation) {
60+
if ($annotation instanceof Groups) {
61+
foreach ($annotation->getGroups() as $group) {
6162
$attributesMetadata[$property->name]->addGroup($group);
6263
}
64+
} elseif ($annotation instanceof MaxDepth) {
65+
$attributesMetadata[$property->name]->setMaxDepth($annotation->getMaxDepth());
6366
}
6467

6568
$loaded = true;
@@ -68,29 +71,40 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata)
6871
}
6972

7073
foreach ($reflectionClass->getMethods() as $method) {
71-
if ($method->getDeclaringClass()->name === $className) {
72-
foreach ($this->reader->getMethodAnnotations($method) as $groups) {
73-
if ($groups instanceof Groups) {
74-
if (preg_match('/^(get|is|has|set)(.+)$/i', $method->name, $matches)) {
75-
$attributeName = lcfirst($matches[2]);
76-
77-
if (isset($attributesMetadata[$attributeName])) {
78-
$attributeMetadata = $attributesMetadata[$attributeName];
79-
} else {
80-
$attributesMetadata[$attributeName] = $attributeMetadata = new AttributeMetadata($attributeName);
81-
$classMetadata->addAttributeMetadata($attributeMetadata);
82-
}
83-
84-
foreach ($groups->getGroups() as $group) {
85-
$attributeMetadata->addGroup($group);
86-
}
87-
} else {
88-
throw new MappingException(sprintf('Groups on "%s::%s" cannot be added. Groups can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name));
89-
}
74+
if ($method->getDeclaringClass()->name !== $className) {
75+
continue;
76+
}
77+
78+
$accessorOrMutator = preg_match('/^(get|is|has|set)(.+)$/i', $method->name, $matches);
79+
if ($accessorOrMutator) {
80+
$attributeName = lcfirst($matches[2]);
81+
82+
if (isset($attributesMetadata[$attributeName])) {
83+
$attributeMetadata = $attributesMetadata[$attributeName];
84+
} else {
85+
$attributesMetadata[$attributeName] = $attributeMetadata = new AttributeMetadata($attributeName);
86+
$classMetadata->addAttributeMetadata($attributeMetadata);
87+
}
88+
}
89+
90+
foreach ($this->reader->getMethodAnnotations($method) as $annotation) {
91+
if ($annotation instanceof Groups) {
92+
if (!$accessorOrMutator) {
93+
throw new MappingException(sprintf('Groups on "%s::%s" cannot be added. Groups can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name));
9094
}
9195

92-
$loaded = true;
96+
foreach ($annotation->getGroups() as $group) {
97+
$attributeMetadata->addGroup($group);
98+
}
99+
} elseif ($annotation instanceof MaxDepth) {
100+
if (!$accessorOrMutator) {
101+
throw new MappingException(sprintf('MaxDepth on "%s::%s" cannot be added. MaxDepth can only be added on methods beginning with "get", "is", "has" or "set".', $className, $method->name));
102+
}
103+
104+
$attributeMetadata->setMaxDepth($annotation->getMaxDepth());
93105
}
106+
107+
$loaded = true;
94108
}
95109
}
96110

src/Symfony/Component/Serializer/Mapping/Loader/XmlFileLoader.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata)
6262
foreach ($attribute->group as $group) {
6363
$attributeMetadata->addGroup((string) $group);
6464
}
65+
66+
if (isset($attribute['max-depth'])) {
67+
$attributeMetadata->setMaxDepth((int) $attribute['max-depth']);
68+
}
6569
}
6670

6771
return true;

src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata)
7878
$attributeMetadata->addGroup($group);
7979
}
8080
}
81+
82+
if (isset($data['max_depth'])) {
83+
if (!is_int($data['max_depth'])) {
84+
throw new MappingException('The "max_depth" value must an integer in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName());
85+
}
86+
87+
$attributeMetadata->setMaxDepth($data['max_depth']);
88+
}
8189
}
8290
}
8391

src/Symfony/Component/Serializer/Mapping/Loader/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,20 @@
4444
<xsd:complexType name="attribute">
4545
<xsd:annotation>
4646
<xsd:documentation><![CDATA[
47-
Contains serialization groups for a attributes. The name of the attribute should be given in the "name" option.
47+
Contains serialization groups and max depth for attributes. The name of the attribute should be given in the "name" option.
4848
]]></xsd:documentation>
4949
</xsd:annotation>
50-
<xsd:sequence>
50+
<xsd:sequence minOccurs="0">
5151
<xsd:element name="group" type="xsd:string" maxOccurs="unbounded" />
5252
</xsd:sequence>
5353
<xsd:attribute name="name" type="xsd:string" use="required" />
54+
<xsd:attribute name="max-depth">
55+
<xsd:simpleType>
56+
<xsd:restriction base="xsd:integer">
57+
<xsd:minInclusive value="0" />
58+
</xsd:restriction>
59+
</xsd:simpleType>
60+
</xsd:attribute>
5461
</xsd:complexType>
5562

5663
</xsd:schema>

0 commit comments

Comments
 (0)