2012-06-24 19 views
8

Come definire un costruttore nel controller Symfony2. Voglio ottenere i dati dell'utente loggato disponibili in tutti i metodi del mio controller, Attualmente faccio qualcosa del genere in ogni azione del mio controller per ottenere l'utente connesso.Funzione di costruzione nel controller Symfony2

$em = $this->getDoctrine()->getEntityManager("pp_userdata"); 
$user = $this->get("security.context")->getToken()->getUser(); 

voglio farlo una volta in un costruttore e fanno di questo utente connesso disponibili su tutte le mie azioni

risposta

12

Per una soluzione generale per l'esecuzione di codice prima di ogni azione del controller è possibile collegare un listener di eventi per la kernel.controller evento in questo modo:

<service id="your_app.listener.before_controller" class="App\CoreBundle\EventListener\BeforeControllerListener" scope="request"> 
    <tag name="kernel.event_listener" event="kernel.controller" method="onKernelController"/> 
    <argument type="service" id="security.context"/> 
</service> 

Poi, nel tuo BeforeControllerListener si verificherà il controller per vedere se si implementa un'interfaccia, se lo fa, si chiamare un metodo dall'interfaccia e passare il sec contesto di urezza.

<?php 

namespace App\CoreBundle\EventListener; 

use Symfony\Component\HttpKernel\Event\FilterControllerEvent; 
use Symfony\Component\Security\Core\SecurityContextInterface; 
use App\CoreBundle\Model\InitializableControllerInterface; 

/** 
* @author Matt Drollette <[email protected]> 
*/ 
class BeforeControllerListener 
{ 

    protected $security_context; 

    public function __construct(SecurityContextInterface $security_context) 
    { 
     $this->security_context = $security_context; 
    } 

    public function onKernelController(FilterControllerEvent $event) 
    { 
     $controller = $event->getController(); 

     if (!is_array($controller)) { 
      // not a object but a different kind of callable. Do nothing 
      return; 
     } 

     $controllerObject = $controller[0]; 

     // skip initializing for exceptions 
     if ($controllerObject instanceof ExceptionController) { 
      return; 
     } 

     if ($controllerObject instanceof InitializableControllerInterface) { 
      // this method is the one that is part of the interface. 
      $controllerObject->initialize($event->getRequest(), $this->security_context); 
     } 
    } 
} 

Quindi, qualsiasi controller che si desidera avere l'utente sempre disponibile sarà sufficiente implementare tale interfaccia e impostare l'utente in questo modo:

use App\CoreBundle\Model\InitializableControllerInterface; 

class DefaultController implements InitializableControllerInterface 
{ 
    /** 
    * Current user. 
    * 
    * @var User 
    */ 
    private $user; 

    /** 
    * {@inheritdoc} 
    */ 
    public function initialize(Request $request, SecurityContextInterface $security_context) 
    { 
     $this->user = $security_context->getToken()->getUser(); 
    } 
// .... 
} 

L'interfaccia non è altro che

namespace App\CoreBundle\Model; 

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\Security\Core\SecurityContextInterface; 

interface InitializableControllerInterface 
{ 
    public function initialize(Request $request, SecurityContextInterface $security_context); 
} 
+0

qualcuno conosce il modo per scrivere il config in yaml? usiamo yaml e non so come aggiungere l'argomento '. Ho letto questo: http://symfony.com/doc/current/cookbook/service_container/event_listener.html pure senza aiuto ovviamente – Toskan

+0

@Toskan puoi semplicemente fare qualcosa del tipo: 'argomenti: [" @em "," @ some_service "]' – takeit

+0

app.listener.constructor_listener: classe: AppBundle \ EventListener \ ConstructorListener portata: richiesta argomenti: - {type: servizio, id: security.context} tags: - {name: kernel.event_listener , evento: kernel.controller, metodo: onKernelController} http://pastebin.com/NTySb68a – r4ccoon

2

il mio approccio a questo è stato:

  1. Fare un vuoto interfaccia InitializableControllerInterface
  2. Fai listener di eventi per
 
namespace ACMEBundle\Event; 

use Symfony\Component\HttpKernel\Event\FilterControllerEvent; 

class ControllerConstructor 
{ 
    public function onKernelController(FilterControllerEvent $event) 
    { 
     $controller = $event->getController(); 
     if (!is_array($controller)) { 
      // not a object but a different kind of callable. Do nothing 
      return; 
     } 

     $controllerObject = $controller[0]; 
     if ($controllerObject instanceof InitializableControllerInterface) { 
      $controllerObject->__init($event->getRequest()); 
     } 
    } 
} 
  1. nel controller aggiuntivo:
 
class ProfileController extends Controller implements 
     InitializableControllerInterface 
{ 
public function __init() 
    { 
$this->user = $security_context->getToken()->getUser(); 
} 

E si sarà in grado di ottenere il $ this-> utente in ogni azione.

saluti

3

sto runnig un po 'tardi, ma in un controllore si può solo accedere l'utente:

$this->getUser(); 

dovrebbe funzionare dal 2,1

Problemi correlati