JMSSerializerBundle. no control over third party meta data
Solution 1
I bet xxx\xxx\Entity\User:
refers to your own namespace and class.
If it is, it is the wrong way to do.
The rules must be applied to the class where the properties live.
Given the property you exposed in your configuration, I guess you're using FOSUserBundle
.
Therefore, you must apply your rules on FOS\UserBundle\Model\User
.
Then you need to add a JMSSerializer
config to indicate where the serializer metadata live for the given namespace.
It should look like:
jms_serializer:
metadata:
auto_detection: true
directories:
FOSUserBundle:
namespace_prefix: "FOS\\UserBundle"
path: "@YourUserBundle/Resources/config/serializer/fos"
In fos/
directory you should have Model.User.yml
With something like:
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]
Details:
When applying rules to the Serializer through metadata, the Serializer looks for the property which are declared inside the class which is defined in the Metadata.
Example:
class Foo {
protected $foo;
}
class Bar extends Foo {
protected $bar;
}
Your metadata will look like this:
Foo:
exclusion_policy: ALL
properties:
foo:
expose: true
Bar:
exclusion_policy: ALL
properties:
bar:
expose: true
THE EXAMPLE BELOW IS NOT THE CORRECT WAY TO DO
Bar:
exclusion_policy: ALL
properties:
foo:
expose: true
bar:
expose: true
if you do this, only the rules on the property bar
will be applied (and exposed).
Solution 2
I had this problem that I was getting the serializer in a wrong way. You need JMSSerializerBundle
and use the service for configuration to take effect.
So instead of:
//In controller we can use $this instead of $container
$serializer = $this->get('jms_serializer'); //JMSSerializerBundle
I used:
$serializer = SerializerBuilder::create()->build(); //JMSSerializer
Using the first way will load your configuration. Since I'm using Propel
, I needed to ignore all BaseObject
fields:
#app/config.yml
jms_serializer:
metadata:
auto_detection: true
directories:
Propel:
namespace_prefix: ""
path: "@MySupporterBundle/Resources/config/serializer"
Note that BaseObject
has no namespace and you need the following packages for this to work (bugged before metadata 1.2):
"jms/serializer": "0.12.*",
"jms/serializer-bundle" : "0.12.*@dev",
"jms/metadata" : "1.3.*",
So I made this file:
#My/SupporterBundle/Resources/config/serializer/BaseObject.yml
BaseObject:
exclusion_policy: ALL
and for specific objects(in Model namespace) you need files (with default namespace as My/OtherBundle):
My/OtherBundle/Resources/config/serializer/Model.om.BaseClass.yml My/OtherBundle/Resources/config/serializer/Model.Class.yml
Note: You need to clear cache when creating new serializer files
Related videos on Youtube
tolgap
Updated on June 04, 2022Comments
-
tolgap almost 2 years
I have two entities I wish to serialize with the JMSSerializerBundle. The
Music
Entity has a mapping-file withexclusion_policy: NONE
.The
Music
entity has a field of the entityUser
fromFOSUserBundle
. TheUser
entity has a mapping-file withexclusion_policy: ALL
with a few fields set toexpose: true
, so they will be serialized.The problem is, the
User
field gets fully serialized. It does not matter if I change the mapping-file of theUser
entity.This is how it looks:
#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
Why does it not refer to it's own mapping file? Or am I mistaken somewhere?
What have I tried thusfar
I have read the third party meta data documentation. It simply says to add a new directory in my serializer service. I have done that, but I have to extend the
FOS\UserBundle\Entity
class, and that also does not have access to the parent protected fields I'm trying to exclude. -
tolgap over 11 yearsSo I can remove the mapping for MyBundle/Entity/User which extends FOSUserBundle/Entity/User?
-
Boris Guéry over 11 yearswell, it depends, you need to remove it only if you're not trying to apply rules on property of your own. If you extended the User Model/Entity and added properties, you should keep it but include only the property which are defined your own
User
class. -
Boris Guéry over 11 years@tolgap yeah most likely for every modification you make to the metadata.
-
tolgap over 11 yearsLet me do your modifications, and if it works I'll accept it for my question.
-
Sean Quinn over 10 yearsSorry to raise the specter of this question and answer, but I'm noticing that
directories
andauto_detection
don't appear to work together. If I try to override the location where JMS looks for the third-party metadata, it won't apply it. But if I place that same metadata in the default/expected path and comment out the directory configuration injms_serializer
it does get applied. I'm assuming the two should work in tandem? -
Chris almost 9 yearsWhy couldnt this information just be included in the official docs.... took me to long to find this
-
Boris Guéry almost 9 years@Chris, feel free to make a PR ;)
-
lony over 8 yearsIf I use this, do I have to change all my annotations to yaml configurations as well?
-
Genar about 8 yearsI was having problems excluding properties from FOS\UserBundle\Model\User and finally I discovered you should define the properties as it is defined in User class. So $plainPassword and others should be defined in the yml using camelCase as well.