init
This commit is contained in:
185
backend/vendor/symfony/serializer/Mapping/AttributeMetadata.php
vendored
Normal file
185
backend/vendor/symfony/serializer/Mapping/AttributeMetadata.php
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
<?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;
|
||||
|
||||
use Symfony\Component\PropertyAccess\PropertyPath;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*
|
||||
* @final since Symfony 7.4
|
||||
*/
|
||||
class AttributeMetadata implements AttributeMetadataInterface
|
||||
{
|
||||
private string $name;
|
||||
private array $groups = [];
|
||||
private ?int $maxDepth = null;
|
||||
private ?string $serializedName = null;
|
||||
private ?PropertyPath $serializedPath = null;
|
||||
private bool $ignore = false;
|
||||
|
||||
/**
|
||||
* @var array[] Normalization contexts per group name ("*" applies to all groups)
|
||||
*/
|
||||
private array $normalizationContexts = [];
|
||||
|
||||
/**
|
||||
* @var array[] Denormalization contexts per group name ("*" applies to all groups)
|
||||
*/
|
||||
private array $denormalizationContexts = [];
|
||||
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function addGroup(string $group): void
|
||||
{
|
||||
if (!\in_array($group, $this->groups, true)) {
|
||||
$this->groups[] = $group;
|
||||
}
|
||||
}
|
||||
|
||||
public function getGroups(): array
|
||||
{
|
||||
return $this->groups;
|
||||
}
|
||||
|
||||
public function setMaxDepth(?int $maxDepth): void
|
||||
{
|
||||
$this->maxDepth = $maxDepth;
|
||||
}
|
||||
|
||||
public function getMaxDepth(): ?int
|
||||
{
|
||||
return $this->maxDepth;
|
||||
}
|
||||
|
||||
public function setSerializedName(?string $serializedName): void
|
||||
{
|
||||
$this->serializedName = $serializedName;
|
||||
}
|
||||
|
||||
public function getSerializedName(): ?string
|
||||
{
|
||||
return $this->serializedName;
|
||||
}
|
||||
|
||||
public function setSerializedPath(?PropertyPath $serializedPath = null): void
|
||||
{
|
||||
$this->serializedPath = $serializedPath;
|
||||
}
|
||||
|
||||
public function getSerializedPath(): ?PropertyPath
|
||||
{
|
||||
return $this->serializedPath;
|
||||
}
|
||||
|
||||
public function setIgnore(bool $ignore): void
|
||||
{
|
||||
$this->ignore = $ignore;
|
||||
}
|
||||
|
||||
public function isIgnored(): bool
|
||||
{
|
||||
return $this->ignore;
|
||||
}
|
||||
|
||||
public function getNormalizationContexts(): array
|
||||
{
|
||||
return $this->normalizationContexts;
|
||||
}
|
||||
|
||||
public function getNormalizationContextForGroups(array $groups): array
|
||||
{
|
||||
$contexts = [];
|
||||
foreach ($groups as $group) {
|
||||
$contexts[] = $this->normalizationContexts[$group] ?? [];
|
||||
}
|
||||
|
||||
return array_merge($this->normalizationContexts['*'] ?? [], ...$contexts);
|
||||
}
|
||||
|
||||
public function setNormalizationContextForGroups(array $context, array $groups = []): void
|
||||
{
|
||||
if (!$groups) {
|
||||
$this->normalizationContexts['*'] = $context;
|
||||
}
|
||||
|
||||
foreach ($groups as $group) {
|
||||
$this->normalizationContexts[$group] = $context;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDenormalizationContexts(): array
|
||||
{
|
||||
return $this->denormalizationContexts;
|
||||
}
|
||||
|
||||
public function getDenormalizationContextForGroups(array $groups): array
|
||||
{
|
||||
$contexts = [];
|
||||
foreach ($groups as $group) {
|
||||
$contexts[] = $this->denormalizationContexts[$group] ?? [];
|
||||
}
|
||||
|
||||
return array_merge($this->denormalizationContexts['*'] ?? [], ...$contexts);
|
||||
}
|
||||
|
||||
public function setDenormalizationContextForGroups(array $context, array $groups = []): void
|
||||
{
|
||||
if (!$groups) {
|
||||
$this->denormalizationContexts['*'] = $context;
|
||||
}
|
||||
|
||||
foreach ($groups as $group) {
|
||||
$this->denormalizationContexts[$group] = $context;
|
||||
}
|
||||
}
|
||||
|
||||
public function merge(AttributeMetadataInterface $attributeMetadata): void
|
||||
{
|
||||
foreach ($attributeMetadata->getGroups() as $group) {
|
||||
$this->addGroup($group);
|
||||
}
|
||||
|
||||
// Overwrite only if not defined
|
||||
$this->maxDepth ??= $attributeMetadata->getMaxDepth();
|
||||
$this->serializedName ??= $attributeMetadata->getSerializedName();
|
||||
$this->serializedPath ??= $attributeMetadata->getSerializedPath();
|
||||
|
||||
// Overwrite only if both contexts are empty
|
||||
if (!$this->normalizationContexts && !$this->denormalizationContexts) {
|
||||
$this->normalizationContexts = $attributeMetadata->getNormalizationContexts();
|
||||
$this->denormalizationContexts = $attributeMetadata->getDenormalizationContexts();
|
||||
}
|
||||
|
||||
if ($ignore = $attributeMetadata->isIgnored()) {
|
||||
$this->ignore = $ignore;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal since Symfony 7.4, will be replaced by `__serialize()` in 8.0
|
||||
*
|
||||
* @final since Symfony 7.4, will be replaced by `__serialize()` in 8.0
|
||||
*/
|
||||
public function __sleep(): array
|
||||
{
|
||||
return ['name', 'groups', 'maxDepth', 'serializedName', 'serializedPath', 'ignore', 'normalizationContexts', 'denormalizationContexts'];
|
||||
}
|
||||
}
|
||||
112
backend/vendor/symfony/serializer/Mapping/AttributeMetadataInterface.php
vendored
Normal file
112
backend/vendor/symfony/serializer/Mapping/AttributeMetadataInterface.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?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;
|
||||
|
||||
use Symfony\Component\PropertyAccess\PropertyPath;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public function getName(): string;
|
||||
|
||||
/**
|
||||
* Adds this attribute to the given group.
|
||||
*/
|
||||
public function addGroup(string $group): void;
|
||||
|
||||
/**
|
||||
* Gets groups of this attribute.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getGroups(): array;
|
||||
|
||||
/**
|
||||
* Sets the serialization max depth for this attribute.
|
||||
*/
|
||||
public function setMaxDepth(?int $maxDepth): void;
|
||||
|
||||
/**
|
||||
* Gets the serialization max depth for this attribute.
|
||||
*/
|
||||
public function getMaxDepth(): ?int;
|
||||
|
||||
/**
|
||||
* Sets the serialization name for this attribute.
|
||||
*/
|
||||
public function setSerializedName(?string $serializedName): void;
|
||||
|
||||
/**
|
||||
* Gets the serialization name for this attribute.
|
||||
*/
|
||||
public function getSerializedName(): ?string;
|
||||
|
||||
public function setSerializedPath(?PropertyPath $serializedPath): void;
|
||||
|
||||
public function getSerializedPath(): ?PropertyPath;
|
||||
|
||||
/**
|
||||
* Sets if this attribute must be ignored or not.
|
||||
*/
|
||||
public function setIgnore(bool $ignore): void;
|
||||
|
||||
/**
|
||||
* Gets if this attribute is ignored or not.
|
||||
*/
|
||||
public function isIgnored(): bool;
|
||||
|
||||
/**
|
||||
* Merges an {@see AttributeMetadataInterface} with in the current one.
|
||||
*/
|
||||
public function merge(self $attributeMetadata): void;
|
||||
|
||||
/**
|
||||
* Gets all the normalization contexts per group ("*" being the base context applied to all groups).
|
||||
*/
|
||||
public function getNormalizationContexts(): array;
|
||||
|
||||
/**
|
||||
* Gets the computed normalization contexts for given groups.
|
||||
*/
|
||||
public function getNormalizationContextForGroups(array $groups): array;
|
||||
|
||||
/**
|
||||
* Sets the normalization context for given groups.
|
||||
*/
|
||||
public function setNormalizationContextForGroups(array $context, array $groups = []): void;
|
||||
|
||||
/**
|
||||
* Gets all the denormalization contexts per group ("*" being the base context applied to all groups).
|
||||
*/
|
||||
public function getDenormalizationContexts(): array;
|
||||
|
||||
/**
|
||||
* Gets the computed denormalization contexts for given groups.
|
||||
*/
|
||||
public function getDenormalizationContextForGroups(array $groups): array;
|
||||
|
||||
/**
|
||||
* Sets the denormalization context for given groups.
|
||||
*/
|
||||
public function setDenormalizationContextForGroups(array $context, array $groups = []): void;
|
||||
}
|
||||
81
backend/vendor/symfony/serializer/Mapping/ClassDiscriminatorFromClassMetadata.php
vendored
Normal file
81
backend/vendor/symfony/serializer/Mapping/ClassDiscriminatorFromClassMetadata.php
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
<?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;
|
||||
|
||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
|
||||
|
||||
/**
|
||||
* @author Samuel Roze <samuel.roze@gmail.com>
|
||||
*/
|
||||
class ClassDiscriminatorFromClassMetadata implements ClassDiscriminatorResolverInterface
|
||||
{
|
||||
private array $mappingForMappedObjectCache = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly ClassMetadataFactoryInterface $classMetadataFactory,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getMappingForClass(string $class): ?ClassDiscriminatorMapping
|
||||
{
|
||||
if ($this->classMetadataFactory->hasMetadataFor($class)) {
|
||||
return $this->classMetadataFactory->getMetadataFor($class)->getClassDiscriminatorMapping();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getMappingForMappedObject(object|string $object): ?ClassDiscriminatorMapping
|
||||
{
|
||||
if ($this->classMetadataFactory->hasMetadataFor($object)) {
|
||||
$metadata = $this->classMetadataFactory->getMetadataFor($object);
|
||||
|
||||
if (null !== $metadata->getClassDiscriminatorMapping()) {
|
||||
return $metadata->getClassDiscriminatorMapping();
|
||||
}
|
||||
}
|
||||
|
||||
$cacheKey = \is_object($object) ? $object::class : $object;
|
||||
if (!\array_key_exists($cacheKey, $this->mappingForMappedObjectCache)) {
|
||||
$this->mappingForMappedObjectCache[$cacheKey] = $this->resolveMappingForMappedObject($object);
|
||||
}
|
||||
|
||||
return $this->mappingForMappedObjectCache[$cacheKey];
|
||||
}
|
||||
|
||||
public function getTypeForMappedObject(object|string $object): ?string
|
||||
{
|
||||
if (null === $mapping = $this->getMappingForMappedObject($object)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $mapping->getMappedObjectType($object);
|
||||
}
|
||||
|
||||
private function resolveMappingForMappedObject(object|string $object): ?ClassDiscriminatorMapping
|
||||
{
|
||||
$reflectionClass = new \ReflectionClass($object);
|
||||
if ($parentClass = $reflectionClass->getParentClass()) {
|
||||
if (null !== ($parentMapping = $this->getMappingForMappedObject($parentClass->getName()))) {
|
||||
return $parentMapping;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($reflectionClass->getInterfaceNames() as $interfaceName) {
|
||||
if (null !== ($interfaceMapping = $this->getMappingForMappedObject($interfaceName))) {
|
||||
return $interfaceMapping;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
70
backend/vendor/symfony/serializer/Mapping/ClassDiscriminatorMapping.php
vendored
Normal file
70
backend/vendor/symfony/serializer/Mapping/ClassDiscriminatorMapping.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* @author Samuel Roze <samuel.roze@gmail.com>
|
||||
*/
|
||||
class ClassDiscriminatorMapping
|
||||
{
|
||||
/**
|
||||
* @param array<string, string> $typesMapping
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly string $typeProperty,
|
||||
private array $typesMapping = [],
|
||||
private readonly ?string $defaultType = null,
|
||||
) {
|
||||
uasort($this->typesMapping, static function (string $a, string $b): int {
|
||||
if (is_a($a, $b, true)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (is_a($b, $a, true)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
public function getTypeProperty(): string
|
||||
{
|
||||
return $this->typeProperty;
|
||||
}
|
||||
|
||||
public function getClassForType(string $type): ?string
|
||||
{
|
||||
return $this->typesMapping[$type] ?? null;
|
||||
}
|
||||
|
||||
public function getMappedObjectType(object|string $object): ?string
|
||||
{
|
||||
foreach ($this->typesMapping as $type => $typeClass) {
|
||||
if (is_a($object, $typeClass, true)) {
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getTypesMapping(): array
|
||||
{
|
||||
return $this->typesMapping;
|
||||
}
|
||||
|
||||
public function getDefaultType(): ?string
|
||||
{
|
||||
return $this->defaultType;
|
||||
}
|
||||
}
|
||||
26
backend/vendor/symfony/serializer/Mapping/ClassDiscriminatorResolverInterface.php
vendored
Normal file
26
backend/vendor/symfony/serializer/Mapping/ClassDiscriminatorResolverInterface.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* Knows how to get the class discriminator mapping for classes and objects.
|
||||
*
|
||||
* @author Samuel Roze <samuel.roze@gmail.com>
|
||||
*/
|
||||
interface ClassDiscriminatorResolverInterface
|
||||
{
|
||||
public function getMappingForClass(string $class): ?ClassDiscriminatorMapping;
|
||||
|
||||
public function getMappingForMappedObject(object|string $object): ?ClassDiscriminatorMapping;
|
||||
|
||||
public function getTypeForMappedObject(object|string $object): ?string;
|
||||
}
|
||||
91
backend/vendor/symfony/serializer/Mapping/ClassMetadata.php
vendored
Normal file
91
backend/vendor/symfony/serializer/Mapping/ClassMetadata.php
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*
|
||||
* @final since Symfony 7.4
|
||||
*/
|
||||
class ClassMetadata implements ClassMetadataInterface
|
||||
{
|
||||
private string $name;
|
||||
|
||||
/**
|
||||
* @var AttributeMetadataInterface[]
|
||||
*/
|
||||
private array $attributesMetadata = [];
|
||||
|
||||
private ?\ReflectionClass $reflClass = null;
|
||||
private ?ClassDiscriminatorMapping $classDiscriminatorMapping = null;
|
||||
|
||||
public function __construct(string $class, ?ClassDiscriminatorMapping $classDiscriminatorMapping = null)
|
||||
{
|
||||
$this->name = $class;
|
||||
$this->classDiscriminatorMapping = $classDiscriminatorMapping;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function addAttributeMetadata(AttributeMetadataInterface $attributeMetadata): void
|
||||
{
|
||||
$this->attributesMetadata[$attributeMetadata->getName()] = $attributeMetadata;
|
||||
}
|
||||
|
||||
public function getAttributesMetadata(): array
|
||||
{
|
||||
return $this->attributesMetadata;
|
||||
}
|
||||
|
||||
public function merge(ClassMetadataInterface $classMetadata): void
|
||||
{
|
||||
foreach ($classMetadata->getAttributesMetadata() as $attributeMetadata) {
|
||||
if (isset($this->attributesMetadata[$attributeMetadata->getName()])) {
|
||||
$this->attributesMetadata[$attributeMetadata->getName()]->merge($attributeMetadata);
|
||||
} else {
|
||||
$this->addAttributeMetadata($attributeMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getReflectionClass(): \ReflectionClass
|
||||
{
|
||||
return $this->reflClass ??= new \ReflectionClass($this->getName());
|
||||
}
|
||||
|
||||
public function getClassDiscriminatorMapping(): ?ClassDiscriminatorMapping
|
||||
{
|
||||
return $this->classDiscriminatorMapping;
|
||||
}
|
||||
|
||||
public function setClassDiscriminatorMapping(?ClassDiscriminatorMapping $mapping): void
|
||||
{
|
||||
$this->classDiscriminatorMapping = $mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal since Symfony 7.4, will be replaced by `__serialize()` in 8.0
|
||||
*
|
||||
* @final since Symfony 7.4, will be replaced by `__serialize()` in 8.0
|
||||
*/
|
||||
public function __sleep(): array
|
||||
{
|
||||
return [
|
||||
'name',
|
||||
'attributesMetadata',
|
||||
'classDiscriminatorMapping',
|
||||
];
|
||||
}
|
||||
}
|
||||
57
backend/vendor/symfony/serializer/Mapping/ClassMetadataInterface.php
vendored
Normal file
57
backend/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.
|
||||
*/
|
||||
public function getName(): string;
|
||||
|
||||
/**
|
||||
* Adds an {@link AttributeMetadataInterface}.
|
||||
*/
|
||||
public function addAttributeMetadata(AttributeMetadataInterface $attributeMetadata): void;
|
||||
|
||||
/**
|
||||
* Gets the list of {@link AttributeMetadataInterface}.
|
||||
*
|
||||
* @return array<string, AttributeMetadataInterface>
|
||||
*/
|
||||
public function getAttributesMetadata(): array;
|
||||
|
||||
/**
|
||||
* Merges a {@link ClassMetadataInterface} in the current one.
|
||||
*/
|
||||
public function merge(self $classMetadata): void;
|
||||
|
||||
/**
|
||||
* Returns a {@link \ReflectionClass} instance for this class.
|
||||
*/
|
||||
public function getReflectionClass(): \ReflectionClass;
|
||||
|
||||
public function getClassDiscriminatorMapping(): ?ClassDiscriminatorMapping;
|
||||
|
||||
public function setClassDiscriminatorMapping(?ClassDiscriminatorMapping $mapping): void;
|
||||
}
|
||||
62
backend/vendor/symfony/serializer/Mapping/Factory/CacheClassMetadataFactory.php
vendored
Normal file
62
backend/vendor/symfony/serializer/Mapping/Factory/CacheClassMetadataFactory.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?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;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Caches metadata using a PSR-6 implementation.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class CacheClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
{
|
||||
use ClassResolverTrait;
|
||||
|
||||
/**
|
||||
* @var array<string, ClassMetadataInterface>
|
||||
*/
|
||||
private array $loadedClasses = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly ClassMetadataFactoryInterface $decorated,
|
||||
private readonly CacheItemPoolInterface $cacheItemPool,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getMetadataFor(string|object $value): ClassMetadataInterface
|
||||
{
|
||||
$class = $this->getClass($value);
|
||||
|
||||
if (isset($this->loadedClasses[$class])) {
|
||||
return $this->loadedClasses[$class];
|
||||
}
|
||||
|
||||
$key = rawurlencode(strtr($class, '\\', '_'));
|
||||
|
||||
$item = $this->cacheItemPool->getItem($key);
|
||||
if ($item->isHit()) {
|
||||
return $this->loadedClasses[$class] = $item->get();
|
||||
}
|
||||
|
||||
$metadata = $this->decorated->getMetadataFor($value);
|
||||
$this->cacheItemPool->save($item->set($metadata));
|
||||
|
||||
return $this->loadedClasses[$class] = $metadata;
|
||||
}
|
||||
|
||||
public function hasMetadataFor(mixed $value): bool
|
||||
{
|
||||
return $this->decorated->hasMetadataFor($value);
|
||||
}
|
||||
}
|
||||
67
backend/vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactory.php
vendored
Normal file
67
backend/vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactory.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\Mapping\Factory;
|
||||
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Returns a {@link ClassMetadata}.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
{
|
||||
use ClassResolverTrait;
|
||||
|
||||
/**
|
||||
* @var array<string, ClassMetadataInterface>
|
||||
*/
|
||||
private array $loadedClasses;
|
||||
|
||||
public function __construct(
|
||||
private readonly LoaderInterface $loader,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getMetadataFor(string|object $value): ClassMetadataInterface
|
||||
{
|
||||
$class = $this->getClass($value);
|
||||
|
||||
if (isset($this->loadedClasses[$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));
|
||||
}
|
||||
|
||||
return $this->loadedClasses[$class] = $classMetadata;
|
||||
}
|
||||
|
||||
public function hasMetadataFor(mixed $value): bool
|
||||
{
|
||||
return \is_object($value) || (\is_string($value) && (class_exists($value) || interface_exists($value, false)));
|
||||
}
|
||||
}
|
||||
73
backend/vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactoryCompiler.php
vendored
Normal file
73
backend/vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactoryCompiler.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?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\Mapping\ClassMetadataInterface;
|
||||
use Symfony\Component\VarExporter\VarExporter;
|
||||
|
||||
trigger_deprecation('symfony/serializer', '7.4', 'The "%s" class is deprecated.', ClassMetadataFactoryCompiler::class);
|
||||
|
||||
/**
|
||||
* @author Fabien Bourigault <bourigaultfabien@gmail.com>
|
||||
*
|
||||
* @deprecated since Symfony 7.4
|
||||
*/
|
||||
final class ClassMetadataFactoryCompiler
|
||||
{
|
||||
/**
|
||||
* @param ClassMetadataInterface[] $classMetadatas
|
||||
*/
|
||||
public function compile(array $classMetadatas): string
|
||||
{
|
||||
return <<<EOF
|
||||
<?php
|
||||
|
||||
// This file has been auto-generated by the Symfony Serializer Component.
|
||||
|
||||
return [{$this->generateDeclaredClassMetadata($classMetadatas)}
|
||||
];
|
||||
EOF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadataInterface[] $classMetadatas
|
||||
*/
|
||||
private function generateDeclaredClassMetadata(array $classMetadatas): string
|
||||
{
|
||||
$compiled = '';
|
||||
|
||||
foreach ($classMetadatas as $classMetadata) {
|
||||
$attributesMetadata = [];
|
||||
foreach ($classMetadata->getAttributesMetadata() as $attributeMetadata) {
|
||||
$attributesMetadata[$attributeMetadata->getName()] = [
|
||||
$attributeMetadata->getGroups(),
|
||||
$attributeMetadata->getMaxDepth(),
|
||||
$attributeMetadata->getSerializedName(),
|
||||
$attributeMetadata->getSerializedPath(),
|
||||
];
|
||||
}
|
||||
|
||||
$classDiscriminatorMapping = $classMetadata->getClassDiscriminatorMapping() ? [
|
||||
$classMetadata->getClassDiscriminatorMapping()->getTypeProperty(),
|
||||
$classMetadata->getClassDiscriminatorMapping()->getTypesMapping(),
|
||||
$classMetadata->getClassDiscriminatorMapping()->getDefaultType(),
|
||||
] : null;
|
||||
|
||||
$compiled .= \sprintf("\n'%s' => %s,", $classMetadata->getName(), VarExporter::export([
|
||||
$attributesMetadata,
|
||||
$classDiscriminatorMapping,
|
||||
]));
|
||||
}
|
||||
|
||||
return $compiled;
|
||||
}
|
||||
}
|
||||
45
backend/vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactoryInterface.php
vendored
Normal file
45
backend/vendor/symfony/serializer/Mapping/Factory/ClassMetadataFactoryInterface.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\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.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getMetadataFor(string|object $value): ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Checks if class has metadata.
|
||||
*/
|
||||
public function hasMetadataFor(mixed $value): bool;
|
||||
}
|
||||
42
backend/vendor/symfony/serializer/Mapping/Factory/ClassResolverTrait.php
vendored
Normal file
42
backend/vendor/symfony/serializer/Mapping/Factory/ClassResolverTrait.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\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.
|
||||
*
|
||||
* @throws InvalidArgumentException If the class does not exist
|
||||
*/
|
||||
private function getClass(object|string $value): string
|
||||
{
|
||||
if (\is_string($value)) {
|
||||
if (!class_exists($value) && !interface_exists($value, false)) {
|
||||
throw new InvalidArgumentException(\sprintf('The class or interface "%s" does not exist.', $value));
|
||||
}
|
||||
|
||||
return ltrim($value, '\\');
|
||||
}
|
||||
|
||||
return $value::class;
|
||||
}
|
||||
}
|
||||
83
backend/vendor/symfony/serializer/Mapping/Factory/CompiledClassMetadataFactory.php
vendored
Normal file
83
backend/vendor/symfony/serializer/Mapping/Factory/CompiledClassMetadataFactory.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?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\Mapping\AttributeMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
trigger_deprecation('symfony/serializer', '7.3', 'The "%s" class is deprecated.', CompiledClassMetadataFactory::class);
|
||||
|
||||
/**
|
||||
* @author Fabien Bourigault <bourigaultfabien@gmail.com>
|
||||
*
|
||||
* @deprecated since Symfony 7.3
|
||||
*/
|
||||
final class CompiledClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
{
|
||||
private array $compiledClassMetadata = [];
|
||||
|
||||
private array $loadedClasses = [];
|
||||
|
||||
public function __construct(
|
||||
string $compiledClassMetadataFile,
|
||||
private readonly ClassMetadataFactoryInterface $classMetadataFactory,
|
||||
) {
|
||||
if (!file_exists($compiledClassMetadataFile)) {
|
||||
throw new \RuntimeException("File \"{$compiledClassMetadataFile}\" could not be found.");
|
||||
}
|
||||
|
||||
$compiledClassMetadata = require $compiledClassMetadataFile;
|
||||
if (!\is_array($compiledClassMetadata)) {
|
||||
throw new \RuntimeException(\sprintf('Compiled metadata must be of the type array, %s given.', \gettype($compiledClassMetadata)));
|
||||
}
|
||||
|
||||
$this->compiledClassMetadata = $compiledClassMetadata;
|
||||
}
|
||||
|
||||
public function getMetadataFor(string|object $value): ClassMetadataInterface
|
||||
{
|
||||
$className = \is_object($value) ? $value::class : $value;
|
||||
|
||||
if (!isset($this->compiledClassMetadata[$className])) {
|
||||
return $this->classMetadataFactory->getMetadataFor($value);
|
||||
}
|
||||
|
||||
if (!isset($this->loadedClasses[$className])) {
|
||||
$classMetadata = new ClassMetadata($className);
|
||||
foreach ($this->compiledClassMetadata[$className][0] as $name => $compiledAttributesMetadata) {
|
||||
$classMetadata->addAttributeMetadata($attributeMetadata = new AttributeMetadata($name));
|
||||
foreach ($compiledAttributesMetadata[0] as $group) {
|
||||
$attributeMetadata->addGroup($group);
|
||||
}
|
||||
$attributeMetadata->setMaxDepth($compiledAttributesMetadata[1]);
|
||||
$attributeMetadata->setSerializedName($compiledAttributesMetadata[2]);
|
||||
}
|
||||
$classMetadata->setClassDiscriminatorMapping($this->compiledClassMetadata[$className][1]
|
||||
? new ClassDiscriminatorMapping(...$this->compiledClassMetadata[$className][1])
|
||||
: null
|
||||
);
|
||||
|
||||
$this->loadedClasses[$className] = $classMetadata;
|
||||
}
|
||||
|
||||
return $this->loadedClasses[$className];
|
||||
}
|
||||
|
||||
public function hasMetadataFor(mixed $value): bool
|
||||
{
|
||||
$className = \is_object($value) ? $value::class : $value;
|
||||
|
||||
return isset($this->compiledClassMetadata[$className]) || $this->classMetadataFactory->hasMetadataFor($value);
|
||||
}
|
||||
}
|
||||
101
backend/vendor/symfony/serializer/Mapping/Loader/AccessorCollisionResolverTrait.php
vendored
Normal file
101
backend/vendor/symfony/serializer/Mapping/Loader/AccessorCollisionResolverTrait.php
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
<?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\Attribute\Ignore;
|
||||
|
||||
/**
|
||||
* Provides methods to detect accessor name collisions during serialization.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait AccessorCollisionResolverTrait
|
||||
{
|
||||
private function getAttributeNameFromAccessor(\ReflectionClass $class, \ReflectionMethod $method, bool $andMutator): ?string
|
||||
{
|
||||
$methodName = $method->name;
|
||||
|
||||
$i = match ($methodName[0]) {
|
||||
's' => $andMutator && str_starts_with($methodName, 'set') ? 3 : null,
|
||||
'g' => str_starts_with($methodName, 'get') ? 3 : null,
|
||||
'h' => str_starts_with($methodName, 'has') ? 3 : null,
|
||||
'c' => str_starts_with($methodName, 'can') ? 3 : null,
|
||||
'i' => str_starts_with($methodName, 'is') ? 2 : null,
|
||||
default => null,
|
||||
};
|
||||
|
||||
// ctype_lower check to find out if method looks like accessor but actually is not, e.g. hash, cancel
|
||||
if (null === $i || ctype_lower($methodName[$i] ?? 'a') || (!$andMutator && $method->isStatic())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ('s' === $methodName[0] ? !$method->getNumberOfParameters() : ($method->getNumberOfRequiredParameters() || \in_array((string) $method->getReturnType(), ['void', 'never'], true))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$attributeName = substr($methodName, $i);
|
||||
|
||||
if (!$class->hasProperty($attributeName)) {
|
||||
$attributeName = lcfirst($attributeName);
|
||||
}
|
||||
|
||||
return $attributeName;
|
||||
}
|
||||
|
||||
private function hasPropertyForAccessor(\ReflectionClass $class, string $propName): bool
|
||||
{
|
||||
do {
|
||||
if ($class->hasProperty($propName)) {
|
||||
return true;
|
||||
}
|
||||
} while ($class = $class->getParentClass());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function hasAttributeNameCollision(\ReflectionClass $class, string $attributeName, string $methodName): bool
|
||||
{
|
||||
if ($this->hasPropertyForAccessor($class, $attributeName)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($class->hasMethod($attributeName)) {
|
||||
$candidate = $class->getMethod($attributeName);
|
||||
if ($candidate->getName() !== $methodName && $this->isReadableAccessorMethod($candidate)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$ucAttributeName = ucfirst($attributeName);
|
||||
foreach (['get', 'is', 'has', 'can'] as $prefix) {
|
||||
$candidateName = $prefix.$ucAttributeName;
|
||||
if ($candidateName === $methodName || !$class->hasMethod($candidateName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isReadableAccessorMethod($class->getMethod($candidateName))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function isReadableAccessorMethod(\ReflectionMethod $method): bool
|
||||
{
|
||||
return $method->isPublic()
|
||||
&& !$method->isStatic()
|
||||
&& !$method->getAttributes(Ignore::class)
|
||||
&& !$method->getNumberOfRequiredParameters()
|
||||
&& !\in_array((string) $method->getReturnType(), ['void', 'never'], true);
|
||||
}
|
||||
}
|
||||
262
backend/vendor/symfony/serializer/Mapping/Loader/AttributeLoader.php
vendored
Normal file
262
backend/vendor/symfony/serializer/Mapping/Loader/AttributeLoader.php
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
<?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\Attribute\Context;
|
||||
use Symfony\Component\Serializer\Attribute\DiscriminatorMap;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
use Symfony\Component\Serializer\Attribute\Ignore;
|
||||
use Symfony\Component\Serializer\Attribute\MaxDepth;
|
||||
use Symfony\Component\Serializer\Attribute\SerializedName;
|
||||
use Symfony\Component\Serializer\Attribute\SerializedPath;
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
|
||||
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Loader for PHP attributes.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
* @author Alexander M. Turek <me@derrabus.de>
|
||||
* @author Alexandre Daubois <alex.daubois@gmail.com>
|
||||
*/
|
||||
class AttributeLoader implements LoaderInterface
|
||||
{
|
||||
use AccessorCollisionResolverTrait;
|
||||
|
||||
private const KNOWN_ATTRIBUTES = [
|
||||
DiscriminatorMap::class,
|
||||
Groups::class,
|
||||
Ignore::class,
|
||||
MaxDepth::class,
|
||||
SerializedName::class,
|
||||
SerializedPath::class,
|
||||
Context::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @param bool|null $allowAnyClass Null is allowed for BC with Symfony <= 6
|
||||
* @param array<class-string, class-string[]> $mappedClasses
|
||||
*/
|
||||
public function __construct(
|
||||
private ?bool $allowAnyClass = true,
|
||||
private array $mappedClasses = [],
|
||||
) {
|
||||
$this->allowAnyClass ??= true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string[]
|
||||
*/
|
||||
public function getMappedClasses(): array
|
||||
{
|
||||
return array_keys($this->mappedClasses);
|
||||
}
|
||||
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
|
||||
{
|
||||
if (!$sourceClasses = $this->mappedClasses[$classMetadata->getName()] ??= $this->allowAnyClass ? [$classMetadata->getName()] : []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$success = false;
|
||||
foreach ($sourceClasses as $sourceClass) {
|
||||
$reflectionClass = $classMetadata->getName() === $sourceClass ? $classMetadata->getReflectionClass() : new \ReflectionClass($sourceClass);
|
||||
$success = $this->doLoadClassMetadata($reflectionClass, $classMetadata) || $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
private function doLoadClassMetadata(\ReflectionClass $reflectionClass, ClassMetadataInterface $classMetadata): bool
|
||||
{
|
||||
$className = $reflectionClass->name;
|
||||
$loaded = false;
|
||||
$classGroups = [];
|
||||
$classContextAttribute = null;
|
||||
|
||||
$attributesMetadata = $classMetadata->getAttributesMetadata();
|
||||
|
||||
foreach ($this->loadAttributes($reflectionClass) as $attribute) {
|
||||
match (true) {
|
||||
$attribute instanceof DiscriminatorMap => $classMetadata->setClassDiscriminatorMapping(new ClassDiscriminatorMapping($attribute->typeProperty, $attribute->mapping, $attribute->defaultType)),
|
||||
$attribute instanceof Groups => $classGroups = $attribute->groups,
|
||||
$attribute instanceof Context => $classContextAttribute = $attribute,
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
if (!isset($attributesMetadata[$property->name])) {
|
||||
$attributesMetadata[$property->name] = new AttributeMetadata($property->name);
|
||||
$classMetadata->addAttributeMetadata($attributesMetadata[$property->name]);
|
||||
}
|
||||
|
||||
$attributeMetadata = $attributesMetadata[$property->name];
|
||||
if ($property->getDeclaringClass()->name === $className) {
|
||||
if ($classContextAttribute) {
|
||||
$this->setAttributeContextsForGroups($classContextAttribute, $attributeMetadata);
|
||||
}
|
||||
|
||||
foreach ($classGroups as $group) {
|
||||
$attributeMetadata->addGroup($group);
|
||||
}
|
||||
|
||||
foreach ($this->loadAttributes($property) as $attribute) {
|
||||
$loaded = true;
|
||||
|
||||
if ($attribute instanceof Groups) {
|
||||
foreach ($attribute->groups as $group) {
|
||||
$attributeMetadata->addGroup($group);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
match (true) {
|
||||
$attribute instanceof MaxDepth => $attributeMetadata->setMaxDepth($attribute->maxDepth),
|
||||
$attribute instanceof SerializedName => $attributeMetadata->setSerializedName($attribute->serializedName),
|
||||
$attribute instanceof SerializedPath => $attributeMetadata->setSerializedPath($attribute->serializedPath),
|
||||
$attribute instanceof Ignore => $attributeMetadata->setIgnore(true),
|
||||
$attribute instanceof Context => $this->setAttributeContextsForGroups($attribute, $attributeMetadata),
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($reflectionClass->getMethods() as $method) {
|
||||
if ($method->getDeclaringClass()->name !== $className) {
|
||||
continue;
|
||||
}
|
||||
$name = $method->name;
|
||||
|
||||
if (0 === stripos($name, 'get') && $method->getNumberOfRequiredParameters()) {
|
||||
continue; /* matches the BC behavior in `Symfony\Component\Serializer\Normalizer\ObjectNormalizer::extractAttributes` */
|
||||
}
|
||||
|
||||
$attributeName = $this->getAttributeNameFromAccessor($reflectionClass, $method, true);
|
||||
$accessorOrMutator = null !== $attributeName;
|
||||
$hasProperty = $this->hasPropertyForAccessor($method->getDeclaringClass(), $name);
|
||||
$attributeMetadata = null;
|
||||
|
||||
if ($hasProperty || $accessorOrMutator) {
|
||||
if (null === $attributeName || 's' !== $name[0] && $hasProperty && $this->hasAttributeNameCollision($reflectionClass, $attributeName, $name)) {
|
||||
$attributeName = $name;
|
||||
}
|
||||
|
||||
if (isset($attributesMetadata[$attributeName])) {
|
||||
$attributeMetadata = $attributesMetadata[$attributeName];
|
||||
} else {
|
||||
$attributesMetadata[$attributeName] = $attributeMetadata = new AttributeMetadata($attributeName);
|
||||
$classMetadata->addAttributeMetadata($attributeMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->loadAttributes($method) as $attribute) {
|
||||
if ($attribute instanceof Groups) {
|
||||
if (!$attributeMetadata) {
|
||||
throw new MappingException(\sprintf('Groups on "%s::%s()" cannot be added. Groups can only be added on methods beginning with "get", "is", "has", "can" or "set".', $className, $method->name));
|
||||
}
|
||||
|
||||
foreach ($attribute->groups as $group) {
|
||||
$attributeMetadata->addGroup($group);
|
||||
}
|
||||
} elseif ($attribute instanceof MaxDepth) {
|
||||
if (!$attributeMetadata) {
|
||||
throw new MappingException(\sprintf('MaxDepth on "%s::%s()" cannot be added. MaxDepth can only be added on methods beginning with "get", "is", "has", "can" or "set".', $className, $method->name));
|
||||
}
|
||||
|
||||
$attributeMetadata->setMaxDepth($attribute->maxDepth);
|
||||
} elseif ($attribute instanceof SerializedName) {
|
||||
if (!$attributeMetadata) {
|
||||
throw new MappingException(\sprintf('SerializedName on "%s::%s()" cannot be added. SerializedName can only be added on methods beginning with "get", "is", "has", "can" or "set".', $className, $method->name));
|
||||
}
|
||||
|
||||
$attributeMetadata->setSerializedName($attribute->serializedName);
|
||||
} elseif ($attribute instanceof SerializedPath) {
|
||||
if (!$attributeMetadata) {
|
||||
throw new MappingException(\sprintf('SerializedPath on "%s::%s()" cannot be added. SerializedPath can only be added on methods beginning with "get", "is", "has", "can" or "set".', $className, $method->name));
|
||||
}
|
||||
|
||||
$attributeMetadata->setSerializedPath($attribute->serializedPath);
|
||||
} elseif ($attribute instanceof Ignore) {
|
||||
if ($attributeMetadata) {
|
||||
$attributeMetadata->setIgnore(true);
|
||||
}
|
||||
} elseif ($attribute instanceof Context) {
|
||||
if (!$attributeMetadata) {
|
||||
throw new MappingException(\sprintf('Context on "%s::%s()" cannot be added. Context can only be added on methods beginning with "get", "is", "has", "can" or "set".', $className, $method->name));
|
||||
}
|
||||
|
||||
$this->setAttributeContextsForGroups($attribute, $attributeMetadata);
|
||||
}
|
||||
|
||||
$loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $loaded;
|
||||
}
|
||||
|
||||
private function loadAttributes(\ReflectionMethod|\ReflectionClass|\ReflectionProperty $reflector): iterable
|
||||
{
|
||||
foreach ($reflector->getAttributes() as $attribute) {
|
||||
if ($this->isKnownAttribute($attribute->getName())) {
|
||||
try {
|
||||
yield $attribute->newInstance();
|
||||
} catch (\Error $e) {
|
||||
if (\Error::class !== $e::class) {
|
||||
throw $e;
|
||||
}
|
||||
$on = match (true) {
|
||||
$reflector instanceof \ReflectionClass => ' on class '.$reflector->name,
|
||||
$reflector instanceof \ReflectionMethod => \sprintf(' on "%s::%s()"', $reflector->getDeclaringClass()->name, $reflector->name),
|
||||
$reflector instanceof \ReflectionProperty => \sprintf(' on "%s::$%s"', $reflector->getDeclaringClass()->name, $reflector->name),
|
||||
default => '',
|
||||
};
|
||||
|
||||
throw new MappingException(\sprintf('Could not instantiate attribute "%s"%s.', $attribute->getName(), $on), 0, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function setAttributeContextsForGroups(Context $attribute, AttributeMetadataInterface $attributeMetadata): void
|
||||
{
|
||||
$context = $attribute->context;
|
||||
$groups = $attribute->groups;
|
||||
$normalizationContext = $attribute->normalizationContext;
|
||||
$denormalizationContext = $attribute->denormalizationContext;
|
||||
|
||||
if ($normalizationContext || $context) {
|
||||
$attributeMetadata->setNormalizationContextForGroups($normalizationContext ?: $context, $groups);
|
||||
}
|
||||
|
||||
if ($denormalizationContext || $context) {
|
||||
$attributeMetadata->setDenormalizationContextForGroups($denormalizationContext ?: $context, $groups);
|
||||
}
|
||||
}
|
||||
|
||||
private function isKnownAttribute(string $attributeName): bool
|
||||
{
|
||||
foreach (self::KNOWN_ATTRIBUTES as $knownAttribute) {
|
||||
if (is_a($attributeName, $knownAttribute, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
39
backend/vendor/symfony/serializer/Mapping/Loader/FileLoader.php
vendored
Normal file
39
backend/vendor/symfony/serializer/Mapping/Loader/FileLoader.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\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
|
||||
{
|
||||
/**
|
||||
* @param string $file The mapping file to load
|
||||
*
|
||||
* @throws MappingException if the mapping file does not exist or is not readable
|
||||
*/
|
||||
public function __construct(
|
||||
protected string $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));
|
||||
}
|
||||
}
|
||||
}
|
||||
64
backend/vendor/symfony/serializer/Mapping/Loader/LoaderChain.php
vendored
Normal file
64
backend/vendor/symfony/serializer/Mapping/Loader/LoaderChain.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\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
|
||||
{
|
||||
/**
|
||||
* 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(private readonly array $loaders)
|
||||
{
|
||||
foreach ($loaders as $loader) {
|
||||
if (!$loader instanceof LoaderInterface) {
|
||||
throw new MappingException(\sprintf('Class "%s" is expected to implement LoaderInterface.', get_debug_type($loader)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function loadClassMetadata(ClassMetadataInterface $metadata): bool
|
||||
{
|
||||
$success = false;
|
||||
|
||||
foreach ($this->loaders as $loader) {
|
||||
$success = $loader->loadClassMetadata($metadata) || $success;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoaderInterface[]
|
||||
*/
|
||||
public function getLoaders(): array
|
||||
{
|
||||
return $this->loaders;
|
||||
}
|
||||
}
|
||||
24
backend/vendor/symfony/serializer/Mapping/Loader/LoaderInterface.php
vendored
Normal file
24
backend/vendor/symfony/serializer/Mapping/Loader/LoaderInterface.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\Mapping\Loader;
|
||||
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
|
||||
/**
|
||||
* Loads {@link ClassMetadataInterface}.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
interface LoaderInterface
|
||||
{
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool;
|
||||
}
|
||||
186
backend/vendor/symfony/serializer/Mapping/Loader/XmlFileLoader.php
vendored
Normal file
186
backend/vendor/symfony/serializer/Mapping/Loader/XmlFileLoader.php
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
<?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\PropertyAccess\Exception\InvalidPropertyPathException;
|
||||
use Symfony\Component\PropertyAccess\PropertyPath;
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping;
|
||||
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 array<class-string, \SimpleXMLElement>|null
|
||||
*/
|
||||
private ?array $classes = null;
|
||||
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
|
||||
{
|
||||
if (!$this->classes ??= $this->getClassesFromXml()) {
|
||||
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']);
|
||||
}
|
||||
|
||||
if (isset($attribute['serialized-name'])) {
|
||||
$attributeMetadata->setSerializedName((string) $attribute['serialized-name']);
|
||||
}
|
||||
|
||||
if (isset($attribute['serialized-path'])) {
|
||||
try {
|
||||
$attributeMetadata->setSerializedPath(new PropertyPath((string) $attribute['serialized-path']));
|
||||
} catch (InvalidPropertyPathException) {
|
||||
throw new MappingException(\sprintf('The "serialized-path" value must be a valid property path for the attribute "%s" of the class "%s".', $attributeName, $classMetadata->getName()));
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($attribute['ignore'])) {
|
||||
$attributeMetadata->setIgnore(XmlUtils::phpize($attribute['ignore']));
|
||||
}
|
||||
|
||||
foreach ($attribute->context as $node) {
|
||||
$groups = (array) $node->group;
|
||||
$context = $this->parseContext($node->entry);
|
||||
$attributeMetadata->setNormalizationContextForGroups($context, $groups);
|
||||
$attributeMetadata->setDenormalizationContextForGroups($context, $groups);
|
||||
}
|
||||
|
||||
foreach ($attribute->normalization_context as $node) {
|
||||
$groups = (array) $node->group;
|
||||
$context = $this->parseContext($node->entry);
|
||||
$attributeMetadata->setNormalizationContextForGroups($context, $groups);
|
||||
}
|
||||
|
||||
foreach ($attribute->denormalization_context as $node) {
|
||||
$groups = (array) $node->group;
|
||||
$context = $this->parseContext($node->entry);
|
||||
$attributeMetadata->setDenormalizationContextForGroups($context, $groups);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($xml->{'discriminator-map'})) {
|
||||
$mapping = [];
|
||||
foreach ($xml->{'discriminator-map'}->mapping as $element) {
|
||||
$elementAttributes = $element->attributes();
|
||||
$mapping[(string) $elementAttributes->type] = (string) $elementAttributes->class;
|
||||
}
|
||||
|
||||
$classMetadata->setClassDiscriminatorMapping(new ClassDiscriminatorMapping(
|
||||
(string) $xml->{'discriminator-map'}->attributes()->{'type-property'},
|
||||
$mapping,
|
||||
$xml->{'discriminator-map'}->attributes()->{'default-type'} ?? null
|
||||
));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the names of the classes mapped in this file.
|
||||
*
|
||||
* @return class-string[]
|
||||
*/
|
||||
public function getMappedClasses(): array
|
||||
{
|
||||
return array_keys($this->classes ??= $this->getClassesFromXml());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an XML File.
|
||||
*
|
||||
* @throws MappingException
|
||||
*/
|
||||
private function parseFile(string $file): \SimpleXMLElement
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string, \SimpleXMLElement>
|
||||
*/
|
||||
private function getClassesFromXml(): array
|
||||
{
|
||||
$xml = $this->parseFile($this->file);
|
||||
$classes = [];
|
||||
|
||||
foreach ($xml->class as $class) {
|
||||
$classes[(string) $class['name']] = $class;
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
private function parseContext(\SimpleXMLElement $nodes): array
|
||||
{
|
||||
$context = [];
|
||||
|
||||
foreach ($nodes as $node) {
|
||||
if (\count($node) > 0) {
|
||||
if (\count($node->entry) > 0) {
|
||||
$value = $this->parseContext($node->entry);
|
||||
} else {
|
||||
$value = [];
|
||||
}
|
||||
} else {
|
||||
$value = XmlUtils::phpize($node);
|
||||
}
|
||||
|
||||
if (isset($node['name'])) {
|
||||
$context[(string) $node['name']] = $value;
|
||||
} else {
|
||||
$context[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $context;
|
||||
}
|
||||
}
|
||||
177
backend/vendor/symfony/serializer/Mapping/Loader/YamlFileLoader.php
vendored
Normal file
177
backend/vendor/symfony/serializer/Mapping/Loader/YamlFileLoader.php
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
<?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\PropertyAccess\Exception\InvalidPropertyPathException;
|
||||
use Symfony\Component\PropertyAccess\PropertyPath;
|
||||
use Symfony\Component\Serializer\Exception\MappingException;
|
||||
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
|
||||
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorMapping;
|
||||
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* YAML File Loader.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class YamlFileLoader extends FileLoader
|
||||
{
|
||||
private ?Parser $yamlParser = null;
|
||||
|
||||
/**
|
||||
* @var array<class-string, array>
|
||||
*/
|
||||
private ?array $classes = null;
|
||||
|
||||
public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
|
||||
{
|
||||
if (!$this->classes ??= $this->getClassesFromYaml()) {
|
||||
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']);
|
||||
}
|
||||
|
||||
if (isset($data['serialized_name'])) {
|
||||
if (!\is_string($data['serialized_name']) || '' === $data['serialized_name']) {
|
||||
throw new MappingException(\sprintf('The "serialized_name" value must be a non-empty string in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName()));
|
||||
}
|
||||
|
||||
$attributeMetadata->setSerializedName($data['serialized_name']);
|
||||
}
|
||||
|
||||
if (isset($data['serialized_path'])) {
|
||||
try {
|
||||
$attributeMetadata->setSerializedPath(new PropertyPath((string) $data['serialized_path']));
|
||||
} catch (InvalidPropertyPathException) {
|
||||
throw new MappingException(\sprintf('The "serialized_path" value must be a valid property path in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName()));
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data['ignore'])) {
|
||||
if (!\is_bool($data['ignore'])) {
|
||||
throw new MappingException(\sprintf('The "ignore" value must be a boolean in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName()));
|
||||
}
|
||||
|
||||
$attributeMetadata->setIgnore($data['ignore']);
|
||||
}
|
||||
|
||||
foreach ($data['contexts'] ?? [] as $line) {
|
||||
$groups = $line['groups'] ?? [];
|
||||
|
||||
if ($context = $line['context'] ?? false) {
|
||||
$attributeMetadata->setNormalizationContextForGroups($context, $groups);
|
||||
$attributeMetadata->setDenormalizationContextForGroups($context, $groups);
|
||||
}
|
||||
|
||||
if ($context = $line['normalization_context'] ?? false) {
|
||||
$attributeMetadata->setNormalizationContextForGroups($context, $groups);
|
||||
}
|
||||
|
||||
if ($context = $line['denormalization_context'] ?? false) {
|
||||
$attributeMetadata->setDenormalizationContextForGroups($context, $groups);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($yaml['discriminator_map'])) {
|
||||
if (!isset($yaml['discriminator_map']['type_property'])) {
|
||||
throw new MappingException(\sprintf('The "type_property" key must be set for the discriminator map of the class "%s" in "%s".', $classMetadata->getName(), $this->file));
|
||||
}
|
||||
|
||||
if (!isset($yaml['discriminator_map']['mapping'])) {
|
||||
throw new MappingException(\sprintf('The "mapping" key must be set for the discriminator map of the class "%s" in "%s".', $classMetadata->getName(), $this->file));
|
||||
}
|
||||
|
||||
$classMetadata->setClassDiscriminatorMapping(new ClassDiscriminatorMapping(
|
||||
$yaml['discriminator_map']['type_property'],
|
||||
$yaml['discriminator_map']['mapping'],
|
||||
$yaml['discriminator_map']['default_type'] ?? null
|
||||
));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the names of the classes mapped in this file.
|
||||
*
|
||||
* @return class-string[]
|
||||
*/
|
||||
public function getMappedClasses(): array
|
||||
{
|
||||
return array_keys($this->classes ??= $this->getClassesFromYaml());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string, array>
|
||||
*/
|
||||
private function getClassesFromYaml(): array
|
||||
{
|
||||
if (!stream_is_local($this->file)) {
|
||||
throw new MappingException(\sprintf('This is not a local file "%s".', $this->file));
|
||||
}
|
||||
|
||||
$this->yamlParser ??= new Parser();
|
||||
|
||||
$classes = $this->yamlParser->parseFile($this->file, Yaml::PARSE_CONSTANT);
|
||||
|
||||
if (!$classes) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!\is_array($classes)) {
|
||||
throw new MappingException(\sprintf('The file "%s" must contain a YAML array.', $this->file));
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?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, Samuel Roze
|
||||
|
||||
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:element name="discriminator-map" type="discriminator-map" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="discriminator-map">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="mapping" type="discriminator-map-mapping" maxOccurs="unbounded" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="type-property" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="default-type" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="discriminator-map-mapping">
|
||||
<xsd:attribute name="type" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="class" 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:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="group" type="xsd:string" maxOccurs="unbounded" />
|
||||
<xsd:element name="context" type="context" maxOccurs="unbounded" />
|
||||
<xsd:element name="normalization_context" type="context" maxOccurs="unbounded" />
|
||||
<xsd:element name="denormalization_context" type="context" maxOccurs="unbounded" />
|
||||
</xsd:choice>
|
||||
<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:attribute name="serialized-name">
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:minLength value="1" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="serialized-path">
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:minLength value="1" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="ignore" type="xsd:boolean" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="context">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="group" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="entry" type="context-root-entry" maxOccurs="unbounded" />
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="context-root-entry" mixed="true">
|
||||
<xsd:sequence minOccurs="0">
|
||||
<xsd:element name="entry" type="context-entry" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute type="xsd:string" name="name" use="required" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="context-entry" mixed="true">
|
||||
<xsd:sequence minOccurs="0">
|
||||
<xsd:element name="entry" type="context-entry" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute type="xsd:string" name="name" />
|
||||
</xsd:complexType>
|
||||
|
||||
</xsd:schema>
|
||||
418
backend/vendor/symfony/serializer/Mapping/Loader/schema/serialization.schema.json
vendored
Normal file
418
backend/vendor/symfony/serializer/Mapping/Loader/schema/serialization.schema.json
vendored
Normal file
@@ -0,0 +1,418 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Symfony Serializer Mapping Schema",
|
||||
"description": "JSON schema for Symfony's serialization mapping",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[A-Za-z0-9\\\\_]+$": {
|
||||
"type": "object",
|
||||
"description": "Class metadata configuration",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"attributes": {
|
||||
"type": "object",
|
||||
"description": "Attribute metadata configurations",
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"description": "Attribute metadata configuration",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"groups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Serialization groups for this attribute"
|
||||
},
|
||||
"max_depth": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Maximum serialization depth for this attribute"
|
||||
},
|
||||
"serialized_name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Custom name for serialization"
|
||||
},
|
||||
"serialized_path": {
|
||||
"type": "string",
|
||||
"description": "Property path for serialization (e.g., '[one][two]')"
|
||||
},
|
||||
"ignore": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to ignore this attribute during serialization"
|
||||
},
|
||||
"contexts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Context entry with optional groups",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"context": {
|
||||
"$ref": "#/definitions/contextObject"
|
||||
},
|
||||
"normalization_context": {
|
||||
"$ref": "#/definitions/contextObject"
|
||||
},
|
||||
"denormalization_context": {
|
||||
"$ref": "#/definitions/contextObject"
|
||||
},
|
||||
"groups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Groups this context applies to"
|
||||
}
|
||||
},
|
||||
"anyOf": [
|
||||
{
|
||||
"required": ["context"]
|
||||
},
|
||||
{
|
||||
"required": ["normalization_context"]
|
||||
},
|
||||
{
|
||||
"required": ["denormalization_context"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Context configurations for this attribute"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null",
|
||||
"description": "Empty attribute metadata"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"discriminator_map": {
|
||||
"type": "object",
|
||||
"description": "Class discriminator mapping configuration",
|
||||
"additionalProperties": false,
|
||||
"required": ["type_property", "mapping"],
|
||||
"properties": {
|
||||
"type_property": {
|
||||
"type": "string",
|
||||
"description": "Property name used to determine the class type"
|
||||
},
|
||||
"mapping": {
|
||||
"type": "object",
|
||||
"description": "Mapping from type values to class names",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"default_type": {
|
||||
"type": "string",
|
||||
"description": "Default type when no mapping is found"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"contextObject": {
|
||||
"type": "object",
|
||||
"description": "Context object with key-value pairs",
|
||||
"properties": {
|
||||
"circular_reference_limit": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "How many loops of circular reference to allow while normalizing"
|
||||
},
|
||||
"object_to_populate": {
|
||||
"type": "object",
|
||||
"description": "Object to be updated instead of creating a new instance"
|
||||
},
|
||||
"groups": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "Groups containing attributes to (de)normalize"
|
||||
},
|
||||
"attributes": {
|
||||
"type": "object",
|
||||
"description": "Attributes to (de)normalize"
|
||||
},
|
||||
"allow_extra_attributes": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to ignore extra attributes or throw an exception"
|
||||
},
|
||||
"default_constructor_arguments": {
|
||||
"type": "object",
|
||||
"description": "Hashmap of classes containing hashmaps of constructor argument => default value"
|
||||
},
|
||||
"callbacks": {
|
||||
"type": "object",
|
||||
"description": "Hashmap of field name => callable to normalize this field"
|
||||
},
|
||||
"circular_reference_handler": {
|
||||
"type": "object",
|
||||
"description": "Handler to call when a circular reference has been detected"
|
||||
},
|
||||
"ignored_attributes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Attributes to be skipped when normalizing an object tree"
|
||||
},
|
||||
"require_all_properties": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to require all properties to be listed in the input"
|
||||
},
|
||||
"enable_max_depth": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to respect the max depth metadata on fields"
|
||||
},
|
||||
"depth_key_pattern": {
|
||||
"type": "string",
|
||||
"description": "Pattern to keep track of the current depth (must contain exactly two string placeholders)"
|
||||
},
|
||||
"disable_type_enforcement": {
|
||||
"type": "boolean",
|
||||
"description": "Whether verifying types match during denormalization"
|
||||
},
|
||||
"skip_null_values": {
|
||||
"type": "boolean",
|
||||
"description": "Whether fields with the value null should be output during normalization"
|
||||
},
|
||||
"skip_uninitialized_values": {
|
||||
"type": "boolean",
|
||||
"description": "Whether uninitialized typed class properties should be excluded during normalization"
|
||||
},
|
||||
"max_depth_handler": {
|
||||
"type": "object",
|
||||
"description": "Callback to allow to set a value for an attribute when the max depth has been reached"
|
||||
},
|
||||
"exclude_from_cache_keys": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Context keys not relevant to determine which attributes to (de)normalize"
|
||||
},
|
||||
"deep_object_to_populate": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to tell the denormalizer to also populate existing objects on attributes"
|
||||
},
|
||||
"preserve_empty_objects": {
|
||||
"type": "boolean",
|
||||
"description": "Whether an empty object should be kept as an object or converted to a list"
|
||||
},
|
||||
"normalize_visibility": {
|
||||
"type": "integer",
|
||||
"description": "Whether fields should be output based on visibility (PropertyNormalizer)"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "Format of the date (DateTimeNormalizer)"
|
||||
},
|
||||
"timezone": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object"
|
||||
}
|
||||
],
|
||||
"description": "Timezone of the date (DateTimeNormalizer)"
|
||||
},
|
||||
"forceTimezone": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to enforce the timezone during denormalization (DateTimeNormalizer)"
|
||||
},
|
||||
"cast": {
|
||||
"enum": ["int", "float"],
|
||||
"description": "Cast type for DateTime (DateTimeNormalizer)"
|
||||
},
|
||||
"encode_options": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "json_encode flags bitmask (JsonEncoder)"
|
||||
},
|
||||
"decode_options": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "json_decode flags bitmask (JsonEncoder)"
|
||||
},
|
||||
"associative": {
|
||||
"type": "boolean",
|
||||
"description": "Whether decoded objects will be given as associative arrays (JsonEncoder)"
|
||||
},
|
||||
"recursion_depth": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "Maximum recursion depth (JsonEncoder)"
|
||||
},
|
||||
"as_collection": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the decoded result should be considered as a collection (XmlEncoder/CsvEncoder)"
|
||||
},
|
||||
"decoder_ignored_node_types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
},
|
||||
"description": "Node types to ignore while decoding (XmlEncoder)"
|
||||
},
|
||||
"encoder_ignored_node_types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
},
|
||||
"description": "Node types to ignore while encoding (XmlEncoder)"
|
||||
},
|
||||
"encoding": {
|
||||
"type": "string",
|
||||
"description": "DOMDocument encoding (XmlEncoder)"
|
||||
},
|
||||
"format_output": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to encode with indentation and extra space (XmlEncoder)"
|
||||
},
|
||||
"load_options": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "DOMDocument::loadXml options bitmask (XmlEncoder)"
|
||||
},
|
||||
"save_options": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "DOMDocument::saveXml options bitmask (XmlEncoder)"
|
||||
},
|
||||
"remove_empty_tags": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to keep empty nodes (XmlEncoder)"
|
||||
},
|
||||
"root_node_name": {
|
||||
"type": "string",
|
||||
"description": "Name of the root node (XmlEncoder)"
|
||||
},
|
||||
"standalone": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the document will be standalone (XmlEncoder)"
|
||||
},
|
||||
"type_cast_attributes": {
|
||||
"type": "boolean",
|
||||
"description": "Whether casting numeric string attributes to integers or floats (XmlEncoder)"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "Version number of the document (XmlEncoder)"
|
||||
},
|
||||
"cdata_wrapping": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to wrap strings within CDATA sections (XmlEncoder)"
|
||||
},
|
||||
"cdata_wrapping_pattern": {
|
||||
"type": "string",
|
||||
"description": "Pattern used to evaluate if a CDATA section should be added (XmlEncoder)"
|
||||
},
|
||||
"ignore_empty_attributes": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to ignore empty attributes (XmlEncoder)"
|
||||
},
|
||||
"preserve_numeric_keys": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to preserve numeric keys in array (XmlEncoder)"
|
||||
},
|
||||
"inline_threshold": {
|
||||
"type": "integer",
|
||||
"description": "Threshold to switch to inline YAML (YamlEncoder)"
|
||||
},
|
||||
"indent_level": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Indentation level (YamlEncoder)"
|
||||
},
|
||||
"flags": {
|
||||
"type": "integer",
|
||||
"description": "Yaml::dump flags bitmask (YamlEncoder)"
|
||||
},
|
||||
"preserved_empty_objects": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to preserve empty objects or convert them to null (YamlEncoder)"
|
||||
},
|
||||
"delimiter": {
|
||||
"type": "string",
|
||||
"maxLength": 1,
|
||||
"description": "Column delimiter character (CsvEncoder)"
|
||||
},
|
||||
"enclosure": {
|
||||
"type": "string",
|
||||
"maxLength": 1,
|
||||
"description": "Field enclosure character (CsvEncoder)"
|
||||
},
|
||||
"escape_char": {
|
||||
"type": "string",
|
||||
"maxLength": 1,
|
||||
"description": "Escape character (CsvEncoder, deprecated)"
|
||||
},
|
||||
"key_separator": {
|
||||
"type": "string",
|
||||
"description": "Key separator when (un)flattening arrays (CsvEncoder)"
|
||||
},
|
||||
"headers": {
|
||||
"type": "array",
|
||||
"description": "Headers (CsvEncoder)"
|
||||
},
|
||||
"escaped_formulas": {
|
||||
"type": "boolean",
|
||||
"description": "Whether formulas should be escaped (CsvEncoder)"
|
||||
},
|
||||
"no_headers": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the input/output is containing headers (CsvEncoder)"
|
||||
},
|
||||
"end_of_line": {
|
||||
"type": "string",
|
||||
"description": "End of line characters (CsvEncoder)"
|
||||
},
|
||||
"output_utf8_bom": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to add the UTF-8 Byte Order Mark (CsvEncoder)"
|
||||
}
|
||||
},
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user