2013-08-14 2 views
8

Я использую эквивалент этого кода во множестве действий контроллера, в основном он захватывает имя пользователя пользователя, и если это имя пользователя привязано к объекту блога, это позволит пользователю чтобы увидеть сущность блога (ы):Symfony2 доступ к пользователю и доктрине в службе

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

Я попытался с помощью событий subscriber/listener тег, но это Безразлично» Кажется, я выполняю задание, которое я хочу.

Вот моя совершенно ужасная попытка служения. Я не мог получить от него никакого ответа, не используя конструктор.

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

Я об этом совершенно неправильно? Есть ли лучший способ, который мне не хватает?

EDIT/ОТВЕТ:

модифицирована мое именование немного:

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

Еще нужно две строки, чтобы получить переменную $ сущностей в контроллере, но это лучше, чем определение одной и той же вещи снова и снова.

ответ

11

"Security.context" является устаревшим с Symfony 2.6

После некоторого сообщества дискуссий, было решено, что SecurityContext дает слишком много зависимостей для извлечения простого объекта Token/User. Вот почему, начиная с Symfony 2.6, служба thesecurity.context устарела и разделена на две новые службы: security.authorization_checker и security.token_storage.

Source

Таким образом, новый способ сделать это будет, в первую очередь настроить свой сервис как:

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

Вы смотрите, как «вводить» другие сервисы в свою собственную службу. Взгляните на документацию Service Container.

В вашем случае вы можете вводить doctrine.orm.entity_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"] 
+2

Так как с symfony v. 2.6 контекст безопасности устарел: http://symfony.com/doc/current/book/security.html – 11mb

5

Да, вы делаете это в неправильном направлении. Давайте посмотрим на код:

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

Вы не можете назвать получение 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 
    } 
} 

Более подробную информацию о Dependency injection

+0

нет подчеркивания в собственном s! –

+1

@Pazi - это все еще действительные имена свойств. – NHG

+0

вызывает ли '': '' часть службы запускает любую указанную вами функцию? Есть ли преимущество в использовании этого вместо конструктора, помимо гибкости (или повторного использования того же класса, который вызывается разными службами?) – gan

Смежные вопросы