cakephp3 Controllerを階層化する際の方法
ちょっとした決済システムを構築しています。
販売者(merchants)と顧客(customers)がいて、
決済(orders)を通じてデータが紐付いています。
それぞれにMVC(Model,View,Controller)があるわけですが、
販売者、顧客が自身の決済を参照するために、
管理画面を用意する必要があります。
そうなると、
販売者はmerchants/merchant:id/orders/index
顧客はcustomers/customer:id/orders/index
で決済を見るようにしたいわけです。
それを実現するために、
Controllerを階層化したいのですが、
Google先生で調べながらやると、
迷走してしまいました^^;
迷走した理由は、
2つの情報が錯綜しているからなのですが、
それは後述するとして、
先に階層化する方法を書きます。
Controllerを階層化する際の方法
(1) routes.phpに以下を追記する
>|php|
Router::prefix('merchants',function($routes){
$routes->fallbacks(DashedRoute::class);
});
|
(2) Controller/Merchants/OrdersController.phpを作成する
<?php namespace App\Controller\Merchants; use App\Controller\AppController; /** * Merchants\Orders Controller * * @property \App\Model\Table\OrdersTable $Orders * * @method \App\Model\Entity\Order[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = []) */ class OrdersController extends AppController { ... /** * Index method * * @return \Cake\Http\Response|void */ public function index(){ } ... }
(3) Template/Merchants/Orders/index.ctpを作成する
以外と簡単な設定ですみました。
ちなみにログイン画面は、
merchants/loginでアクセスしたいと考えた場合、
上記のroutes.phpの設定では、
merchantsController.phpを探しに行くのではなく、
src/Controller/Merchants/LoginController.phpを
探しにいってしまいます。
MerchantsController::loginの方に
アクセスしたい場合は、
routes.phpに
$routes->connect('/merchants/login', ['controller' => 'Merchants','action' => 'login', 'prefix' => null]);
と記載すればOKです。
[補足] Google検索したら迷走した理由
階層化は前述の通り比較的簡単な設定ですみましたが、
実際ここにたどり着くためには、1,2時間要してしましました。
理由は2つの情報が錯綜していたからです。
2つの情報は、それぞれ以下です。
▼1つ目(Controllerを階層化する方法)
teratail.com
▼2つ目(階層化した時にController名がかぶった場合の設定)
norm-nois.com
1つ目の情報によると、
Controllerを階層化するには、
composer.jsonを修正して、
src/Controller/Merchants/ を自動読み込みすればよい
ということが書いてあります。
2つ目の情報によると、
src/Controller/UsersController.php
src/Controller/Admins/UsersController.php
のように別階層に同じ名前のControllerを置く場合は、
bootstarp.phpに数行その旨を記述しないといけない
ということが書いてあります。
最初に見つけた情報が
1つ目の記事だったので、
書いてあるとおりに実行をしたら、
Controllerを階層化することには成功しました。
しかし、階層構造の中に
同じ名前のコントローラが出てくると
片方のコントローラが読み込みエラーになります。
そのため、
2つ目の記事にある
src/Controller/UsersController.php
src/Controller/Admins/UsersController.php
という階層構造を作る方法を実践してみたのですが、
こちらはうまくいきませんでした。
最終的に、
1つ目の設定を解除して
routes.phpで公式ドキュメントにある
プレフィックスルーティングの設定をすることで
解決したというところになります。