ユアマイスター株式会社エンジニアブログ

ユアマイスター株式会社のエンジニアが日々徒然。

CakePHPで画面上で同じ処理を行いたいときのコントローラーのいじり方

こんばんは、エンジニアインターン二等兵の竹本です。
僕はエンジニアを始めて数日の身なので、初心者目線の解釈でブログを書いていきたいと思います。 突然ですがみなさん、lineの画面を思い出して見てください。

http://my-closet.jp/wp-content/uploads/2012/11/data-200x300.jpg

友達リストのページでも、メッセージの通知が分かりやすいようにトークの上に赤い通知マークがあるのが分かりますよね。 今回僕はこのようなトークの画面にいない時にも通知のアイコンを出す処理を、コントローラで一括処理するには??という題材で書いていきたいと思います。

そもそもコントローラって?

弊社で扱っているフレームワークMVC型のCakePHPです。
MVC型のフレームワークとは

M(Model)
V(View)
C(Controller)

という大きく三つの役割に分担します。
Modelとはデータベースからデータを操作するクラスのことで、Viewは画面に出てくる(HTML部分)、ControllerはModelとViewの橋渡しというイメージですね。三者がどのようにつながっていくかを具体的に言えば、
①ユーザがUI上でなんらかのリクエストをサーバーに送る
②コントローラーはそのリクエストの処理を管理する=Modelに処理内容を送信
③Modelコントローラーから受け取ったデータをもとに、データベースにアクセスし更新や削除をする
④Modelは処理の結果をコントローラーに返し、処理内容をViewに渡す
⑤コントローラーから受け取った情報を得て、テンプレートを解釈し、データをUIに埋め込んだりする

複数のViewでトークの通知アイコンを表示させる

本題に戻ってきました。
分かりやすく今回は1Viewに対して1Controller、1Modelという風な感じで成り立っているとしましょう。
画面は「友達リスト」「トーク」「マイページ」のような三つの画面があるとし、トークViewからはトークController、トークModelにしかアクセスできないと設定します。
まず通知が来た時にデータベースに「通知が来たよ!」って知らせるのは「トーク」のコントローラーなのは想像つくと思います。そしてトークcontrollerからトークmodelへと通知の内容を更新して、それをviewに戻して通知のアイコンが点灯します。

しかし、この過程からだと「友達リスト」「マイページ」にいくと通知のアイコンが点灯しません。「トーク」開いてないと通知がわからないなんてアプリ嫌ですよね笑

三つのページの親コントローラーで処理を行う

「友達リスト」「トーク」「マイページ」のコントローラーの親クラスAppControllerで通知アイコンが表示するという処理を書いて、そこの部分だけをトークのデータベースにつなぐようにすれば、子である「友達リスト」「マイページ」のコントローラーでも親のコントローラーの処理をもらってViewに表示することができます!
それを行うためには親・子を結ぶ処理をしなければなりません。
そこで扱うのがbeforeFilterです。このメソッドは要するに【子画面が表示される時に必ず実行】するメソッドです。

class AppController extends Controller
{
  public function beforeFilter(Event $event) {
        ※1
    }
     private function unreadOrdersMessagesCount(){
        // DBから未読のメッセージを取得する処理
    }
これをまず親コントローラー(AppController.php)で定義して、beforeFilterの※1に入れ込む
    public function beforeFilter(Event $event) {
        $this->set('auth',$this->Auth);
        $this->unreadOrdersMessagesCount();
    }

親コントローラーで定義したら子供でもbeforeFilterを定義

class XxxxxController extends AppController {
    public function beforeFilter(Event $event){
        parent::beforeFilter($event);
    }
}

コントローラーで定義したらあとはViewファイルで表示させるだけ

        <div class=“talk”>
            <?php if (empty($countMessages)) : ?>
            <a href="<?= $this->Url->build(['controller'=>’Messages', 'action'=>'index']); ?>" class="-reduce">トーク</a>
            <?php else: ?>
            <a href="<?= $this->Url->build(['controller'=>'Messages', 'action'=>'index']); ?>" class="-reduce">トーク<span class="badge"><?= $countMessages ?></span></a>
            <?php endif; ?>
        </div>

上の処理は$countMessagesに何も入ってなかったら通知アイコンを出さない。
<?php else: ?>以下で通知アイコン($countMessages )を表示してって指令してます。

「友達リスト」「マイページ」から手間かけて「トーク」のデータベースにつなげるより、親のコントローラーで一括で処理してくれた方が簡単ですよね。
以上今週の竹本でした!