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]

我怎样才能做到这一点?

几个月前我已经完成了,但我选择了更简单的方法。我的用例是根据当前登录的用户(ProfileTeacher)注入对象。

查看此 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

        }
        // ...
}