Symfony2访问服务中的用户和原则

Symfony2访问服务中的用户和原则,symfony,service,controller,fosuserbundle,Symfony,Service,Controller,Fosuserbundle,我在大量控制器操作中运行与此代码等效的代码,基本上它获取用户的用户名,如果该用户名附加到博客实体,则允许用户查看博客实体: 我想把它转移到一个服务中,这样我就可以减少代码重复。我希望避免在控制器中尽可能多地执行逻辑 也就是说,我不确定如何访问服务中的用户会话和原则 这是我的服务。yml: mysite.user.blog: class: MySite\SiteBundle\Services\BlogUser 下面是我试图在控制器中调用它的方式: public function test

我在大量控制器操作中运行与此代码等效的代码,基本上它获取用户的用户名,如果该用户名附加到博客实体,则允许用户查看博客实体:

我想把它转移到一个服务中,这样我就可以减少代码重复。我希望避免在控制器中尽可能多地执行逻辑

也就是说,我不确定如何访问服务中的用户会话和原则

这是我的服务。yml:

mysite.user.blog:
    class: MySite\SiteBundle\Services\BlogUser
下面是我试图在控制器中调用它的方式:

public function testAction() {
    $response = $this->get('mysite.user.blog');
    return new Response($response);
}
我确实尝试过使用事件标记,但这似乎无法完成我想要的任务

这是我在一次服务中完全可怕的尝试。如果不使用构造函数,我无法从中获得任何响应

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));
    }
}
我是不是走错了路?有没有更好的方法让我错过

编辑/答复: 稍微修改了我的命名约定:

//services.yml
mysite.user.blog.entities:
    class: Mysite\SiteBundle\Services\BlogUser
    arguments: ["@doctrine.orm.entity_manager", "@security.context"]
在控制器操作中:

$userEntities = $this->get('mysite.user.blog.entities');
$entities = $userEntities->getEntities();
在服务本身中:

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;
    }
}

仍然需要两行代码才能在控制器中获取$entities变量,但这比反复定义相同的内容要好得多。

您正在研究如何将其他服务“注入”到自定义服务中。看看文档

在您的情况下,您可以通过构造函数注入将
doctor.orm.entity\u manager
security.context
服务注入到
BlogUser
类中。例如:

class BlogUser {

    public function __construct($em, $securityContext) {
        $user = $securityContext->getToken()->getUser();
        $this->entities = $em->getRepository('MySiteBundle:Blog')->findBy(array('user' => $user));
    }

}
并按以下方式配置您的服务:

mysite.user.blog:
    class: MySite\SiteBundle\Services\BlogUser
    arguments:    ["@doctrine.orm.entity_manager", "@security.context"]

是的,你做得不对。让我们看看您的代码:

    # call to undefined object method getDoctrine()
    $em = $this->getDoctrine()->getManager();
    # call to undefined object method get()
    $user = $this->get('security.context')->getToken()->getUser();
您不能像在控制器中一样在服务中调用getting entitymanager和
security.context
。相反,您必须注入entitymanager和
security.context
服务。例如:

# services.yml
mysite.user.blog:
    class: MySite\SiteBundle\Services\BlogUser
    calls:
        - [ setUserFromSecurityContext, [ @security.context ]]
        - [ setEntityManager, [ @doctrine.orm.entity_manager ]]
以及改善服务:

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
    }
}
有关“Security.context”的详细信息自Symfony 2.6以来已被弃用

经过一些社区讨论,确定SecurityContext提供了太多依赖项,无法检索简单的令牌/用户对象。这就是为什么从Symfony 2.6开始,security.context服务被弃用,并被分为两个新服务:security.authorization\u checker和security.token\u storage

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

mysite.user.blog:
    class: MySite\SiteBundle\Services\BlogUser
    arguments: ["@doctrine.orm.entity_manager", "@security.token_storage"]
然后在服务类构造函数中:

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));
    }
}

@Pazi它仍然是有效的属性名称。
调用:“
服务的一部分是否运行您指定的任何函数?除了灵活性(或者重新使用由不同服务调用的同一类)之外,使用它而不是构造函数是否有好处?@Chris我主要使用setter注入,因为:1。这对我来说更清楚(特别是当注射量很大时),2。当我使用父服务时,setter很容易管理。更多信息:,自symfony v。2.6不推荐使用安全上下文:
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));
    }
}