CakePHP5入門【CakePHP5実用編⑨】ユーザ登録申込み①

A子
誰でもユーザ申込みを行うことができて、(申し込んだ人が)勝手にユーザ登録されるようにはできないかな?

B美
(本番環境に公開したあとの話だけど)
そもそも(存在しない)適当なメールアドレスで申し込むかもしれないし…

C菜
そうすれば存在しないメールアドレスや、他人のメールアドレスを使うことはできなくなりますよね~?

A子
システム側は申込者専用のURLを作って、それをメールに記載して送信
メールを受け取った申込者は、そのURLリンクをクリックすることで確認ページに到達するって感じで…
あと、時間制限も設ければ完璧じゃない?

B美
チャットルームの新規作成や削除をする権限を与えるのかってことだけど…

C菜
でもそうすると、「users」テーブルの構造も変えなきゃですね~

A子
「管理者」「一般ユーザ」「お試しユーザ」の3種類にして
・管理者…何でもできる特権ユーザ
・一般ユーザ…ユーザ管理以外は全てOK(チャットルームの作成も可) ・お試しユーザ…チャットルームに入室して、発言だけ可能 |
…って感じで、どうかな?
あ、当然「users」テーブルには項目を一つ追加するよ
int型の「role_num」って項目名でどう?

C菜
あと、「管理者」はユーザ管理画面の中で、「お試しユーザ」を「一般ユーザ」に昇格させることができるようにしましょう~

B美
複数の「管理者」権限を許可するの?

A子
本来は「一人だけ」にすべきだろうけど、もしも一人しかいない「管理者」が突然失踪したりすると…(笑)

C菜
「管理者」は、他のユーザを「管理者」に任命(というか昇格)できるようにしましょうよ~

A子
んじゃ、まずは「users」テーブルの修正からね
create table users (
id int auto_increment primary key, email varchar(255), password varchar(255), status int, session varchar(255), login_time datetime, logout_time datetime, role_num int, created datetime, modified datetime ); |
で、どうかな?

C菜
(「config/const.php」ファイルに追加)
define("ADMIN", 1); //管理者
define("NORMAL", 2); //一般ユーザ define("GUEST", 3); //お試しユーザ |

B美
それじゃ、とりあえず「ALTER TABLE」で「users」テーブルに項目を追加したあと、関連のControllerやViewを修正してみなさい
あ、多分だけどModelである「User.php」や「UsersTable.php」の変更は必要ないと思う
(キャッシュクリアは必要だけど…)

C菜
まずは「ALTER TABLE」です~
えっと「MATE端末」を開いてから「mysql」コマンドを叩きますね~
mysql -u root -p chatdb[Enter] |
ALTER TABLE users
ADD role_num int AFTER logout_time;[Enter] |


B美
show fields from users;[Enter] |


A子
んじゃ、何はともあれキャッシュクリアをやっておこう
cd html/authapp[Enter]
bin/cake cache clear_all[Enter] |


C菜
「templates/Users」の中にある「index.php」「view.php」「edit.php」だけで良いでしょうか~?

A子
「add.php」は良いの?

C菜
(最初のユーザ作成である「first_user.php」で登録した人が、自動的に「管理者」になるのと一緒です~)

A子
あ、先に「config/const.php」の中に定数を追加しておこう


C菜

B美
define("ROLE_NAME", ["-", "管理者", "一般ユーザ", "お試しユーザ"]); |
とすれば、「ROLE_NAME[$user->role_num]」で簡単に表示できるから…
(配列の添字がゼロから始まることに注意してね)

A子
もしかして連想配列も定数化できるの?

B美
define("定数名", ["キー1" => "値1", "キー2" => "値2", "キー3" => "値3", ・・・]); |
…って感じね

C菜
(【コラム③】を参照)

A子
そうだったっけ?(汗)

B美

C菜


C菜
wide表示のほうだけ「ユーザ権限」を表示しましょう~
(narrow表示のほうは以前のままです~)


A子


B美
「role_num」がnullであるときの対応を記述しているのは大したものだけど、実際にはnullになることは無いと思うわよ
なので、既存のユーザの「role_num」をSQL文でセットしてからテストしたほうが良いかもね
mysql -u root -p chatdb[Enter] |
UPDATE users SET role_num=1 WHERE id=1;
UPDATE users SET role_num=2 WHERE id=2; UPDATE users SET role_num=3 WHERE id=3; |
これで私(B美)が「管理者」、A子が「一般ユーザ」、C菜が「お試しユーザ」になるわ


C菜

B美
わざわざ書き換える必要は無いわよ
(蛇足にはなるけど、「念のため」という観点では悪くないしね)

A子
「ユーザ権限」をラジオボタンで選択できるようにしたいんだけど、どうすれば良い?

B美
<?= $this->Form->radio('role_num', [
['value' => 1, 'text' => ' '.ROLE_NAME[1]], ['value' => 2, 'text' => ' '.ROLE_NAME[2]], ['value' => 3, 'text' => ' '.ROLE_NAME[3]], ], [ 'label' => ['style' => 'display: block;margin-bottom: 5px;'] ]) ?> |
これで現在の(role_numの)値によって自動的に選択状態になるの
(ちなみに、style指定しているところがポイントね)


A子
どういうこと?

B美
上記のようにstyle指定すると、三つの項目が「縦方向」に並ぶってわけ
(あと、ROLE_NAMEの左の「' '.」は、黒丸とラベルがくっつき過ぎないように付けてるだけ)


C菜
よくよく考えると、パスワードの変更は「本人のみが行えるように」すべきではないでしょうか~?
(管理者の権限で変更できるのは「ハンドルネーム」と「ユーザ権限」だけにして…)

A子
うん、そのほうが良いかも…
それじゃ、「edit.php」を「change_password.php」というファイル名で保存して、不要な部分を削除だね


C菜



B美


A子
(具体的には「templates/Top」の中にある「index.php」ね)

↓


C菜
public function changePassword()
{ $user = $this->Users->get($this->identity->id, contain: []); if ($this->request->is(['patch', 'post', 'put'])) { $user = $this->Users->patchEntity($user, $this->request->getData()); if ($this->Users->save($user)) { $this->Flash->success(__('パスワードを変更しました。')); return $this->redirect(['controller' => 'Top', 'action' => 'index']); } $this->Flash->error(__('パスワードの変更に失敗しました。')); } $this->set(compact('user')); } |
ポイントは、メソッド名が(「change_password」ではなく)「changePassword」であることと、「$this->identity->id」で自分自身のidを取得していることですね~


A子
あとは「最初のユーザ作成(first_user.php)」と「ユーザ登録(add.php)」について、「src/Controller」の中にある「UsersController.php」を修正するだけだね
(「firstUser」メソッドと「add」メソッドね)



C菜
データベースを初期化するために以下のコマンドを打ち込みますね~
mysql -u root -p chatdb[Enter]
drop database chatdb;[Enter] quit[Enter] mysql -u root -p < chatdb.sql[Enter] cd html/authapp[Enter] bin/cake cache clear_all[Enter] |
あ、もちろん「chatdb.sql」には「users」テーブルに「role_num」の項目を追加済みです~




A子
最初のユーザとして私(A子)を登録したよ
そのあと、ユーザ管理画面に入って、「新規ユーザ登録」でB美とC菜の二人を登録した


C菜
ここからB美部長を「管理者」にできますか~?

A子
うん、バッチリ昇格できたみたい


B美
「管理者」でないと「ユーザ管理画面」へのリンクが出現しないようにして、さらに「UsersController.php」でも管理者チェックを行うようにしておきなさいね

A子
まずは「UsersController.php」だけど、管理者用のメソッドである「index」「view」「add」「edit」「delete」の五つについて、管理者権限があるかどうかのチェックを入れよう

C菜

A子
private function checkAdmin()
{ if ($this->identity->role_num != ADMIN) { $this->Flash->error(__('管理者以外はアクセスできません。')); return $this->redirect(['controller' => 'Top', 'action' => 'index']); } } |
これをさっきの五つのメソッドから呼び出すよ
$this->checkAdmin(); |
上記の一文を各メソッドの先頭行に追記ね



B美
まぁ、難しくなっちゃうからそこまでは求めないわ
(A子のやり方のほうがシンプルで分かりやすいし…)

C菜
「templates/Top」の中にある「index.php」を修正するです~
<?php if ($identity->role_num == ADMIN) { ?>
・・・ <?php } ?> |
を使って「ユーザ管理」へのリンクタグを囲みますね~


B美
ただ、ちょっと長くなっちゃったから、お試しユーザの自動登録機能は次回に回しましょう

A子

C菜