何がやりたいのかっていうと、Paginator みたいなのを自作したいです。
- CakePHP 2.7.5
Component が呼ばれたら Helper も自動で呼ぶ
Paginator は Controller 内で public $components = array('Paginator');
で呼び出すと、Helper も自動で使えるようになるので同じように Helper が呼び出されるようにします。
<?php class SampleComponent extends Component { public $settings = array(); public function __construct(ComponentCollection $collection, $settings = array()) { $settings = array_merge($this->settings, (array)$settings); // Controller をこの Component 内で使えるようにする $this->Controller = $collection->getController(); // SampleHelper を ctp 内で利用できるようにする if (!in_array('Sample', $this->Controller->helpers) && !array_key_exists('Sample', $this->Controller->helpers) ) { $this->Controller->helpers[] = 'Sample'; } parent::__construct($collection, $settings); }
Paginator では、pagenate()
内で $this->Controller->helpers[] = 'Pagenate';
をしていますが、今回は関数を実行していなくても Helper を使いたかったので、コンストラクタで同様の処理をしました。
Helper で Component の設定を使えるようにする
Pagenator では外から設定を行うことができます。
<?php $this->Paginator->settings = array( 'paramType' => 'querystring', 'limit' => 20, 'order' => 'Info.created desc');
同じように設定できて、かつ、この設定を Helper 内で使えるようにします。
<?php public function beforeRender(Controller $controller){ // 設定が利用できるように request に設定する if (!isset($this->Controller->request['__sample_setting'])) { $this->Controller->request['__sample_setting'] = array(); } $this->Controller->request['__sample_setting'] = array_merge( (array)$this->Controller->request['__sample_setting'], $this->settings ); }
いい方法が見つからなくて、Controller の request に設定しちゃってます。もっと腑に落ちるやり方がありそうなんですがどうなんでしょうかね。
Component 内のメソッドで設定をいじってもいいように beforeRender
でやってます。
これで、Helper 内で $this->request->params['__sample_setting']
でアクセスできるようになります。
まとめ
- Component の呼び出しで Helper を使えるようにする
- Component と Helper で設定の共有
を実装してみた話でした。
Bake が何かわかってないレベルの僕が作ったやつなので、モアベターがあれば教えてほしいです。