假设我的Symfony2应用中有User
和Message
实体,两个实体之间有oneToMany
关系,因此用户可以有多条消息,我想要显示我主导航中未读消息的数量
其中(6)
是未读邮件的数量。为了独立地为每个用户控制器获取此数量的未读消息,我可以考虑定义User
实体方法:
public function getUnreadMessagesCount() {
$unreadMessagesCount = 0;
foreach($this->messages as $message) {
if($message->isUnread()) {
$unreadMessagesCount++;
}
}
}
并在我的menu.html.twig
{% set umc = app.user.getUnreadMessagesCount() %}
{% if umc > 0 %}
({{ umc }})
{% endif %}
但出于性能原因,我想避免遍历整个消息集,只是为了检查它是否未读。所以我更愿意通过DQL调用来获取它(并将此获取放在UserRepository
类中)
$query = $em->createQuery("
SELECT COUNT(m.id) AS umc
FROM AcmeBundle:User u
JOIN AcmeBundle:Message m
WITH u.id = m.user_id
WHERE m.unread = true
AND u.id = :uid");
但是,使用存储库方法或在实体类中使用权利管理器(或Doctrine)是不好的做法。
我考虑过在服务中获取值并将其注入我的实体。但也不建议将服务注入诱惑。
那么获取此值并在所有模板中输出它的合法方法是什么(也可能没有实体方法,例如将值注入所有控制器中)?
答案 0 :(得分:2)
我不太喜欢这种方法,但是 - 为了完整性 - I found this:
您可以在
config.yml
中将服务设置为twig全局变量,例如
#app/config/config.yml
twig:
globals:
your_service: "@your_service"
请参阅here。
只需定义您的服务
即可class AcmeService {
public function __construct() {
// construct
}
public function myMethod() {
// do stuff
}
}
在您的config.yml
中声明此服务,将其定义为twig globale(请参阅上面引用的答案),您可以在您的twig文件中使用您的方法
{{ your_service.myMethod() }}
答案 1 :(得分:2)
我使用另一种解决方案从存储库中获取数据。
首先,定义服务:
## in bundle/Resources/config/services.yml
services:
YOUR_BUNDLE.twig.NAME_OF_THE_EXTENSION:
class: YOUR\BUNDLE\Twig\CLASSNAME
arguments:
- @service_container
tags:
- { name: twig.extension }
然后定义Twig扩展类:
# YOUR_BUNDLE/Twig/CLASSNAME.php
<?php
namespace YOUR\BUNDLE\Twig;
class CLASSNAME extends \Twig_Extension
{
protected $container;
public function __construct($container)
{
$this->container = $container;
}
public function getGlobals()
{
return(array(
'unreadMessagesCount' => $this->container->get('doctrine')
->getManager()
->getRepository('YOUR_BUNDLE:UserRepository')
->getUnreadMessagesCount()
));
}
public function getName()
{
return 'NAME_OF_THE_EXTENSION';
}
}