Doctrine: Symfony 2 foreign key null just before flush - symfony

I am new to Symfony2 and Doctrine, i am stuck a little bit. Error receiving while saving to the database.
An exception occurred while executing 'INSERT INTO tho_provider (provid_name, provid_logo, provid_logo_path, created_time, provider_created_by) VALUES (?, ?, ?, ?, ?)' with params ["test", {}, "qwwwww", "2015-08-11 16:03:15", null]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'provider_created_by' cannot be null
I have the form where i am only getting provider name input and logo, rest is i am handling in the controller, Including provider_created_by which gets null just after the flush, before the flush command its showing the value.
public function createAction(Request $request)
{
$user = $this->getUser();
$entity = new Provider();
$entity->setProvidLogoPath("qwwwww");
$entity->setProviderCreatedBy($user);
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
//$entity->setCreatedBy($user);
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('provider_show', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
I have entities, PROVIDER and USER.
User's can create many provider and providers only belongs to one user. One to many relationship.
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* Provider
*
* #ORM\Table(name="tho_provider")
* #ORM\Entity(repositoryClass="AppBundle\Entity\ProviderRepository")
* #Vich\Uploadable
* #ORM\HasLifecycleCallbacks()
*/
class Provider
{
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="providers")
* #ORM\JoinColumn(name="provider_created_by", referencedColumnName="id")
*/
protected $users;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #Assert\NotBlank()
* #ORM\Column(name="provid_name", type="string", length=255)
*/
private $providName;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Vich\UploadableField(mapping="general_image", fileNameProperty="provid_logo")
*
* #var File
*/
private $imageFile;
/**
* #var string
*
* #ORM\Column(name="provid_logo", type="string", length=255)
*/
private $providLogo;
/**
* #var string
*
* #ORM\Column(name="provid_logo_path", type="string", length=255)
*/
private $providLogoPath;
/**
* #var \DateTime
* #Assert\Type("\DateTime")
* #ORM\Column(name="created_time", type="datetime")
*/
private $createdTime;
/**
* #var integer
*
* #ORM\Column(name="provider_created_by", type="integer")
*/
public $providerCreatedBy;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set providName
*
* #param string $providName
* #return Provider
*/
public function setProvidName($providName)
{
$this->providName = $providName;
return $this;
}
/**
* Get providName
*
* #return string
*/
public function getProvidName()
{
return $this->providName;
}
/**
* Set providLogo
*
* #param string $providLogo
* #return Provider
*/
public function setProvidLogo($providLogo)
{
$this->providLogo = $providLogo;
return $this;
}
/**
* Get providLogo
*
* #return string
*/
public function getProvidLogo()
{
return $this->providLogo;
}
/**
* Set providLogoPath
*
* #param string $providLogoPath
* #return Provider
*/
public function setProvidLogoPath($providLogoPath)
{
$this->providLogoPath = $providLogoPath;
return $this;
}
/**
* Get providLogoPath
*
* #return string
*/
public function getProvidLogoPath()
{
return $this->providLogoPath;
}
/**
* Set createdTime
*
* #param \DateTime $createdTime
* #return Provider
*/
public function setCreatedTime($createdTime)
{
$this->createdTime = $createdTime;
return $this;
}
/**
* Get createdTime
*
* #return \DateTime
*/
public function getCreatedTime()
{
return $this->createdTime;
}
/**
* Set users
*
* #param \AppBundle\Entity\User $users
* #return Provider
*/
public function setUsers(\AppBundle\Entity\User $users = null)
{
$this->users = $users;
return $this;
}
/**
* Get users
*
* #return \AppBundle\Entity\User
*/
public function getUsers()
{
return $this->users;
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTime('now');
}
}
/**
* #return File
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* #ORM\PrePersist
*/
public function setCreatedTimeValue()
{
$this->createdTime = new \DateTime();
}
/**
* Set providerCreatedBy
*
* #param integer $providerCreatedBy
* #return Provider
*/
public function setProviderCreatedBy($providerCreatedBy)
{
$this->providerCreatedBy = $providerCreatedBy;
return $this;
}
/**
* Get providerCreatedBy
*
* #return integer
*/
public function getProviderCreatedBy()
{
return $this->providerCreatedBy;
}
}
USER:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* User
*
* #ORM\Table(name="tho_user")
* #ORM\Entity(repositoryClass="AppBundle\Entity\UserRepository")
* #UniqueEntity(fields="email",message = "This email already exist.")
* #UniqueEntity(fields = "username",message = "This username already taken")
*/
class User implements AdvancedUserInterface, \Serializable
{
/**
* #ORM\OneToMany(targetEntity="Provider", mappedBy="user")
*/
protected $providers;
public function __construct()
{
$this->providers = new ArrayCollection();
}
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*#Assert\NotBlank(message="Username is required!")
* #Assert\Length(min=3,minMessage="Minimum 3 characters long.")
* #ORM\Column(name="username", type="string", length=255)
*/
protected $username;
/**
* #var string
*
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $password;
/**
* #var array
*
* #ORM\Column(name="roles",type="json_array")
*/
private $roles = array();
/**
* #var bool
*
* #ORM\Column(name="is_active",type="boolean")
*/
private $isActive = true;
/**
* #var string
*#Assert\NotBlank()
* #Assert\Email
* #ORM\Column(name="email",type="string", length=255)
*/
private $email;
/**
* #var string
*#Assert\NotBlank()
*
* #ORM\Column(name="first_name",type="string", length=255)
*/
private $firstName;
/**
* #var string
*#Assert\NotBlank()
* #ORM\Column(name="last_name",type="string", length=255)
*/
private $lastName;
/**
* #var string
*
* #ORM\Column(name="iata",type="string", length=255)
*/
private $iata;
/**
* #var string
*
* #ORM\Column(name="job_title",type="string", length=255)
*/
private $jobTitle;
/**
* #var string
*
* #ORM\Column(name="agency_phone",type="string", length=255)
*/
private $agencyPhone;
/**
* #var string
*
* #ORM\Column(name="emergency_mobile",type="string", length=255)
*/
private $emergencyMobile;
/**
* Storing password temporarily
* #Assert\NotBlank()
* #Assert\Length(min=6,minMessage="Minimum 6 characters long.")
* #var string
*/
private $plainPassword;
/**
* Get id
*
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
* #return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set password
*
* #param string $password
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
public function getRoles()
{
$roles = $this->roles;
$roles[] = 'ROLE_ADMIN';
return array_unique($roles);
}
public function setRoles(array $roles)
{
$this->roles = $roles;
return $this;
}
public function eraseCredentials()
{
$this->setPlainPassword(null);
}
public function getSalt()
{
return null;
}
/**
* #return boolean
*/
public function isIsActive()
{
return $this->isActive;
}
/**
* #param boolean $isActive
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
}
/**
* Checks whether the user's account has expired.
*
* Internally, if this method returns false, the authentication system
* will throw an AccountExpiredException and prevent login.
*
* #return bool true if the user's account is non expired, false otherwise
*
* #see AccountExpiredException
*/
public function isAccountNonExpired()
{
return true;
}
/**
* Checks whether the user is locked.
*
* Internally, if this method returns false, the authentication system
* will throw a LockedException and prevent login.
*
* #return bool true if the user is not locked, false otherwise
*
* #see LockedException
*/
public function isAccountNonLocked()
{
return true;
}
/**
* Checks whether the user's credentials (password) has expired.
*
* Internally, if this method returns false, the authentication system
* will throw a CredentialsExpiredException and prevent login.
*
* #return bool true if the user's credentials are non expired, false otherwise
*
* #see CredentialsExpiredException
*/
public function isCredentialsNonExpired()
{
return true;
}
/**
* Checks whether the user is enabled.
*
* Internally, if this method returns false, the authentication system
* will throw a DisabledException and prevent login.
*
* #return bool true if the user is enabled, false otherwise
*
* #see DisabledException
*/
public function isEnabled()
{
return true;
}
/**
* Get isActive
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* Set email
*
* #param string $email
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* (PHP 5 >= 5.1.0)<br/>
* String representation of object
* #link http://php.net/manual/en/serializable.serialize.php
* #return string the string representation of the object or null
*/
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password
));
}
/**
* (PHP 5 >= 5.1.0)<br/>
* Constructs the object
* #link http://php.net/manual/en/serializable.unserialize.php
* #param string $serialized <p>
* The string representation of the object.
* </p>
* #return void
*/
public function unserialize($serialized)
{
list(
$this->id,
$this->username,
$this->password
) = unserialize($serialized);
}
/**
* #return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* #param string $firstName
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
/**
* #return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* #param string $lastName
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
/**
* #return string
*/
public function getIata()
{
return $this->iata;
}
/**
* #param string $iata
*/
public function setIata($iata)
{
$this->iata = $iata;
}
/**
* #return string
*/
public function getJobTitle()
{
return $this->jobTitle;
}
/**
* #param string $jobTitle
*/
public function setJobTitle($jobTitle)
{
$this->jobTitle = $jobTitle;
}
/**
* #return string
*/
public function getAgencyPhone()
{
return $this->agencyPhone;
}
/**
* #param string $agencyPhone
*/
public function setAgencyPhone($agencyPhone)
{
$this->agencyPhone = $agencyPhone;
}
/**
* #return string
*/
public function getEmergencyMobile()
{
return $this->emergencyMobile;
}
/**
* #param string $emergencyMobile
*/
public function setEmergencyMobile($emergencyMobile)
{
$this->emergencyMobile = $emergencyMobile;
}
/**
* #return string
*/
public function getPlainPassword()
{
return $this->plainPassword;
}
/**
* #param string $plainPassword
*/
public function setPlainPassword($plainPassword)
{
$this->plainPassword = $plainPassword;
}
/**
* Set provider
*
* #param \AppBundle\Entity\Provider $provider
* #return User
*/
public function setProvider(\AppBundle\Entity\Provider $provider = null)
{
$this->provider = $provider;
return $this;
}
/**
* Get provider
*
* #return \AppBundle\Entity\Provider
*/
public function getProvider()
{
return $this->provider;
}
/**
* Add providers
*
* #param \AppBundle\Entity\Provider $providers
* #return User
*/
public function addProvider(\AppBundle\Entity\Provider $providers)
{
$this->providers[] = $providers;
return $this;
}
/**
* Remove providers
*
* #param \AppBundle\Entity\Provider $providers
*/
public function removeProvider(\AppBundle\Entity\Provider $providers)
{
$this->providers->removeElement($providers);
}
/**
* Get providers
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProviders()
{
return $this->providers;
}
}

Your metadata is
/**
* #var integer
*
* #ORM\Column(name="provider_created_by", type="integer")
*/
public $providerCreatedBy;
but you are passing an object (probably null):
$user = $this->getUser();
/* ... */
$entity->setProviderCreatedBy($user);
And the setter has no type hint:
public function setProviderCreatedBy($providerCreatedBy)
{
$this->providerCreatedBy = $providerCreatedBy;
return $this;
}
You must change your mapping of $providerCreatedBy to ManyToOne with User entity.

Check if your user has been logged in, $this->getUser() returns null if user is anonymous, also I think you should change your mapping info for providerCreatedBy field, from column type integer to ManyToOne relationship with User class..

Related

Authentication Symfony is not working

I am having a problem with symfony Authentication, the point is, when i create a user, i send a email notification with a token, then when the user click on the link is when his account is activate and i do some verification like the token is correct, the user exist the account is active etc, and after that is when i am having my problem, everything is correctly until the user click on his link i do every verification but when i logged the user automatically and redirect the user to homepage the browser say that is redirecting a lot return $this->redirect($this->generateUrl('homepage'));
well there is when i am having a problem, here is my code on the securityController in activateUserAction is when i am having the problem, i hope someone can helpme
User entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Validator\Constraints as Assert;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
*/
class User implements AdvancedUserInterface,\Serializable
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255, unique=true)
* #Assert\Email(
* message = "The email '{{ value }}' is not a valid email.",
* checkMX = true
* )
*
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $password;
/**
* #Assert\NotBlank(groups={"register"})
* #Assert\Length(min = 6)
*/
private $passwordClear;
/**
* #var bool
*
* #ORM\Column(name="active", type="boolean")
*/
private $active;
/**
* #ORM\Column(type="json_array")
*/
private $roles = array();
/**
* #ORM\Column(name="expired", type="boolean")
*/
private $expired;
/**
* #ORM\OneToOne(targetEntity="AppBundle\Entity\Person",cascade={"persist"})
*/
private $person;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set email
*
* #param string $email
*
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set password
*
* #param string $password
*
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* get PasswordClear
*/
public function getPasswordClear(){
return $this->passwordClear;
}
/**
* set passwordClear
*/
public function setPasswordClear($password){
$this->passwordClear=$password;
}
/**
* Set active
*
* #param boolean $active
*
* #return User
*/
public function setActive($active=0)
{
$this->active = $active;
return $this;
}
/**
* Get active
*
* #return bool
*/
public function getActive()
{
return $this->active;
}
/**
* Set roles
*
* #param array $roles
*
* #return User
*/
public function setRoles($roles)
{
$this->roles = $roles;
return $this;
}
/**
* Get roles
*
* #return array
*/
public function getRoles()
{
return array($this->roles);
}
/**
* Set person
*
* #param \AppBundle\Entity\Person $person
*
* #return User
*/
public function setPerson(\AppBundle\Entity\Person $person = null)
{
$this->person = $person;
return $this;
}
/**
* Get person
*
* #return \AppBundle\Entity\Person
*/
public function getPerson()
{
return $this->person;
}
public function getUsername()
{
return $this->getEmail();
}
public function eraseCredentials()
{
$this->passwordClear = null;
}
public function getSalt()
{
return null;
}
public function isAccountNonExpired(){
return true;
}
public function isAccountNonLocked(){
return true;
}
public function isCredentialsNonExpired(){
return true;
}
public function isEnabled(){
return $this->active;
}
/**
* Set expired
*
* #param boolean $expired
*
* #return User
*/
public function setExpired($expired)
{
$this->expired = $expired;
return $this;
}
/**
* Get expired
*
* #return boolean
*/
public function getExpired()
{
return $this->expired;
}
/** #see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->email,
$this->password,
));
}
/** #see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
$this->id,
$this->email,
$this->password,
) = unserialize($serialized);
}
}
Entity Person
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpKernel\Kernel;
/**
* Person
*
* #ORM\Table(name="person")
* #ORM\Entity(repositoryClass="AppBundle\Repository\PersonRepository")
*/
class Person
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="last_name", type="string", length=255)
*/
private $lastName;
/**
* #var string
* #ORM\Column(name="desccription",type="string", length=255,nullable=true)
*/
private $description;
/**
* #var string
*
* #ORM\Column(name="token", type="string", length=255)
*/
private $token;
/**
* #var string
*
* #ORM\Column(name="url_validate", type="string", length=255)
*/
private $urlValidate;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Person
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set lastName
*
* #param string $lastName
*
* #return Person
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
return $this;
}
/**
* Get lastName
*
* #return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Set token
*
* #param string $token
*
* #return Person
*/
public function setToken($token)
{
$this->token = $token;
return $this;
}
/**
* Get token
*
* #return string
*/
public function getToken()
{
return $this->token;
}
/**
* Set urlValidate
*
* #param string $urlValidate
*
* #return Person
*/
public function setUrlValidate($urlValidate)
{
$this->urlValidate = $urlValidate;
return $this;
}
/**
* Get urlValidate
*
* #return string
*/
public function getUrlValidate()
{
return $this->urlValidate;
}
}
My securityController
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security
\Core\Authentication\Token \UsernamePasswordToken;
use Symfony\Component\Security
\Http\Firewall\ListenerInterface;
use Symfony\Component\Security
\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security
\Core\Authentication\Token\Storage\TokenStorageInterface;
use AppBundle\Form\RegisterType;
use AppBundle\Entity\Register;
class SecurityController extends Controller
{
/**
* #Route("/login", name="user_login")
*/
public function loginAction()
{
if($this->getUser()){
return $this->redirectToRoute('homepage');
}
$authUtils = $this->get('security.authentication_utils');
return $this->render('front/homepage/_singin.html.twig', array(
'last_username' => $authUtils->getLastUsername(),
'error' => $authUtils->getLastAuthenticationError(),
));
}
/**
* #Route("/login_check", name="user_login_check")
*/
public function loginCheckAction()
{
}
/**
* #Route("/logout", name="user_logout")
*/
public function logoutAction()
{
}
/**
*
* #Route("/token/{token}", name="activate")
*/
public function activateUserAction($token){
$em = $this->getDoctrine()->getManager();
$person=$em->getRepository('AppBundle:Person')->findByToken($token);
if($person){
$user=$em->getRepository('AppBundle:User')->findByPerson($person);
$user->setActive(1);
$person->setToken("");
$person->setActivatedDate(new \DateTime());
$em->persist($person);
$em->flush();
$em->persist($user);
$em->flush();
$token= new UsernamePasswordToken(
$user,
$user->getPassword(),
'user',
$user->getRoles()
);
$this->get('security.token_storage')->setToken($token);
return $this->redirect($this->generateUrl('homepage'));
}else{
return $this->redirect($this->generateUrl('caducada'));
}
}

Semantical Error in symfony2 while fetching the data

I am trying to write a web service to fetch the category list and all the business under that category in an nested array fashion.
I am getting an Semantical Error saying :
{
code: 500
message: "[Semantical Error] line 0, col 14 near 'StreetBumbApiBundle:Buss_owner': Error: Class 'StreetBumb\ApiBundle\Entity\Buss_owner' is not defined."
}
I already defined the entity in the controller, i dont know why it is showing this error.
This is how my controller's function looks like:
public function getCategoryAction(){
$em = $this->getDoctrine()->getEntityManager();
$pro = $em->getRepository('StreetBumbApiBundle:Category')
->getBusinessByCategory();
//return $pro;
$i = 0;
foreach($pro as $p)
{
$data['category'][$i]['id'] = $p->getId();
$data['category'][$i]['Name'] = $p->getCatName();
//$result[$i] = $p->getId();
$catId = $p->getId();
$business = $em->createQuery('SELECT b FROM StreetBumbApiBundle:Buss_owner b WHERE b.catId = :catId')->setParameter('catId', $catId);
$result = $business->getResult();
foreach($result as $r)
{
$data['business'][$i]['id'][] = $r->getId();
}
$i++;
}
return $data;
}
Please guide if anyone have idea.. Thanx
UPDATE:
Buss_owner Entity:
<?php
namespace StreetBumb\ApiBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Buss_owner
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="StreetBumb\ApiBundle\Entity\Buss_ownerRepository")
*/
class Buss_owner
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=50)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255)
*/
private $email;
/**
* #var integer
*
* #ORM\Column(name="phno", type="integer")
*/
private $phno;
/**
* #var string
*
* #ORM\Column(name="address", type="string", length=255)
*/
private $address;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $password;
/**
* #var string
*
* #ORM\Column(name="fbId", type="integer")
*/
private $fbId;
/**
* #var string
*
* #ORM\Column(name="uniqueId", type="string", length=255)
*/
private $uniqueId;
/**
* #var integer
*
* #ORM\Column(name="catId", type="integer")
* #ORM\ManyToMany(targetEntity="Category", mappedBy="Buss_owner")
*/
private $catId;
public function __construct() {
$this->catId = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Buss_owner
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set email
*
* #param string $email
* #return Buss_owner
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set phno
*
* #param integer $phno
* #return Buss_owner
*/
public function setPhno($phno)
{
$this->phno = $phno;
return $this;
}
/**
* Get phno
*
* #return integer
*/
public function getPhno()
{
return $this->phno;
}
/**
* Set address
*
* #param string $address
* #return Buss_owner
*/
public function setAddress($address)
{
$this->address = $address;
return $this;
}
/**
* Get address
*
* #return string
*/
public function getAddress()
{
return $this->address;
}
/**
* Set catId
*
* #param integer $catId
* #return Buss_owner
*/
public function setCatId($catId)
{
$this->catId = $catId;
return $this;
}
/**
* Get catId
*
* #return integer
*/
public function getCatId()
{
return $this->catId;
}
/**
* Set password
*
* #param string $password
* #return Buss_owner
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set uniqueId
*
* #param string $uniqueId
* #return Buss_owner
*/
public function setUniqueId($uniqueId)
{
$this->uniqueId = $uniqueId;
return $this;
}
/**
* Get uniqueId
*
* #return string
*/
public function getUniqueId()
{
return $this->uniqueId;
}
/**
* Set fbId
*
* #param integer $fbId
* #return Buss_owner
*/
public function setFbId($fbId)
{
$this->fbId = $fbId;
return $this;
}
/**
* Get fbId
*
* #return integer
*/
public function getFbId()
{
return $this->fbId;
}
}
I believe the problem is the underscore in the entity name.
Doctrine's naming convention is to use CamelCase which it then converts to underscores in the database. Due to this behind the scenes magic, underscores can cause problems in entity names.
Try changing the entity class name to BussOwner and calling this in the controller. If you can't change the table name you can handle this by modifying the entity annotation to:
#ORM\Table(name="buss_owner")

Symfony2 "Error: Call to a member function toArray() on a non-object" when loading Roles from Database

I've been battling with this for several hours. I've built an app in Symfony 2.5 and when I go to log in as a user I receive this error:
FatalErrorException: Error: Call to a member function toArray() on a
non-object in /var/www/cwwa/src/CWWA/CoreBundle/Entity/Users.php line
402
On line 402, I have this code:
/**
* #inheritDoc
*/
public function getRoles()
{
//return array('ROLE_CUSTOMER_USER');
return $this->roles->toArray();
}
If I comment out return $this->roles->toArray(); and replace it with the line above it, my user gets logged in to the system without an issue.
Now the main issue I see other people having has been with Symfony2 running on a server with PHP 5.4. My laptop was running this until I downgraded it to 5.3. This hasn't solved the issue.
Another method I used was to replace return $this->roles->toArray(); to return $this->roles;, I get this error:
Catchable Fatal Error: Argument 4 passed to
Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken::__construct()
must be an array, integer given, called in
/var/www/cwwa/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php
on line 96 and defined in
/var/www/cwwa/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php
line 36
I assume from this that the system is retrieving a value from the database.
My Database uses two tables for security. One User table and the other is the Role table. I've included the Entity files for both the User and Role tables below:
Users.php
<?php
namespace CWWA\CoreBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Users
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="CWWA\CoreBundle\Entity\Users")
*/
class Users implements UserInterface, \Serializable
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=500, nullable=false)
*/
private $username;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=500, nullable=false)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=500, nullable=false)
*/
private $password;
/**
* #var string
*
* #ORM\Column(name="salt", type="string", length=500, nullable=false)
*/
private $salt;
/**
* #var string
*
* #ORM\Column(name="first_name", type="string", length=125, nullable=false)
*/
private $firstName;
/**
* #var string
*
* #ORM\Column(name="surname", type="string", length=45, nullable=false)
*/
private $surname;
/**
* #var integer
*
* #ORM\Column(name="customer", type="integer", nullable=false)
*/
private $customer;
/**
* #var \DateTime
*
* #ORM\Column(name="created", type="datetime", nullable=false)
*/
private $created;
/**
* #var boolean
*
* #ORM\Column(name="is_active", type="boolean", nullable=false)
*/
private $isActive;
/**
* #var boolean
*
* #ORM\Column(name="blocked", type="boolean", nullable=false)
*/
private $blocked;
/**
* #var integer
*
* #ORM\Column(name="access_list", type="integer", nullable=false)
*/
private $accessList;
/**
* #ORM\ManyToMany(targetEntity="Roles", inversedBy="roles")
*
*/
private $roles;
public function __construct()
{
return $this->isActive = true;
return $this->salt = md5(uniqid(null, true));
return $this->roles = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
* #return Users
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set email
*
* #param string $email
* #return Users
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set password
*
* #param string $password
* #return Users
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set salt
*
* #param string $salt
* #return Users
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Get salt
*
* #return string
*/
public function getSalt()
{
return $this->salt;
}
/**
* Set firstName
*
* #param string $firstName
* #return Users
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
return $this;
}
/**
* Get firstName
*
* #return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Set surname
*
* #param string $surname
* #return Users
*/
public function setSurname($surname)
{
$this->surname = $surname;
return $this;
}
/**
* Get surname
*
* #return string
*/
public function getSurname()
{
return $this->surname;
}
/**
* Set customer
*
* #param integer $customer
* #return Users
*/
public function setCustomer($customer)
{
$this->customer = $customer;
return $this;
}
/**
* Get customer
*
* #return integer
*/
public function getCustomer()
{
return $this->customer;
}
/**
* Set created
*
* #param \DateTime $created
* #return Users
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created
*
* #return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* Set isActive
*
* #param boolean $isActive
* #return Users
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get isActive
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* Set blocked
*
* #param boolean $blocked
* #return Users
*/
public function setBlocked($blocked)
{
$this->blocked = $blocked;
return $this;
}
/**
* Get blocked
*
* #return boolean
*/
public function getBlocked()
{
return $this->blocked;
}
/**
* Set accessList
*
* #param integer $accessList
* #return Users
*/
public function setAccessList($accessList)
{
$this->accessList = $accessList;
return $this;
}
/**
* Get accessList
*
* #return integer
*/
public function getAccessList()
{
return $this->accessList;
}
/**
* Set roles
*
* #param integer $roles
* #return Users
*/
public function setRoles($roles)
{
$this->roles = $roles;
return $this;
}
/**
* #inheritDoc
*/
public function getRoles()
{
//return array('ROLE_CUSTOMER_USER');
return $this->roles;
}
/**
* #inheritDoc
*/
public function eraseCredentials()
{
}
/**
* #see \Serializable::serialize()
*/
public function serialize()
{
return serialize(array(
$this->id,
));
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
) = unserialize($serialized);
}
public function isEqualTo(UserInterface $user)
{
return $this->id === $user->getId();
}
}
Roles.php
<?php
namespace CWWA\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Security\Core\Role\RoleInterface;
/**
* Roles
*
* #ORM\Table(name="roles")
* #ORM\Entity
*/
class Roles implements RoleInterface
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="names", type="string", length=30, nullable=false)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="role", type="string", length=20, nullable=false)
*/
private $role;
/**
* #ORM\ManyToMany(targetEntity="Users", mappedBy="roles")
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set names
*
* #param string $names
* #return Roles
*/
public function setNames($names)
{
$this->names = $names;
return $this;
}
/**
* Get names
*
* #return string
*/
public function getNames()
{
return $this->names;
}
/**
* Set role
*
* #param string $role
* #return Roles
*/
public function setRole($role)
{
$this->role = $role;
return $this;
}
/**
* Get role
*
* #return string
*/
public function getRole()
{
return $this->role;
}
}
Any help would be fantastic, especially after 4 hours of hitting brick walls!
In your User entity, the roles field should be inversed by users (the field on the other side of the entity).
/**
* #ORM\ManyToMany(targetEntity="Roles", inversedBy="users")
*/
private $roles;
You might need to update your database.
I had a similar problem. The toArray() method isn't working because $this->roles is not an instance of ArrayCollection, instead it's an integer. I don't quite understand why you have three return statements in your Users constructor function; try getting rid of those first and just set the properties you need to set:
public function __construct()
{
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
$this->roles = new ArrayCollection();
}
Now the toArray() method should work as $this->roles should be an ArrayCollection(). Just remember that the Symfony security layer expects either an array of role objects or an array of strings.

Missing an assigned ID for field

I'm lost in a complexe relation (for me). I've a entity project for an entity client and you can attach users to a project. When i try to add a project without users, no problem. But, when i try to add a project and users Sf2 display this error :
Entity of type Intranet\IntranetBundle\Entity\ProjectUser is missing an assigned ID for field 'project'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.
I'm understand it's angry because the project_id is null. But i don't know why it's null.
My Project.php
namespace Intranet\IntranetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Project
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Intranet\IntranetBundle\Entity\ProjectRepository")
*/
class Project
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
* #Assert\NotBlank(
* message = "The field cannot be empty"
* )
*/
private $name;
/**
* #Gedmo\Slug(fields={"name"})
* #ORM\Column(length=255, unique=true)
*/
private $slug;
/**
* #var string
*
* #ORM\Column(name="contact_client", type="text", nullable=true)
*/
private $contactClient;
/**
* #var string
*
* #ORM\Column(name="technologies", type="string", length=255, nullable=true)
*/
private $technologies;
/**
* #var string
*
* #ORM\Column(name="languages", type="string", length=255, nullable=true)
*/
private $languages;
/**
* #var string
*
* #ORM\Column(name="extern", type="text", nullable=true)
*/
private $extern;
/**
* #var string
*
* #ORM\Column(name="url_prod", type="string", length=255, nullable=true)
*/
private $urlProd;
/**
* #var string
*
* #ORM\Column(name="url_staging", type="text", nullable=true)
*/
private $urlStaging;
/**
* #var string
*
* #ORM\Column(name="url_dev", type="text", nullable=true)
*/
private $urlDev;
/**
* #var string
*
* #ORM\Column(name="hosting_company", type="string", length=255, nullable=true)
*/
private $hostingCompany;
/**
* #var string
*
* #ORM\Column(name="hosting_type", type="string", length=255, nullable=true)
*/
private $hostingType;
/**
* #var string
*
* #ORM\Column(name="hosting_manager", type="text", nullable=true)
*/
private $hostingManager;
/**
* #var string
*
* #ORM\Column(name="ssh", type="text", nullable=true)
*/
private $ssh;
/**
* #var string
*
* #ORM\Column(name="ftp", type="text", nullable=true)
*/
private $ftp;
/**
* #var string
*
* #ORM\Column(name="db", type="text", nullable=true)
*/
private $db;
/**
* #var string
*
* #ORM\Column(name="emails", type="text", nullable=true)
*/
private $emails;
/**
* #var string
*
* #ORM\Column(name="cms", type="text", nullable=true)
*/
private $cms;
/**
* #var string
*
* #ORM\Column(name="web_services", type="text", nullable=true)
*/
private $webServices;
/**
* #var string
*
* #ORM\Column(name="comment", type="text", nullable=true)
*/
private $comment;
/**
* #ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\Client", inversedBy="projects")
* #ORM\JoinColumn(nullable=false)
*/
private $client;
/**
* #ORM\OneToMany(targetEntity="Intranet\IntranetBundle\Entity\ProjectUser", mappedBy="project", cascade={"persist"})
*/
private $projectUsers;
public function __construct()
{
$this->projectUsers = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Project
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set slug
*
* #param string $slug
* #return Client
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set contactClient
*
* #param string $contactClient
* #return Project
*/
public function setContactClient($contactClient)
{
$this->contactClient = $contactClient;
return $this;
}
/**
* Get contactClient
*
* #return string
*/
public function getContactClient()
{
return $this->contactClient;
}
/**
* Set technologies
*
* #param string $technologies
* #return Project
*/
public function setTechnologies($technologies)
{
$this->technologies = $technologies;
return $this;
}
/**
* Get technologies
*
* #return string
*/
public function getTechnologies()
{
return $this->technologies;
}
/**
* Set languages
*
* #param string $languages
* #return Project
*/
public function setLanguages($languages)
{
$this->languages = $languages;
return $this;
}
/**
* Get languages
*
* #return string
*/
public function getLanguages()
{
return $this->languages;
}
/**
* Set extern
*
* #param string $extern
* #return Project
*/
public function setExtern($extern)
{
$this->extern = $extern;
return $this;
}
/**
* Get extern
*
* #return string
*/
public function getExtern()
{
return $this->extern;
}
/**
* Set urlProd
*
* #param string $urlProd
* #return Project
*/
public function setUrlProd($urlProd)
{
$this->urlProd = $urlProd;
return $this;
}
/**
* Get urlProd
*
* #return string
*/
public function getUrlProd()
{
return $this->urlProd;
}
/**
* Set urlStaging
*
* #param string $urlStaging
* #return Project
*/
public function setUrlStaging($urlStaging)
{
$this->urlStaging = $urlStaging;
return $this;
}
/**
* Get urlStaging
*
* #return string
*/
public function getUrlStaging()
{
return $this->urlStaging;
}
/**
* Set urlDev
*
* #param string $urlDev
* #return Project
*/
public function setUrlDev($urlDev)
{
$this->urlDev = $urlDev;
return $this;
}
/**
* Get urlDev
*
* #return string
*/
public function getUrlDev()
{
return $this->urlDev;
}
/**
* Set hostingCompany
*
* #param string $hostingCompany
* #return Project
*/
public function setHostingCompany($hostingCompany)
{
$this->hostingCompany = $hostingCompany;
return $this;
}
/**
* Get hostingCompany
*
* #return string
*/
public function getHostingCompany()
{
return $this->hostingCompany;
}
/**
* Set hostingType
*
* #param string $hostingType
* #return Project
*/
public function setHostingType($hostingType)
{
$this->hostingType = $hostingType;
return $this;
}
/**
* Get hostingType
*
* #return string
*/
public function getHostingType()
{
return $this->hostingType;
}
/**
* Set hostingManager
*
* #param string $hostingManager
* #return Project
*/
public function setHostingManager($hostingManager)
{
$this->hostingManager = $hostingManager;
return $this;
}
/**
* Get hostingManager
*
* #return string
*/
public function getHostingManager()
{
return $this->hostingManager;
}
/**
* Set ssh
*
* #param string $ssh
* #return Project
*/
public function setSsh($ssh)
{
$this->ssh = $ssh;
return $this;
}
/**
* Get ssh
*
* #return string
*/
public function getSsh()
{
return $this->ssh;
}
/**
* Set ftp
*
* #param string $ftp
* #return Project
*/
public function setFtp($ftp)
{
$this->ftp = $ftp;
return $this;
}
/**
* Get ftp
*
* #return string
*/
public function getFtp()
{
return $this->ftp;
}
/**
* Set db
*
* #param string $db
* #return Project
*/
public function setDb($db)
{
$this->db = $db;
return $this;
}
/**
* Get db
*
* #return string
*/
public function getDb()
{
return $this->db;
}
/**
* Set emails
*
* #param string $emails
* #return Project
*/
public function setEmails($emails)
{
$this->emails = $emails;
return $this;
}
/**
* Get emails
*
* #return string
*/
public function getEmails()
{
return $this->emails;
}
/**
* Set cms
*
* #param string $cms
* #return Project
*/
public function setCms($cms)
{
$this->cms = $cms;
return $this;
}
/**
* Get cms
*
* #return string
*/
public function getCms()
{
return $this->cms;
}
/**
* Set webServices
*
* #param string $webServices
* #return Project
*/
public function setWebServices($webServices)
{
$this->webServices = $webServices;
return $this;
}
/**
* Get webServices
*
* #return string
*/
public function getWebServices()
{
return $this->webServices;
}
/**
* Set comment
*
* #param string $comment
* #return Project
*/
public function setComment($comment)
{
$this->comment = $comment;
return $this;
}
/**
* Get comment
*
* #return string
*/
public function getComment()
{
return $this->comment;
}
/**
* Set client
*
* #param \Intranet\IntranetBundle\Entity\Client $client
* #return Project
*/
public function setClient(\Intranet\IntranetBundle\Entity\Client $client)
{
$this->client = $client;
return $this;
}
/**
* Get client
*
* #return \Intranet\IntranetBundle\Entity\Client
*/
public function getClient()
{
return $this->client;
}
public function addProjectUser(\Intranet\IntranetBundle\Entity\ProjectUser $projectUser)
{
$this->projectUsers[] = $projectUser;
}
public function removeProjectUser(\Intranet\IntranetBundle\Entity\ProjectUser $projectUser)
{
$this->projectUsers->removeElement($projectUser);
}
public function getProjectUsers()
{
return $this->projectUsers;
}
}
My ProjectUser.php
namespace Intranet\IntranetBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class ProjectUser
{
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\Project", inversedBy="projectUsers")
*/
private $project;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="Intranet\UserBundle\Entity\User")
*/
private $user;
/**
* #ORM\Column(name="profil", type="smallint")
*/
private $profil;
public function setProject(\Intranet\IntranetBundle\Entity\Project $project)
{
$project->addProjectUser($this);
$this->project = $project;
}
public function getProject()
{
return $this->project;
}
public function setUser(\Intranet\UserBundle\Entity\User $user)
{
$this->user = $user;
}
public function getUser()
{
return $this->user;
}
public function setProfil($profil)
{
$this->profil = $profil;
}
public function getProfil()
{
return $this->profil;
}
}
profil = smallint for the job of the user (1=manager, 2=designer, ...)
My ProjectController (addAction)
public function addAction()
{
$project = new Project;
$form = $this->createForm(new ProjectType, $project);
$request = $this->get('request');
if ($request->getMethod() == 'POST') {
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($project);
$em->flush();
foreach ($form->get('projectUsers')->getData() as $u) {
$u->setProject($project);
$em->persist($u);
}
$em->flush();
$this->get('session')->getFlashBag()->add('success', 'The project : '. $project->getName() .' has been added');
return $this->redirect($this->generateUrl('clients_list'));
}
}
return $this->render('IntranetIntranetBundle:Project:add_project.html.twig', array(
'form' => $form->createView()
));
}
Thanks for your help
Well, first of all, you shouldn't specify #ORM\Id annotation on every foreign key in your ProjectUser entity - it is for primary keys.
Then you should declare column join on foreign key fields:
/**
* #ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\Project", inversedBy="projectUsers")
* #ORM\JoinColumn(name="project_id", referencedColumnName="id")
*/
private $project;
/**
* #ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\User", inversedBy="projects")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
You also should have a field like
class User
{
// ...
/**
* #ORM\OneToMany(targetEntity="Intranet\IntranetBundle\Entity\ProjectUser", mappedBy="user")
*/
private $projects;
// ...
}
Finally, to add user to project, I suggest you embed a ProjectUserType form with user selection into ProjectType form. In your controller, you can have something like
public function addAction()
{
$project = new Project;
$projectUser = new ProjectUser();
$projectUser->setProject($project);
$project->addProjectUser($projectUser);
$form = $this->createForm(new ProjectType, $project);
// ...
And in form ProjectUserType
class ProjectUserType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('user', 'entity', array(
'class' => 'Intranet:IntranetBundle:User'
));
// ...
Hope this helps at least a little bit.
When you code : $em->persist($project);
$project is equal to $project = new Project; (don't you have forget '()' ?)
Actually the $projet is empty... To do this, I think you forget to code :
$project = $form->getData();

Form nulling a value when user doesn't supply it

Reading this page I've setup a form to handle PATCH requests.
I've a Player entity:
<?php
namespace Acme\PlayerBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
/**
* Acme\PlayerBundle\Entity\Player
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Acme\PlayerBundle\Entity\PlayerRepository")
*/
class Player
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255)
* #Assert\NotBlank()
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="Acme\UserBundle\Entity\User", inversedBy="players")
* #ORM\JoinColumn(nullable=false)
*/
private $owner;
/**
* #ORM\ManyToOne(targetEntity="Acme\TeamBundle\Entity\Team", inversedBy="players")
* #ORM\JoinColumn(nullable=false)
* #Assert\NotBlank()
*/
private $team;
/**
* #var integer $shirtNumber
*
* #ORM\Column(name="shirtNumber", type="smallint")
* #Assert\NotBlank()
*/
private $shirtNumber;
/**
* #var integer $vsid
*
* #ORM\Column(name="vsid", type="integer", nullable=true)
*/
private $vsid;
/**
* #var string $firstname
*
* #ORM\Column(name="firstname", type="string", length=255, nullable=true)
*/
private $firstname;
/**
* #var string $lastname
*
* #ORM\Column(name="lastname", type="string", length=255, nullable=true)
*/
private $lastname;
/**
* #var boolean $deleted
*
* #ORM\Column(name="deleted", type="boolean")
*/
private $deleted = false;
/**
* #var integer $role
*
* #ORM\Column(type="integer", nullable=true)
*/
private $role;
/**
* Create the user salt
*/
public function __construct()
{
//TODO: just for test
$this->uniqueId = substr(uniqid(), 0, 14);
}
/* MANAGED BY DOCTRINE, DON'T EDIT */
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Player
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set shirtNumber
*
* #param integer $shirtNumber
* #return Player
*/
public function setShirtNumber($shirtNumber)
{
$this->shirtNumber = $shirtNumber;
return $this;
}
/**
* Get shirtNumber
*
* #return integer
*/
public function getShirtNumber()
{
return $this->shirtNumber;
}
/**
* Set vsid
*
* #param integer $vsid
* #return Player
*/
public function setVsid($vsid)
{
$this->vsid = $vsid;
return $this;
}
/**
* Get vsid
*
* #return integer
*/
public function getVsid()
{
return $this->vsid;
}
/**
* Set firstname
*
* #param string $firstname
* #return Player
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/**
* Get firstname
*
* #return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set lastname
*
* #param string $lastname
* #return Player
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
/**
* Get lastname
*
* #return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* Set deleted
*
* #param boolean $deleted
* #return Player
*/
public function setDeleted($deleted)
{
$this->deleted = $deleted;
return $this;
}
/**
* Get deleted
*
* #return boolean
*/
public function getDeleted()
{
return $this->deleted;
}
/**
* Set role
*
* #param integer $role
* #return Player
*/
public function setRole($role)
{
$this->role = $role;
return $this;
}
/**
* Get role
*
* #return integer
*/
public function getRole()
{
return $this->role;
}
/**
* Set owner
*
* #param Acme\UserBundle\Entity\User $owner
* #return Player
*/
public function setOwner(\Acme\UserBundle\Entity\User $owner)
{
$this->owner = $owner;
return $this;
}
/**
* Get owner
*
* #return Acme\UserBundle\Entity\User
*/
public function getOwner()
{
return $this->owner;
}
/**
* Set team
*
* #param Acme\TeamBundle\Entity\Team $team
* #return Player
*/
public function setTeam(\Acme\TeamBundle\Entity\Team $team)
{
$this->team = $team;
return $this;
}
/**
* Get team
*
* #return Acme\TeamBundle\Entity\Team
*/
public function getTeam()
{
return $this->team;
}
}
and a Team entity:
<?php
namespace Acme\TeamBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Acme\TeamBundle\Entity\Team
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Acme\TeamBundle\Entity\TeamRepository")
*/
class Team
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $uniqueId
*
* #ORM\Column(name="uniqueId", type="string", length=15)
*/
private $uniqueId;
/**
* #ORM\ManyToOne(targetEntity="Acme\UserBundle\Entity\User", inversedBy="teams")
* #ORM\JoinColumn(nullable=false)
*/
private $owner;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=50)
* #Assert\NotBlank()
*/
private $name;
/**
* #var string $homeColor
*
* #ORM\Column(name="homeColor", type="string", length=7, nullable=true)
*/
private $homeColor;
/**
* #var string $awayColor
*
* #ORM\Column(name="awayColor", type="string", length=7, nullable=true)
*/
private $awayColor;
/**
* #var string $homeShirt
*
* #ORM\Column(name="homeShirt", type="string", length=50, nullable=true)
*/
private $homeShirt;
/**
* #var string $awayShirt
*
* #ORM\Column(name="awayShirt", type="string", length=50, nullable=true)
*/
private $awayShirt;
/**
* #var string $teamLogo
*
* #ORM\Column(name="teamLogo", type="string", length=50, nullable=true)
*/
private $teamLogo;
/**
* #var boolean $deleted
*
* #ORM\Column(name="deleted", type="boolean")
*/
private $deleted = false;
/**
* #ORM\OneToMany(targetEntity="Acme\PlayerBundle\Entity\Player", mappedBy="team", cascade={"persist", "remove"})
*/
private $players;
/**
* #ORM\OneToMany(targetEntity="Acme\MatchBundle\Entity\Match", mappedBy="homeTeam")
*/
private $homeMatches;
/**
* #ORM\OneToMany(targetEntity="Acme\MatchBundle\Entity\Match", mappedBy="awayTeam")
*/
private $awayMatches;
/**
* Create the user salt
*/
public function __construct()
{
$this->players = new ArrayCollection();
$this->homeMatches = new ArrayCollection();
$this->awayMatches = new ArrayCollection();
//TODO: just for test
$this->uniqueId = substr(uniqid(), 0, 14);
}
public function getMatches()
{
return array_merge($this->awayMatches->toArray(), $this->homeMatches->toArray());
}
/* MANAGED BY DOCTRINE, DON'T EDIT */
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set uniqueId
*
* #param string $uniqueId
* #return Team
*/
public function setUniqueId($uniqueId)
{
$this->uniqueId = $uniqueId;
return $this;
}
/**
* Get uniqueId
*
* #return string
*/
public function getUniqueId()
{
return $this->uniqueId;
}
/**
* Set name
*
* #param string $name
* #return Team
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set homeColor
*
* #param string $homeColor
* #return Team
*/
public function setHomeColor($homeColor)
{
$this->homeColor = $homeColor;
return $this;
}
/**
* Get homeColor
*
* #return string
*/
public function getHomeColor()
{
return $this->homeColor;
}
/**
* Set awayColor
*
* #param string $awayColor
* #return Team
*/
public function setAwayColor($awayColor)
{
$this->awayColor = $awayColor;
return $this;
}
/**
* Get awayColor
*
* #return string
*/
public function getAwayColor()
{
return $this->awayColor;
}
/**
* Set homeShirt
*
* #param string $homeShirt
* #return Team
*/
public function setHomeShirt($homeShirt)
{
$this->homeShirt = $homeShirt;
return $this;
}
/**
* Get homeShirt
*
* #return string
*/
public function getHomeShirt()
{
return $this->homeShirt;
}
/**
* Set awayShirt
*
* #param string $awayShirt
* #return Team
*/
public function setAwayShirt($awayShirt)
{
$this->awayShirt = $awayShirt;
return $this;
}
/**
* Get awayShirt
*
* #return string
*/
public function getAwayShirt()
{
return $this->awayShirt;
}
/**
* Set teamLogo
*
* #param string $teamLogo
* #return Team
*/
public function setTeamLogo($teamLogo)
{
$this->teamLogo = $teamLogo;
return $this;
}
/**
* Get teamLogo
*
* #return string
*/
public function getTeamLogo()
{
return $this->teamLogo;
}
/**
* Set deleted
*
* #param boolean $deleted
* #return Team
*/
public function setDeleted($deleted)
{
$this->deleted = $deleted;
return $this;
}
/**
* Get deleted
*
* #return boolean
*/
public function getDeleted()
{
return $this->deleted;
}
/**
* Add players
*
* #param Acme\PlayerBundle\Entity\Player $players
* #return Team
*/
public function addPlayer(\Acme\PlayerBundle\Entity\Player $players)
{
$this->players[] = $players;
return $this;
}
/**
* Remove players
*
* #param Acme\PlayerBundle\Entity\Player $players
*/
public function removePlayer(\Acme\PlayerBundle\Entity\Player $players)
{
$this->players->removeElement($players);
}
/**
* Get players
*
* #return Doctrine\Common\Collections\Collection
*/
public function getPlayers()
{
return $this->players;
}
/**
* Add homeMatches
*
* #param Acme\MatchBundle\Entity\Match $homeMatches
* #return Team
*/
public function addHomeMatche(\Acme\MatchBundle\Entity\Match $homeMatches)
{
$this->homeMatches[] = $homeMatches;
return $this;
}
/**
* Remove homeMatches
*
* #param Acme\MatchBundle\Entity\Match $homeMatches
*/
public function removeHomeMatche(\Acme\MatchBundle\Entity\Match $homeMatches)
{
$this->homeMatches->removeElement($homeMatches);
}
/**
* Get homeMatches
*
* #return Doctrine\Common\Collections\Collection
*/
public function getHomeMatches()
{
return $this->homeMatches;
}
/**
* Add awayMatches
*
* #param Acme\MatchBundle\Entity\Match $awayMatches
* #return Team
*/
public function addAwayMatche(\Acme\MatchBundle\Entity\Match $awayMatches)
{
$this->awayMatches[] = $awayMatches;
return $this;
}
/**
* Remove awayMatches
*
* #param Acme\MatchBundle\Entity\Match $awayMatches
*/
public function removeAwayMatche(\Acme\MatchBundle\Entity\Match $awayMatches)
{
$this->awayMatches->removeElement($awayMatches);
}
/**
* Get awayMatches
*
* #return Doctrine\Common\Collections\Collection
*/
public function getAwayMatches()
{
return $this->awayMatches;
}
/**
* Set owner
*
* #param Acme\UserBundle\Entity\User $owner
* #return Team
*/
public function setOwner(\Acme\UserBundle\Entity\User $owner)
{
$this->owner = $owner;
return $this;
}
/**
* Get owner
*
* #return Acme\UserBundle\Entity\User
*/
public function getOwner()
{
return $this->owner;
}
}
Now I've created a player form class with the app/console and I've edited the team field to be an instance of the Team entity, this way:
<?php
namespace Acme\PlayerBundle\Form;
use Acme\TeamBundle\Entity\TeamRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class PlayerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('shirtNumber')
->add('firstname')
->add('lastname')
->add('role')
->add('team', 'entity', array(
'class' => 'AcmeTeamBundle:Team',
'query_builder' => function(TeamRepository $er) {
$query = $er->createQueryBuilder('t');
return $query;
}
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\PlayerBundle\Entity\Player',
'csrf_protection' => false
));
}
public function getName()
{
return 'player';
}
}
And this is the relevant part of my controller:
/**
* Create a new player
*
* #Route(".{_format}", name="api_player_create")
* #Method("POST")
* #ApiDoc(
* description="Create a new player",
* statusCodes={
* 201="Player created and informations are returned",
* 400="Missing informations",
* 403="The user isn't authorized"
* },
* input="Acme\PlayerBundle\Form\PlayerType",
* return="Acme\PlayerBundle\Entity\Player"
* )
*
* #return Renders the player just created
*/
public function createPlayerAction()
{
return $this->processForm(new Player());
}
/**
* Edit a player
*
* #param integer $id The id of the player to be created
*
* #Route("/{id}.{_format}", name="api_player_patch", requirements={ "id": "\d+" })
* #Method("PATCH")
* #ApiDoc(
* description="Edit a player",
* statusCodes={
* 200="Player is updated",
* 400="Missing informations",
* 403="The user isn't authorized"
* },
* input="Acme\PlayerBundle\Form\PlayerType",
* return="Acme\PlayerBundle\Entity\Player"
* )
*
* #return Renders the player just edited
*/
public function editPlayerAction(Player $player)
{
if ($player->getOwner() != $this->getUser()) {
throw new ApiException\PermissionDeniedException;
}
return $this->processForm($player);
}
/**
* Function to handle a form to create/edit a player
*
* #param Player $player The player to be created or edited
*
* #return Api Response
*/
private function processForm(Player $player)
{
/**
* Check if the player is new (to be created) or we're editing a player
*/
$statusCode = is_null($player->getId()) ? 201 : 200;
$form = $this->createForm(new PlayerType(), $player);
$form->bind($this->getRequest());
if ($form->isValid()) {
if($player->getTeam()->getOwner() != $this->getUser()) {
throw new ApiException\PermissionDeniedException;
}
$player->setOwner($this->getUser());
$this->entityManager->persist($player);
$this->entityManager->flush();
return $this->apiResponse->getResponse($player, $statusCode);
}
return $this->apiResponse->getResponse($form, 400, 'Missing arguments');
}
The player creation works fine, the player edit doesn't, when the user makes the api request, passing the ID in the url and the name of the player I get:
Catchable Fatal Error: Argument 1 passed to Acme\PlayerBundle\Entity\Player::setTeam() must be an instance of Acme\TeamBundle\Entity\Team, null given, called in /Volumes/Dati/Users/alessandro/Sites/acme-api/vendor/symfony/symfony/src/Symfony/Component/Form/Util/PropertyPath.php on line 538 and defined in /Volumes/Dati/Users/alessandro/Sites/acme-api/src/Acme/PlayerBundle/Entity/Player.php line 278
Seems that form is trying to set the Team to null, why?
I've tried both sending and not the team as the form parameters but it doesn't work.
Any clue?
Figured it out that null unsent fields in the form is the default behaviour in symfony.
There is an open request for partial form binding in symfony. For now a guy created a form event subscriber that adds the missing fields with the actual values:
https://gist.github.com/3720535
This is his code:
<?php
namespace Foo;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
/**
* Changes Form->bind() behavior so that it treats not set values as if they
* were sent unchanged.
*
* Use when you don't want fields to be set to NULL when they are not displayed
* on the page (or to implement PUT/PATCH requests).
*/
class PatchSubscriber implements EventSubscriberInterface
{
public function onPreBind(FormEvent $event)
{
$form = $event->getForm();
$clientData = $event->getData();
$clientData = array_replace($this->unbind($form), $clientData ?: array());
$event->setData($clientData);
}
/**
* Returns the form's data like $form->bind() expects it
*/
protected function unbind($form)
{
if ($form->hasChildren()) {
$ary = array();
foreach ($form->getChildren() as $name => $child) {
$ary[$name] = $this->unbind($child);
}
return $ary;
} else {
return $form->getClientData();
}
}
static public function getSubscribedEvents()
{
return array(
FormEvents::PRE_BIND => 'onPreBind',
);
}
}
to add to the form you have to edit the buildForm method in the form class:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$subscriber = new PatchSubscriber();
$builder->addEventSubscriber($subscriber);
$builder->add('name');
....
}
In this case you're ok to use the PATCH REST requests to edit an entity just by the sent fields

Resources