Symfony2访问服务中的用户和教义

gan*_*gan 8 service controller symfony fosuserbundle

我在很多很多控制器操作中运行相当于这段代码,基本上它抓住用户的用户名,如果该用户名附加到博客实体,它将允许用户查看博客实体:

    $em = $this->getDoctrine()->getManager();
    $user = $this->get('security.context')->getToken()->getUser();
    $entities = $em->getRepository('MySiteBundle:Blog')->findBy(array('user' => $user));

    return $this->render('MySiteBundle:Blog:index.html.twig', array(
        'entities' => $entities,
Run Code Online (Sandbox Code Playgroud)

我想将它转移到服务中,这样我就可以减少代码重复.我想避免在控制器中尽可能多地使用逻辑.

话虽这么说,我不知道如何在服务中访问用户会话和学说.

这是我的services.yml:

mysite.user.blog:
    class: MySite\SiteBundle\Services\BlogUser
Run Code Online (Sandbox Code Playgroud)

这就是我试图在控制器中调用它的方式:

public function testAction() {
    $response = $this->get('mysite.user.blog');
    return new Response($response);
}
Run Code Online (Sandbox Code Playgroud)

我确实尝试使用事件订阅者/侦听器标记,但这似乎没有完成我想要的任务.

这是我完全可怕的服务尝试.没有使用构造函数我无法得到任何响应.

namespace MySite\SiteBundle\Services;

use MySite\SiteBundle\Entity\Blog;

class BlogUser {

    protected $entities;

    public function __construct(){
        $em = $this->getDoctrine()->getManager();
        $user = $this->get('security.context')->getToken()->getUser();
        $this->entities = $em->getRepository('MySiteBundle:Blog')->findBy(array('user' => $user));
    }
}
Run Code Online (Sandbox Code Playgroud)

我是以完全错误的方式来做这件事的吗?有没有更好的方法让我失踪?

编辑/回答:

修改了我的命名约定:

//services.yml
mysite.user.blog.entities:
    class: Mysite\SiteBundle\Services\BlogUser
    arguments: ["@doctrine.orm.entity_manager", "@security.context"]
Run Code Online (Sandbox Code Playgroud)

在控制器动作中:

$userEntities = $this->get('mysite.user.blog.entities');
$entities = $userEntities->getEntities();
Run Code Online (Sandbox Code Playgroud)

在服务本身:

class BlogUser {

    protected $entities;

    public function __construct($em, $securityContext){
        $user = $securityContext->getToken()->getUser();
        $this->entities = $em->getRepository('MySiteBundle:Blog')->findBy(array('user' => $user));
    }
    public function getEntities(){
        return $this->entities;
    }
}
Run Code Online (Sandbox Code Playgroud)

仍需要两行来获取控制器中的$ entities变量,但这比一遍又一遍地定义相同的东西要好.

Saw*_*ant 11

自Symfony 2.6以来,"Security.context"已被弃用

经过一些社区讨论后,确定SecurityContext提供了太多依赖项来检索简单的令牌/用户对象.这就是为什么,从Symfony 2.6开始,不推荐使用thiscurity.context服务并将其拆分为两个新服务:security.authorization_checker和security.token_storage.

资源

因此,新的方法是,首先将您的服务配置为:

mysite.user.blog:
    class: MySite\SiteBundle\Services\BlogUser
    arguments: ["@doctrine.orm.entity_manager", "@security.token_storage"]
Run Code Online (Sandbox Code Playgroud)

然后在服务类构造函数中:

class BlogUser
{
    protected $user;
    protected $entities;

    public function __construct(EntityManager $em, TokenStorage $tokenStorage)
    {
        $this->user = $tokenStorage->getToken()->getUser();
        $this->entities = $em->getRepository('MySiteBundle:Blog')->findBy(array('user' => $user));
    }
}
Run Code Online (Sandbox Code Playgroud)


NHG*_*NHG 5

是的,你是以错误的方式做到的.我们来看看你的代码:

    # call to undefined object method getDoctrine()
    $em = $this->getDoctrine()->getManager();
    # call to undefined object method get()
    $user = $this->get('security.context')->getToken()->getUser();
Run Code Online (Sandbox Code Playgroud)

您不能security.context像在控制器中一样调用获取实体管理器和服务.相反,您必须注入实体管理器和security.context服务.例:

# services.yml
mysite.user.blog:
    class: MySite\SiteBundle\Services\BlogUser
    calls:
        - [ setUserFromSecurityContext, [ @security.context ]]
        - [ setEntityManager, [ @doctrine.orm.entity_manager ]]
Run Code Online (Sandbox Code Playgroud)

并改善服务:

namespace Catablog\SiteBundle\Services;

use MySite\SiteBundle\Entity\Blog;

class BlogUser {
    private $entityManager;
    private $user;

    public function setEntityManager(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function setUserFromSecurityContext(SecurityContext $securityContext)
    {
        # notice, there are a cases when `getToken()` returns null, so improve this
        $this->user = $securityContext->getToken()->getUser();
    }
    public function getEntities(){
        # your code here
    }
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息Dependency injection