我有Customer
、Product
、Budget
和BudgetItem
实体。 Budget
与Customer
@ORM\ManyToOne和@ORM\OneToMany与BudgetItem
相关。 BudgetItem
与Product
和Budget
相关的@ORM\ManyToOne。
在BudgetItem
内部有一种计算先前选择的Products
的总价格的方法,然后保存到budget_itens
表中。更新项时,将再次执行代码并成功保存到数据库中。方法如下:
public function calculateTotalPrice()
{
return $this->getProduct()->getPrice() * $this->getMeters();
}
/**
* @ORMPrePersist
*/
public function onPreEvents()
{
$this->setPrice($this->calculateTotalPrice());
}
现在,我在Budget
里面有:
/**
* @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();
}
/**
* @ORMPrePersist
*/
public function onPreEvents()
{
$this->setNextPaymentDate($this->generateNextPaymentDate());
$this->setInstallmentRatePrice($this->calculateInstallmentRatePrice());
$this->setTotalBudgetPrice($this->calculateTotalBudgetPrice());
}
这些方法都没有在编辑Budget
后将其结果保存到数据库中。如果我理解得很好,似乎 Doctrine2 不会更新其他相关实体,但这些字段属于该实体。我还需要做什么?
编辑
BudgetController
,我坚持和冲洗的地方。
<?php
namespace CDGBundleController;
use SymfonyBundleFrameworkBundleControllerController;
use SymfonyComponentHttpFoundationRequest;
use CDGBundleEntityBudget;
use CDGBundleFormBudgetType;
class BudgetController extends Controller
{
/**
* Lista todos os orçamentos
*/
public function indexAction()
{
return $this->render('budget/index.html.twig', array(
'budgets' => $this->getDoctrine()->getRepository('CDGBundle:Budget')->findAll(),
'title' => 'Lista de Orçamentos'
));
}
/**
* Adicionar um novo orçamento
*
* @param Request $request
* @return SymfonyComponentHttpFoundationRedirectResponse|Response
*/
public function addAction(Request $request)
{
$budget = new Budget();
$form = $this->createForm(new BudgetType(), $budget);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($budget);
$em->flush();
return $this->redirectToRoute('budgets');
}
return $this->render('budget/add.html.twig', array(
'form' => $form->createView(),
'title' => 'Novo Orçamento'
));
}
/**
* Exibe os detalhes do orçamento selecionado
*
* @param integer $id
* @return Budget
*/
public function showAction($id)
{
$budget = $this->getDoctrine()->getRepository('CDGBundle:Budget')->find($id);
return $this->render('budget/show.html.twig', array(
'budget' => $budget,
'title' => 'Dados do orçamento #' . $budget->getId()
));
}
/**
* Edita as informações do orçamento selecionado
*
* @param integer $id
* @param Request $request
* @return SymfonyComponentHttpFoundationRedirectResponse|Response
*/
public function editAction($id, Request $request)
{
$budget = $this->getDoctrine()->getRepository('CDGBundle:Budget')->find($id);
$form = $this->createForm(new BudgetType(), $budget);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($budget);
$em->flush();
return $this->redirectToRoute('budgets');
}
return $this->render('budget/edit.html.twig', array(
'form' => $form->createView(),
'title' => 'Editar orçamento #' . $budget->getId()
));
}
/**
* Deleção de um orçamento
*
* @param integer $id
* @return Budget
*/
public function deleteAction($id)
{
$budget = $this->getDoctrine()->getRepository('CDGBundle:Budget')->find($id);
$em = $this->getDoctrine()->getManager();
$em->remove($budget);
$em->flush();
return $this->redirectToRoute('budgets');
}
}
我的Budget
课:
<?php
namespace CDGBundleEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineORMMapping as ORM;
use CDGBundleEntityCustomer;
use CDGBundleEntityBudgetItem;
/**
* Budget
*
* @ORMTable()
* @ORMEntity(repositoryClass="CDGBundleEntityRepositoryBudgetRepository")
* @ORMHasLifecycleCallbacks
*/
class Budget
{
/**
* @var integer
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var integer
*
* @ORMManyToOne(targetEntity="Customer", inversedBy="budgets")
*/
private $customer;
/**
* @var integer
*
* @ORMOneToMany(targetEntity="BudgetItem", mappedBy="budget", cascade={"persist"})
*/
private $items;
/**
* @var string
*
* @ORMColumn(name="address", type="string", length=255)
*/
private $address;
/**
* @var integer
*
* @ORMColumn(name="installment_rate", type="integer")
*/
private $installmentRate;
/**
* @var integer
*
* @ORMColumn(name="check_for", type="integer")
*/
private $checkFor;
/**
* @var DateTime
*
* @ORMColumn(name="starts_at", type="datetime", nullable=true)
*/
private $startsAt;
/**
* @var DateTime
*
* @ORMColumn(name="deadline", type="datetime", nullable=true)
*/
private $deadline;
/**
* @var string
*
* @ORMColumn(name="is_approved", type="string", length=1, nullable=true)
*/
private $isApproved;
/**
* @var string
*
* @ORMColumn(name="has_started", type="string", length=1, nullable=true)
*/
private $hasStarted;
/**
* @var decimal
*
* @ORMColumn(name="installment_rate_price", type="decimal", scale=2, nullable=true)
*/
private $installmentRatePrice;
/**
* @var decimal
*
* @ORMColumn(name="total_budget_price", type="decimal", scale=2, nullable=true)
*/
private $totalBudgetPrice;
/**
* @var DateTime
*
* @ORMColumn(name="next_payment_date", type="datetime", nullable=true)
*/
private $nextPaymentDate;
/**
* @var string
*
* @ORMColumn(name="is_paid", type="string", length=1)
*/
private $isPaid;
/**
* @var string
*
* @ORMColumn(name="obs", type="text", nullable=true)
*/
private $obs;
/**
* @var DateTime
*
* @ORMColumn(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[] = $item;
return $this;
}
/**
* Remove item
*
* @param BudgetItem $item
*/
public function removeItem(BudgetItem $item)
{
$this->items->removeElement($item);
}
/**
* Get items
*
* @return DoctrineCommonCollectionsCollection
*/
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();
}
/**
* @ORMPrePersist
* @ORMPreUpdate
*/
public function onPreEvents()
{
$this->setNextPaymentDate($this->generateNextPaymentDate());
$this->setInstallmentRatePrice($this->calculateInstallmentRatePrice());
$this->setTotalBudgetPrice($this->calculateTotalBudgetPrice());
}
}
编辑2
我刚刚意识到@ORM\PreUpdate正在工作,但仅适用于我的nextPaymentDate
。我在Budget
有一个collection
,ProductController
里面有一种收集产品信息的方法:
<?php
namespace CDGBundleController;
use SymfonyBundleFrameworkBundleControllerController;
use SymfonyComponentHttpFoundationRequest;
use CDGBundleEntityProduct;
use CDGBundleFormProductType;
use SymfonyComponentHttpFoundationJsonResponse;
class ProductController extends Controller
{
/**
* Lista todos os materials
*/
public function indexAction()
{
return $this->render('product/index.html.twig', array(
'products' => $this->getDoctrine()->getRepository('CDGBundle:Product')->findAll(),
'title' => 'Lista de Materiais'
));
}
/**
* Adicionar um novo material
*
* @param Request $request
* @return SymfonyComponentHttpFoundationRedirectResponse|Response
*/
public function addAction(Request $request)
{
$product = new Product();
$form = $this->createForm(new ProductType(), $product);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
return $this->redirectToRoute('products');
}
return $this->render('product/add.html.twig', array(
'form' => $form->createView(),
'title' => 'Novo Material'
));
}
/**
* Exibe os detalhes do material selecionado
*
* @param integer $id
* @return Product
*/
public function showAction($id)
{
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
return $this->render('product/show.html.twig', array(
'product' => $product,
'title' => 'Dados do material #' . $product->getId()
));
}
/**
* Edita as informações do material selecionado
*
* @param integer $id
* @param Request $request
* @return SymfonyComponentHttpFoundationRedirectResponse|Response
*/
public function editAction($id, Request $request)
{
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
$form = $this->createForm(new ProductType(), $product);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->merge($product);
$em->flush();
return $this->redirectToRoute('products');
}
return $this->render('product/edit.html.twig', array(
'form' => $form->createView(),
'title' => 'Editar material #' . $product->getId() . ' - ' . $product->getName()
));
}
/**
* Deleção de um material
*
* @param integer $id
* @return Product
*/
public function deleteAction($id)
{
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
$em = $this->getDoctrine()->getManager();
$em->remove($product);
$em->flush();
return $this->redirectToRoute('products');
}
/**
* Traz as informações do material selecionado na criação do orçamento.
*
* @param Request $request
* @return JsonResponse
*/
public function getProductInfoAction(Request $request)
{
$id = $request->query->get('id');
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
if ($request->query->get('format') == 'json') {
$data = array(
'id' => $product->getId(),
'name' => $product->getName(),
'price' => $product->getPrice(),
'meters' => $product->getMeters(),
'description' => $product->getDescription(),
'created_at' => $product->getCreatedAt()->format('d-m-Y H:i'),
);
return new JsonResponse($data, 200, array(
'Content-type' => 'application/json'
));
}
}
}
编辑它时似乎有问题,因为我遇到了一些错误,比如如果我在单击编辑后更改了一些产品信息,就像根本没有选择产品一样。
请参阅文档,特别是prePersist
应该注意的是,此事件仅在初始时触发 实体的持久性(即它不会在将来的更新中触发(。
因此,您还需要添加一个预更新侦听器。