我有一个用户实体,可以向他的客户收费。因此,用户可以创建发票实体。我想要做的是通过汇总发票总额,能够轻松检索用户已收取的费用。我可以通过将$ user变量传递给汇总这些发票的方法,轻松地在我的发票存储库中执行此操作。但是我想将这个值存储在User实体中,所以在我的twig模板中,我可以用这样的方式调用它:{{app.user.chargedAmount}}
但据我所知,我无法在我的用户实体中创建一个getChargedAmount(),它将使用发票存储库并设置受保护的$ chargedAmount属性。
我应该如何在我的用户实体中存储此自定义值?
答案 0 :(得分:1)
有几种方法可以做到这一点,这些方法都不会涉及实体中的存储库。 (说实话,可能还有很多方法可以做到这一点。)
假设您的用户模型和发票模型使用oneToMany
关联,您可以在您的用户模型中使用一种方法,该方法可以循环关联的发票并即时获取总和。这意味着当前的总数不会持久存储到数据库中。
$totalCharged = null;
public function getTotalCharged()
{
if (null !== $totalCharged) {
return $totalCharged;
}
$totalCharged = 0;
foreach ($this->getInvoices() as $invoice) {
$totalCharged += $invoice->getTotal();
}
return $totalCharged;
}
您可以设置一个事件监听器,每次更改(创建,更新,删除)发票时都会监听,然后使用最终结果更新您的用户模型。 (假设您使用的是Doctrine ORM)。如果您尚未使用这些事件,则可能需要您更新控制器操作以包含事件。
use Doctrine\ORM\EntityRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
class UserInvoiceTotalChargedSubscriber implements EventSubscriberInterface
{
protected $invoiceRepository;
public function __construct(EntityRepository $invoiceRepository)
{
$this->invoiceRepository = $invoiceRepository;
}
public static function getSubscribedEvents()
{
return array(
'acme.invoice.create' => 'updateTotalCharged',
'acme.invoice.update' => 'updateTotalCharged',
'acme.invoice.remove' => 'updateTotalCharged',
);
}
public function updateTotalCharged(GenericEvent $event)
{
$invoice = $event->getSubject();
if (!$invoice instanceof InvoiceInterface) {
// Or Invoice if you are not using interfaces
throw new \Exception(
sprintf('Invoice expected, %s provided', get_class($invoice)
);
}
$user = $invoice->getUser();
$totalCharged = $this->invoiceRepository
->getTotalChargedForUser($user);
$user->setTotalCharged($totalCharged);
// This could be moved to a separate class that performed the
// calculation instead where you could call it like
// $this->totalChargedCalculator->calculate($invoice->getUser());
// Obviously this would need to be injected instead of the repository
}
}
如果您只想在树枝模板中访问此属性,则可以创建自定义树枝扩展并在其中调用它。您可以在{{ acme_invoice_total_charged(user) }}
模板中使用哪个,但这并不提供相同类型的可移植性。这(与选项1一样)意味着当前总数不会持久存储到数据库中。
class AcmeExtension extends \Twig_Extension
{
protected $invoiceRepository;
public function __construct(EntityRepository $invoiceRepository)
{
$this->invoiceRepository = $invoiceRepository;
}
public function getFunctions()
{
return array(
new \Twig_SimpleFunction(
'acme_invoice_total_charged',
array($this, 'getTotalChargedForUser')
),
);
}
public function getTotalChargedForUser(UserInterface $user)
{
return $this->invoiceRepository->getTotalChargedForUser($user);
}
public function getName()
{
return 'acme_invoice_extension';
}
}
答案 1 :(得分:0)
在您的UserRepository中,您可以创建一个自定义查询(例如findChargedAmount
)来检索收费金额。
public function findChargedAmount($user)
{
$em = $this->getEntityManager();
$query = $em->createQuery('SELECT SUM(i.total) AS amount FROM MyBundle:Invoice i WHERE i.user = :user');
$query->setParameter('user', $user);
$sum = $query->getResult();
return $sum[0]['amount'];
}
假设发票实体作为用户的外键。您还可以使用query builder。
构建此查询希望能帮助你。