デコレータの作成
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メソッドを使う必要があります。
