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
, а также не иметь доступа к родительским защищенным полям, которые я пытаюсь исключить.
Ответы
Ответ 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
Примечание: вам необходимо очистить кеш при создании новых файлов сериализатора