Update Composer, update everything
This commit is contained in:
parent
ea3e94409f
commit
dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions
3
vendor/symfony/serializer/.gitignore
vendored
Normal file
3
vendor/symfony/serializer/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
59
vendor/symfony/serializer/Annotation/Groups.php
vendored
Normal file
59
vendor/symfony/serializer/Annotation/Groups.php
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?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\Annotation;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Annotation class for @Groups().
|
||||
*
|
||||
* @Annotation
|
||||
* @Target({"PROPERTY", "METHOD"})
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class Groups
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $groups;
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $data)
|
||||
{
|
||||
if (!isset($data['value']) || !$data['value']) {
|
||||
throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" cannot be empty.', \get_class($this)));
|
||||
}
|
||||
|
||||
$value = (array) $data['value'];
|
||||
foreach ($value as $group) {
|
||||
if (!\is_string($group)) {
|
||||
throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" must be a string or an array of strings.', \get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
$this->groups = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets groups.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getGroups()
|
||||
{
|
||||
return $this->groups;
|
||||
}
|
||||
}
|
48
vendor/symfony/serializer/Annotation/MaxDepth.php
vendored
Normal file
48
vendor/symfony/serializer/Annotation/MaxDepth.php
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?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\Annotation;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Annotation class for @MaxDepth().
|
||||
*
|
||||
* @Annotation
|
||||
* @Target({"PROPERTY", "METHOD"})
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class MaxDepth
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $maxDepth;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
if (!isset($data['value'])) {
|
||||
throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" should be set.', \get_class($this)));
|
||||
}
|
||||
|
||||
if (!\is_int($data['value']) || $data['value'] <= 0) {
|
||||
throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" must be a positive integer.', \get_class($this)));
|
||||
}
|
||||
|
||||
$this->maxDepth = $data['value'];
|
||||
}
|
||||
|
||||
public function getMaxDepth()
|
||||
{
|
||||
return $this->maxDepth;
|
||||
}
|
||||
}
|
131
vendor/symfony/serializer/CHANGELOG.md
vendored
Normal file
131
vendor/symfony/serializer/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,131 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
|
||||
3.4.0
|
||||
-----
|
||||
|
||||
* added `AbstractObjectNormalizer::DISABLE_TYPE_ENFORCEMENT` context option
|
||||
to disable throwing an `UnexpectedValueException` on a type mismatch
|
||||
* added support for serializing `DateInterval` objects
|
||||
* added getter for extra attributes in `ExtraAttributesException`
|
||||
* improved `CsvEncoder` to handle variable nested structures
|
||||
* CSV headers can be passed to the `CsvEncoder` via the `csv_headers` serialization context variable
|
||||
* added `$context` when checking for encoding, decoding and normalizing in `Serializer`
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
||||
* added `SerializerPass`
|
||||
|
||||
3.1.0
|
||||
-----
|
||||
|
||||
* added support for serializing objects that implement `JsonSerializable`
|
||||
* added the `DenormalizerAwareTrait` and `NormalizerAwareTrait` traits to
|
||||
support normalizer/denormalizer awareness
|
||||
* added the `DenormalizerAwareInterface` and `NormalizerAwareInterface`
|
||||
interfaces to support normalizer/denormalizer awareness
|
||||
* added a PSR-6 compatible adapter for caching metadata
|
||||
* added a `MaxDepth` option to limit the depth of the object graph when
|
||||
serializing objects
|
||||
* added support for serializing `SplFileInfo` objects
|
||||
* added support for serializing objects that implement `DateTimeInterface`
|
||||
* added `AbstractObjectNormalizer` as a base class for normalizers that deal
|
||||
with objects
|
||||
* added support to relation deserialization
|
||||
|
||||
2.7.0
|
||||
-----
|
||||
|
||||
* added support for serialization and deserialization groups including
|
||||
annotations, XML and YAML mapping.
|
||||
* added `AbstractNormalizer` to factorise code and ease normalizers development
|
||||
* added circular references handling for `PropertyNormalizer`
|
||||
* added support for a context key called `object_to_populate` in `AbstractNormalizer`
|
||||
to reuse existing objects in the deserialization process
|
||||
* added `NameConverterInterface` and `CamelCaseToSnakeCaseNameConverter`
|
||||
* [DEPRECATION] `GetSetMethodNormalizer::setCamelizedAttributes()` and
|
||||
`PropertyNormalizer::setCamelizedAttributes()` are replaced by
|
||||
`CamelCaseToSnakeCaseNameConverter`
|
||||
* [DEPRECATION] the `Exception` interface has been renamed to `ExceptionInterface`
|
||||
* added `ObjectNormalizer` leveraging the `PropertyAccess` component to normalize
|
||||
objects containing both properties and getters / setters / issers / hassers methods.
|
||||
* added `xml_type_cast_attributes` context option for allowing users to opt-out of typecasting
|
||||
xml attributes.
|
||||
|
||||
2.6.0
|
||||
-----
|
||||
|
||||
* added a new serializer: `PropertyNormalizer`. Like `GetSetMethodNormalizer`,
|
||||
this normalizer will map an object's properties to an array.
|
||||
* added circular references handling for `GetSetMethodNormalizer`
|
||||
|
||||
2.5.0
|
||||
-----
|
||||
|
||||
* added support for `is.*` getters in `GetSetMethodNormalizer`
|
||||
|
||||
2.4.0
|
||||
-----
|
||||
|
||||
* added `$context` support for XMLEncoder.
|
||||
* [DEPRECATION] JsonEncode and JsonDecode where modified to throw
|
||||
an exception if error found. No need for get*Error() functions
|
||||
|
||||
2.3.0
|
||||
-----
|
||||
|
||||
* added `GetSetMethodNormalizer::setCamelizedAttributes` to allow calling
|
||||
camel cased methods for underscored properties
|
||||
|
||||
2.2.0
|
||||
-----
|
||||
|
||||
* [BC BREAK] All Serializer, Normalizer and Encoder interfaces have been
|
||||
modified to include an optional `$context` array parameter.
|
||||
* The XML Root name can now be configured with the `xml_root_name`
|
||||
parameter in the context option to the `XmlEncoder`.
|
||||
* Options to `json_encode` and `json_decode` can be passed through
|
||||
the context options of `JsonEncode` and `JsonDecode` encoder/decoders.
|
||||
|
||||
2.1.0
|
||||
-----
|
||||
|
||||
* added DecoderInterface::supportsDecoding(),
|
||||
EncoderInterface::supportsEncoding()
|
||||
* removed NormalizableInterface::denormalize(),
|
||||
NormalizerInterface::denormalize(),
|
||||
NormalizerInterface::supportsDenormalization()
|
||||
* removed normalize() denormalize() encode() decode() supportsSerialization()
|
||||
supportsDeserialization() supportsEncoding() supportsDecoding()
|
||||
getEncoder() from SerializerInterface
|
||||
* Serializer now implements NormalizerInterface, DenormalizerInterface,
|
||||
EncoderInterface, DecoderInterface in addition to SerializerInterface
|
||||
* added DenormalizableInterface and DenormalizerInterface
|
||||
* [BC BREAK] changed `GetSetMethodNormalizer`'s key names from all lowercased
|
||||
to camelCased (e.g. `mypropertyvalue` to `myPropertyValue`)
|
||||
* [BC BREAK] convert the `item` XML tag to an array
|
||||
|
||||
``` xml
|
||||
<?xml version="1.0"?>
|
||||
<response>
|
||||
<item><title><![CDATA[title1]]></title></item><item><title><![CDATA[title2]]></title></item>
|
||||
</response>
|
||||
```
|
||||
|
||||
Before:
|
||||
|
||||
Array()
|
||||
|
||||
After:
|
||||
|
||||
Array(
|
||||
[item] => Array(
|
||||
[0] => Array(
|
||||
[title] => title1
|
||||
)
|
||||
[1] => Array(
|
||||
[title] => title2
|
||||
)
|
||||
)
|
||||
)
|
60
vendor/symfony/serializer/DependencyInjection/SerializerPass.php
vendored
Normal file
60
vendor/symfony/serializer/DependencyInjection/SerializerPass.php
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?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\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Adds all services with the tags "serializer.encoder" and "serializer.normalizer" as
|
||||
* encoders and normalizers to the "serializer" service.
|
||||
*
|
||||
* @author Javier Lopez <f12loalf@gmail.com>
|
||||
* @author Robin Chalas <robin.chalas@gmail.com>
|
||||
*/
|
||||
class SerializerPass implements CompilerPassInterface
|
||||
{
|
||||
use PriorityTaggedServiceTrait;
|
||||
|
||||
private $serializerService;
|
||||
private $normalizerTag;
|
||||
private $encoderTag;
|
||||
|
||||
public function __construct($serializerService = 'serializer', $normalizerTag = 'serializer.normalizer', $encoderTag = 'serializer.encoder')
|
||||
{
|
||||
$this->serializerService = $serializerService;
|
||||
$this->normalizerTag = $normalizerTag;
|
||||
$this->encoderTag = $encoderTag;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition($this->serializerService)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$normalizers = $this->findAndSortTaggedServices($this->normalizerTag, $container)) {
|
||||
throw new RuntimeException(sprintf('You must tag at least one service as "%s" to use the "%s" service.', $this->normalizerTag, $this->serializerService));
|
||||
}
|
||||
|
||||
$serializerDefinition = $container->getDefinition($this->serializerService);
|
||||
$serializerDefinition->replaceArgument(0, $normalizers);
|
||||
|
||||
if (!$encoders = $this->findAndSortTaggedServices($this->encoderTag, $container)) {
|
||||
throw new RuntimeException(sprintf('You must tag at least one service as "%s" to use the "%s" service.', $this->encoderTag, $this->serializerService));
|
||||
}
|
||||
|
||||
$serializerDefinition->replaceArgument(1, $encoders);
|
||||
}
|
||||
}
|
87
vendor/symfony/serializer/Encoder/ChainDecoder.php
vendored
Normal file
87
vendor/symfony/serializer/Encoder/ChainDecoder.php
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Decoder delegating the decoding to a chain of decoders.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
||||
*
|
||||
* @final since version 3.3.
|
||||
*/
|
||||
class ChainDecoder implements DecoderInterface /*, ContextAwareDecoderInterface*/
|
||||
{
|
||||
protected $decoders = array();
|
||||
protected $decoderByFormat = array();
|
||||
|
||||
public function __construct(array $decoders = array())
|
||||
{
|
||||
$this->decoders = $decoders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
final public function decode($data, $format, array $context = array())
|
||||
{
|
||||
return $this->getDecoder($format, $context)->decode($data, $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDecoding($format/*, array $context = array()*/)
|
||||
{
|
||||
$context = \func_num_args() > 1 ? func_get_arg(1) : array();
|
||||
|
||||
try {
|
||||
$this->getDecoder($format, $context);
|
||||
} catch (RuntimeException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the decoder supporting the format.
|
||||
*
|
||||
* @param string $format
|
||||
* @param array $context
|
||||
*
|
||||
* @return DecoderInterface
|
||||
*
|
||||
* @throws RuntimeException if no decoder is found
|
||||
*/
|
||||
private function getDecoder($format, array $context)
|
||||
{
|
||||
if (isset($this->decoderByFormat[$format])
|
||||
&& isset($this->decoders[$this->decoderByFormat[$format]])
|
||||
) {
|
||||
return $this->decoders[$this->decoderByFormat[$format]];
|
||||
}
|
||||
|
||||
foreach ($this->decoders as $i => $decoder) {
|
||||
if ($decoder->supportsDecoding($format, $context)) {
|
||||
$this->decoderByFormat[$format] = $i;
|
||||
|
||||
return $decoder;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('No decoder found for format "%s".', $format));
|
||||
}
|
||||
}
|
111
vendor/symfony/serializer/Encoder/ChainEncoder.php
vendored
Normal file
111
vendor/symfony/serializer/Encoder/ChainEncoder.php
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Encoder delegating the decoding to a chain of encoders.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
||||
*
|
||||
* @final since version 3.3.
|
||||
*/
|
||||
class ChainEncoder implements EncoderInterface /*, ContextAwareEncoderInterface*/
|
||||
{
|
||||
protected $encoders = array();
|
||||
protected $encoderByFormat = array();
|
||||
|
||||
public function __construct(array $encoders = array())
|
||||
{
|
||||
$this->encoders = $encoders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
final public function encode($data, $format, array $context = array())
|
||||
{
|
||||
return $this->getEncoder($format, $context)->encode($data, $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsEncoding($format/*, array $context = array()*/)
|
||||
{
|
||||
$context = \func_num_args() > 1 ? func_get_arg(1) : array();
|
||||
|
||||
try {
|
||||
$this->getEncoder($format, $context);
|
||||
} catch (RuntimeException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the normalization is needed for the given format.
|
||||
*
|
||||
* @param string $format
|
||||
* @param array $context
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function needsNormalization($format/*, array $context = array()*/)
|
||||
{
|
||||
$context = \func_num_args() > 1 ? func_get_arg(1) : array();
|
||||
$encoder = $this->getEncoder($format, $context);
|
||||
|
||||
if (!$encoder instanceof NormalizationAwareInterface) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($encoder instanceof self) {
|
||||
return $encoder->needsNormalization($format, $context);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the encoder supporting the format.
|
||||
*
|
||||
* @param string $format
|
||||
* @param array $context
|
||||
*
|
||||
* @return EncoderInterface
|
||||
*
|
||||
* @throws RuntimeException if no encoder is found
|
||||
*/
|
||||
private function getEncoder($format, array $context)
|
||||
{
|
||||
if (isset($this->encoderByFormat[$format])
|
||||
&& isset($this->encoders[$this->encoderByFormat[$format]])
|
||||
) {
|
||||
return $this->encoders[$this->encoderByFormat[$format]];
|
||||
}
|
||||
|
||||
foreach ($this->encoders as $i => $encoder) {
|
||||
if ($encoder->supportsEncoding($format, $context)) {
|
||||
$this->encoderByFormat[$format] = $i;
|
||||
|
||||
return $encoder;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('No encoder found for format "%s".', $format));
|
||||
}
|
||||
}
|
27
vendor/symfony/serializer/Encoder/ContextAwareDecoderInterface.php
vendored
Normal file
27
vendor/symfony/serializer/Encoder/ContextAwareDecoderInterface.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?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\Encoder;
|
||||
|
||||
/**
|
||||
* Adds the support of an extra $context parameter for the supportsDecoding method.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface ContextAwareDecoderInterface extends DecoderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param array $context options that decoders have access to
|
||||
*/
|
||||
public function supportsDecoding($format, array $context = array());
|
||||
}
|
27
vendor/symfony/serializer/Encoder/ContextAwareEncoderInterface.php
vendored
Normal file
27
vendor/symfony/serializer/Encoder/ContextAwareEncoderInterface.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?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\Encoder;
|
||||
|
||||
/**
|
||||
* Adds the support of an extra $context parameter for the supportsEncoding method.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface ContextAwareEncoderInterface extends EncoderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param array $context options that encoders have access to
|
||||
*/
|
||||
public function supportsEncoding($format, array $context = array());
|
||||
}
|
247
vendor/symfony/serializer/Encoder/CsvEncoder.php
vendored
Normal file
247
vendor/symfony/serializer/Encoder/CsvEncoder.php
vendored
Normal file
|
@ -0,0 +1,247 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Encodes CSV data.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
* @author Oliver Hoff <oliver@hofff.com>
|
||||
*/
|
||||
class CsvEncoder implements EncoderInterface, DecoderInterface
|
||||
{
|
||||
const FORMAT = 'csv';
|
||||
const DELIMITER_KEY = 'csv_delimiter';
|
||||
const ENCLOSURE_KEY = 'csv_enclosure';
|
||||
const ESCAPE_CHAR_KEY = 'csv_escape_char';
|
||||
const KEY_SEPARATOR_KEY = 'csv_key_separator';
|
||||
const HEADERS_KEY = 'csv_headers';
|
||||
|
||||
private $delimiter;
|
||||
private $enclosure;
|
||||
private $escapeChar;
|
||||
private $keySeparator;
|
||||
|
||||
/**
|
||||
* @param string $delimiter
|
||||
* @param string $enclosure
|
||||
* @param string $escapeChar
|
||||
* @param string $keySeparator
|
||||
*/
|
||||
public function __construct($delimiter = ',', $enclosure = '"', $escapeChar = '\\', $keySeparator = '.')
|
||||
{
|
||||
$this->delimiter = $delimiter;
|
||||
$this->enclosure = $enclosure;
|
||||
$this->escapeChar = $escapeChar;
|
||||
$this->keySeparator = $keySeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function encode($data, $format, array $context = array())
|
||||
{
|
||||
$handle = fopen('php://temp,', 'w+');
|
||||
|
||||
if (!\is_array($data)) {
|
||||
$data = array(array($data));
|
||||
} elseif (empty($data)) {
|
||||
$data = array(array());
|
||||
} else {
|
||||
// Sequential arrays of arrays are considered as collections
|
||||
$i = 0;
|
||||
foreach ($data as $key => $value) {
|
||||
if ($i !== $key || !\is_array($value)) {
|
||||
$data = array($data);
|
||||
break;
|
||||
}
|
||||
|
||||
++$i;
|
||||
}
|
||||
}
|
||||
|
||||
list($delimiter, $enclosure, $escapeChar, $keySeparator, $headers) = $this->getCsvOptions($context);
|
||||
|
||||
foreach ($data as &$value) {
|
||||
$flattened = array();
|
||||
$this->flatten($value, $flattened, $keySeparator);
|
||||
$value = $flattened;
|
||||
}
|
||||
unset($value);
|
||||
|
||||
$headers = array_merge(array_values($headers), array_diff($this->extractHeaders($data), $headers));
|
||||
|
||||
fputcsv($handle, $headers, $delimiter, $enclosure, $escapeChar);
|
||||
|
||||
$headers = array_fill_keys($headers, '');
|
||||
foreach ($data as $row) {
|
||||
fputcsv($handle, array_replace($headers, $row), $delimiter, $enclosure, $escapeChar);
|
||||
}
|
||||
|
||||
rewind($handle);
|
||||
$value = stream_get_contents($handle);
|
||||
fclose($handle);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsEncoding($format)
|
||||
{
|
||||
return self::FORMAT === $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decode($data, $format, array $context = array())
|
||||
{
|
||||
$handle = fopen('php://temp', 'r+');
|
||||
fwrite($handle, $data);
|
||||
rewind($handle);
|
||||
|
||||
$headers = null;
|
||||
$nbHeaders = 0;
|
||||
$headerCount = array();
|
||||
$result = array();
|
||||
|
||||
list($delimiter, $enclosure, $escapeChar, $keySeparator) = $this->getCsvOptions($context);
|
||||
|
||||
while (false !== ($cols = fgetcsv($handle, 0, $delimiter, $enclosure, $escapeChar))) {
|
||||
$nbCols = \count($cols);
|
||||
|
||||
if (null === $headers) {
|
||||
$nbHeaders = $nbCols;
|
||||
|
||||
foreach ($cols as $col) {
|
||||
$header = explode($keySeparator, $col);
|
||||
$headers[] = $header;
|
||||
$headerCount[] = \count($header);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = array();
|
||||
for ($i = 0; ($i < $nbCols) && ($i < $nbHeaders); ++$i) {
|
||||
$depth = $headerCount[$i];
|
||||
$arr = &$item;
|
||||
for ($j = 0; $j < $depth; ++$j) {
|
||||
// Handle nested arrays
|
||||
if ($j === ($depth - 1)) {
|
||||
$arr[$headers[$i][$j]] = $cols[$i];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($arr[$headers[$i][$j]])) {
|
||||
$arr[$headers[$i][$j]] = array();
|
||||
}
|
||||
|
||||
$arr = &$arr[$headers[$i][$j]];
|
||||
}
|
||||
}
|
||||
|
||||
$result[] = $item;
|
||||
}
|
||||
fclose($handle);
|
||||
|
||||
if (empty($result) || isset($result[1])) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// If there is only one data line in the document, return it (the line), the result is not considered as a collection
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDecoding($format)
|
||||
{
|
||||
return self::FORMAT === $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens an array and generates keys including the path.
|
||||
*
|
||||
* @param array $array
|
||||
* @param array $result
|
||||
* @param string $keySeparator
|
||||
* @param string $parentKey
|
||||
*/
|
||||
private function flatten(array $array, array &$result, $keySeparator, $parentKey = '')
|
||||
{
|
||||
foreach ($array as $key => $value) {
|
||||
if (\is_array($value)) {
|
||||
$this->flatten($value, $result, $keySeparator, $parentKey.$key.$keySeparator);
|
||||
} else {
|
||||
$result[$parentKey.$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getCsvOptions(array $context)
|
||||
{
|
||||
$delimiter = isset($context[self::DELIMITER_KEY]) ? $context[self::DELIMITER_KEY] : $this->delimiter;
|
||||
$enclosure = isset($context[self::ENCLOSURE_KEY]) ? $context[self::ENCLOSURE_KEY] : $this->enclosure;
|
||||
$escapeChar = isset($context[self::ESCAPE_CHAR_KEY]) ? $context[self::ESCAPE_CHAR_KEY] : $this->escapeChar;
|
||||
$keySeparator = isset($context[self::KEY_SEPARATOR_KEY]) ? $context[self::KEY_SEPARATOR_KEY] : $this->keySeparator;
|
||||
$headers = isset($context[self::HEADERS_KEY]) ? $context[self::HEADERS_KEY] : array();
|
||||
|
||||
if (!\is_array($headers)) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" context variable must be an array or null, given "%s".', self::HEADERS_KEY, \gettype($headers)));
|
||||
}
|
||||
|
||||
return array($delimiter, $enclosure, $escapeChar, $keySeparator, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function extractHeaders(array $data)
|
||||
{
|
||||
$headers = array();
|
||||
$flippedHeaders = array();
|
||||
|
||||
foreach ($data as $row) {
|
||||
$previousHeader = null;
|
||||
|
||||
foreach ($row as $header => $_) {
|
||||
if (isset($flippedHeaders[$header])) {
|
||||
$previousHeader = $header;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null === $previousHeader) {
|
||||
$n = \count($headers);
|
||||
} else {
|
||||
$n = $flippedHeaders[$previousHeader] + 1;
|
||||
|
||||
for ($j = \count($headers); $j > $n; --$j) {
|
||||
++$flippedHeaders[$headers[$j] = $headers[$j - 1]];
|
||||
}
|
||||
}
|
||||
|
||||
$headers[$n] = $header;
|
||||
$flippedHeaders[$header] = $n;
|
||||
$previousHeader = $header;
|
||||
}
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
}
|
49
vendor/symfony/serializer/Encoder/DecoderInterface.php
vendored
Normal file
49
vendor/symfony/serializer/Encoder/DecoderInterface.php
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* Defines the interface of decoders.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface DecoderInterface
|
||||
{
|
||||
/**
|
||||
* Decodes a string into PHP data.
|
||||
*
|
||||
* @param string $data Data to decode
|
||||
* @param string $format Format name
|
||||
* @param array $context Options that decoders have access to
|
||||
*
|
||||
* The format parameter specifies which format the data is in; valid values
|
||||
* depend on the specific implementation. Authors implementing this interface
|
||||
* are encouraged to document which formats they support in a non-inherited
|
||||
* phpdoc comment.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
public function decode($data, $format, array $context = array());
|
||||
|
||||
/**
|
||||
* Checks whether the deserializer can decode from given format.
|
||||
*
|
||||
* @param string $format Format name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supportsDecoding($format);
|
||||
}
|
44
vendor/symfony/serializer/Encoder/EncoderInterface.php
vendored
Normal file
44
vendor/symfony/serializer/Encoder/EncoderInterface.php
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* Defines the interface of encoders.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface EncoderInterface
|
||||
{
|
||||
/**
|
||||
* Encodes data into the given format.
|
||||
*
|
||||
* @param mixed $data Data to encode
|
||||
* @param string $format Format name
|
||||
* @param array $context Options that normalizers/encoders have access to
|
||||
*
|
||||
* @return string|int|float|bool
|
||||
*
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
public function encode($data, $format, array $context = array());
|
||||
|
||||
/**
|
||||
* Checks whether the serializer can encode to given format.
|
||||
*
|
||||
* @param string $format Format name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supportsEncoding($format);
|
||||
}
|
107
vendor/symfony/serializer/Encoder/JsonDecode.php
vendored
Normal file
107
vendor/symfony/serializer/Encoder/JsonDecode.php
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
|
||||
|
||||
/**
|
||||
* Decodes JSON data.
|
||||
*
|
||||
* @author Sander Coolen <sander@jibber.nl>
|
||||
*/
|
||||
class JsonDecode implements DecoderInterface
|
||||
{
|
||||
protected $serializer;
|
||||
|
||||
private $associative;
|
||||
private $recursionDepth;
|
||||
|
||||
/**
|
||||
* Constructs a new JsonDecode instance.
|
||||
*
|
||||
* @param bool $associative True to return the result associative array, false for a nested stdClass hierarchy
|
||||
* @param int $depth Specifies the recursion depth
|
||||
*/
|
||||
public function __construct($associative = false, $depth = 512)
|
||||
{
|
||||
$this->associative = $associative;
|
||||
$this->recursionDepth = (int) $depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes data.
|
||||
*
|
||||
* @param string $data The encoded JSON string to decode
|
||||
* @param string $format Must be set to JsonEncoder::FORMAT
|
||||
* @param array $context An optional set of options for the JSON decoder; see below
|
||||
*
|
||||
* The $context array is a simple key=>value array, with the following supported keys:
|
||||
*
|
||||
* json_decode_associative: boolean
|
||||
* If true, returns the object as associative array.
|
||||
* If false, returns the object as nested stdClass
|
||||
* If not specified, this method will use the default set in JsonDecode::__construct
|
||||
*
|
||||
* json_decode_recursion_depth: integer
|
||||
* Specifies the maximum recursion depth
|
||||
* If not specified, this method will use the default set in JsonDecode::__construct
|
||||
*
|
||||
* json_decode_options: integer
|
||||
* Specifies additional options as per documentation for json_decode. Only supported with PHP 5.4.0 and higher
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws NotEncodableValueException
|
||||
*
|
||||
* @see http://php.net/json_decode json_decode
|
||||
*/
|
||||
public function decode($data, $format, array $context = array())
|
||||
{
|
||||
$context = $this->resolveContext($context);
|
||||
|
||||
$associative = $context['json_decode_associative'];
|
||||
$recursionDepth = $context['json_decode_recursion_depth'];
|
||||
$options = $context['json_decode_options'];
|
||||
|
||||
$decodedData = json_decode($data, $associative, $recursionDepth, $options);
|
||||
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
throw new NotEncodableValueException(json_last_error_msg());
|
||||
}
|
||||
|
||||
return $decodedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDecoding($format)
|
||||
{
|
||||
return JsonEncoder::FORMAT === $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the default options of the Json Decoder with the passed context.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function resolveContext(array $context)
|
||||
{
|
||||
$defaultOptions = array(
|
||||
'json_decode_associative' => $this->associative,
|
||||
'json_decode_recursion_depth' => $this->recursionDepth,
|
||||
'json_decode_options' => 0,
|
||||
);
|
||||
|
||||
return array_merge($defaultOptions, $context);
|
||||
}
|
||||
}
|
65
vendor/symfony/serializer/Encoder/JsonEncode.php
vendored
Normal file
65
vendor/symfony/serializer/Encoder/JsonEncode.php
vendored
Normal file
|
@ -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\Encoder;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
|
||||
|
||||
/**
|
||||
* Encodes JSON data.
|
||||
*
|
||||
* @author Sander Coolen <sander@jibber.nl>
|
||||
*/
|
||||
class JsonEncode implements EncoderInterface
|
||||
{
|
||||
private $options;
|
||||
|
||||
public function __construct($bitmask = 0)
|
||||
{
|
||||
$this->options = $bitmask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes PHP data to a JSON string.
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function encode($data, $format, array $context = array())
|
||||
{
|
||||
$context = $this->resolveContext($context);
|
||||
|
||||
$encodedJson = json_encode($data, $context['json_encode_options']);
|
||||
|
||||
if (JSON_ERROR_NONE !== json_last_error() && (false === $encodedJson || !($context['json_encode_options'] & JSON_PARTIAL_OUTPUT_ON_ERROR))) {
|
||||
throw new NotEncodableValueException(json_last_error_msg());
|
||||
}
|
||||
|
||||
return $encodedJson;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsEncoding($format)
|
||||
{
|
||||
return JsonEncoder::FORMAT === $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge default json encode options with context.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function resolveContext(array $context = array())
|
||||
{
|
||||
return array_merge(array('json_encode_options' => $this->options), $context);
|
||||
}
|
||||
}
|
63
vendor/symfony/serializer/Encoder/JsonEncoder.php
vendored
Normal file
63
vendor/symfony/serializer/Encoder/JsonEncoder.php
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?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\Encoder;
|
||||
|
||||
/**
|
||||
* Encodes JSON data.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class JsonEncoder implements EncoderInterface, DecoderInterface
|
||||
{
|
||||
const FORMAT = 'json';
|
||||
|
||||
protected $encodingImpl;
|
||||
protected $decodingImpl;
|
||||
|
||||
public function __construct(JsonEncode $encodingImpl = null, JsonDecode $decodingImpl = null)
|
||||
{
|
||||
$this->encodingImpl = $encodingImpl ?: new JsonEncode();
|
||||
$this->decodingImpl = $decodingImpl ?: new JsonDecode(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function encode($data, $format, array $context = array())
|
||||
{
|
||||
return $this->encodingImpl->encode($data, self::FORMAT, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decode($data, $format, array $context = array())
|
||||
{
|
||||
return $this->decodingImpl->decode($data, self::FORMAT, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsEncoding($format)
|
||||
{
|
||||
return self::FORMAT === $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDecoding($format)
|
||||
{
|
||||
return self::FORMAT === $format;
|
||||
}
|
||||
}
|
24
vendor/symfony/serializer/Encoder/NormalizationAwareInterface.php
vendored
Normal file
24
vendor/symfony/serializer/Encoder/NormalizationAwareInterface.php
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?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\Encoder;
|
||||
|
||||
/**
|
||||
* Defines the interface of encoders that will normalize data themselves.
|
||||
*
|
||||
* Implementing this interface essentially just tells the Serializer that the
|
||||
* data should not be pre-normalized before being passed to this Encoder.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface NormalizationAwareInterface
|
||||
{
|
||||
}
|
27
vendor/symfony/serializer/Encoder/SerializerAwareEncoder.php
vendored
Normal file
27
vendor/symfony/serializer/Encoder/SerializerAwareEncoder.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use Symfony\Component\Serializer\SerializerAwareInterface;
|
||||
use Symfony\Component\Serializer\SerializerAwareTrait;
|
||||
|
||||
/**
|
||||
* SerializerAware Encoder implementation.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @deprecated since version 3.2, to be removed in 4.0. Use the SerializerAwareTrait instead.
|
||||
*/
|
||||
abstract class SerializerAwareEncoder implements SerializerAwareInterface
|
||||
{
|
||||
use SerializerAwareTrait;
|
||||
}
|
567
vendor/symfony/serializer/Encoder/XmlEncoder.php
vendored
Normal file
567
vendor/symfony/serializer/Encoder/XmlEncoder.php
vendored
Normal file
|
@ -0,0 +1,567 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
|
||||
|
||||
/**
|
||||
* Encodes XML data.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @author John Wards <jwards@whiteoctober.co.uk>
|
||||
* @author Fabian Vogler <fabian@equivalence.ch>
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, DecoderInterface, NormalizationAwareInterface
|
||||
{
|
||||
const FORMAT = 'xml';
|
||||
|
||||
/**
|
||||
* @var \DOMDocument
|
||||
*/
|
||||
private $dom;
|
||||
private $format;
|
||||
private $context;
|
||||
private $rootNodeName = 'response';
|
||||
private $loadOptions;
|
||||
|
||||
/**
|
||||
* Construct new XmlEncoder and allow to change the root node element name.
|
||||
*
|
||||
* @param string $rootNodeName
|
||||
* @param int|null $loadOptions A bit field of LIBXML_* constants
|
||||
*/
|
||||
public function __construct($rootNodeName = 'response', $loadOptions = null)
|
||||
{
|
||||
$this->rootNodeName = $rootNodeName;
|
||||
$this->loadOptions = null !== $loadOptions ? $loadOptions : LIBXML_NONET | LIBXML_NOBLANKS;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function encode($data, $format, array $context = array())
|
||||
{
|
||||
if ($data instanceof \DOMDocument) {
|
||||
return $data->saveXML();
|
||||
}
|
||||
|
||||
$xmlRootNodeName = $this->resolveXmlRootName($context);
|
||||
|
||||
$this->dom = $this->createDomDocument($context);
|
||||
$this->format = $format;
|
||||
$this->context = $context;
|
||||
|
||||
if (null !== $data && !is_scalar($data)) {
|
||||
$root = $this->dom->createElement($xmlRootNodeName);
|
||||
$this->dom->appendChild($root);
|
||||
$this->buildXml($root, $data, $xmlRootNodeName);
|
||||
} else {
|
||||
$this->appendNode($this->dom, $data, $xmlRootNodeName);
|
||||
}
|
||||
|
||||
return $this->dom->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decode($data, $format, array $context = array())
|
||||
{
|
||||
if ('' === trim($data)) {
|
||||
throw new NotEncodableValueException('Invalid XML data, it can not be empty.');
|
||||
}
|
||||
|
||||
$internalErrors = libxml_use_internal_errors(true);
|
||||
$disableEntities = libxml_disable_entity_loader(true);
|
||||
libxml_clear_errors();
|
||||
|
||||
$dom = new \DOMDocument();
|
||||
$dom->loadXML($data, $this->loadOptions);
|
||||
|
||||
libxml_use_internal_errors($internalErrors);
|
||||
libxml_disable_entity_loader($disableEntities);
|
||||
|
||||
if ($error = libxml_get_last_error()) {
|
||||
libxml_clear_errors();
|
||||
|
||||
throw new NotEncodableValueException($error->message);
|
||||
}
|
||||
|
||||
$rootNode = null;
|
||||
foreach ($dom->childNodes as $child) {
|
||||
if (XML_DOCUMENT_TYPE_NODE === $child->nodeType) {
|
||||
throw new NotEncodableValueException('Document types are not allowed.');
|
||||
}
|
||||
if (!$rootNode && XML_PI_NODE !== $child->nodeType) {
|
||||
$rootNode = $child;
|
||||
}
|
||||
}
|
||||
|
||||
// todo: throw an exception if the root node name is not correctly configured (bc)
|
||||
|
||||
if ($rootNode->hasChildNodes()) {
|
||||
$xpath = new \DOMXPath($dom);
|
||||
$data = array();
|
||||
foreach ($xpath->query('namespace::*', $dom->documentElement) as $nsNode) {
|
||||
$data['@'.$nsNode->nodeName] = $nsNode->nodeValue;
|
||||
}
|
||||
|
||||
unset($data['@xmlns:xml']);
|
||||
|
||||
if (empty($data)) {
|
||||
return $this->parseXml($rootNode, $context);
|
||||
}
|
||||
|
||||
return array_merge($data, (array) $this->parseXml($rootNode, $context));
|
||||
}
|
||||
|
||||
if (!$rootNode->hasAttributes()) {
|
||||
return $rootNode->nodeValue;
|
||||
}
|
||||
|
||||
$data = array();
|
||||
|
||||
foreach ($rootNode->attributes as $attrKey => $attr) {
|
||||
$data['@'.$attrKey] = $attr->nodeValue;
|
||||
}
|
||||
|
||||
$data['#'] = $rootNode->nodeValue;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsEncoding($format)
|
||||
{
|
||||
return self::FORMAT === $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDecoding($format)
|
||||
{
|
||||
return self::FORMAT === $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the root node name.
|
||||
*
|
||||
* @param string $name Root node name
|
||||
*/
|
||||
public function setRootNodeName($name)
|
||||
{
|
||||
$this->rootNodeName = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root node name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRootNodeName()
|
||||
{
|
||||
return $this->rootNodeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMNode $node
|
||||
* @param string $val
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
final protected function appendXMLString(\DOMNode $node, $val)
|
||||
{
|
||||
if (\strlen($val) > 0) {
|
||||
$frag = $this->dom->createDocumentFragment();
|
||||
$frag->appendXML($val);
|
||||
$node->appendChild($frag);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMNode $node
|
||||
* @param string $val
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
final protected function appendText(\DOMNode $node, $val)
|
||||
{
|
||||
$nodeText = $this->dom->createTextNode($val);
|
||||
$node->appendChild($nodeText);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMNode $node
|
||||
* @param string $val
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
final protected function appendCData(\DOMNode $node, $val)
|
||||
{
|
||||
$nodeText = $this->dom->createCDATASection($val);
|
||||
$node->appendChild($nodeText);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMNode $node
|
||||
* @param \DOMDocumentFragment $fragment
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
final protected function appendDocumentFragment(\DOMNode $node, $fragment)
|
||||
{
|
||||
if ($fragment instanceof \DOMDocumentFragment) {
|
||||
$node->appendChild($fragment);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the name is a valid xml element name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
final protected function isElementNameValid($name)
|
||||
{
|
||||
return $name &&
|
||||
false === strpos($name, ' ') &&
|
||||
preg_match('#^[\pL_][\pL0-9._:-]*$#ui', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the input DOMNode into an array or a string.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
private function parseXml(\DOMNode $node, array $context = array())
|
||||
{
|
||||
$data = $this->parseXmlAttributes($node, $context);
|
||||
|
||||
$value = $this->parseXmlValue($node, $context);
|
||||
|
||||
if (!\count($data)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (!\is_array($value)) {
|
||||
$data['#'] = $value;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
if (1 === \count($value) && key($value)) {
|
||||
$data[key($value)] = current($value);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
foreach ($value as $key => $val) {
|
||||
$data[$key] = $val;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the input DOMNode attributes into an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseXmlAttributes(\DOMNode $node, array $context = array())
|
||||
{
|
||||
if (!$node->hasAttributes()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$typeCastAttributes = $this->resolveXmlTypeCastAttributes($context);
|
||||
|
||||
foreach ($node->attributes as $attr) {
|
||||
if (!is_numeric($attr->nodeValue) || !$typeCastAttributes) {
|
||||
$data['@'.$attr->nodeName] = $attr->nodeValue;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false !== $val = filter_var($attr->nodeValue, FILTER_VALIDATE_INT)) {
|
||||
$data['@'.$attr->nodeName] = $val;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$data['@'.$attr->nodeName] = (float) $attr->nodeValue;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the input DOMNode value (content and children) into an array or a string.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
private function parseXmlValue(\DOMNode $node, array $context = array())
|
||||
{
|
||||
if (!$node->hasChildNodes()) {
|
||||
return $node->nodeValue;
|
||||
}
|
||||
|
||||
if (1 === $node->childNodes->length && \in_array($node->firstChild->nodeType, array(XML_TEXT_NODE, XML_CDATA_SECTION_NODE))) {
|
||||
return $node->firstChild->nodeValue;
|
||||
}
|
||||
|
||||
$value = array();
|
||||
|
||||
foreach ($node->childNodes as $subnode) {
|
||||
if (XML_PI_NODE === $subnode->nodeType) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$val = $this->parseXml($subnode, $context);
|
||||
|
||||
if ('item' === $subnode->nodeName && isset($val['@key'])) {
|
||||
if (isset($val['#'])) {
|
||||
$value[$val['@key']] = $val['#'];
|
||||
} else {
|
||||
$value[$val['@key']] = $val;
|
||||
}
|
||||
} else {
|
||||
$value[$subnode->nodeName][] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($value as $key => $val) {
|
||||
if (\is_array($val) && 1 === \count($val)) {
|
||||
$value[$key] = current($val);
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the data and convert it to DOMElements.
|
||||
*
|
||||
* @param \DOMNode $parentNode
|
||||
* @param array|object $data
|
||||
* @param string|null $xmlRootNodeName
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws NotEncodableValueException
|
||||
*/
|
||||
private function buildXml(\DOMNode $parentNode, $data, $xmlRootNodeName = null)
|
||||
{
|
||||
$append = true;
|
||||
|
||||
if (\is_array($data) || ($data instanceof \Traversable && !$this->serializer->supportsNormalization($data, $this->format))) {
|
||||
foreach ($data as $key => $data) {
|
||||
//Ah this is the magic @ attribute types.
|
||||
if (0 === strpos($key, '@') && $this->isElementNameValid($attributeName = substr($key, 1))) {
|
||||
if (!is_scalar($data)) {
|
||||
$data = $this->serializer->normalize($data, $this->format, $this->context);
|
||||
}
|
||||
$parentNode->setAttribute($attributeName, $data);
|
||||
} elseif ('#' === $key) {
|
||||
$append = $this->selectNodeType($parentNode, $data);
|
||||
} elseif (\is_array($data) && false === is_numeric($key)) {
|
||||
// Is this array fully numeric keys?
|
||||
if (ctype_digit(implode('', array_keys($data)))) {
|
||||
/*
|
||||
* Create nodes to append to $parentNode based on the $key of this array
|
||||
* Produces <xml><item>0</item><item>1</item></xml>
|
||||
* From array("item" => array(0,1));.
|
||||
*/
|
||||
foreach ($data as $subData) {
|
||||
$append = $this->appendNode($parentNode, $subData, $key);
|
||||
}
|
||||
} else {
|
||||
$append = $this->appendNode($parentNode, $data, $key);
|
||||
}
|
||||
} elseif (is_numeric($key) || !$this->isElementNameValid($key)) {
|
||||
$append = $this->appendNode($parentNode, $data, 'item', $key);
|
||||
} elseif (null !== $data || !isset($this->context['remove_empty_tags']) || false === $this->context['remove_empty_tags']) {
|
||||
$append = $this->appendNode($parentNode, $data, $key);
|
||||
}
|
||||
}
|
||||
|
||||
return $append;
|
||||
}
|
||||
|
||||
if (\is_object($data)) {
|
||||
$data = $this->serializer->normalize($data, $this->format, $this->context);
|
||||
if (null !== $data && !is_scalar($data)) {
|
||||
return $this->buildXml($parentNode, $data, $xmlRootNodeName);
|
||||
}
|
||||
|
||||
// top level data object was normalized into a scalar
|
||||
if (!$parentNode->parentNode->parentNode) {
|
||||
$root = $parentNode->parentNode;
|
||||
$root->removeChild($parentNode);
|
||||
|
||||
return $this->appendNode($root, $data, $xmlRootNodeName);
|
||||
}
|
||||
|
||||
return $this->appendNode($parentNode, $data, 'data');
|
||||
}
|
||||
|
||||
throw new NotEncodableValueException(sprintf('An unexpected value could not be serialized: %s', var_export($data, true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the type of node to create and appends it to the parent.
|
||||
*
|
||||
* @param \DOMNode $parentNode
|
||||
* @param array|object $data
|
||||
* @param string $nodeName
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function appendNode(\DOMNode $parentNode, $data, $nodeName, $key = null)
|
||||
{
|
||||
$node = $this->dom->createElement($nodeName);
|
||||
if (null !== $key) {
|
||||
$node->setAttribute('key', $key);
|
||||
}
|
||||
$appendNode = $this->selectNodeType($node, $data);
|
||||
// we may have decided not to append this node, either in error or if its $nodeName is not valid
|
||||
if ($appendNode) {
|
||||
$parentNode->appendChild($node);
|
||||
}
|
||||
|
||||
return $appendNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a value contains any characters which would require CDATA wrapping.
|
||||
*
|
||||
* @param string $val
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function needsCdataWrapping($val)
|
||||
{
|
||||
return 0 < preg_match('/[<>&]/', $val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the value being passed and decide what sort of element to create.
|
||||
*
|
||||
* @param \DOMNode $node
|
||||
* @param mixed $val
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws NotEncodableValueException
|
||||
*/
|
||||
private function selectNodeType(\DOMNode $node, $val)
|
||||
{
|
||||
if (\is_array($val)) {
|
||||
return $this->buildXml($node, $val);
|
||||
} elseif ($val instanceof \SimpleXMLElement) {
|
||||
$child = $this->dom->importNode(dom_import_simplexml($val), true);
|
||||
$node->appendChild($child);
|
||||
} elseif ($val instanceof \Traversable) {
|
||||
$this->buildXml($node, $val);
|
||||
} elseif (\is_object($val)) {
|
||||
return $this->selectNodeType($node, $this->serializer->normalize($val, $this->format, $this->context));
|
||||
} elseif (is_numeric($val)) {
|
||||
return $this->appendText($node, (string) $val);
|
||||
} elseif (\is_string($val) && $this->needsCdataWrapping($val)) {
|
||||
return $this->appendCData($node, $val);
|
||||
} elseif (\is_string($val)) {
|
||||
return $this->appendText($node, $val);
|
||||
} elseif (\is_bool($val)) {
|
||||
return $this->appendText($node, (int) $val);
|
||||
} elseif ($val instanceof \DOMNode) {
|
||||
$child = $this->dom->importNode($val, true);
|
||||
$node->appendChild($child);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get real XML root node name, taking serializer options into account.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function resolveXmlRootName(array $context = array())
|
||||
{
|
||||
return isset($context['xml_root_node_name'])
|
||||
? $context['xml_root_node_name']
|
||||
: $this->rootNodeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get XML option for type casting attributes Defaults to true.
|
||||
*
|
||||
* @param array $context
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function resolveXmlTypeCastAttributes(array $context = array())
|
||||
{
|
||||
return isset($context['xml_type_cast_attributes'])
|
||||
? (bool) $context['xml_type_cast_attributes']
|
||||
: true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a DOM document, taking serializer options into account.
|
||||
*
|
||||
* @param array $context Options that the encoder has access to
|
||||
*
|
||||
* @return \DOMDocument
|
||||
*/
|
||||
private function createDomDocument(array $context)
|
||||
{
|
||||
$document = new \DOMDocument();
|
||||
|
||||
// Set an attribute on the DOM document specifying, as part of the XML declaration,
|
||||
$xmlOptions = array(
|
||||
// nicely formats output with indentation and extra space
|
||||
'xml_format_output' => 'formatOutput',
|
||||
// the version number of the document
|
||||
'xml_version' => 'xmlVersion',
|
||||
// the encoding of the document
|
||||
'xml_encoding' => 'encoding',
|
||||
// whether the document is standalone
|
||||
'xml_standalone' => 'xmlStandalone',
|
||||
);
|
||||
foreach ($xmlOptions as $xmlOption => $documentProperty) {
|
||||
if (isset($context[$xmlOption])) {
|
||||
$document->$documentProperty = $context[$xmlOption];
|
||||
}
|
||||
}
|
||||
|
||||
return $document;
|
||||
}
|
||||
}
|
77
vendor/symfony/serializer/Encoder/YamlEncoder.php
vendored
Normal file
77
vendor/symfony/serializer/Encoder/YamlEncoder.php
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\RuntimeException;
|
||||
use Symfony\Component\Yaml\Dumper;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
|
||||
/**
|
||||
* Encodes YAML data.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class YamlEncoder implements EncoderInterface, DecoderInterface
|
||||
{
|
||||
const FORMAT = 'yaml';
|
||||
|
||||
private $dumper;
|
||||
private $parser;
|
||||
private $defaultContext = array('yaml_inline' => 0, 'yaml_indent' => 0, 'yaml_flags' => 0);
|
||||
|
||||
public function __construct(Dumper $dumper = null, Parser $parser = null, array $defaultContext = array())
|
||||
{
|
||||
if (!class_exists(Dumper::class)) {
|
||||
throw new RuntimeException('The YamlEncoder class requires the "Yaml" component. Install "symfony/yaml" to use it.');
|
||||
}
|
||||
|
||||
$this->dumper = $dumper ?: new Dumper();
|
||||
$this->parser = $parser ?: new Parser();
|
||||
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function encode($data, $format, array $context = array())
|
||||
{
|
||||
$context = array_merge($this->defaultContext, $context);
|
||||
|
||||
return $this->dumper->dump($data, $context['yaml_inline'], $context['yaml_indent'], $context['yaml_flags']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsEncoding($format)
|
||||
{
|
||||
return self::FORMAT === $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decode($data, $format, array $context = array())
|
||||
{
|
||||
$context = array_merge($this->defaultContext, $context);
|
||||
|
||||
return $this->parser->parse($data, $context['yaml_flags']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDecoding($format)
|
||||
{
|
||||
return self::FORMAT === $format;
|
||||
}
|
||||
}
|
16
vendor/symfony/serializer/Exception/BadMethodCallException.php
vendored
Normal file
16
vendor/symfony/serializer/Exception/BadMethodCallException.php
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?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\Exception;
|
||||
|
||||
class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface
|
||||
{
|
||||
}
|
21
vendor/symfony/serializer/Exception/CircularReferenceException.php
vendored
Normal file
21
vendor/symfony/serializer/Exception/CircularReferenceException.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?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\Exception;
|
||||
|
||||
/**
|
||||
* CircularReferenceException.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class CircularReferenceException extends RuntimeException
|
||||
{
|
||||
}
|
21
vendor/symfony/serializer/Exception/ExceptionInterface.php
vendored
Normal file
21
vendor/symfony/serializer/Exception/ExceptionInterface.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?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\Exception;
|
||||
|
||||
/**
|
||||
* Base exception interface.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
41
vendor/symfony/serializer/Exception/ExtraAttributesException.php
vendored
Normal file
41
vendor/symfony/serializer/Exception/ExtraAttributesException.php
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?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\Exception;
|
||||
|
||||
/**
|
||||
* ExtraAttributesException.
|
||||
*
|
||||
* @author Julien DIDIER <julien@didier.io>
|
||||
*/
|
||||
class ExtraAttributesException extends RuntimeException
|
||||
{
|
||||
private $extraAttributes;
|
||||
|
||||
public function __construct(array $extraAttributes, \Exception $previous = null)
|
||||
{
|
||||
$msg = sprintf('Extra attributes are not allowed ("%s" are unknown).', implode('", "', $extraAttributes));
|
||||
|
||||
$this->extraAttributes = $extraAttributes;
|
||||
|
||||
parent::__construct($msg, 0, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extra attributes that are not allowed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getExtraAttributes()
|
||||
{
|
||||
return $this->extraAttributes;
|
||||
}
|
||||
}
|
21
vendor/symfony/serializer/Exception/InvalidArgumentException.php
vendored
Normal file
21
vendor/symfony/serializer/Exception/InvalidArgumentException.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?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\Exception;
|
||||
|
||||
/**
|
||||
* InvalidArgumentException.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
21
vendor/symfony/serializer/Exception/LogicException.php
vendored
Normal file
21
vendor/symfony/serializer/Exception/LogicException.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?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\Exception;
|
||||
|
||||
/**
|
||||
* LogicException.
|
||||
*
|
||||
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class LogicException extends \LogicException implements ExceptionInterface
|
||||
{
|
||||
}
|
21
vendor/symfony/serializer/Exception/MappingException.php
vendored
Normal file
21
vendor/symfony/serializer/Exception/MappingException.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?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\Exception;
|
||||
|
||||
/**
|
||||
* MappingException.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class MappingException extends RuntimeException
|
||||
{
|
||||
}
|
19
vendor/symfony/serializer/Exception/NotEncodableValueException.php
vendored
Normal file
19
vendor/symfony/serializer/Exception/NotEncodableValueException.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?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\Exception;
|
||||
|
||||
/**
|
||||
* @author Christian Flothmann <christian.flothmann@sensiolabs.de>
|
||||
*/
|
||||
class NotEncodableValueException extends UnexpectedValueException
|
||||
{
|
||||
}
|
19
vendor/symfony/serializer/Exception/NotNormalizableValueException.php
vendored
Normal file
19
vendor/symfony/serializer/Exception/NotNormalizableValueException.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?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\Exception;
|
||||
|
||||
/**
|
||||
* @author Christian Flothmann <christian.flothmann@sensiolabs.de>
|
||||
*/
|
||||
class NotNormalizableValueException extends UnexpectedValueException
|
||||
{
|
||||
}
|
21
vendor/symfony/serializer/Exception/RuntimeException.php
vendored
Normal file
21
vendor/symfony/serializer/Exception/RuntimeException.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?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\Exception;
|
||||
|
||||
/**
|
||||
* RuntimeException.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class RuntimeException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
21
vendor/symfony/serializer/Exception/UnexpectedValueException.php
vendored
Normal file
21
vendor/symfony/serializer/Exception/UnexpectedValueException.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?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\Exception;
|
||||
|
||||
/**
|
||||
* UnexpectedValueException.
|
||||
*
|
||||
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class UnexpectedValueException extends \UnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
}
|
21
vendor/symfony/serializer/Exception/UnsupportedException.php
vendored
Normal file
21
vendor/symfony/serializer/Exception/UnsupportedException.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?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\Exception;
|
||||
|
||||
/**
|
||||
* UnsupportedException.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class UnsupportedException extends InvalidArgumentException
|
||||
{
|
||||
}
|
19
vendor/symfony/serializer/LICENSE
vendored
Normal file
19
vendor/symfony/serializer/LICENSE
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2004-2018 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
120
vendor/symfony/serializer/Mapping/AttributeMetadata.php
vendored
Normal file
120
vendor/symfony/serializer/Mapping/AttributeMetadata.php
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?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
|
||||
{
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*
|
||||
* @internal This property is public in order to reduce the size of the
|
||||
* class' serialized representation. Do not access it. Use
|
||||
* {@link getMaxDepth()} instead.
|
||||
*/
|
||||
public $maxDepth;
|
||||
|
||||
/**
|
||||
* 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 setMaxDepth($maxDepth)
|
||||
{
|
||||
$this->maxDepth = $maxDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMaxDepth()
|
||||
{
|
||||
return $this->maxDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function merge(AttributeMetadataInterface $attributeMetadata)
|
||||
{
|
||||
foreach ($attributeMetadata->getGroups() as $group) {
|
||||
$this->addGroup($group);
|
||||
}
|
||||
|
||||
// Overwrite only if not defined
|
||||
if (null === $this->maxDepth) {
|
||||
$this->maxDepth = $attributeMetadata->getMaxDepth();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of the properties that should be serialized.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
return array('name', 'groups', 'maxDepth');
|
||||
}
|
||||
}
|
64
vendor/symfony/serializer/Mapping/AttributeMetadataInterface.php
vendored
Normal file
64
vendor/symfony/serializer/Mapping/AttributeMetadataInterface.php
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?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.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* Sets the serialization max depth for this attribute.
|
||||
*
|
||||
* @param int|null $maxDepth
|
||||
*/
|
||||
public function setMaxDepth($maxDepth);
|
||||
|
||||
/**
|
||||
* Gets the serialization max depth for this attribute.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getMaxDepth();
|
||||
|
||||
/**
|
||||
* Merges an {@see AttributeMetadataInterface} with in the current one.
|
||||
*/
|
||||
public function merge(AttributeMetadataInterface $attributeMetadata);
|
||||
}
|
114
vendor/symfony/serializer/Mapping/ClassMetadata.php
vendored
Normal file
114
vendor/symfony/serializer/Mapping/ClassMetadata.php
vendored
Normal file
|
@ -0,0 +1,114 @@
|
|||
<?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 ClassMetadata implements ClassMetadataInterface
|
||||
{
|
||||
/**
|
||||
* @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 AttributeMetadataInterface[]
|
||||
*
|
||||
* @internal This property is public in order to reduce the size of the
|
||||
* class' serialized representation. Do not access it. Use
|
||||
* {@link getAttributesMetadata()} instead.
|
||||
*/
|
||||
public $attributesMetadata = array();
|
||||
|
||||
/**
|
||||
* @var \ReflectionClass
|
||||
*/
|
||||
private $reflClass;
|
||||
|
||||
/**
|
||||
* Constructs a metadata for the given class.
|
||||
*
|
||||
* @param string $class
|
||||
*/
|
||||
public function __construct($class)
|
||||
{
|
||||
$this->name = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addAttributeMetadata(AttributeMetadataInterface $attributeMetadata)
|
||||
{
|
||||
$this->attributesMetadata[$attributeMetadata->getName()] = $attributeMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAttributesMetadata()
|
||||
{
|
||||
return $this->attributesMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function merge(ClassMetadataInterface $classMetadata)
|
||||
{
|
||||
foreach ($classMetadata->getAttributesMetadata() as $attributeMetadata) {
|
||||
if (isset($this->attributesMetadata[$attributeMetadata->getName()])) {
|
||||
$this->attributesMetadata[$attributeMetadata->getName()]->merge($attributeMetadata);
|
||||
} else {
|
||||
$this->addAttributeMetadata($attributeMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getReflectionClass()
|
||||
{
|
||||
if (!$this->reflClass) {
|
||||
$this->reflClass = new \ReflectionClass($this->getName());
|
||||
}
|
||||
|
||||
return $this->reflClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of the properties that should be serialized.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
return array(
|
||||
'name',
|
||||
'attributesMetadata',
|
||||
);
|
||||
}
|
||||
}
|
57
vendor/symfony/serializer/Mapping/ClassMetadataInterface.php
vendored
Normal file
57
vendor/symfony/serializer/Mapping/ClassMetadataInterface.php
vendored
Normal file
|
@ -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 set of attributes to serialize or deserialize.
|
||||
*
|
||||
* There may only exist one metadata for each attribute according to its name.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @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}.
|
||||
*/
|
||||
public function addAttributeMetadata(AttributeMetadataInterface $attributeMetadata);
|
||||
|
||||
/**
|
||||
* Gets the list of {@link AttributeMetadataInterface}.
|
||||
*
|
||||
* @return AttributeMetadataInterface[]
|
||||
*/
|
||||
public function getAttributesMetadata();
|
||||
|
||||
/**
|
||||
* Merges a {@link ClassMetadataInterface} in the current one.
|
||||
*/
|
||||
public function merge(self $classMetadata);
|
||||
|
||||
/**
|
||||
* Returns a {@link \ReflectionClass} instance for this class.
|
||||
*
|
||||
* @return \ReflectionClass
|
||||
*/
|
||||
public function getReflectionClass();
|
||||
}
|
68
vendor/symfony/serializer/Mapping/Factory/CacheClassMetadataFactory.php
vendored
Normal file
68
vendor/symfony/serializer/Mapping/Factory/CacheClassMetadataFactory.php
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?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 Psr\Cache\CacheItemPoolInterface;
|
||||
|
||||
/**
|
||||
* Caches metadata using a PSR-6 implementation.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class CacheClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
{
|
||||
use ClassResolverTrait;
|
||||
|
||||
/**
|
||||
* @var ClassMetadataFactoryInterface
|
||||
*/
|
||||
private $decorated;
|
||||
|
||||
/**
|
||||
* @var CacheItemPoolInterface
|
||||
*/
|
||||
private $cacheItemPool;
|
||||
|
||||
public function __construct(ClassMetadataFactoryInterface $decorated, CacheItemPoolInterface $cacheItemPool)
|
||||
{
|
||||
$this->decorated = $decorated;
|
||||
$this->cacheItemPool = $cacheItemPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadataFor($value)
|
||||
{
|
||||
$class = $this->getClass($value);
|
||||
// Key cannot contain backslashes according to PSR-6
|
||||
$key = strtr($class, '\\', '_');
|
||||
|
||||
$item = $this->cacheItemPool->getItem($key);
|
||||
if ($item->isHit()) {
|
||||
return $item->get();
|
||||
}
|
||||
|
||||
$metadata = $this->decorated->getMetadataFor($value);
|
||||
$this->cacheItemPool->save($item->set($metadata));
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasMetadataFor($value)
|
||||
{
|
||||
return $this->decorated->hasMetadataFor($value);
|
||||
}
|
||||
}
|
94
vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactory.php
vendored
Normal file
94
vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactory.php
vendored
Normal file
|
@ -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\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;
|
||||
|
||||
/**
|
||||
* Returns a {@link ClassMetadata}.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
{
|
||||
use ClassResolverTrait;
|
||||
|
||||
private $loader;
|
||||
private $cache;
|
||||
private $loadedClasses;
|
||||
|
||||
public function __construct(LoaderInterface $loader, Cache $cache = null)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
$this->cache = $cache;
|
||||
|
||||
if (null !== $cache) {
|
||||
@trigger_error(sprintf('Passing a Doctrine Cache instance as 2nd parameter of the "%s" constructor is deprecated since Symfony 3.1. This parameter will be removed in Symfony 4.0. Use the "%s" class instead.', __CLASS__, CacheClassMetadataFactory::class), E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMetadataFor($value)
|
||||
{
|
||||
$class = $this->getClass($value);
|
||||
|
||||
if (isset($this->loadedClasses[$class])) {
|
||||
return $this->loadedClasses[$class];
|
||||
}
|
||||
|
||||
if ($this->cache && ($this->loadedClasses[$class] = $this->cache->fetch($class))) {
|
||||
return $this->loadedClasses[$class];
|
||||
}
|
||||
|
||||
$classMetadata = new ClassMetadata($class);
|
||||
$this->loader->loadClassMetadata($classMetadata);
|
||||
|
||||
$reflectionClass = $classMetadata->getReflectionClass();
|
||||
|
||||
// Include metadata from the parent class
|
||||
if ($parent = $reflectionClass->getParentClass()) {
|
||||
$classMetadata->merge($this->getMetadataFor($parent->name));
|
||||
}
|
||||
|
||||
// Include metadata from all implemented interfaces
|
||||
foreach ($reflectionClass->getInterfaces() as $interface) {
|
||||
$classMetadata->merge($this->getMetadataFor($interface->name));
|
||||
}
|
||||
|
||||
if ($this->cache) {
|
||||
$this->cache->save($class, $classMetadata);
|
||||
}
|
||||
|
||||
return $this->loadedClasses[$class] = $classMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasMetadataFor($value)
|
||||
{
|
||||
try {
|
||||
$this->getClass($value);
|
||||
|
||||
return true;
|
||||
} catch (InvalidArgumentException $invalidArgumentException) {
|
||||
// Return false in case of exception
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
53
vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactoryInterface.php
vendored
Normal file
53
vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactoryInterface.php
vendored
Normal file
|
@ -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 \Symfony\Component\Serializer\Mapping\Loader\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);
|
||||
}
|
50
vendor/symfony/serializer/Mapping/Factory/ClassResolverTrait.php
vendored
Normal file
50
vendor/symfony/serializer/Mapping/Factory/ClassResolverTrait.php
vendored
Normal file
|
@ -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\Factory;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Resolves a class name.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
trait ClassResolverTrait
|
||||
{
|
||||
/**
|
||||
* Gets a class name for a given class or instance.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws InvalidArgumentException If the class does not exists
|
||||
*/
|
||||
private function getClass($value)
|
||||
{
|
||||
if (\is_string($value)) {
|
||||
if (!class_exists($value) && !interface_exists($value)) {
|
||||
throw new InvalidArgumentException(sprintf('The class or interface "%s" does not exist.', $value));
|
||||
}
|
||||
|
||||
return ltrim($value, '\\');
|
||||
}
|
||||
|
||||
if (!\is_object($value)) {
|
||||
throw new InvalidArgumentException(sprintf('Cannot create metadata for non-objects. Got: "%s"', \gettype($value)));
|
||||
}
|
||||
|
||||
return \get_class($value);
|
||||
}
|
||||
}
|
107
vendor/symfony/serializer/Mapping/Loader/AnnotationLoader.php
vendored
Normal file
107
vendor/symfony/serializer/Mapping/Loader/AnnotationLoader.php
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?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\Loader;
|
||||
|
||||
use Doctrine\Common\Annotations\Reader;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
use Symfony\Component\Serializer\Annotation\MaxDepth;
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Annotation loader.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class AnnotationLoader implements LoaderInterface
|
||||
{
|
||||
private $reader;
|
||||
|
||||
public function __construct(Reader $reader)
|
||||
{
|
||||
$this->reader = $reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata)
|
||||
{
|
||||
$reflectionClass = $classMetadata->getReflectionClass();
|
||||
$className = $reflectionClass->name;
|
||||
$loaded = false;
|
||||
|
||||
$attributesMetadata = $classMetadata->getAttributesMetadata();
|
||||
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
if (!isset($attributesMetadata[$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 $annotation) {
|
||||
if ($annotation instanceof Groups) {
|
||||
foreach ($annotation->getGroups() as $group) {
|
||||
$attributesMetadata[$property->name]->addGroup($group);
|
||||
}
|
||||
} elseif ($annotation instanceof MaxDepth) {
|
||||
$attributesMetadata[$property->name]->setMaxDepth($annotation->getMaxDepth());
|
||||
}
|
||||
|
||||
$loaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($reflectionClass->getMethods() as $method) {
|
||||
if ($method->getDeclaringClass()->name !== $className) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$accessorOrMutator = preg_match('/^(get|is|has|set)(.+)$/i', $method->name, $matches);
|
||||
if ($accessorOrMutator) {
|
||||
$attributeName = lcfirst($matches[2]);
|
||||
|
||||
if (isset($attributesMetadata[$attributeName])) {
|
||||
$attributeMetadata = $attributesMetadata[$attributeName];
|
||||
} else {
|
||||
$attributesMetadata[$attributeName] = $attributeMetadata = new AttributeMetadata($attributeName);
|
||||
$classMetadata->addAttributeMetadata($attributeMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->reader->getMethodAnnotations($method) as $annotation) {
|
||||
if ($annotation instanceof Groups) {
|
||||
if (!$accessorOrMutator) {
|
||||
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));
|
||||
}
|
||||
|
||||
foreach ($annotation->getGroups() as $group) {
|
||||
$attributeMetadata->addGroup($group);
|
||||
}
|
||||
} elseif ($annotation instanceof MaxDepth) {
|
||||
if (!$accessorOrMutator) {
|
||||
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));
|
||||
}
|
||||
|
||||
$attributeMetadata->setMaxDepth($annotation->getMaxDepth());
|
||||
}
|
||||
|
||||
$loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $loaded;
|
||||
}
|
||||
}
|
42
vendor/symfony/serializer/Mapping/Loader/FileLoader.php
vendored
Normal file
42
vendor/symfony/serializer/Mapping/Loader/FileLoader.php
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?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\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
|
||||
{
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* @param string $file The mapping file to load
|
||||
*
|
||||
* @throws MappingException if the mapping file does not exist or is not readable
|
||||
*/
|
||||
public function __construct($file)
|
||||
{
|
||||
if (!is_file($file)) {
|
||||
throw new MappingException(sprintf('The mapping file %s does not exist', $file));
|
||||
}
|
||||
|
||||
if (!is_readable($file)) {
|
||||
throw new MappingException(sprintf('The mapping file %s is not readable', $file));
|
||||
}
|
||||
|
||||
$this->file = $file;
|
||||
}
|
||||
}
|
71
vendor/symfony/serializer/Mapping/Loader/LoaderChain.php
vendored
Normal file
71
vendor/symfony/serializer/Mapping/Loader/LoaderChain.php
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?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\Loader;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Calls multiple {@link LoaderInterface} instances in a chain.
|
||||
*
|
||||
* This class accepts multiple instances of LoaderInterface to be passed to the
|
||||
* 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
|
||||
{
|
||||
private $loaders;
|
||||
|
||||
/**
|
||||
* Accepts a list of LoaderInterface instances.
|
||||
*
|
||||
* @param LoaderInterface[] $loaders An array of LoaderInterface instances
|
||||
*
|
||||
* @throws MappingException If any of the loaders does not implement LoaderInterface
|
||||
*/
|
||||
public function __construct(array $loaders)
|
||||
{
|
||||
foreach ($loaders as $loader) {
|
||||
if (!$loader instanceof LoaderInterface) {
|
||||
throw new MappingException(sprintf('Class %s is expected to implement LoaderInterface', \get_class($loader)));
|
||||
}
|
||||
}
|
||||
|
||||
$this->loaders = $loaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadClassMetadata(ClassMetadataInterface $metadata)
|
||||
{
|
||||
$success = false;
|
||||
|
||||
foreach ($this->loaders as $loader) {
|
||||
$success = $loader->loadClassMetadata($metadata) || $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoaderInterface[]
|
||||
*/
|
||||
public function getLoaders()
|
||||
{
|
||||
return $this->loaders;
|
||||
}
|
||||
}
|
27
vendor/symfony/serializer/Mapping/Loader/LoaderInterface.php
vendored
Normal file
27
vendor/symfony/serializer/Mapping/Loader/LoaderInterface.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?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\Loader;
|
||||
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Loads {@link ClassMetadataInterface}.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface LoaderInterface
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata);
|
||||
}
|
121
vendor/symfony/serializer/Mapping/Loader/XmlFileLoader.php
vendored
Normal file
121
vendor/symfony/serializer/Mapping/Loader/XmlFileLoader.php
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
<?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\Loader;
|
||||
|
||||
use Symfony\Component\Config\Util\XmlUtils;
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Loads XML mapping files.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class XmlFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* An array of {@class \SimpleXMLElement} instances.
|
||||
*
|
||||
* @var \SimpleXMLElement[]|null
|
||||
*/
|
||||
private $classes;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata)
|
||||
{
|
||||
if (null === $this->classes) {
|
||||
$this->classes = $this->getClassesFromXml();
|
||||
}
|
||||
|
||||
if (!$this->classes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$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) {
|
||||
$attributeMetadata->addGroup((string) $group);
|
||||
}
|
||||
|
||||
if (isset($attribute['max-depth'])) {
|
||||
$attributeMetadata->setMaxDepth((int) $attribute['max-depth']);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the names of the classes mapped in this file.
|
||||
*
|
||||
* @return string[] The classes names
|
||||
*/
|
||||
public function getMappedClasses()
|
||||
{
|
||||
if (null === $this->classes) {
|
||||
$this->classes = $this->getClassesFromXml();
|
||||
}
|
||||
|
||||
return array_keys($this->classes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a XML File.
|
||||
*
|
||||
* @param string $file Path of file
|
||||
*
|
||||
* @return \SimpleXMLElement
|
||||
*
|
||||
* @throws MappingException
|
||||
*/
|
||||
private function parseFile($file)
|
||||
{
|
||||
try {
|
||||
$dom = XmlUtils::loadFile($file, __DIR__.'/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd');
|
||||
} catch (\Exception $e) {
|
||||
throw new MappingException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return simplexml_import_dom($dom);
|
||||
}
|
||||
|
||||
private function getClassesFromXml()
|
||||
{
|
||||
$xml = $this->parseFile($this->file);
|
||||
$classes = array();
|
||||
|
||||
foreach ($xml->class as $class) {
|
||||
$classes[(string) $class['name']] = $class;
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
}
|
128
vendor/symfony/serializer/Mapping/Loader/YamlFileLoader.php
vendored
Normal file
128
vendor/symfony/serializer/Mapping/Loader/YamlFileLoader.php
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
<?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\Loader;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
|
||||
/**
|
||||
* YAML File Loader.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class YamlFileLoader extends FileLoader
|
||||
{
|
||||
private $yamlParser;
|
||||
|
||||
/**
|
||||
* An array of YAML class descriptions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $classes;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata)
|
||||
{
|
||||
if (null === $this->classes) {
|
||||
$this->classes = $this->getClassesFromYaml();
|
||||
}
|
||||
|
||||
if (!$this->classes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($this->classes[$classMetadata->getName()])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$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'])) {
|
||||
if (!\is_array($data['groups'])) {
|
||||
throw new MappingException(sprintf('The "groups" key must be an array of strings in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName()));
|
||||
}
|
||||
|
||||
foreach ($data['groups'] as $group) {
|
||||
if (!\is_string($group)) {
|
||||
throw new MappingException(sprintf('Group names must be strings in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName()));
|
||||
}
|
||||
|
||||
$attributeMetadata->addGroup($group);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data['max_depth'])) {
|
||||
if (!\is_int($data['max_depth'])) {
|
||||
throw new MappingException(sprintf('The "max_depth" value must be an integer in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName()));
|
||||
}
|
||||
|
||||
$attributeMetadata->setMaxDepth($data['max_depth']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the names of the classes mapped in this file.
|
||||
*
|
||||
* @return string[] The classes names
|
||||
*/
|
||||
public function getMappedClasses()
|
||||
{
|
||||
if (null === $this->classes) {
|
||||
$this->classes = $this->getClassesFromYaml();
|
||||
}
|
||||
|
||||
return array_keys($this->classes);
|
||||
}
|
||||
|
||||
private function getClassesFromYaml()
|
||||
{
|
||||
if (!stream_is_local($this->file)) {
|
||||
throw new MappingException(sprintf('This is not a local file "%s".', $this->file));
|
||||
}
|
||||
|
||||
if (null === $this->yamlParser) {
|
||||
$this->yamlParser = new Parser();
|
||||
}
|
||||
|
||||
$classes = $this->yamlParser->parseFile($this->file);
|
||||
|
||||
if (empty($classes)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if (!\is_array($classes)) {
|
||||
throw new MappingException(sprintf('The file "%s" must contain a YAML array.', $this->file));
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" ?>
|
||||
|
||||
<xsd:schema xmlns="http://symfony.com/schema/dic/serializer-mapping"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://symfony.com/schema/dic/serializer-mapping"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Symfony Serializer Mapping Schema, version 1.0
|
||||
Authors: Kévin Dunglas
|
||||
|
||||
A serializer mapping connects attributes with serialization groups.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="serializer" type="serializer" />
|
||||
|
||||
<xsd:complexType name="serializer">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The root element of the serializer mapping definition.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="class" type="class" />
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="class">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Contains serialization groups for a single class.
|
||||
|
||||
Nested elements may be class property and/or getter definitions.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="attribute" type="attribute" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="attribute">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Contains serialization groups and max depth for attributes. The name of the attribute should be given in the "name" option.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence minOccurs="0">
|
||||
<xsd:element name="group" type="xsd:string" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="max-depth">
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:integer">
|
||||
<xsd:minInclusive value="0" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
</xsd:schema>
|
65
vendor/symfony/serializer/NameConverter/CamelCaseToSnakeCaseNameConverter.php
vendored
Normal file
65
vendor/symfony/serializer/NameConverter/CamelCaseToSnakeCaseNameConverter.php
vendored
Normal file
|
@ -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\NameConverter;
|
||||
|
||||
/**
|
||||
* CamelCase to Underscore name converter.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class CamelCaseToSnakeCaseNameConverter implements NameConverterInterface
|
||||
{
|
||||
private $attributes;
|
||||
private $lowerCamelCase;
|
||||
|
||||
/**
|
||||
* @param array|null $attributes The list of attributes to rename or null for all attributes
|
||||
* @param bool $lowerCamelCase Use lowerCamelCase style
|
||||
*/
|
||||
public function __construct(array $attributes = null, $lowerCamelCase = true)
|
||||
{
|
||||
$this->attributes = $attributes;
|
||||
$this->lowerCamelCase = $lowerCamelCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function normalize($propertyName)
|
||||
{
|
||||
if (null === $this->attributes || \in_array($propertyName, $this->attributes)) {
|
||||
return strtolower(preg_replace('/[A-Z]/', '_\\0', lcfirst($propertyName)));
|
||||
}
|
||||
|
||||
return $propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function denormalize($propertyName)
|
||||
{
|
||||
$camelCasedName = preg_replace_callback('/(^|_|\.)+(.)/', function ($match) {
|
||||
return ('.' === $match[1] ? '_' : '').strtoupper($match[2]);
|
||||
}, $propertyName);
|
||||
|
||||
if ($this->lowerCamelCase) {
|
||||
$camelCasedName = lcfirst($camelCasedName);
|
||||
}
|
||||
|
||||
if (null === $this->attributes || \in_array($camelCasedName, $this->attributes)) {
|
||||
return $camelCasedName;
|
||||
}
|
||||
|
||||
return $propertyName;
|
||||
}
|
||||
}
|
38
vendor/symfony/serializer/NameConverter/NameConverterInterface.php
vendored
Normal file
38
vendor/symfony/serializer/NameConverter/NameConverterInterface.php
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?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\NameConverter;
|
||||
|
||||
/**
|
||||
* Defines the interface for property name converters.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface NameConverterInterface
|
||||
{
|
||||
/**
|
||||
* Converts a property name to its normalized value.
|
||||
*
|
||||
* @param string $propertyName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function normalize($propertyName);
|
||||
|
||||
/**
|
||||
* Converts a property name to its denormalized value.
|
||||
*
|
||||
* @param string $propertyName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function denormalize($propertyName);
|
||||
}
|
411
vendor/symfony/serializer/Normalizer/AbstractNormalizer.php
vendored
Normal file
411
vendor/symfony/serializer/Normalizer/AbstractNormalizer.php
vendored
Normal file
|
@ -0,0 +1,411 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
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\AttributeMetadataInterface;
|
||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
|
||||
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
||||
use Symfony\Component\Serializer\SerializerAwareInterface;
|
||||
|
||||
/**
|
||||
* Normalizer implementation.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
|
||||
{
|
||||
use ObjectToPopulateTrait;
|
||||
|
||||
const CIRCULAR_REFERENCE_LIMIT = 'circular_reference_limit';
|
||||
const OBJECT_TO_POPULATE = 'object_to_populate';
|
||||
const GROUPS = 'groups';
|
||||
const ATTRIBUTES = 'attributes';
|
||||
const ALLOW_EXTRA_ATTRIBUTES = 'allow_extra_attributes';
|
||||
|
||||
/**
|
||||
* @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 ClassMetadataFactoryInterface} to use.
|
||||
*/
|
||||
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null)
|
||||
{
|
||||
$this->classMetadataFactory = $classMetadataFactory;
|
||||
$this->nameConverter = $nameConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set circular reference limit.
|
||||
*
|
||||
* @param int $circularReferenceLimit Limit of iterations for the same object
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setCircularReferenceLimit($circularReferenceLimit)
|
||||
{
|
||||
$this->circularReferenceLimit = $circularReferenceLimit;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set circular reference handler.
|
||||
*
|
||||
* @param callable $circularReferenceHandler
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setCircularReferenceHandler(callable $circularReferenceHandler)
|
||||
{
|
||||
$this->circularReferenceHandler = $circularReferenceHandler;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set normalization callbacks.
|
||||
*
|
||||
* @param callable[] $callbacks Help normalize the result
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws InvalidArgumentException if a non-callable callback is set
|
||||
*/
|
||||
public function setCallbacks(array $callbacks)
|
||||
{
|
||||
foreach ($callbacks as $attribute => $callback) {
|
||||
if (!\is_callable($callback)) {
|
||||
throw new InvalidArgumentException(sprintf('The given callback for attribute "%s" is not callable.', $attribute));
|
||||
}
|
||||
}
|
||||
$this->callbacks = $callbacks;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ignored attributes for normalization and denormalization.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setIgnoredAttributes(array $ignoredAttributes)
|
||||
{
|
||||
$this->ignoredAttributes = $ignoredAttributes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if the configured circular reference limit is reached.
|
||||
*
|
||||
* @param object $object
|
||||
* @param array $context
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws CircularReferenceException
|
||||
*/
|
||||
protected function isCircularReference($object, &$context)
|
||||
{
|
||||
$objectHash = spl_object_hash($object);
|
||||
|
||||
if (isset($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash])) {
|
||||
if ($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash] >= $this->circularReferenceLimit) {
|
||||
unset($context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
++$context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash];
|
||||
} else {
|
||||
$context[static::CIRCULAR_REFERENCE_LIMIT][$objectHash] = 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a circular reference.
|
||||
*
|
||||
* If a circular reference handler is set, it will be called. Otherwise, a
|
||||
* {@class CircularReferenceException} will be thrown.
|
||||
*
|
||||
* @param object $object
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws CircularReferenceException
|
||||
*/
|
||||
protected function handleCircularReference($object)
|
||||
{
|
||||
if ($this->circularReferenceHandler) {
|
||||
return \call_user_func($this->circularReferenceHandler, $object);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets attributes to normalize using groups.
|
||||
*
|
||||
* @param string|object $classOrObject
|
||||
* @param array $context
|
||||
* @param bool $attributesAsString If false, return an array of {@link AttributeMetadataInterface}
|
||||
*
|
||||
* @throws LogicException if the 'allow_extra_attributes' context variable is false and no class metadata factory is provided
|
||||
*
|
||||
* @return string[]|AttributeMetadataInterface[]|bool
|
||||
*/
|
||||
protected function getAllowedAttributes($classOrObject, array $context, $attributesAsString = false)
|
||||
{
|
||||
if (!$this->classMetadataFactory) {
|
||||
if (isset($context[static::ALLOW_EXTRA_ATTRIBUTES]) && !$context[static::ALLOW_EXTRA_ATTRIBUTES]) {
|
||||
throw new LogicException(sprintf('A class metadata factory must be provided in the constructor when setting "%s" to false.', static::ALLOW_EXTRA_ATTRIBUTES));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$groups = false;
|
||||
if (isset($context[static::GROUPS]) && \is_array($context[static::GROUPS])) {
|
||||
$groups = $context[static::GROUPS];
|
||||
} elseif (!isset($context[static::ALLOW_EXTRA_ATTRIBUTES]) || $context[static::ALLOW_EXTRA_ATTRIBUTES]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$allowedAttributes = array();
|
||||
foreach ($this->classMetadataFactory->getMetadataFor($classOrObject)->getAttributesMetadata() as $attributeMetadata) {
|
||||
$name = $attributeMetadata->getName();
|
||||
|
||||
if (
|
||||
(false === $groups || array_intersect($attributeMetadata->getGroups(), $groups)) &&
|
||||
$this->isAllowedAttribute($classOrObject, $name, null, $context)
|
||||
) {
|
||||
$allowedAttributes[] = $attributesAsString ? $name : $attributeMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
return $allowedAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this attribute allowed?
|
||||
*
|
||||
* @param object|string $classOrObject
|
||||
* @param string $attribute
|
||||
* @param string|null $format
|
||||
* @param array $context
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = array())
|
||||
{
|
||||
if (\in_array($attribute, $this->ignoredAttributes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($context[self::ATTRIBUTES][$attribute])) {
|
||||
// Nested attributes
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isset($context[self::ATTRIBUTES]) && \is_array($context[self::ATTRIBUTES])) {
|
||||
return \in_array($attribute, $context[self::ATTRIBUTES], true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the given data to an array. It's particularly useful during
|
||||
* the denormalization process.
|
||||
*
|
||||
* @param object|array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareForDenormalization($data)
|
||||
{
|
||||
return (array) $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the method to use to construct an object. This method must be either
|
||||
* the object constructor or static.
|
||||
*
|
||||
* @param array $data
|
||||
* @param string $class
|
||||
* @param array $context
|
||||
* @param \ReflectionClass $reflectionClass
|
||||
* @param array|bool $allowedAttributes
|
||||
*
|
||||
* @return \ReflectionMethod|null
|
||||
*/
|
||||
protected function getConstructor(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes)
|
||||
{
|
||||
return $reflectionClass->getConstructor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates an object using constructor parameters when needed.
|
||||
*
|
||||
* This method also allows to denormalize data into an existing object if
|
||||
* it is present in the context with the object_to_populate. This object
|
||||
* is removed from the context before being returned to avoid side effects
|
||||
* when recursively normalizing an object graph.
|
||||
*
|
||||
* @param array $data
|
||||
* @param string $class
|
||||
* @param array $context
|
||||
* @param \ReflectionClass $reflectionClass
|
||||
* @param array|bool $allowedAttributes
|
||||
* @param string|null $format
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes/*, string $format = null*/)
|
||||
{
|
||||
if (\func_num_args() >= 6) {
|
||||
$format = \func_get_arg(5);
|
||||
} else {
|
||||
if (__CLASS__ !== \get_class($this)) {
|
||||
$r = new \ReflectionMethod($this, __FUNCTION__);
|
||||
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
|
||||
@trigger_error(sprintf('Method %s::%s() will have a 6th `string $format = null` argument in version 4.0. Not defining it is deprecated since Symfony 3.2.', \get_class($this), __FUNCTION__), E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
$format = null;
|
||||
}
|
||||
|
||||
if (null !== $object = $this->extractObjectToPopulate($class, $context, static::OBJECT_TO_POPULATE)) {
|
||||
unset($context[static::OBJECT_TO_POPULATE]);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
$constructor = $this->getConstructor($data, $class, $context, $reflectionClass, $allowedAttributes);
|
||||
if ($constructor) {
|
||||
$constructorParameters = $constructor->getParameters();
|
||||
|
||||
$params = array();
|
||||
foreach ($constructorParameters as $constructorParameter) {
|
||||
$paramName = $constructorParameter->name;
|
||||
$key = $this->nameConverter ? $this->nameConverter->normalize($paramName) : $paramName;
|
||||
|
||||
$allowed = false === $allowedAttributes || \in_array($paramName, $allowedAttributes);
|
||||
$ignored = !$this->isAllowedAttribute($class, $paramName, $format, $context);
|
||||
if (method_exists($constructorParameter, 'isVariadic') && $constructorParameter->isVariadic()) {
|
||||
if ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) {
|
||||
if (!\is_array($data[$paramName])) {
|
||||
throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because the variadic parameter %s can only accept an array.', $class, $constructorParameter->name));
|
||||
}
|
||||
|
||||
$params = array_merge($params, $data[$paramName]);
|
||||
}
|
||||
} elseif ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) {
|
||||
$parameterData = $data[$key];
|
||||
if (null === $parameterData && $constructorParameter->allowsNull()) {
|
||||
$params[] = null;
|
||||
// Don't run set for a parameter passed to the constructor
|
||||
unset($data[$key]);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
if (null !== $constructorParameter->getClass()) {
|
||||
if (!$this->serializer instanceof DenormalizerInterface) {
|
||||
throw new LogicException(sprintf('Cannot create an instance of %s from serialized data because the serializer inject in "%s" is not a denormalizer', $constructorParameter->getClass(), static::class));
|
||||
}
|
||||
$parameterClass = $constructorParameter->getClass()->getName();
|
||||
$parameterData = $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $paramName));
|
||||
}
|
||||
} catch (\ReflectionException $e) {
|
||||
throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $key), 0, $e);
|
||||
}
|
||||
|
||||
// Don't run set for a parameter passed to the constructor
|
||||
$params[] = $parameterData;
|
||||
unset($data[$key]);
|
||||
} elseif ($constructorParameter->isDefaultValueAvailable()) {
|
||||
$params[] = $constructorParameter->getDefaultValue();
|
||||
} else {
|
||||
throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because its constructor requires parameter "%s" to be present.', $class, $constructorParameter->name));
|
||||
}
|
||||
}
|
||||
|
||||
if ($constructor->isConstructor()) {
|
||||
return $reflectionClass->newInstanceArgs($params);
|
||||
} else {
|
||||
return $constructor->invokeArgs(null, $params);
|
||||
}
|
||||
}
|
||||
|
||||
return new $class();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $parentContext
|
||||
* @param string $attribute
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected function createChildContext(array $parentContext, $attribute)
|
||||
{
|
||||
if (isset($parentContext[self::ATTRIBUTES][$attribute])) {
|
||||
$parentContext[self::ATTRIBUTES] = $parentContext[self::ATTRIBUTES][$attribute];
|
||||
} else {
|
||||
unset($parentContext[self::ATTRIBUTES]);
|
||||
}
|
||||
|
||||
return $parentContext;
|
||||
}
|
||||
}
|
380
vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php
vendored
Normal file
380
vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php
vendored
Normal file
|
@ -0,0 +1,380 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
|
||||
use Symfony\Component\PropertyInfo\Type;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||
use Symfony\Component\Serializer\Exception\ExtraAttributesException;
|
||||
use Symfony\Component\Serializer\Exception\LogicException;
|
||||
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
|
||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
|
||||
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
||||
|
||||
/**
|
||||
* Base class for a normalizer dealing with objects.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
||||
{
|
||||
const ENABLE_MAX_DEPTH = 'enable_max_depth';
|
||||
const DEPTH_KEY_PATTERN = 'depth_%s::%s';
|
||||
const DISABLE_TYPE_ENFORCEMENT = 'disable_type_enforcement';
|
||||
|
||||
private $propertyTypeExtractor;
|
||||
private $attributesCache = array();
|
||||
private $cache = array();
|
||||
|
||||
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null)
|
||||
{
|
||||
parent::__construct($classMetadataFactory, $nameConverter);
|
||||
|
||||
$this->propertyTypeExtractor = $propertyTypeExtractor;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null)
|
||||
{
|
||||
return \is_object($data) && !$data instanceof \Traversable;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function normalize($object, $format = null, array $context = array())
|
||||
{
|
||||
if (!isset($context['cache_key'])) {
|
||||
$context['cache_key'] = $this->getCacheKey($format, $context);
|
||||
}
|
||||
|
||||
if ($this->isCircularReference($object, $context)) {
|
||||
return $this->handleCircularReference($object);
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$stack = array();
|
||||
$attributes = $this->getAttributes($object, $format, $context);
|
||||
$class = \get_class($object);
|
||||
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
if (null !== $attributesMetadata && $this->isMaxDepthReached($attributesMetadata, $class, $attribute, $context)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attributeValue = $this->getAttributeValue($object, $attribute, $format, $context);
|
||||
|
||||
if (isset($this->callbacks[$attribute])) {
|
||||
$attributeValue = \call_user_func($this->callbacks[$attribute], $attributeValue);
|
||||
}
|
||||
|
||||
if (null !== $attributeValue && !is_scalar($attributeValue)) {
|
||||
$stack[$attribute] = $attributeValue;
|
||||
}
|
||||
|
||||
$data = $this->updateData($data, $attribute, $attributeValue);
|
||||
}
|
||||
|
||||
foreach ($stack as $attribute => $attributeValue) {
|
||||
if (!$this->serializer instanceof NormalizerInterface) {
|
||||
throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer', $attribute));
|
||||
}
|
||||
|
||||
$data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $this->createChildContext($context, $attribute)));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and caches attributes for the given object, format and context.
|
||||
*
|
||||
* @param object $object
|
||||
* @param string|null $format
|
||||
* @param array $context
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getAttributes($object, $format = null, array $context)
|
||||
{
|
||||
$class = \get_class($object);
|
||||
$key = $class.'-'.$context['cache_key'];
|
||||
|
||||
if (isset($this->attributesCache[$key])) {
|
||||
return $this->attributesCache[$key];
|
||||
}
|
||||
|
||||
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
|
||||
|
||||
if (false !== $allowedAttributes) {
|
||||
if ($context['cache_key']) {
|
||||
$this->attributesCache[$key] = $allowedAttributes;
|
||||
}
|
||||
|
||||
return $allowedAttributes;
|
||||
}
|
||||
|
||||
if (isset($context['attributes'])) {
|
||||
return $this->extractAttributes($object, $format, $context);
|
||||
}
|
||||
|
||||
if (isset($this->attributesCache[$class])) {
|
||||
return $this->attributesCache[$class];
|
||||
}
|
||||
|
||||
return $this->attributesCache[$class] = $this->extractAttributes($object, $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts attributes to normalize from the class of the given object, format and context.
|
||||
*
|
||||
* @param object $object
|
||||
* @param string|null $format
|
||||
* @param array $context
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
abstract protected function extractAttributes($object, $format = null, array $context = array());
|
||||
|
||||
/**
|
||||
* Gets the attribute value.
|
||||
*
|
||||
* @param object $object
|
||||
* @param string $attribute
|
||||
* @param string|null $format
|
||||
* @param array $context
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function getAttributeValue($object, $attribute, $format = null, array $context = array());
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null)
|
||||
{
|
||||
return isset($this->cache[$type]) ? $this->cache[$type] : $this->cache[$type] = class_exists($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function denormalize($data, $class, $format = null, array $context = array())
|
||||
{
|
||||
if (!isset($context['cache_key'])) {
|
||||
$context['cache_key'] = $this->getCacheKey($format, $context);
|
||||
}
|
||||
|
||||
$allowedAttributes = $this->getAllowedAttributes($class, $context, true);
|
||||
$normalizedData = $this->prepareForDenormalization($data);
|
||||
$extraAttributes = array();
|
||||
|
||||
$reflectionClass = new \ReflectionClass($class);
|
||||
$object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes, $format);
|
||||
|
||||
foreach ($normalizedData as $attribute => $value) {
|
||||
if ($this->nameConverter) {
|
||||
$attribute = $this->nameConverter->denormalize($attribute);
|
||||
}
|
||||
|
||||
if ((false !== $allowedAttributes && !\in_array($attribute, $allowedAttributes)) || !$this->isAllowedAttribute($class, $attribute, $format, $context)) {
|
||||
if (isset($context[self::ALLOW_EXTRA_ATTRIBUTES]) && !$context[self::ALLOW_EXTRA_ATTRIBUTES]) {
|
||||
$extraAttributes[] = $attribute;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $this->validateAndDenormalize($class, $attribute, $value, $format, $context);
|
||||
try {
|
||||
$this->setAttributeValue($object, $attribute, $value, $format, $context);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
throw new NotNormalizableValueException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($extraAttributes)) {
|
||||
throw new ExtraAttributesException($extraAttributes);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets attribute value.
|
||||
*
|
||||
* @param object $object
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param string|null $format
|
||||
* @param array $context
|
||||
*/
|
||||
abstract protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array());
|
||||
|
||||
/**
|
||||
* Validates the submitted data and denormalizes it.
|
||||
*
|
||||
* @param string $currentClass
|
||||
* @param string $attribute
|
||||
* @param mixed $data
|
||||
* @param string|null $format
|
||||
* @param array $context
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws NotNormalizableValueException
|
||||
* @throws LogicException
|
||||
*/
|
||||
private function validateAndDenormalize($currentClass, $attribute, $data, $format, array $context)
|
||||
{
|
||||
if (null === $this->propertyTypeExtractor || null === $types = $this->propertyTypeExtractor->getTypes($currentClass, $attribute)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$expectedTypes = array();
|
||||
foreach ($types as $type) {
|
||||
if (null === $data && $type->isNullable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type->isCollection() && null !== ($collectionValueType = $type->getCollectionValueType()) && Type::BUILTIN_TYPE_OBJECT === $collectionValueType->getBuiltinType()) {
|
||||
$builtinType = Type::BUILTIN_TYPE_OBJECT;
|
||||
$class = $collectionValueType->getClassName().'[]';
|
||||
|
||||
// Fix a collection that contains the only one element
|
||||
// This is special to xml format only
|
||||
if ('xml' === $format && !\is_int(key($data))) {
|
||||
$data = array($data);
|
||||
}
|
||||
|
||||
if (null !== $collectionKeyType = $type->getCollectionKeyType()) {
|
||||
$context['key_type'] = $collectionKeyType;
|
||||
}
|
||||
} else {
|
||||
$builtinType = $type->getBuiltinType();
|
||||
$class = $type->getClassName();
|
||||
}
|
||||
|
||||
$expectedTypes[Type::BUILTIN_TYPE_OBJECT === $builtinType && $class ? $class : $builtinType] = true;
|
||||
|
||||
if (Type::BUILTIN_TYPE_OBJECT === $builtinType) {
|
||||
if (!$this->serializer instanceof DenormalizerInterface) {
|
||||
throw new LogicException(sprintf('Cannot denormalize attribute "%s" for class "%s" because injected serializer is not a denormalizer', $attribute, $class));
|
||||
}
|
||||
|
||||
$childContext = $this->createChildContext($context, $attribute);
|
||||
if ($this->serializer->supportsDenormalization($data, $class, $format, $childContext)) {
|
||||
return $this->serializer->denormalize($data, $class, $format, $childContext);
|
||||
}
|
||||
}
|
||||
|
||||
// JSON only has a Number type corresponding to both int and float PHP types.
|
||||
// PHP's json_encode, JavaScript's JSON.stringify, Go's json.Marshal as well as most other JSON encoders convert
|
||||
// floating-point numbers like 12.0 to 12 (the decimal part is dropped when possible).
|
||||
// PHP's json_decode automatically converts Numbers without a decimal part to integers.
|
||||
// To circumvent this behavior, integers are converted to floats when denormalizing JSON based formats and when
|
||||
// a float is expected.
|
||||
if (Type::BUILTIN_TYPE_FLOAT === $builtinType && \is_int($data) && false !== strpos($format, JsonEncoder::FORMAT)) {
|
||||
return (float) $data;
|
||||
}
|
||||
|
||||
if (\call_user_func('is_'.$builtinType, $data)) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($context[self::DISABLE_TYPE_ENFORCEMENT])) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
throw new NotNormalizableValueException(sprintf('The type of the "%s" attribute for class "%s" must be one of "%s" ("%s" given).', $attribute, $currentClass, implode('", "', array_keys($expectedTypes)), \gettype($data)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an attribute and apply the name converter if necessary.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $attributeValue
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function updateData(array $data, $attribute, $attributeValue)
|
||||
{
|
||||
if ($this->nameConverter) {
|
||||
$attribute = $this->nameConverter->normalize($attribute);
|
||||
}
|
||||
|
||||
$data[$attribute] = $attributeValue;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the max depth reached for the given attribute?
|
||||
*
|
||||
* @param AttributeMetadataInterface[] $attributesMetadata
|
||||
* @param string $class
|
||||
* @param string $attribute
|
||||
* @param array $context
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isMaxDepthReached(array $attributesMetadata, $class, $attribute, array &$context)
|
||||
{
|
||||
if (
|
||||
!isset($context[static::ENABLE_MAX_DEPTH]) ||
|
||||
!$context[static::ENABLE_MAX_DEPTH] ||
|
||||
!isset($attributesMetadata[$attribute]) ||
|
||||
null === $maxDepth = $attributesMetadata[$attribute]->getMaxDepth()
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$key = sprintf(static::DEPTH_KEY_PATTERN, $class, $attribute);
|
||||
if (!isset($context[$key])) {
|
||||
$context[$key] = 1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($context[$key] === $maxDepth) {
|
||||
return true;
|
||||
}
|
||||
|
||||
++$context[$key];
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cache key to use.
|
||||
*
|
||||
* @param string|null $format
|
||||
* @param array $context
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
private function getCacheKey($format, array $context)
|
||||
{
|
||||
try {
|
||||
return md5($format.serialize($context));
|
||||
} catch (\Exception $exception) {
|
||||
// The context cannot be serialized, skip the cache
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
88
vendor/symfony/serializer/Normalizer/ArrayDenormalizer.php
vendored
Normal file
88
vendor/symfony/serializer/Normalizer/ArrayDenormalizer.php
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\BadMethodCallException;
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
|
||||
use Symfony\Component\Serializer\SerializerAwareInterface;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
/**
|
||||
* Denormalizes arrays of objects.
|
||||
*
|
||||
* @author Alexander M. Turek <me@derrabus.de>
|
||||
*
|
||||
* @final since version 3.3.
|
||||
*/
|
||||
class ArrayDenormalizer implements DenormalizerInterface, SerializerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var SerializerInterface|DenormalizerInterface
|
||||
*/
|
||||
private $serializer;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws NotNormalizableValueException
|
||||
*/
|
||||
public function denormalize($data, $class, $format = null, array $context = array())
|
||||
{
|
||||
if (null === $this->serializer) {
|
||||
throw new BadMethodCallException('Please set a serializer before calling denormalize()!');
|
||||
}
|
||||
if (!\is_array($data)) {
|
||||
throw new InvalidArgumentException('Data expected to be an array, '.\gettype($data).' given.');
|
||||
}
|
||||
if ('[]' !== substr($class, -2)) {
|
||||
throw new InvalidArgumentException('Unsupported class: '.$class);
|
||||
}
|
||||
|
||||
$serializer = $this->serializer;
|
||||
$class = substr($class, 0, -2);
|
||||
|
||||
$builtinType = isset($context['key_type']) ? $context['key_type']->getBuiltinType() : null;
|
||||
foreach ($data as $key => $value) {
|
||||
if (null !== $builtinType && !\call_user_func('is_'.$builtinType, $key)) {
|
||||
throw new NotNormalizableValueException(sprintf('The type of the key "%s" must be "%s" ("%s" given).', $key, $builtinType, \gettype($key)));
|
||||
}
|
||||
|
||||
$data[$key] = $serializer->denormalize($value, $class, $format, $context);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null/*, array $context = array()*/)
|
||||
{
|
||||
$context = \func_num_args() > 3 ? func_get_arg(3) : array();
|
||||
|
||||
return '[]' === substr($type, -2)
|
||||
&& $this->serializer->supportsDenormalization($data, substr($type, 0, -2), $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSerializer(SerializerInterface $serializer)
|
||||
{
|
||||
if (!$serializer instanceof DenormalizerInterface) {
|
||||
throw new InvalidArgumentException('Expected a serializer that also implements DenormalizerInterface.');
|
||||
}
|
||||
|
||||
$this->serializer = $serializer;
|
||||
}
|
||||
}
|
27
vendor/symfony/serializer/Normalizer/ContextAwareDenormalizerInterface.php
vendored
Normal file
27
vendor/symfony/serializer/Normalizer/ContextAwareDenormalizerInterface.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
/**
|
||||
* Adds the support of an extra $context parameter for the supportsDenormalization method.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface ContextAwareDenormalizerInterface extends DenormalizerInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param array $context options that denormalizers have access to
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null, array $context = array());
|
||||
}
|
27
vendor/symfony/serializer/Normalizer/ContextAwareNormalizerInterface.php
vendored
Normal file
27
vendor/symfony/serializer/Normalizer/ContextAwareNormalizerInterface.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
/**
|
||||
* Adds the support of an extra $context parameter for the supportsNormalization method.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface ContextAwareNormalizerInterface extends NormalizerInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param array $context options that normalizers have access to
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null, array $context = array());
|
||||
}
|
80
vendor/symfony/serializer/Normalizer/CustomNormalizer.php
vendored
Normal file
80
vendor/symfony/serializer/Normalizer/CustomNormalizer.php
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
use Symfony\Component\Serializer\SerializerAwareInterface;
|
||||
use Symfony\Component\Serializer\SerializerAwareTrait;
|
||||
|
||||
/**
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class CustomNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
|
||||
{
|
||||
use ObjectToPopulateTrait;
|
||||
use SerializerAwareTrait;
|
||||
|
||||
private $cache = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function normalize($object, $format = null, array $context = array())
|
||||
{
|
||||
return $object->normalize($this->serializer, $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function denormalize($data, $class, $format = null, array $context = array())
|
||||
{
|
||||
$object = $this->extractObjectToPopulate($class, $context) ?: new $class();
|
||||
$object->denormalize($this->serializer, $data, $format, $context);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given class implements the NormalizableInterface.
|
||||
*
|
||||
* @param mixed $data Data to normalize
|
||||
* @param string $format The format being (de-)serialized from or into
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null)
|
||||
{
|
||||
return $data instanceof NormalizableInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given class implements the DenormalizableInterface.
|
||||
*
|
||||
* @param mixed $data Data to denormalize from
|
||||
* @param string $type The class to which the data should be denormalized
|
||||
* @param string $format The format being deserialized from
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null)
|
||||
{
|
||||
if (isset($this->cache[$type])) {
|
||||
return $this->cache[$type];
|
||||
}
|
||||
|
||||
if (!class_exists($type)) {
|
||||
return $this->cache[$type] = false;
|
||||
}
|
||||
|
||||
return $this->cache[$type] = is_subclass_of($type, 'Symfony\Component\Serializer\Normalizer\DenormalizableInterface');
|
||||
}
|
||||
}
|
157
vendor/symfony/serializer/Normalizer/DataUriNormalizer.php
vendored
Normal file
157
vendor/symfony/serializer/Normalizer/DataUriNormalizer.php
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
use Symfony\Component\HttpFoundation\File\File;
|
||||
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
|
||||
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
|
||||
|
||||
/**
|
||||
* Normalizes an {@see \SplFileInfo} object to a data URI.
|
||||
* Denormalizes a data URI to a {@see \SplFileObject} object.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface
|
||||
{
|
||||
private static $supportedTypes = array(
|
||||
\SplFileInfo::class => true,
|
||||
\SplFileObject::class => true,
|
||||
File::class => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* @var MimeTypeGuesserInterface
|
||||
*/
|
||||
private $mimeTypeGuesser;
|
||||
|
||||
public function __construct(MimeTypeGuesserInterface $mimeTypeGuesser = null)
|
||||
{
|
||||
if (null === $mimeTypeGuesser && class_exists('Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser')) {
|
||||
$mimeTypeGuesser = MimeTypeGuesser::getInstance();
|
||||
}
|
||||
|
||||
$this->mimeTypeGuesser = $mimeTypeGuesser;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function normalize($object, $format = null, array $context = array())
|
||||
{
|
||||
if (!$object instanceof \SplFileInfo) {
|
||||
throw new InvalidArgumentException('The object must be an instance of "\SplFileInfo".');
|
||||
}
|
||||
|
||||
$mimeType = $this->getMimeType($object);
|
||||
$splFileObject = $this->extractSplFileObject($object);
|
||||
|
||||
$data = '';
|
||||
|
||||
$splFileObject->rewind();
|
||||
while (!$splFileObject->eof()) {
|
||||
$data .= $splFileObject->fgets();
|
||||
}
|
||||
|
||||
if ('text' === explode('/', $mimeType, 2)[0]) {
|
||||
return sprintf('data:%s,%s', $mimeType, rawurlencode($data));
|
||||
}
|
||||
|
||||
return sprintf('data:%s;base64,%s', $mimeType, base64_encode($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null)
|
||||
{
|
||||
return $data instanceof \SplFileInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Regex adapted from Brian Grinstead code.
|
||||
*
|
||||
* @see https://gist.github.com/bgrins/6194623
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws NotNormalizableValueException
|
||||
*/
|
||||
public function denormalize($data, $class, $format = null, array $context = array())
|
||||
{
|
||||
if (!preg_match('/^data:([a-z0-9][a-z0-9\!\#\$\&\-\^\_\+\.]{0,126}\/[a-z0-9][a-z0-9\!\#\$\&\-\^\_\+\.]{0,126}(;[a-z0-9\-]+\=[a-z0-9\-]+)?)?(;base64)?,[a-z0-9\!\$\&\\\'\,\(\)\*\+\,\;\=\-\.\_\~\:\@\/\?\%\s]*\s*$/i', $data)) {
|
||||
throw new NotNormalizableValueException('The provided "data:" URI is not valid.');
|
||||
}
|
||||
|
||||
try {
|
||||
switch ($class) {
|
||||
case 'Symfony\Component\HttpFoundation\File\File':
|
||||
return new File($data, false);
|
||||
|
||||
case 'SplFileObject':
|
||||
case 'SplFileInfo':
|
||||
return new \SplFileObject($data);
|
||||
}
|
||||
} catch (\RuntimeException $exception) {
|
||||
throw new NotNormalizableValueException($exception->getMessage(), $exception->getCode(), $exception);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('The class parameter "%s" is not supported. It must be one of "SplFileInfo", "SplFileObject" or "Symfony\Component\HttpFoundation\File\File".', $class));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null)
|
||||
{
|
||||
return isset(self::$supportedTypes[$type]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mime type of the object. Defaults to application/octet-stream.
|
||||
*
|
||||
* @param \SplFileInfo $object
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getMimeType(\SplFileInfo $object)
|
||||
{
|
||||
if ($object instanceof File) {
|
||||
return $object->getMimeType();
|
||||
}
|
||||
|
||||
if ($this->mimeTypeGuesser && $mimeType = $this->mimeTypeGuesser->guess($object->getPathname())) {
|
||||
return $mimeType;
|
||||
}
|
||||
|
||||
return 'application/octet-stream';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the \SplFileObject instance associated with the given \SplFileInfo instance.
|
||||
*
|
||||
* @param \SplFileInfo $object
|
||||
*
|
||||
* @return \SplFileObject
|
||||
*/
|
||||
private function extractSplFileObject(\SplFileInfo $object)
|
||||
{
|
||||
if ($object instanceof \SplFileObject) {
|
||||
return $object;
|
||||
}
|
||||
|
||||
return $object->openFile();
|
||||
}
|
||||
}
|
103
vendor/symfony/serializer/Normalizer/DateIntervalNormalizer.php
vendored
Normal file
103
vendor/symfony/serializer/Normalizer/DateIntervalNormalizer.php
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* Normalizes an instance of {@see \DateInterval} to an interval string.
|
||||
* Denormalizes an interval string to an instance of {@see \DateInterval}.
|
||||
*
|
||||
* @author Jérôme Parmentier <jerome@prmntr.me>
|
||||
*/
|
||||
class DateIntervalNormalizer implements NormalizerInterface, DenormalizerInterface
|
||||
{
|
||||
const FORMAT_KEY = 'dateinterval_format';
|
||||
|
||||
private $format;
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
*/
|
||||
public function __construct($format = 'P%yY%mM%dDT%hH%iM%sS')
|
||||
{
|
||||
$this->format = $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function normalize($object, $format = null, array $context = array())
|
||||
{
|
||||
if (!$object instanceof \DateInterval) {
|
||||
throw new InvalidArgumentException('The object must be an instance of "\DateInterval".');
|
||||
}
|
||||
|
||||
$dateIntervalFormat = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : $this->format;
|
||||
|
||||
return $object->format($dateIntervalFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null)
|
||||
{
|
||||
return $data instanceof \DateInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
public function denormalize($data, $class, $format = null, array $context = array())
|
||||
{
|
||||
if (!\is_string($data)) {
|
||||
throw new InvalidArgumentException(sprintf('Data expected to be a string, %s given.', \gettype($data)));
|
||||
}
|
||||
|
||||
if (!$this->isISO8601($data)) {
|
||||
throw new UnexpectedValueException('Expected a valid ISO 8601 interval string.');
|
||||
}
|
||||
|
||||
$dateIntervalFormat = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : $this->format;
|
||||
|
||||
$valuePattern = '/^'.preg_replace('/%([yYmMdDhHiIsSwW])(\w)/', '(?P<$1>\d+)$2', $dateIntervalFormat).'$/';
|
||||
if (!preg_match($valuePattern, $data)) {
|
||||
throw new UnexpectedValueException(sprintf('Value "%s" contains intervals not accepted by format "%s".', $data, $dateIntervalFormat));
|
||||
}
|
||||
|
||||
try {
|
||||
return new \DateInterval($data);
|
||||
} catch (\Exception $e) {
|
||||
throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null)
|
||||
{
|
||||
return \DateInterval::class === $type;
|
||||
}
|
||||
|
||||
private function isISO8601($string)
|
||||
{
|
||||
return preg_match('/^P(?=\w*(?:\d|%\w))(?:\d+Y|%[yY]Y)?(?:\d+M|%[mM]M)?(?:(?:\d+D|%[dD]D)|(?:\d+W|%[wW]W))?(?:T(?:\d+H|[hH]H)?(?:\d+M|[iI]M)?(?:\d+S|[sS]S)?)?$/', $string);
|
||||
}
|
||||
}
|
154
vendor/symfony/serializer/Normalizer/DateTimeNormalizer.php
vendored
Normal file
154
vendor/symfony/serializer/Normalizer/DateTimeNormalizer.php
vendored
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
|
||||
|
||||
/**
|
||||
* Normalizes an object implementing the {@see \DateTimeInterface} to a date string.
|
||||
* Denormalizes a date string to an instance of {@see \DateTime} or {@see \DateTimeImmutable}.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface
|
||||
{
|
||||
const FORMAT_KEY = 'datetime_format';
|
||||
const TIMEZONE_KEY = 'datetime_timezone';
|
||||
|
||||
private $format;
|
||||
private $timezone;
|
||||
|
||||
private static $supportedTypes = array(
|
||||
\DateTimeInterface::class => true,
|
||||
\DateTimeImmutable::class => true,
|
||||
\DateTime::class => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* @param string $format
|
||||
* @param \DateTimeZone|null $timezone
|
||||
*/
|
||||
public function __construct($format = \DateTime::RFC3339, \DateTimeZone $timezone = null)
|
||||
{
|
||||
$this->format = $format;
|
||||
$this->timezone = $timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function normalize($object, $format = null, array $context = array())
|
||||
{
|
||||
if (!$object instanceof \DateTimeInterface) {
|
||||
throw new InvalidArgumentException('The object must implement the "\DateTimeInterface".');
|
||||
}
|
||||
|
||||
$format = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : $this->format;
|
||||
$timezone = $this->getTimezone($context);
|
||||
|
||||
if (null !== $timezone) {
|
||||
$object = (new \DateTimeImmutable('@'.$object->getTimestamp()))->setTimezone($timezone);
|
||||
}
|
||||
|
||||
return $object->format($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null)
|
||||
{
|
||||
return $data instanceof \DateTimeInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws NotNormalizableValueException
|
||||
*/
|
||||
public function denormalize($data, $class, $format = null, array $context = array())
|
||||
{
|
||||
$dateTimeFormat = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : null;
|
||||
$timezone = $this->getTimezone($context);
|
||||
|
||||
if ('' === $data || null === $data) {
|
||||
throw new NotNormalizableValueException('The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.');
|
||||
}
|
||||
|
||||
if (null !== $dateTimeFormat) {
|
||||
if (null === $timezone && \PHP_VERSION_ID < 70000) {
|
||||
// https://bugs.php.net/bug.php?id=68669
|
||||
$object = \DateTime::class === $class ? \DateTime::createFromFormat($dateTimeFormat, $data) : \DateTimeImmutable::createFromFormat($dateTimeFormat, $data);
|
||||
} else {
|
||||
$object = \DateTime::class === $class ? \DateTime::createFromFormat($dateTimeFormat, $data, $timezone) : \DateTimeImmutable::createFromFormat($dateTimeFormat, $data, $timezone);
|
||||
}
|
||||
|
||||
if (false !== $object) {
|
||||
return $object;
|
||||
}
|
||||
|
||||
$dateTimeErrors = \DateTime::class === $class ? \DateTime::getLastErrors() : \DateTimeImmutable::getLastErrors();
|
||||
|
||||
throw new NotNormalizableValueException(sprintf(
|
||||
'Parsing datetime string "%s" using format "%s" resulted in %d errors:'."\n".'%s',
|
||||
$data,
|
||||
$dateTimeFormat,
|
||||
$dateTimeErrors['error_count'],
|
||||
implode("\n", $this->formatDateTimeErrors($dateTimeErrors['errors']))
|
||||
));
|
||||
}
|
||||
|
||||
try {
|
||||
return \DateTime::class === $class ? new \DateTime($data, $timezone) : new \DateTimeImmutable($data, $timezone);
|
||||
} catch (\Exception $e) {
|
||||
throw new NotNormalizableValueException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null)
|
||||
{
|
||||
return isset(self::$supportedTypes[$type]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats datetime errors.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function formatDateTimeErrors(array $errors)
|
||||
{
|
||||
$formattedErrors = array();
|
||||
|
||||
foreach ($errors as $pos => $message) {
|
||||
$formattedErrors[] = sprintf('at position %d: %s', $pos, $message);
|
||||
}
|
||||
|
||||
return $formattedErrors;
|
||||
}
|
||||
|
||||
private function getTimezone(array $context)
|
||||
{
|
||||
$dateTimeZone = array_key_exists(self::TIMEZONE_KEY, $context) ? $context[self::TIMEZONE_KEY] : $this->timezone;
|
||||
|
||||
if (null === $dateTimeZone) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $dateTimeZone instanceof \DateTimeZone ? $dateTimeZone : new \DateTimeZone($dateTimeZone);
|
||||
}
|
||||
}
|
40
vendor/symfony/serializer/Normalizer/DenormalizableInterface.php
vendored
Normal file
40
vendor/symfony/serializer/Normalizer/DenormalizableInterface.php
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
/**
|
||||
* Defines the most basic interface a class must implement to be denormalizable.
|
||||
*
|
||||
* If a denormalizer is registered for the class and it doesn't implement
|
||||
* the Denormalizable interfaces, the normalizer will be used instead
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface DenormalizableInterface
|
||||
{
|
||||
/**
|
||||
* Denormalizes the object back from an array of scalars|arrays.
|
||||
*
|
||||
* It is important to understand that the denormalize() call should denormalize
|
||||
* recursively all child objects of the implementor.
|
||||
*
|
||||
* @param DenormalizerInterface $denormalizer The denormalizer is given so that you
|
||||
* can use it to denormalize objects contained within this object
|
||||
* @param array|string|int|float|bool $data The data from which to re-create the object
|
||||
* @param string|null $format The format is optionally given to be able to denormalize
|
||||
* differently based on different input formats
|
||||
* @param array $context Options for denormalizing
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array());
|
||||
}
|
27
vendor/symfony/serializer/Normalizer/DenormalizerAwareInterface.php
vendored
Normal file
27
vendor/symfony/serializer/Normalizer/DenormalizerAwareInterface.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
/**
|
||||
* Class accepting a denormalizer.
|
||||
*
|
||||
* @author Joel Wurtz <joel.wurtz@gmail.com>
|
||||
*/
|
||||
interface DenormalizerAwareInterface
|
||||
{
|
||||
/**
|
||||
* Sets the owning Denormalizer object.
|
||||
*
|
||||
* @param DenormalizerInterface $denormalizer
|
||||
*/
|
||||
public function setDenormalizer(DenormalizerInterface $denormalizer);
|
||||
}
|
35
vendor/symfony/serializer/Normalizer/DenormalizerAwareTrait.php
vendored
Normal file
35
vendor/symfony/serializer/Normalizer/DenormalizerAwareTrait.php
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
/**
|
||||
* DenormalizerAware trait.
|
||||
*
|
||||
* @author Joel Wurtz <joel.wurtz@gmail.com>
|
||||
*/
|
||||
trait DenormalizerAwareTrait
|
||||
{
|
||||
/**
|
||||
* @var DenormalizerInterface
|
||||
*/
|
||||
protected $denormalizer;
|
||||
|
||||
/**
|
||||
* Sets the Denormalizer.
|
||||
*
|
||||
* @param DenormalizerInterface $denormalizer A DenormalizerInterface instance
|
||||
*/
|
||||
public function setDenormalizer(DenormalizerInterface $denormalizer)
|
||||
{
|
||||
$this->denormalizer = $denormalizer;
|
||||
}
|
||||
}
|
57
vendor/symfony/serializer/Normalizer/DenormalizerInterface.php
vendored
Normal file
57
vendor/symfony/serializer/Normalizer/DenormalizerInterface.php
vendored
Normal file
|
@ -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\Normalizer;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\BadMethodCallException;
|
||||
use Symfony\Component\Serializer\Exception\ExtraAttributesException;
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Serializer\Exception\LogicException;
|
||||
use Symfony\Component\Serializer\Exception\RuntimeException;
|
||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* Defines the interface of denormalizers.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface DenormalizerInterface
|
||||
{
|
||||
/**
|
||||
* Denormalizes data back into an object of the given class.
|
||||
*
|
||||
* @param mixed $data Data to restore
|
||||
* @param string $class The expected class to instantiate
|
||||
* @param string $format Format the given data was extracted from
|
||||
* @param array $context Options available to the denormalizer
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @throws BadMethodCallException Occurs when the normalizer is not called in an expected context
|
||||
* @throws InvalidArgumentException Occurs when the arguments are not coherent or not supported
|
||||
* @throws UnexpectedValueException Occurs when the item cannot be hydrated with the given data
|
||||
* @throws ExtraAttributesException Occurs when the item doesn't have attribute to receive given data
|
||||
* @throws LogicException Occurs when the normalizer is not supposed to denormalize
|
||||
* @throws RuntimeException Occurs if the class cannot be instantiated
|
||||
*/
|
||||
public function denormalize($data, $class, $format = null, array $context = array());
|
||||
|
||||
/**
|
||||
* Checks whether the given class is supported for denormalization by this normalizer.
|
||||
*
|
||||
* @param mixed $data Data to denormalize from
|
||||
* @param string $type The class to which the data should be denormalized
|
||||
* @param string $format The format being deserialized from
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null);
|
||||
}
|
159
vendor/symfony/serializer/Normalizer/GetSetMethodNormalizer.php
vendored
Normal file
159
vendor/symfony/serializer/Normalizer/GetSetMethodNormalizer.php
vendored
Normal file
|
@ -0,0 +1,159 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
/**
|
||||
* Converts between objects with getter and setter methods and arrays.
|
||||
*
|
||||
* The normalization process looks at all public methods and calls the ones
|
||||
* which have a name starting with get and take no parameters. The result is a
|
||||
* map from property names (method name stripped of the get prefix and converted
|
||||
* to lower case) to property values. Property values are normalized through the
|
||||
* serializer.
|
||||
*
|
||||
* The denormalization first looks at the constructor of the given class to see
|
||||
* if any of the parameters have the same name as one of the properties. The
|
||||
* constructor is then called with all parameters or an exception is thrown if
|
||||
* any required parameters were not present as properties. Then the denormalizer
|
||||
* walks through the given map of property names to property values to see if a
|
||||
* setter method exists for any of the properties. If a setter exists it is
|
||||
* called with the property value. No automatic denormalization of the value
|
||||
* takes place.
|
||||
*
|
||||
* @author Nils Adermann <naderman@naderman.de>
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class GetSetMethodNormalizer extends AbstractObjectNormalizer
|
||||
{
|
||||
private static $setterAccessibleCache = array();
|
||||
private $cache = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null)
|
||||
{
|
||||
return parent::supportsNormalization($data, $format) && (isset($this->cache[$type = \get_class($data)]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null)
|
||||
{
|
||||
return parent::supportsDenormalization($data, $type, $format) && (isset($this->cache[$type]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given class has any get{Property} method.
|
||||
*
|
||||
* @param string $class
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function supports($class)
|
||||
{
|
||||
$class = new \ReflectionClass($class);
|
||||
$methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
|
||||
foreach ($methods as $method) {
|
||||
if ($this->isGetMethod($method)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a method's name is get.* or is.*, and can be called without parameters.
|
||||
*
|
||||
* @return bool whether the method is a getter or boolean getter
|
||||
*/
|
||||
private function isGetMethod(\ReflectionMethod $method)
|
||||
{
|
||||
$methodLength = \strlen($method->name);
|
||||
|
||||
return
|
||||
!$method->isStatic() &&
|
||||
(
|
||||
((0 === strpos($method->name, 'get') && 3 < $methodLength) ||
|
||||
(0 === strpos($method->name, 'is') && 2 < $methodLength) ||
|
||||
(0 === strpos($method->name, 'has') && 3 < $methodLength)) &&
|
||||
0 === $method->getNumberOfRequiredParameters()
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function extractAttributes($object, $format = null, array $context = array())
|
||||
{
|
||||
$reflectionObject = new \ReflectionObject($object);
|
||||
$reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC);
|
||||
|
||||
$attributes = array();
|
||||
foreach ($reflectionMethods as $method) {
|
||||
if (!$this->isGetMethod($method)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attributeName = lcfirst(substr($method->name, 0 === strpos($method->name, 'is') ? 2 : 3));
|
||||
|
||||
if ($this->isAllowedAttribute($object, $attributeName)) {
|
||||
$attributes[] = $attributeName;
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getAttributeValue($object, $attribute, $format = null, array $context = array())
|
||||
{
|
||||
$ucfirsted = ucfirst($attribute);
|
||||
|
||||
$getter = 'get'.$ucfirsted;
|
||||
if (\is_callable(array($object, $getter))) {
|
||||
return $object->$getter();
|
||||
}
|
||||
|
||||
$isser = 'is'.$ucfirsted;
|
||||
if (\is_callable(array($object, $isser))) {
|
||||
return $object->$isser();
|
||||
}
|
||||
|
||||
$haser = 'has'.$ucfirsted;
|
||||
if (\is_callable(array($object, $haser))) {
|
||||
return $object->$haser();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array())
|
||||
{
|
||||
$setter = 'set'.ucfirst($attribute);
|
||||
$key = \get_class($object).':'.$setter;
|
||||
|
||||
if (!isset(self::$setterAccessibleCache[$key])) {
|
||||
self::$setterAccessibleCache[$key] = \is_callable(array($object, $setter)) && !(new \ReflectionMethod($object, $setter))->isStatic();
|
||||
}
|
||||
|
||||
if (self::$setterAccessibleCache[$key]) {
|
||||
$object->$setter($value);
|
||||
}
|
||||
}
|
||||
}
|
67
vendor/symfony/serializer/Normalizer/JsonSerializableNormalizer.php
vendored
Normal file
67
vendor/symfony/serializer/Normalizer/JsonSerializableNormalizer.php
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Serializer\Exception\LogicException;
|
||||
|
||||
/**
|
||||
* A normalizer that uses an objects own JsonSerializable implementation.
|
||||
*
|
||||
* @author Fred Cox <mcfedr@gmail.com>
|
||||
*/
|
||||
class JsonSerializableNormalizer extends AbstractNormalizer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function normalize($object, $format = null, array $context = array())
|
||||
{
|
||||
if ($this->isCircularReference($object, $context)) {
|
||||
return $this->handleCircularReference($object);
|
||||
}
|
||||
|
||||
if (!$object instanceof \JsonSerializable) {
|
||||
throw new InvalidArgumentException(sprintf('The object must implement "%s".', \JsonSerializable::class));
|
||||
}
|
||||
|
||||
if (!$this->serializer instanceof NormalizerInterface) {
|
||||
throw new LogicException('Cannot normalize object because injected serializer is not a normalizer');
|
||||
}
|
||||
|
||||
return $this->serializer->normalize($object->jsonSerialize(), $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null)
|
||||
{
|
||||
return $data instanceof \JsonSerializable;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function denormalize($data, $class, $format = null, array $context = array())
|
||||
{
|
||||
throw new LogicException(sprintf('Cannot denormalize with "%s".', \JsonSerializable::class));
|
||||
}
|
||||
}
|
39
vendor/symfony/serializer/Normalizer/NormalizableInterface.php
vendored
Normal file
39
vendor/symfony/serializer/Normalizer/NormalizableInterface.php
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
/**
|
||||
* Defines the most basic interface a class must implement to be normalizable.
|
||||
*
|
||||
* If a normalizer is registered for the class and it doesn't implement
|
||||
* the Normalizable interfaces, the normalizer will be used instead.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface NormalizableInterface
|
||||
{
|
||||
/**
|
||||
* Normalizes the object into an array of scalars|arrays.
|
||||
*
|
||||
* It is important to understand that the normalize() call should normalize
|
||||
* recursively all child objects of the implementor.
|
||||
*
|
||||
* @param NormalizerInterface $normalizer The normalizer is given so that you
|
||||
* can use it to normalize objects contained within this object
|
||||
* @param string|null $format The format is optionally given to be able to normalize differently
|
||||
* based on different output formats
|
||||
* @param array $context Options for normalizing this object
|
||||
*
|
||||
* @return array|string|int|float|bool
|
||||
*/
|
||||
public function normalize(NormalizerInterface $normalizer, $format = null, array $context = array());
|
||||
}
|
27
vendor/symfony/serializer/Normalizer/NormalizerAwareInterface.php
vendored
Normal file
27
vendor/symfony/serializer/Normalizer/NormalizerAwareInterface.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
/**
|
||||
* Class accepting a normalizer.
|
||||
*
|
||||
* @author Joel Wurtz <joel.wurtz@gmail.com>
|
||||
*/
|
||||
interface NormalizerAwareInterface
|
||||
{
|
||||
/**
|
||||
* Sets the owning Normalizer object.
|
||||
*
|
||||
* @param NormalizerInterface $normalizer
|
||||
*/
|
||||
public function setNormalizer(NormalizerInterface $normalizer);
|
||||
}
|
35
vendor/symfony/serializer/Normalizer/NormalizerAwareTrait.php
vendored
Normal file
35
vendor/symfony/serializer/Normalizer/NormalizerAwareTrait.php
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
/**
|
||||
* NormalizerAware trait.
|
||||
*
|
||||
* @author Joel Wurtz <joel.wurtz@gmail.com>
|
||||
*/
|
||||
trait NormalizerAwareTrait
|
||||
{
|
||||
/**
|
||||
* @var NormalizerInterface
|
||||
*/
|
||||
protected $normalizer;
|
||||
|
||||
/**
|
||||
* Sets the normalizer.
|
||||
*
|
||||
* @param NormalizerInterface $normalizer A NormalizerInterface instance
|
||||
*/
|
||||
public function setNormalizer(NormalizerInterface $normalizer)
|
||||
{
|
||||
$this->normalizer = $normalizer;
|
||||
}
|
||||
}
|
50
vendor/symfony/serializer/Normalizer/NormalizerInterface.php
vendored
Normal file
50
vendor/symfony/serializer/Normalizer/NormalizerInterface.php
vendored
Normal file
|
@ -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\Normalizer;
|
||||
|
||||
use Symfony\Component\Serializer\Exception\CircularReferenceException;
|
||||
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Serializer\Exception\LogicException;
|
||||
|
||||
/**
|
||||
* Defines the interface of normalizers.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface NormalizerInterface
|
||||
{
|
||||
/**
|
||||
* Normalizes an object into a set of arrays/scalars.
|
||||
*
|
||||
* @param mixed $object Object to normalize
|
||||
* @param string $format Format the normalization result will be encoded as
|
||||
* @param array $context Context options for the normalizer
|
||||
*
|
||||
* @return array|string|int|float|bool
|
||||
*
|
||||
* @throws InvalidArgumentException Occurs when the object given is not an attempted type for the normalizer
|
||||
* @throws CircularReferenceException Occurs when the normalizer detects a circular reference when no circular
|
||||
* reference handler can fix it
|
||||
* @throws LogicException Occurs when the normalizer is not called in an expected context
|
||||
*/
|
||||
public function normalize($object, $format = null, array $context = array());
|
||||
|
||||
/**
|
||||
* Checks whether the given class is supported for normalization by this normalizer.
|
||||
*
|
||||
* @param mixed $data Data to normalize
|
||||
* @param string $format The format being (de-)serialized from or into
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null);
|
||||
}
|
117
vendor/symfony/serializer/Normalizer/ObjectNormalizer.php
vendored
Normal file
117
vendor/symfony/serializer/Normalizer/ObjectNormalizer.php
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
|
||||
use Symfony\Component\PropertyAccess\PropertyAccess;
|
||||
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
|
||||
use Symfony\Component\Serializer\Exception\RuntimeException;
|
||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
|
||||
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
|
||||
|
||||
/**
|
||||
* Converts between objects and arrays using the PropertyAccess component.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ObjectNormalizer extends AbstractObjectNormalizer
|
||||
{
|
||||
protected $propertyAccessor;
|
||||
|
||||
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null)
|
||||
{
|
||||
if (!\class_exists(PropertyAccess::class)) {
|
||||
throw new RuntimeException('The ObjectNormalizer class requires the "PropertyAccess" component. Install "symfony/property-access" to use it.');
|
||||
}
|
||||
|
||||
parent::__construct($classMetadataFactory, $nameConverter, $propertyTypeExtractor);
|
||||
|
||||
$this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function extractAttributes($object, $format = null, array $context = array())
|
||||
{
|
||||
// If not using groups, detect manually
|
||||
$attributes = array();
|
||||
|
||||
// methods
|
||||
$reflClass = new \ReflectionClass($object);
|
||||
foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) {
|
||||
if (
|
||||
0 !== $reflMethod->getNumberOfRequiredParameters() ||
|
||||
$reflMethod->isStatic() ||
|
||||
$reflMethod->isConstructor() ||
|
||||
$reflMethod->isDestructor()
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = $reflMethod->name;
|
||||
$attributeName = null;
|
||||
|
||||
if (0 === strpos($name, 'get') || 0 === strpos($name, 'has')) {
|
||||
// getters and hassers
|
||||
$attributeName = substr($name, 3);
|
||||
|
||||
if (!$reflClass->hasProperty($attributeName)) {
|
||||
$attributeName = lcfirst($attributeName);
|
||||
}
|
||||
} elseif (0 === strpos($name, 'is')) {
|
||||
// issers
|
||||
$attributeName = substr($name, 2);
|
||||
|
||||
if (!$reflClass->hasProperty($attributeName)) {
|
||||
$attributeName = lcfirst($attributeName);
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $attributeName && $this->isAllowedAttribute($object, $attributeName, $format, $context)) {
|
||||
$attributes[$attributeName] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// properties
|
||||
foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) {
|
||||
if ($reflProperty->isStatic() || !$this->isAllowedAttribute($object, $reflProperty->name, $format, $context)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attributes[$reflProperty->name] = true;
|
||||
}
|
||||
|
||||
return array_keys($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getAttributeValue($object, $attribute, $format = null, array $context = array())
|
||||
{
|
||||
return $this->propertyAccessor->getValue($object, $attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array())
|
||||
{
|
||||
try {
|
||||
$this->propertyAccessor->setValue($object, $attribute, $value);
|
||||
} catch (NoSuchPropertyException $exception) {
|
||||
// Properties not found are ignored
|
||||
}
|
||||
}
|
||||
}
|
37
vendor/symfony/serializer/Normalizer/ObjectToPopulateTrait.php
vendored
Normal file
37
vendor/symfony/serializer/Normalizer/ObjectToPopulateTrait.php
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
trait ObjectToPopulateTrait
|
||||
{
|
||||
/**
|
||||
* Extract the `object_to_populate` field from the context if it exists
|
||||
* and is an instance of the provided $class.
|
||||
*
|
||||
* @param string $class The class the object should be
|
||||
* @param $context The denormalization context
|
||||
* @param string $key They in which to look for the object to populate.
|
||||
* Keeps backwards compatibility with `AbstractNormalizer`.
|
||||
*
|
||||
* @return object|null an object if things check out, null otherwise
|
||||
*/
|
||||
protected function extractObjectToPopulate($class, array $context, $key = null)
|
||||
{
|
||||
$key = $key ?: 'object_to_populate';
|
||||
|
||||
if (isset($context[$key]) && \is_object($context[$key]) && $context[$key] instanceof $class) {
|
||||
return $context[$key];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
179
vendor/symfony/serializer/Normalizer/PropertyNormalizer.php
vendored
Normal file
179
vendor/symfony/serializer/Normalizer/PropertyNormalizer.php
vendored
Normal file
|
@ -0,0 +1,179 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
/**
|
||||
* Converts between objects and arrays by mapping properties.
|
||||
*
|
||||
* The normalization process looks for all the object's properties (public and private).
|
||||
* The result is a map from property names to property values. Property values
|
||||
* are normalized through the serializer.
|
||||
*
|
||||
* The denormalization first looks at the constructor of the given class to see
|
||||
* if any of the parameters have the same name as one of the properties. The
|
||||
* constructor is then called with all parameters or an exception is thrown if
|
||||
* any required parameters were not present as properties. Then the denormalizer
|
||||
* walks through the given map of property names to property values to see if a
|
||||
* property with the corresponding name exists. If found, the property gets the value.
|
||||
*
|
||||
* @author Matthieu Napoli <matthieu@mnapoli.fr>
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class PropertyNormalizer extends AbstractObjectNormalizer
|
||||
{
|
||||
private $cache = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null)
|
||||
{
|
||||
return parent::supportsNormalization($data, $format) && (isset($this->cache[$type = \get_class($data)]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null)
|
||||
{
|
||||
return parent::supportsDenormalization($data, $type, $format) && (isset($this->cache[$type]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given class has any non-static property.
|
||||
*
|
||||
* @param string $class
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function supports($class)
|
||||
{
|
||||
$class = new \ReflectionClass($class);
|
||||
|
||||
// We look for at least one non-static property
|
||||
do {
|
||||
foreach ($class->getProperties() as $property) {
|
||||
if (!$property->isStatic()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} while ($class = $class->getParentClass());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = array())
|
||||
{
|
||||
if (!parent::isAllowedAttribute($classOrObject, $attribute, $format, $context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$reflectionProperty = $this->getReflectionProperty($classOrObject, $attribute);
|
||||
if ($reflectionProperty->isStatic()) {
|
||||
return false;
|
||||
}
|
||||
} catch (\ReflectionException $reflectionException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function extractAttributes($object, $format = null, array $context = array())
|
||||
{
|
||||
$reflectionObject = new \ReflectionObject($object);
|
||||
$attributes = array();
|
||||
|
||||
do {
|
||||
foreach ($reflectionObject->getProperties() as $property) {
|
||||
if (!$this->isAllowedAttribute($reflectionObject->getName(), $property->name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attributes[] = $property->name;
|
||||
}
|
||||
} while ($reflectionObject = $reflectionObject->getParentClass());
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getAttributeValue($object, $attribute, $format = null, array $context = array())
|
||||
{
|
||||
try {
|
||||
$reflectionProperty = $this->getReflectionProperty($object, $attribute);
|
||||
} catch (\ReflectionException $reflectionException) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Override visibility
|
||||
if (!$reflectionProperty->isPublic()) {
|
||||
$reflectionProperty->setAccessible(true);
|
||||
}
|
||||
|
||||
return $reflectionProperty->getValue($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array())
|
||||
{
|
||||
try {
|
||||
$reflectionProperty = $this->getReflectionProperty($object, $attribute);
|
||||
} catch (\ReflectionException $reflectionException) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($reflectionProperty->isStatic()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Override visibility
|
||||
if (!$reflectionProperty->isPublic()) {
|
||||
$reflectionProperty->setAccessible(true);
|
||||
}
|
||||
|
||||
$reflectionProperty->setValue($object, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|object $classOrObject
|
||||
* @param string $attribute
|
||||
*
|
||||
* @return \ReflectionProperty
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
private function getReflectionProperty($classOrObject, $attribute)
|
||||
{
|
||||
$reflectionClass = new \ReflectionClass($classOrObject);
|
||||
while (true) {
|
||||
try {
|
||||
return $reflectionClass->getProperty($attribute);
|
||||
} catch (\ReflectionException $e) {
|
||||
if (!$reflectionClass = $reflectionClass->getParentClass()) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
vendor/symfony/serializer/Normalizer/SerializerAwareNormalizer.php
vendored
Normal file
27
vendor/symfony/serializer/Normalizer/SerializerAwareNormalizer.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?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\Normalizer;
|
||||
|
||||
use Symfony\Component\Serializer\SerializerAwareInterface;
|
||||
use Symfony\Component\Serializer\SerializerAwareTrait;
|
||||
|
||||
/**
|
||||
* SerializerAware Normalizer implementation.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @deprecated since version 3.1, to be removed in 4.0. Use the SerializerAwareTrait instead.
|
||||
*/
|
||||
abstract class SerializerAwareNormalizer implements SerializerAwareInterface
|
||||
{
|
||||
use SerializerAwareTrait;
|
||||
}
|
16
vendor/symfony/serializer/README.md
vendored
Normal file
16
vendor/symfony/serializer/README.md
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
Serializer Component
|
||||
====================
|
||||
|
||||
With the Serializer component it's possible to handle serializing data
|
||||
structures, including object graphs, into array structures or other formats like
|
||||
XML and JSON. It can also handle deserializing XML and JSON back to object
|
||||
graphs.
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* [Documentation](https://symfony.com/doc/current/components/serializer.html)
|
||||
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
||||
* [Report issues](https://github.com/symfony/symfony/issues) and
|
||||
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
||||
in the [main Symfony repository](https://github.com/symfony/symfony)
|
324
vendor/symfony/serializer/Serializer.php
vendored
Normal file
324
vendor/symfony/serializer/Serializer.php
vendored
Normal file
|
@ -0,0 +1,324 @@
|
|||
<?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;
|
||||
|
||||
use Symfony\Component\Serializer\Encoder\ChainDecoder;
|
||||
use Symfony\Component\Serializer\Encoder\ChainEncoder;
|
||||
use Symfony\Component\Serializer\Encoder\DecoderInterface;
|
||||
use Symfony\Component\Serializer\Encoder\EncoderInterface;
|
||||
use Symfony\Component\Serializer\Exception\LogicException;
|
||||
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
|
||||
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
/**
|
||||
* Serializer serializes and deserializes data.
|
||||
*
|
||||
* objects are turned into arrays by normalizers.
|
||||
* arrays are turned into various output formats by encoders.
|
||||
*
|
||||
* $serializer->serialize($obj, 'xml')
|
||||
* $serializer->decode($data, 'xml')
|
||||
* $serializer->denormalize($data, 'Class', 'xml')
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class Serializer implements SerializerInterface, NormalizerInterface, DenormalizerInterface, EncoderInterface, DecoderInterface
|
||||
{
|
||||
/**
|
||||
* @var Encoder\ChainEncoder
|
||||
*/
|
||||
protected $encoder;
|
||||
|
||||
/**
|
||||
* @var Encoder\ChainDecoder
|
||||
*/
|
||||
protected $decoder;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $normalizers = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @deprecated since 3.1 will be removed in 4.0
|
||||
*/
|
||||
protected $normalizerCache = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* @deprecated since 3.1 will be removed in 4.0
|
||||
*/
|
||||
protected $denormalizerCache = array();
|
||||
|
||||
public function __construct(array $normalizers = array(), array $encoders = array())
|
||||
{
|
||||
foreach ($normalizers as $normalizer) {
|
||||
if ($normalizer instanceof SerializerAwareInterface) {
|
||||
$normalizer->setSerializer($this);
|
||||
}
|
||||
|
||||
if ($normalizer instanceof DenormalizerAwareInterface) {
|
||||
$normalizer->setDenormalizer($this);
|
||||
}
|
||||
|
||||
if ($normalizer instanceof NormalizerAwareInterface) {
|
||||
$normalizer->setNormalizer($this);
|
||||
}
|
||||
}
|
||||
$this->normalizers = $normalizers;
|
||||
|
||||
$decoders = array();
|
||||
$realEncoders = array();
|
||||
foreach ($encoders as $encoder) {
|
||||
if ($encoder instanceof SerializerAwareInterface) {
|
||||
$encoder->setSerializer($this);
|
||||
}
|
||||
if ($encoder instanceof DecoderInterface) {
|
||||
$decoders[] = $encoder;
|
||||
}
|
||||
if ($encoder instanceof EncoderInterface) {
|
||||
$realEncoders[] = $encoder;
|
||||
}
|
||||
}
|
||||
$this->encoder = new ChainEncoder($realEncoders);
|
||||
$this->decoder = new ChainDecoder($decoders);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
final public function serialize($data, $format, array $context = array())
|
||||
{
|
||||
if (!$this->supportsEncoding($format, $context)) {
|
||||
throw new NotEncodableValueException(sprintf('Serialization for the format %s is not supported', $format));
|
||||
}
|
||||
|
||||
if ($this->encoder->needsNormalization($format, $context)) {
|
||||
$data = $this->normalize($data, $format, $context);
|
||||
}
|
||||
|
||||
return $this->encode($data, $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
final public function deserialize($data, $type, $format, array $context = array())
|
||||
{
|
||||
if (!$this->supportsDecoding($format, $context)) {
|
||||
throw new NotEncodableValueException(sprintf('Deserialization for the format %s is not supported', $format));
|
||||
}
|
||||
|
||||
$data = $this->decode($data, $format, $context);
|
||||
|
||||
return $this->denormalize($data, $type, $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function normalize($data, $format = null, array $context = array())
|
||||
{
|
||||
// If a normalizer supports the given data, use it
|
||||
if ($normalizer = $this->getNormalizer($data, $format, $context)) {
|
||||
return $normalizer->normalize($data, $format, $context);
|
||||
}
|
||||
|
||||
if (null === $data || is_scalar($data)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
if (\is_array($data) || $data instanceof \Traversable) {
|
||||
$normalized = array();
|
||||
foreach ($data as $key => $val) {
|
||||
$normalized[$key] = $this->normalize($val, $format, $context);
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
if (\is_object($data)) {
|
||||
if (!$this->normalizers) {
|
||||
throw new LogicException('You must register at least one normalizer to be able to normalize objects.');
|
||||
}
|
||||
|
||||
throw new NotNormalizableValueException(sprintf('Could not normalize object of type %s, no supporting normalizer found.', \get_class($data)));
|
||||
}
|
||||
|
||||
throw new NotNormalizableValueException(sprintf('An unexpected value could not be normalized: %s', var_export($data, true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws NotNormalizableValueException
|
||||
*/
|
||||
public function denormalize($data, $type, $format = null, array $context = array())
|
||||
{
|
||||
if (!$this->normalizers) {
|
||||
throw new LogicException('You must register at least one normalizer to be able to denormalize objects.');
|
||||
}
|
||||
|
||||
if ($normalizer = $this->getDenormalizer($data, $type, $format, $context)) {
|
||||
return $normalizer->denormalize($data, $type, $format, $context);
|
||||
}
|
||||
|
||||
throw new NotNormalizableValueException(sprintf('Could not denormalize object of type %s, no supporting normalizer found.', $type));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null/*, array $context = array()*/)
|
||||
{
|
||||
if (\func_num_args() > 2) {
|
||||
$context = \func_get_arg(2);
|
||||
} else {
|
||||
if (__CLASS__ !== \get_class($this)) {
|
||||
$r = new \ReflectionMethod($this, __FUNCTION__);
|
||||
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
|
||||
@trigger_error(sprintf('The "%s()" method will have a third `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
$context = array();
|
||||
}
|
||||
|
||||
return null !== $this->getNormalizer($data, $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null/*, array $context = array()*/)
|
||||
{
|
||||
if (\func_num_args() > 3) {
|
||||
$context = \func_get_arg(3);
|
||||
} else {
|
||||
if (__CLASS__ !== \get_class($this)) {
|
||||
$r = new \ReflectionMethod($this, __FUNCTION__);
|
||||
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
|
||||
@trigger_error(sprintf('The "%s()" method will have a fourth `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
$context = array();
|
||||
}
|
||||
|
||||
return null !== $this->getDenormalizer($data, $type, $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a matching normalizer.
|
||||
*
|
||||
* @param mixed $data Data to get the serializer for
|
||||
* @param string $format Format name, present to give the option to normalizers to act differently based on formats
|
||||
* @param array $context Options available to the normalizer
|
||||
*
|
||||
* @return NormalizerInterface|null
|
||||
*/
|
||||
private function getNormalizer($data, $format, array $context)
|
||||
{
|
||||
foreach ($this->normalizers as $normalizer) {
|
||||
if ($normalizer instanceof NormalizerInterface && $normalizer->supportsNormalization($data, $format, $context)) {
|
||||
return $normalizer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a matching denormalizer.
|
||||
*
|
||||
* @param mixed $data Data to restore
|
||||
* @param string $class The expected class to instantiate
|
||||
* @param string $format Format name, present to give the option to normalizers to act differently based on formats
|
||||
* @param array $context Options available to the denormalizer
|
||||
*
|
||||
* @return DenormalizerInterface|null
|
||||
*/
|
||||
private function getDenormalizer($data, $class, $format, array $context)
|
||||
{
|
||||
foreach ($this->normalizers as $normalizer) {
|
||||
if ($normalizer instanceof DenormalizerInterface && $normalizer->supportsDenormalization($data, $class, $format, $context)) {
|
||||
return $normalizer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
final public function encode($data, $format, array $context = array())
|
||||
{
|
||||
return $this->encoder->encode($data, $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
final public function decode($data, $format, array $context = array())
|
||||
{
|
||||
return $this->decoder->decode($data, $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsEncoding($format/*, array $context = array()*/)
|
||||
{
|
||||
if (\func_num_args() > 1) {
|
||||
$context = \func_get_arg(1);
|
||||
} else {
|
||||
if (__CLASS__ !== \get_class($this)) {
|
||||
$r = new \ReflectionMethod($this, __FUNCTION__);
|
||||
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
|
||||
@trigger_error(sprintf('The "%s()" method will have a second `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
$context = array();
|
||||
}
|
||||
|
||||
return $this->encoder->supportsEncoding($format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDecoding($format/*, array $context = array()*/)
|
||||
{
|
||||
if (\func_num_args() > 1) {
|
||||
$context = \func_get_arg(1);
|
||||
} else {
|
||||
if (__CLASS__ !== \get_class($this)) {
|
||||
$r = new \ReflectionMethod($this, __FUNCTION__);
|
||||
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
|
||||
@trigger_error(sprintf('The "%s()" method will have a second `$context = array()` argument in version 4.0. Not defining it is deprecated since Symfony 3.3.', __METHOD__), E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
$context = array();
|
||||
}
|
||||
|
||||
return $this->decoder->supportsDecoding($format, $context);
|
||||
}
|
||||
}
|
25
vendor/symfony/serializer/SerializerAwareInterface.php
vendored
Normal file
25
vendor/symfony/serializer/SerializerAwareInterface.php
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?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;
|
||||
|
||||
/**
|
||||
* Defines the interface of encoders.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface SerializerAwareInterface
|
||||
{
|
||||
/**
|
||||
* Sets the owning Serializer object.
|
||||
*/
|
||||
public function setSerializer(SerializerInterface $serializer);
|
||||
}
|
35
vendor/symfony/serializer/SerializerAwareTrait.php
vendored
Normal file
35
vendor/symfony/serializer/SerializerAwareTrait.php
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?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;
|
||||
|
||||
/**
|
||||
* SerializerAware trait.
|
||||
*
|
||||
* @author Joel Wurtz <joel.wurtz@gmail.com>
|
||||
*/
|
||||
trait SerializerAwareTrait
|
||||
{
|
||||
/**
|
||||
* @var SerializerInterface
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
/**
|
||||
* Sets the serializer.
|
||||
*
|
||||
* @param SerializerInterface $serializer A SerializerInterface instance
|
||||
*/
|
||||
public function setSerializer(SerializerInterface $serializer)
|
||||
{
|
||||
$this->serializer = $serializer;
|
||||
}
|
||||
}
|
43
vendor/symfony/serializer/SerializerInterface.php
vendored
Normal file
43
vendor/symfony/serializer/SerializerInterface.php
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?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;
|
||||
|
||||
/**
|
||||
* Defines the interface of the Serializer.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface SerializerInterface
|
||||
{
|
||||
/**
|
||||
* Serializes data in the appropriate format.
|
||||
*
|
||||
* @param mixed $data Any data
|
||||
* @param string $format Format name
|
||||
* @param array $context Options normalizers/encoders have access to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize($data, $format, array $context = array());
|
||||
|
||||
/**
|
||||
* Deserializes data into the given type.
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param string $type
|
||||
* @param string $format
|
||||
* @param array $context
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function deserialize($data, $type, $format, array $context = array());
|
||||
}
|
59
vendor/symfony/serializer/Tests/Annotation/GroupsTest.php
vendored
Normal file
59
vendor/symfony/serializer/Tests/Annotation/GroupsTest.php
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?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\Annotation;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class GroupsTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testEmptyGroupsParameter()
|
||||
{
|
||||
new Groups(array('value' => array()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testNotAnArrayGroupsParameter()
|
||||
{
|
||||
new Groups(array('value' => 12));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testInvalidGroupsParameter()
|
||||
{
|
||||
new Groups(array('value' => array('a', 1, new \stdClass())));
|
||||
}
|
||||
|
||||
public function testGroupsParameters()
|
||||
{
|
||||
$validData = array('a', 'b');
|
||||
|
||||
$groups = new Groups(array('value' => $validData));
|
||||
$this->assertEquals($validData, $groups->getGroups());
|
||||
}
|
||||
|
||||
public function testSingleGroup()
|
||||
{
|
||||
$groups = new Groups(array('value' => 'a'));
|
||||
$this->assertEquals(array('a'), $groups->getGroups());
|
||||
}
|
||||
}
|
57
vendor/symfony/serializer/Tests/Annotation/MaxDepthTest.php
vendored
Normal file
57
vendor/symfony/serializer/Tests/Annotation/MaxDepthTest.php
vendored
Normal file
|
@ -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\Annotation;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Annotation\MaxDepth;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class MaxDepthTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage Parameter of annotation "Symfony\Component\Serializer\Annotation\MaxDepth" should be set.
|
||||
*/
|
||||
public function testNotSetMaxDepthParameter()
|
||||
{
|
||||
new MaxDepth(array());
|
||||
}
|
||||
|
||||
public function provideInvalidValues()
|
||||
{
|
||||
return array(
|
||||
array(''),
|
||||
array('foo'),
|
||||
array('1'),
|
||||
array(0),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideInvalidValues
|
||||
*
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage Parameter of annotation "Symfony\Component\Serializer\Annotation\MaxDepth" must be a positive integer.
|
||||
*/
|
||||
public function testNotAnIntMaxDepthParameter($value)
|
||||
{
|
||||
new MaxDepth(array('value' => $value));
|
||||
}
|
||||
|
||||
public function testMaxDepthParameters()
|
||||
{
|
||||
$maxDepth = new MaxDepth(array('value' => 3));
|
||||
$this->assertEquals(3, $maxDepth->getMaxDepth());
|
||||
}
|
||||
}
|
75
vendor/symfony/serializer/Tests/DependencyInjection/SerializerPassTest.php
vendored
Normal file
75
vendor/symfony/serializer/Tests/DependencyInjection/SerializerPassTest.php
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?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\DependencyInjection;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\Serializer\DependencyInjection\SerializerPass;
|
||||
|
||||
/**
|
||||
* Tests for the SerializerPass class.
|
||||
*
|
||||
* @author Javier Lopez <f12loalf@gmail.com>
|
||||
*/
|
||||
class SerializerPassTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedExceptionMessage You must tag at least one service as "serializer.normalizer" to use the "serializer" service
|
||||
*/
|
||||
public function testThrowExceptionWhenNoNormalizers()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('serializer');
|
||||
|
||||
$serializerPass = new SerializerPass();
|
||||
$serializerPass->process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedExceptionMessage You must tag at least one service as "serializer.encoder" to use the "serializer" service
|
||||
*/
|
||||
public function testThrowExceptionWhenNoEncoders()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('serializer')
|
||||
->addArgument(array())
|
||||
->addArgument(array());
|
||||
$container->register('normalizer')->addTag('serializer.normalizer');
|
||||
|
||||
$serializerPass = new SerializerPass();
|
||||
$serializerPass->process($container);
|
||||
}
|
||||
|
||||
public function testServicesAreOrderedAccordingToPriority()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$definition = $container->register('serializer')->setArguments(array(null, null));
|
||||
$container->register('n2')->addTag('serializer.normalizer', array('priority' => 100))->addTag('serializer.encoder', array('priority' => 100));
|
||||
$container->register('n1')->addTag('serializer.normalizer', array('priority' => 200))->addTag('serializer.encoder', array('priority' => 200));
|
||||
$container->register('n3')->addTag('serializer.normalizer')->addTag('serializer.encoder');
|
||||
|
||||
$serializerPass = new SerializerPass();
|
||||
$serializerPass->process($container);
|
||||
|
||||
$expected = array(
|
||||
new Reference('n1'),
|
||||
new Reference('n2'),
|
||||
new Reference('n3'),
|
||||
);
|
||||
$this->assertEquals($expected, $definition->getArgument(0));
|
||||
$this->assertEquals($expected, $definition->getArgument(1));
|
||||
}
|
||||
}
|
80
vendor/symfony/serializer/Tests/Encoder/ChainDecoderTest.php
vendored
Normal file
80
vendor/symfony/serializer/Tests/Encoder/ChainDecoderTest.php
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Encoder\ChainDecoder;
|
||||
|
||||
class ChainDecoderTest extends TestCase
|
||||
{
|
||||
const FORMAT_1 = 'format1';
|
||||
const FORMAT_2 = 'format2';
|
||||
const FORMAT_3 = 'format3';
|
||||
|
||||
private $chainDecoder;
|
||||
private $decoder1;
|
||||
private $decoder2;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->decoder1 = $this
|
||||
->getMockBuilder('Symfony\Component\Serializer\Encoder\DecoderInterface')
|
||||
->getMock();
|
||||
|
||||
$this->decoder1
|
||||
->method('supportsDecoding')
|
||||
->will($this->returnValueMap(array(
|
||||
array(self::FORMAT_1, array(), true),
|
||||
array(self::FORMAT_2, array(), false),
|
||||
array(self::FORMAT_3, array(), false),
|
||||
array(self::FORMAT_3, array('foo' => 'bar'), true),
|
||||
)));
|
||||
|
||||
$this->decoder2 = $this
|
||||
->getMockBuilder('Symfony\Component\Serializer\Encoder\DecoderInterface')
|
||||
->getMock();
|
||||
|
||||
$this->decoder2
|
||||
->method('supportsDecoding')
|
||||
->will($this->returnValueMap(array(
|
||||
array(self::FORMAT_1, array(), false),
|
||||
array(self::FORMAT_2, array(), true),
|
||||
array(self::FORMAT_3, array(), false),
|
||||
)));
|
||||
|
||||
$this->chainDecoder = new ChainDecoder(array($this->decoder1, $this->decoder2));
|
||||
}
|
||||
|
||||
public function testSupportsDecoding()
|
||||
{
|
||||
$this->assertTrue($this->chainDecoder->supportsDecoding(self::FORMAT_1));
|
||||
$this->assertTrue($this->chainDecoder->supportsDecoding(self::FORMAT_2));
|
||||
$this->assertFalse($this->chainDecoder->supportsDecoding(self::FORMAT_3));
|
||||
$this->assertTrue($this->chainDecoder->supportsDecoding(self::FORMAT_3, array('foo' => 'bar')));
|
||||
}
|
||||
|
||||
public function testDecode()
|
||||
{
|
||||
$this->decoder1->expects($this->never())->method('decode');
|
||||
$this->decoder2->expects($this->once())->method('decode');
|
||||
|
||||
$this->chainDecoder->decode('string_to_decode', self::FORMAT_2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\RuntimeException
|
||||
*/
|
||||
public function testDecodeUnsupportedFormat()
|
||||
{
|
||||
$this->chainDecoder->decode('string_to_decode', self::FORMAT_3);
|
||||
}
|
||||
}
|
137
vendor/symfony/serializer/Tests/Encoder/ChainEncoderTest.php
vendored
Normal file
137
vendor/symfony/serializer/Tests/Encoder/ChainEncoderTest.php
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Encoder\ChainEncoder;
|
||||
use Symfony\Component\Serializer\Encoder\EncoderInterface;
|
||||
use Symfony\Component\Serializer\Encoder\NormalizationAwareInterface;
|
||||
|
||||
class ChainEncoderTest extends TestCase
|
||||
{
|
||||
const FORMAT_1 = 'format1';
|
||||
const FORMAT_2 = 'format2';
|
||||
const FORMAT_3 = 'format3';
|
||||
|
||||
private $chainEncoder;
|
||||
private $encoder1;
|
||||
private $encoder2;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->encoder1 = $this
|
||||
->getMockBuilder('Symfony\Component\Serializer\Encoder\EncoderInterface')
|
||||
->getMock();
|
||||
|
||||
$this->encoder1
|
||||
->method('supportsEncoding')
|
||||
->will($this->returnValueMap(array(
|
||||
array(self::FORMAT_1, array(), true),
|
||||
array(self::FORMAT_2, array(), false),
|
||||
array(self::FORMAT_3, array(), false),
|
||||
array(self::FORMAT_3, array('foo' => 'bar'), true),
|
||||
)));
|
||||
|
||||
$this->encoder2 = $this
|
||||
->getMockBuilder('Symfony\Component\Serializer\Encoder\EncoderInterface')
|
||||
->getMock();
|
||||
|
||||
$this->encoder2
|
||||
->method('supportsEncoding')
|
||||
->will($this->returnValueMap(array(
|
||||
array(self::FORMAT_1, array(), false),
|
||||
array(self::FORMAT_2, array(), true),
|
||||
array(self::FORMAT_3, array(), false),
|
||||
)));
|
||||
|
||||
$this->chainEncoder = new ChainEncoder(array($this->encoder1, $this->encoder2));
|
||||
}
|
||||
|
||||
public function testSupportsEncoding()
|
||||
{
|
||||
$this->assertTrue($this->chainEncoder->supportsEncoding(self::FORMAT_1));
|
||||
$this->assertTrue($this->chainEncoder->supportsEncoding(self::FORMAT_2));
|
||||
$this->assertFalse($this->chainEncoder->supportsEncoding(self::FORMAT_3));
|
||||
$this->assertTrue($this->chainEncoder->supportsEncoding(self::FORMAT_3, array('foo' => 'bar')));
|
||||
}
|
||||
|
||||
public function testEncode()
|
||||
{
|
||||
$this->encoder1->expects($this->never())->method('encode');
|
||||
$this->encoder2->expects($this->once())->method('encode');
|
||||
|
||||
$this->chainEncoder->encode(array('foo' => 123), self::FORMAT_2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\RuntimeException
|
||||
*/
|
||||
public function testEncodeUnsupportedFormat()
|
||||
{
|
||||
$this->chainEncoder->encode(array('foo' => 123), self::FORMAT_3);
|
||||
}
|
||||
|
||||
public function testNeedsNormalizationBasic()
|
||||
{
|
||||
$this->assertTrue($this->chainEncoder->needsNormalization(self::FORMAT_1));
|
||||
$this->assertTrue($this->chainEncoder->needsNormalization(self::FORMAT_2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider booleanProvider
|
||||
*/
|
||||
public function testNeedsNormalizationChainNormalizationAware($bool)
|
||||
{
|
||||
$chainEncoder = $this
|
||||
->getMockBuilder('Symfony\Component\Serializer\Tests\Encoder\ChainNormalizationAwareEncoder')
|
||||
->getMock();
|
||||
|
||||
$chainEncoder->method('supportsEncoding')->willReturn(true);
|
||||
$chainEncoder->method('needsNormalization')->willReturn($bool);
|
||||
|
||||
$sut = new ChainEncoder(array($chainEncoder));
|
||||
|
||||
$this->assertEquals($bool, $sut->needsNormalization(self::FORMAT_1));
|
||||
}
|
||||
|
||||
public function testNeedsNormalizationNormalizationAware()
|
||||
{
|
||||
$encoder = new NormalizationAwareEncoder();
|
||||
$sut = new ChainEncoder(array($encoder));
|
||||
|
||||
$this->assertFalse($sut->needsNormalization(self::FORMAT_1));
|
||||
}
|
||||
|
||||
public function booleanProvider()
|
||||
{
|
||||
return array(
|
||||
array(true),
|
||||
array(false),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChainNormalizationAwareEncoder extends ChainEncoder implements NormalizationAwareInterface
|
||||
{
|
||||
}
|
||||
|
||||
class NormalizationAwareEncoder implements EncoderInterface, NormalizationAwareInterface
|
||||
{
|
||||
public function supportsEncoding($format)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function encode($data, $format, array $context = array())
|
||||
{
|
||||
}
|
||||
}
|
294
vendor/symfony/serializer/Tests/Encoder/CsvEncoderTest.php
vendored
Normal file
294
vendor/symfony/serializer/Tests/Encoder/CsvEncoderTest.php
vendored
Normal file
|
@ -0,0 +1,294 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Encoder\CsvEncoder;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class CsvEncoderTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var CsvEncoder
|
||||
*/
|
||||
private $encoder;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->encoder = new CsvEncoder();
|
||||
}
|
||||
|
||||
public function testSupportEncoding()
|
||||
{
|
||||
$this->assertTrue($this->encoder->supportsEncoding('csv'));
|
||||
$this->assertFalse($this->encoder->supportsEncoding('foo'));
|
||||
}
|
||||
|
||||
public function testEncode()
|
||||
{
|
||||
$value = array('foo' => 'hello', 'bar' => 'hey ho');
|
||||
|
||||
$this->assertEquals(<<<'CSV'
|
||||
foo,bar
|
||||
hello,"hey ho"
|
||||
|
||||
CSV
|
||||
, $this->encoder->encode($value, 'csv'));
|
||||
}
|
||||
|
||||
public function testEncodeCollection()
|
||||
{
|
||||
$value = array(
|
||||
array('foo' => 'hello', 'bar' => 'hey ho'),
|
||||
array('foo' => 'hi', 'bar' => 'let\'s go'),
|
||||
);
|
||||
|
||||
$this->assertEquals(<<<'CSV'
|
||||
foo,bar
|
||||
hello,"hey ho"
|
||||
hi,"let's go"
|
||||
|
||||
CSV
|
||||
, $this->encoder->encode($value, 'csv'));
|
||||
}
|
||||
|
||||
public function testEncodePlainIndexedArray()
|
||||
{
|
||||
$this->assertEquals(<<<'CSV'
|
||||
0,1,2
|
||||
a,b,c
|
||||
|
||||
CSV
|
||||
, $this->encoder->encode(array('a', 'b', 'c'), 'csv'));
|
||||
}
|
||||
|
||||
public function testEncodeNonArray()
|
||||
{
|
||||
$this->assertEquals(<<<'CSV'
|
||||
0
|
||||
foo
|
||||
|
||||
CSV
|
||||
, $this->encoder->encode('foo', 'csv'));
|
||||
}
|
||||
|
||||
public function testEncodeNestedArrays()
|
||||
{
|
||||
$value = array('foo' => 'hello', 'bar' => array(
|
||||
array('id' => 'yo', 1 => 'wesh'),
|
||||
array('baz' => 'Halo', 'foo' => 'olá'),
|
||||
));
|
||||
|
||||
$this->assertEquals(<<<'CSV'
|
||||
foo,bar.0.id,bar.0.1,bar.1.baz,bar.1.foo
|
||||
hello,yo,wesh,Halo,olá
|
||||
|
||||
CSV
|
||||
, $this->encoder->encode($value, 'csv'));
|
||||
}
|
||||
|
||||
public function testEncodeCustomSettings()
|
||||
{
|
||||
$this->encoder = new CsvEncoder(';', "'", '|', '-');
|
||||
|
||||
$value = array('a' => 'he\'llo', 'c' => array('d' => 'foo'));
|
||||
|
||||
$this->assertEquals(<<<'CSV'
|
||||
a;c-d
|
||||
'he''llo';foo
|
||||
|
||||
CSV
|
||||
, $this->encoder->encode($value, 'csv'));
|
||||
}
|
||||
|
||||
public function testEncodeCustomSettingsPassedInContext()
|
||||
{
|
||||
$value = array('a' => 'he\'llo', 'c' => array('d' => 'foo'));
|
||||
|
||||
$this->assertSame(<<<'CSV'
|
||||
a;c-d
|
||||
'he''llo';foo
|
||||
|
||||
CSV
|
||||
, $this->encoder->encode($value, 'csv', array(
|
||||
CsvEncoder::DELIMITER_KEY => ';',
|
||||
CsvEncoder::ENCLOSURE_KEY => "'",
|
||||
CsvEncoder::ESCAPE_CHAR_KEY => '|',
|
||||
CsvEncoder::KEY_SEPARATOR_KEY => '-',
|
||||
)));
|
||||
}
|
||||
|
||||
public function testEncodeEmptyArray()
|
||||
{
|
||||
$this->assertEquals("\n\n", $this->encoder->encode(array(), 'csv'));
|
||||
$this->assertEquals("\n\n", $this->encoder->encode(array(array()), 'csv'));
|
||||
}
|
||||
|
||||
public function testEncodeVariableStructure()
|
||||
{
|
||||
$value = array(
|
||||
array('a' => array('foo', 'bar')),
|
||||
array('a' => array(), 'b' => 'baz'),
|
||||
array('a' => array('bar', 'foo'), 'c' => 'pong'),
|
||||
);
|
||||
$csv = <<<CSV
|
||||
a.0,a.1,c,b
|
||||
foo,bar,,
|
||||
,,,baz
|
||||
bar,foo,pong,
|
||||
|
||||
CSV;
|
||||
|
||||
$this->assertEquals($csv, $this->encoder->encode($value, 'csv'));
|
||||
}
|
||||
|
||||
public function testEncodeCustomHeaders()
|
||||
{
|
||||
$context = array(
|
||||
CsvEncoder::HEADERS_KEY => array(
|
||||
'b',
|
||||
'c',
|
||||
),
|
||||
);
|
||||
$value = array(
|
||||
array('a' => 'foo', 'b' => 'bar'),
|
||||
);
|
||||
$csv = <<<CSV
|
||||
b,c,a
|
||||
bar,,foo
|
||||
|
||||
CSV;
|
||||
|
||||
$this->assertEquals($csv, $this->encoder->encode($value, 'csv', $context));
|
||||
}
|
||||
|
||||
public function testSupportsDecoding()
|
||||
{
|
||||
$this->assertTrue($this->encoder->supportsDecoding('csv'));
|
||||
$this->assertFalse($this->encoder->supportsDecoding('foo'));
|
||||
}
|
||||
|
||||
public function testDecode()
|
||||
{
|
||||
$expected = array('foo' => 'a', 'bar' => 'b');
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode(<<<'CSV'
|
||||
foo,bar
|
||||
a,b
|
||||
CSV
|
||||
, 'csv'));
|
||||
}
|
||||
|
||||
public function testDecodeCollection()
|
||||
{
|
||||
$expected = array(
|
||||
array('foo' => 'a', 'bar' => 'b'),
|
||||
array('foo' => 'c', 'bar' => 'd'),
|
||||
array('foo' => 'f'),
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode(<<<'CSV'
|
||||
foo,bar
|
||||
a,b
|
||||
c,d
|
||||
f
|
||||
|
||||
CSV
|
||||
, 'csv'));
|
||||
}
|
||||
|
||||
public function testDecodeToManyRelation()
|
||||
{
|
||||
$expected = array(
|
||||
array('foo' => 'bar', 'relations' => array(array('a' => 'b'), array('a' => 'b'))),
|
||||
array('foo' => 'bat', 'relations' => array(array('a' => 'b'), array('a' => ''))),
|
||||
array('foo' => 'bat', 'relations' => array(array('a' => 'b'))),
|
||||
array('foo' => 'baz', 'relations' => array(array('a' => 'c'), array('a' => 'c'))),
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode(<<<'CSV'
|
||||
foo,relations.0.a,relations.1.a
|
||||
bar,b,b
|
||||
bat,b,
|
||||
bat,b
|
||||
baz,c,c
|
||||
CSV
|
||||
, 'csv'));
|
||||
}
|
||||
|
||||
public function testDecodeNestedArrays()
|
||||
{
|
||||
$expected = array(
|
||||
array('foo' => 'a', 'bar' => array('baz' => array('bat' => 'b'))),
|
||||
array('foo' => 'c', 'bar' => array('baz' => array('bat' => 'd'))),
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode(<<<'CSV'
|
||||
foo,bar.baz.bat
|
||||
a,b
|
||||
c,d
|
||||
CSV
|
||||
, 'csv'));
|
||||
}
|
||||
|
||||
public function testDecodeCustomSettings()
|
||||
{
|
||||
$this->encoder = new CsvEncoder(';', "'", '|', '-');
|
||||
|
||||
$expected = array('a' => 'hell\'o', 'bar' => array('baz' => 'b'));
|
||||
$this->assertEquals($expected, $this->encoder->decode(<<<'CSV'
|
||||
a;bar-baz
|
||||
'hell''o';b;c
|
||||
CSV
|
||||
, 'csv'));
|
||||
}
|
||||
|
||||
public function testDecodeCustomSettingsPassedInContext()
|
||||
{
|
||||
$expected = array('a' => 'hell\'o', 'bar' => array('baz' => 'b'));
|
||||
$this->assertEquals($expected, $this->encoder->decode(<<<'CSV'
|
||||
a;bar-baz
|
||||
'hell''o';b;c
|
||||
CSV
|
||||
, 'csv', array(
|
||||
CsvEncoder::DELIMITER_KEY => ';',
|
||||
CsvEncoder::ENCLOSURE_KEY => "'",
|
||||
CsvEncoder::ESCAPE_CHAR_KEY => '|',
|
||||
CsvEncoder::KEY_SEPARATOR_KEY => '-',
|
||||
)));
|
||||
}
|
||||
|
||||
public function testDecodeMalformedCollection()
|
||||
{
|
||||
$expected = array(
|
||||
array('foo' => 'a', 'bar' => 'b'),
|
||||
array('foo' => 'c', 'bar' => 'd'),
|
||||
array('foo' => 'f'),
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode(<<<'CSV'
|
||||
foo,bar
|
||||
a,b,e
|
||||
c,d,g,h
|
||||
f
|
||||
|
||||
CSV
|
||||
, 'csv'));
|
||||
}
|
||||
|
||||
public function testDecodeEmptyArray()
|
||||
{
|
||||
$this->assertEquals(array(), $this->encoder->decode('', 'csv'));
|
||||
}
|
||||
}
|
75
vendor/symfony/serializer/Tests/Encoder/JsonDecodeTest.php
vendored
Normal file
75
vendor/symfony/serializer/Tests/Encoder/JsonDecodeTest.php
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Encoder\JsonDecode;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||
|
||||
class JsonDecodeTest extends TestCase
|
||||
{
|
||||
/** @var \Symfony\Component\Serializer\Encoder\JsonDecode */
|
||||
private $decode;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->decode = new JsonDecode();
|
||||
}
|
||||
|
||||
public function testSupportsDecoding()
|
||||
{
|
||||
$this->assertTrue($this->decode->supportsDecoding(JsonEncoder::FORMAT));
|
||||
$this->assertFalse($this->decode->supportsDecoding('foobar'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider decodeProvider
|
||||
*/
|
||||
public function testDecode($toDecode, $expected, $context)
|
||||
{
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
$this->decode->decode($toDecode, JsonEncoder::FORMAT, $context)
|
||||
);
|
||||
}
|
||||
|
||||
public function decodeProvider()
|
||||
{
|
||||
$stdClass = new \stdClass();
|
||||
$stdClass->foo = 'bar';
|
||||
|
||||
$assoc = array('foo' => 'bar');
|
||||
|
||||
return array(
|
||||
array('{"foo": "bar"}', $stdClass, array()),
|
||||
array('{"foo": "bar"}', $assoc, array('json_decode_associative' => true)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires function json_last_error_msg
|
||||
* @dataProvider decodeProviderException
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
|
||||
*/
|
||||
public function testDecodeWithException($value)
|
||||
{
|
||||
$this->decode->decode($value, JsonEncoder::FORMAT);
|
||||
}
|
||||
|
||||
public function decodeProviderException()
|
||||
{
|
||||
return array(
|
||||
array("{'foo': 'bar'}"),
|
||||
array('kaboom!'),
|
||||
);
|
||||
}
|
||||
}
|
60
vendor/symfony/serializer/Tests/Encoder/JsonEncodeTest.php
vendored
Normal file
60
vendor/symfony/serializer/Tests/Encoder/JsonEncodeTest.php
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncode;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||
|
||||
class JsonEncodeTest extends TestCase
|
||||
{
|
||||
private $encoder;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->encode = new JsonEncode();
|
||||
}
|
||||
|
||||
public function testSupportsEncoding()
|
||||
{
|
||||
$this->assertTrue($this->encode->supportsEncoding(JsonEncoder::FORMAT));
|
||||
$this->assertFalse($this->encode->supportsEncoding('foobar'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider encodeProvider
|
||||
*/
|
||||
public function testEncode($toEncode, $expected, $context)
|
||||
{
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
$this->encode->encode($toEncode, JsonEncoder::FORMAT, $context)
|
||||
);
|
||||
}
|
||||
|
||||
public function encodeProvider()
|
||||
{
|
||||
return array(
|
||||
array(array(), '[]', array()),
|
||||
array(array(), '{}', array('json_encode_options' => JSON_FORCE_OBJECT)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires function json_last_error_msg
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
|
||||
*/
|
||||
public function testEncodeWithError()
|
||||
{
|
||||
$this->encode->encode("\xB1\x31", JsonEncoder::FORMAT);
|
||||
}
|
||||
}
|
121
vendor/symfony/serializer/Tests/Encoder/JsonEncoderTest.php
vendored
Normal file
121
vendor/symfony/serializer/Tests/Encoder/JsonEncoderTest.php
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
|
||||
use Symfony\Component\Serializer\Serializer;
|
||||
|
||||
class JsonEncoderTest extends TestCase
|
||||
{
|
||||
private $encoder;
|
||||
private $serializer;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->encoder = new JsonEncoder();
|
||||
$this->serializer = new Serializer(array(new CustomNormalizer()), array('json' => new JsonEncoder()));
|
||||
}
|
||||
|
||||
public function testEncodeScalar()
|
||||
{
|
||||
$obj = new \stdClass();
|
||||
$obj->foo = 'foo';
|
||||
|
||||
$expected = '{"foo":"foo"}';
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->encode($obj, 'json'));
|
||||
}
|
||||
|
||||
public function testComplexObject()
|
||||
{
|
||||
$obj = $this->getObject();
|
||||
|
||||
$expected = $this->getJsonSource();
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->encode($obj, 'json'));
|
||||
}
|
||||
|
||||
public function testOptions()
|
||||
{
|
||||
$context = array('json_encode_options' => JSON_NUMERIC_CHECK);
|
||||
|
||||
$arr = array();
|
||||
$arr['foo'] = '3';
|
||||
|
||||
$expected = '{"foo":3}';
|
||||
|
||||
$this->assertEquals($expected, $this->serializer->serialize($arr, 'json', $context));
|
||||
|
||||
$arr = array();
|
||||
$arr['foo'] = '3';
|
||||
|
||||
$expected = '{"foo":"3"}';
|
||||
|
||||
$this->assertEquals($expected, $this->serializer->serialize($arr, 'json'), 'Context should not be persistent');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
|
||||
*/
|
||||
public function testEncodeNotUtf8WithoutPartialOnError()
|
||||
{
|
||||
$arr = array(
|
||||
'utf8' => 'Hello World!',
|
||||
'notUtf8' => "\xb0\xd0\xb5\xd0",
|
||||
);
|
||||
|
||||
$this->encoder->encode($arr, 'json');
|
||||
}
|
||||
|
||||
public function testEncodeNotUtf8WithPartialOnError()
|
||||
{
|
||||
$context = array('json_encode_options' => JSON_PARTIAL_OUTPUT_ON_ERROR);
|
||||
|
||||
$arr = array(
|
||||
'utf8' => 'Hello World!',
|
||||
'notUtf8' => "\xb0\xd0\xb5\xd0",
|
||||
);
|
||||
|
||||
$result = $this->encoder->encode($arr, 'json', $context);
|
||||
$jsonLastError = json_last_error();
|
||||
|
||||
$this->assertSame(JSON_ERROR_UTF8, $jsonLastError);
|
||||
$this->assertEquals('{"utf8":"Hello World!","notUtf8":null}', $result);
|
||||
|
||||
$this->assertEquals('0', $this->serializer->serialize(NAN, 'json', $context));
|
||||
}
|
||||
|
||||
public function testDecodeFalseString()
|
||||
{
|
||||
$result = $this->encoder->decode('false', 'json');
|
||||
$this->assertSame(JSON_ERROR_NONE, json_last_error());
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
protected function getJsonSource()
|
||||
{
|
||||
return '{"foo":"foo","bar":["a","b"],"baz":{"key":"val","key2":"val","A B":"bar","item":[{"title":"title1"},{"title":"title2"}],"Barry":{"FooBar":{"Baz":"Ed","@id":1}}},"qux":"1"}';
|
||||
}
|
||||
|
||||
protected function getObject()
|
||||
{
|
||||
$obj = new \stdClass();
|
||||
$obj->foo = 'foo';
|
||||
$obj->bar = array('a', 'b');
|
||||
$obj->baz = array('key' => 'val', 'key2' => 'val', 'A B' => 'bar', 'item' => array(array('title' => 'title1'), array('title' => 'title2')), 'Barry' => array('FooBar' => array('Baz' => 'Ed', '@id' => 1)));
|
||||
$obj->qux = '1';
|
||||
|
||||
return $obj;
|
||||
}
|
||||
}
|
733
vendor/symfony/serializer/Tests/Encoder/XmlEncoderTest.php
vendored
Normal file
733
vendor/symfony/serializer/Tests/Encoder/XmlEncoderTest.php
vendored
Normal file
|
@ -0,0 +1,733 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Encoder\XmlEncoder;
|
||||
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Symfony\Component\Serializer\Serializer;
|
||||
use Symfony\Component\Serializer\Tests\Fixtures\Dummy;
|
||||
use Symfony\Component\Serializer\Tests\Fixtures\NormalizableTraversableDummy;
|
||||
use Symfony\Component\Serializer\Tests\Fixtures\ScalarDummy;
|
||||
|
||||
class XmlEncoderTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var XmlEncoder
|
||||
*/
|
||||
private $encoder;
|
||||
|
||||
private $exampleDateTimeString = '2017-02-19T15:16:08+0300';
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->encoder = new XmlEncoder();
|
||||
$serializer = new Serializer(array(new CustomNormalizer()), array('xml' => new XmlEncoder()));
|
||||
$this->encoder->setSerializer($serializer);
|
||||
}
|
||||
|
||||
public function testEncodeScalar()
|
||||
{
|
||||
$obj = new ScalarDummy();
|
||||
$obj->xmlFoo = 'foo';
|
||||
|
||||
$expected = '<?xml version="1.0"?>'."\n".
|
||||
'<response>foo</response>'."\n";
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->encode($obj, 'xml'));
|
||||
}
|
||||
|
||||
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 testDocTypeIsNotAllowed()
|
||||
{
|
||||
$this->encoder->decode('<?xml version="1.0"?><!DOCTYPE foo><foo></foo>', 'foo');
|
||||
}
|
||||
|
||||
public function testAttributes()
|
||||
{
|
||||
$obj = new ScalarDummy();
|
||||
$obj->xmlFoo = array(
|
||||
'foo-bar' => array(
|
||||
'@id' => 1,
|
||||
'@name' => 'Bar',
|
||||
),
|
||||
'Foo' => array(
|
||||
'Bar' => 'Test',
|
||||
'@Type' => 'test',
|
||||
),
|
||||
'föo_bär' => 'a',
|
||||
'Bar' => array(1, 2, 3),
|
||||
'a' => 'b',
|
||||
);
|
||||
$expected = '<?xml version="1.0"?>'."\n".
|
||||
'<response>'.
|
||||
'<foo-bar id="1" name="Bar"/>'.
|
||||
'<Foo Type="test"><Bar>Test</Bar></Foo>'.
|
||||
'<föo_bär>a</föo_bär>'.
|
||||
'<Bar>1</Bar>'.
|
||||
'<Bar>2</Bar>'.
|
||||
'<Bar>3</Bar>'.
|
||||
'<a>b</a>'.
|
||||
'</response>'."\n";
|
||||
$this->assertEquals($expected, $this->encoder->encode($obj, 'xml'));
|
||||
}
|
||||
|
||||
public function testElementNameValid()
|
||||
{
|
||||
$obj = new ScalarDummy();
|
||||
$obj->xmlFoo = array(
|
||||
'foo-bar' => 'a',
|
||||
'foo_bar' => 'a',
|
||||
'föo_bär' => 'a',
|
||||
);
|
||||
|
||||
$expected = '<?xml version="1.0"?>'."\n".
|
||||
'<response>'.
|
||||
'<foo-bar>a</foo-bar>'.
|
||||
'<foo_bar>a</foo_bar>'.
|
||||
'<föo_bär>a</föo_bär>'.
|
||||
'</response>'."\n";
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->encode($obj, 'xml'));
|
||||
}
|
||||
|
||||
public function testEncodeSimpleXML()
|
||||
{
|
||||
$xml = simplexml_load_string('<firstname>Peter</firstname>');
|
||||
$array = array('person' => $xml);
|
||||
|
||||
$expected = '<?xml version="1.0"?>'."\n".
|
||||
'<response><person><firstname>Peter</firstname></person></response>'."\n";
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
|
||||
}
|
||||
|
||||
public function testEncodeXmlAttributes()
|
||||
{
|
||||
$xml = simplexml_load_string('<firstname>Peter</firstname>');
|
||||
$array = array('person' => $xml);
|
||||
|
||||
$expected = '<?xml version="1.1" encoding="utf-8" standalone="yes"?>'."\n".
|
||||
'<response><person><firstname>Peter</firstname></person></response>'."\n";
|
||||
|
||||
$context = array(
|
||||
'xml_version' => '1.1',
|
||||
'xml_encoding' => 'utf-8',
|
||||
'xml_standalone' => true,
|
||||
);
|
||||
|
||||
$this->assertSame($expected, $this->encoder->encode($array, 'xml', $context));
|
||||
}
|
||||
|
||||
public function testEncodeRemovingEmptyTags()
|
||||
{
|
||||
$array = array('person' => array('firstname' => 'Peter', 'lastname' => null));
|
||||
|
||||
$expected = '<?xml version="1.0"?>'."\n".
|
||||
'<response><person><firstname>Peter</firstname></person></response>'."\n";
|
||||
|
||||
$context = array('remove_empty_tags' => true);
|
||||
|
||||
$this->assertSame($expected, $this->encoder->encode($array, 'xml', $context));
|
||||
}
|
||||
|
||||
public function testEncodeNotRemovingEmptyTags()
|
||||
{
|
||||
$array = array('person' => array('firstname' => 'Peter', 'lastname' => null));
|
||||
|
||||
$expected = '<?xml version="1.0"?>'."\n".
|
||||
'<response><person><firstname>Peter</firstname><lastname/></person></response>'."\n";
|
||||
|
||||
$this->assertSame($expected, $this->encoder->encode($array, 'xml'));
|
||||
}
|
||||
|
||||
public function testContext()
|
||||
{
|
||||
$array = array('person' => array('name' => 'George Abitbol'));
|
||||
$expected = <<<'XML'
|
||||
<?xml version="1.0"?>
|
||||
<response>
|
||||
<person>
|
||||
<name>George Abitbol</name>
|
||||
</person>
|
||||
</response>
|
||||
|
||||
XML;
|
||||
|
||||
$context = array(
|
||||
'xml_format_output' => true,
|
||||
);
|
||||
|
||||
$this->assertSame($expected, $this->encoder->encode($array, 'xml', $context));
|
||||
}
|
||||
|
||||
public function testEncodeScalarRootAttributes()
|
||||
{
|
||||
$array = array(
|
||||
'#' => 'Paul',
|
||||
'@gender' => 'm',
|
||||
);
|
||||
|
||||
$expected = '<?xml version="1.0"?>'."\n".
|
||||
'<response gender="m">Paul</response>'."\n";
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
|
||||
}
|
||||
|
||||
public function testEncodeRootAttributes()
|
||||
{
|
||||
$array = array(
|
||||
'firstname' => 'Paul',
|
||||
'@gender' => 'm',
|
||||
);
|
||||
|
||||
$expected = '<?xml version="1.0"?>'."\n".
|
||||
'<response gender="m"><firstname>Paul</firstname></response>'."\n";
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
|
||||
}
|
||||
|
||||
public function testEncodeCdataWrapping()
|
||||
{
|
||||
$array = array(
|
||||
'firstname' => 'Paul <or Me>',
|
||||
);
|
||||
|
||||
$expected = '<?xml version="1.0"?>'."\n".
|
||||
'<response><firstname><![CDATA[Paul <or Me>]]></firstname></response>'."\n";
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
|
||||
}
|
||||
|
||||
public function testEncodeScalarWithAttribute()
|
||||
{
|
||||
$array = array(
|
||||
'person' => array('@gender' => 'M', '#' => 'Peter'),
|
||||
);
|
||||
|
||||
$expected = '<?xml version="1.0"?>'."\n".
|
||||
'<response><person gender="M">Peter</person></response>'."\n";
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeScalar()
|
||||
{
|
||||
$source = '<?xml version="1.0"?>'."\n".
|
||||
'<response>foo</response>'."\n";
|
||||
|
||||
$this->assertEquals('foo', $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeBigDigitAttributes()
|
||||
{
|
||||
$source = <<<XML
|
||||
<?xml version="1.0"?>
|
||||
<document index="182077241760011681341821060401202210011000045913000000017100">Name</document>
|
||||
XML;
|
||||
|
||||
$this->assertSame(array('@index' => 182077241760011681341821060401202210011000045913000000017100, '#' => 'Name'), $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeNegativeIntAttribute()
|
||||
{
|
||||
$source = <<<XML
|
||||
<?xml version="1.0"?>
|
||||
<document index="-1234">Name</document>
|
||||
XML;
|
||||
|
||||
$this->assertSame(array('@index' => -1234, '#' => 'Name'), $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeFloatAttribute()
|
||||
{
|
||||
$source = <<<XML
|
||||
<?xml version="1.0"?>
|
||||
<document index="-12.11">Name</document>
|
||||
XML;
|
||||
|
||||
$this->assertSame(array('@index' => -12.11, '#' => 'Name'), $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeNegativeFloatAttribute()
|
||||
{
|
||||
$source = <<<XML
|
||||
<?xml version="1.0"?>
|
||||
<document index="-12.11">Name</document>
|
||||
XML;
|
||||
|
||||
$this->assertSame(array('@index' => -12.11, '#' => 'Name'), $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testNoTypeCastAttribute()
|
||||
{
|
||||
$source = <<<XML
|
||||
<?xml version="1.0"?>
|
||||
<document a="018" b="-12.11">
|
||||
<node a="018" b="-12.11"/>
|
||||
</document>
|
||||
XML;
|
||||
|
||||
$data = $this->encoder->decode($source, 'xml', array('xml_type_cast_attributes' => false));
|
||||
$expected = array(
|
||||
'@a' => '018',
|
||||
'@b' => '-12.11',
|
||||
'node' => array(
|
||||
'@a' => '018',
|
||||
'@b' => '-12.11',
|
||||
'#' => '',
|
||||
),
|
||||
);
|
||||
$this->assertSame($expected, $data);
|
||||
}
|
||||
|
||||
public function testEncode()
|
||||
{
|
||||
$source = $this->getXmlSource();
|
||||
$obj = $this->getObject();
|
||||
|
||||
$this->assertEquals($source, $this->encoder->encode($obj, 'xml'));
|
||||
}
|
||||
|
||||
public function testEncodeWithNamespace()
|
||||
{
|
||||
$source = $this->getNamespacedXmlSource();
|
||||
$array = $this->getNamespacedArray();
|
||||
|
||||
$this->assertEquals($source, $this->encoder->encode($array, 'xml'));
|
||||
}
|
||||
|
||||
public function testEncodeSerializerXmlRootNodeNameOption()
|
||||
{
|
||||
$options = array('xml_root_node_name' => 'test');
|
||||
$this->encoder = new XmlEncoder();
|
||||
$serializer = new Serializer(array(), array('xml' => new XmlEncoder()));
|
||||
$this->encoder->setSerializer($serializer);
|
||||
|
||||
$array = array(
|
||||
'person' => array('@gender' => 'M', '#' => 'Peter'),
|
||||
);
|
||||
|
||||
$expected = '<?xml version="1.0"?>'."\n".
|
||||
'<test><person gender="M">Peter</person></test>'."\n";
|
||||
|
||||
$this->assertEquals($expected, $serializer->serialize($array, 'xml', $options));
|
||||
}
|
||||
|
||||
public function testEncodeTraversableWhenNormalizable()
|
||||
{
|
||||
$this->encoder = new XmlEncoder();
|
||||
$serializer = new Serializer(array(new CustomNormalizer()), array('xml' => new XmlEncoder()));
|
||||
$this->encoder->setSerializer($serializer);
|
||||
|
||||
$expected = <<<'XML'
|
||||
<?xml version="1.0"?>
|
||||
<response><foo>normalizedFoo</foo><bar>normalizedBar</bar></response>
|
||||
|
||||
XML;
|
||||
|
||||
$this->assertEquals($expected, $serializer->serialize(new NormalizableTraversableDummy(), 'xml'));
|
||||
}
|
||||
|
||||
public function testDecode()
|
||||
{
|
||||
$source = $this->getXmlSource();
|
||||
$obj = $this->getObject();
|
||||
|
||||
$this->assertEquals(get_object_vars($obj), $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeCdataWrapping()
|
||||
{
|
||||
$expected = array(
|
||||
'firstname' => 'Paul <or Me>',
|
||||
);
|
||||
|
||||
$xml = '<?xml version="1.0"?>'."\n".
|
||||
'<response><firstname><![CDATA[Paul <or Me>]]></firstname></response>'."\n";
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode($xml, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeCdataWrappingAndWhitespace()
|
||||
{
|
||||
$expected = array(
|
||||
'firstname' => 'Paul <or Me>',
|
||||
);
|
||||
|
||||
$xml = '<?xml version="1.0"?>'."\n".
|
||||
'<response><firstname>'."\n".
|
||||
'<![CDATA[Paul <or Me>]]></firstname></response>'."\n";
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode($xml, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeWithNamespace()
|
||||
{
|
||||
$source = $this->getNamespacedXmlSource();
|
||||
$array = $this->getNamespacedArray();
|
||||
|
||||
$this->assertEquals($array, $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeScalarWithAttribute()
|
||||
{
|
||||
$source = '<?xml version="1.0"?>'."\n".
|
||||
'<response><person gender="M">Peter</person></response>'."\n";
|
||||
|
||||
$expected = array(
|
||||
'person' => array('@gender' => 'M', '#' => 'Peter'),
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeScalarRootAttributes()
|
||||
{
|
||||
$source = '<?xml version="1.0"?>'."\n".
|
||||
'<person gender="M">Peter</person>'."\n";
|
||||
|
||||
$expected = array(
|
||||
'#' => 'Peter',
|
||||
'@gender' => 'M',
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeRootAttributes()
|
||||
{
|
||||
$source = '<?xml version="1.0"?>'."\n".
|
||||
'<person gender="M"><firstname>Peter</firstname><lastname>Mac Calloway</lastname></person>'."\n";
|
||||
|
||||
$expected = array(
|
||||
'firstname' => 'Peter',
|
||||
'lastname' => 'Mac Calloway',
|
||||
'@gender' => 'M',
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeArray()
|
||||
{
|
||||
$source = '<?xml version="1.0"?>'."\n".
|
||||
'<response>'.
|
||||
'<people>'.
|
||||
'<person><firstname>Benjamin</firstname><lastname>Alexandre</lastname></person>'.
|
||||
'<person><firstname>Damien</firstname><lastname>Clay</lastname></person>'.
|
||||
'</people>'.
|
||||
'</response>'."\n";
|
||||
|
||||
$expected = array(
|
||||
'people' => array('person' => array(
|
||||
array('firstname' => 'Benjamin', 'lastname' => 'Alexandre'),
|
||||
array('firstname' => 'Damien', 'lastname' => 'Clay'),
|
||||
)),
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeXMLWithProcessInstruction()
|
||||
{
|
||||
$source = <<<'XML'
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/xsl" href="/xsl/xmlverbatimwrapper.xsl"?>
|
||||
<?display table-view?>
|
||||
<?sort alpha-ascending?>
|
||||
<response>
|
||||
<foo>foo</foo>
|
||||
<?textinfo whitespace is allowed ?>
|
||||
<bar>a</bar>
|
||||
<bar>b</bar>
|
||||
<baz>
|
||||
<key>val</key>
|
||||
<key2>val</key2>
|
||||
<item key="A B">bar</item>
|
||||
<item>
|
||||
<title>title1</title>
|
||||
</item>
|
||||
<?item ignore-title ?>
|
||||
<item>
|
||||
<title>title2</title>
|
||||
</item>
|
||||
<Barry>
|
||||
<FooBar id="1">
|
||||
<Baz>Ed</Baz>
|
||||
</FooBar>
|
||||
</Barry>
|
||||
</baz>
|
||||
<qux>1</qux>
|
||||
</response>
|
||||
<?instruction <value> ?>
|
||||
XML;
|
||||
$obj = $this->getObject();
|
||||
|
||||
$this->assertEquals(get_object_vars($obj), $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeIgnoreWhiteSpace()
|
||||
{
|
||||
$source = <<<'XML'
|
||||
<?xml version="1.0"?>
|
||||
<people>
|
||||
<person>
|
||||
<firstname>Benjamin</firstname>
|
||||
<lastname>Alexandre</lastname>
|
||||
</person>
|
||||
<person>
|
||||
<firstname>Damien</firstname>
|
||||
<lastname>Clay</lastname>
|
||||
</person>
|
||||
</people>
|
||||
XML;
|
||||
$expected = array('person' => array(
|
||||
array('firstname' => 'Benjamin', 'lastname' => 'Alexandre'),
|
||||
array('firstname' => 'Damien', 'lastname' => 'Clay'),
|
||||
));
|
||||
|
||||
$this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
|
||||
}
|
||||
|
||||
public function testDecodeWithoutItemHash()
|
||||
{
|
||||
$obj = new ScalarDummy();
|
||||
$obj->xmlFoo = array(
|
||||
'foo-bar' => array(
|
||||
'@key' => 'value',
|
||||
'item' => array('@key' => 'key', 'key-val' => 'val'),
|
||||
),
|
||||
'Foo' => array(
|
||||
'Bar' => 'Test',
|
||||
'@Type' => 'test',
|
||||
),
|
||||
'föo_bär' => 'a',
|
||||
'Bar' => array(1, 2, 3),
|
||||
'a' => 'b',
|
||||
);
|
||||
$expected = array(
|
||||
'foo-bar' => array(
|
||||
'@key' => 'value',
|
||||
'key' => array('@key' => 'key', 'key-val' => 'val'),
|
||||
),
|
||||
'Foo' => array(
|
||||
'Bar' => 'Test',
|
||||
'@Type' => 'test',
|
||||
),
|
||||
'föo_bär' => 'a',
|
||||
'Bar' => array(1, 2, 3),
|
||||
'a' => 'b',
|
||||
);
|
||||
$xml = $this->encoder->encode($obj, 'xml');
|
||||
$this->assertEquals($expected, $this->encoder->decode($xml, 'xml'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
|
||||
*/
|
||||
public function testDecodeInvalidXml()
|
||||
{
|
||||
$this->encoder->decode('<?xml version="1.0"?><invalid><xml>', 'xml');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
|
||||
*/
|
||||
public function testPreventsComplexExternalEntities()
|
||||
{
|
||||
$this->encoder->decode('<?xml version="1.0"?><!DOCTYPE scan[<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource=XmlEncoderTest.php">]><scan>&test;</scan>', 'xml');
|
||||
}
|
||||
|
||||
public function testDecodeEmptyXml()
|
||||
{
|
||||
if (method_exists($this, 'expectException')) {
|
||||
$this->expectException('Symfony\Component\Serializer\Exception\UnexpectedValueException');
|
||||
$this->expectExceptionMessage('Invalid XML data, it can not be empty.');
|
||||
} else {
|
||||
$this->setExpectedException('Symfony\Component\Serializer\Exception\UnexpectedValueException', 'Invalid XML data, it can not be empty.');
|
||||
}
|
||||
$this->encoder->decode(' ', 'xml');
|
||||
}
|
||||
|
||||
protected function getXmlSource()
|
||||
{
|
||||
return '<?xml version="1.0"?>'."\n".
|
||||
'<response>'.
|
||||
'<foo>foo</foo>'.
|
||||
'<bar>a</bar><bar>b</bar>'.
|
||||
'<baz><key>val</key><key2>val</key2><item key="A B">bar</item>'.
|
||||
'<item><title>title1</title></item><item><title>title2</title></item>'.
|
||||
'<Barry><FooBar id="1"><Baz>Ed</Baz></FooBar></Barry></baz>'.
|
||||
'<qux>1</qux>'.
|
||||
'</response>'."\n";
|
||||
}
|
||||
|
||||
protected function getNamespacedXmlSource()
|
||||
{
|
||||
return '<?xml version="1.0"?>'."\n".
|
||||
'<response xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns:media="http://search.yahoo.com/mrss/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:yt="http://gdata.youtube.com/schemas/2007">'.
|
||||
'<qux>1</qux>'.
|
||||
'<app:foo>foo</app:foo>'.
|
||||
'<yt:bar>a</yt:bar><yt:bar>b</yt:bar>'.
|
||||
'<media:baz><media:key>val</media:key><media:key2>val</media:key2><item key="A B">bar</item>'.
|
||||
'<item><title>title1</title></item><item><title>title2</title></item>'.
|
||||
'<Barry size="large"><FooBar gd:id="1"><Baz>Ed</Baz></FooBar></Barry></media:baz>'.
|
||||
'</response>'."\n";
|
||||
}
|
||||
|
||||
protected function getNamespacedArray()
|
||||
{
|
||||
return array(
|
||||
'@xmlns' => 'http://www.w3.org/2005/Atom',
|
||||
'@xmlns:app' => 'http://www.w3.org/2007/app',
|
||||
'@xmlns:media' => 'http://search.yahoo.com/mrss/',
|
||||
'@xmlns:gd' => 'http://schemas.google.com/g/2005',
|
||||
'@xmlns:yt' => 'http://gdata.youtube.com/schemas/2007',
|
||||
'qux' => '1',
|
||||
'app:foo' => 'foo',
|
||||
'yt:bar' => array('a', 'b'),
|
||||
'media:baz' => array(
|
||||
'media:key' => 'val',
|
||||
'media:key2' => 'val',
|
||||
'A B' => 'bar',
|
||||
'item' => array(
|
||||
array(
|
||||
'title' => 'title1',
|
||||
),
|
||||
array(
|
||||
'title' => 'title2',
|
||||
),
|
||||
),
|
||||
'Barry' => array(
|
||||
'@size' => 'large',
|
||||
'FooBar' => array(
|
||||
'Baz' => 'Ed',
|
||||
'@gd:id' => 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected function getObject()
|
||||
{
|
||||
$obj = new Dummy();
|
||||
$obj->foo = 'foo';
|
||||
$obj->bar = array('a', 'b');
|
||||
$obj->baz = array('key' => 'val', 'key2' => 'val', 'A B' => 'bar', 'item' => array(array('title' => 'title1'), array('title' => 'title2')), 'Barry' => array('FooBar' => array('Baz' => 'Ed', '@id' => 1)));
|
||||
$obj->qux = '1';
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
public function testEncodeXmlWithBoolValue()
|
||||
{
|
||||
$expectedXml = <<<'XML'
|
||||
<?xml version="1.0"?>
|
||||
<response><foo>1</foo><bar>0</bar></response>
|
||||
|
||||
XML;
|
||||
|
||||
$actualXml = $this->encoder->encode(array('foo' => true, 'bar' => false), 'xml');
|
||||
|
||||
$this->assertEquals($expectedXml, $actualXml);
|
||||
}
|
||||
|
||||
public function testEncodeXmlWithDateTimeObjectValue()
|
||||
{
|
||||
$xmlEncoder = $this->createXmlEncoderWithDateTimeNormalizer();
|
||||
|
||||
$actualXml = $xmlEncoder->encode(array('dateTime' => new \DateTime($this->exampleDateTimeString)), 'xml');
|
||||
|
||||
$this->assertEquals($this->createXmlWithDateTime(), $actualXml);
|
||||
}
|
||||
|
||||
public function testEncodeXmlWithDateTimeObjectField()
|
||||
{
|
||||
$xmlEncoder = $this->createXmlEncoderWithDateTimeNormalizer();
|
||||
|
||||
$actualXml = $xmlEncoder->encode(array('foo' => array('@dateTime' => new \DateTime($this->exampleDateTimeString))), 'xml');
|
||||
|
||||
$this->assertEquals($this->createXmlWithDateTimeField(), $actualXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XmlEncoder
|
||||
*/
|
||||
private function createXmlEncoderWithDateTimeNormalizer()
|
||||
{
|
||||
$encoder = new XmlEncoder();
|
||||
$serializer = new Serializer(array($this->createMockDateTimeNormalizer()), array('xml' => new XmlEncoder()));
|
||||
$encoder->setSerializer($serializer);
|
||||
|
||||
return $encoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \PHPUnit_Framework_MockObject_MockObject|NormalizerInterface
|
||||
*/
|
||||
private function createMockDateTimeNormalizer()
|
||||
{
|
||||
$mock = $this->getMockBuilder('\Symfony\Component\Serializer\Normalizer\CustomNormalizer')->getMock();
|
||||
|
||||
$mock
|
||||
->expects($this->once())
|
||||
->method('normalize')
|
||||
->with(new \DateTime($this->exampleDateTimeString), 'xml', array())
|
||||
->willReturn($this->exampleDateTimeString);
|
||||
|
||||
$mock
|
||||
->expects($this->once())
|
||||
->method('supportsNormalization')
|
||||
->with(new \DateTime($this->exampleDateTimeString), 'xml')
|
||||
->willReturn(true);
|
||||
|
||||
return $mock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function createXmlWithDateTime()
|
||||
{
|
||||
return sprintf('<?xml version="1.0"?>
|
||||
<response><dateTime>%s</dateTime></response>
|
||||
', $this->exampleDateTimeString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function createXmlWithDateTimeField()
|
||||
{
|
||||
return sprintf('<?xml version="1.0"?>
|
||||
<response><foo dateTime="%s"/></response>
|
||||
', $this->exampleDateTimeString);
|
||||
}
|
||||
}
|
71
vendor/symfony/serializer/Tests/Encoder/YamlEncoderTest.php
vendored
Normal file
71
vendor/symfony/serializer/Tests/Encoder/YamlEncoderTest.php
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?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\Encoder;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Serializer\Encoder\YamlEncoder;
|
||||
use Symfony\Component\Yaml\Dumper;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class YamlEncoderTest extends TestCase
|
||||
{
|
||||
public function testEncode()
|
||||
{
|
||||
$encoder = new YamlEncoder();
|
||||
|
||||
$this->assertEquals('foo', $encoder->encode('foo', 'yaml'));
|
||||
$this->assertEquals('{ foo: 1 }', $encoder->encode(array('foo' => 1), 'yaml'));
|
||||
}
|
||||
|
||||
public function testSupportsEncoding()
|
||||
{
|
||||
$encoder = new YamlEncoder();
|
||||
|
||||
$this->assertTrue($encoder->supportsEncoding('yaml'));
|
||||
$this->assertFalse($encoder->supportsEncoding('json'));
|
||||
}
|
||||
|
||||
public function testDecode()
|
||||
{
|
||||
$encoder = new YamlEncoder();
|
||||
|
||||
$this->assertEquals('foo', $encoder->decode('foo', 'yaml'));
|
||||
$this->assertEquals(array('foo' => 1), $encoder->decode('{ foo: 1 }', 'yaml'));
|
||||
}
|
||||
|
||||
public function testSupportsDecoding()
|
||||
{
|
||||
$encoder = new YamlEncoder();
|
||||
|
||||
$this->assertTrue($encoder->supportsDecoding('yaml'));
|
||||
$this->assertFalse($encoder->supportsDecoding('json'));
|
||||
}
|
||||
|
||||
public function testContext()
|
||||
{
|
||||
$encoder = new YamlEncoder(new Dumper(), new Parser(), array('yaml_inline' => 1, 'yaml_indent' => 4, 'yaml_flags' => Yaml::DUMP_OBJECT | Yaml::PARSE_OBJECT));
|
||||
|
||||
$obj = new \stdClass();
|
||||
$obj->bar = 2;
|
||||
|
||||
$legacyTag = " foo: !php/object:O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}\n";
|
||||
$spacedTag = " foo: !php/object 'O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}'\n";
|
||||
$this->assertThat($encoder->encode(array('foo' => $obj), 'yaml'), $this->logicalOr($this->equalTo($legacyTag), $this->equalTo($spacedTag)));
|
||||
$this->assertEquals(' { foo: null }', $encoder->encode(array('foo' => $obj), 'yaml', array('yaml_inline' => 0, 'yaml_indent' => 2, 'yaml_flags' => 0)));
|
||||
$this->assertEquals(array('foo' => $obj), $encoder->decode("foo: !php/object 'O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}'", 'yaml'));
|
||||
$this->assertEquals(array('foo' => null), $encoder->decode("foo: !php/object 'O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}'", 'yaml', array('yaml_flags' => 0)));
|
||||
}
|
||||
}
|
60
vendor/symfony/serializer/Tests/Fixtures/AbstractNormalizerDummy.php
vendored
Normal file
60
vendor/symfony/serializer/Tests/Fixtures/AbstractNormalizerDummy.php
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
|
||||
/**
|
||||
* Provides a dummy Normalizer which extends the AbstractNormalizer.
|
||||
*
|
||||
* @author Konstantin S. M. Möllers <ksm.moellers@gmail.com>
|
||||
*/
|
||||
class AbstractNormalizerDummy extends AbstractNormalizer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAllowedAttributes($classOrObject, array $context, $attributesAsString = false)
|
||||
{
|
||||
return parent::getAllowedAttributes($classOrObject, $context, $attributesAsString);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function normalize($object, $format = null, array $context = array())
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsNormalization($data, $format = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function denormalize($data, $class, $format = null, array $context = array())
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supportsDenormalization($data, $type, $format = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
23
vendor/symfony/serializer/Tests/Fixtures/CircularReferenceDummy.php
vendored
Normal file
23
vendor/symfony/serializer/Tests/Fixtures/CircularReferenceDummy.php
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class CircularReferenceDummy
|
||||
{
|
||||
public function getMe()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
22
vendor/symfony/serializer/Tests/Fixtures/DenormalizableDummy.php
vendored
Normal file
22
vendor/symfony/serializer/Tests/Fixtures/DenormalizableDummy.php
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizableInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
|
||||
class DenormalizableDummy implements DenormalizableInterface
|
||||
{
|
||||
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array())
|
||||
{
|
||||
}
|
||||
}
|
43
vendor/symfony/serializer/Tests/Fixtures/Dummy.php
vendored
Normal file
43
vendor/symfony/serializer/Tests/Fixtures/Dummy.php
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizableInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizableInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
class Dummy implements NormalizableInterface, DenormalizableInterface
|
||||
{
|
||||
public $foo;
|
||||
public $bar;
|
||||
public $baz;
|
||||
public $qux;
|
||||
|
||||
public function normalize(NormalizerInterface $normalizer, $format = null, array $context = array())
|
||||
{
|
||||
return array(
|
||||
'foo' => $this->foo,
|
||||
'bar' => $this->bar,
|
||||
'baz' => $this->baz,
|
||||
'qux' => $this->qux,
|
||||
);
|
||||
}
|
||||
|
||||
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array())
|
||||
{
|
||||
$this->foo = $data['foo'];
|
||||
$this->bar = $data['bar'];
|
||||
$this->baz = $data['baz'];
|
||||
$this->qux = $data['qux'];
|
||||
}
|
||||
}
|
80
vendor/symfony/serializer/Tests/Fixtures/GroupDummy.php
vendored
Normal file
80
vendor/symfony/serializer/Tests/Fixtures/GroupDummy.php
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class GroupDummy extends GroupDummyParent implements GroupDummyInterface
|
||||
{
|
||||
/**
|
||||
* @Groups({"a"})
|
||||
*/
|
||||
private $foo;
|
||||
/**
|
||||
* @Groups({"b", "c", "name_converter"})
|
||||
*/
|
||||
protected $bar;
|
||||
private $fooBar;
|
||||
private $symfony;
|
||||
|
||||
/**
|
||||
* @Groups({"b"})
|
||||
*/
|
||||
public function setBar($bar)
|
||||
{
|
||||
$this->bar = $bar;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Groups({"c"})
|
||||
*/
|
||||
public function getBar()
|
||||
{
|
||||
return $this->bar;
|
||||
}
|
||||
|
||||
public function setFoo($foo)
|
||||
{
|
||||
$this->foo = $foo;
|
||||
}
|
||||
|
||||
public function getFoo()
|
||||
{
|
||||
return $this->foo;
|
||||
}
|
||||
|
||||
public function setFooBar($fooBar)
|
||||
{
|
||||
$this->fooBar = $fooBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Groups({"a", "b", "name_converter"})
|
||||
*/
|
||||
public function isFooBar()
|
||||
{
|
||||
return $this->fooBar;
|
||||
}
|
||||
|
||||
public function setSymfony($symfony)
|
||||
{
|
||||
$this->symfony = $symfony;
|
||||
}
|
||||
|
||||
public function getSymfony()
|
||||
{
|
||||
return $this->symfony;
|
||||
}
|
||||
}
|
33
vendor/symfony/serializer/Tests/Fixtures/GroupDummyChild.php
vendored
Normal file
33
vendor/symfony/serializer/Tests/Fixtures/GroupDummyChild.php
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
class GroupDummyChild extends GroupDummy
|
||||
{
|
||||
private $baz;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBaz()
|
||||
{
|
||||
return $this->baz;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $baz
|
||||
*/
|
||||
public function setBaz($baz)
|
||||
{
|
||||
$this->baz = $baz;
|
||||
}
|
||||
}
|
25
vendor/symfony/serializer/Tests/Fixtures/GroupDummyInterface.php
vendored
Normal file
25
vendor/symfony/serializer/Tests/Fixtures/GroupDummyInterface.php
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface GroupDummyInterface
|
||||
{
|
||||
/**
|
||||
* @Groups({"a", "name_converter"})
|
||||
*/
|
||||
public function getSymfony();
|
||||
}
|
49
vendor/symfony/serializer/Tests/Fixtures/GroupDummyParent.php
vendored
Normal file
49
vendor/symfony/serializer/Tests/Fixtures/GroupDummyParent.php
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class GroupDummyParent
|
||||
{
|
||||
/**
|
||||
* @Groups({"a"})
|
||||
*/
|
||||
private $kevin;
|
||||
private $coopTilleuls;
|
||||
|
||||
public function setKevin($kevin)
|
||||
{
|
||||
$this->kevin = $kevin;
|
||||
}
|
||||
|
||||
public function getKevin()
|
||||
{
|
||||
return $this->kevin;
|
||||
}
|
||||
|
||||
public function setCoopTilleuls($coopTilleuls)
|
||||
{
|
||||
$this->coopTilleuls = $coopTilleuls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Groups({"a", "b"})
|
||||
*/
|
||||
public function getCoopTilleuls()
|
||||
{
|
||||
return $this->coopTilleuls;
|
||||
}
|
||||
}
|
25
vendor/symfony/serializer/Tests/Fixtures/JsonSerializableDummy.php
vendored
Normal file
25
vendor/symfony/serializer/Tests/Fixtures/JsonSerializableDummy.php
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
class JsonSerializableDummy implements \JsonSerializable
|
||||
{
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return array(
|
||||
'foo' => 'a',
|
||||
'bar' => 'b',
|
||||
'baz' => 'c',
|
||||
'qux' => $this,
|
||||
);
|
||||
}
|
||||
}
|
45
vendor/symfony/serializer/Tests/Fixtures/MaxDepthDummy.php
vendored
Normal file
45
vendor/symfony/serializer/Tests/Fixtures/MaxDepthDummy.php
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\MaxDepth;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class MaxDepthDummy
|
||||
{
|
||||
/**
|
||||
* @MaxDepth(2)
|
||||
*/
|
||||
public $foo;
|
||||
|
||||
public $bar;
|
||||
|
||||
/**
|
||||
* @var self
|
||||
*/
|
||||
public $child;
|
||||
|
||||
/**
|
||||
* @MaxDepth(3)
|
||||
*/
|
||||
public function getBar()
|
||||
{
|
||||
return $this->bar;
|
||||
}
|
||||
|
||||
public function getChild()
|
||||
{
|
||||
return $this->child;
|
||||
}
|
||||
}
|
36
vendor/symfony/serializer/Tests/Fixtures/NormalizableTraversableDummy.php
vendored
Normal file
36
vendor/symfony/serializer/Tests/Fixtures/NormalizableTraversableDummy.php
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizableInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizableInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
class NormalizableTraversableDummy extends TraversableDummy implements NormalizableInterface, DenormalizableInterface
|
||||
{
|
||||
public function normalize(NormalizerInterface $normalizer, $format = null, array $context = array())
|
||||
{
|
||||
return array(
|
||||
'foo' => 'normalizedFoo',
|
||||
'bar' => 'normalizedBar',
|
||||
);
|
||||
}
|
||||
|
||||
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array())
|
||||
{
|
||||
return array(
|
||||
'foo' => 'denormalizedFoo',
|
||||
'bar' => 'denormalizedBar',
|
||||
);
|
||||
}
|
||||
}
|
32
vendor/symfony/serializer/Tests/Fixtures/NullableConstructorArgumentDummy.php
vendored
Normal file
32
vendor/symfony/serializer/Tests/Fixtures/NullableConstructorArgumentDummy.php
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?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\Fixtures;
|
||||
|
||||
class NullableConstructorArgumentDummy
|
||||
{
|
||||
private $foo;
|
||||
|
||||
public function __construct(?\stdClass $foo)
|
||||
{
|
||||
$this->foo = $foo;
|
||||
}
|
||||
|
||||
public function setFoo($foo)
|
||||
{
|
||||
$this->foo = 'this setter should not be called when using the constructor argument';
|
||||
}
|
||||
|
||||
public function getFoo()
|
||||
{
|
||||
return $this->foo;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue