ObserverでMagentoを拡張する
この記事は公開から 1年以上が経過しています。現在の最新情報との整合性については弊社では一切の責任を負いかねます。
Magentoには3種類の既存処理の拡張方法が用意されています。
1つ目はRewriteによる拡張。2つ目はlocalコードプールへのコードコピー。そして3つ目は今回紹介するObserverです。
Observerとは何か?
Observerはいわゆる「フック処理」です。
既存の処理に設けられたフックポイントに対し、実行する処理を定義した上で、Magentoの設定ファイルに定義を行います。
たったそれだけのことで、Magentoの内部処理に設けられた数多くのフックポイントを利用した処理を記述することができます。
また、Observerは複数のモジュールが同一のフックポイントで処理を行うことができます。
Rewriteやコードコピーによる既存処理の拡張では、1つのクラスについて1回しか拡張ができないので、拡張同士の衝突が 起きることがありますが、Observerは複数の処理が共存できるため、よほど相反する実装をしない限りは問題が起きにくいようになっています。
Observerが利用できる場所
Magentoを構成するクラスの中には、
Mage::dispatchEvent('eventname', $params);
というような記述が度々出てきます。
これがObserver用に用意されたフックポイントです。
中には
Mage::dispatchEvent($this->_eventPrefix . '_load_before', $params);
のようにフックポイント名が継承先のクラス名などによって動的に変わるものがあります。
いずれにしても、Magento上には様々な箇所にフックポイントが設けられているので、一度調べてみるとよいでしょう。
Observerを使うために必要なこと
Observerを使うためには、2つの作業が必要になります。
- Observerクラスの実装
- config.xmlへの定義追加
どちらかが欠けてもObserverは動作しません。
Observerを使う際には、上記の2つを忘れずに実装する必要があります。
Observerクラスの実装
一般的にObserverクラスはModelの下に実装します。
Mage_Core_Model_Abstractを継承して実装しても良いですが、親クラスの存在しない、プレーンなPHPオブジェクトとして実装しても構いません。
要はMagentoのクラス名の命名規則にクラス名が従っていれば良いわけです。
次に、実行したい処理のメソッドを実装します。
このとき、Varien_Event_Observer型の引数を1つ適当な名前で定義するのを忘れないようにしてください。
(これを忘れると何のためのObserverなのかわからなくなってしまいます)
そして、メソッド内で実行したい処理を書きます。
引数に含まれているイベント元から渡されている値の取得方法
引数として与えられた変数からは、
$Xxx = $observer->getEvent()->getXxx();
という形で、Mage::dispatchEvent側で与えた値を取得することができます。
あとは任意の処理を書くことができます。
config.xmlへの定義追加
仕上げにconfig.xmlに定義を書きます。
global, frontend, admintmlそれぞれに定義ができるので、必要に応じて使い分けます。
(globalで定義すると、frontendでもadminhtmlでも実行されます)
定義の書き方は以下のとおりです。
model Myextension_Model_Observer mymethod
typeタグに指定できる値は3種類ほどありますが、普段はtypeタグ自体を定義しなくてもObserverの定義は可能です。
後述するObserverの無効化の場合は、反対に明示的に書かないといけない作りになっています。
Observerの無効化
様々な理由で、既存のObserver処理が邪魔になることがあります。
定義をしているconfig.xmlを改変してしまうと、アップデートの際に問題になってしまうため、できるだけ避けたほうがよいでしょう。
アップデートの際にもトラブルを避けつつ、既存のObserver定義を無効化する場合は、typeタグの値にdisabledを指定します。
以下のように書くわけですね。
disabled
こうすることで、コアの定義ファイルに手を加えること無く、Observerを無効化する事ができます。
まとめ
- MagentoにはObserverというフック機能が用意されている
- Mage::dispatchEventが定義されている箇所は非常に多いので、一度確認しておく必要がある
- Observerクラスとconfig.xmlの定義だけでObserverは使うことができる
- Observerを無効化したい場合は、typeタグにdisabledを与える