Подтвердить что ты не робот

JMSSerializerBundle. отсутствие контроля над метаданными третьих сторон

У меня есть два объекта, которые я хочу сериализовать с помощью JMSSerializerBundle. Объект Music имеет файл сопоставления с exclusion_policy: NONE.

Объект Music имеет поле объекта User от FOSUserBundle. Объект User имеет файл-сопоставление с exclusion_policy: ALL с несколькими полями, установленными на expose: true, поэтому они будут сериализованы.

Проблема в том, что поле User полностью сериализуется. Не имеет значения, если я изменил файл-сопоставление объекта User.

Вот как это выглядит:

#My/Bundle/Resources/config/serializer/Entity.Music.yml
xxx\xxx\Entity\Music:
    exclusion_policy: NONE

#My/Bundle/Resources/config/serializer/Entity.User.yml
xxx\xxx\Entity\User:
    exclusion_policy: ALL
    properties:
        id:
            expose: true
        username:
            expose: true
        username_canonical:
            exclude: true
        email:
            exclude: true
        email_canonical:
            exclude: true
        enabled:
            exclude: true
        salt:
            exclude: true
        password:
            exclude: true
        last_login:
            exclude: true
        confirmation_token:
            exclude: true
        password_requested_at:
            exclude: true
        groups:
            exclude: true
        locked:
            exclude: true
        expired:
            exclude: true
        expires_at:
            exclude: true
        roles:
            expose: true
        credentials_expired:
            exclude: true
        credentials_expired_at:
            exclude: true

Почему он не ссылается на собственный файл сопоставления? Или я где-то ошибаюсь?

Что я пробовал, таким образом,

Я прочитал документацию сторонних метаданных. Он просто говорит, чтобы добавить новый каталог в мою службу serializer. Я сделал это, но мне нужно расширить класс FOS\UserBundle\Entity, а также не иметь доступа к родительским защищенным полям, которые я пытаюсь исключить.

4b9b3361

Ответ 1

Я ставлю, что xxx\xxx\Entity\User: относится к вашему собственному пространству имен и классу.

Если это так, это способ неправильный.

Правила должны применяться к классу, в котором живут свойства.

Учитывая свойство, которое вы выставили в своей конфигурации, я думаю, вы используете FOSUserBundle.

Следовательно, вы должны применять свои правила на FOS\UserBundle\Model\User.

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

Он должен выглядеть так:

jms_serializer:
  metadata:
    auto_detection: true
    directories:
      FOSUserBundle:
        namespace_prefix: "FOS\\UserBundle"
        path: "@YourUserBundle/Resources/config/serializer/fos"

В каталоге fos/ у вас должен быть Model.User.yml

С чем-то вроде:

FOS\UserBundle\Model\User:
  exclusion_policy: ALL
  properties:
    id:
      expose: true
      groups: [list, details]
    username:
      expose: true
      groups: [details]
    email:
      expose: true
      groups: [me]
    roles:
      expose: true
      groups: [details]

Подробнее:

При применении правил к Сериализатору через метаданные Сериализатор ищет свойство, которое объявлено внутри класса определено в метаданных.

Пример:

class Foo {
     protected $foo;
}

class Bar extends Foo {
     protected $bar;
}

Ваши метаданные будут выглядеть так:

Foo:
  exclusion_policy: ALL
  properties:
      foo: 
          expose: true

Bar:
  exclusion_policy: ALL
  properties:
      bar: 
          expose: true

ПРИМЕР НИЖЕ НЕ ПРАВИЛЬНЫЙ ПУТЬ ДЕЛАТЬ

Bar:
  exclusion_policy: ALL
  properties:
      foo: 
          expose: true
      bar: 
          expose: true

если вы сделаете это, будут применены (и выставлены) только правила свойства bar.

Ответ 2

У меня была эта проблема, что я получал сериализатор неправильно. Вам нужно JMSSerializerBundle и использовать сервис для конфигурации, чтобы вступить в силу.

Итак, вместо:

//In controller we can use $this instead of $container
$serializer = $this->get('jms_serializer'); //JMSSerializerBundle

Я использовал:

$serializer = SerializerBuilder::create()->build(); //JMSSerializer

Использование первого способа загрузит вашу конфигурацию. Поскольку я использую Propel, мне нужно было игнорировать все поля BaseObject:

#app/config.yml
jms_serializer:
metadata:
    auto_detection: true
    directories:
        Propel:
            namespace_prefix: ""
            path: "@MySupporterBundle/Resources/config/serializer"

Обратите внимание, что BaseObject не имеет пространства имен, и для этого вам нужны следующие пакеты (прослушиваются до метаданных 1.2):

        "jms/serializer": "0.12.*",
        "jms/serializer-bundle" : "0.12.*@dev",
        "jms/metadata" : "1.3.*",

Итак, я сделал этот файл:

#My/SupporterBundle/Resources/config/serializer/BaseObject.yml
BaseObject:
    exclusion_policy: ALL

а для конкретных объектов (в пространстве имен модели) нужны файлы (с пространством имен по умолчанию в виде My/OtherBundle):

Мой/OtherBundle/Ресурсы/конфигурации/сериализатору/Model.om.BaseClass.yml Мой/OtherBundle/Ресурсы/конфигурация/сериализатор/Model.Class.yml

Примечание: вам необходимо очистить кеш при создании новых файлов сериализатора