symfony2, doctrine2, class inheritance - symfony

I'm playing a little with doctrine and symfony and i encountered a problem with this model.
I setup a base class ( entity ) and then a child class ( entity ), so far everything works smooth after that i wanted to add more fields to my table and i used doctrine:generate:entities BundleName. And here is the problem. If i do not set the variables from base class to protected symfony / doctrine says it cannot access that variable but if i set it as protected and generate the entities again it creates getters and setters for the protected variables from base class in my child class which i find it weird so i googled a little but i only found one topic about this problem and didn't had an answer for it.
The Base Class got set the annotation MappedSuperclass but .. didn't had any effect on it.
Base class which implements AdvancedUserInterface
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
/**
* #ORM\MappedSuperclass
*/
class BaseUser implements AdvancedUserInterface
{
/**
* #var string
* #ORM\Column(name="username", type="string", length=255, nullable=true)
*/
protected $username;
/**
* #var string
* #ORM\Column(name="password", type="string", length=255)
*/
protected $password;
/**
* #var bool
* #ORM\Column(name="isActive", type="boolean")
*/
protected $isActive = '0';
/**
* [$isAccountNonExpired description].
*
* #var bool
* #ORM\Column(name="isAccountNonExpired", type="boolean")
*/
protected $isAccountNonExpired = '1';
/**
* [$isAccountNonLocked description].
*
* #var bool
* #ORM\Column(name="isAccountNonLocked", type="boolean")
*/
protected $isAccountNonLocked = '0';
/**
* [$isCredentialsNonExpired description].
*
* #var bool
* #ORM\Column(name="isCredentialsNonExpired", type="boolean")
*/
protected $isCredentialsNonExpired = '0';
/**
* 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;
}
/**
* 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;
}
/**
* USER INTERFACE IMPLEMENTATION.
*/
public function getSalt()
{
// you *may* need a real salt depending on your encoder
// see section on salt below
}
public function getRoles()
{
return array('ROLE_ADMIN');
}
public function eraseCredentials()
{
return $this->plainPassword = null;
}
/**
* ADVANCED USER INTERFACE IMPLEMENTATION.
*/
/**
* 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 $this->isAccountNonExpired;
}
/**
* 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 $this->isAccountNonLocked;
}
/**
* 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 $this->isCredentialsNonExpired;
}
/**
* 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 $this->isActive;
}
/**
* Set isActive
*
* #param boolean $isActive
* #return BaseUser
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get isActive
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* Set isAccountNonExpired
*
* #param boolean $isAccountNonExpired
* #return BaseUser
*/
public function setIsAccountNonExpired($isAccountNonExpired)
{
$this->isAccountNonExpired = $isAccountNonExpired;
return $this;
}
/**
* Get isAccountNonExpired
*
* #return boolean
*/
public function getIsAccountNonExpired()
{
return $this->isAccountNonExpired;
}
/**
* Set isAccountNonLocked
*
* #param boolean $isAccountNonLocked
* #return BaseUser
*/
public function setIsAccountNonLocked($isAccountNonLocked)
{
$this->isAccountNonLocked = $isAccountNonLocked;
return $this;
}
/**
* Get isAccountNonLocked
*
* #return boolean
*/
public function getIsAccountNonLocked()
{
return $this->isAccountNonLocked;
}
/**
* Set isCredentialsNonExpired
*
* #param boolean $isCredentialsNonExpired
* #return BaseUser
*/
public function setIsCredentialsNonExpired($isCredentialsNonExpired)
{
$this->isCredentialsNonExpired = $isCredentialsNonExpired;
return $this;
}
/**
* Get isCredentialsNonExpired
*
* #return boolean
*/
public function getIsCredentialsNonExpired()
{
return $this->isCredentialsNonExpired;
}
}
And child class
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Gedmo\Mapping\Annotation as Gedmo;
use AppBundle\Entity\BaseUser;
/**
* User
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Zenith\UserBundle\Entity\UserRepository")
* #UniqueEntity(fields="email", message="Email already taken")
* #UniqueEntity(fields="username", message="Username already taken")
*/
class User extends BaseUser
{
/**
* #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)
* #Assert\Email()
* #Assert\NotBlank()
*/
private $email;
/**
* #var string
* #Assert\NotBlank()
* #Assert\Length(max = 4096)
*/
protected $plainPassword;
/**
* Date when the user needs to change his password
* for security reasons.
*
* #var datetime
*
* #ORM\Column(name="credentialsExpireAt", type="datetime", nullable=true)
*/
private $credentialsExpireAt;
/**
* Date when the account expires
* This can be used for temporary accounts.
*
* #var datetime
*
* #ORM\Column(name="accountExpireAt", type="datetime", nullable=true)
*/
private $accountExpireAt;
/**
* Saves last login date of the user.
*
* #var datetime
* #ORM\Column(name="lastLogin", type="datetime", nullable=true)
*/
private $lastLogin;
/**
*
*
* #ORM\Column(name="createdAt", type="datetime")
* #Gedmo\Timestampable(on="create")
*
* #var datetime
*/
private $createdAt;
/**
* #ORM\Column(name="editedAt", type="datetime")
* #Gedmo\Timestampable(on="update")
*
* #var datetime
*/
private $editedAt;
/**
* Get id
*
* #return integer
*/
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 credentialsExpireAt
*
* #param \DateTime $credentialsExpireAt
* #return User
*/
public function setCredentialsExpireAt($credentialsExpireAt)
{
$this->credentialsExpireAt = $credentialsExpireAt;
return $this;
}
/**
* Get credentialsExpireAt
*
* #return \DateTime
*/
public function getCredentialsExpireAt()
{
return $this->credentialsExpireAt;
}
/**
* Set accountExpireAt
*
* #param \DateTime $accountExpireAt
* #return User
*/
public function setAccountExpireAt($accountExpireAt)
{
$this->accountExpireAt = $accountExpireAt;
return $this;
}
/**
* Get accountExpireAt
*
* #return \DateTime
*/
public function getAccountExpireAt()
{
return $this->accountExpireAt;
}
/**
* Set lastLogin
*
* #param \DateTime $lastLogin
* #return User
*/
public function setLastLogin($lastLogin)
{
$this->lastLogin = $lastLogin;
return $this;
}
/**
* Get lastLogin
*
* #return \DateTime
*/
public function getLastLogin()
{
return $this->lastLogin;
}
/**
* Set createdAt
*
* #param \DateTime $createdAt
* #return User
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set editedAt
*
* #param \DateTime $editedAt
* #return User
*/
public function setEditedAt($editedAt)
{
$this->editedAt = $editedAt;
return $this;
}
/**
* Get editedAt
*
* #return \DateTime
*/
public function getEditedAt()
{
return $this->editedAt;
}
}

So what is the question? Why the command do so? Or how to use it in this case?
doctrine:generate:entities generates an entity class from it's mapping. The mapping may be described in different formats, and PHP annotation is only one of them (along with xml and yml). I suppose the logic works that way - first from annotations mapping is creating, and later from mapping (regardless how this mapping was described, and if properties were inherited on no) is generated a class.
So don't worry, remove unnecessary code and move on. This is only a tool that saves some time.

Related

Doctrine. One to many. How to write annotations?

I have a OneToMany relation between two tables 'user' and 'profil'
(a user has one only profile, and a profile can be asseigned to many users)
I'm getting this error whenever I try to update the schema in doctrine console.
here is my two entities :
<?php
namespace CNAM\CMSBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping\ManyToOne;
/**
* user
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class user
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=40)
*/
private $password;
public function __construct()
{
}
/**
* #var boolean
*
* #ORM\Column(name="etat", type="boolean")
*/
private $etat;
/**
* #var profil $profil
*
* #ORMManyToOne(targetEntity="profil", inversedBy="users", cascade={"persist", "merge"})
* #ORMJoinColumns({
* #ORMJoinColumn(name="profil", referencedColumnName="id")
* })
*/
private $profil;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set id
*
* #param integer $id
* #return user
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* 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;
}
/**
* Set etat
*
* #param boolean $etat
* #return user
*/
public function setEtat($etat)
{
$this->etat = $etat;
return $this;
}
/**
* Get etat
*
* #return boolean
*/
public function getEtat()
{
return $this->etat;
}
/**
* Get profil
*
* #return integer
*/
public function getProfil()
{
return $this->profil;
}
/**
* Set profil
*
* #param integer $profil
* #return user
*/
public function setProfil($profil)
{
$this->profil = $profil;
return $this;
}
public function getUsername()
{
return $this->id;
}
public function getRoles()
{
return array('ROLE_USER');
}
public function getSalt()
{
return null;
}
public function eraseCredentials()
{
}
public function equals(UserInterface $user)
{
return $user->getId() == $this->getId();
}
}
<?php
namespace CNAM\CMSBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping\OneToMany;
/**
* profil
*
* #ORM\Table(name="profil")
* #ORM\Entity
*/
class profil
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="libelle", type="string", length=20)
*/
private $libelle;
/**
* #var ArrayCollection $users
*
* #ORMOneToMany(targetEntity="user", mappedBy="profil", cascade={"persist", "remove", "merge"})
*/
private $users;
public function __construct()
{
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set libelle
*
* #param string $libelle
* #return profil
*/
public function setLibelle($libelle)
{
$this->libelle = $libelle;
return $this;
}
/**
* Get libelle
*
* #return string
*/
public function getLibelle()
{
return $this->libelle;
}
/**
* Set id
*
* #param integer $id
* #return profil
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
public function __toString() {
return $this->libelle;
}
}
You have syntax mistake.
#ORMManyToOne - this is mistake.
#ORM\ManyToOne(targetEntity="Profil", inversedBy="users")
Above will be correct. And everywhere you use ORM You need to write ORM\something. ORM - is just a namespace, or simply path to the ORM classes in doctrine vendor directory!
Every class name should start with capital letter. It is a wright way! So you should write class User, but not class user!
You didn't show in Profil class, that you have a lot of users to each profil. the users field will be of array collection type (simple array but with useful methods.) So in Profil class in __construct() method:
public function __construct()
{
$this->users = new ArrayCollection();
}
You have One-To-Many, Bidirectional relation.
You can say :
Every (ONE) profile can have a lot of (MANY) users, which use it (One-To-Many)
Every user can use only one exact profile
So try this
// Class Profil
/**
* Bidirectional - One-To-Many (INVERSED SIDE)
* One Profile can have many users, which use it
*
* #var ArrayCollection $users
*
* #ORM\OneToMany(targetEntity="Path-to-your-user-class\Users", mappedBy="profil", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
// Class user
/**
* Bidirectional - One-To-Many (OWNER SIDE)
* One user have only one profile (or profil)
*
* #var Profil $profil
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Profil", inversedBy="users")
* #ORM\JoinColumn(name="profil_id", referencedColumnName="id")
*/
private $profil;

How to get a sum of child object values in main entity by default

I have a PurchaseOrder entity and I have a Payments entity. Inside of the PurchaseOrder entity I'm trying to get the sum of Payments.amountPaid however it doesn't work as expected. Ideally the $allPaid should have a sum of all payments amountPaid for each PurchaseOrder. I was following this tutorial: enter link description here
Here is my PurchaseOrder entity:
class PurchaseOrder
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="RequestForEstimate", fetch="EAGER")
* #ORM\JoinColumn(name="request_id", referencedColumnName="request_id")
*/
private $request;
/**
* #ORM\OneToMany(targetEntity="Payment", mappedBy="purchaseOrder", orphanRemoval=true, cascade={"persist"}, fetch="EAGER")
*/
private $payments;
/**
* #var \DateTime
*
* #ORM\Column(name="create_time", type="datetime")
*/
private $createTime;
/**
* #var \DateTime
*
* #ORM\Column(name="update_time", type="datetime")
*/
private $updateTime;
/**
* #ORM\ManyToOne(targetEntity="PurchaseOrderStatus", cascade={"persist"})
*/
private $status;
/**
* #var \DateTime
*
* #ORM\Column(name="ship_date",type="datetime")
*/
private $shipDate;
private $allPaid = 0;
public function getAllPaid()
{
foreach ($this->payments as $payment) {
$this->allPaid += $payment->amountPaid();
}
return $this->allPaid;
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set createTime
*
* #param \DateTime $createTime
*
* #return PurchaseOrder
*/
public function setCreateTime($createTime)
{
$this->createTime = $createTime;
return $this;
}
/**
* Get createTime
*
* #return \DateTime
*/
public function getCreateTime()
{
return $this->createTime;
}
/**
* Set updateTime
*
* #param \DateTime $updateTime
*
* #return PurchaseOrder
*/
public function setUpdateTime($updateTime)
{
$this->updateTime = $updateTime;
return $this;
}
/**
* Get updateTime
*
* #return \DateTime
*/
public function getUpdateTime()
{
return $this->updateTime;
}
/**
* Set status
*
* #param integer $status
*
* #return PurchaseOrder
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* Get status
*
* #return int
*/
public function getStatus()
{
return $this->status;
}
/**
* Set shipDate
*
* #param \DateTime $shipDate
*
* #return PurchaseOrder
*/
public function setShipDate($shipDate)
{
$this->shipDate = $shipDate;
return $this;
}
/**
* Get shipDate
*
* #return \DateTime
*/
public function getShipDate()
{
return $this->shipDate;
}
/**
* Set requestForEstimate
*
* #param \InboundBundle\Entity\RequestForEstimate $requestForEstimate
*
* #return PurchaseOrder
*/
public function setRequestForEstimate(\InboundBundle\Entity\RequestForEstimate $requestForEstimate = null)
{
$this->requestForEstimate = $requestForEstimate;
return $this;
}
/**
* Get requestForEstimate
*
* #return \InboundBundle\Entity\RequestForEstimate
*/
public function getRequestForEstimate()
{
return $this->requestForEstimate;
}
/**
* Set requestId
*
* #param \InboundBundle\Entity\RequestForEstimate $requestId
*
* #return PurchaseOrder
*/
// public function setRequest(\InboundBundle\Entity\RequestForEstimate $request = null)
// {
// $this->request = $request;
// $request->setRequestId($this);
// return $this;
// }
public function setPayments(Payment $payments = null)
{
$this->payments = $payments;
return $this;
}
/**
* Get requestId
*
* #return \InboundBundle\Entity\RequestForEstimate
*/
public function getRequest()
{
return $this->request;
}
/**
* Set request
*
* #param \InboundBundle\Entity\RequestForEstimate $request
*
* #return PurchaseOrder
*/
/**
* Constructor
*/
public function __construct()
{
$this->payments = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add payment
*
* #param \InboundBundle\Entity\Payment $payment
*
* #return PurchaseOrder
*/
public function addPayment(\InboundBundle\Entity\Payment $payment)
{
$this->payments[] = $payment;
return $this;
}
/**
* Remove payment
*
* #param \InboundBundle\Entity\Payment $payment
*/
public function removePayment(\InboundBundle\Entity\Payment $payment)
{
$this->payments->removeElement($payment);
}
/**
* Get payments
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getPayments()
{
return $this->payments;
}
/**
* Set request
*
* #param \InboundBundle\Entity\RequestForEstimate $request
*
* #return PurchaseOrder
*/
public function setRequest(\InboundBundle\Entity\RequestForEstimate $request = null)
{
$this->request = $request;
return $this;
}
}
Payment entity:
class Payment
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="PurchaseOrder", inversedBy="payments", cascade={"persist", "detach"})
* #ORM\JoinColumn(name="purchase_order", referencedColumnName="id")
*/
private $purchaseOrder;
/**
* #var \DateTime
*
* #ORM\Column(name="create_time", type="datetime")
*/
private $createTime;
/**
* #var \DateTime
*
* #ORM\Column(name="update_time", type="datetime")
*/
private $updateTime;
/**
* #var int
*
* #ORM\Column(name="creator", type="integer")
*/
private $creator;
/**
* #var string
*
* #ORM\Column(name="amount_paid", type="decimal", precision=10, scale=2)
*/
private $amountPaid;
/**
* #ORM\ManyToOne(targetEntity="PaymentType", cascade={"persist"})
* #ORM\JoinColumn(name="payment_type", referencedColumnName="id")
*/
private $paymentType;
/**
* #var string
*
* #ORM\Column(name="external_transaction_id", type="string", length=255)
*/
private $externalTransactionId;
/**
* #var string
*
* #ORM\Column(name="including_fees", type="decimal", precision=10, scale=2)
*/
private $includingFees;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set createTime
*
* #param \DateTime $createTime
*
* #return Payment
*/
public function setCreateTime($createTime)
{
$this->createTime = $createTime;
return $this;
}
/**
* Get createTime
*
* #return \DateTime
*/
public function getCreateTime()
{
return $this->createTime;
}
/**
* Set updateTime
*
* #param \DateTime $updateTime
*
* #return Payment
*/
public function setUpdateTime($updateTime)
{
$this->updateTime = $updateTime;
return $this;
}
/**
* Get updateTime
*
* #return \DateTime
*/
public function getUpdateTime()
{
return $this->updateTime;
}
/**
* Set creator
*
* #param integer $creator
*
* #return Payment
*/
public function setCreator($creator)
{
$this->creator = $creator;
return $this;
}
/**
* Get creator
*
* #return integer
*/
public function getCreator()
{
return $this->creator;
}
/**
* Set amountPaid
*
* #param string $amountPaid
*
* #return Payment
*/
public function setAmountPaid($amountPaid)
{
$this->amountPaid = $amountPaid;
return $this;
}
/**
* Get amountPaid
*
* #return string
*/
public function getAmountPaid()
{
return $this->amountPaid;
}
/**
* Set paymentType
*
* #param string $paymentType
*
* #return Payment
*/
public function setPaymentType($paymentType)
{
$this->paymentType = $paymentType;
return $this;
}
/**
* Get paymentType
*
* #return string
*/
public function getPaymentType()
{
return $this->paymentType;
}
/**
* Set externalTransactionId
*
* #param string $externalTransactionId
*
* #return Payment
*/
public function setExternalTransactionId($externalTransactionId)
{
$this->externalTransactionId = $externalTransactionId;
return $this;
}
/**
* Get externalTransactionId
*
* #return string
*/
public function getExternalTransactionId()
{
return $this->externalTransactionId;
}
/**
* Set includingFees
*
* #param string $includingFees
*
* #return Payment
*/
public function setIncludingFees($includingFees)
{
$this->includingFees = $includingFees;
return $this;
}
/**
* Get includingFees
*
* #return string
*/
public function getIncludingFees()
{
return $this->includingFees;
}
/**
* Set purchaseOrder
*
* #param \InboundBundle\Entity\PurchaseOrder $purchaseOrder
*
* #return Payment
*/
public function setPurchaseOrder(\InboundBundle\Entity\PurchaseOrder $purchaseOrder = null)
{
$this->purchaseOrder = $purchaseOrder;
return $this;
}
/**
* Get purchaseOrder
*
* #return \InboundBundle\Entity\PurchaseOrder
*/
public function getPurchaseOrder()
{
return $this->purchaseOrder;
}
}
When I dump the object it shows that the allPaid is 0 as set by default:
Matko's answer works, but your question makes implies that you're (or at least you were) missing something fundamental.
In your original code, the internal (private) allPaid property is initialized to zero. Your getAllPaid() method computes the actual value and returns it. As written, getAllPaid() will iterate over the payments collection every time it's invoked.
When you dump your entity, the $allPaid property is zero because you're dumping before getAllPaid() was invoked. If you call getAllPaid() and then dump, you'll see it contains the computed value. That is because getAllPaid() sets that value along the way. Or, instead of dumping (and seeing the uninitialized internal value), test by actually invoking getAllPaid() and see that the correct value is returned.
The weakness with Matko's solution is that it eagerly loads the collection every time. It's likely that there are some scenarios where you need to load a PurchaseOrder without loading all the payments.
Since $allPaid is private, you'll always be using getAllPaid() to access the value.
To improve your code, I would you memoize $allPaid
Initialize private $allPaid = null;. The semantics of null are more appropriate, because upon initialization, the value is not zero. It's unknown.
In getAllPaid(), add a check that $this->allPaid !== null, and if so, return early. That way, repeated calls to getAllPaid() don't recompute the value each time.
Be sure to clear the memo when the payments collection changes. PurchaseOrder::addPayment() and PurchaseOrder::removePayment() should both set $this->allPaid to null, forcing the value to be recomputed on the next time getAllPaid() is invoked.
Finally, remove the eager fetchmode on PurchaseOrder::payments. If you want to eagerly load them in cases where you know you'll need them, you can fetch-join them in your query.
You should use Doctrine2 postLoad event. The postLoad event occurs for an entity after the entity has been loaded into the current EntityManager from the database or after the refresh operation has been applied to it.
...
use Doctrine\ORM\Mapping as ORM;
...
/**
* ...
* #ORM\HasLifecycleCallbacks
* ...
*/
class PurchaseOrder
{
...
private $allPaid = null;
/**
* #ORM\PostLoad
*/
public function getAllPaid()
{
if (null === $this->allPaid) {
foreach ($this->payments as $payment) {
$this->allPaid += $payment->amountPaid();
}
}
return $this->allPaid;
}
}

Doctrine: Symfony 2 foreign key null just before flush

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..

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.

Symfony2 - PUGXMultiUserBundle - Cannot instantiate abstract class

I tried to install PUGXMultiUserBundle, now as I did all steps I tried to load the application (only the main location: http://localhost/jpp/web/app_dev.php ), but I always get the following error:
Fatal error: Cannot instantiate abstract class JPP\UserBundle\Entity\User in C:\xampp\htdocs\JPP\vendor\symfony\symfony\src\Symfony\Component\Security\Core\Authentication\Token\AbstractToken.php on line 155
I tried several things without success, please could you help me? Below you can find my Entity classes. I was able to create all the tables in the database with GIT. The rentity classes are located under: JPP/UserBundle/Entity. If you need more files please tell me... Thank you very much!!!
Roger
Abstract User Class:
<?php
namespace JPP\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Entity\User as BaseUser;
/**
* #ORM\Entity
* #ORM\Table(name="user")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap({"userprofile" = "UserProfile", "usercompany" = "UserCompany"})
*
*/
abstract class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
}
Class UserCompany
<?php
// src/jpp/UserBundle/Entity/User.php
namespace JPP\UserBundle\Entity;
use PUGX\MultiUserBundle\Validator\Constraints\UniqueEntity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="userCompany")
* #UniqueEntity(fields = "username", targetClass = "JPP\UserBundle\Entity\User", message="fos_user.username.already_used")
* #UniqueEntity(fields = "email", targetClass = "JPP\UserBundle\Entity\User", message="fos_user.email.already_used")
*/
class UserCompany extends User
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var integer
*
* #ORM\Column(name="usertype", type="integer")
*/
protected $userType;
/**
* #var string
*
* #ORM\Column(name="companyName", type="string", length=255)
*/
protected $companyName;
/**
* #var string
*
* #ORM\Column(name="sector", type="string", length=255)
*/
protected $sector;
/**
* #var string
*
* #ORM\Column(name="amountOfEmployees", type="string", length=255)
*/
protected $amountOfEmployees;
/**
* #var string
*
* #ORM\Column(name="turnover", type="string", length=255)
*/
protected $turnover;
/**
* #var string
*
* #ORM\Column(name="companyLink", type="string", length=255)
*/
protected $companyLink;
/**
* #var string
*
* #ORM\Column(name="facebookLink", type="string", length=255)
*/
protected $facebookLink;
/**
* #var string
*
* #ORM\Column(name="twitterLink", type="string", length=255)
*/
protected $twitterLink;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set userType
*
* #param integer $userType
* #return UserType
*/
public function setUserType($userType)
{
$this->userType = $userType;
return $this;
}
/**
* Get userType
*
* #return integer
*/
public function getUserType()
{
return $this->userType;
}
/**
* Set companyName
*
* #param string $companyName
* #return Company
*/
public function setCompanyName($companyName)
{
$this->companyName = $companyName;
return $this;
}
/**
* Get companyName
*
* #return string
*/
public function getCompanyName()
{
return $this->companyName;
}
/**
* Set sector
*
* #param string $sector
* #return Company
*/
public function setSector($sector)
{
$this->sector = $sector;
return $this;
}
/**
* Get sector
*
* #return string
*/
public function getSector()
{
return $this->sector;
}
/**
* Set amountOfEmployees
*
* #param string $amountOfEmployees
* #return Company
*/
public function setAmountOfEmployees($amountOfEmployees)
{
$this->amountOfEmployees = $amountOfEmployees;
return $this;
}
/**
* Get amountOfEmployees
*
* #return string
*/
public function getAmountOfEmployees()
{
return $this->amountOfEmployees;
}
/**
* Set turnover
*
* #param string $turnover
* #return Company
*/
public function setTurnover($turnover)
{
$this->turnover = $turnover;
return $this;
}
/**
* Get turnover
*
* #return string
*/
public function getTurnover()
{
return $this->turnover;
}
/**
* Set companyLink
*
* #param string $companyLink
* #return Company
*/
public function setCompanyLink($companyLink)
{
$this->companyLink = $companyLink;
return $this;
}
/**
* Get companyLink
*
* #return string
*/
public function getCompanyLink()
{
return $this->companyLink;
}
/**
* Set facebookLink
*
* #param string $facebookLink
* #return Company
*/
public function setFacebookLink($facebookLink)
{
$this->facebookLink = $facebookLink;
return $this;
}
/**
* Get facebookLink
*
* #return string
*/
public function getFacebookLink()
{
return $this->facebookLink;
}
/**
* Set twitterLink
*
* #param string $twitterLink
* #return Company
*/
public function setTwitterLink($twitterLink)
{
$this->twitterLink = $twitterLink;
return $this;
}
/**
* Get twitterLink
*
* #return string
*/
public function getTwitterLink()
{
return $this->twitterLink;
}
}
Class UserProfile
// src/jpp/UserBundle/Entity/User.php
namespace JPP\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use PUGX\MultiUserBundle\Validator\Constraints\UniqueEntity;
/**
* #ORM\Entity
* #ORM\Table(name="userProfile")
* #UniqueEntity(fields = "username", targetClass = "JPP\UserBundle\Entity\User", message="fos_user.username.already_used")
* #UniqueEntity(fields = "email", targetClass = "JPP\UserBundle\Entity\User", message="fos_user.email.already_used")
*/
class UserProfile extends User
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var integer
*
* #ORM\Column(name="usertype", type="integer")
*/
protected $userType;
/**
* #ORM\Column(type="string", length=255)
*
*/
protected $foreName;
/**
* #ORM\Column(type="string", length=255)
*
*/
protected $surName;
/**
* #ORM\Column(type="string", length=255)
*
*/
protected $street;
/**
* #ORM\Column(type="string", length=255)
*
*/
protected $plz;
/**
* #ORM\Column(type="string", length=255)
*
*/
protected $place;
/**
* #ORM\Column(type="string", length=255)
*
*/
protected $phone;
/**
* #ORM\Column(type="string", length=255)
*
*/
protected $mobile;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set userType
*
* #param integer $userType
* #return UserType
*/
public function setUserType($userType)
{
$this->userType = $userType;
return $this;
}
/**
* Get userType
*
* #return integer
*/
public function getUserType()
{
return $this->userType;
}
/**
* Set foreName
*
* #param string $foreName
* #return ForeName
*/
public function setForeName($foreName)
{
$this->foreName = $foreName;
return $this;
}
/**
* Get foreName
*
* #return string
*/
public function getForeName()
{
return $this->foreName;
}
/**
* Set surName
*
* #param string $surName
* #return SurName
*/
public function setSurName($surName)
{
$this->surName = $surName;
return $this;
}
/**
* Get surName
*
* #return string
*/
public function getSurName()
{
return $this->surName;
}
/**
* Set street
*
* #param string $street
* #return Street
*/
public function setStreet($street)
{
$this->street = $street;
return $this;
}
/**
* Get street
*
* #return string
*/
public function getStreet()
{
return $this->street;
}
/**
* Set plz
*
* #param string $plz
* #return PLZ
*/
public function setPlz($plz)
{
$this->plz = $plz;
return $this;
}
/**
* Get plz
*
* #return string
*/
public function getPlz()
{
return $this->plz;
}
/**
* Set place
*
* #param string $place
* #return Place
*/
public function setPlace($place)
{
$this->place = $place;
return $this;
}
/**
* Get place
*
* #return string
*/
public function getPlace()
{
return $this->place;
}
/**
* Set phone
*
* #param string $phone
* #return Phone
*/
public function setPhone($phone)
{
$this->phone = $phone;
return $this;
}
/**
* Get phone
*
* #return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* Set mobile
*
* #param string $mobile
* #return Mobile
*/
public function setMobile($mobile)
{
$this->mobile = $mobile;
return $this;
}
/**
* Get mobile
*
* #return string
*/
public function getMobile()
{
return $this->mobile;
}
//public function __construct()
//{
// parent::__construct();
// your own logic
//}
}
The error says:
Fatal error: Cannot instantiate abstract class JPP\UserBundle\Entity\User in C:\xampp\htdocs\JPP\vendor\symfony\symfony\src\Symfony\Component\Security\Core\Authentication\Token\AbstractToken.php on line 155
It means that Symfony tries to instantiante your User class (e.g. new User()) but fails because this class is abstract. So, just remove abstract definition.
Replace
abstract class User extends BaseUser
with
class User extends BaseUser

Resources