Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable serializer for FOSUserBundle entities #78

Closed
ruudk opened this issue Feb 7, 2012 · 59 comments
Closed

Disable serializer for FOSUserBundle entities #78

ruudk opened this issue Feb 7, 2012 · 59 comments

Comments

@ruudk
Copy link
Contributor

ruudk commented Feb 7, 2012

I am using the FOSUserBundle and have my own entity extended of the FOSUserBundle Model.

In my user entity I want to serialize some things. But the rest should be excluded.

So I added @Serializer\ExclusionPolicy("all") but somehow all the UserBundle's properties are exposed.

In my cache directory I keep getting this file: serializer/FOS-UserBundle-Model-User.cache.php.

How can I get rid of this?

@mvrhov
Copy link
Contributor

mvrhov commented Feb 7, 2012

I had the same problem recently and there is a new section on overriding metadata in docs. I can tell you that this overriding won't work with annotations.

@ruudk
Copy link
Contributor Author

ruudk commented Feb 7, 2012

Thanks @mvrhov

Is there no fix for it?

/ping @schmittjoh

@ruudk
Copy link
Contributor Author

ruudk commented Feb 7, 2012

@mvrhov I moved my annotations to a YAML file. But I'm still getting the properties of the FOSUserBundle. How did you fix this?

@mvrhov
Copy link
Contributor

mvrhov commented Feb 7, 2012

Read Overriding Metadata section in docs.

@ruudk
Copy link
Contributor Author

ruudk commented Feb 7, 2012

Already did, but that doesn't work.. or I don't know how to do it...

@mvrhov
Copy link
Contributor

mvrhov commented Feb 7, 2012

From the top of my head...

jms_serializer:
    metadata:
        directories:
            FOSUB:
                namespace_prefix: FOS\UserBundle
                path: %kernel.root_dir%/serializer/FOSUB
# %kernel.root_dir%/serializer/FOSUB/Model.User.yml
FOS\UserBundle\Model\User:
    exclusion_policy: NONE
    properties:
        emailCanonical:
            exclude: true
        usernameCanonical:
            exclude: true

@schmittjoh
Copy link
Owner

You can still use annotations in your model, but obviously not for a model that is provided by a third-party where you can't change the code.

@ruudk
Copy link
Contributor Author

ruudk commented Feb 8, 2012

My UserEntity looks like this:

namespace Ruudk\UserBundle\Entity;
class User extends \FOS\UserBundle\Model\User

I annotate my User class with @ExclusionPolicy(all) so that everything is excluded by default.

I @expose a couple of properties in my own User class

And then all the inherited properties of the FOS User class will get exposed automatically... I think that is bad because I said in my User class to Exclude everything by default?

@ruudk
Copy link
Contributor Author

ruudk commented Feb 13, 2012

@schmittjoh Could this please be reopened?

@stof
Copy link
Contributor

stof commented Feb 13, 2012

@ruudk the solution has been posted by @mvrhov: #78 (comment)

@ruudk
Copy link
Contributor Author

ruudk commented Feb 13, 2012

Yes but that only works if I don't use annotations. But why isn't is possible to use annotations? When I put @ExclusionPolicyAll(all) on top of MY class then it should respect that for the inheritance of the FOSUser class too, right? Because the FOSUser class doesn't even have any Serializer annotations or what so ever.

@stof
Copy link
Contributor

stof commented Feb 13, 2012

@ruudk you can still use annotations for your own classes. You cannot use annotations for FOSUserBundle classes as adding them would require editing third party code.

@schmittjoh
Copy link
Owner

The exclusion policy only affects the class in which it is defined, not any parent entities.

@leek
Copy link

leek commented Mar 2, 2012

<?php
abstract class Parent {
    protected $property;
}

class Child extends Parent {
    /**
     * @Exclude
     */
    protected $property;
}

Doing this should work.
If the above code not working as expected is intended behavior, I believe this should be re-opened for discussion.

/cc @schmittjoh @stof

@JohnLoo
Copy link

JohnLoo commented Apr 4, 2012

Hello,
I am using the FOSUserBundle and I have an entity in my own bundle which extends the Model\User. I want to exclude all the attributes provided by the parent class. I tried the solution given by mvrhov but I have not manage to make it works. Whatever name has a file in serializer/FOSUB, It seems to have no effect.
Does the file need to have a specific name ? I have the following configuration (same as in the documentation) :

jms_serializer:
    metadata:
        directories:
            FOSUB:
                namespace_prefix: "FOS\\UserBundle"
                path: "%kernel.root_dir%/serializer/FOSUB"

and my file %kernel.root_dir%/serializer/FOSUB/Model.User.yml contains :

FOS\UserBundle\Model\User:
    exclusion_policy: ALL

Maybe someone can help me ?

@las94
Copy link

las94 commented Apr 6, 2012

You have to clear the cache !

@JohnLoo
Copy link

JohnLoo commented Apr 14, 2012

My bad, thanks :)

@wheelsandcogs
Copy link
Contributor

Just a quick note that might be obvious for some but had me scratching my head for a good while...

If you're using MongoDB with FOSUserBundle you still need to set this up on FOS\UserBundle\Model\User rather than FOS\UserBundle\Document\User because you can't influence parent classes as previously mentioned.

@hugomn
Copy link

hugomn commented May 24, 2013

+1 for this solution. Didn't know Overriding Third-Party Metadata section in documentation. Saved my day!

Thank you all! ;)

@ioleo
Copy link

ioleo commented Jan 4, 2014

Remember to use namespace_prefix: "FOS\\UserBundle" like in @JohnLoo comment, and NOT namespace_prefix: FOS\UserBundle! That mistake gave me a headache for a while!

@hugomn
Copy link

hugomn commented Jan 7, 2014

I was checking my code, and for some unknown reason, overriding metadata for FOSUserBundle is not working anymore. I was trying to discover what happened and I saw that Entity classes in FOSUserBundle was deprecated, acording to this commit: FriendsOfSymfony/FOSUserBundle@89be8e9.

My code is exactly this:

jms_serializer:
    metadata:
        directories:
            FOSUB:
                namespace_prefix: "FOS\\UserBundle"
                path: "%kernel.root_dir%/serializer/FOSUB"

And my file %kernel.root_dir%/serializer/FOSUB/Model.User.yml

FOS\UserBundle\Model\User:
    exclusion_policy: ALL

Does anyone knows if I have to change something after this depraction in FOSUseBundle? I've tried to point config fo FOS\UserBundle\Model, but it didn't work also. @schmittjoh any ideia?

@ioleo
Copy link

ioleo commented Jan 7, 2014

@hugomn did you clear your cache?

@hugomn
Copy link

hugomn commented Jan 7, 2014

Yes, a lot of times. And I've tried a lot of combinations for namespace_prefix: "FOS\\UserBundle"configuration. Is anyone else having the same problem? Thanks!

@schmittjoh
Copy link
Owner

I've been thinking about adding something to the Symfony profiler which lists the location where metadata was loaded from. If someone has time to contribute something.

@hugomn
Copy link

hugomn commented Jan 7, 2014

@schmittjoh I can try it, I'm just not so familiar with JMSSerializerBundle. The metadata for each directory is loaded in the file JMSSerializerExtension, right?

@schmittjoh
Copy link
Owner

We need to add the location from where the metadata was loaded by the drivers to the ClassMetadata (this needs to be done in schmittjoh/serializer and schmittjoh/metadata) and then add a data collector for the Symfony profiler to this bundle.

@hugomn
Copy link

hugomn commented Jan 7, 2014

@schmittjoh sorry, I don't know how to do it... =/

@schmittjoh
Copy link
Owner

No worries, maybe someone else comes along and can help :)

On Tue, Jan 7, 2014 at 9:48 PM, Hugo Magalhães notifications@github.comwrote:

@schmittjoh https://github.com/schmittjoh sorry, I don't know how to do
it... =/


Reply to this email directly or view it on GitHubhttps://github.com//issues/78#issuecomment-31777656
.

@adetwiler
Copy link

@hugomn I am also seeing something similar to you

I am not able to exclude anything anymore from FOSUserBundle. My user entity extends the FOSUserBundle User Model, and neither the expose rules in the annotations, or the serializer\Entity.User.yml are working.

I tried it out on an entity not related to FOSUser and it is working just fine. Not sure what would stop it from using these rules even when I extended their model and am using a separate Entity class.

@hugomn
Copy link

hugomn commented Jan 8, 2014

@stof I've just copied your configs and it didn't work. I'm thinking maybe its versions issues. Which version of FOSUserBundle and JMSSerializerBundle are you using? Thanks!

@stof
Copy link
Contributor

stof commented Jan 8, 2014

FOSUserBundle master branch (commit is FriendsOfSymfony/FOSUserBundle@c66cb66)
JMSSerializerBundle master (commit is bb15db3)
JMSSerializer master (commit is schmittjoh/serializer@cf70eea)
Metadata master (commit is schmittjoh/metadata@f44eefc)

@hugomn
Copy link

hugomn commented Jan 8, 2014

@stof even using all bundles in master still not working. How is you User class definition? Mine is like this:

<?php
namespace Acme\AppBundle\Entity;

use FOS\UserBundle\Model\User as BaseUser;
use FOS\UserBundle\Model\UserInterface;
use JMS\Serializer\Annotation\ExclusionPolicy;

/**
 * @ExclusionPolicy("all")
 */
class User extends BaseUser implements UserInterface {

// my code

}

@adetwiler
Copy link

@stof Those config changes worked for me, but only whenever I took out "duplicates" between the Model and my Entity. I tested by upgrading to dev-master of FOSUserBundle and it told me that username was duplicated.

I am using Symfony 2.4.1, JMSSerializerBundle 0.13.0 and FOSUserBundle 1.3.3.

However, if I stay on the versions above, all data except id is null:

"user": {
        "id": 3,
        "email": null,
        "enabled": null,

When I upgrade to FOSUserBundle dev-master I get the correct data

    "user": {
        "id": 3,
        "email": "andrew@detwiler.it",
        "enabled": true,

@stof
Copy link
Contributor

stof commented Jan 8, 2014

well, if you use 1.3.3, why are you extending from Model directly ? It looks to me that you followed the documentation of FOSUserBundle dev-master while using the 1.3.x version

@adetwiler
Copy link

@stoff I changed to extending the entity for 1.3.3 (updated config and my entity) and it doesn't seem to work anymore. I think I will stick to the dev-master version for now.

Thanks for the help!

@hpatoio
Copy link

hpatoio commented Mar 3, 2014

It works for me

# app/config/config.yml
jms_serializer:
    metadata:
        directories:
            FOSUserBundle:
                path: "%kernel.root_dir%/Resources/FOSUserBundle/serializer"
                namespace_prefix: "FOS\\UserBundle"
#app/Resources/FOSUserBundle/serializer/Model.User.yml
FOS\UserBundle\Model\User:
    exclusion_policy: ALL
    properties:
        id:
            expose: true
        email:
            expose: true
        enabled:
            expose: true
        locked:
            expose: true

Packages:

jms/metadata                         1.5.0              Class/method/property metadata management in PHP
jms/parser-lib                       1.0.0              A library for easily creating recursive-descent parsers.
jms/serializer                       0.15.0             Library for (de-)serializing data of any complexity; supports XML, JSON, and YAML.
jms/serializer-bundle                dev-master ca66cd3 Allows you to easily serialize, and deserialize data of any complexity
friendsofsymfony/user-bundle         dev-master 23d15ad Symfony FOSUserBundle

@enrike1983
Copy link

I still have the same problem. My conf:
"friendsofsymfony/user-bundle": "1.3.3"
"friendsofsymfony/rest-bundle": "dev-master"
"jms/serializer-bundle": "dev-master"

No way to make it work...

@james-bw
Copy link

I had this same problem. Then I found from http://stackoverflow.com/questions/12960141/jmsserializerbundle-no-control-over-third-party-meta-data that I was using the JMSSerializer method rather than the JMSSerializerBundle.

I used:

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

which doesn't work, but this does:

$serializer = $this->get('jms_serializer'); //JMSSerializerBundle

Hope this helps someone else.

@geoffreytran
Copy link

Running into this same issue now with

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

Used to work perfectly with older version.

RESOLVED:

I've located the issue down to a change in my yaml config.

Make sure namespace_prefix is using double quotes and not single quotes for those of you who may run into the same issue.

jms_serializer:
metadata:
directories:
FOSUB:
namespace_prefix: "FOS\UserBundle"
path: %kernel.root_dir%/serializer/FOSUB

@nept
Copy link

nept commented May 16, 2014

@james-bw Thank you for your answer!
I searched for more than three hours the problem and your solution worked perfectly :)

@PierrickMartos
Copy link

I had the same error as you, don't forget to specify the groups if you use serializerGroups.

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

hope this help

@nept
Copy link

nept commented Jul 11, 2014

Of course @PierrickMartos ! Thank you to specify this precision for future readers ;)

@cambot
Copy link

cambot commented Jul 22, 2014

Is there a technical reason why this bundle cannot support using an @exclude annotation on an inherited property? I'm working on a project that is not using yaml files to configure Entities and it would be much easier to use an annotation. If there is such a reason, then it should be documented to avoid confusion rather than simply dismissing attempts to use the bundle in this way.

@igormancos
Copy link

+1 @cambot
How you resolved the issue?

@cambot
Copy link

cambot commented Mar 9, 2015

@igorladela, the project I was working on ended up writing custom functions to provide arrays containing subsets of the entity fields. We were already doing this to provide several different views for a single entity, so it was an easy way for us to get around this issue too.

@skonsoft
Copy link

Solution as described in #78 Works after clearing the cache 👍

@smilesrg
Copy link

smilesrg commented Feb 1, 2016

@mvrhov @schmittjoh @skonsoft @PierrickMartos @geoffreytran @hpatoio @stof Tried all these solutions and they don't work. Even after clearing the cache. What reason could be?

My config is:

#app/config/config.yml
jms_serializer:
    metadata:
        directories:
            FOSUB:
                namespace_prefix: "FOS\\UserBundle"
                path: "%kernel.root_dir%/serializer/FOSUB"
#app/serializer/FOSUB/User.yml
FOS\UserBundle\Model\User:
    exclusion_policy: ALL
    properties:
        email:
            expose: true
            groups: [Registration, Profile, Default]
        # enabled:
        #     expose: true
        # locked:
        #     expose: true
<?php
//src/UserBundle/Entity/User.php
namespace UserBundle\Entity;

use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 */
class User extends BaseUser
{

@marijnz0r
Copy link

@smilesrg

My friend, you have to name your file as Model.User.yml

Before:

#app/serializer/FOSUB/User.yml
FOS\UserBundle\Model\User:
    exclusion_policy: ALL
    properties:
        email:
            expose: true
            groups: [Registration, Profile, Default]
        # enabled:
        #     expose: true
        # locked:
        #     expose: true

After:

#app/serializer/FOSUB/Model.User.yml
FOS\UserBundle\Model\User:
    exclusion_policy: ALL
    properties:
        email:
            expose: true
            groups: [Registration, Profile, Default]
        # enabled:
        #     expose: true
        # locked:
        #     expose: true

And then, of course, change the file name as well.

Let me know if this helped you.

@stof
Copy link
Contributor

stof commented Mar 17, 2016

the other solution if you want to keep the file name as User.yml is to change the namespace prefix in your config (to include the Model part there)

@Mortagus
Copy link

Mortagus commented Feb 3, 2017

Hello everybody,

I've got a very similar problem into my project.
The only difference is : I'm not using the FOSUB.

I'm working on an API and I need to exclude some fields from my entities when they are requested.
I'm using the FosRestBundle and I can't make my JMSSerializer annotations work !

I try to implement the solutions presented here, but nothing works.

Does somebody can help me ?

@bruno-ds
Copy link

Hello, I've spent a lot of time on these pitfalls, maybe the doc could have a tooltip to help prevent them :

  • if you have inheritance, you can only alter the serialisation of the fields owned by the class, not by its parents (see point 2 for overwriting the parents)
  • in case of third party redefinition : you can cascade the definitions and only overwrite the serialization of one entity, for the others, the serializer will fall back to the third party definition.
  • in the namespace_prefix config. you can aim to partial namespace, in this case, the serialization config file name must complete the lacking part, for example : for a class Foo\Bar\Baz\Toto\EntityName with namespace_prefix: "Foo\\Bar", the serialization config file name must be "Baz.Toto.EntityName.yml"
  • in the namespace_prefix use double quotes, and escape the backslashes

@mehdi-zarrin
Copy link

mehdi-zarrin commented Oct 1, 2018

Yes, a lot of times. And I've tried a lot of combinations for namespace_prefix: "FOS\\UserBundle"configuration. Is anyone else having the same problem? Thanks!

@hugomn I'm using SF4 and I have the same issue have you figure out your problem?

update:

I noticed that the issue was related to wrong way of calling the serializer:
instead of
$serializer = $this->get('jms_serializer');

I was doing :

       $serializerBuilder = SerializerBuilder::create();
       $serializerBuilder->setPropertyNamingStrategy(new \JMS\Serializer\Naming\IdenticalPropertyNamingStrategy());
        $serializer = $serializerBuilder->build();

now it's fixed.

@reskume
Copy link

reskume commented Jan 29, 2019

In addition to @bruno-ds comment, it may also be helpful to note that when overwriting third-party metadata, only files with the .yml extension are picked up. Files with .yaml seem to be ignored, at least for my setup...

@picks44
Copy link

picks44 commented Feb 18, 2019

Hi guys,

Since my upgrade to Symfony 3.4, I can't serialize the Fos/UserBundle/Model/User class attributes (username, email...). It was working fine in version 2.8 of Symfony...
I'm using v2.4.3 of JMSSerializer.

Here is my config

config.yml

# JmsSerializer Configuration
jms_serializer:
    metadata:
        auto_detection: true
        directories:
            FOSUB:
                namespace_prefix: "FOS\\UserBundle"
                path: "%kernel.root_dir%/serializer/FOSUB"

Model.User.yml (in app/serializer/FOSUB)

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

Now my API doesn't return me any attributes from the thrid-party class
Neither the property "username" nor one of the methods "getUsername()", "username()", "isUsername()", "hasUsername()", "__get()" exist and have public access in class "stdClass".

Any clue?

@goetas
Copy link
Collaborator

goetas commented Feb 18, 2019

@picks44
this looks related to symfony serializer of symfony forms... not to jms serializer

@picks44
Copy link

picks44 commented Feb 18, 2019

Hi @goetas, I don’t use the Symfony Serializer.... and it’s not related to a form. The API method is supposed to return the user info through a simple Doctrine findOneBy request.

@goetas
Copy link
Collaborator

goetas commented Feb 18, 2019 via email

@picks44
Copy link

picks44 commented Feb 18, 2019

Alright my bad, just some naughty cache in my test env...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests