symfonyは標準的にpropelというO/Rマッパライブラリを使用しています。このpropelに対して独自の処理を付け加える機構がsfPropelBehaviorです。
この機構を使うことで、たとえば『saveしたときに自動的に更新者のIPアドレスを保存する』などといった透過的処理を、簡単に追加することができます。
本日記では、そのPropelBehaviorの使い方を説明します。実装の際に便利そうなテンプレートも用意しましたので、もしよければ使ってみてください。なお、本稿ではこのテンプレートを使用しています。
※初期設定※
PropelBehaviorを使うためにはまずpropel.iniに以下の行を足す必要があります。
propel.builder.addBehaviors = true
その上でMapperの生成を行ってください。
$ symfony propel-build-model
※ファイルを配置※
添付のzipファイル(sfPropelBehaviorTemplatePlugin.zip)に入っているsfPropelBehaviorTemplatePluginディレクトリを、プロジェクトのplugin/に設置してください。以下のような配置になればOKです。
$SF_ROOT_DIR/ plugin/ sfPropelBehaviorTemplatePlugin/ config/ config.php lib/ sfPropelBehaviorTemplate.php
※プラグインポイント※
sfPropelBehaviorTemplateクラスの内容を見ると、いくつかのメソッドがすでに書かれています。これはpropelへ処理をはさむことのできるプラグインポイントを示しています。
詳しい説明は省略しますので、メソッド名とコメントの内容で雰囲気をつかんでほしいのですが、特に@returnの記述には気をつけてください。たとえばhook_save_pre()はBaseObject#save()の前処理としてコールされるのですが、返却値として数値を返すとsave処理が行われなくなってしまいます。意図しない動作にならないように、上手に自分の処理を書いてください。
なお、初期状態で書かれているメソッドは『極力なにもしない』コード記述となっていますが、必要の無いプラグインポイントはconfig.phpから取り除いておくと、コール自体が行われず余計な処理オーバーヘッドを除去できますので、これを推奨します。
※処理を記述※
それでは、自分の必要とする処理を実際に書きましょう。今回は『saveしたときに自動的に更新者のIPアドレスを保存する』という振る舞いを持たせることにします。この処理では、ターゲットのテーブルにupdater_remote_addressというカラムを必要とします。
sfPropelBehaviorTemplate#hook_Peer_doUpdate_pre()に処理を記述します。
public function hook_Peer_doUpdate_pre($peerClazz, $object, Connection $con=null) { if ($object instanceof Criteria) { $object = $this->getBaseObject($peerClazz, $object); } $object->setUpdaterRemoteAddress($_SERVER['REMOTE_ADDR']); ※この行を追加 return false; }
※ターゲットを指定※
このPropelBehaviorを適用したいターゲットのモデル名を指定し、sfPropelBehavior::add()を呼びます。このコールはモデルを使用する前段階ならどこでも構わないのですが、通常は当該モデルのPeerクラスの下に書くのが一般的のようです。
今回はhoge_memberテーブルをターゲットとしましょう。HogeMemberPeer.phpに以下を記述します。
class HogeMemberPeer extends BaseHogeMemberPeer { } sfPropelBehavior::add('HogeMember', array('sfPropelBehaviorTemplate')); ※この行を追加
※おわりに※
これでsave()を実行すると勝手にREMOTE_ADDRが保存されるPropelBehaviorができました。ね、簡単でしょ?
このようなPropelBehaviorがSymfonyPluginsにはたくさん登録されています。是非みなさんも面白い&便利なPropelBehaviorを作って、僕にも教えてくださいね!
次回の日記では、僕のつくったPropelBehaviorを紹介します(^^

