web-dev-qa-db-ja.com

JMSSerializerBundle。サードパーティのメタデータを制御できません

JMSSerializerBundleでシリアル化したいエンティティが2つあります。 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

独自のマッピングファイルを参照しないのはなぜですか?それとも私はどこかで間違っていますか?

これまでに何を試しましたか

サードパーティのメタデータドキュメントを読みました。シリアライザーサービスに新しいディレクトリを追加するように指示するだけです。私はそれを実行しましたが、FOS\UserBundle\Entityクラスを拡張する必要があり、除外しようとしている親保護フィールドにもアクセスできません。

25
tolgap

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]

詳細:

メタデータを介してSerializerにルールを適用する場合、Serializerは、メタデータ内のdefinedであるクラス内でdeclaredであるプロパティを検索します。

例:

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

以下の例IS正しい方法ではありません

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

これを行うと、プロパティbarのルールのみが適用(および公開)されます。

66
Boris Guéry

シリアライザーを間違った方法で取得していたというこの問題がありました。 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)。

My/OtherBundle/Resources/config/serializer/Model.om.BaseClass.yml My/OtherBundle/Resources/config/serializer/Model.Class.yml

注:新しいシリアライザーファイルを作成するときは、キャッシュをクリアする必要があります

4
zebra