如何从数据库中获取值并将其显示在所有模板中?

时间:2014-04-21 17:17:29

标签: symfony service doctrine-orm repository entity

假设我的Symfony2应用中有UserMessage实体,两个实体之间有oneToMany关系,因此用户可以有多条消息,我想要显示我主导航中未读消息的数量

  • 主页
  • 无论
  • 消息(6)
  • 我的个人资料

其中(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)是不好的做法。

我考虑过在服务中获取值并将其注入我的实体。但也不建议将服务注入诱惑。

那么获取此值并在所有模板中输出它的合法方法是什么(也可能没有实体方法,例如将值注入所有控制器中)?

2 个答案:

答案 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';
    }
}