2012年4月1日日曜日

独自のアノテーションを作成する

独自のアノテーションを作成したいっ!ってなったことありませんか? ( @Route, @Template のように )
例えば、Entity で CreatedAt を Annotation につけると現在時刻を付加 (→ http://www.scandio.de/2012/02/symfony2-custom-annotations/ で紹介されています)等のことが楽にできるようになります。


この独自アノテーションの作成方法を簡単にまとめておきます。

※ 以下のように、param フィールド をもつ Custom というコントローラーのアノテーションを作ることにします。

<?php

namespace Application\MogeraBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Core\HogeBundle\Annotations\Custom;

class DefaultController extends Controller
{
   /**
     * @Custom(param="hogehoge")
     */
    public function indexAction()
    {
  exit();
    }
}


① まずこの Custom クラスを作成
<?php
namespace Core\HogeBundle\Annotations;

/**
* @Annotation
*/
class Custom
{
    // fields
    private $param = "";
    
    // constructor
    public function __construct(array $data)
    {
        // アノテーションに記述した値が $data の中に入ってる
        $this->param = $data['param'];
    }

    // get value of param
    public function getParam(){
         return $this->param;
    }
}


② アノテーションを処理するDriver部分を作成
この例では、コントローラーが呼ばれるタイミングの、onKernelController で、アノテーションを処理させます。
<?php

namespace Core\HogeBundle\Annotations;

use Doctrine\Common\Annotations\Reader;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

class CustomAnnotationDriver{

    private $reader;

    public function __construct(Reader $reader)
    {
        // set annotations reader
        $this->reader = $reader;
    }

    /**
     * onKernelController
     */
    public function onKernelController(FilterControllerEvent $event)
    {
        if (!is_array($controller = $event->getController())) {
            return;
        }

        $object = new \ReflectionObject($controller[0]);// get controller
        $method = $object->getMethod($controller[1]);// get method
        
        // getMethodAnnotation は 第二引数に指定したアノテーションタイプにマッチしたものを返します
        // annotation reader には、アノテーションの種類によってもいくつかメソッドが用意されてるので、ソースは見ておくと良いかも
        $custom = $this->reader->getMethodAnnotation( $method, 'Core\\HogeBundle\\Annotations\\Custom' );
        if( !empty($custom) ){
            print $custom->getParam(); // hogehoge と出力される
        }
    }
}


③ service に登録 (今回は onKernelController で アノテーションを処理するので以下のように。)
また、CustomAnnotationDriver にはコンストラクタで annotation_reader で 必要とするので、arguments にそれを記述。
services:
    hoge_annotation_driver:
        class: Core\HogeBundle\Annotations\CustomAnnotationDriver
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
        arguments: [@annotation_reader]



こんな感じ。ただ、今回は print しか処理をしてないです。
参考になれば嬉しいです。

0 コメント:

コメントを投稿

Share

Twitter Delicious Facebook Digg Stumbleupon Favorites More