Posted at

CakePHP-Observerパターン使い方

More than 1 year has passed since last update.


Observerパターンとは

簡単に説明するとプログラム内のオブジェクトの状態を観察するようなプログラムで使われるDesignパターン。

以下のイメージのように、イベントを発生させる部分、そのイベントを観察してイベントに対して処理を行うリスナーで構成されます。

詳細は以下を参照してください。

https://ja.wikipedia.org/wiki/Observer_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3

今回はCakeEventを利用したObserverパターン実装してみます。

参考:

http://andy-carter.com/blog/events-in-cakephp-2-using-the-observer-pattern


以下のコードを見てみましょう。

ユーザー情報を保存して成功だったらメールを送るコードです。

if($this->User->save($this->data)) {

$this->Email->send('saved');
}

このコードを単純にControllerでロジックを実装して、EmailUtilityをつくって実装するコードですがこれを

Observerパターンで実装してみます。


①Raise Event : モデルにイベントを発生させるコードを追加します

App-Model-User.php


User.php


<?php
App::uses('AppModel', 'Model');
App::uses('CakeEvent', 'Event');

class User extends AppModel {

public function afterSave($created, $options = array()) {
parent::afterSave($created, $options);
if ($created === true) {
// アカウントが追加されるとEvent発生
$Event = new CakeEvent('Model.User.created', $this, array(
'title' => 'アカウント追加',       //メールタイトル設定
'content' => 'アカウントが追加されました。' //メール内容設定
));
$this->getEventManager()->dispatch($Event);
}
}
}



②イベントリスナー追加

app/Lib/UserListener.php追加


UserListener.php

<?php

App::uses('CakeEventListener', 'Event');
App::uses('CakeEmail', 'Network/Email');

class UserListener implements CakeEventListener {

public function implementedEvents() {
return array(
'Model.User.created' => 'sendConfirmationEmail',
);
}

public function sendConfirmationEmail(CakeEvent $Event) {
$email = new CakeEmail('gmail');  // gmail設定
$email->from( array( '送信メールアドレス' => 'Sender'));   // 送信元
$email->to( '相手のメールアドレス');  // 送信先
$email->subject( $Event->data['title']); // メールタイトル
$email->send($Event->data['content']);           // メール内容
return;
}
}



※gmailでメール送信したい場合、以下の設定が必要

app/Config/email.php


email.php

    public $gmail = array(

'host' => 'ssl://smtp.gmail.com',
'port' => 465,
'username' => 'gmailアカウント', // ユーザ名
'password' => 'パスワード', // パスワード
'transport' => 'Smtp',

);


これだとエラーが発生します。

「SMTP Error: 534 5.7.14 https://support.google.com/mail/bin/answer.py?answer=78754 ~~ - gsmtp」

gmail側の設定で、安全性の低いアプリがアカウントにアクセスするのを許可するという設定を有効にしないといけないです。

設定方法は以下

https://support.google.com/accounts/answer/6010255?hl=ja


③リスナー設定

app/Config/events.php追加


events.php

<?php

App::uses('CakeEventManager', 'Event');
App::uses('UserListener', 'Lib/Event');
CakeEventManager::instance()->attach(new UserListener());


④bootstrap.phpに以下の内容追加


bootstrap.php

require_once APP . 'Config' . DS . 'events.php';


これでユーザーを登録すると自動的に登録完了メールがgmailで送られます。