I use FosUserBundle and SonataUserBundle for my Symfony2 project.
I get confused now. I want to add fields for the entity User but it's not working. There is no update for the schema for example.
Here is my config :
AppKernel:
...
new FOS\UserBundle\FOSUserBundle(),
new Sonata\UserBundle\SonataUserBundle(),
new Application\Sonata\UserBundle\ApplicationSonataUserBundle('FOSUserBundle')
config.yml:
...
# FOSUserBundle Configuration
fos_user:
db_driver: orm # BDD type
firewall_name: main # firewall name
user_class: Application\Sonata\UserBundle\Entity\User # entity class defined
And the User entity with added fields, in app/Application/Sonata/userBundle/Entity/
namespace Application\Sonata\UserBundle\Entity;
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
/**
* This file has been generated by the Sonata EasyExtends bundle ( http://sonata- project.org/easy-extends )
*
* References :
* working with object : http://www.doctrine-project.org/projects/orm/2.0 /docs/reference/working-with-objects/en
*
* #author <yourname> <youremail>
*/
class User extends BaseUser
{
/**
* #var integer $id
*/
protected $id;
/**
* #var string
*/
protected $institution;
/**
* #var string
*/
protected $department;
/**
* #var string
*/
protected $city;
/**
* #var string
*/
protected $country;
/**
* Get id
*
* #return integer $id
*/
public function getId()
{
return $this->id;
}
/**
* #return string
*/
public function getInstitution()
{
return $this->institution;
}
/**
* #return string
*/
public function getDepartment()
{
return $this->department;
}
/**
* #return string
*/
public function getCity()
{
return $this->city;
}
/**
* #return string
*/
public function getCountry()
{
return $this->country;
}
}
In my database, table fos_user_user seems to be the table with user saved data.
Added fields (country, city...) are not created when calling "php app/console doctrine:schema:update --force". How to add fields to the user entity ? I'm lost in fosuserbundle and sonatauserbundle....
In fact, it appear that the way i use fos and sonata user bundles force me to use XML definition. So for example adding a field called "city" you have to add these lines :
User.php (in /app/Application/Sonata/UserBundle/Entity/) :
protected $city;
User.orm.xml (in /app/Application/Sonata/UserBundle/Ressource/config/doctrine/) :
<field name="city" column="city" type="text"/>
Maybe putting this in the documentation of the bundles would be interesting for newbies ;)
I found a better solution if you want use annotations.
Delete UserBundle/Resorces/config/doctrine folder and you can use annotations in your UserBundle/Entity folder
Related
I'm trying to add a field 'name' to my user and this is how I proceeded
namespace User\UserBundle\Controller;
use FOS\UserBundle\Controller\RegistrationController as BaseController;
class DefaultController extends BaseController
{
public function indexAction()
{
$response = parent::registerAction();
// ... do custom stuff
return $response;
}
And this is My userType
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder
->add('nom')
->add('prenom')
;
}
When I try to add,
{{ form_widget(form.name) }}
I get this error
Method "nom" for object "Symfony\Component\Form\FormView" does not exist in FOSUserBundle:Registration:register.html.twig at line
This is my user class
namespace User\UserBundle\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;
public function __construct()
{
parent::__construct();
// your own logic
}
/**
* #var string
*
* #ORM\Column(name="nom", type="string", length=255, nullable=true )
*/
private $nom;
/**
* #var string
*
* #ORM\Column(name="prenom", type="string", length=255, nullable=true )
*/
private $prenom;
/**
* Set nom
*
* #param string $nom
* #return User
*/
public function setNom($nom)
{
$this->nom = $nom;
return $this;
}
/**
* Get nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
/**
* Set prenom
*
* #param string $prenom
* #return User
*/
public function setPrenom($prenom)
{
$this->prenom = $prenom;
return $this;
}
/**
* Get prenom
*
* #return string
*/
public function getPrenom()
{
return $this->prenom;
}
}
This is what I have under app/config
enter image description here
What should I do more? Any suggestions please? i'm newly starter with FOSUserBundle. THanks
It looks like you're trying to add the nom and prenom fields to the registration form. So you need to override the FOSUserBundle registration form. Follow the guide at Overriding Default FOSUserBundle Forms which shows how to override any form.
Maybe this link will help you http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_forms.html
This is my config.yml
Do you write it all in config.yml ?
you need to write this code in config.yml:
fos_user:
db_driver: orm
firewall_name: main
user_class: User\UserBundle\Entity\User
registration:
form:
type: user_userbundle_user
and the remaining write in ./config/services.yml
services:
fos_user.doctrine_registry:
alias: doctrine
app.form.registration:
class: UserUserBundle\Form\UserType
tags:
- { name: form.type, alias: user_userbundle_user }
So I finally got it ! I added construct to my userType
public function __construct($class)
{
parent::__construct($class);
}
And this is my new services.yml
parameters:
user_user.registration.class: User\UserBundle\Entity\User
services:
user.form.user:
class: User\UserBundle\Form\UserType
arguments: [%user_user.registration.class%]
tags:
- { name: form.type, alias: user_userbundle_user }
And that's it I hope it helps someOne. Thanks everyone
I have a doctrine entity User and a document Address (stored in mongoDB). I want to set an one to many relation between them by userId property. (the user has many addresses)
My User Entity:
namespace BlaBla\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $firstName;
... and so on
My Address document:
namespace BlaBla\UserBundle\Document;
/**
* BlaBla\UserBundle\Document\Address
*/
class Address
{
/**
* #var MongoId $id
*/
protected $id;
/**
* #var string $firstName
*/
protected $firstName;
/**
* #var string $lastName
*/
protected $lastName;
/**
* #var int $userId
*/
protected $userId;
... and so on
My goal is to create the getUser() method for the Address object and the getAddresses() method for the User object.
I've decided to place the method getAddresses() to the doctrine UserRepository class and to inject there the necessary document manager to be able to access to the Address Document. I've overriden the constructor of the userRepository and passed to it the necessary document manager object.
Please, look to the UserRepository class:
<?php
namespace BlaBla\UserBundle\Repository;
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository
{
/**
* #var \Doctrine\ODM\MongoDB\DocumentManager
*/
private $_dm;
/**
* #param \Doctrine\ORM\EntityManager $dm
*/
public function __construct(\Doctrine\ORM\EntityManager $em, $dm) {
$metaData = new \Doctrine\ORM\Mapping\ClassMetadata('BlaBla\UserBundle\Entity\User');
parent::__construct($em, $metaData);
$this->_dm = $dm;
}
/**
* #param $user_id integer
* #return \BlaBla\UserBundle\Document\Address
*/
public function getAddress($user_id) {
$address = $this->_dm->getRepository('BlaBlaUserBundle:Address');
$rt = $address->findByUserId($user_id);
return $rt;
}
public function getAllUsers()
{
return $this->findAll();
}
}
After this I can access to the repository from my controller via:
$em = $this->getDoctrine()->getManager();
$dm = $this->get('doctrine_mongodb')->getManager();
$t = new \BlaBla\UserBundle\Repository\UserRepository($em, $dm);
var_dump($t->getAddress($id));
var_dump($t->getAllUsers());
Both methods work just fine, but now I can't access to the repository using shortcuts like:
$user = $this->getDoctrine()->getRepository('BlaBlaUserBundle:User');
I thought about making the Repository as service with something like this:
user.repository:
class: BlaBla\UserBundle\Repository\UserRepository
arguments: [#doctrine.orm.entity_manager, #doctrine.odm.mongo_db.document_manager]
in my services.yml file, but this only lets me to access the repository with:
$this->get('user.repository');
the default shortcuts doesn't work still.
Please help to find a correct solution for this problem.
Thanks.
Where did you specified the UserRepository? In your User.php with annotation ? Maybe that is the only thing what is missing.
But if you want to use entity and document repository, I advise you to use Doctrine extensions, specifically Reference.
I trying to create CRUD panel from FOSUserBundle but i have some troubles. I mean that i created User entity for FOS and made crud panel for this entity. Now when i trying to add new user i have error like below
Neither the property "expiresAt" nor one of the methods "getExpiresAt()", "isExpiresAt()", "hasExpiresAt()", "_get()" or "_call()" exist and have public access in class "Bn\UserBundle\Entity\User".
It's my first project so please understand when i will ask for simple function, some suggestion ? What is wrong ?
<?php
namespace Bn\UserBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* #ORM\Table(name="fos_user")
* #ORM\Entity
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* Get expiresAt
*
* #return \DateTime
*/
public function getExpiresAt()
{
return $this->expiresAt;
}
/**
* Get credentials_expire_at
*
* #return \DateTime
*/
public function getCredentialsExpireAt()
{
return $this->credentialsExpireAt;
}
public function __construct()
{
parent::__construct();
// your own logic
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Now is working but i don't know why i must declare again function for getter.
I believe this means you need to add public accessors setExpiresAt() and getExpiresAt() to your User entity.
You need only add getExpiresAt to your User.php class. FOSUserBundle\User doesn't have getter for this field, but Sensio generator creates views for all fields.
public function getExpiresAt()
{
return $this->expiresAt;
}
In Symfony2 you can work with multiple entity managers and use something like the code below:
$em = $this->get('doctrine')->getManager();
$em = $this->get('doctrine')->getManager('default');
$customerEm = $this->get('doctrine')->getManager('customer');
We can inject the default manager to any service by using:
"#doctrine.orm.entity_manager"
How can you inject non-default entity managers into services?
If your entity managers config name is non_default then you can reference it as #doctrine.orm.non_default_entity_manager
For those who are using Symfony 3+, use the console :
php bin/console debug:container
Then you should see many lines starting with : 'doctrine.orm.MY_CUSTOM_ENTITY_MANAGER_xxxxxxxxxx'
So if you want the entity manager corresponding to your custom entity manager, find the line :
'doctrine.orm.MY_CUSTOM_ENTITY_MANAGER_entity_manager'
You can insert it in your service arguments.
Hope it helps.
You should define your custom entity manager as a service:
services:
name_of_your_custom_manager:
class: %doctrine.orm.entity_manager.class%
factory_service: doctrine
factory_method: getEntityManager
arguments: ["name_of_your_custom_manager"]
Then, you can inject it in the same way as you do with every service:
#name_of_your_custom_manager
Edit:
Pay attention that factory method may differ between symfony's version (it could be getEntityManager or getManager)
Hello first of all create your manager, in my example I create the manager for my Item class that is in a CoreBundle:
<?php
// src/Sybio/Bundle/CoreBundle/Manager/ItemManager.php:
namespace Sybio\Bundle\CoreBundle\Manager;
use Sybio\Bundle\CoreBundle\Entity\Item;
class ItemManager
{
/**
* #var \Doctrine\ORM\EntityManager $em entity manager
*/
protected $em;
/**
* #var \Doctrine\ORM\EntityRepository $em repository
*/
protected $repository;
/**
* #var string $entityName
*/
protected $entityName;
/**
* Constructor
*
* #param EntityManager $em
* #param string $entityName
*
* #return void
*/
public function __construct(EntityManager $em, $entityName)
{
$this->em = $em;
$this->repository = $em->getRepository($entityName);
$this->entityName = $entityName;
}
/**
* Save a entity object
*
* #param Object $entity
*
* #return Object Entity
*/
public function save($entity)
{
$this->persistAndFlush($entity);
return $entity;
}
/**
* Remove a entity object
*
* #param Object $entity
*
* #return Object Entity
*/
public function remove($entity)
{
return $this->removeAndFlush($entity);
}
/**
* Persist object
*
* #param mixed $entity
*
* #return void
*/
protected function persistAndFlush($entity)
{
$this->em->persist($entity);
$this->em->flush();
}
/**
* Remove object
*
* #param mixed $entity entity to remove
*
* #return void
*/
protected function removeAndFlush($entity)
{
$this->em->remove($entity);
$this->em->flush();
}
/**
* Returns entity repository object
*
* #return EntityRepository
*/
public function getRepository()
{
return $this->repository;
}
/**
* Create a new object
*
* #return mixed
*/
public function createNewObject()
{
return new Item();
}
// Create your own methods to manage the object
}
If the manager structure is shared between multiple manager, you can create a BaseManager extended by all other managers !
Then register it in the services.yml (or xml) file of your bundle:
# src/Sybio/Bundle/CoreBundle/Resources/config/services.yml or xml !:
parameters:
# Managers _________________
sybio.item_manager.entity: SybioCoreBundle:Item
sybio.item_manager.class: Sybio\Bundle\CoreBundle\Manager\ItemManager
services:
# Managers _________________
sybio.item_manager:
class: %sybio.item_manager.class%
arguments: [#doctrine.orm.entity_manager, %sybio.item_manager.entity%]
That's it, you can now use it:
// Controller:
$im = $this->get('sybio.item_manager');
$item = $im->createNewObject();
$im->save($item);
You can then improve your manager, here I give an array of config parameters to my manager:
# src/Sybio/Bundle/CoreBundle/Resources/config/services.yml or xml !:
sybio.item_manager:
class: %sybio.item_manager.class%
arguments: [#doctrine.orm.entity_manager, %sybio.item_manager.entity%, {'item_removed_state': %item_removed_state%, 'item_unpublished_state': %item_unpublished_state%, 'item_published_state': %item_published_state%}]
// src/Sybio/Bundle/CoreBundle/Manager/ItemManager.php:
public function __construct(EntityManager $em, $entityName, $params = array()) {
// ...
$this->params = $params;
}
If you create a BaseManager, you can also create a usefull generic method to initialize an object:
// src/Sybio/Bundle/CoreBundle/Manager/BaseManager.php:
/**
* Create a new object
*
* #return mixed
*/
public function createNewObject()
{
$entityName = explode(":", $this->entityName);
$entityName = "Sybio\Bundle\CoreBundle\Entity\\".$entityName[1];
return new $entityName;
}
I've got a problem when I want to override the FOSUserBundle registration Form.
The deal is, in the User entity, some of the users can have a "Sponsor" (a sponsor is a ManyToOne to the same entity), to be more explicit, this is the User Entity :
<?php
namespace Diz\UserBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="users")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* create FK "sponsor_id" referenced to the id field on the same table
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(name="sponsor_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected $sponsor;
public function __construct()
{
// import FOSUserBundle properities ->
parent::__construct();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set sponsor
*
* #param Dizsurf\UserBundle\Entity\User $sponsor
*/
public function setSponsor(\Dizsurf\UserBundle\Entity\User $sponsor)
{
$this->sponsor = $sponsor;
}
/**
* Get sponsor
*
* #return Dizsurf\UserBundle\Entity\User
*/
public function getSponsor()
{
return $this->sponsor;
}
}
You see ?
Then, to override the RegistrationFormType, I've created one with the official help :
<?php
namespace Diz\UserBundle\Form\Type;
use Symfony\Component\Form\FormBuilder;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
class RegistrationFormType extends BaseType
{
public function buildForm(FormBuilder $builder, array $options)
{
parent::buildForm($builder, $options);
// add your custom field
$builder->add('sponsor', 'fos_user_username');
}
public function getName()
{
return 'diz_user_registration';
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Diz\UserBundle\Entity\User', // Ni de modifier la classe ici.
);
}
}
And that's all ! Look like to be pretty simple ! But...
To simply convert the username into a User Entity, FOS advice to use "fos_user_username" in the builder.
Ok for me, but when I test this form :
With a sponsor who does exist, I've got this error "Please enter a password". (of course I've entered the password twice..).
But when I submit a form with an user whose does not exist, the registration form was submitted with success !
Have I done something wrong ?
Thank you for your help ! ;-)
Dizda.
Fixed.
I've just upgraded symfony from 2.0.10 to 2.1 and the problem is not present anymore !