Add fields for Sonata UserBundle - php

I have a question about extending Sonata UserBundle entity. I need to add more fields to the entity.
Firstly, I extended Sonata UserBundle to my project on the folder src\Application\Sonata\UserBundle
Then I tried to add these fields on the User Entity available on the same folder:
<?php
namespace App\Application\Sonata\UserBundle\Entity;
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
/**
* This file has been generated by the SonataEasyExtendsBundle.
*
* #link https://sonata-project.org/easy-extends
*
* References:
* #link http://www.doctrine-project.org/projects/orm/2.0/docs/reference/working-with-objects/en
*/
class User extends BaseUser
{
/**
* #var int $id
*/
protected $id;
/**
* Get id.
*
* #return int $id
*/
public function getId()
{
return $this->id;
}
/**
* #var string
* #ORM\Column(type="string")
*/
protected $accountType;
/**
* #var int
* #ORM\ManyToOne(targetEntity="App\Entity\Specialty")
*/
protected $specialty;
/**
* Get AccountType
* #return string
*/
public function getAccountType()
{
return $this->accountType;
}
/**
* Set AccountType
* #param string $accountType
* #return $this
*/
public function setAccountType($accountType)
{
$this->accountType = $accountType;
return $this;
}
/**
* Get Specialty
* #return int
*/
public function getSpecialty()
{
return $this->specialty;
}
/**
* Set Specialty
* #param int $specialty
* #return Specialty
*/
public function setSpecialty($specialty)
{
$this->specialty = $specialty;
return $this;
}
}
On the fos_user.yml I mapped this entity. But when I try to update my schema, by running this command:
php bin/console doctrine:s:u --force
I have a message that states that Nothing to update - your database is already in sync with the current entity metadata.
The added field isn't added on my table. I'm not an expert on Symfony, so I tried to explain my situation as possible as I can.
Specialty entity:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="specialties")
* #ORM\Entity
*/
class Specialty
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Icon")
*/
private $icon;
/**
* #ORM\Column(type="boolean")
*/
private $status;
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
/**
* Get string
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set name
* #param string $name
* #return Specialty
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* #return mixed
*/
public function getIcon()
{
return $this->icon;
}
/**
* #param mixed $icon
* #return $this
*/
public function setIcon($icon)
{
$this->icon = $icon;
return $this;
}
public function getStatus()
{
return $this->status;
}
public function setStatus($status)
{
$this->status = $status;
return $this;
}
public function __toString()
{
return $this->getId() ? (string) $this->getName() : '-';
}
}

Did you run php bin/console make:migration after adjusting the Entity?
php bin/console make:entity (create or update the Entity)
If you prefer to add new properties manually, the make:entity command can generate the getter & setter methods for you: php bin/console make:entity --regenerate
php bin/console make:migration
inspect src/Migrations/ folder
run the migrations php bin/console doctrine:migrations:migrate
read

Related

Symfony and Doctrine - getDoctrine not found

I am trying to build a simple app
I have a database with a table "matches"the table structure
and i wrote this code as Entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="matches")
*/
class Match
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="text", length=512)
*/
private $descr;
/**
* #ORM\Column(type="string", length=255)
*/
private $team_a;
/**
* #ORM\Column(type="string", length=255)
*/
private $team_b;
/**
* #ORM\Column(type="string", length=255)
*/
private $location;
/**
* #ORM\Column(type="datetime")
*/
private $datetime;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set descr
*
* #param string $descr
*
* #return Match
*/
public function setDescr($descr)
{
$this->descr = $descr;
return $this;
}
/**
* Get descr
*
* #return string
*/
public function getDescr()
{
return $this->descr;
}
/**
* Set teamA
*
* #param string $teamA
*
* #return Match
*/
public function setTeamA($teamA)
{
$this->team_a = $teamA;
return $this;
}
/**
* Get teamA
*
* #return string
*/
public function getTeamA()
{
return $this->team_a;
}
/**
* Set teamB
*
* #param string $teamB
*
* #return Match
*/
public function setTeamB($teamB)
{
$this->team_b = $teamB;
return $this;
}
/**
* Get teamB
*
* #return string
*/
public function getTeamB()
{
return $this->team_b;
}
/**
* Set location
*
* #param string $location
*
* #return Match
*/
public function setLocation($location)
{
$this->location = $location;
return $this;
}
/**
* Get location
*
* #return string
*/
public function getLocation()
{
return $this->location;
}
/**
* Set datetime
*
* #param \DateTime $datetime
*
* #return Match
*/
public function setDatetime($datetime)
{
$this->datetime = $datetime;
return $this;
}
/**
* Get datetime
*
* #return \DateTime
*/
public function getDatetime()
{
return $this->datetime;
}
}
and this as controller:
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\Match;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
class AddMatch
{
/**
* #Route("/addmatch")
*/
public function createAction()
{
$match = new Match();
$match->setDescr('Descrizione Partita');
$match->setTeamA('Squadra A');
$match->setTeamB('Squadra B');
$match->setLocation('a nice Gym');
$match->setLocation('12/12/2012');
$em = $this->getDoctrine()->getManager();
// tells Doctrine you want to (eventually) save the Product (no queries yet)
$em->persist($match);
// actually executes the queries (i.e. the INSERT query)
$em->flush();
return new Response('Saved new match with id '.$match->getId());
}
}
but it dosent work and I get Not Found
What am I missing?
I am super n00b :(
thanks for your help
You have to extend the base symfony controller:
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class AddMatch extends Controller
{
...
}
If, for some reason, you can't extend a controller, you still can use Doctrine entity manager. In that case you need to inject the service container and then get the entity manager with
$container->get('doctrine')->getManager();
You should thoroughly read the Symfony guide on Service Container.

Foreign key on composite primary key not working

I have an entity that references another entity with a composite primary key.
I'm simply doing a ManyToOne relationship. Each company can have many trades. Each company is part of some Stock Exchange and its unique identifier is both the Stock Exchange they're listed on and their stock symbol.
The error that I get when I try to update the schema is:
Column name ``id`` referenced for relation from Application\Entity\Trade towards Application\Entity\Company does not exist.
I think it's trying to default to id on the company. Is there any way to specify multiple foreign keys for the primary key on one table?
<?php
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="trade")
*/
class Trade
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(name="id",type="integer")
*/
protected $id;
/**
* #ORM\Column(type="integer")
*/
protected $price;
/**
* #ORM\Column(type="integer")
*/
protected $size;
/**
* #ORM\Column(type="datetime")
*/
protected $dateTime;
/**
* #ORM\ManyToOne(targetEntity="Application\Entity\Company", inversedBy="trade")
*/
protected $company;
/**
* #return mixed
*/
public function getPrice()
{
return $this->price;
}
/**
* #param mixed $price
*/
public function setPrice($price)
{
$this->price = $price;
}
/**
* #return mixed
*/
public function getSize()
{
return $this->size;
}
/**
* #param mixed $size
*/
public function setSize($size)
{
$this->size = $size;
}
/**
* #return mixed
*/
public function getDateTime()
{
return $this->dateTime;
}
/**
* #param mixed $dateTime
*/
public function setDateTime($dateTime)
{
$this->dateTime = $dateTime;
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return mixed
*/
public function getCompany()
{
return $this->company;
}
/**
* #param mixed $company
*/
public function setCompany($company)
{
$this->company = $company;
}
}
Here's the company entity if that helps
<?php
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="company")
*/
class Company
{
/**
* #ORM\Id
* #ORM\Column(length=5)
*/
protected $symbol;
/**
* #ORM\Id #ORM\ManyToOne(targetEntity="\Application\Entity\Exchange", inversedBy="company")
* #ORM\JoinColumn(name="exchangeKey", referencedColumnName="exchangeKey")
*/
protected $exchange;
/**
* #return mixed
*/
public function getSymbol()
{
return $this->symbol;
}
/**
* #param mixed $symbol
*/
public function setSymbol($symbol)
{
$this->symbol = $symbol;
}
/**
* #return mixed
*/
public function getExchange()
{
return $this->exchange;
}
/**
* #param mixed $exchange
*/
public function setExchange($exchange)
{
$this->exchange = $exchange;
}
}
You should be able to reference multiple columns using the #ORM\JoinColumns annotation. Inside you can define one or more #ORM\JoinColumn annotations.
For example
/**
* #ORM\ManyToOne(targetEntity="Application\Entity\Company", inversedBy="trade")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="symbol", referencedColumnName="symbol"),
* #ORM\JoinColumn(name="exchange", referencedColumnName="exchangeKey")
* });
*/
protected $company;
I was going to link to the documentation, however all I can find is this.
An array of #JoinColumn annotations for a #ManyToOne or #OneToOne relation with an entity that has multiple identifiers.

Doctrine + Zend Framework 2: Insert array of data in a many to many relationship

I have an application with Zend Framework2 and Doctrine2 as ORM.
I have this Entity called User:
namespace Adm\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="user")
*/
class User{
/**
* #ORM\Id
* #ORM\Column(type="integer");
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string")
*/
protected $name;
/**
* #ORM\Column(type="string")
*/
protected $email;
/**
* #ORM\Column(type="string")
*/
protected $password;
/**
* #ORM\ManyToMany(targetEntity="Module")
* #ORM\JoinTable(
* name="user_module",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="module_id", referencedColumnName="id")}
* )
*/
protected $modules;
public function __construct() {
$this->modules = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #return the $id
*/
public function getId() {
return $this->id;
}
/**
* #return the $name
*/
public function getName() {
return $this->name;
}
/**
* #return the $email
*/
public function getEmail() {
return $this->email;
}
/**
* #return the $password
*/
public function getPassword() {
return $this->password;
}
/**
* #param field_type $id
*/
public function setId($id) {
$this->id = $id;
}
/**
* #param field_type $name
*/
public function setName($name) {
$this->name = $name;
}
/**
* #param field_type $email
*/
public function setEmail($email) {
$this->email = $email;
}
/**
* #param field_type $password
*/
public function setPassword($password) {
$this->password = $password;
}
/**
* Add module
*
* #param dm\Entity\Module
* #return User
*/
public function addModules(Module $modules = null){
$this->modules[] = $modules;
}
/**
* Get modules
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getModules(){
return $this->modules;
}
}
See the modules property is a relation Many to Many with a table called user_modules.
And i have the Entity Module as well:
namespace Adm\Entity;
use Doctrine\ORM\Mapping as ORM;
class Module{
/**
* #ORM\Id
* #ORM\Column(type="integer");
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\Column(type="integer")
*/
private $status;
/**
* #return the $id
*/
public function getId() {
return $this->id;
}
/**
* #return the $name
*/
public function getName() {
return $this->name;
}
/**
* #return the $status
*/
public function getStatus() {
return $this->status;
}
/**
* #param field_type $id
*/
public function setId($id) {
$this->id = $id;
}
/**
* #param field_type $name
*/
public function setName($name) {
$this->name = $name;
}
/**
* #param field_type $status
*/
public function setStatus($status) {
$this->status = $status;
}
}
I receive a array variable containing the Post from a form to insert in a table. Each post element have it's property in Entity, as expected. Together, i have a $module variable which is an array containing id's of the modules. My question is: How do i insert this data in the user_module table?
My add function is this:
public function addUser($newUser){
$user = new User();
$user->setName($newUser['name']);
...
$this->getEm()->persist($user);
$this->getEm()->flush();
}
Firstly you need to have cascade={"persist"} as mentioned by #skrilled.
Then you need to retrieve the module entities from the database. You mentioned you have the id's in the $module variable.
You need a DQL statement something like this
$builder = $this->getEntityManager()->createQueryBuilder();
$builder->select('m')
->from('Adm\Entity\Module', 'm')
->where('m.id IN (:modules)')
->setParameter('modules', $modules);
$moduleEntities= $builder->getQuery()->getResult(Query::HYDRATE_OBJECT);
and in your User entity you will need
public function addModules(Array $moduleEntities)
{
foreach ($moduleEntities as $module) {
if ($module instanceof Module) {
$this->modules[] = $module;
}
}
return $this;
}
finally in your addUser method you will need to add the array of modules from the above DQL
public function addUser($newUser, $moduleEntities)
{
$user = new User();
$user->setName($newUser['name']);
....
$user->addModules($moduleEntities);
$this->getEm()->persist($user);
$this->getEm()->flush();
}
I hope this helps
You should read about using cascade. This will allow you to save/modify/remove the associated relationships and how you expect this to work.
In this case, you would want the relationship to persist since you want the associated entities to be saved when user itself is saved.
#ORM\ManyToMany(targetEntity="Module", cascade={"persist"})
http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html
By default, no operations are cascaded.
The following cascade options exist:
persist : Cascades persist operations to the associated entities.
remove : Cascades remove operations to the associated entities.
merge : Cascades merge operations to the associated entities.
detach : Cascades detach operations to the associated entities.
refresh : Cascades refresh operations to the associated entities.
all : Cascades persist, remove, merge, refresh and detach operations to associated entities.

error when trying to register in Symfony2

I am new in symfony2, I would like to register some user in my profile_tbl.
here is my code in the controller.
<?php
namespace Ai\QABlogBundle\Controller;
use Ai\QABlogBundle\Entity\Profile_tbl;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class QABlogController extends Controller
{
/**
*#Route("/" , name= "home")
*/
public function homeAction()
{
return $this->render('AiQABlogBundle:QABlog:primaries/index.html.twig');
}
/**
*#Route("/register/" ,name= "register")
*/
public function registerAction(Request $request)
{
$profile = new Profile_tbl();
$form = $this -> createFormBuilder($profile)
-> add ('fname' , 'text')
-> add ('lname' , 'text')
-> add ('gender' , 'text')
-> add ('email' , 'text')
-> add ('register' , 'submit')
->getForm();
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($profile);
$em->flush();
return new Response('News added successfuly');
}
$build['form'] = $form->createView();
return $this->render('AiQABlogBundle:QABlog:primaries/registration.html.twig', $build);
}
}
When I try to run it in my browser it gives an error
"Attempted to load class "Profile_tbl" from namespace "Ai\QABlogBundle\Entity".
Did you forget a "use" statement for another namespace?"
I don't know what is wrong .. Can you help me?
my Profile_tbl entity
<?php
namespace Ai\QABlogBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Profile_tbl
*
* #ORM\Table()
* #ORM\Entity
*/
class Profile_tbl
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="fname", type="string", length=255)
*/
private $fname;
/**
* #var string
*
* #ORM\Column(name="lname", type="string", length=255)
*/
private $lname;
/**
* #var string
*
* #ORM\Column(name="gender", type="string", length=255)
*/
private $gender;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255)
*/
private $email;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set fname
*
* #param string $fname
* #return Profile_tbl
*/
public function setFname($fname)
{
$this->fname = $fname;
return $this;
}
/**
* Get fname
*
* #return string
*/
public function getFname()
{
return $this->fname;
}
/**
* Set lname
*
* #param string $lname
* #return Profile_tbl
*/
public function setLname($lname)
{
$this->lname = $lname;
return $this;
}
/**
* Get lname
*
* #return string
*/
public function getLname()
{
return $this->lname;
}
/**
* Set gender
*
* #param string $gender
* #return Profile_tbl
*/
public function setGender($gender)
{
$this->gender = $gender;
return $this;
}
/**
* Get gender
*
* #return string
*/
public function getGender()
{
return $this->gender;
}
/**
* Set email
*
* #param string $email
* #return Profile_tbl
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
}
I try to rename or make another entity ..
steps that I tried to generate my new entity.
Creating Database:
php app/console doctrine:database:create
Generate Entity:
php app/console doctrine:generate:entity
Generate the Getters and Setters:
php app/console doctrine:generate:entities AiQABlogBundle
after this I run it in my browser.
and gives me an error ,
Attempted to load class "Profile" from namespace "Ai\QABlogBundle\Controller".
Did you forget a "use" statement for e.g. "Twig_Profiler_Profile" or "Symfony\Component\HttpKernel\Profiler\Profile"?
This happened to me a few times. It usually happens when I copy-paste an old class file to create a new class. Check your classname and the filename of the file containing your class; they should be the same. In your case they should be Profile_tbl and Profile_tbl .php respectively.
Update
Profile_tbl is converted to Profile/tbl.php as per the PSR-0 autoload convention which Composer uses by default to load classes inside the src/ directory. You'll have to rename the class to something that does not use an underscore e.g. ProfileTbl or simply Profile.
// This should be in the file: src/Ai/QABlogBundle/Entity/Profile.php
namespace Ai\QABlogBundle\Entity;
/**
* Profile
*
* #ORM\Table()
* #ORM\Entity
*/
class Profile
{
// ...
}
Credits to Pazi for pointing this out.

Symfony2, Sonata MediaBundle : add new fields to table

I'm trying to add 4 new fields in Sonata MediaBundle for the GalleryHasMedia.
I correctly override the GalleryHasMediaAdmin :
To override it i added in services.yml this line :
parameters:
sonata.media.admin.gallery_has_media.class: Application\Sonata\MediaBundle\Admin\GalleryHasMediaAdmin
I had to create the methods manually (getName and else) since php app/console doctrine:generate:entities ApplicationSonataMediaBundle:GalleryHasMedia
apparently not caring about my new fields set in my custom entity Application\Sonata\MediaBundle\Entity\GalleryHasMedia.
As well --dump-sql return "Nothing to update". But the methods (getName and else) are correctly recognize in the Sonata admin, so why not the new fields?
here my custom entity :
<?php
namespace Application\Sonata\MediaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Sonata\MediaBundle\Entity\BaseGalleryHasMedia as BaseGalleryHasMedia;
/**
* #ORM\Entity
* #ORM\Table(name="media__gallery_media")
*/
class GalleryHasMedia extends BaseGalleryHasMedia
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=64, nullable=false, name="name")
**/
private $name;
/**
* #ORM\Column(type="string", length=64, nullable=false, name="activity")
**/
private $activity;
/**
* #ORM\Column(type="text", nullable=false, name="description")
*/
private $description;
/**
* #ORM\Column(type="string", length=255, nullable=false, name="code")
**/
private $link;
/**
* Get id
*
* #return integer $id
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return GalleryHasMedia
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set activity
*
* #param string $activity
* #return GalleryHasMedia
*/
public function setActivity($activity)
{
$this->activity = $activity;
return $this;
}
/**
* Get activity
*
* #return string
*/
public function getActivity()
{
return $this->activity;
}
/**
* Set description
*
* #param string $description
* #return GalleryHasMedia
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set link
*
* #param string $link
* #return GalleryHasMedia
*/
public function setLink($link)
{
$this->link = $link;
return $this;
}
/**
* Get link
*
* #return string
*/
public function getLink()
{
return $this->link;
}
}
And i correctly set as said in their Documentation :
sonata_media:
# if you don't use default namespace configuration
class:
media: Application\Sonata\MediaBundle\Entity\Media
gallery: Application\Sonata\MediaBundle\Entity\Gallery
gallery_has_media: Application\Sonata\MediaBundle\Entity\GalleryHasMedia
I'm using auto mapping so my custom entity is correctly mapped :
[OK] Application\Sonata\MediaBundle\Entity\GalleryHasMedia
here the actual table (sonata's default table) :
So any ideas why i can't add any new fields to the gallery_has_media table?
UPDATE :
I'm guessing it is because i'm using annotations. How can i keep using annotations and makes it sync with my database?
This guy encountered a similar problem Issue
Okay, i found the answer correctly explained here.
Deleting Application/Sonata/MediaBundle/Resources/config/doctrine allowed me to use annotations inside my custom entity.

Categories