通过Twig扩展中的自定义存储库获取数据

mat*_*h88 11 symfony doctrine-orm twig

我想在symfony 2 webapplication的每个页面上显示新的通知.我被建议使用Twig Extension.我在该扩展中创建了一个函数getFriendRequests,但我不知道在twig扩展中通过我的自定义存储库获取数据是否是一个好习惯:现在它给了我错误,它找不到getDoctrine方法.

<?php

namespace Tennisconnect\DashboardBundle\Extension;

class NotificationTwigExtension extends \Twig_Extension
{
    public function getFriendRequests($user)
    {
        $users = $this->getDoctrine()
            ->getRepository('TennisconnectUserBundle:User')
            ->getFriendRequests();
        return count($users);
    }

    public function getName()
    {
        return 'notification';
    }

    public function getFunctions()
    {
        return array(
            'getFriendRequests' => new \Twig_Function_Method($this, 'getFriendRequests'));
    }
}
Run Code Online (Sandbox Code Playgroud)

Mat*_*att 28

我认为直接从你的枝条扩展中获取数据并不是那么糟糕.毕竟,如果您不在此处执行此操作,则需要先获取这些记录,然后将它们传递到扩展程序以进行显示.

重要的是在存储库中执行DQL/SQL工作,就像您已经在做的那样.这对于将数据库语句与项目的其他部分分开很重要.

您遇到的问题是getDoctrine该类中不存在该方法.据我所知,您从扩展FrameworkBundle基本控制器的控制器中获取此代码.FrameworkBundle定义此方法的基本控制器.

要解决此问题,您必须将正确的服务注入到您的扩展中.这基于依赖注入容器.你当然为你的枝条扩展定义了一个服务,就像这个定义:

services:
  acme.twig.extension.notification:
    class: Acme\WebsiteBundle\Twig\Extension\NotificationExtension
    tags:
      - { name: twig.extension }
Run Code Online (Sandbox Code Playgroud)

现在的诀窍是注入你需要的依赖项,如下所示:

services:
  acme.twig.extension.notification:
    class: Acme\WebsiteBundle\Twig\Extension\NotificationExtension
    arguments:
      doctrine: "@doctrine"
    tags:
      - { name: twig.extension }
Run Code Online (Sandbox Code Playgroud)

然后,在您的扩展中,您定义一个接收学说依赖关系的构造函数:

    use Symfony\Bridge\Doctrine\RegistryInterface;

    class NotificationTwigExtension extends \Twig_Extension
    {
        protected $doctrine;

        public function __construct(RegistryInterface $doctrine)
        {
            $this->doctrine = $doctrine;
        }

        // Now you can do $this->doctrine->getRepository('TennisconnectUserBundle:User')

        // Rest of twig extension
    }
Run Code Online (Sandbox Code Playgroud)

这是依赖注入的概念.你可以看到我之前回答的关于访问控制器外部服务的另一个问题:这里

希望这可以帮助.

问候,
马特