BudgetItem
与ManyToOne
与Budget
和Product
相关联。以下是3个实体:
BudgetItem
<?php
namespace CDGBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use CDGBundle\Entity\Product;
/**
* BudgetItem
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="CDGBundle\Entity\Repository\BudgetItemRepository")
* @ORM\HasLifecycleCallbacks
*/
class BudgetItem
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Product")
* @ORM\JoinColumn(nullable=false)
*/
private $product;
/**
* @var integer
*
* @ORM\Column(name="meters", type="integer")
*/
private $meters;
/**
* @var string
*
* @ORM\Column(name="price", type="decimal", scale=2)
*/
private $price;
/**
* @ORM\ManyToOne(targetEntity="Budget", inversedBy="items")
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
*/
private $budget;
/**
* To String
*
* @return string
*/
public function __toString()
{
return $this->getProduct()->getName();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set budget
*
* @param integer $budget
*
* @return BudgetItem
*/
public function setBudget(Budget $budget)
{
$this->budget = $budget;
return $this;
}
/**
* Get budget
*
* @return integer
*/
public function getBudget()
{
return $this->budget;
}
/**
* Set product
*
* @param integer $product
*
* @return BudgetItem
*/
public function setProduct(Product $product = null)
{
$this->product = $product;
return $this;
}
/**
* Get product
*
* @return integer
*/
public function getProduct()
{
return $this->product;
}
/**
* Set meters
*
* @param integer $meters
*
* @return BudgetItem
*/
public function setMeters($meters)
{
$this->meters = $meters;
return $this;
}
/**
* Get meters
*
* @return integer
*/
public function getMeters()
{
return $this->meters;
}
/**
* Set price
*
* @param string $price
*
* @return BudgetItem
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* @return string
*/
public function getPrice()
{
return $this->price;
}
/**
* @return integer;
*/
public function decreaseProductMeters()
{
return $this->getProduct()->getMeters() - $this->getMeters();
}
/**
* @ORM\PrePersist
*/
public function onPreEvents()
{
$this->getProduct()->setMeters($this->decreaseProductMeters());
}
public function onFlush(\Doctrine\ORM\Event\OnFlushEventArgs $args)
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityUpdates() as $entity) {
$entity->getProduct();
$em->persist($entity);
$uow->recomputeSingleEntityChangeSet($em->getClassMetadata(get_class($entity)), $entity);
}
}
}
Budget
<?php
namespace CDGBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use CDGBundle\Entity\Customer;
use CDGBundle\Entity\BudgetItem;
/**
* Budget
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="CDGBundle\Entity\Repository\BudgetRepository")
* @ORM\HasLifecycleCallbacks
*/
class Budget
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var integer
*
* @ORM\ManyToOne(targetEntity="Customer", inversedBy="budgets")
*/
private $customer;
/**
* @var integer
*
* @ORM\OneToMany(targetEntity="BudgetItem", mappedBy="budget", cascade={"persist"})
*/
private $items;
/**
* @var string
*
* @ORM\Column(name="address", type="string", length=255)
*/
private $address;
/**
* @var integer
*
* @ORM\Column(name="installment_rate", type="integer")
*/
private $installmentRate;
/**
* @var integer
*
* @ORM\Column(name="check_for", type="integer")
*/
private $checkFor;
/**
* @var \DateTime
*
* @ORM\Column(name="starts_at", type="datetime", nullable=true)
*/
private $startsAt;
/**
* @var \DateTime
*
* @ORM\Column(name="deadline", type="datetime", nullable=true)
*/
private $deadline;
/**
* @var string
*
* @ORM\Column(name="is_approved", type="string", length=1, nullable=true)
*/
private $isApproved;
/**
* @var string
*
* @ORM\Column(name="has_started", type="string", length=1, nullable=true)
*/
private $hasStarted;
/**
* @var decimal
*
* @ORM\Column(name="installment_rate_price", type="decimal", scale=2, nullable=true)
*/
private $installmentRatePrice;
/**
* @var decimal
*
* @ORM\Column(name="total_budget_price", type="decimal", scale=2, nullable=true)
*/
private $totalBudgetPrice;
/**
* @var \DateTime
*
* @ORM\Column(name="next_payment_date", type="datetime", nullable=true)
*/
private $nextPaymentDate;
/**
* @var string
*
* @ORM\Column(name="is_paid", type="string", length=1)
*/
private $isPaid;
/**
* @var string
*
* @ORM\Column(name="obs", type="text", nullable=true)
*/
private $obs;
/**
* @var \DateTime
*
* @ORM\Column(name="created_at", type="datetime")
*/
private $createdAt;
/**
* Constructor
*/
public function __construct()
{
$this->items = new ArrayCollection();
$this->createdAt = new \DateTime();
$this->isPaid = 'n';
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set address
*
* @param string $address
*
* @return Budget
*/
public function setAddress($address)
{
$this->address = $address;
return $this;
}
/**
* Get address
*
* @return string
*/
public function getAddress()
{
return $this->address;
}
/**
* Set installmentRate
*
* @param integer $installmentRate
*
* @return Budget
*/
public function setInstallmentRate($installmentRate)
{
$this->installmentRate = $installmentRate;
return $this;
}
/**
* Get installmentRate
*
* @return integer
*/
public function getInstallmentRate()
{
return $this->installmentRate;
}
/**
* Set checkFor
*
* @param integer $checkFor
*
* @return Budget
*/
public function setCheckFor($checkFor)
{
$this->checkFor = $checkFor;
return $this;
}
/**
* Get checkFor
*
* @return integer
*/
public function getCheckFor()
{
return $this->checkFor;
}
/**
* Set startsAt
*
* @param \DateTime $startsAt
*
* @return Budget
*/
public function setStartsAt($startsAt)
{
$this->startsAt = $startsAt;
return $this;
}
/**
* Get startsAt
*
* @return \DateTime
*/
public function getStartsAt()
{
return $this->startsAt;
}
/**
* Set deadline
*
* @param \DateTime $deadline
*
* @return Budget
*/
public function setDeadline($deadline)
{
$this->deadline = $deadline;
return $this;
}
/**
* Get deadline
*
* @return \DateTime
*/
public function getDeadline()
{
return $this->deadline;
}
/**
* Set isApproved
*
* @param string $isApproved
*
* @return Budget
*/
public function setIsApproved($isApproved)
{
$this->isApproved = $isApproved;
return $this;
}
/**
* Get isApproved
*
* @return string
*/
public function getIsApproved()
{
return $this->isApproved;
}
/**
* Set hasStarted
*
* @param string $hasStarted
*
* @return Budget
*/
public function setHasStarted($hasStarted)
{
$this->hasStarted = $hasStarted;
return $this;
}
/**
* Get hasStarted
*
* @return string
*/
public function getHasStarted()
{
return $this->hasStarted;
}
/**
* Set installmentRatePrice
*
* @param string $installmentRatePrice
*
* @return Budget
*/
public function setInstallmentRatePrice($installmentRatePrice)
{
$this->installmentRatePrice = $installmentRatePrice;
return $this;
}
/**
* Get installmentRatePrice
*
* @return string
*/
public function getInstallmentRatePrice()
{
return $this->installmentRatePrice;
}
/**
* Set totalBudgetPrice
*
* @param string $totalBudgetPrice
*
* @return Budget
*/
public function setTotalBudgetPrice($totalBudgetPrice)
{
$this->totalBudgetPrice = $totalBudgetPrice;
return $this;
}
/**
* Get totalBudgetPrice
*
* @return string
*/
public function getTotalBudgetPrice()
{
return $this->totalBudgetPrice;
}
/**
* Set nextPaymentDate
*
* @param \DateTime $nextPaymentDate
*
* @return Budget
*/
public function setNextPaymentDate($nextPaymentDate)
{
$this->nextPaymentDate = $nextPaymentDate;
return $this;
}
/**
* Get nextPaymentDate
*
* @return \DateTime
*/
public function getNextPaymentDate()
{
return $this->nextPaymentDate;
}
/**
* Set isPaid
*
* @param string $isPaid
*
* @return Budget
*/
public function setIsPaid($isPaid)
{
$this->isPaid = $isPaid;
return $this;
}
/**
* Get isPaid
*
* @return string
*/
public function getIsPaid()
{
return $this->isPaid;
}
/**
* Set obs
*
* @param string $obs
*
* @return Budget
*/
public function setObs($obs)
{
$this->obs = $obs;
return $this;
}
/**
* Get obs
*
* @return string
*/
public function getObs()
{
return $this->obs;
}
/**
* Set createdAt
*
* @param \DateTime $createdAt
*
* @return Budget
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Set customer
*
* @param Customer $customer
*
* @return Budget
*/
public function setCustomer(Customer $customer = null)
{
$this->customer = $customer;
return $this;
}
/**
* Get customer
*
* @return Customer
*/
public function getCustomer()
{
return $this->customer;
}
/**
* Add item
*
* @param BudgetItem $item
*
* @return Budget
*/
public function addItem(BudgetItem $item)
{
$item->setBudget($this);
$this->items->add($item);
return $this;
}
/**
* Remove item
*
* @param BudgetItem $item
*/
public function removeItem(BudgetItem $item)
{
$this->items->removeElement($item);
}
/**
* Get items
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getItems()
{
return $this->items;
}
/**
* @return \DateTime
*/
public function generateNextPaymentDate()
{
if ($this->getStartsAt() !== null) {
$date = new \DateTime($this->getStartsAt()->format('Y-m-d'));
return $date->add(new \DateInterval('P' . $this->getCheckFor() . 'D'));
}
}
/**
* @return decimal
*/
public function calculateTotalBudgetPrice()
{
$totalBudgetPrice = 0;
foreach ($this->getItems() as $item) {
$totalBudgetPrice += $item->getPrice();
}
return $totalBudgetPrice;
}
/**
* @return decimal
*/
public function calculateInstallmentRatePrice()
{
return $this->calculateTotalBudgetPrice() / $this->getInstallmentRate();
}
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function onPreEvents()
{
$this->setNextPaymentDate($this->generateNextPaymentDate());
$this->setInstallmentRatePrice($this->calculateInstallmentRatePrice());
$this->setTotalBudgetPrice($this->calculateTotalBudgetPrice());
}
}
Product
<?php
namespace CDGBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use CDGBundle\Entity\ProductType;
/**
* Product
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="CDGBundle\Entity\Repository\ProductRepository")
* @ORM\HasLifecycleCallbacks
*/
class Product
{
/**
* @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;
/**
* @var string
*
* @ORM\ManyToOne(targetEntity="ProductType")
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
*/
private $type;
/**
* @var string
*
* @ORM\Column(name="price", type="decimal", scale=2)
*/
private $price;
/**
* @var integer
*
* @ORM\Column(name="meters", type="integer", nullable=true)
*/
private $meters;
/**
* @var string
*
* @ORM\Column(name="description", type="text", nullable=true)
*/
private $description;
/**
* @var \DateTime
*
* @ORM\Column(name="created_at", type="datetime")
*/
private $createdAt;
/**
* Constructor
*/
public function __construct()
{
$this->createdAt = new \DateTime();
}
/**
* To String
*
* @return string
*/
public function __toString()
{
return $this->name;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Product
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set type
*
* @param \CDGBundle\Entity\ProductType $type
*
* @return Product
*/
public function setType(ProductType $type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return \CDGBundle\Entity\ProductType
*/
public function getType()
{
return $this->type;
}
/**
* Set price
*
* @param string $price
*
* @return Product
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* @return string
*/
public function getPrice()
{
return $this->price;
}
/**
* Set meters
*
* @param integer $meters
*
* @return Product
*/
public function setMeters($meters)
{
$this->meters = $meters;
return $this;
}
/**
* Get meters
*
* @return integer
*/
public function getMeters()
{
return $this->meters;
}
/**
* Set description
*
* @param string $description
*
* @return Product
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set createdAt
*
* @param \DateTime $createdAt
*
* @return Product
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
}
Product
是Budget
内的集合表单。它列出了在注册新预算时要选择的所有注册产品。我有所有必要的JavaScript和宏来显示表单。
在编辑现有meters
时,我需要更新Product
实体的Budget
总金额。我在onFlush
内有一个BudgetItem
方法:
public function onFlush(\Doctrine\ORM\Event\OnFlushEventArgs $args)
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityUpdates() as $entity) {
$entity->getItems();
$em->persist($entity);
$uow->recomputeSingleEntityChangeSet($em->getClassMetadata(get_class($entity)), $entity);
}
}
现在这是我的问题。我不知道在foreach
方法中要做什么。我需要像在PrePersist
方法中那样做,但是我得到了不同的错误。
在循环内部,如果我$entity->getItems()
,我收到错误:
尝试调用名为&#34; getItems&#34;的未定义方法。类&#34; CDGBundle \ Entity \ BudgetItem&#34;。
如果我$entity->getProduct()
,则错误:
尝试调用名为&#34; getProduct&#34;的未定义方法。类&#34; CDGBundle \ Entity \ Budget&#34;。
为什么它会神奇地改变实体?为了上帝的缘故,有人帮助我。 Doctrine2有一个太复杂的更新事件。
答案 0 :(得分:0)
在Doctrine监听器中,您始终需要检查实体的类,因为每个更新的项都存储在getScheduledEntityUpdates()方法中。
解决方案是测试更新的实体是否为预算实例:
foreach ($uow->getScheduledEntityUpdates() as $entity) {
if ($entity instanceof Budget) {
// $entity is a Budget entity
// ... your code here
}
}