デコレータの作成
Zend_Frameworkに添付されているデコレータを紹介しましたが、これだけでは機能が足りないことがあるかもしれません。また、良く使うデコレータの組合せがある場合、それらをまとめて一つのデコレータにしておいた方が後から便利なことがあります。その際にはデコレータを自分で作るの一つの解決策となります。
自分で作成したデコレータを使用するには、デコレータ自身の作成と、デコレータを設置したパスの設定の二段階があります。
デコレータ自身の作成
デコレータは通常はZend_Decorator_Abstractクラスのサブクラスとして実装します。本来、デコレータはZend_Decorator_Interfaceを継承していれば良いのですが、こちらですとメソッドを11個実装する必要があるため、render
メソッドのみを実装すれば良いZend_Decorator_Abstractを利用するのがお勧めです。
デコレータのクラス名は(接頭辞_デコレータ名)という形になっています。例えば標準で添付されるZend_Form_Decorator_HtmlTagデコレータは「Zend_Form_Decorator」が接頭辞で「HtmlTag」がデコレータ名となっています。
ここで、例えば「My_Decorator_Simple」という簡単なデコレータを実装することを考えます。このデコレータは与えられた文字列の頭に"simple is the best"と付け加えるのみのデコレータです:
<?php class My_Decorator_Simple extends Zend_Form_Decorator_Abstract { public function render($content) { return "simple is the best".$content; } }
単純にrender
メソッドを実装していて、前のデコレータが描画した内容にそのまま文字列をつけて返すようになっています。
ここで、デコレータを保存するためのフォルダ「C:\codezine\zendapps\decorators」を作成し、このファイルをデコレータ名の「Simple.php」で保存しておきます。
デコレータの利用
次に先程作ったデコレータを利用する方法について説明します。そのためには、まずデコレータが置いてあるパスと、自作のデコレータにつけた接頭辞をフォームに登録する必要があります。
まず、パスと接頭辞の登録にはZend_FormのaddPrefixPath
メソッドを使います。このメソッドはaddPrefixPath($prefix, $path, $type)
の3つの引数を指定します。$prefix
は接頭辞を、$path
には先程作成したデコレータを保存するためのフォルダのパスを指定します。また$type
は登録するパス・接頭辞の種類で、この場合では'decorator'を指定します。
なお、$path
を相対パスで指定した場合にはPHPのinculude_pathに含まれているパスからの相対パスを調べます。筆者の環境ではinclude_pathの先頭に'.'が含まれているため、index.phpが設置されている「C:\codezine\htdocs」から見て「../zendapps/decorators」に先程設置したフォルダがあるので、このような相対パスの指定を行っています。異なるinclude_pathの設定を行っているのであれば、相対パスでなく絶対パスで指定する(C:\codezine\zendapps\decorators)必要があるかもしれません。
登録が済めば、通常のデコレータと同様に利用することができ、フォーム要素のaddDecorator
メソッドにデコレータ名を渡すことで利用することができます:
public function mydecoratorAction() { $form = new Zend_Form; $form->addPrefixPath('My_Decorator', '../zendapps/decorators', 'decorator');
//フォーム要素の作成 $this->addElements($form); //既に追加済のフォーム要素にも登録 //$form->addElementPrefixPath('My_Decorator', // '../zendapps/decorators', // 'decorator'); $user = $form->getElement('user'); //個別のフォーム要素に加える //$user->addPrefixPath('My_Decorator', // '../zendapps/decorators', // 'decorator'); $user->addDecorator('Simple'); $this->view->assign('form', $form); return $this->render('index'); }
なお、今回はZend_Formのインスタンスを作成した直後に登録したのでaddPrefixPath
メソッドを利用しましたが、作成済・登録済のフォーム要素にも影響を与えるためにはaddElementPrefixPath
メソッドを、また、個別のフォーム要素に登録するためにはフォーム要素のaddPrefixPath
メソッドを使う必要があります。