8

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

    $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,

我想把它移到服务中,这样我就可以减少代码重复。我想避免在我的控制器中做尽可能多的逻辑。

话虽如此,我不确定如何访问服务中的用户会话和原则。

这是我的 services.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 变量,但这比一遍又一遍地定义相同的东西要好得多。

4

3 回答 3

11

“Security.context” 自 Symfony 2.6 起已被弃用

经过一些社区讨论后,决定 SecurityContext 提供了太多依赖项来检索简单的 Token/User 对象。这就是为什么从 Symfony 2.6 开始,security.context 服务已被弃用并被拆分为两个新服务:security.authorization_checker 和 security.token_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));
    }
}
于 2016-08-23T10:29:41.097 回答
5

是的,你做错了。让我们看看你的代码:

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

您不能security.context像在控制器中那样调用获取 entitymanager 和在您的服务中。相反,您必须注入 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
    }
}

有关依赖注入的更多信息

于 2013-08-14T06:08:39.017 回答
2

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

在您的情况下,您可以通过构造函数注入将服务注入到您的类doctrine.orm.entity_managersecurity.contextBlogUser例如:

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"]
于 2013-08-14T06:03:51.323 回答