wrapsモジュールを手直しした際の覚え書きで恐縮ですが…
・Cube2.1かどうかを判断する
if( defined( 'XOOPS_CUBE_LEGACY' ) ) {
class_exists('XCUBE_ROOT') だと、Shadeとの区別がつきません。
(ShadeでもX2でも動くモジュール、というのはさすがに想像つきませんが)
・デリゲートやアクションフィルターを登録する
X2, Cube2.1の両方で通過し得るコードについて、Cube2.1専用の機能を使うなら、当然、上の条件式で判断します。(そうしなければ、X2側でfatal)
ただ、モジュールpreloadを使う、というのも良い手です。
ROOT_PATH側に、preload/(class名).class.php というファイルを置いておけば、ここを処理するのは、Cube2.1だけです。
Legacy_Controllerを読めば判りますが、そのファイルをrequire_onceした後で、(class名)のインスタンスを作り、アクションフィルターに登録しようとします。
残念ながら、この仕掛けの後半部分は、複製可能モジュールには利用できないので、「(class名)のクラスを作らないこと」が重要です。クラスが存在したら、インスタンスが作られ、登録されてしまいます。
D3モジュール側でアクションフィルターを登録する場合は、(class名)とは異なるクラスを作って、自分で $root->mController->addActionFilter()する必要がありそうです。
・preloadディレクトリを用意する
当たり前ではありますが、XOOPS_ROOT_PATH側にpreload/ディレクトリを掘る必要があります。
ただ、ROOT_PATH側である、というところが嫌らしい点で、せっかくのD3モジュールの売りである、ROOT_PATH側はアップデートしなくていい、というメリットが消えてしまいます。早めに、ROOT_PATH側にpreload/(class名).class.php を用意しておいた方が良いでしょう。もちろん中身はTRUST_PATH側を読み出しに行くだけのスケルトンで構いません。
意味あるロジックはすべてTRUST_PATH側で処理するのがD3モジュールの基本ですから。
・インストール/アップデート/アンインストール時のメッセージ出力
デリゲート
Legacy.Admin.Event.Module(Install|Update|Uninstall).Success
の第2パラメーターに、logオブジェクトが渡されます。
というわけで、$log->add( メッセージ ) ; するだけです!
minahitoさん、ありがとう。