symfony2获取自定义注释中的paramConverter值

时间:2015-01-29 15:58:41

标签: symfony doctrine-orm annotations

我正在尝试创建自己的symfony2注释。 我想要实现的是在我的注释中(在我的控制器中)获取paramConverter对象,比如

/**
 * @ParamConverter("member", class="AppBundle:Member")
 * @Route("my/route/{member}", name="my_route")
 * @MyCustomAnnotation("member", some_other_stuff="...")
 */
public function myAction(Member $member) {...}

这里的目的是在我的注释中获取“成员”,所以我可以在它传递给控制器​​动作之前对其进行处理

目前,我的注释“读者”正在作为服务工作

MyCustomAnnotationDriver:
            class: Vendor\Bundle\Driver\CustomAnnotationDriver
            tags: [{name: kernel.event_listener, event: kernel.controller, method: onKernelController}]
            arguments: [@annotation_reader]

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:2)

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

检查此GIST:

GIST:https://gist.github.com/24d3b1778bc86429c7b3.git

PASTEBIN(gist目前不起作用):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应用于控制台的类。

答案 1 :(得分:0)

所以我找到了潜伏在doc中的解决方案。实际上,事件正在处理请求,因此对于我的路径中的每个参数,我检查相应的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

        }
        // ...
}