2013-06-10 5 views
5

aufgerufen werden Ich verwende symfony2 und FOSUserBundle.Wie bekomme ich userid von eventlistener, die von AJAX

Normalerweise kann ich Benutzerdaten von Steuer

$user = $this->get('security.context')->getToken()->getUser(); 

oder

$user = $this->container->get('security.context')->getToken()->getUser(); 

Aber jetzt bekommen, möchte ich die Benutzerdaten von eventlistner erhalten, die von Ajax genannt werden.

Ist es möglich? oder nicht?

meine Quelle ist hier.

namespace Acme\MemberBundle\EventListener; 

    use ADesigns\CalendarBundle\Event\CalendarEvent; 
    use ADesigns\CalendarBundle\Entity\EventEntity; 
    use Doctrine\ORM\EntityManager; 

    class CalendarEventListener 
    { 
     private $entityManager; 

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

     public function loadEvents(CalendarEvent $calendarEvent) 
     { 
      $startDate = $calendarEvent->getStartDatetime(); 
      $endDate = $calendarEvent->getEndDatetime(); 


      $user = $this->container->get('security.context')->getToken()->getUser();//it doesnt work 

      // load events using your custom logic here, 
      // for instance, retrieving events from a repository 

      $companyEvents = $this->entityManager->getRepository('UserBundle:MutorSche') 
        ->createQueryBuilder('company_events') 
        ->where('company_events.event_datetime BETWEEN :startDate and :endDate') 
        ->setParameter('startDate', $startDate->format('Y-m-d H:i:s')) 
        ->setParameter('endDate', $endDate->format('Y-m-d H:i:s')) 
        ->getQuery()->getResults(); 



      foreach($companyEvents as $companyEvent) { 

       // create an event with a start/end time, or an all day event 
       if ($companyEvent->getAllDayEvent() === false) { 
        $eventEntity = new EventEntity($companyEvent->getTitle(), $companyEvent->getStartDatetime(), $companyEvent->getEndDatetime()); 
       } else { 
        $eventEntity = new EventEntity($companyEvent->getTitle(), $companyEvent->getStartDatetime(), null, true); 
       } 

       //optional calendar event settings 
       $eventEntity->setAllDay(true); // default is false, set to true if this is an all day event 
       $eventEntity->setBgColor('#FF0000'); //set the background color of the event's label 
       $eventEntity->setFgColor('#FFFFFF'); //set the foreground color of the event's label 
       $eventEntity->setUrl('http://www.google.com'); // url to send user to when event label is clicked 
       $eventEntity->setCssClass('my-custom-class'); // a custom class you may want to apply to event labels 

       //finally, add the event to the CalendarEvent for displaying on the calendar 
       $calendarEvent->addEvent($eventEntity); 
      } 
     } 
    } 

nach @ Nifr Beratung.

änderte ich ein bisschen in meiner Quelle Kabel wie

class CalendarEventListener 
{ 
    private $entityManager; 
    private $container;//add 

    public function __construct(
      EntityManager $entityManager, 
      ContainerInterface $container)//add 
    { 
     $this->entityManager = $entityManager; 
     $this->container = $container;//add 
    } 

dann möchte ich das zweite Argument zu eventlistner passieren. Ich verwende services.xml, um Listener zu erstellen. Wie kann ich ein zweites Argument hinzufügen?

<?xml version="1.0" encoding="UTF-8" ?> 
     <container xmlns="http://symfony.com/schema/dic/services"> 

     <services> 
      <service id="acme.memberbundle.calendar_listener" class="Acme\MemberBundle\EventListener\CalendarEventListener"> 
       <argument type="service" id="doctrine.orm.entity_manager" /> 
       <tag name="kernel.event_listener" event="calendar.load_events" method="loadEvents" /> 
      </service> 

     </services> 
     </container> 

Antwort

5

benötigen Sie den Behälter über Dependency Injection in Ihre Listener-Klasse zu injizieren, um es zu acccess.

Lesen Sie mehr darüber in der book chapter.

your.listener: 
    class: Acme\MemberBundle\EventListener\CalendarEventListener 
    arguments: ["@service_container"] 

Obwohl die gesamte Behälter Injektion ist leistungsmäßig nicht die beste Idee, unter einigen anderen Gründen wie Testbarkeit (Sie sollten in der Regel injizieren nur die Dienste, die Sie in Ihrer Klasse benötigen anstelle des Behälters) ...

... in Ihrem Fall, wenn Sie kein UserCallable verwenden, erhalten Sie einen Zirkelverweis beim Injizieren @security.context.

So ist die schnellste Lösung wird das Einspritzen des Behälters und Ihre Zuhörer Konstruktor Einstellung:

private $container; 

public function __construct(ContainerInterface $container) 
{ 
    $this->container = $container; 
} 



public function someOtherMethod() 
{ 
    $user = $this->container->get('security.context')->getToken()->getUser(); 

    // ... 
} 
+0

Vielen Dank @nifr ich es fast .in meinem Fall, ich brauche zwei Argumente an Ereignis-Listener übergeben beide EntityManager und Container Also habe ich die Quelle geändert und zum Hauptartikel hinzugefügt. Könnten Sie das bitte überprüfen? – whitebear

+0

Es ist möglich, mehrere Argumente hinzuzufügen, fügen Sie einfach einen anderen XML-Knoten '', aber Sie brauchen nicht zwei Argumente in Ihrem Fall ... Sie können den EntityManager von der Container aswell ... '$ this-> entityManager = $ container-> get ('doctrine.orm.entity_manager')' im Konstruktor. – nifr

+0

Ich sehe. @ Nifr aber '' sagt Der Dienst "acme.memberbundle.calendar_listener" hat eine Abhängigkeit von einem nicht existenten Service "Container" .Ich komme fast dorthin ... aber..danke für Ihre Unterstützung. – whitebear

9

Ab Symfony 2.6 dieses Problem sollte behoben werden. Eine Pull-Anforderung wurde gerade in den Master übernommen. Dein Problem wird hier beschrieben. https://github.com/symfony/symfony/pull/11690

Ab Symfony 2.6 können Sie die security.token_storage in Ihren Listener injizieren. Dieser Dienst enthält das Token, das von SecurityContext in < = 2.5 verwendet wird. In 3.0 ersetzt dieser Dienst die SecurityContext::getToken() insgesamt. Hier sehen Sie eine grundlegende Änderungsliste: http://symfony.com/blog/new-in-symfony-2-6-security-component-improvements#deprecated-the-security-context-service

Beispielverwendung in 2.6:

Ihre Konfiguration:

services: 
    my.listener: 
     class: EntityListener 
     arguments: 
      - "@security.token_storage" 
     tags: 
      - { name: doctrine.event_listener, event: prePersist } 


Ihre Zuhörer

use Doctrine\ORM\Event\LifecycleEventArgs; 
use Symfony\Component\DependencyInjection\ContainerInterface; 
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 

class EntityListener 
{ 
    private $token_storage; 

    public function __construct(TokenStorageInterface $token_storage) 
    { 
     $this->token_storage = $token_storage; 
    } 

    public function prePersist(LifeCycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 
     $entity->setCreatedBy($this->token_storage->getToken()->getUsername()); 
    } 
} 
+1

Das ist jetzt die richtige Antwort! – Acyra

3

Seien Sie sicher, dass der Symfony profiler/toolbar eingeschaltet, um nicht zu haben. Ich weiß nicht warum, aber das machte $this->container->get('security.context')->getToken() zurück null jedes Mal.

in der Datei config_dev.yml sicherstellen, dass die folgenden gesetzt:

web_profiler: 
    toolbar: false 
+1

Ich hasse es, wenn meine Antworten ohne Erklärung, warum, abgelehnt werden. Dies war eine legitime Lösung für mich. – craned

Verwandte Themen