whi*_*ear 8 symfony fosuserbundle
我正在使用symfony2和FOSUserBundle.
通常,我可以从Controller获取用户数据
$user = $this->get('security.context')->getToken()->getUser();
Run Code Online (Sandbox Code Playgroud)
要么
$user = $this->container->get('security.context')->getToken()->getUser();
Run Code Online (Sandbox Code Playgroud)
但是现在,我想从eventlistner获取从Ajax调用的userdata.
可能吗?或不?
我的来源在这里.
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
根据@nifr的建议.
我在源代码中改变了一下
class CalendarEventListener
{
private $entityManager;
private $container;//add
public function __construct(
EntityManager $entityManager,
ContainerInterface $container)//add
{
$this->entityManager = $entityManager;
$this->container = $container;//add
}
Run Code Online (Sandbox Code Playgroud)
然后我想将第二个参数传递给eventlistner.我正在使用services.xml来创建监听器.我怎样才能在此添加第二个参数?
<?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>
Run Code Online (Sandbox Code Playgroud)
Any*_*one 17
从Symfony 2.6开始,这个问题应该修复.拉取请求刚刚被主人接受.您的问题在此处描述. https://github.com/symfony/symfony/pull/11690
从Symfony 2.6开始,您可以将其security.token_storage
注入您的监听器.此服务将包含SecurityContext
in <= 2.5中使用的令牌.在3.0中,这项服务将SecurityContext::getToken()
完全取代.您可以在此处查看基本更改列表:http://symfony.com/blog/new-in-symfony-2-6-security-component-improvements#deprecated-the-security-context-service
2.6中的示例用法:
你的配置:
services:
my.listener:
class: EntityListener
arguments:
- "@security.token_storage"
tags:
- { name: doctrine.event_listener, event: prePersist }
Run Code Online (Sandbox Code Playgroud)
你的倾听者
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());
}
}
Run Code Online (Sandbox Code Playgroud)
在本书的章节中阅读更多相关内容.
your.listener:
class: Acme\MemberBundle\EventListener\CalendarEventListener
arguments: ["@service_container"]
Run Code Online (Sandbox Code Playgroud)
尽管注入整个容器在性能方面并不是最好的想法,还有一些其他原因,比如可测试性(你通常只需要在你的类而不是容器中注入你需要的服务)......
...在您的情况下,如果您没有使用UserCallable,您将在注入时获得循环引用@security.context
.
所以最快的解决方案是注入容器并调整监听器的构造函数:
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function someOtherMethod()
{
$user = $this->container->get('security.context')->getToken()->getUser();
// ...
}
Run Code Online (Sandbox Code Playgroud)
一定不要Symfony profiler/toolbar
打开.我不知道为什么,但每次都$this->container->get('security.context')->getToken()
回来了null
.
在文件中,config_dev.yml
确保设置以下内容:
web_profiler:
toolbar: false
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12387 次 |
最近记录: |