根据会话值选择实体 [英] Select entity based on session value
问题描述
我有两个实体.一个是 WebshopItem 实体,另一个是 WebshopPrice 实体.每次,您在创建一个 WebshopItem 的同时,也填写了 3 个 WebshopPrices.网上商店价格是 3 种货币(欧元、美元和英镑).
I got two entities. One is a WebshopItem entity, the other one is a WebshopPrice entity. Each time, you are creating a WebshopItem, you are also filling in 3 WebshopPrices. The WebshopPrices are 3 currencies (EUR, USD and GBP).
根据您选择的货币(并保存在您的会话中),我想显示您选择的货币.所以,如果你选择了 EUR,我当然想显示 EUR 的价格.
Based on the currency you selected (and is saved in your session) I want to display the currency you selected. So, if you picked EUR, I of course want to display the EUR price.
在 symfony 中执行此操作的一般方法是什么?我应该根据会话中的内容使用从 WebshopItem 对象返回价格的树枝扩展吗?我应该已经从数据库中过滤 WebshopPrices 了吗?
What's the general way of doing this in symfony? Should I use a twig extension which returns the price from the WebshopItem object, based on what's in your session? Should I already filter the WebshopPrices from the database?
期待您的最佳解决方案.谢谢!
Looking forward to your best solutions. Thanks!
实体/WebshopItem.php
Entity/WebshopItem.php
class WebshopItem
{
/**
* @var \Doctrine\Common\Collections\Collection
*/
private $prices;
etc....
}
实体/WebshopItemPrice.php
Entity/WebshopItemPrice.php
class WebshopItemPrice
{
/**
* @var integer
*/
private $id;
/**
* @var string
*/
private $currency;
/**
* @var string
*/
private $price;
private $webshopItem;
}
推荐答案
UPDATE
您可以使用实体侦听器也是,但在这种情况下,您需要覆盖默认解析器以在您的侦听器中获取会话:
You can use an entity listener too, but in that case you'll need to override the default resolver to get the session in your listener:
src/Your/GreatBundle/Resources/config/services.yml
doctrine.orm.default_entity_listener_resolver:
class: Your\GreatBundle\Listener\EntityListenerResolver
arguments: [@service_container]
src/Your/GreatBundle/Listener/EntityListenerResolver
namespace Your\GreatBundle\Listener;
use Doctrine\ORM\Mapping\EntityListenerResolver as EntityListenerResolverInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class EntityListenerResolver implements EntityListenerResolverInterface
{
private $instances = [];
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function clear($className = null)
{
if ($className === null) {
$this->instances = [];
return;
}
if (isset($this->instances[$className = trim($className, '\\')])) {
unset($this->instances[$className]);
}
}
public function register($object)
{
if ( ! is_object($object)) {
throw new \InvalidArgumentException(sprintf('An object was expected, but got "%s".', gettype($object)));
}
$this->instances[get_class($object)] = $object;
}
public function resolve($className)
{
if (isset($this->instances[$className = trim($className, '\\')])) {
return $this->instances[$className];
}
// Here we are injecting the entire container to the listeners
return $this->instances[$className] = new $className($this->container);
}
}
<小时>
您可能会听到 Doctrine 的 postLoad 事件在注入用户会话的服务中:
You might listen to the Doctrine's postLoad event in a service injected with the user's session:
src/Your/GreatBundle/Resources/config/services.yml
services:
price.listener:
class: Your\GreatBundle\Listener\PriceListener
arguments: [@session]
tags:
- { name: doctrine.event_listener, event: postLoad }
src/Your/GreatBundle/Listener/PriceListener.php
namespace Your\GreatBundle\Listener\PriceListener;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Your\GreatBundle\Entity\WebshopItem;
class PriceListener
{
private $session;
public function __construct(SessionInterface $session)
{
$this->session = $session;
}
public function postLoad(LifecycleEventArgs $event)
{
$entity = $event->getEntity();
if ($entity instanceof WebshopItem) {
$currency = $this->session->get('currency', 'EUR');
$entity->setCurrency(currency);
}
}
}
src/Your/GreatBundle/Entity/WebshopItem.php
namespace Your\GreatBundle\Entity;
class WebshopItem
{
...
// You don't need to persist this...
private $currency = 'EUR';
public function setCurrency($currency)
{
$this->currency = $currency;
}
public function getPrice()
{
foreach ($this->prices as $price) {
if ($price->getCurrency() === $this->currency) {
return ($price->getPrice();
}
}
return null;
}
}
这篇关于根据会话值选择实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!