CakePHP5入門【CakePHP5実用編⑰】バージョンアップ

A子
やっぱもう少し改良したいんだよね

B美

A子
1.お試しユーザの「申込み」時と「最終登録」時に管理者宛てにメール通知する
2.入室制限とは別に、お試しユーザのみ「発言可能」か「閲覧のみ」の制約を部屋ごとに設定できるようにする 3.ユーザごとに(チャット画面の)背景色や文字色を設定できるようにする |
…って感じかな

C菜
でも少し大変そうです~(汗)

B美
私は(なるべく)口出ししないから、できるだけ二人でやってみなさい

A子
それじゃ、まずは1番だね
1.お試しユーザの「申込み」時と「最終登録」時に管理者宛てにメール通知する |

C菜
「config/const.php」ですけど、前回(本番環境へのデプロイ時)はファイルの内容を直接書き換えましたよね~

A子
そだね

C菜
なので、このようにしませんか~?
define("ENVIRONMENT", 1); //1…開発環境,2…本番環境
・・・ if (ENVIRONMENT == 1) { define("WEBSOCKET_IP", "192.168.1.205"); //WebSocketサーバのIPアドレス define("WEBSOCKET_NAME", "192.168.1.205"); //WebSocketサーバのドメイン名 } else if (ENVIRONMENT == 2) { define("WEBSOCKET_IP", "49.212.186.238"); //WebSocketサーバのIPアドレス define("WEBSOCKET_NAME", "friction-river.jp"); //WebSocketサーバのドメイン名 } |
上記以外にも「BASIC認証」「サーバ証明書」「メール中に記載するURL」を同じようにif文で切り分けるということです~





A子
本番環境にアップロードするときは「ENVIRONMENT」の値を「2」に変更するだけで良いってわけね

B美
「const.php」がPHPファイル(プログラム)だってこと、よく分かってるじゃない

A子
「src/Mailer」の中にある「ApplicantMailer.php」にメソッドを追加すれば良いよね
public function info1($email)
{ $this->setEmailFormat('html') ->setFrom([FROM_ADDRESS => APPLICATION_NAME]) ->setTo(ADMIN_ADDRESS) ->setSubject(MAIL_INFO1_SUBJECT) ->viewBuilder() ->setTemplate('info1') ->setLayout('default') ->setVars(['email' => $email]); } public function info2($email) { $this->setEmailFormat('html') ->setFrom([FROM_ADDRESS => APPLICATION_NAME]) ->setTo(ADMIN_ADDRESS) ->setSubject(MAIL_INFO2_SUBJECT) ->viewBuilder() ->setTemplate('info2') ->setLayout('default') ->setVars(['email' => $email]); } |
「info1」が「申込み」時に、「info2」が「最終登録」時に実行されるやつね
あ、もちろん以下の定数を「const.php」に追加するよ
define("ADMIN_ADDRESS", "xxxx@friction-river.jp"); //管理者メールアドレス
define("MAIL_INFO1_SUBJECT", "お試しユーザ申込み通知"); //管理者宛てメールのタイトル(申込み有り) define("MAIL_INFO2_SUBJECT", "お試しユーザ登録通知"); //管理者宛てメールのタイトル(新規登録有り) |



C菜



A子
具体的には「regist」メソッドと「finalCheck」メソッドに一行ずつ追加しただけ…



C菜
では、次ですね~
2.入室制限とは別に、お試しユーザのみ「発言可能」か「閲覧のみ」の制約を部屋ごとに設定できるようにする |
これって、「chat_rooms」テーブルに項目を追加しないといけないですね~

A子
create table chat_rooms (
id int auto_increment primary key, theme varchar(255) not null, admin_id int not null, delete_flag int not null, access_policy int, guest_read_write int, created datetime, modified datetime, foreign key(admin_id) references users(id) ) charset=utf8mb4; |
で、どうかな?

C菜
それでは、その項目に格納する値はこうしましょう~
define("GUEST_WRITE_OK", 1); //発言許可
define("GUEST_READ_ONLY", 2); //閲覧のみ define("GUEST_POLICY", ["-", "発言許可", "閲覧のみ"]); |


A子
それじゃ「chat_rooms」テーブルを(ALTER TABLEで)修正しよう
mysql -u root -p chatdb[Enter] |
ALTER TABLE chat_rooms
ADD guest_read_write int AFTER access_policy;[Enter] |


C菜
'guest_read_write' => true, |


A子
具体的には、「templates/ChatRooms」の中にある「add.php」「edit.php」「view.php」だね
(「index.php」は修正しなくても良いかな)

C菜

↓


B美
テスト実行する前に、必ずキャッシュクリアしておきなさいね

C菜


A子
次は「edit.php」だね


C菜


A子
アクセス者が「お試しユーザ」で、かつチャットルームの制約が「お試しユーザは閲覧のみ」だった場合、フラグ($guest_ng)をtrueにするよ
$guest_ng = false;
if ($this->identity->role_num == GUEST && $chat_room->guest_read_write == GUEST_READ_ONLY) { //お試しユーザで、かつチャットルームの制約が「お試しユーザは閲覧のみ」である場合 $guest_ng = true; } $this->set(compact('guest_ng')); |


C菜

↓


B美
さて、最後は3番だけど、どこまでやるつもり?
3.ユーザごとに(チャット画面の)背景色や文字色を設定できるようにする |

A子
定数化している項目を「users」テーブルに追加するつもりだけど?

C菜
定数名 | 値 | 用途 |
---|---|---|
SENT_COLOR | #dcf8c6 | 自分の発言の背景色 |
RECEIVED_COLOR | #e5e5e5 | 他人の発言の背景色 |
THEME_COLOR | #006400 | テーマの文字色 |
USER_LIST_COLOR | #fffacd | 入室ユーザリストの背景色 |

A子
でも、それ以外の三つは各ユーザが設定できるようにしよう
それぞれに文字色設定も加えて、全部で6項目だね

C菜
項目名 | データ型 | 用途 |
---|---|---|
sent_backcolor | varchar(10) | 自分の発言の背景色 |
sent_forecolor | varchar(10) | 自分の発言の文字色 |
received_backcolor | varchar(10) | 他人の発言の背景色 |
received_forecolor | varchar(10) | 他人の発言の文字色 |
userlist_backcolor | varchar(10) | 入室ユーザリストの背景色 |
userlist_forecolor | varchar(10) | 入室ユーザリストの文字色 |
あ、データ型は「int」のほうが良いのでしょうか~?

B美
あと、色情報って必ず7文字以下の16進数だから、「varchar(7)」でも良いけどね
(まぁ、少し余裕を持たせて「varchar(10)」でもOK)

A子
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, sent_backcolor varchar(10), sent_forecolor varchar(10), received_backcolor varchar(10), received_forecolor varchar(10), userlist_backcolor varchar(10), userlist_forecolor varchar(10), created datetime, modified datetime ); |

C菜
mysql -u root -p chatdb[Enter] |
ALTER TABLE users
ADD sent_backcolor varchar(10) AFTER role_num, ADD sent_forecolor varchar(10) AFTER sent_backcolor, ADD received_backcolor varchar(10) AFTER sent_forecolor, ADD received_forecolor varchar(10) AFTER received_backcolor, ADD userlist_backcolor varchar(10) AFTER received_forecolor, ADD userlist_forecolor varchar(10) AFTER userlist_backcolor;[Enter] |

↓


A子
んじゃ、念のためキャッシュクリアを実行しておこう


C菜
public function changeColor()
{ if ($this->request->is('post')) { $sent_backcolor = $this->request->getData('sent_backcolor'); $sent_forecolor = $this->request->getData('sent_forecolor'); $received_backcolor = $this->request->getData('received_backcolor'); $received_forecolor = $this->request->getData('received_forecolor'); $userlist_backcolor = $this->request->getData('userlist_backcolor'); $userlist_forecolor = $this->request->getData('userlist_forecolor'); $user = $this->Users->get($this->identity->id, contain: []); $user->sent_backcolor = $sent_backcolor; $user->sent_forecolor = $sent_forecolor; $user->received_backcolor = $received_backcolor; $user->received_forecolor = $received_forecolor; $user->userlist_backcolor = $userlist_backcolor; $user->userlist_forecolor = $userlist_forecolor; if ($this->Users->save($user)) { $this->Flash->success(__('色設定を変更しました。')); return $this->redirect(['controller' => 'Top', 'action' => 'index']); } $this->Flash->error(__('色設定の変更に失敗しました。')); } } |
あと「templates/Users」の中に「change_color.php」を新規作成しますね~




A子
うーん、分かりづらい…
デフォルト値が全部「黒色」だし、凡例も無いし…


C菜
(凡例表示のためにも…)
えっと~
とりあえず修正が必要なのは~
①.「templates/layout」の中にある「default.php」
②.「webroot/css」の中にある「chat.css」 ③.「templates/Chat」の中にある「index.php」 |
ですかね~?

A子
<style>
:root { --sent-backcolor: <?= $identity->sent_backcolor ?>; --sent-forecolor: <?= $identity->sent_forecolor ?>; --received-backcolor: <?= $identity->received_backcolor ?>; --received-forecolor: <?= $identity->received_forecolor ?>; } </style> |

C菜
その項目には、最初はNULLが入ってますから~

A子
うーん、NULLなら定数の値で、NULLでなけりゃその値で…ってことにしたいよね

C菜
その準備を「AppController.php」の「beforeFilter」メソッドでやれば良いのではないでしょうか~?
(だって、「ChatController」でも「UsersController」でも使いますし…)

A子
$sent_backcolor = $this->identity->sent_backcolor == null ? SENT_COLOR : $this->identity->sent_backcolor; |
という記述を全部で6種類記述すれば良いんじゃない?

B美
A子が提示したように三項演算子を使っても良いんだけど、PHP7以降の新しい文法を使ってみても良いかもよ
$sent_backcolor = $this->identity->sent_backcolor ?? SENT_COLOR; |
という書き方なの
これって「??」の左側が未定義またはNULLだった場合、「??」の右側の値になるのよ

C菜
(効率的です~)
では、6種類を記述してみるです~
$sent_backcolor = $this->identity->sent_backcolor ?? SENT_COLOR;
$sent_forecolor = $this->identity->sent_forecolor ?? '#000000'; $received_backcolor = $this->identity->received_backcolor ?? RECEIVED_COLOR; $received_forecolor = $this->identity->received_forecolor ?? '#000000'; $userlist_backcolor = $this->identity->userlist_backcolor ?? USER_LIST_COLOR; $userlist_forecolor = $this->identity->userlist_forecolor ?? '#000000'; $this->set(compact( 'sent_backcolor', 'sent_forecolor', 'received_backcolor', 'received_forecolor', 'userlist_backcolor', 'userlist_forecolor' )); |
で、どうでしょうか~?
ちなみに、文字色のデフォルト値は黒('#000000')です~


A子
<style>
:root { --sent-backcolor: <?= $sent_backcolor ?>; --sent-forecolor: <?= $sent_forecolor ?>; --received-backcolor: <?= $received_backcolor ?>; --received-forecolor: <?= $received_forecolor ?>; } </style> |
あ、「$userlist_backcolor」と「$userlist_forecolor」については、「chat.css」内で使ってないから設定してないよ


C菜
.sent {
color: var(--sent-forecolor); background-color: var(--sent-backcolor); align-self: flex-end; text-align: right; } .received { color: var(--received-forecolor); background-color: var(--received-backcolor); align-self: flex-start; text-align: left; } .sent::after { content: ""; position: absolute; right: -8px; top: 50%; transform: translateY(-50%); width: 0; height: 0; border-style: solid; border-width: 8px 0 8px 10px; border-color: transparent transparent transparent var(--sent-backcolor); } .received::after { content: ""; position: absolute; left: -8px; top: 50%; transform: translateY(-50%); width: 0; height: 0; border-style: solid; border-width: 8px 10px 8px 0; border-color: transparent var(--received-backcolor) transparent transparent; } |



A子


C菜

A子
うん、デフォルトの色になってるみたいで、特に問題ないかな


C菜
色のデフォルト値設定と16進数表記も追加して、JavaScriptで凡例がリアルタイムに更新されるようにしてみました~
(ポイントはCSS変数の値を書き換えていることです~)






A子
うーん
さすがはC菜、一発で成功だよ


A子
ちょっと待って…
「更新」をクリックしたあと、あらためてもう一度同じ画面(チャット画面の背景色や文字色の変更)を表示してみたんだけど、何にも変わってないよ(汗)


B美
そうね
一度「ログアウト」してから、再度「ログイン」してみなさい

A子
あ、ばっちり更新されてるじゃん


C菜

B美
「UsersController.php」の「changeColor」メソッドに以下の一文を追加してみなさい
(これにより「セッション情報の再設定」を行うの)
$this->Authentication->setIdentity($user); |
記述する箇所は「save」が成功したあとね


A子
今度は(再ログインすることなく)即座に更新されたよ
(完璧じゃん!)

C菜
Ver.1.1.0でどうでしょうか~?

A子
最後に「const.php」の全体像を示しておこうか





B美
なかなかのものね
あ、「FROM_ADDRESS」についても開発環境と本番環境で切り分けたのは良いと思うわよ
(受信側メールサーバがSPFレコードを確認する場合、プロバイダのメールアドレスで送信しないとメールが届かないからね)

A子
(宛先のアドレスがGmailだと届かないなぁ…って)

C菜


A子
なんだか性格が出てる気がするよ(苦笑)