8000 [Serializer] Unified normalizers/encoders config through default context solely by ogizanagi · Pull Request #31699 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Serializer] Unified normalizers/encoders config through default context solely #31699

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions UPGRADE-5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,24 @@ Serializer
----------

* The default value of the `CsvEncoder` "as_collection" option was changed to `true`.
* Individual encoders & normalizers options as constructor arguments were removed.
Use the default context instead.
* The following method and properties:
- `AbstractNormalizer::$circularReferenceLimit`
- `AbstractNormalizer::$circularReferenceHandler`
- `AbstractNormalizer::$callbacks`
- `AbstractNormalizer::$ignoredAttributes`
- `AbstractNormalizer::$camelizedAttributes`
- `AbstractNormalizer::setCircularReferenceLimit()`
- `AbstractNormalizer::setCircularReferenceHandler()`
- `AbstractNormalizer::setCallbacks()`
- `AbstractNormalizer::setIgnoredAttributes()`
- `AbstractObjectNormalizer::$maxDepthHandler`
- `AbstractObjectNormalizer::setMaxDepthHandler()`
- `XmlEncoder::setRootNodeName()`
- `XmlEncoder::getRootNodeName()`

were removed, use the default context instead.
* The `AbstractNormalizer::handleCircularReference()` method has two new `$format` and `$context` arguments.

Translation
Expand Down
9 changes: 9 additions & 0 deletions src/Symfony/Component/Serializer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ CHANGELOG
* throw an exception when creating a `Serializer` with normalizers which neither implement `NormalizerInterface` nor `DenormalizerInterface`
* throw an exception when creating a `Serializer` with encoders which neither implement `EncoderInterface` nor `DecoderInterface`
* changed the default value of the `CsvEncoder` "as_collection" option to `true`
* removed `AbstractNormalizer::$circularReferenceLimit`, `AbstractNormalizer::$circularReferenceHandler`,
`AbstractNormalizer::$callbacks`, `AbstractNormalizer::$ignoredAttributes`,
`AbstractNormalizer::$camelizedAttributes`, `AbstractNormalizer::setCircularReferenceLimit()`,
`AbstractNormalizer::setCircularReferenceHandler()`, `AbstractNormalizer::setCallbacks()` and
`AbstractNormalizer::setIgnoredAttributes()`, use the default context instead.
* removed `AbstractObjectNormalizer::$maxDepthHandler` and `AbstractObjectNormalizer::setMaxDepthHandler()`,
use the default context instead.
* removed `XmlEncoder::setRootNodeName()` & `XmlEncoder::getRootNodeName()`, use the default context instead.
* removed individual encoders/normalizers options as constructor arguments.

4.3.0
-----
Expand Down
17 changes: 1 addition & 16 deletions src/Symfony/Component/Serializer/Encoder/CsvEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,8 @@ class CsvEncoder implements EncoderInterface, DecoderInterface
self::NO_HEADERS_KEY => false,
];

/**
* @param array $defaultContext
*/
public function __construct($defaultContext = [], string $enclosure = '"', string $escapeChar = '\\', string $keySeparator = '.', bool $escapeFormulas = false)
public function __construct(array $defaultContext = [])
{
if (!\is_array($defaultContext)) {
@trigger_error('Passing configuration options directly to the constructor is deprecated since Symfony 4.2, use the default context instead.', E_USER_DEPRECATED);

$defaultContext = [
self::DELIMITER_KEY => (string) $defaultContext,
self::ENCLOSURE_KEY => $enclosure,
self::ESCAPE_CHAR_KEY => $escapeChar,
self::KEY_SEPARATOR_KEY => $keySeparator,
self::ESCAPE_FORMULAS_KEY => $escapeFormulas,
];
}

$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
}

Expand Down
44 changes: 1 addition & 43 deletions src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,8 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
private $format;
private $context;

/**
* @param array $defaultContext
*/
public function __construct($defaultContext = [], int $loadOptions = null, array $decoderIgnoredNodeTypes = [XML_PI_NODE, XML_COMMENT_NODE], array $encoderIgnoredNodeTypes = [])
public function __construct(array $defaultContext = [])
{
if (!\is_array($defaultContext)) {
@trigger_error('Passing configuration options directly to the constructor is deprecated since Symfony 4.2, use the default context instead.', E_USER_DEPRECATED);

$defaultContext = [
self::DECODER_IGNORED_NODE_TYPES => $decoderIgnoredNodeTypes,
self::ENCODER_IGNORED_NODE_TYPES => $encoderIgnoredNodeTypes,
self::LOAD_OPTIONS => $loadOptions ?? LIBXML_NONET | LIBXML_NOBLANKS,
self::ROOT_NODE_NAME => (string) $defaultContext,
];
}

$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
}

Expand Down Expand Up @@ -203,34 +189,6 @@ public function supportsDecoding($format)
return self::FORMAT === $format;
}

/**
* Sets the root node name.
*
* @deprecated since Symfony 4.2
*
* @param string $name Root node name
*/
public function setRootNodeName($name)
{
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the context instead.', __METHOD__), E_USER_DEPRECATED);

$this->defaultContext[self::ROOT_NODE_NAME] = $name;
}

/**
* Returns the root node name.
*
* @deprecated since Symfony 4.2
*
* @return string
*/
public function getRootNodeName()
{
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the context instead.', __METHOD__), E_USER_DEPRECATED);

return $this->defaultContext[self::ROOT_NODE_NAME];
}

final protected function appendXMLString(\DOMNode $node, string $val): bool
{
if ('' !== $val) {
Expand Down
113 changes: 5 additions & 108 deletions src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,22 +118,11 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn

protected $defaultContext = [
self::ALLOW_EXTRA_ATTRIBUTES => true,
self::CIRCULAR_REFERENCE_HANDLER => null,
self::CIRCULAR_REFERENCE_LIMIT => 1,
self::IGNORED_ATTRIBUTES => [],
];

/**
* @deprecated since Symfony 4.2
*/
protected $circularReferenceLimit = 1;

/**
* @deprecated since Symfony 4.2
*
* @var callable|null
*/
protected $circularReferenceHandler;

/**
* @var ClassMetadataFactoryInterface|null
*/
Expand All @@ -144,21 +133,6 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
*/
protected $nameConverter;

/**
* @deprecated since Symfony 4.2
*/
protected $callbacks = [];

/**
10000 * @deprecated since Symfony 4.2
*/
protected $ignoredAttributes = [];

/**
* @deprecated since Symfony 4.2
*/
protected $camelizedAttributes = [];

/**
* Sets the {@link ClassMetadataFactoryInterface} to use.
*/
Expand All @@ -185,83 +159,6 @@ public function __construct(ClassMetadataFactoryInterface $classMetadataFactory
}
}

/**
* Sets circular reference limit.
*
* @deprecated since Symfony 4.2
*
* @param int $circularReferenceLimit Limit of iterations for the same object
*
* @return self
*/
public function setCircularReferenceLimit($circularReferenceLimit)
{
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the "circular_reference_limit" key of the context instead.', __METHOD__), E_USER_DEPRECATED);

$this->defaultContext[self::CIRCULAR_REFERENCE_LIMIT] = $this->circularReferenceLimit = $circularReferenceLimit;

return $this;
}

/**
* Sets circular reference handler.
*
* @deprecated since Symfony 4.2
*
* @param callable $circularReferenceHandler
*
* @return self
*/
public function setCircularReferenceHandler(callable $circularReferenceHandler)
{
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the "circular_reference_handler" key of the context instead.', __METHOD__), E_USER_DEPRECATED);

$this->defaultContext[self::CIRCULAR_REFERENCE_HANDLER] = $this->circularReferenceHandler = $circularReferenceHandler;

return $this;
}

/**
* Sets normalization callbacks.
*
* @deprecated since Symfony 4.2
*
* @param callable[] $callbacks Help normalize the result
*
* @return self
*
* @throws InvalidArgumentException if a non-callable callback is set
*/
public function setCallbacks(array $callbacks)
{
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the "callbacks" key of the context instead.', __METHOD__), E_USER_DEPRECATED);

foreach ($callbacks as $attribute => $callback) {
if (!\is_callable($callback)) {
throw new InvalidArgumentException(sprintf('The given callback for attribute "%s" is not callable.', $attribute));
}
}
$this->defaultContext[self::CALLBACKS] = $this->callbacks = $callbacks;

return $this;
}

/**
* Sets ignored attributes for normalization and denormalization.
*
* @deprecated since Symfony 4.2
*
* @return self
*/
public function setIgnoredAttributes(array $ignoredAttributes)
{
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the "ignored_attributes" key of the context instead.', __METHOD__), E_USER_DEPRECATED);

$this->defaultContext[self::IGNORED_ATTRIBUTES] = $this->ignoredAttributes = $ignoredAttributes;

return $this;
}

/**
* {@inheritdoc}
*/
Expand All @@ -284,7 +181,7 @@ protected function isCircularReference($object, &$context)
{
$objectHash = spl_object_hash($object);

$circularReferenceLimit = $context[self::CIRCULAR_REFERENCE_LIMIT] ?? $this->defaultContext[self::CIRCULAR_REFERENCE_LIMIT] ?? $this->circularReferenceLimit;
$circularReferenceLimit = $context[self::CIRCULAR_REFERENCE_LIMIT] ?? $this->defaultContext[self::CIRCULAR_REFERENCE_LIMIT];
if (isset($context[self::CIRCULAR_REFERENCE_LIMIT_COUNTERS][$objectHash])) {
if ($context[self::CIRCULAR_REFERENCE_LIMIT_COUNTERS][$objectHash] >= $circularReferenceLimit) {
unset($context[self::CIRCULAR_REFERENCE_LIMIT_COUNTERS][$objectHash]);
Expand Down Expand Up @@ -324,12 +221,12 @@ protected function handleCircularReference($object/*, string $format = null, arr
$format = \func_num_args() > 1 ? func_get_arg(1) : null;
$context = \func_num_args() > 2 ? func_get_arg(2) : [];

$circularReferenceHandler = $context[self::CIRCULAR_REFERENCE_HANDLER] ?? $this->defaultContext[self::CIRCULAR_REFERENCE_HANDLER] ?? $this->circularReferenceHandler;
$circularReferenceHandler = $context[self::CIRCULAR_REFERENCE_HANDLER] ?? $this->defaultContext[self::CIRCULAR_REFERENCE_HANDLER];
if ($circularReferenceHandler) {
return $circularReferenceHandler($object, $format, $context);
}

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));
throw new CircularReferenceException(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d)', \get_class($object), $context[self::CIRCULAR_REFERENCE_LIMIT] ?? $this->defaultContext[self::CIRCULAR_REFERENCE_LIMIT]));
}

/**
Expand Down Expand Up @@ -387,7 +284,7 @@ protected function getAllowedAttributes($classOrObject, array $context, $attribu
*/
protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = [])
{
$ignoredAttributes = $context[self::IGNORED_ATTRIBUTES] ?? $this->defaultContext[self::IGNORED_ATTRIBUTES] ?? $this->ignoredAttributes;
$ignoredAttributes = $context[self::IGNORED_ATTRIBUTES] ?? $this->defaultContext[self::IGNORED_ATTRIBUTES];
if (\in_array($attribute, $ignoredAttributes)) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,6 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
private $typesCache = [];
private $attributesCache = [];

/**
* @deprecated since Symfony 4.2
*
* @var callable|null
*/
private $maxDepthHandler;
private $objectClassResolver;

/**
Expand Down Expand Up @@ -168,8 +162,7 @@ public function normalize($object, $format = null, array $context = [])
throw new InvalidArgumentException(sprintf('The "%s" given in the context is not callable.', self::MAX_DEPTH_HANDLER));
}
} else {
// already validated in constructor resp by type declaration of setMaxDepthHandler
$maxDepthHandler = $this->defaultContext[self::MAX_DEPTH_HANDLER] ?? $this->maxDepthHandler;
$maxDepthHandler = null;
}

foreach ($attributes as $attribute) {
Expand All @@ -186,7 +179,7 @@ public function normalize($object, $format = null, array $context = [])
/**
* @var callable|null
*/
$callback = $context[self::CALLBACKS][$attribute] ?? $this->defaultContext[self::CALLBACKS][$attribute] ?? $this->callbacks[$attribute] ?? null;
$callback = $context[self::CALLBACKS][$attribute] ?? $this->defaultContext[self::CALLBACKS][$attribute] ?? null;
if ($callback) {
$attributeValue = $callback($attributeValue, $object, $attribute, $format, $context);
}
Expand Down Expand Up @@ -295,18 +288,6 @@ abstract protected function extractAttributes($object, $format = null, array $co
*/
abstract protected function getAttributeValue($object, $attribute, $format = null, array $context = []);

/**
* Sets a handler function that will be called when the max depth is reached.
*
* @deprecated since Symfony 4.2
*/
public function setMaxDepthHandler(?callable $handler): void
{
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the "max_depth_handler" key of the context instead.', __METHOD__), E_USER_DEPRECATED);

E966 $this->maxDepthHandler = $handler;
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -595,8 +576,7 @@ private function getCacheKey(?string $format, array $context)
try {
return md5($format.serialize([
'context' => $context,
'ignored' => $this->ignoredAttributes,
'camelized' => $this->camelizedAttributes,
'ignored' => $context[self::IGNORED_ATTRIBUTES] ?? $this->defaultContext[self::IGNORED_ATTRIBUTES],
]));
} catch (\Exception $exception) {
// The context cannot be serialized, skip the cache
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,8 @@ class DateIntervalNormalizer implements NormalizerInterface, DenormalizerInterfa
self::FORMAT_KEY => 'P%yY%mM%dDT%hH%iM%sS',
];

/**
* @param array $defaultContext
*/
public function __construct($defaultContext = [])
public function __construct(array $defaultContext = [])
{
if (!\is_array($defaultContext)) {
@trigger_error(sprintf('The "format" parameter is deprecated since Symfony 4.2, use the "%s" key of the context instead.', self::FORMAT_KEY), E_USER_DEPRECATED);

$defaultContext = [self::FORMAT_KEY => (string) $defaultContext];
}

$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
}

Expand Down
Loading
0