Як створити вашого власного користувацького будівника контексту

Дата оновлення перекладу 2024-06-03

Як створити вашого власного користувацького будівника контексту

Компнент Serializer використовує Нормалізатори та Кодувальники, щоб перетворювати будь-які дані на будь-які структури даних (наприклад, JSON). Такий процес серіалізації може бути сконфігурований завдяки контексту серіалізації , який може бути побудований завдяки будівникам контексту .

Кожний вбудований нормалізатор/кодувальник повʼязаний з будівником контексту. Однак, ви можете захотіти створити користувацький будівник контексту для ваших користувацьких нормалізаторів.

Створення нового будівника контексту

Уявімо, що ви хочете обробити денормалізацію дати по-іншому, якщо вона походить з успадкованої системи, шляхом перетворення дат на null, якщо серіалізоване значення - 0000-00-00. Щоб зробити це, вам спершу буде потрібно створити ваш нормалізатор:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// src/Serializer/ZeroDateTimeDenormalizer.php
namespace App\Serializer;

use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

final class ZeroDateTimeDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface
{
    use DenormalizerAwareTrait;

    public function denormalize($data, string $type, string $format = null, array $context = []): mixed
    {
        if ('0000-00-00' === $data) {
            return null;
        }

        unset($context['zero_datetime_to_null']);

        return $this->denormalizer->denormalize($data, $type, $format, $context);
    }

    public function supportsDenormalization($data, string $type, string $format = null, array $context = []): bool
    {
        return true === ($context['zero_datetime_to_null'] ?? false)
            && is_a($type, \DateTimeInterface::class, true);
    }
}

Тепер ви можете перетворити дати з нулями на null під час денормалізації:

1
2
$legacyData = '{"updatedAt": "0000-00-00"}';
$serializer->deserialize($legacyData, MyModel::class, 'json', ['zero_datetime_to_null' => true]);

Тепер, щоб уникнути необхідності памʼятати про цей конкретний ключ контексту zero_date_to_null, ви можете створити відповідний будівник контексту:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// src/Serializer/LegacyContextBuilder
namespace App\Serializer;

use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\ContextBuilderTrait;

final class LegacyContextBuilder implements ContextBuilderInterface
{
    use ContextBuilderTrait;

    public function withLegacyDates(bool $legacy): static
    {
        return $this->with('zero_datetime_to_null', $legacy);
    }
}

І, нарешті, використати його для побудови контексту серіалізації:

1
2
3
4
5
6
7
$legacyData = '{"updatedAt": "0000-00-00"}';

$context = (new LegacyContextBuilder())
    ->withLegacyDates(true)
    ->toArray();

$serializer->deserialize($legacyData, MyModel::class, 'json', $context);