NTTドコモ様_dカーシェア
NTTドコモ様_dカーシェア
2012.08.06

CakePHP2系でコンポーネントを動的に追加する方法。

小林

⌘ + Ctrl + F 小林です。

CakePHP2系で開発をしている諸兄はもちろんのこと、これから開発しようと思っている諸兄もコンポーネントには興味津々ですよね?かく言う自分も大好きです。コンポーネント。もうね、語感がいいですよね。コンポーネント。コンポーでネントですよ。たまらんわー。

さて、そんなドラスティックなコンポーネントですけど、基本的な使い方ですと、Alwaysコンポーネントしていなきゃいけない感じですよね。少なくともコントローラでは。

CookBooks 2.X のコンポーネントの項を見ますと、こんな記述が見受けられます。

class PostsController extends AppController {
  public $components = array(
    'Auth' => array(
      'authorize' => array('controller'),
      'loginAction' => array('controller' => 'users',
                             'action' => 'login')
      ),
    'Cookie' => array('name' => 'CookieMonster')
  );

これってつまり常にコンポーネントがコンポーネントされてしまっている状態ってことなんですよね。そこで、もし、コンポーネントを好きなときだけコンポーネントできたらそれはとっても素敵じゃないですか!?

というわけで、それを実現する二つの方法をご紹介します。

一つ目は、先ほどの CookBooks 2.X のコンポーネントの項に書いてありました。

$this->OneTimer = $this->Components->load('OneTimer');
$this->OneTimer->getTime();

素晴らしいですね。こんな簡単にできるなんて。

もうひとつは、コントローラのコンストラクタをオーバーライドする方法です。

では、こんなシナリオで利用例を紹介しようかと思います。

「管理画面があるサイトを作るよ。これはAdminルーティングを使おう。そして、もちろん管理画面へのアクセスは認証を必要にしたい。じゃあ認証用にAuthComponentを使おう。でもページ数が多いからAppControllerでAuthコンポーネントは定義したいなぁ。でも認証が必要じゃないページについてはどうしよう・・・。困ったなぁ・・・。」

AppController.php

public $components = array( 'Session' );
public function __construct( $request = null, $response = null ) {
    //CakeRequest::is()で判定できるパラメータの追加
    //以下はAdminルーティング設定時にURLにadminが含まれている場合
    Router::getRequest()->addDetector( 'Admin', array( 'param' => 'admin', 'value' => '1' ) );
    if ( Router::getRequest()->is( 'Admin' ) ) {
        //この段階ではまだヘルパーおよびコンポーネントは生成されていないので変更可能
        $this->components[] = 'Auth';
    }
}

これで、Adminルーティングで設定した管理画面へのアクセス時のみ、Authコンポーネントを有効にすることができました。同じ要領でヘルパーの動的追加もできちゃうんですね。

※プラグインを利用するものについてはこの限りではないと言わざるを得ません。