8000 Fixes · symfony/symfony@c3801fd · GitHub
[go: up one dir, main page]

Skip to content

Commit c3801fd

Browse files
committed
Fixes
1 parent eedfba8 commit c3801fd

File tree

6 files changed

+190
-105
lines changed

6 files changed

+190
-105
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,11 +1217,6 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
12171217
$serializerLoaders[] = $annotationLoader;
12181218
}
12191219

1220-
if (!$config['enable_normalizer_generation']) {
1221-
$container->removeDefinition('serializer.normalizer.object.generated');
1222-
$container->removeDefinition('serializer.normalizer.object.dumper');
1223-
}
1224-
12251220
$fileRecorder = function ($extension, $path) use (&$serializerLoaders) {
12261221
$definition = new Definition(in_array($extension, array('yaml', 'yml')) ? 'Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader' : 'Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array($path));
12271222
$definition->setPublic(false);
@@ -1277,6 +1272,12 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
12771272

12781273
if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) {
12791274
$container->getDefinition('serializer.normalizer.object')->addMethodCall('setCircularReferenceHandler', array(new Reference($config['circular_reference_handler'])));
1275+
$container->getDefinition('serializer.normalizer.object.generated')->addMethodCall('setCircularReferenceHandler', array(new Reference($config['circular_reference_handler'])));
1276+
}
1277+
1278+
if (!$config['enable_normalizer_generation']) {
1279+
$container->removeDefinition('serializer.normalizer.object.generated');
1280+
$container->removeDefinition('serializer.normalizer.object.dumper');
12801281
}
12811282
}
12821283

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"symfony/process": "~3.4|~4.0",
4545
"symfony/security-core": "~3.4|~4.0",
4646
"symfony/security-csrf": "~3.4|~4.0",
47-
"symfony/serializer": "~3.4|~4.0",
47+
"symfony/serializer": "~4.1",
4848
"symfony/stopwatch": "~3.4|~4.0",
4949
"symfony/translation": "~3.4|~4.0",
5050
"symfony/templating": "~3.4|~4.0",

src/Symfony/Component/Serializer/Dumper/NormalizerDumper.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
/**
1919
* @author Guilhem Niot <guilhem.niot@gmail.com>
2020
* @author Amrouche Hamza <hamza.simperfit@gmail.com>
21+
*
2122
* @experimental
2223
*/
2324
final class NormalizerDumper
@@ -42,6 +43,7 @@ public function dump(string $class, array $context = array())
4243
<?php
4344
$namespaceLine
4445
use Symfony\Component\Serializer\Exception\CircularReferenceException;
46+
use Symfony\Component\Serializer\Normalizer\CircularReferenceTrait;
4547
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
4648
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
4749
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
@@ -53,7 +55,7 @@ public function dump(string $class, array $context = array())
5355
*/
5456
class {$context['class']} implements NormalizerInterface, NormalizerAwareInterface
5557
{
56-
use NormalizerAwareTrait;
58+
use CircularReferenceTrait, NormalizerAwareTrait;
5759
5860
{$this->generateNormalizeMethod($reflectionClass)}
5961
@@ -79,11 +81,8 @@ private function generateNormalizeMethodInner(\ReflectionClass $reflectionClass)
7981
{
8082
$code = <<<EOL
8183
82-
\$objectHash = spl_object_hash(\$object);
83-
if (isset(\$context[ObjectNormalizer::CIRCULAR_REFERENCE_LIMIT][\$objectHash])) {
84-
return null;
85-
} else {
86-
\$context[ObjectNormalizer::CIRCULAR_REFERENCE_LIMIT][\$objectHash] = 1;
84+
if (\$this->isCircularReference(\$object, \$context)) {
85+
return \$this->handleCircularReference(\$object);
8786
}
8887
8988
\$groups = isset(\$context[ObjectNormalizer::GROUPS]) && is_array(\$context[ObjectNormalizer::GROUPS]) ? \$context[ObjectNormalizer::GROUPS] : null;

src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php

Lines changed: 6 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace Symfony\Component\Serializer\Normalizer;
1313

14-
use Symfony\Component\Serializer\Exception\CircularReferenceException;
1514
use Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException;
1615
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
1716
use Symfony\Component\Serializer\Exception\LogicException;
@@ -29,6 +28,7 @@
2928
*/
3029
abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
3130
{
31+
use CircularReferenceTrait;
3232
use ObjectToPopulateTrait;
3333
use SerializerAwareTrait;
3434

@@ -39,16 +39,6 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
3939
const ALLOW_EXTRA_ATTRIBUTES = 'allow_extra_attributes';
4040
const DEFAULT_CONSTRUCTOR_ARGUMENTS = 'default_constructor_arguments';
4141

42-
/**
43-
* @var int
44-
*/
45-
protected $circularReferenceLimit = 1;
46-
47-
/**
48-
* @var callable
49-
*/
50-
protected $circularReferenceHandler;
51-
5242
/**
5343
* @var ClassMetadataFactoryInterface|null
5444
*/
@@ -83,34 +73,6 @@ public function __construct(ClassMetadataFactoryInterface $classMetadataFactory
8373
$this->nameConverter = $nameConverter;
8474
}
8575

86-
/**
87-
* Set circular reference limit.
88-
*
89-
* @param int $circularReferenceLimit Limit of iterations for the same object
90-
*
91-
* @return self
92-
*/
93-
public function setCircularReferenceLimit($circularReferenceLimit)
94-
{
95-
$this->circularReferenceLimit = $circularReferenceLimit;
96-
97-
return $this;
98-
}
99-
100-
/**
101-
* Set circular reference handler.
102-
*
103-
* @param callable $circularReferenceHandler
104-
*
105-
* @return self
106-
*/
107-
public function setCircularReferenceHandler(callable $circularReferenceHandler)
108-
{
109-
$this->circularReferenceHandler = $circularReferenceHandler;
110-
111-
return $this;
112-
}
113-
11476
/**
11577
* Set normalization callbacks.
11678
*
@@ -147,56 +109,6 @@ public function setIgnoredAttributes(array $ignoredAttributes)
147109
return $this;
148110
}
149111

150-
/**
151-
* Detects if the configured circular reference limit is reached.
152-
*
153-
* @param object $object
154-
* @param array $context
155-
*
156-
* @return bool
157-
*
158-
* @throws CircularReferenceException
159-
*/
160-
protected function isCircularReference($object, &$context)
161-
{
162-
$objectHash = spl_object_hash($object);
163-
164-
if (isset($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash])) {
165-
if ($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash] >= $this->circularReferenceLimit) {
166-
unset($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash]);
167-
168-
return true;
169-
}
170-
171-
++$context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash];
172-
} else {
173-
$context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash] = 1;
174-
}
175-
176-
return false;
177-
}
178-
179-
/**
180-
* Handles a circular reference.
181-
*
182-
* If a circular reference handler is set, it will be called. Otherwise, a
183-
* {@class CircularReferenceException} will be thrown.
184-
*
185-
* @param object $object
186-
*
187-
* @return mixed
188-
*
189-
* @throws CircularReferenceException
190-
*/
191-
protected function handleCircularReference($object)
192-
{
193-
if ($this->circularReferenceHandler) {
194-
return \call_user_func($this->circularReferenceHandler, $object);
195-
}
196-
197-
throw new CircularReferenceException(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d)', \get_class($object), $this->circularReferenceLimit));
198-
}
199-
200112
/**
201113
* Gets attributes to normalize using groups.
202114
*
@@ -399,4 +311,9 @@ protected function createChildContext(array $parentContext, $attribute)
399311

400312
return $parentContext;
401313
}
314+
315+
private function getCircularReferenceLimitField()
316+
{
317+
return static::CIRCULAR_REFERENCE_LIMIT;
318+
}
402319
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Normalizer;
13+
14+
use Symfony\Component\Serializer\Exception\CircularReferenceException;
15+
16+
/**
17+
* Handle circular references.
18+
*
19+
* @author Kévin Dunglas <dunglas@gmail.com>
20+
*
21+
* @internal
22+
*/
23+
trait CircularReferenceTrait
24+
{
25+
/**
26+
* @var int
27+
*/
28+
protected $circularReferenceLimit = 1;
29+
30+
/**
31+
* @var callable
32+
*/
33+
protected $circularReferenceHandler;
34+
35+
/**
36+
* Set circular reference limit.
37+
*
38+
* @param int $circularReferenceLimit Limit of iterations for the same object
39+
*
40+
* @return self
41+
*/
42+
public function setCircularReferenceLimit($circularReferenceLimit)
43+
{
44+
$this->circularReferenceLimit = $circularReferenceLimit;
45+
46+
return $this;
47+
}
48+
49+
/**
50+
* Set circular reference handler.
51+
*
52+
* @param callable $circularReferenceHandler
53+
*
54+
* @return self
55+
*/
56+
public function setCircularReferenceHandler(callable $circularReferenceHandler)
57+
{
58+
$this->circularReferenceHandler = $circularReferenceHandler;
59+
60+
return $this;
61+
}
62+
63+
/**
64+
* Detects if the configured circular reference limit is reached.
65+
*
66+
* @param object $object
67+
* @param array $context
68+
*
69+
* @return bool
70+
*
71+
* @throws CircularReferenceException
72+
*/
73+
protected function isCircularReference($object, &$context)
74+
{
75+
$objectHash = spl_object_hash($object);
76+
77+
$circularReferenceLimitField = $this->getCircularReferenceLimitField();
78+
if (isset($context[$circularReferenceLimitField][$objectHash])) {
79+
if ($context[$circularReferenceLimitField][$objectHash] >= $this->circularReferenceLimit) {
80+
unset($context[$circularReferenceLimitField][$objectHash]);
81+
82+
return true;
83+
}
84+
85+
++$context[$circularReferenceLimitField][$objectHash];
86+
} else {
87+
$context[$circularReferenceLimitField][$objectHash] = 1;
88+
}
89+
90+
return false;
91+
}
92+
93+
/**
94+
* Handles a circular reference.
95+
*
96+
* If a circular reference handler is set, it will be called. Otherwise, a
97+
* {@class CircularReferenceException} will be thrown.
98+
*
99+
* @param object $object
100+
*
101+
* @return mixed
102+
*
103+
* @throws CircularReferenceException
104+
*/
105+
protected function handleCircularReference($object)
106+
{
107+
if ($this->circularReferenceHandler) {
108+
return \call_user_func($this->circularReferenceHandler, $object);
109+
}
110+
111+
throw new CircularReferenceException(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d)', \get_class($object), $this->circularReferenceLimit));
112+
}
113+
114+
private function getCircularReferenceLimitField()
115+
{
116+
return ObjectNormalizer::CIRCULAR_REFERENCE_LIMIT;
117+
}
118+
}

0 commit comments

Comments
 (0)
0