I want to expose only a few properties of my User class, using JMSSerializerBundle and FOSRestBundle.
It seems like the serializer bundle is not reading my configuration file.
My User class is in src/AppBundle/Entity/User and it extends the FOSUserBundle user class.
Here is my User class:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Component\Validator\Constraints as Assert;
/**
* User
*
* #ORM\Table(name="backoffice_user")
* #ORM\Entity(repositoryClass="AppBundle\Entity\Repository\UserRepository")
*/
class User extends BaseUser
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="lastname", type="string", length=70)
*/
private $lastname;
/**
* #var string
*
* #ORM\Column(name="firstname", type="string", length=70)
*/
private $firstname;
}
This is my app/config.yml file
jms_serializer:
metadata:
debug: true
auto_detection: true
And the yml mappgin file in src/AppBundle/Resources/config/serializer/Entity.User.yml :
AppBundle\Entity\User:
exclusion_policy: ALL
exclude: true
properties:
email:
exclude: true
expose: true
The file is not read (or at least not taken into account), because my API returns me all fields of my entity.
Am I forgetting something ?
Your mapping file is not loaded, because the serializer applies the rules to the class where the properties are defined. In your case - that is FOS\UserBundle\Model\User. What you need is to override the Third-Party Metadata - a brief sample can be seen in bundle's documentation
In your config.yml, jms_serializer should probably look like this:
jms_serializer:
metadata:
auto_detection: true
directories:
FOSUserBundle:
namespace_prefix: "FOS\\UserBundle"
path: "#AppBundle/Resources/config/serializer"
Inside directory serializer you should have a file named Model.User.yml with configuration like this:
FOS\UserBundle\Model\User:
exclusion_policy: ALL
# add your desired configuration below.
In JMSSerializer you need to have one file for each class of the hierarchy.
So, the exclusion policy only apply to properties id, lastname and firstname; for BaseUser it use the default rule, which is to include everything.
To override a configuration file from another bundle, you first need to setup the folder for the namespace in the configuration with:
jms_serializer:
metadata:
directories:
FOSUB:
namespace_prefix: "FOS\\UserBundle"
path: "%kernel.root_dir%/serializer/FOSUB"
And add the serializer config file in app/serializer/FOSUB/Model.User.yml. See the official docs for other configurations option.
Related
I am wondering if there is a way to change (or define inside) annotations in a child class inheriting a MappedSuperClass, for example, let say we have a class BaseUser (mappedsuperclass), a child class User :
<?php
...
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
...
/**
* #ORM\MappedSuperclass
*/
class BaseUser
{
/**
* #ORM\Column(name="firstname", type="string", length=100)
* #Serializer\SerializedName("First_Name")
* #Serializer\Expose
* #Serializer\Type("string")
* #Serializer\Groups({"Basic"})
*/
protected $firstName;
}
/**
* #ORM\Entity
*/
class User extends BaseUser
{
/**
* #ORM\Column(name="sign", type="string", length=50)
*/
private $sign;
}
What I would like to do is either defining the "Serializer" annotations from User class directly (but let the property firstName to be defined in the BaseUser class), OR, overriding the definition of Serialize from the User class.
I did not found anything about this topic, has someone already figured it out? Thanks
You can tell the JMS Serializer what to expose or not in your config.
app/config/config.yml:
jms_serializer:
metadata:
directories:
- { 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
username:
expose: true
enabled:
expose: true
locked:
expose: true
Source: https://github.com/schmittjoh/JMSSerializerBundle/issues/78#issuecomment-31831236
I have an issue when serializing a User instance with one additional field $name, which extends the base User from FOSUserBundle:
<?php
namespace AppBundle\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
/**
* User
*/
class User extends BaseUser
{
/**
* #var string
*/
private $name;
/**
* Set name
* #param string $name
* #return User
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
* #return string
*/
public function getName()
{
return $this->name;
}
}
To simplify, I need to expose only $salt field from User entity using JMSSerializerBundle
#AppBundle\Resources\config\serializer\Model.User.yml
FOS\UserBundle\Model\User:
exclusion_policy: all
properties:
salt:
expose: true
Here's the config for it:
#app\config\config.yml
jms_serializer:
metadata:
auto_detection: true
directories:
FOSUserBundle:
namespace_prefix: "FOS\\UserBundle"
path: "#AppBundle/Resources/config/serializer"
The issue is that the serializer exposes also $name field, which I don't want as I need only to have $salt exposed:
{
"salt": "abcdefg",
"name": "Admin"
}
I believe I need to tell the serializer to use a config for my AppBundle\Entity\User instead of the base user entity from FOSUserBundle, but I have no clue how to implement it.
This is how I solved the issue . I have a User.php class that
inherit from FOS\UserBundle\Model\User as BaseUser. I need control the serialization from both my BaseUser class and my User class.
Solution: you need 2 separated config file to control each class.
config.yml
#Serializer configuration
jms_serializer:
metadata:
directories:
AppBundle:
path: "#AppBundle/Resources/config/serializer"
FOSUB:
namespace_prefix: "FOS\\UserBundle"
path: "%kernel.root_dir%/serializer/FOSUB"
Model.User.yml
FOS\UserBundle\Model\User:
exclusion_policy: ALL
properties:
id:
expose: true
username:
expose: true
email:
expose: true
enabled:
expose: true
Entity.User.yml
AppBundle\Entity\User:
exclusion_policy: ALL
properties:
imageAvatar:
expose: true
updatedAt:
expose: true
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* #ORM\Table(name="usuario")
* #ORM\Entity(repositoryClass="DietaBundle\Repository\UserRepository")
*
*
*/
class User extends BaseUser
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255)
*
* #var string
*/
private $imageAvatar;
/**
* #ORM\Column(type="datetime")
*
* #var \DateTime
*/
private $updatedAt;
Clear the cache after each change in the configuration files.
cache:clear
It happens because you are using the exclusion_policy: all on the parent entity, instead of on the child entity, which still exposing all of it's properties.
you should switch to your bundle in the configuration (config.yml) under the jms_seriazlier:directories.
any-name:
namespace_prefix: "My\\FooBundle"
path: "#MyFooBundle/Resources/config/serializer"
now you could use the same configuration to expose only the desired property.
#AppBundle\Resources\config\serializer\Entity.User.yml
My\FooBundle\Entity\User:
exclusion_policy: all
properties:
salt:
expose: true
this my entity class
<?php
namespace Application\MainAppBundleBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Oryzone\Bundle\MediaStorageBundle\Entity\Media as BaseMedia;
/**
Application\MainAppBundleBundle\Entity\Media *
#ORM\Table(name="media")
#ORM\Entity() */
class Media extends BaseMedia
{
/**
* #ORM\Id
* #ORM\Column(name="id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* {#inheritDoc}
*/
public function getId()
{
return $this->id;
}
}
?>
when i execute "php app/console doctrine:update:schema --force" i get this message
nothing to update ...
help please
Resolved ✔
the problem: when I execute doctrine:schema:update, the update of the data base is based on the files in # MyBundle / Resources / config / doctrine / MyFiles.orm.yml since I created my entity Entity / media.php and I have not Media.orm.yml the media table will not be created, so I deleted all files * orm.yml and I execute php app / console doctrine.: schema: update and the table is created
#hourss2040
I think you can't combine .orm.yml and annotations in same Entity.
Try to switch auto mapping on like this:
doctrine:
orm:
auto_mapping: true
Or register your bundle mapping like this:
doctrine:
orm:
entity_managers:
default:
connection: default
mappings:
MainAppBundleBundle: ~
I would like to ask you how it si possible to implement the sortable repository for gedmo sortable extension into symfony 2. I am a little confused how to inject the EntityManager and ClassMetadata into the constructor and how the repository register correctly in services.yml and entity.
Here is the repository:
https://github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/Sortable/Entity/Repository/SortableRepository.php
Thank you very much!
I recommend you install the StofDoctrineExtensionsBundle
And you can enable the sortable behavior in your config file.
Example:
config.yml
stof_doctrine_extensions:
orm:
default:
sortable: true
Entity class
/**
* Acme\Bundle\ProjectBundle\Entity\Foo
*
* #ORM\Table
* #ORM\Entity(repositoryClass="Gedmo\Sortable\Entity\Repository\SortableRepository")
*/
class Foo
{
/**
* #var integer $position
*
* #Gedmo\SortablePosition
* #ORM\Column(name="position", type="integer")
*/
private $position;
}
Remember to subscribe GedmoListener on boot()
<?php
class AcmeBundle extends Bundle
{
$em = $this->container->get('doctrine.orm.default_entity_manager');
$evm = $em->geteventmanager();
$evm->addeventsubscriber(new \gedmo\sortable\sortablelistener);
}
I want to extend default user entity attributes. In database after extending FOSUserBundle with SonataUserBunle there are 2 tables for storing users: fos_user and fos_user_user. I want to extend fos_user
Here is app/AppKernel.php:
new Sonata\UserBundle\SonataUserBundle('FOSUserBundle'),
new Application\Sonata\UserBundle\ApplicationSonataUserBundle(),
in app/config.yml file I set:
fos_user:
db_driver: orm<br>
firewall_name: main<br>
user_class: Acme\DemoBundle\Entity\User<br>
group:<br>
group_class: Application\Sonata\UserBundle\Entity\Group<br>
sonata_user:
security_acl: true
class:
user: Acme\DemoBundle\Entity\User
admin:
user:
class: Acme\DemoBundle\Admin\UserAdmin
parameters:
sonata.user.admin.user.class: Blogger\BlogBundle\Admin\UserAdmin
sonata.user.admin.user.entity: Blogger\BlogBundle\Entity\User
doctrine:
orm:
auto_mapping: auto
SonataUserBundle is created in src/Application/Sonata/UserBundle
To override SonataUserBundle, i extended UserAdmin by creating another UserAdmin class in src/Acme/DemoBundle/Admin/UserAdmin and all works fine
Now I want to extend User entity (fos_user table) to add new attributes.
Here is my Acme/Demo/Entity/User.php that I want to extend the default User entity
namespace Acme\DemoBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/*
* #ORM\Column(type="string", name="newAttribute")
*/
protected $newAttribute;
public function __construct()
{
parent::__construct();
// your own logic
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
What should I do to extend default fos_user table with php app/console doctrine:generate:entities Acme/DemoBundle
I've read many posts about this issue but none of the solutions helped me. I tried to extend Model class instead of Entity class but also nothing changed
You don't have to.
new Sonata\UserBundle\SonataUserBundle('FOSUserBundle')
Here your are telling the SonataUserBundle to use the FOSUserBundle as well.
Then in your User entity you set:
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="User")
*/
class User extends BaseUser
Because you have said to the SonataUserBundle "use the fosuserbundle" and you extend from the sonata user bundle user entity he's gonna "merge" those 2 models into 1 and add your custom fields from in your user entity as well.