Extend Exisiting Entity to override getters and setters - symfony

I want to override an existing Entity's getters and setters. Is it possible to do this?
I want to add additional logic to the getters and setters.
Thanks
Jake He

for this you must make an entity that extend that entity you want to override
e.g
my base entity
abstract class AbstractEntity
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var \DateTime
*
* #ORM\Column(type="datetime")
* #Gedmo\Timestampable(on="create")
*/
protected $createdAt;
/**
* #var \DateTime
*
* #ORM\Column(type="datetime", nullable=true)
* #Gedmo\Timestampable(on="update")
*/
protected $updatedAt;
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set createdAt
*
* #param \DateTime $createdAt
*
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
}
/**`enter code here`
* Get created
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set updatedAt
*
* #param \DateTime $updatedAt
*
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
}
/**
* Get updatedAt
*
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
}
and then in my entity
class Group extends BaseEntity
{
public function __construct()
{
$this->children = [];
$this->users = [];
$this->accounts = [];
$this->isActive = true;
}
/**
* Set updatedAt
*
* #param \DateTime $updatedAt
*
*/
public function setCreatedAt($createdAt)
{
parent::setCreatedAt($createdAt); //
TODO: Override the implementation
}
}
hope it will help

Related

The associationrefers to the owning side field e which is not defined as association, but as field

I'm making a blog project. So I have an article Class and a Commentaire Blog class.
But I'm having an error when I want to link boths :
[Mapping] FAIL - The entity-class 'AppBundle\Entity\Article' mapping
is invalid:
* The association AppBundle\Entity\Article#commentaires refers to the owning side field AppBundle\Entity\Commentaire_blog#message which is
not defined as association, but as field.
* The association AppBundle\Entity\Article#commentaires refers to the owning side field AppBundle\Entity\Commentaire_blog#message which does
not exist.
[Mapping] FAIL - The entity-class 'AppBundle\Entity\Commentaire_blog'
mapping is invalid:
* The mappings AppBundle\Entity\Commentaire_blog#article and AppBundle\Entity\Article#commentaires are inconsistent with each
other.
I'm a bit lost...
Here are my both Class :
* Article
*
* #ORM\Table(name="article")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ArticleRepository")
*/
class Article
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="Titre", type="text")
*/
private $titre;
/**
* #var string
*
* #ORM\Column(name="article", type="text")
*/
private $article;
/**
* #var \DateTime
*
* #ORM\Column(name="date_article", type="datetime")
*/
private $dateArticle;
/**
* #ORM\OneToMany(targetEntity="Commentaire_blog", mappedBy="messa")
*/
private $commentaires;
public function __construct()
{
$this->commentaires = new ArrayCollection();
}
/**
* #return Collection|Commentaire_blog[]
*/
public function getCommentaires()
{
return $this->commentaires;
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set titre
*
* #param string $titre
*
* #return Article
*/
public function setTitre($titre)
{
$this->titre = $titre;
return $this;
}
/**
* Get titre
*
* #return string
*/
public function getTitre()
{
return $this->titre;
}
/**
* Set article
*
* #param string $article
*
* #return Article
*/
public function setArticle($article)
{
$this->article = $article;
return $this;
}
/**
* Get article
*
* #return string
*/
public function getArticle()
{
return $this->article;
}
/**
* Set dateArticle
*
* #param \DateTime $dateArticle
*
* #return Article
*/
public function setDateArticle($dateArticle)
{
$this->dateArticle = $dateArticle;
return $this;
}
/**
* Get dateArticle
*
* #return \DateTime
*/
public function getDateArticle()
{
return $this->dateArticle;
}
And The second :
* Commentaire_blog
*
* #ORM\Table(name="commentaire_blog")
* #ORM\Entity(repositoryClass="AppBundle\Repository \Commentaire_blogRepository")
*/
class Commentaire_blog
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="usernamne", type="string", length=255)
*/
private $usernamne;
/**
* #var string
*
* #ORM\Column(name="message", type="text")
*/
private $message;
/**
* #var bool
*
* #ORM\Column(name="is_visible", type="boolean")
*/
private $isVisible;
/**
* #return mixed
*/
public function getArticle()
{
return $this->article;
}
/**
* #param mixed $article
*/
public function setArticle($article)
{
$this->article = $article;
}
/**
* #ORM\ManyToOne(targetEntity="Article", inversedBy="commentaires")
* #ORM\JoinColumn(nullable=true)
*/
private $article;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set usernamne
*
* #param string $usernamne
*
* #return Commentaire_blog
*/
public function setUsernamne($usernamne)
{
$this->usernamne = $usernamne;
return $this;
}
/**
* Get usernamne
*
* #return string
*/
public function getUsernamne()
{
return $this->usernamne;
}
/**
* Set message
*
* #param string $message
*
* #return Commentaire_blog
*/
public function setMessage($message)
{
$this->message = $message;
return $this;
}
/**
* Get message
*
* #return string
*/
public function getMessage()
{
return $this->message;
}
/**
* Set isVisible
*
* #param boolean $isVisible
*
* #return Commentaire_blog
*/
public function setIsVisible($isVisible)
{
$this->isVisible = $isVisible;
return $this;
}
/**
* Get isVisible
*
* #return bool
*/
public function getIsVisible()
{
return $this->isVisible;
}
}
Any Idea how to make the link correct...
Try this:
Class Article:
/**
* #ORM\OneToMany(targetEntity="Commentaire_blog", mappedBy="article")
*/
private $commentaires;
Class commentaire_blog:
/**
* #ORM\ManyToOne(targetEntity="Article", inversedBy="commentaires")
* #ORM\JoinColumn(nullable=true)
*/
private $article;
Also, consider converting the getCommentaires result to Array:
public function getCommentaires()
{
return $this->commentaires->toArray();
}
To understand more about the owning and inverse side of each relation try reading this: Associations: Owning and Inverse Side.

Cannot create an instance of DateTime from serialized data

I have a problem with the date.
Maybe I don't understand something in the process of serialization, but, when, I send a datetime to Api-Platform (Symfony) for example
dateEvaluation: "2017-12-05T11:52:00.000Z"
I obtain this message of error
Cannot create an instance of DateTime from serialized data because its constructor requires parameter "time" to be present.
This is my Entity
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ORM\Entity(repositoryClass="App\Repository\EvaluationRepository")
* #ORM\HasLifecycleCallbacks()
* #ApiResource(attributes={
* "normalization_context"={
* "groups"={"Evaluation"}
* }
* })
*/
class Evaluation
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
* #Groups({"NotesEvaluations", "Evaluation"})
*/
private $id;
/**
* #var \DateTime
* #ORM\Column(type="datetime")
* #Groups({"Evaluation"})
*/
private $created;
/**
* #var \DateTime
* #ORM\Column(type="datetime")
* #Groups({"Evaluation"})
*/
private $updated;
/**
* #var \DateTime
* #ORM\Column(type="datetime")
* #Groups({"Evaluation"})
*/
private $dateEvaluation;
/**
* #var string
*
* #ORM\Column(type="text")
* #Groups({"Evaluation"})
*/
private $commentaire;
/**
* #var
*
* #ORM\ManyToOne(targetEntity="App\Entity\Personnel")
* #Groups({"NotesEvaluations", "Evaluation"})
*/
private $auteur;
/**
* #var
*
* #ORM\ManyToMany(targetEntity="App\Entity\Personnel")
*/
private $autorises;
/**
* #var integer
*
* #ORM\Column(type="integer")
*/
private $annee;
/**
* #var
*
* #ORM\ManyToOne(targetEntity="App\Entity\Module", inversedBy="evaluations")
* #Groups({"Evaluation"})
*/
private $module;
/**
* #var Boolean
*
* #ORM\Column(type="boolean")
* #Groups({"NotesEvaluations"})
*/
private $visible;
/**
* #var Boolean
*
* #ORM\Column(type="boolean")
* #Groups({"NotesEvaluations"})
*/
private $modifiable;
/**
* #var
*
* #ORM\ManyToOne(targetEntity="App\Entity\TypeGroupe")
* #Groups({"Evaluation"})
*/
private $typegroupe;
/**
* #var float
*
* #ORM\Column(type="decimal")
* #Groups({"Evaluation"})
*/
private $coefficient;
/**
* #return float
*/
public function getCoefficient(): float
{
return $this->coefficient;
}
/**
* #return mixed
*/
public function getTypegroupe()
{
return $this->typegroupe;
}
/**
* #param mixed $typegroupe
*/
public function setTypegroupe($typegroupe): void
{
$this->typegroupe = $typegroupe;
}
/**
* #return \DateTime
*/
public function getDateEvaluation(): \DateTime
{
return $this->dateEvaluation;
}
/**
* #param \DateTime $dateEvaluation
*/
public function setDateEvaluation(\DateTime $dateEvaluation): void
{
$this->dateEvaluation = $dateEvaluation;
}
/**
* #return string
*/
public function getCommentaire(): string
{
return $this->commentaire;
}
/**
* #param string $commentaire
*/
public function setCommentaire(string $commentaire): void
{
$this->commentaire = $commentaire;
}
/**
* #param float $coefficient
*/
public function setCoefficient(float $coefficient): void
{
$this->coefficient = $coefficient;
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return \DateTime
*/
public function getCreated(): \DateTime
{
return $this->created;
}
/**
* #param \DateTime $created
*/
public function setCreated(\DateTime $created): void
{
$this->created = $created;
}
/**
* #return \DateTime
*/
public function getUpdated(): \DateTime
{
return $this->updated;
}
/**
* #param \DateTime $updated
*/
public function setUpdated(\DateTime $updated): void
{
$this->updated = $updated;
}
/**
* #return mixed
*/
public function getAuteur()
{
return $this->auteur;
}
/**
* #param mixed $auteur
*/
public function setAuteur($auteur): void
{
$this->auteur = $auteur;
}
/**
* #return mixed
*/
public function getAutorises()
{
return $this->autorises;
}
/**
* #param mixed $autorises
*/
public function setAutorises($autorises): void
{
$this->autorises = $autorises;
}
/**
* #return int
*/
public function getAnnee(): int
{
return $this->annee;
}
/**
* #param int $annee
*/
public function setAnnee(int $annee): void
{
$this->annee = $annee;
}
/**
* #return mixed
*/
public function getModule()
{
return $this->module;
}
/**
* #param mixed $module
*/
public function setModule($module): void
{
$this->module = $module;
}
/**
* #return bool
*/
public function isVisible(): bool
{
return $this->visible;
}
/**
* #param bool $visible
*/
public function setVisible(bool $visible): void
{
$this->visible = $visible;
}
/**
* #return bool
*/
public function isModifiable(): bool
{
return $this->modifiable;
}
/**
* #param bool $modifiable
*/
public function setModifiable(bool $modifiable): void
{
$this->modifiable = $modifiable;
}
/**
* #ORM\PreUpdate
*/
public function updateDate(): void
{
$this->setUpdated(new \Datetime());
}
public function __construct()
{
$this->setCreated(new \Datetime());
$this->setUpdated(new \Datetime());
}
}
I don't understand why "time" is missing. Maybe it is for created or updated fields ? Anyway, created and updated fields return with ApiPlatform an object with timezone ...
created:
{timezone: {name: "Europe/Paris",…}, offset: 561, timestamp: -62169984561}
offset:561
timestamp:-62169984561
timezone:{name: "Europe/Paris",…}
Thanks for your help.
David
I've found a way to manage this error that works for me. I declare the DateTimeNormalizer in my config.yml like that :
datetime_normalizer:
class: Symfony\Component\Serializer\Normalizer\DateTimeNormalizer
public: false
tags: [serializer.normalizer]
I hope that will help you !
In my case, I was using Symfony's Serializer Component without Symfony project and on the process of denormalization I had that issue so I had to add the DateTimeNormalizer before the ObjectNormalizer on the array of normalizers like this:
$serializer = new Serializer([new DateTimeNormalizer(), new ObjectNormalizer(null, new CamelCaseToSnakeCaseNameConverter())]);
Note that the order here is important.
In v1.1, using the class \DateTimeImmutable instead of \DateTime is what api-platform wait by default.
class Evaluation {
public function __construct()
{
$this->setCreated(new \DateTimeImmutable());
$this->setUpdated(new \DateTimeImmutable());
}
}
Change \DateTime in your entity to \DateTimeInterface. It should work.

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;
}
}

Sonata AdminBundle, get the parameter of an entity

I have an entity Prototype with a relation many to one with project and I want to override a function in the CRUDController.
Here is the code :
$idPrototype = $this->get('request')->get($this->admin->getIdParameter());
I get the id of the prototype, but I want the parameter 'project' ( the id of the project )
Here is my prototype entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Prototype
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Entity\PrototypeRepository")
*/
class Prototype
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="nom", type="string", length=255)
*/
private $nom;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255)
*/
private $description;
/**
* #var \DateTime
*
* #ORM\Column(name="dateCreation", type="date")
*/
private $dateCreation;
private $projet;
public function __construct()
{
$this->dateCreation = new \DateTime("now");
$this->nom = "";
$this->description = " ";
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
public function __toString()
{
return $this->getNom();
}
/**
* Set nom
*
* #param string $nom
* #return Prototype
*/
public function setNom($nom)
{
$this->nom = $nom;
return $this;
}
/**
* Set description
*
* #param string $description
* #return Prototype
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set dateCreation
*
* #param \DateTime $dateCreation
* #return Prototype
*/
public function setDateCreation($dateCreation)
{
$this->dateCreation = $dateCreation;
return $this;
}
/**
* Get dateCreation
*
* #return \DateTime
*/
public function getDateCreation()
{
return $this->dateCreation;
}
/**
* Set projet
*
* #param \AppBundle\Entity\Projet $projet
* #return Prototype
*/
public function setProjet(\AppBundle\Entity\Projet $projet = null)
{
$this->projet = $projet;
return $this;
}
/**
* Get projet
*
* #return \AppBundle\Entity\Projet
*/
public function getProjet()
{
return $this->projet;
}
}
I've tried to use ModelManager() but I get this error "Attempted to call an undefined method named "getModelManager" of class "AppBundle\Controller\CRUDProtoController". "
I'm new with sonata and symfony and I find difficulties with it.

Why Symfony and Doctrine uses __toString instead of getId when inserting/updateing record

I have a form with 4 realtionships but have a problem with 2 of them.
Here is code for my form:
<?php
namespace Psw\AdminBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class MeatType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name_pl')
->add('name_en')
->add('jm')
->add('vat')
->add('net_price')
->add('min')
->add('new')
->add('promotion', 'entity', array(
'class' => 'PswAdminBundle:Promotions',
'empty_value' => 'No promotion',
'required' => false
))
->add('promotion_price')
->add('producer', 'entity', array(
'class' => 'PswAdminBundle:MeatProducers'
))
->add('animals')
->add('categories')
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Psw\AdminBundle\Entity\Meat'
));
}
public function getName()
{
return 'psw_adminbundle_meattype';
}
}
And entities
Meat:
<?php
namespace Psw\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Meat
*
* #ORM\Table()
* #ORM\Entity
*/
class Meat
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name_pl", type="string", length=255)
*/
private $name_pl;
/**
* #var string
*
* #ORM\Column(name="name_en", type="string", length=255)
*/
private $name_en;
/**
* #var string
*
* #ORM\Column(name="jm", type="string", length=10)
*/
private $jm;
/**
* #var integer
*
* #ORM\Column(name="vat", type="integer")
*/
private $vat;
/**
* #var float
*
* #ORM\Column(name="net_price", type="float")
*/
private $net_price;
/**
* #var float
*
* #ORM\Column(name="min", type="float")
*/
private $min;
/**
* #var boolean
*
* #ORM\Column(name="new", type="boolean")
*/
private $new;
/**
* #var integer
*
* #ORM\Column(name="promotion", type="integer", nullable=true)
* #ORM\ManyToOne(targetEntity="Promotions")
*/
private $promotion;
/**
* #var float
*
* #ORM\Column(name="promotion_price", type="float")
*
*/
private $promotion_price;
/**
* #ORM\ManyToMany(targetEntity="Animals")
* #ORM\JoinTable(name="meat_animals",
* joinColumns={#ORM\JoinColumn(name="meat_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="animal_id", referencedColumnName="id")}
* )
**/
private $animals;
/**
* #ORM\ManyToMany(targetEntity="MeatCategories")
* #ORM\JoinTable(name="meat_meat_categories",
* joinColumns={#ORM\JoinColumn(name="meat_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="category_id", referencedColumnName="id")}
* )
**/
private $categories;
/**
* #ORM\Column(name="producer", type="integer")
*
* #ORM\ManyToOne(targetEntity="MeatProducers", inversedBy="products")
* #ORM\JoinColumn(name="producer", referencedColumnName="id")
**/
private $producer;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name_pl
*
* #param string $namePl
* #return Meat
*/
public function setNamePl($namePl)
{
$this->name_pl = $namePl;
return $this;
}
/**
* Get name_pl
*
* #return string
*/
public function getNamePl()
{
return $this->name_pl;
}
/**
* Set name_en
*
* #param string $nameEn
* #return Meat
*/
public function setNameEn($nameEn)
{
$this->name_en = $nameEn;
return $this;
}
/**
* Get name_en
*
* #return string
*/
public function getNameEn()
{
return $this->name_en;
}
/**
* Set jm
*
* #param string $jm
* #return Meat
*/
public function setJm($jm)
{
$this->jm = $jm;
return $this;
}
/**
* Get jm
*
* #return string
*/
public function getJm()
{
return $this->jm;
}
/**
* Set vat
*
* #param integer $vat
* #return Meat
*/
public function setVat($vat)
{
$this->vat = $vat;
return $this;
}
/**
* Get vat
*
* #return integer
*/
public function getVat()
{
return $this->vat;
}
/**
* Set net_price
*
* #param float $netPrice
* #return Meat
*/
public function setNetPrice($netPrice)
{
$this->net_price = $netPrice;
return $this;
}
/**
* Get net_price
*
* #return float
*/
public function getNetPrice()
{
return $this->net_price;
}
/**
* Set min
*
* #param float $min
* #return Meat
*/
public function setMin($min)
{
$this->min = $min;
return $this;
}
/**
* Get min
*
* #return float
*/
public function getMin()
{
return $this->min;
}
/**
* Set new
*
* #param boolean $new
* #return Meat
*/
public function setNew($new)
{
$this->new = $new;
return $this;
}
/**
* Get new
*
* #return boolean
*/
public function getNew()
{
return $this->new;
}
/**
* Set promotion
*
* #param integer $promotion
* #return Meat
*/
public function setPromotion($promotion)
{
$this->promotion = $promotion;
return $this;
}
/**
* Get promotion
*
* #return integer
*/
public function getPromotion()
{
return $this->promotion;
}
/**
* Constructor
*/
public function __construct()
{
$this->animals = new ArrayCollection();
$this->categories = new ArrayCollection();
}
/**
* Add animals
*
* #param \Psw\AdminBundle\Entity\Animals $animals
* #return Meat
*/
public function addAnimal(\Psw\AdminBundle\Entity\Animals $animals)
{
$this->animals[] = $animals;
return $this;
}
/**
* Remove animals
*
* #param \Psw\AdminBundle\Entity\Animals $animals
*/
public function removeAnimal(\Psw\AdminBundle\Entity\Animals $animals)
{
$this->animals->removeElement($animals);
}
/**
* Get animals
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getAnimals()
{
return $this->animals;
}
/**
* Add categories
*
* #param \Psw\AdminBundle\Entity\Meat_categories $categories
* #return Meat
*/
public function addCategorie(\Psw\AdminBundle\Entity\Meat_categories $categories)
{
$this->categories[] = $categories;
return $this;
}
/**
* Remove categories
*
* #param \Psw\AdminBundle\Entity\Meat_categories $categories
*/
public function removeCategorie(\Psw\AdminBundle\Entity\Meat_categories $categories)
{
$this->categories->removeElement($categories);
}
/**
* Get categories
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCategories()
{
return $this->categories;
}
/**
* Set producer
*
* #param \Psw\AdminBundle\Entity\MeatProducers $producer
* #return Meat
*/
public function setProducer(\Psw\AdminBundle\Entity\MeatProducers $producer = null)
{
$this->producer = $producer;
return $this;
}
/**
* Get producer
*
* #return \Psw\AdminBundle\Entity\MeatProducers
*/
public function getProducer()
{
return $this->producer;
}
/**
* Set promotion_price
*
* #param float $promotionPrice
* #return Meat
*/
public function setPromotionPrice($promotionPrice)
{
$this->promotion_price = $promotionPrice;
return $this;
}
/**
* Get promotion_price
*
* #return float
*/
public function getPromotionPrice()
{
return $this->promotion_price;
}
}
MeatProducers:
<?php
namespace Psw\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* MeatProducers
*
* #ORM\Table()
* #ORM\Entity
*/
class MeatProducers
{
/**
* #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)
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="Meat", mappedBy="producer")
**/
private $products;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return MeatProducers
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
public function __toString()
{
return $this->name;
}
/**
* Constructor
*/
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add products
*
* #param \Psw\AdminBundle\Entity\Meat $products
* #return MeatProducers
*/
public function addProduct(\Psw\AdminBundle\Entity\Meat $products)
{
$this->products[] = $products;
return $this;
}
/**
* Remove products
*
* #param \Psw\AdminBundle\Entity\Meat $products
*/
public function removeProduct(\Psw\AdminBundle\Entity\Meat $products)
{
$this->products->removeElement($products);
}
/**
* Get products
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProducts()
{
return $this->products;
}
}
There are no problems with many to many raltions on Animals and Categories.
But Promotions and Producers where i have many to one cause some issues.
Problem is that when trying to insert/update record doctrine calls __toString method instead of getId to obtain value to put into database.
I have working example like this with other entities, they are almost the same but in this case it just does not want to work.
Controller code is from crud generator, I didn't change anything there if necessary I may post it.
Question is how to make it use getId method?
The issue here is not with the __toString, it lies in your mapping annotation. You should not use #Column for association mappings. Instead, use #JoinColumn:
/**
* #ORM\ManyToOne(targetEntity="Promotions")
* #ORM\JoinColumn(name="promotion_id", referencedColumnName="id")
*/
private $promotion;

Resources