Skip to content

Instantly share code, notes, and snippets.

@kanonji
Created January 8, 2013 09:14
Show Gist options
  • Save kanonji/4482399 to your computer and use it in GitHub Desktop.
Save kanonji/4482399 to your computer and use it in GitHub Desktop.

CakeEventManager

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()で、指定したイベントが発火していくけど、ローカルマネージャーだった場合は、グローバルマネージャも発火する。見ての通り、ローカルマネージャーよりもグローバルマネージャーが先に処理されます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment