Сериализация с аннотационными группами - PullRequest
0 голосов
/ 08 февраля 2019

Symfony v4.2

Я пытаюсь использовать нормализатор и сериализатор Symfony для преобразования моих сущностей в JSON.

Я следовал шаблону аннотаций Groups, потому что он звучит как наиболее интуитивныйи перспективный способ сделать это.

Согласно документам , нам нужно вручную создать экземпляр ClassMetadataFactory, чтобы загрузить AnnotationLoader.Я все еще использую ObjectNormalizer, который работал нормально до использования аннотаций.

Вот мой метод сериализации:

/**
 * @param bool $event Serialize all event fields (except references)
 * @param bool $meta Serialize referenced meta instance
 * @param bool $targets Serialize referenced target instances
 * @param bool $users Serialize referenced user instances
 * @param bool $videos Serialize referenced video instances
 * @param bool $photos Serialize referenced photo instances
 * @return string
 */
public function serialize($event = true, $meta = false, $targets = false, $users = false, $videos = false, $photos = false) {
    $serializingGroups = [];
    if ($event) {
        $serializingGroups[] = 'event';
    }
    if ($meta) {
        $serializingGroups[] = 'meta';
    }
    if ($targets) {
        $serializingGroups[] = "targets";
    }
    if ($users) {
        $serializingGroups[] = 'users';
    }
    if ($videos) {
        $serializingGroups[] = 'videos';
    }
    if ($photos) {
        $serializingGroups[] = 'photos';
    }

    $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
    $normalizer = new ObjectNormalizer($classMetadataFactory);
    $serializer = new Serializer([$normalizer], [new JsonEncoder()]);

    $data = $serializer->normalize($this, null, ['groups' => $serializingGroups]);
    return $serializer->serialize($data, 'json');
}

Эти группы существуют для ускорения сериализации, если мне не нужноассоциации должны быть сериализованы.

Теперь, когда я использую групповые аннотации, json выглядит следующим образом

"{"id":2,
"title":"test",
"description":"<p>&nbsp;test<\/p>",
"subscriptionPrice":"0.00",
"subscriptionUntil":[], // DATE  - WHY EMPTY ARRAY?
"start":[], // DATE  - WHY EMPTY ARRAY?
"end":[], // DATE  - WHY EMPTY ARRAY?
"allDay":false,
"creationDate":[], // DATE  - WHY EMPTY ARRAY?
"editDate":[], // DATE  - WHY EMPTY ARRAY?
"editable":true,
"startEditable":true,
"durationEditable":true,
"overlap":false,
"color":"#9EABAB",
"backgroundColor":"#9eabab",
"borderColor":"#9eabab",
"textColor":"#000000",
"isRecurring":true,
"meta":[], // ASSOCIATED ENTITY  - WHY EMPTY ARRAY?
"targets":[[]] // ASSOCIATED COLLECTION OF ENTITIES  - WHY EMPTY ARRAY?
}"

Почему это работает, когда я не использую аннотации?Почему даты и другие объекты являются пустыми массивами, когда я использую аннотации?

1 Ответ

0 голосов
/ 10 февраля 2019

Eureca!

Вот фрагмент кода из моего метода сериализации:

$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizer = new ObjectNormalizer($classMetadataFactory);
$serializer = new Serializer([
    // Add a Datetimenormalizer as the first normalizer in the list
    new DatetimeNormalizer(),
    $normalizer
], [new JsonEncoder()]);

return $serializer->serialize($this, 'json', [
    // $serializer->addCircularReferenceHandler() IS DEPRECATED
    // define the handler like this:
    ObjectNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($event) {
        return '/event/'.$event->id;
    }
    ,ObjectNormalizer::GROUPS => $serializingGroups
]);

Прежде всего, причина, по которой meta и targets не были сериализованы, заключалась в том, чтоУ меня был неправильный импорт в моих Meta и Target сущностях.Удостоверьтесь, что это: use Symfony\Component\Serializer\Annotation\Groups; ... так что ... да ... дальше.

Даты сериализовались, когда я закомментировал //,ObjectNormalizer::GROUPS => $serializingGroups.Так почему же они не сериализуются, когда группы не закомментированы?Я предполагаю, что класс DateTime не имеет аннотаций Groups, поэтому нормализатор никогда не смог получить ни один из атрибутов DateTime

. Это решается добавлением DatetimeNormalizer какпервый нормализатор в массиве: $serializer = new Serializer([new DatetimeNormalizer(),$normalizer])

Вот как мои сущности сериализуются правильно: D

...