シェアする

  • このエントリーをはてなブックマークに追加

[CakePHP2]コントローラから呼び出したコンポーネントのコンストラクタで呼び出し元コントローラを取得する

コンポーネントには以下のコールバックメソッドがあります。

  • initialize(Controller $controller)
  • startup(Controller $controller)
  • beforeRender(Controller $controller)
  • shutdown(Controller $controller)
  • beforeRedirect(Controller $controller, $url, $status=null, $exit=true)

いずれのコールバックメソッドも引数にコントローラを持っているので、コンポーネントからコントローラのプロパティやメソッドにアクセスできます。

例えばコントローラのbeforeFilterの前に実行されるinitializeメソッドで以下のように書けば、コンポーネントの別のメソッドでもコントローラにアクセスできるわけです。

HogeComponent

public function initialize(Controller $controller) {
	$this->controller = $controller;
}

public function test() {
	// Viewに変数を渡したり
	$this->controller->set('title_for_layout', 'Hogeコンポーネントのtestメソッドからセットしたタイトル');
	// Sessionメッセージを設定したり(セッションコンポーネントをコンポーネントでセットすればコントローラを通さなくてもいいけど)
	$this->controller->Session->setFlash('Hogeコンポーネントのtestメソッドからセットしたメッセージ');
	// Modelも使えます。(App::usesで呼ぶ方がスマートだけど)
	$this->controller->loadModel('Test');
}

ところが、コントローラでコンポーネントを読み込む場合はちょっと問題があります。

例えば呼び出し元コントローラのあるメソッドでこんな風にHogeコンポーネントを読み込む場合。

class FugasController {
	
	function aru() {
		$this->Hoge = $this->Components->load(Hoge);
	}
}

この場合、コンポーネントのコールバックメソッド「initiazile」と「startup」は通すことができません。*[1]
コンポーネント側の通常のメソッドを、コントローラを使用する前提で作ったりすると困ったことになるわけです。

コンポーネントのコンストラクタで呼出元コントローラをセットする

そこで、コンストラクタを使って呼び出し元コントローラをプロパティにセットすることにしました。

HogeComponent

	public function __constract(ComponentCollection $collection) {
		$this->controller = $collection->getController();
	}

コンストラクタの引数はコントローラではなくComponentCollectionであることに注意しましょう。
ComponentCollectionは呼び出し元のコントローラを_Controllerプロパティに持っていますが、protectedのためHogeComponentからはアクセスできません。
なので、getControllerメソッドを使って取得しています。

コントローラ単位でコンポーネントをセットするのは勿体無い、だけどコントローラにもアクセスしたい。というのはよくあるケースだったのでφ(..)メモしておきます。

  1. どちらのメソッドもFugasコントローラのaruメソッド実行前に呼出が終わっているから []

シェアする

  • このエントリーをはてなブックマークに追加

フォローする