symfony2 在自定义注释中获取 paramConverter 值
symfony2 get paramConverter value in custom annotation
我正在尝试创建自己的 symfony2 注释。
我想要实现的是在我的注释(在我的控制器中)中获取 paramConverter 对象,例如
/**
* @ParamConverter("member", class="AppBundle:Member")
* @Route("my/route/{member}", name="my_route")
* @MyCustomAnnotation("member", some_other_stuff="...")
*/
public function myAction(Member $member) {...}
这里的目的是在我的注释中获取 "member",这样我就可以在它传递给控制器操作之前处理它
目前,我的注释 "reader" 作为服务工作
MyCustomAnnotationDriver:
class: Vendor\Bundle\Driver\CustomAnnotationDriver
tags: [{name: kernel.event_listener, event: kernel.controller, method: onKernelController}]
arguments: [@annotation_reader]
我怎样才能做到这一点?
几个月前我已经完成了,但我选择了更简单的方法。我的用例是根据当前登录的用户(Profile
或 Teacher
)注入对象。
查看此 GIST:
要点:https://gist.github.com/24d3b1778bc86429c7b3.git
PASTEBIN(要点目前不起作用):http://pastebin.com/CBjrHvbM
然后,将转换器注册为:
<service id="my_param_converter" class="AcmeBundle\Services\RoleParamConverter">
<argument type="service" id="security.context"/>
<argument type="service" id="doctrine.orm.entity_manager"/>
<tag name="request.param_converter" converter="role_converter"/>
</service>
最后,使用它:
/**
* @Route("/news")
* @ParamConverter("profile", class="AcmeBundle:Profile", converter="role_converter")
*/
public function indexAction(Profile $profile){
// action's body
}
您也可以将此自定义 ParamConverter
应用到控制器的 class。
所以我在文档中找到了一个解决方案。事实上,事件正在与请求一起工作,所以对于我路由中的每个参数,我检查相应的 ParamConverter,并获取实体。
这是我得到的:
public function onKernelController(FilterControllerEvent $event)
{
if (!is_array($controller = $event->getController()))
return; //Annotation only available in controllers
$object = new \ReflectionObject($controller[0]);
$method = $object->getMethod($controller[1]);
$annotations = new ArrayCollection();
$params = new ArrayCollection();
foreach ($this->reader->getMethodAnnotations($method) as $configuration) {
if($configuration instanceof SecureResource) //SecureResource is my annotation
$annotations->add($configuration);
else if($configuration instanceof \Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter)
$params->add($configuration);
}
foreach($annotations as $ann) {
$name = $ann->resource; // member in my case
$param = $params->filter(
function($entry) use ($name){
if($entry->getName() == $name) return $entry;
} //Get the corresponding paramConverter to get the repo
)[0];
$entityId = $event->getRequest()->attributes->get('_route_params')[$name];
$entity = $this->em->getRepository($param->getClass())->find($entityId);
//.. do stuff with your entity
}
// ...
}
我正在尝试创建自己的 symfony2 注释。 我想要实现的是在我的注释(在我的控制器中)中获取 paramConverter 对象,例如
/**
* @ParamConverter("member", class="AppBundle:Member")
* @Route("my/route/{member}", name="my_route")
* @MyCustomAnnotation("member", some_other_stuff="...")
*/
public function myAction(Member $member) {...}
这里的目的是在我的注释中获取 "member",这样我就可以在它传递给控制器操作之前处理它
目前,我的注释 "reader" 作为服务工作
MyCustomAnnotationDriver:
class: Vendor\Bundle\Driver\CustomAnnotationDriver
tags: [{name: kernel.event_listener, event: kernel.controller, method: onKernelController}]
arguments: [@annotation_reader]
我怎样才能做到这一点?
几个月前我已经完成了,但我选择了更简单的方法。我的用例是根据当前登录的用户(Profile
或 Teacher
)注入对象。
查看此 GIST:
要点:https://gist.github.com/24d3b1778bc86429c7b3.git
PASTEBIN(要点目前不起作用):http://pastebin.com/CBjrHvbM
然后,将转换器注册为:
<service id="my_param_converter" class="AcmeBundle\Services\RoleParamConverter">
<argument type="service" id="security.context"/>
<argument type="service" id="doctrine.orm.entity_manager"/>
<tag name="request.param_converter" converter="role_converter"/>
</service>
最后,使用它:
/**
* @Route("/news")
* @ParamConverter("profile", class="AcmeBundle:Profile", converter="role_converter")
*/
public function indexAction(Profile $profile){
// action's body
}
您也可以将此自定义 ParamConverter
应用到控制器的 class。
所以我在文档中找到了一个解决方案。事实上,事件正在与请求一起工作,所以对于我路由中的每个参数,我检查相应的 ParamConverter,并获取实体。
这是我得到的:
public function onKernelController(FilterControllerEvent $event)
{
if (!is_array($controller = $event->getController()))
return; //Annotation only available in controllers
$object = new \ReflectionObject($controller[0]);
$method = $object->getMethod($controller[1]);
$annotations = new ArrayCollection();
$params = new ArrayCollection();
foreach ($this->reader->getMethodAnnotations($method) as $configuration) {
if($configuration instanceof SecureResource) //SecureResource is my annotation
$annotations->add($configuration);
else if($configuration instanceof \Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter)
$params->add($configuration);
}
foreach($annotations as $ann) {
$name = $ann->resource; // member in my case
$param = $params->filter(
function($entry) use ($name){
if($entry->getName() == $name) return $entry;
} //Get the corresponding paramConverter to get the repo
)[0];
$entityId = $event->getRequest()->attributes->get('_route_params')[$name];
$entity = $this->em->getRepository($param->getClass())->find($entityId);
//.. do stuff with your entity
}
// ...
}