----------
* 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
* 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
-----
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);
}
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);
}
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) {
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
*/
*/
protected $nameConverter;
- /**
- * @deprecated since Symfony 4.2
- */
- protected $callbacks = [];
-
- /**
- * @deprecated since Symfony 4.2
- */
- protected $ignoredAttributes = [];
-
- /**
- * @deprecated since Symfony 4.2
- */
- protected $camelizedAttributes = [];
-
/**
* Sets the {@link ClassMetadataFactoryInterface} to use.
*/
}
}
- /**
- * 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}
*/
{
$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]);
$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]));
}
/**
*/
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;
}
private $typesCache = [];
private $attributesCache = [];
- /**
- * @deprecated since Symfony 4.2
- *
- * @var callable|null
- */
- private $maxDepthHandler;
private $objectClassResolver;
/**
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) {
/**
* @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);
}
*/
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);
-
- $this->maxDepthHandler = $handler;
- }
-
/**
* {@inheritdoc}
*/
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
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);
}
const FORMAT_KEY = 'datetime_format';
const TIMEZONE_KEY = 'datetime_timezone';
- private $defaultContext;
+ private $defaultContext = [
+ self::FORMAT_KEY => \DateTime::RFC3339,
+ self::TIMEZONE_KEY => null,
+ ];
private static $supportedTypes = [
\DateTimeInterface::class => true,
\DateTime::class => true,
];
- /**
- * @param array $defaultContext
- */
- public function __construct($defaultContext = [], \DateTimeZone $timezone = null)
+ public function __construct(array $defaultContext = [])
{
- $this->defaultContext = [
- self::FORMAT_KEY => \DateTime::RFC3339,
- self::TIMEZONE_KEY => null,
- ];
-
- 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::FORMAT_KEY => (string) $defaultContext];
- $defaultContext[self::TIMEZONE_KEY] = $timezone;
- }
-
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
}
public function testEncodeCustomSettings()
{
- $this->doTestEncodeCustomSettings();
- }
-
- public function testLegacyEncodeCustomSettings()
- {
- $this->doTestEncodeCustomSettings(true);
- }
-
- private function doTestEncodeCustomSettings(bool $legacy = false)
- {
- if ($legacy) {
- $this->encoder = new CsvEncoder(';', "'", '|', '-');
- } else {
- $this->encoder = new CsvEncoder([
- CsvEncoder::DELIMITER_KEY => ';',
- CsvEncoder::ENCLOSURE_KEY => "'",
- CsvEncoder::ESCAPE_CHAR_KEY => '|',
- CsvEncoder::KEY_SEPARATOR_KEY => '-',
- ]);
- }
+ $this->encoder = new CsvEncoder([
+ CsvEncoder::DELIMITER_KEY => ';',
+ CsvEncoder::ENCLOSURE_KEY => "'",
+ CsvEncoder::ESCAPE_CHAR_KEY => '|',
+ CsvEncoder::KEY_SEPARATOR_KEY => '-',
+ ]);
$value = ['a' => 'he\'llo', 'c' => ['d' => 'foo']];
public function testEncodeFormulas()
{
- $this->doTestEncodeFormulas();
- }
-
- public function testLegacyEncodeFormulas()
- {
- $this->doTestEncodeFormulas(true);
- }
-
- private function doTestEncodeFormulas(bool $legacy = false)
- {
- if ($legacy) {
- $this->encoder = new CsvEncoder(',', '"', '\\', '.', true);
- } else {
- $this->encoder = new CsvEncoder([CsvEncoder::ESCAPE_FORMULAS_KEY => true]);
- }
+ $this->encoder = new CsvEncoder([CsvEncoder::ESCAPE_FORMULAS_KEY => true]);
$this->assertSame(<<<'CSV'
0
public function testDecodeCustomSettings()
{
- $this->doTestDecodeCustomSettings();
- }
-
- public function testLegacyDecodeCustomSettings()
- {
- $this->doTestDecodeCustomSettings(true);
- }
-
- private function doTestDecodeCustomSettings(bool $legacy = false)
- {
- if ($legacy) {
- $this->encoder = new CsvEncoder(';', "'", '|', '-');
- } else {
- $this->encoder = new CsvEncoder([
- CsvEncoder::DELIMITER_KEY => ';',
- CsvEncoder::ENCLOSURE_KEY => "'",
- CsvEncoder::ESCAPE_CHAR_KEY => '|',
- CsvEncoder::KEY_SEPARATOR_KEY => '-',
- ]);
- }
+ $this->encoder = new CsvEncoder([
+ CsvEncoder::DELIMITER_KEY => ';',
+ CsvEncoder::ENCLOSURE_KEY => "'",
+ CsvEncoder::ESCAPE_CHAR_KEY => '|',
+ CsvEncoder::KEY_SEPARATOR_KEY => '-',
+ ]);
$expected = [['a' => 'hell\'o', 'bar' => ['baz' => 'b']]];
$this->assertEquals($expected, $this->encoder->decode(<<<'CSV'
$this->assertEquals($expected, $this->encoder->encode($obj, 'xml'));
}
- /**
- * @group legacy
- */
- public function testSetRootNodeName()
- {
- $obj = new ScalarDummy();
- $obj->xmlFoo = 'foo';
-
- $this->encoder->setRootNodeName('test');
- $expected = '<?xml version="1.0"?>'."\n".
- '<test>foo</test>'."\n";
-
- $this->assertEquals($expected, $this->encoder->encode($obj, 'xml'));
- }
-
/**
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
* @expectedExceptionMessage Document types are not allowed.
}
public function testDecodePreserveComments()
- {
- $this->doTestDecodePreserveComments();
- }
-
- public function testLegacyDecodePreserveComments()
- {
- $this->doTestDecodePreserveComments(true);
- }
-
- private function doTestDecodePreserveComments(bool $legacy = false)
{
$source = <<<'XML'
<?xml version="1.0"?>
</people>
XML;
- if ($legacy) {
- $this->encoder = new XmlEncoder('people', null, [XML_PI_NODE]);
- } else {
- $this->encoder = new XmlEncoder([
- XmlEncoder::ROOT_NODE_NAME => 'people',
- XmlEncoder::DECODER_IGNORED_NODE_TYPES => [XML_PI_NODE],
- ]);
- }
+ $this->encoder = new XmlEncoder([
+ XmlEncoder::ROOT_NODE_NAME => 'people',
+ XmlEncoder::DECODER_IGNORED_NODE_TYPES => [XML_PI_NODE],
+ ]);
$serializer = new Serializer([new CustomNormalizer()], ['xml' => new XmlEncoder()]);
$this->encoder->setSerializer($serializer);
public function testDecodeAlwaysAsCollection()
{
- $this->doTestDecodeAlwaysAsCollection();
- }
-
- public function testLegacyDecodeAlwaysAsCollection()
- {
- $this->doTestDecodeAlwaysAsCollection(true);
- }
-
- private function doTestDecodeAlwaysAsCollection(bool $legacy = false)
- {
- if ($legacy) {
- $this->encoder = new XmlEncoder('response', null);
- } else {
- $this->encoder = new XmlEncoder([XmlEncoder::ROOT_NODE_NAME => 'response']);
- }
+ $this->encoder = new XmlEncoder([XmlEncoder::ROOT_NODE_NAME => 'response']);
$serializer = new Serializer([new CustomNormalizer()], ['xml' => new XmlEncoder()]);
$this->encoder->setSerializer($serializer);
public function testEncodeWithoutPi()
{
- $this->doTestEncodeWithoutPi();
- }
-
- public function testLegacyEncodeWithoutPi()
- {
- $this->doTestEncodeWithoutPi(true);
- }
-
- private function doTestEncodeWithoutPi(bool $legacy = false)
- {
- if ($legacy) {
- $encoder = new XmlEncoder('response', null, [], [XML_PI_NODE]);
- } else {
- $encoder = new XmlEncoder([
- XmlEncoder::ROOT_NODE_NAME => 'response',
- XmlEncoder::ENCODER_IGNORED_NODE_TYPES => [XML_PI_NODE],
- ]);
- }
+ $encoder = new XmlEncoder([
+ XmlEncoder::ROOT_NODE_NAME => 'response',
+ XmlEncoder::ENCODER_IGNORED_NODE_TYPES => [XML_PI_NODE],
+ ]);
$expected = '<response/>';
public function testEncodeWithoutComment()
{
- $this->doTestEncodeWithoutComment();
- }
-
- public function testLegacyEncodeWithoutComment()
- {
- $this->doTestEncodeWithoutComment(true);
- }
-
- private function doTestEncodeWithoutComment(bool $legacy = false)
- {
- if ($legacy) {
- $encoder = new XmlEncoder('response', null, [], [XML_COMMENT_NODE]);
- } else {
- $encoder = new XmlEncoder([
- XmlEncoder::ROOT_NODE_NAME => 'response',
- XmlEncoder::ENCODER_IGNORED_NODE_TYPES => [XML_COMMENT_NODE],
- ]);
- }
+ $encoder = new XmlEncoder([
+ XmlEncoder::ROOT_NODE_NAME => 'response',
+ XmlEncoder::ENCODER_IGNORED_NODE_TYPES => [XML_COMMENT_NODE],
+ ]);
$expected = <<<'XML'
<?xml version="1.0"?>
*/
public function testNormalizeUsingFormatPassedInConstructor($format, $output, $input)
{
- $this->doTestNormalizeUsingFormatPassedInConstructor($format, $output, $input);
- }
-
- /**
- * @dataProvider dataProviderISO
- */
- public function testLegacyNormalizeUsingFormatPassedInConstructor($format, $output, $input)
- {
- $this->doTestNormalizeUsingFormatPassedInConstructor($format, $output, $input, true);
- }
-
- private function doTestNormalizeUsingFormatPassedInConstructor($format, $output, $input, bool $legacy = false)
- {
- $normalizer = $legacy ? new DateIntervalNormalizer($format) : new DateIntervalNormalizer([DateIntervalNormalizer::FORMAT_KEY => $format]);
+ $normalizer = new DateIntervalNormalizer([DateIntervalNormalizer::FORMAT_KEY => $format]);
$this->assertEquals($output, $normalizer->normalize(new \DateInterval($input)));
}
*/
public function testDenormalizeUsingFormatPassedInConstructor($format, $input, $output)
{
- $this->doTestDenormalizeUsingFormatPassedInConstructor($format, $input, $output);
- }
-
- /**
- * @dataProvider dataProviderISO
- */
- public function testLegacyDenormalizeUsingFormatPassedInConstructor($format, $input, $output)
- {
- $this->doTestDenormalizeUsingFormatPassedInConstructor($format, $input, $output, true);
- }
-
- private function doTestDenormalizeUsingFormatPassedInConstructor($format, $input, $output, bool $legacy = false)
- {
- $normalizer = $legacy ? new DateIntervalNormalizer($format) : new DateIntervalNormalizer([DateIntervalNormalizer::FORMAT_KEY => $format]);
+ $normalizer = new DateIntervalNormalizer([DateIntervalNormalizer::FORMAT_KEY => $format]);
$this->assertDateIntervalEquals(new \DateInterval($output), $normalizer->denormalize($input, \DateInterval::class));
}
public function testNormalizeUsingFormatPassedInConstructor()
{
- $this->doTestNormalizeUsingFormatPassedInConstructor();
- }
-
- public function testLegacyNormalizeUsingFormatPassedInConstructor()
- {
- $this->doTestNormalizeUsingFormatPassedInConstructor(true);
- }
-
- private function doTestNormalizeUsingFormatPassedInConstructor(bool $legacy = false)
- {
- $normalizer = $legacy ? new DateTimeNormalizer('y') : new DateTimeNormalizer([DateTimeNormalizer::FORMAT_KEY => 'y']);
+ $normalizer = new DateTimeNormalizer([DateTimeNormalizer::FORMAT_KEY => 'y']);
$this->assertEquals('16', $normalizer->normalize(new \DateTime('2016/01/01', new \DateTimeZone('UTC'))));
}
public function testNormalizeUsingTimeZonePassedInConstructor()
{
- $this->doTestNormalizeUsingTimeZonePassedInConstructor();
- }
-
- public function testLegacyNormalizeUsingTimeZonePassedInConstructor()
- {
- $this->doTestNormalizeUsingTimeZonePassedInConstructor(true);
- }
-
- private function doTestNormalizeUsingTimeZonePassedInConstructor(bool $legacy = false)
- {
- if ($legacy) {
- $normalizer = new DateTimeNormalizer(\DateTime::RFC3339, new \DateTimeZone('Japan'));
- } else {
- $normalizer = new DateTimeNormalizer([DateTimeNormalizer::TIMEZONE_KEY => new \DateTimeZone('Japan')]);
- }
+ $normalizer = new DateTimeNormalizer([DateTimeNormalizer::TIMEZONE_KEY => new \DateTimeZone('Japan')]);
$this->assertSame('2016-12-01T00:00:00+09:00', $normalizer->normalize(new \DateTime('2016/12/01', new \DateTimeZone('Japan'))));
$this->assertSame('2016-12-01T09:00:00+09:00', $normalizer->normalize(new \DateTime('2016/12/01', new \DateTimeZone('UTC'))));
}
public function testDenormalizeUsingTimezonePassedInConstructor()
- {
- $this->doTestDenormalizeUsingTimezonePassedInConstructor();
- }
-
- public function testLegacyDenormalizeUsingTimezonePassedInConstructor()
- {
- $this->doTestDenormalizeUsingTimezonePassedInConstructor(true);
- }
-
- private function doTestDenormalizeUsingTimezonePassedInConstructor(bool $legacy = false)
{
$timezone = new \DateTimeZone('Japan');
$expected = new \DateTime('2016/12/01 17:35:00', $timezone);
- $normalizer = $legacy ? new DateTimeNormalizer(null, $timezone) : new DateTimeNormalizer([DateTimeNormalizer::TIMEZONE_KEY => $timezone]);
+ $normalizer = new DateTimeNormalizer([DateTimeNormalizer::TIMEZONE_KEY => $timezone]);
$this->assertEquals($expected, $normalizer->denormalize('2016.12.01 17:35:00', \DateTime::class, null, [
DateTimeNormalizer::FORMAT_KEY => 'Y.m.d H:i:s',
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
-use Symfony\Component\Serializer\Exception\CircularReferenceException;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy;
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
use Symfony\Component\Serializer\Tests\Fixtures\SiblingHolder;
-use Symfony\Component\Serializer\Tests\Normalizer\Features\CallbacksObject;
use Symfony\Component\Serializer\Tests\Normalizer\Features\CallbacksTestTrait;
use Symfony\Component\Serializer\Tests\Normalizer\Features\CircularReferenceTestTrait;
use Symfony\Component\Serializer\Tests\Normalizer\Features\ConstructorArgumentsTestTrait;
->expects($this->once())
->method('normalize')
->with($object, 'any')
- ->will($this->returnValue('string_object'))
+ ->willReturn('string_object')
;
$this->assertEquals(
return new GetSetMethodNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory));
}
- /**
- * @dataProvider provideCallbacks
- */
- public function testLegacyCallbacks($callbacks, $value, $result)
- {
- $this->normalizer->setCallbacks($callbacks);
-
- $obj = new CallbacksObject($value);
- $this->assertEquals(
- $result,
- $this->normalizer->normalize($obj, 'any')
- );
- }
-
protected function getNormalizerForCircularReference(): GetSetMethodNormalizer
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
return new CircularReferenceDummy();
}
- public function testLegacyUnableToNormalizeCircularReference()
- {
- $this->normalizer->setCircularReferenceLimit(2);
- $this->serializer = new Serializer([$this->normalizer]);
- $this->normalizer->setSerializer($this->serializer);
-
- $obj = new CircularReferenceDummy();
-
- $this->expectException(CircularReferenceException::class);
- $this->normalizer->normalize($obj);
- }
-
- public function testLegacyCircularReferenceHandler()
- {
- $handler = function ($obj) {
- return \get_class($obj);
- };
-
- $this->normalizer->setCircularReferenceHandler($handler);
- $this->serializer = new Serializer([$this->normalizer]);
- $this->normalizer->setSerializer($this->serializer);
-
- $obj = new CircularReferenceDummy();
-
- $expected = ['me' => CircularReferenceDummy::class];
- $this->assertEquals($expected, $this->normalizer->normalize($obj));
- }
-
protected function getDenormalizerForConstructArguments(): GetSetMethodNormalizer
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
return $normalizer;
}
- public function testLegacyIgnoredAttributes()
- {
- $ignoredAttributes = ['foo', 'bar', 'baz', 'camelCase', 'object'];
- $this->normalizer->setIgnoredAttributes($ignoredAttributes);
-
- $obj = new GetSetDummy();
- $obj->setFoo('foo');
- $obj->setBar('bar');
- $obj->setBaz(true);
-
- $this->assertEquals(
- ['fooBar' => 'foobar'],
- $this->normalizer->normalize($obj, 'any')
- );
- }
-
/**
* @expectedException \Symfony\Component\Serializer\Exception\LogicException
* @expectedExceptionMessage Cannot normalize attribute "object" because the injected serializer is not a normalizer
}
}
-class GetCamelizedDummy
-{
- private $kevinDunglas;
- private $fooBar;
- private $bar_foo;
-
- public function __construct($kevinDunglas = null)
- {
- $this->kevinDunglas = $kevinDunglas;
- }
-
- public function getKevinDunglas()
- {
- return $this->kevinDunglas;
- }
-
- public function setFooBar($fooBar)
- {
- $this->fooBar = $fooBar;
- }
-
- public function getFooBar()
- {
- return $this->fooBar;
- }
-
- public function setBar_foo($bar_foo)
- {
- $this->bar_foo = $bar_foo;
- }
-
- public function getBar_foo()
- {
- return $this->bar_foo;
- }
-}
-
class ObjectConstructorArgsWithPrivateMutatorDummy
{
private $foo;
$this->serializer
->expects($this->once())
->method('normalize')
- ->will($this->returnCallback(function ($data) {
+ ->willReturnCallback(function ($data) {
$this->assertArraySubset(['foo' => 'a', 'bar' => 'b', 'baz' => 'c'], $data);
return 'string_object';
- }))
+ })
;
$this->assertEquals('string_object', $this->normalizer->normalize(new JsonSerializableDummy()));
*/
public function testCircularNormalize()
{
- $this->doTestCircularNormalize();
- }
-
- /**
- * @expectedException \Symfony\Component\Serializer\Exception\CircularReferenceException
- */
- public function testLegacyCircularNormalize()
- {
- $this->doTestCircularNormalize(true);
- }
-
- /**
- * @expectedException \Symfony\Component\Serializer\Exception\CircularReferenceException
- */
- private function doTestCircularNormalize(bool $legacy = false)
- {
- $legacy ? $this->normalizer->setCircularReferenceLimit(1) : $this->createNormalizer([JsonSerializableNormalizer::CIRCULAR_REFERENCE_LIMIT => 1]);
+ $this->createNormalizer([JsonSerializableNormalizer::CIRCULAR_REFERENCE_LIMIT => 1]);
$this->serializer
->expects($this->once())
->method('normalize')
- ->will($this->returnCallback(function ($data, $format, $context) {
+ ->willReturnCallback(function ($data, $format, $context) {
$this->normalizer->normalize($data['qux'], $format, $context);
return 'string_object';
- }))
+ })
;
$this->assertEquals('string_object', $this->normalizer->normalize(new JsonSerializableDummy()));
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
-use Symfony\Component\Serializer\Exception\CircularReferenceException;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy;
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
-use Symfony\Component\Serializer\Tests\Fixtures\MaxDepthDummy;
use Symfony\Component\Serializer\Tests\Fixtures\SiblingHolder;
use Symfony\Component\Serializer\Tests\Normalizer\Features\AttributesTestTrait;
-use Symfony\Component\Serializer\Tests\Normalizer\Features\CallbacksObject;
use Symfony\Component\Serializer\Tests\Normalizer\Features\CallbacksTestTrait;
use Symfony\Component\Serializer\Tests\Normalizer\Features\CircularReferenceTestTrait;
use Symfony\Component\Serializer\Tests\Normalizer\Features\ConstructorArgumentsTestTrait;
->expects($this->once())
->method('normalize')
->with($object, 'any')
- ->will($this->returnValue('string_object'))
+ ->willReturn('string_object')
;
$this->assertEquals(
return new ObjectNormalizer();
}
- /**
- * @dataProvider provideCallbacks
- */
- public function testLegacyCallbacks($callbacks, $value, $result)
- {
- $this->normalizer->setCallbacks($callbacks);
- $obj = new CallbacksObject($value);
-
- $this->assertEquals(
- $result,
- $this->normalizer->normalize($obj, 'any')
- );
- }
-
- /**
- * @dataProvider provideInvalidCallbacks
- */
- public function testLegacyUncallableCallbacks($callbacks)
- {
- $this->expectException(\InvalidArgumentException::class);
-
- $this->normalizer->setCallbacks($callbacks);
- }
-
// circular reference
protected function getNormalizerForCircularReference(): ObjectNormalizer
return new CircularReferenceDummy();
}
- public function testLegacyUnableToNormalizeCircularReference()
- {
- $this->normalizer->setCircularReferenceLimit(2);
- $serializer = new Serializer([$this->normalizer]);
- $this->normalizer->setSerializer($serializer);
-
- $obj = new CircularReferenceDummy();
-
- $this->expectException(CircularReferenceException::class);
- $this->normalizer->normalize($obj);
- }
-
public function testSiblingReference()
{
$serializer = new Serializer([$this->normalizer]);
$this->assertEquals($expected, $this->normalizer->normalize($siblingHolder));
}
- public function testLegacyCircularReferenceHandler()
- {
- new Serializer([$this->normalizer]);
-
- $obj = new CircularReferenceDummy();
- $expected = ['me' => CircularReferenceDummy::class];
-
- $this->normalizer->setCircularReferenceHandler(function ($obj, string $format, array $context) {
- $this->assertInstanceOf(CircularReferenceDummy::class, $obj);
- $this->assertSame('test', $format);
- $this->assertArrayHasKey('foo', $context);
-
- return \get_class($obj);
- });
- $this->assertEquals($expected, $this->normalizer->normalize($obj, 'test', ['foo' => 'bar']));
- }
-
// constructor arguments
protected function getDenormalizerForConstructArguments(): ObjectNormalizer
return $normalizer;
}
- public function testLegacyIgnoredAttributes()
- {
- $ignoredAttributes = ['foo', 'bar', 'baz', 'camelCase', 'object'];
- $this->normalizer->setIgnoredAttributes($ignoredAttributes);
-
- $obj = new ObjectDummy();
- $obj->setFoo('foo');
- $obj->bar = 'bar';
- $obj->setBaz(true);
-
- $this->assertEquals(
- ['fooBar' => 'foobar'],
- $this->normalizer->normalize($obj, 'any')
- );
-
- $ignoredAttributes = ['foo', 'baz', 'camelCase', 'object'];
- $this->normalizer->setIgnoredAttributes($ignoredAttributes);
-
- $this->assertEquals(
- [
- 'fooBar' => 'foobar',
- 'bar' => 'bar',
- ],
- $this->normalizer->normalize($obj, 'any')
- );
- }
-
- public function testLegacyIgnoredAttributesDenormalize()
- {
- $ignoredAttributes = ['fooBar', 'bar', 'baz'];
- $this->normalizer->setIgnoredAttributes($ignoredAttributes);
-
- $obj = new ObjectDummy();
- $obj->setFoo('foo');
-
- $this->assertEquals(
- $obj,
- $this->normalizer->denormalize(['fooBar' => 'fooBar', 'foo' => 'foo', 'baz' => 'baz'], ObjectDummy::class)
- );
- }
-
// max depth
protected function getNormalizerForMaxDepth(): ObjectNormalizer
return $normalizer;
}
- public function testLegacyMaxDepth()
- {
- $level1 = new MaxDepthDummy();
- $level1->foo = 'level1';
-
- $level2 = new MaxDepthDummy();
- $level2->foo = 'level2';
- $level1->child = $level2;
-
- $level3 = new MaxDepthDummy();
- $level3->foo = 'level3';
- $level2->child = $level3;
-
- $this->createNormalizerWithMaxDepthHandler(null);
- $result = $this->serializer->normalize($level1, null, [ObjectNormalizer::ENABLE_MAX_DEPTH => true]);
-
- $expected = [
- 'bar' => null,
- 'foo' => 'level1',
- 'child' => [
- 'bar' => null,
- 'foo' => 'level2',
- 'child' => [
- 'bar' => null,
- 'child' => null,
- ],
- ],
- ];
-
- $this->assertEquals($expected, $result);
-
- $expected = [
- 'bar' => null,
- 'foo' => 'level1',
- 'child' => [
- 'bar' => null,
- 'foo' => 'level2',
- 'child' => [
- 'bar' => null,
- 'child' => null,
- 'foo' => 'handler',
- ],
- ],
- ];
-
- $this->createNormalizerWithMaxDepthHandler(function () {
- return 'handler';
- });
- $result = $this->serializer->normalize($level1, null, [ObjectNormalizer::ENABLE_MAX_DEPTH => true]);
- $this->assertEquals($expected, $result);
-
- $this->createNormalizerWithMaxDepthHandler(function ($object, $parentObject, $attributeName, $format, $context) {
- $this->assertSame('level3', $object);
- $this->assertInstanceOf(MaxDepthDummy::class, $parentObject);
- $this->assertSame('foo', $attributeName);
- $this->assertSame('test', $format);
- $this->assertArrayHasKey(ObjectNormalizer::ENABLE_MAX_DEPTH, $context);
-
- return 'handler';
- });
- $this->serializer->normalize($level1, 'test', [ObjectNormalizer::ENABLE_MAX_DEPTH => true]);
- }
-
- private function createNormalizerWithMaxDepthHandler(callable $handler = null)
- {
- $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
- $this->createNormalizer([], $classMetadataFactory);
- if (null !== $handler) {
- $this->normalizer->setMaxDepthHandler($handler);
- }
- $this->serializer = new Serializer([$this->normalizer]);
- $this->normalizer->setSerializer($this->serializer);
- }
-
// object to populate
protected function getDenormalizerForObjectToPopulate(): ObjectNormalizer
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
-use Symfony\Component\Serializer\Exception\CircularReferenceException;
-use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummyChild;
use Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy;
use Symfony\Component\Serializer\Tests\Fixtures\PropertySiblingHolder;
-use Symfony\Component\Serializer\Tests\Normalizer\Features\CallbacksObject;
use Symfony\Component\Serializer\Tests\Normalizer\Features\CallbacksTestTrait;
use Symfony\Component\Serializer\Tests\Normalizer\Features\CircularReferenceTestTrait;
use Symfony\Component\Serializer\Tests\Normalizer\Features\ConstructorArgumentsTestTrait;
return new PropertyNormalizer();
}
- /**
- * @dataProvider provideCallbacks
- */
- public function testLegacyCallbacks($callbacks, $value, $result)
- {
- $this->normalizer->setCallbacks($callbacks);
-
- $obj = new CallbacksObject($value);
-
- $this->assertEquals(
- $result,
- $this->normalizer->normalize($obj, 'any')
- );
- }
-
- /**
- * @dataProvider provideInvalidCallbacks
- */
- public function testLegacyUncallableCallbacks($callbacks)
- {
- $this->expectException(InvalidArgumentException::class);
-
- $this->normalizer->setCallbacks($callbacks);
- }
-
protected function getNormalizerForCircularReference(): PropertyNormalizer
{
$normalizer = new PropertyNormalizer();
return new PropertyCircularReferenceDummy();
}
- public function testLegacyUnableToNormalizeCircularReference()
- {
- $this->normalizer->setCircularReferenceLimit(2);
- new Serializer([$this->normalizer]);
-
- $obj = new PropertyCircularReferenceDummy();
-
- $this->expectException(CircularReferenceException::class);
- $this->normalizer->normalize($obj);
- }
-
public function testSiblingReference()
{
$serializer = new Serializer([$this->normalizer]);
$this->assertEquals($expected, $this->normalizer->normalize($siblingHolder));
}
- public function testLegacyCircularReferenceHandler()
- {
- $this->normalizer->setCircularReferenceHandler(function ($obj) {
- return \get_class($obj);
- });
-
- new Serializer([$this->normalizer]);
-
- $obj = new PropertyCircularReferenceDummy();
-
- $expected = ['me' => PropertyCircularReferenceDummy::class];
- $this->assertEquals($expected, $this->normalizer->normalize($obj));
- }
-
protected function getDenormalizerForConstructArguments(): PropertyNormalizer
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$this->markTestSkipped('This has not been tested previously - did not manage to make the test work');
}
- public function testLegacyIgnoredAttributes()
- {
- $ignoredAttributes = ['foo', 'bar', 'camelCase'];
- $this->normalizer->setIgnoredAttributes($ignoredAttributes);
-
- $obj = new PropertyDummy();
- $obj->foo = 'foo';
- $obj->setBar('bar');
-
- $this->assertEquals(
- [],
- $this->normalizer->normalize($obj, 'any')
- );
- }
-
protected function getNormalizerForMaxDepth(): PropertyNormalizer
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
}
}
-class PropertyCamelizedDummy
-{
- private $kevinDunglas;
- public $fooBar;
- public $bar_foo;
-
- public function __construct($kevinDunglas = null)
- {
- $this->kevinDunglas = $kevinDunglas;
- }
-}
-
class StaticPropertyDummy
{
private static $property = 'value';