CakeEventManagerについて、ソースコードを読んで分かった事を、それでも全部を読み切ってはないので、予想も含めつつまとめます。
CakeEventManagerは、アプリケーション全体のイベントを管理する、グローバルマネージャーとしてシングルトン風に生成される。同時に、互いに干渉しない、ローカルマネージャーの生成も行える。 CakePHPのコードをgrepした所、Model, View, Controller, Dispatcherがそれぞれローカルマネージャーを持っていて、互いに干渉しない作りとなっている。ただし、グローバルマネージャーは、どのローカルマネージャーがdispatch()しても、必ずイベントを発火させる。
public static function instance($manager = null) {
if ($manager instanceof CakeEventManager) {
self::$_generalManager = $manager;
}
if (empty(self::$_generalManager)) {
self::$_generalManager = new CakeEventManager;
}
self::$_generalManager->_isGlobal = true;
return self::$_generalManager;
}
https://github.com/cakephp/cakephp/blob/2.2.4/lib/Cake/Event/CakeEventManager.php#L70
CakeEventManager::instance();で生成すると_isGlobal = true
でグローバルマネージャーとして生成される。
public function getEventManager() {
if (empty($this->_eventManager)) {
$this->_eventManager = new CakeEventManager();
$this->_eventManager->attach($this->Behaviors);
$this->_eventManager->attach($this);
}
return $this->_eventManager;
}
https://github.com/cakephp/cakephp/blob/2.2.4/lib/Cake/Model/Model.php#L766
public function getEventManager() {
if (empty($this->_eventManager)) {
$this->_eventManager = new CakeEventManager();
}
if (!$this->_eventManagerConfigured) {
$this->_eventManager->attach($this->Helpers);
$this->_eventManagerConfigured = true;
}
return $this->_eventManager;
}
https://github.com/cakephp/cakephp/blob/2.2.4/lib/Cake/View/View.php#L339
public function getEventManager() {
if (empty($this->_eventManager)) {
$this->_eventManager = new CakeEventManager();
$this->_eventManager->attach($this->Components);
$this->_eventManager->attach($this);
}
return $this->_eventManager;
}
https://github.com/cakephp/cakephp/blob/2.2.4/lib/Cake/Controller/Controller.php#L649
public function getEventManager() {
if (!$this->_eventManager) {
$this->_eventManager = new CakeEventManager();
$this->_eventManager->attach($this);
$this->_attachFilters($this->_eventManager);
}
return $this->_eventManager;
}
https://github.com/cakephp/cakephp/blob/2.2.4/lib/Cake/Routing/Dispatcher.php#L67
Model, View, Controller, Dispatcherの少なくとも4クラスで、new CakeEventManager()
している。newすると、CakeEventManagerにコンストラクタは無いので、_isGlobal = true
にならないので、そういう名前が付いてるか分からないけど、ローカルマネージャーとなる。
public function dispatch($event) {
if (is_string($event)) {
$event = new CakeEvent($event);
}
if (!$this->_isGlobal) {
self::instance()->dispatch($event);
}
//snipped actual dispatching code.
https://github.com/cakephp/cakephp/blob/2.2.4/lib/Cake/Event/CakeEventManager.php#L226
CakeEventManager->dispatch()
で、指定したイベントが発火していくけど、ローカルマネージャーだった場合は、グローバルマネージャも発火する。見ての通り、ローカルマネージャーよりもグローバルマネージャーが先に処理されます。