8

symfony2 と FOSUserBundle を使用しています。

通常、コントローラーからユーザーデータを取得できます

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

また

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

しかし今、Ajax から呼び出される eventlistner からユーザーデータを取得したいと考えています。

出来ますか?か否か?

私のソースはここにあります。

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

@nifr のアドバイスによると。

ソースコードを少し変更しました

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

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

次に、2 番目の引数を eventlistner に渡します。services.xml を使用してリスナーを作成しています。これに2番目の引数を追加するにはどうすればよいですか?

 <?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>
4

3 に答える 3

5

コンテナーにアクセスするには、依存性注入を介してリスナー クラスにコンテナーを注入する必要があります。

詳細については、本の章を参照してください。

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

コンテナ全体を注入することは、テスト容易性などの他のいくつかの理由の中で、パフォーマンスの面で最良のアイデアではありませんが(通常、コンテナではなく、クラスで必要なサービスのみを注入する必要があります)...

...あなたの場合、 UserCallable を使用していない場合、注入時に循環参照が発生し@security.contextます。

したがって、最も簡単な解決策は、コンテナーを挿入し、リスナーのコンストラクターを調整することです。

private $container;

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



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

    // ...
}
于 2013-06-10T11:00:44.780 に答える