CakePHP2.xにおけるパッケージとカスタム領域の分離


数年前から CakePHP2.xをベースに、あるパッケージソフトウェアを開発しているのだが、実際にお客さんに提供する際に、一部の機能、デザインをカスタマイズして提供することが多い。

しかしパッケージ本体のソースコードに手を入れてしまうと、後々パッケージをバージョンアップした際に、マージするのが非常に煩雑になる。WordPress のプラグインように、CakePHP のプラグイン機能を使って拡張する方法も検討してみたが、制約が多く、なかなか思うようにはいかない。そこで CakePHP のクラスパスを利用し、ソースの読み込み順を制御することによって、パッケージ本体とカスタム領域を分離することを試みた。

具体的には、CakePHP の構成設定ファイル、Config/bootstrap.php に以下のような設定を行った。

// カスタマイズ用ディレクトリの登録(このディレクトリに格納されたソースを優先して読み込む)
App::build(
	array(
		'Model'                     => array(APP.'Custom'.DS.'Model'.DS),
		'Model/Behavior'            => array(APP.'Custom'.DS.'Model'.DS.'Behavior'.DS),
		'Model/Datasource'          => array(APP.'Custom'.DS.'Model'.DS.'Datasource'.DS),
		'Model/Datasource/Database' => array(APP.'Custom'.DS.'Model'.DS.'Datasource'.DS.'Database'.DS),
		'Model/Datasource/Session'  => array(APP.'Custom'.DS.'Model'.DS.'Datasource'.DS.'Session'.DS),
		'Controller'                => array(APP.'Custom'.DS.'Controller'.DS),
		'Controller/Component'      => array(APP.'Custom'.DS.'Controller'.DS.'Component'.DS),
		'Controller/Component/Auth' => array(APP.'Custom'.DS.'Controller'.DS.'Component'.DS.'Auth'.DS),
		'Controller/Component/Acl'  => array(APP.'Custom'.DS.'Controller'.DS.'Component'.DS.'Acl'.DS),
		'View'                      => array(APP.'Custom'.DS.'View'.DS),
		'View/Helper'               => array(APP.'Custom'.DS.'View'.DS.'Helper'.DS),
		'Console'                   => array(APP.'Custom'.DS.'Console'.DS),
		'Console/Command'           => array(APP.'Custom'.DS.'Console'.DS.'Command'.DS),
		'Lib'                       => array(APP.'Custom'.DS.'Lib'.DS),
		'Locale'                    => array(APP.'Custom'.DS.'Locale'.DS),
		'Vendor'                    => array(APP.'Custom'.DS.'Vendor'.DS),
		'Plugin'                    => array(APP.'Custom'.DS.'Plugin'.DS),
	)
);

その結果、Custom ディレクトリにパッケージ本体と同名のソースファイルを配置した場合、 Custom ディレクトリ上のファイルが優先的に読み込めるようになった。例えばパッケージのログイン画面をカスタマイズしたい場合は、パッケージの View/login.ctp を Custom/View/User ディレクトリにコピーし、カスタマイズを行う。パッケージ側のソースファイルには修正が入らないため、ファイルの差し替えだけでパッケージの更新が可能となる。

加えて、同じく Config/bootstrap.php に以下の行を加えることによって、Custom ディレクトリに配置した config.php ファイルによって、パッケージ本体の設定の上書き、及び追加ができるようになった。

// カスタマイズ用設定ファイルをロード
Configure::config('default', new PhpReader(APP.'Custom'.DS.'Config'.DS));
Configure::load("config");

図にすると以下の通りとなる。


これでパッケージ本体とカスタム領域を一応は分離することが可能となった。しかしながら、この方法ではソースファイル単位での差分が発生してしまい(例えば UsersContoller.php の特定のメソッドを書き換えたいだけ場合も、ソースを丸ごとコピーする必要がある。 )、まだ改善の余地があるように思う。

関連記事:

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください