vendor/shopware/core/Framework/DataAbstractionLayer/FieldSerializer/CustomFieldsSerializer.php line 87
<?php declare(strict_types=1);namespace Shopware\Core\Framework\DataAbstractionLayer\FieldSerializer;use Shopware\Core\Framework\DataAbstractionLayer\DefinitionInstanceRegistry;use Shopware\Core\Framework\DataAbstractionLayer\Exception\InvalidSerializerFieldException;use Shopware\Core\Framework\DataAbstractionLayer\Field\CustomFields;use Shopware\Core\Framework\DataAbstractionLayer\Field\Field;use Shopware\Core\Framework\DataAbstractionLayer\Field\JsonField;use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\JsonUpdateCommand;use Shopware\Core\Framework\DataAbstractionLayer\Write\DataStack\KeyValuePair;use Shopware\Core\Framework\DataAbstractionLayer\Write\EntityExistence;use Shopware\Core\Framework\DataAbstractionLayer\Write\WriteParameterBag;use Shopware\Core\Framework\Log\Package;use Shopware\Core\Framework\Util\Json;use Shopware\Core\Framework\Uuid\Uuid;use Shopware\Core\System\CustomField\CustomFieldService;use Symfony\Component\Validator\Validator\ValidatorInterface;/*** @internal*/#[Package('core')]class CustomFieldsSerializer extends JsonFieldSerializer{public function __construct(DefinitionInstanceRegistry $definitionRegistry,ValidatorInterface $validator,private readonly CustomFieldService $attributeService) {parent::__construct($validator, $definitionRegistry);}public function encode(Field $field, EntityExistence $existence, KeyValuePair $data, WriteParameterBag $parameters): \Generator{if (!$field instanceof CustomFields) {throw new InvalidSerializerFieldException(CustomFields::class, $field);}$this->validateIfNeeded($field, $existence, $data, $parameters);$attributes = $data->getValue();if ($attributes === null) {yield $field->getStorageName() => null;return;}if (empty($attributes)) {yield $field->getStorageName() => '{}';return;}// set fields dynamically/** @var array<string, mixed> $attributes */$field->setPropertyMapping($this->getFields(array_keys($attributes)));$encoded = $this->validateMapping($field, $attributes, $parameters);if (empty($encoded)) {return;}if ($existence->exists()) {$this->extractJsonUpdate([$field->getStorageName() => $encoded], $existence, $parameters);return;}yield $field->getStorageName() => Json::encode($encoded);}/*** @return array<string, mixed>|object|null*/public function decode(Field $field, mixed $value): array|object|null{if (!$field instanceof CustomFields) {throw new InvalidSerializerFieldException(CustomFields::class, $field);}if ($value) {// set fields dynamically/** @var array<string> $attributes */$attributes = array_keys(json_decode((string) $value, true, 512, \JSON_THROW_ON_ERROR));$field->setPropertyMapping($this->getFields($attributes));}return parent::decode($field, $value);}/*** @param array<string> $attributeNames** @return array<Field>*/private function getFields(array $attributeNames): array{$fields = [];foreach ($attributeNames as $attributeName) {$fields[] = $this->attributeService->getCustomField($attributeName)?? new JsonField($attributeName, $attributeName);}return $fields;}/*** @param array<string, array<string, mixed>> $data*/private function extractJsonUpdate(array $data, EntityExistence $existence, WriteParameterBag $parameters): void{foreach ($data as $storageName => $attributes) {$entityName = $existence->getEntityName();if (!$entityName) {continue;}$definition = $this->definitionRegistry->getByEntityName($entityName);$pks = Uuid::fromHexToBytesList($existence->getPrimaryKey());$jsonUpdateCommand = new JsonUpdateCommand($definition,$storageName,$attributes,$pks,$existence,$parameters->getPath());$parameters->getCommandQueue()->add($jsonUpdateCommand->getDefinition(), $jsonUpdateCommand);}}}