前の記事が2年前だった、、、。
リアルにCakePHP3のサイトをいくつか(3つかな)作っていてこちらに手が回りませんでした。
整理のためにCakePHPのバージョンを3.8.2アップして続きを書きます。

認証メソッドを追加する

先に認証コンポーネントで以下の設定をしました。

認証時にAdminテーブルを検索する時に findAuth メソッドを使用する。

このための実装は次のようになります。Model\Entity\Admin.php追加します。

public function findAuth(\Cake\ORM\Query $query, array $options)
{
$query
->select(['id', 'admin_cd', 'admin_name','password','role'])
->where(['Admin.delete_flg' => 0
]);

return $query;
}

パスワードはハッシュ化してから保存する必要があります。
対象は Model\Entity\Admin.php で定義の部分に次を追加します。

use Cake\Auth\DefaultPasswordHasher;

ハッシュ化部分には次を追加します。

protected function _setPassword($value)
{
if (strlen($value)) {
$hasher = new DefaultPasswordHasher();

return $hasher->hash($value);
}
}

これで準備は完了していますが、/admin/admin にアクセスするとはじかれちゃいますよ。はて、管理者はどうやって登録するんだ?

最初の管理者を登録するために、 Controller\Admin\AdminController.php に次のコードを追加します。

public function beforeFilter(\Cake\Event\Event $event) {
parent::beforeFilter($event);
$this->Auth->allow('add');
}

これで /admin/admin/add にアクセス出来て管理者が追加できるようになります。追加した管理者でログインできたらめでたしめでたし。
(※ 最初の管理者を追加したらこのコードは削除してください。)

とりあえず今回は終了。後は何を書こうか。

さて、サクサク進めましょう。

ログインを実装する

管理画面用の AppController.php に認証コンポーネントを設定しました。その結果 /admin/ アクセスしようとすると /admin/admin/login に遷移するようになりましたので、早速ログインを実装してきます。

こちらもチュートリアルの記事が参考になります。AdminController.php にloginメソッドを追加します。

public function login(){
    if ($this->request->is('post')) {
        $admin = $this->Auth->identify();
        if ($admin) {
            $this->Auth->setUser($admin);
            return $this->redirect($this->Auth->redirectUrl());
         }
         $this->Flash->error('管理者IDかパスワードが不正です。');
    }
}

loginテンプレートを作成します。Template/Admin/Admin/login.ctp を作成して、こんな感じでフォームを作ります。

<h1>管理者ログイン</h1>
<?= $this->Form->create() ?>
<?= $this->Form->control('admin_cd') ?>
<?= $this->Form->control('password') ?>
<?= $this->Form->button('Login') ?>
<?= $this->Form->end() ?>

ログインした後のことを考えて、 home メソッドとテンプレートも作りましょう。

AdminController.phpに以下を追加します。

public function home(){

}

Template/Admin/Admin/home.ctp を作ります。中身は適当に。

ログアウトも必要ですね。logoutメソッドも作りましょう。AdminController.phpに以下を追加します。

public function logout() {
$this->Flash->success('ログアウトしました');
return $this->redirect($this->Auth->logout());
}

1,000文字超えてしまったので、続きはまた次回。

だいぶ間があいてしまいました。
が、バージョン3.5もリリースされたことなので、そちらを使って管理画面の構築を続けていきます。
CakePHPのアプリケーションが作成されていて、DBの設定とPrefixルーティングが済んだ状態の想定です。

adminテーブルを作る

まずはテーブル「admin」を作ります。
最近はバージョン管理システムでスキーマの変更も管理できるように、PHPスクリプトでテーブルを作ったりすることも出来るようですが、レトロエンジニアな私はDDLで作ります。こんな感じ。

--
-- テーブルの構造 `admin`
--

CREATE TABLE `admin` (
`id` int(11) NOT NULL,
`admin_cd` varchar(255) CHARACTER SET utf8 NOT NULL,
`admin_name` varchar(64) CHARACTER SET utf8 NOT NULL,
`password` varchar(255) NOT NULL,
`role` char(1) NOT NULL DEFAULT '0',
`delete_flg` char(1) NOT NULL DEFAULT '0',
`create_user` int(10) NOT NULL,
`modified_user` int(10) NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Indexes for dumped tables
--

--
-- Indexes for table `admin`
--
ALTER TABLE `admin`
ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `admin`
--
ALTER TABLE `admin`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

いずれ管理者ごとに権限を制御をするかもしれないので、一般的そうな項目に「role」を付け加えておきました。

モデルとテンプレートをbakeする

テーブルが出来たら、そう、bakeしてモデルとテンプレートを作ります。

bin\cake bake model admin
bin\cake bake template --prefix admin admin

–prefix を忘れずに。(はい、私は忘れました_| ̄|○。)

再度 /admin/Admin にアクセスしてみましょう。
こんな風に表示されたらOKです。

これで下準備が終了。

管理者ログインを作成して、認証を設定する

管理者用のログイン処理、認証コンポーネントを設定していきます。
CakePHP3 で一般ユーザにログインを追加する方法は、チュートリアルのこちらに詳しく記載があります。
ここで考えなきゃいけないのが、作りたいのが「管理者」用のログインであるということです。
すなわち、一般ユーザとは分ける必要があります。
結論を言うと、以下のように設定していきます。

  • /admin/ 用の AppController.php を追加する。
  • 追加した AppController.php に管理者に認証コンポーネントを設定する。
  • AdminController.php の継承元を追加した AppController.php に変更する。

/admin/ 用のAppController.php は元々あるAppController.php をコピーして作り、namespace 部分を次のように変更します。
namespace App\Controller\Admin;
チュートリアルを参照しながら、Authコンポーネントを設定します。具体的には initialize メソッドを次のようにします。
public function initialize()
{
    parent::initialize();

    $this->loadComponent('RequestHandler');
    $this->loadComponent('Flash');

    $this->loadComponent('Auth',[
        'authenticate' => [
            'Form' => [
                'userModel' => 'Admin',
                 'fields' => [
'username' => 'admin_cd',
'password' => 'password'
],
              'finder' => 'auth',
            ]
        ],
        'loginAction' => [
'controller' => 'Admin',
'action' => 'login'
],

        'loginRedirect' => [
             'controller' => 'Admin',
             'action' => 'home',
        ],
        'storage' => [
'className' => 'Session',
'key' => 'Auth.Admin'
]

]);
}

ポイントは次の通りです。ソースの上から順番に。
(ソースコードがフォーマット出来てなくゴメンなさい。)

  • モデル(テーブル)はAdmin(admin)を使用する。
  • ログインのID / パスワードには、項目名 admin_cd / password を使用する。
  • 認証時にAdminテーブルを検索する時に findAuth メソッドを使用する。
  • ログイン処理は /admin/login (Adminコントローラの login メソッド)で行う。
  • ログイン後は /admin/home (adminコントローラの home メソッド)にリダイレクトする。
  • ログイン状態を Session の Auth.Admin というキーに格納する。

AdminController.php の継承元をこのファイルに変更します。
use App\Controller\Admin\AppController;

再度、 /admin/Admin にアクセスしてみると、こんなエラーになりました。

そりゃ当たり前だ。まだ login メソッド作ってませんからね。

認証を先に設定してしまったので編集画面にたどり着けませんでしたが、次回は是非。

去年から今年に掛けてCakePHP3を使ってWebシステムをいくつか作っております。
Webシステムと言えば管理画面が必要になりますね。そこで主に自分のためにCakePHP3を使った実装手順を整理してみることにしました。
なお、文中、フロント側とは一般のサイト利用者が使う側、管理側はサイトの管理者が使う側を指しています。

CakePHPはフロント側と管理画面で同じものを使う

以前、CakePHP1.3を使って同様に独自CMSなWebシステムを構築したときには、フロント側と管理側、それぞれ用にCakePHPを用意して使いました。
ルーティングがうまく使いこなかったこと(調べたり試したりする時間も無かった)、フロント側と管理側で体制が分かれていたのが理由でした。今回は、それではあんまりにも格好悪いので1つのCakePHP3でフロント側、管理側で共有しようと思います。

プレフィックスルーティングで管理側をフロント側から分離する

1.3で使いこなせなかったプレフィクスルーティングを3.0のCookBookで見てみます。なんだか以前よりスッキリしている気がします。config/routes.phpに以下を追加すると/adminでアクセス出来るようになって、src/Controllers/Admin 以下のコントローラが呼び出されるらしい。そしてテンプレートはsrc/Template/Admin/に用意すればいいと書いてあります。

Router::prefix('admin', function ($routes) {
$routes->fallbacks('DashedRoute');
});

この記述だけを追記した状態で /admin/Admin/ にアクセスしようとすると、Missing Controllerのエラーが表示されます。(Adminテーブルを管理するイメージ)

Controller/Adminの下にAdminController.php を作ってAdminControllerクラスを定義せよとのことです。
bakeでさくっとコントローラを作成します。(Windows環境なので \ がディレクトリを指しています。)

※アプリケーションのディレクトリで実行
bin\cake bake controller --prefix admin admin

気をつけるのは –prefix admin を付けること。これでController/Admin以下にファイルが作られます。この状態でアクセスすると、エラーの内容がadminテーブルが無いに変わりました。

そりゃ当たり前だ。まだ作ってないんだから。

今回はここまで。次回は管理者の管理用のadminテーブルを追加して、編集画面を作っていきたいと思います。

CakePHP3の構造になれるためにサンプルコードを増やしています。

カレンダーがサイトにあるといろいろ重宝しそうですよね。もちろん、こういったものは先人が用意してくれているはずですので調べてみます。
すると、FullCalendar というJavascriptで出来たカレンダーをCakePHP3に組み込むプラグイン「CakePHP-Full-Calendar-Plugin」が見つかったので、そちらをを使わせてもらうことにしました。プラグインはこちらから入手できます。(CakePHP2用と間違えないように。)

READMEに「INSTALLED IN 6 SIMPLE STEPS」と書いてありますが、プラグインをロードするときにプラグインのroutes.php を読み込むよう指定しているので、実際は5ステップ目はいらないと思われます。さくっとインストールして指示の通り event_typeを登録してからeventを登録しますが、、、表示されない!

Chromeのデベロッパーツールなんかを見ながらソースを追ってみると、EventsControllerのfeedメソッドでJSON形式のデータを返すべきところで配列(というかArray()っていう素っ気ないアレ)が返されてしまっているっぽい。こういう時はGoogle先生に訊くか本家サイトでドキュメントをを見るべし、ということで見てみたら、CakePHPでJSONを扱うにはRequestHandlerをロードせよ、とのことだったのでAppControllerに追記。おー、表示された。あれ?終日の予定の表示がヘン、、、。

再びプラグインのソース追っかけてみたところ、同じくEventsControllerのfeedメソッドで終日の予定を判定する時に比較を「===」で行っているところで判定できていないっぽい。「==」に修正したら正しく表示されました(^_^)v。こんな修正でよかったかはあとできちんと調べよう。