CakePHPでWebアプリを作った後に追加要件として表示内容を差し替えて欲しいと言われた場合の最終手段です。本日は「CakePHPのafterFilterで全てのビューファイルを置換する」についてです。
こんにちは。猫ITソリューションズ広報の齊藤メイ(♀)です。本日は、「CakePHPのafterFilterで全てのビューファイルを置換する」についてです。
CakePHPは多くのWebアプリケーションで使われているPHPフレームワークです。先に書いた「差し替えて欲しい」というのも当然一括置換で通常なら楽勝で対応可能なのですが、状況によってはそう上手くいかない場合もあります。例えば全ページにおいて差し替えが必要で、全てのコントローラーに記述していてはリリースまでに時間がかかる、、、とかです。そもそも面倒くさいというもっと重大な問題もありますが。そんなときに便利なのが今回ご紹介するリクエストライフサイクルコールバック「afterFilter」です。なお今回使用するバージョンは1.2.7になります。
リクエストライフサイクルコールバックとは
CakePHPのコントローラーにはリクエストのライフサイクル周り、つまりゆりかごから墓場までロジックを挿入できるコールバック関数がついています。その中の一つがafterFilter()です。全部で3つあります。
http://book.cakephp.org/2.0/ja/controllers.html#controller-life-cycle
- Controller::beforeFilter()
各アクションの前に実行される - Controller::beforeRender()
アクションの後でビューが描画される前に呼ばれる - Controller::afterFilter()
アクションの後で描画が完了した後に呼ばれる
今回は最後の最後、ブラウザーに表示される直前に置換したいのでafterFilterを使います。
サンプル
要件
では早速作ってみましょう。今回サンプルとして作るプラグインの要件と制約は以下の通りです。ちなみに過去記事「Smartyプリフィルタプラグインで全てのビューファイルを置換する」と全く同じです。
- 全てのページの</body>タグの前にJavaScriptコードを埋め込みたい
- JavaScriptコードは外部ファイル
- 実プログラムには1ミリも手を加えられない
スーパークラスAppControllerを確認
コードはスーパークラスであるAppControllerに記述しますので、どこにあるかを確認しましょう。ここでは、
/cake/app/app_controller.php
とします。
JavaScript外部ファイルを用意する
要件ですので用意します。今回は、
/cake/app/webroot/js/test.js
とします。
コードを書く
それではコードを書くのですが、、、少し補足します。サンプルコードではafterFilter()の有効/無効は別ファイル/cake/app/config/bootstrap.phpに定数ANALYTICS_CAKEPHPとして設定しています。意味不明な定数名ですが、そこは華麗にスルーして適当に脳内置換した上で参考にしてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php public function afterFilter() { if(ANALYTICS_CAKEPHP == 1){ $pattern = '/<\/body>/i'; if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'){ $protocol_current = 'https'; } else { $protocol_current = 'http'; } $replacement = file_get_contents($protocol_current.'://'.$_SERVER["SERVER_ADDR"] .'/cake/app/webroot/js/test.js'); $replacement = $replacement.''; $this->output = preg_replace($pattern, $replacement, $this->output); } } ?> |
以上です。これで全てのビューファイル中の</body>タグがJavaScriptコード+</body>として置換されます。
CakePHPを使ったそれなりに規模が大きいプロジェクトにおいて全体的な修正をかけたい場合に便利です。しかし最初に書いたとおりで「最終手段」と猫ITソリューションズは考えています。出来ればこういう状況にならないようにしたいものですね。