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


2015年から 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");

また View/Layouts/default.php に以下のコードを追加し、全画面で「custom.css」と「custom.js」を読み込み、カスタマイズ用の CSS とJavaScript を追加できるようにした。

echo $this->Html->css('custom.css'); // カスタマイズ用CSS
echo $this->Html->script('custom.js'); // カスタマイズ用スクリプト

ブラウザで /update を実行すると、パッケージ本体のテーブル定義のアップデートと、カスタマイズ用のテーブル定義のアップデートが同時に行われる。

ディレクトリ構成を図にすると以下の通りとなる。


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

関連記事:

コメントを残す

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

CAPTCHA


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