質問するログイン新規登録

回答編集履歴

2

一部追記

2017/05/17 03:07

投稿

coba-coba
coba-coba

スコア1409

answer CHANGED
@@ -68,6 +68,7 @@
68
68
  それと、```save()```はコントローラーだけではなく、config/bootstrap.phpでもできます。どこかで```$this->eventManager()->dispatch($event);```を実行した段階で、bootstrap.phpに書いたコードがイベントのdispatchを検知して、指定したリスナー名に該当した場合に処理を行うことができます。そこでは```save()```もできます。
69
69
 
70
70
  例えば以下のように設定すると、Model.Hoge.exampleにイベントが伝わったことを検知して、function()内の処理を行います。
71
+ なお、Model.Hoge.exampleをModel.beforeSaveにすると、コントローラーに```public function beforeSave(Event $event , $entity , $options) {}```を記述しなくてもbeforeSaveを使うことができます。
71
72
 
72
73
  ```PHP
73
74
  // bootstrap.php

1

コメントに対するコメント

2017/05/17 03:07

投稿

coba-coba
coba-coba

スコア1409

answer CHANGED
@@ -44,4 +44,43 @@
44
44
  - 渡す値によって異なるログファイルにログを書き込む
45
45
  - 渡す値によって異なる相手にメールを送る
46
46
  - 渡す値によって異なるキャッシュファイルに書き込む
47
- - 渡す値によってイベントを中止する
47
+ - 渡す値によってイベントを中止する
48
+
49
+ コメントに対するコメント
50
+ ---
51
+ > $this->eventManager()->dispatch($event);の部分が気になるのですが、これはEventManager.phpに$eventを通知して、atachされているeventに対して、適用するという動きでいいんでしょうか。
52
+
53
+ そうですね。新しいイベントを事前に紐づけていたリスナーに伝え、そのリスナーのメソッドを実行させるということですね。
54
+ 具体的には、EventManager.phpのdispatchメソッドに$eventを渡し、そこでリスナーのメソッドに$eventを渡してそのメソッドを実行するという流れです。
55
+
56
+
57
+ > createNotificationAfterCheckはpublic function createNotificationAfterCheck(Event $event , $entity , $options) {}を書かないと呼ばれないと思うのですが、beforeSaveだと「呼ばれるのはsave前だな」とフックされるタイミングが直感的にわかるのですが、独自イベントだとそのタイミングってどこで設定するんでしょうか。結局、コントローラからTableを呼ぶだけみたいになってしまうんでしょうか。
58
+
59
+ やはりイベントが発生したことをどこかで伝える必要があるので、```$this->eventManager()->dispatch($event);```は必要になるのではないでしょうか。ウェブサイト表示のリクエストを受けてからデータを返すまでの流れ以外については、CakePHPではタイミングを判断しようがありません。
60
+
61
+ しかし、独自にイベントを作成した場合、そのイベントの中で処理する内容に対して独自に優先順位をつけることはできます。具体的には、```$this->eventManager()->on()```で```['priority' => 数値]```(デフォルトは10)を設定する方法です(バージョンによってはattach())。```$this->eventManager()->on()```で同じリスナーを複数加えられるので、それらの優先順位を設定すれば、タイミングを好きに設定できます。例えば、①```save()```の前に行う処理、②```save()```、③```save()```の後に行う処理、のように分ければbeforeSaveやafterSaveができます。
62
+
63
+
64
+ > あと設計スタイルの話になりますが、呼び出すには当然、public function beforeSave(Event $event , $entity , $options) {}の記述が必要かと思いますが、それってsaveの処理を対応するコントローラに書かないといけないので、コントローラから新たにサブコントローラを呼んでみたいな細分化された設計ってできないのかなぁとちょっと思いました。
65
+
66
+ すみません、なんとなくしかやりたいことが分からないのですが、管理が面倒になるだけでサブコントローラー(サブクラス)を作ってもかまわないと思います。
67
+
68
+ それと、```save()```はコントローラーだけではなく、config/bootstrap.phpでもできます。どこかで```$this->eventManager()->dispatch($event);```を実行した段階で、bootstrap.phpに書いたコードがイベントのdispatchを検知して、指定したリスナー名に該当した場合に処理を行うことができます。そこでは```save()```もできます。
69
+
70
+ 例えば以下のように設定すると、Model.Hoge.exampleにイベントが伝わったことを検知して、function()内の処理を行います。
71
+
72
+ ```PHP
73
+ // bootstrap.php
74
+ use Cake\ORM\TableRegistry;
75
+
76
+ $hoge = TableRegistry::get('Hoges');
77
+ $hoge
78
+ ->eventManager()
79
+ ->on('Model.Hoge.example', ['priority' => 15], function($event, $entity) use ($hoge)
80
+ {
81
+ // バージョンによって$event->data['hoge']の取得方法が異なる
82
+ if($hoge->save($event->data['hoge'])) {
83
+ debug('save()できた!');
84
+ }
85
+ });
86
+ ```