summaryrefslogtreecommitdiff
path: root/lib/Minz/Dispatcher.php
blob: f62a9291136ca59628739dd60940a91807b416cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php
/** 
 * MINZ - Copyright 2011 Marien Fressinaud
 * Sous licence AGPL3 <http://www.gnu.org/licenses/>
*/

/**
 * Le Dispatcher s'occupe d'initialiser le Controller et d'executer l'action
 * déterminée dans la Request
 * C'est un singleton
 */
class Minz_Dispatcher {
	const CONTROLLERS_PATH_NAME = '/Controllers';

	/* singleton */
	private static $instance = null;
	private static $needsReset;

	private $controller;

	/**
	 * Récupère l'instance du Dispatcher
	 */
	public static function getInstance () {
		if (self::$instance === null) {
			self::$instance = new Minz_Dispatcher ();
		}
		return self::$instance;
	}

	/**
	 * Lance le controller indiqué dans Request
	 * Remplit le body de Response à partir de la Vue
	 * @exception Minz_Exception
	 */
	public function run () {
		do {
			self::$needsReset = false;

			try {
				$this->createController ('FreshRSS_' . Minz_Request::controllerName () . '_Controller');
				$this->controller->init ();
				$this->controller->firstAction ();
				if (!self::$needsReset) {
					$this->launchAction (
						Minz_Request::actionName ()
						. 'Action'
					);
				}
				$this->controller->lastAction ();

				if (!self::$needsReset) {
					$this->controller->view ()->build ();
				}
			} catch (Minz_Exception $e) {
				throw $e;
			}
		} while (self::$needsReset);
	}

	/**
	 * Informe le contrôleur qu'il doit recommancer car la requête a été modifiée
	 */
	public static function reset() {
		self::$needsReset = true;
	}

	/**
	 * Instancie le Controller
	 * @param $controller_name le nom du controller à instancier
	 * @exception ControllerNotExistException le controller n'existe pas
	 * @exception ControllerNotActionControllerException controller n'est
	 *          > pas une instance de ActionController
	 */
	private function createController ($controller_name) {
		$filename = APP_PATH . self::CONTROLLERS_PATH_NAME . '/'
		          . $controller_name . '.php';

		if (!class_exists ($controller_name)) {
			throw new Minz_ControllerNotExistException (
				$controller_name,
				Minz_Exception::ERROR
			);
		}
		$this->controller = new $controller_name ();

		if (! ($this->controller instanceof Minz_ActionController)) {
			throw new Minz_ControllerNotActionControllerException (
				$controller_name,
				Minz_Exception::ERROR
			);
		}
	}

	/**
	 * Lance l'action sur le controller du dispatcher
	 * @param $action_name le nom de l'action
	 * @exception ActionException si on ne peut pas exécuter l'action sur
	 *  le controller
	 */
	private function launchAction ($action_name) {
		if (!is_callable (array (
			$this->controller,
			$action_name
		))) {
			throw new Minz_ActionException (
				get_class ($this->controller),
				$action_name,
				Minz_Exception::ERROR
			);
		}
		call_user_func (array (
			$this->controller,
			$action_name
		));
	}
}