Rev 51 | Rev 57 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 51 | Rev 52 | ||
---|---|---|---|
1 | <?php
|
1 | <?php
|
2 | 2 | ||
3 | namespace PointedEars\PHPX; |
3 | namespace PointedEars\PHPX; |
4 | 4 | ||
- | 5 | function autoload ($class) |
|
- | 6 | {
|
|
- | 7 | if (\strpos($class, '..')) |
|
- | 8 | {
|
|
5 | require_once __DIR__ . '/AbstractModel.php'; |
9 | throw new \InvalidArgumentException( |
- | 10 | 'Refusing to load unsafe class ' . $class); |
|
- | 11 | }
|
|
- | 12 | ||
6 | require_once __DIR__ . '/Registry.php'; |
13 | require_once \preg_replace('#\\\#', '/', |
- | 14 | \preg_replace('#^' . \preg_quote(__NAMESPACE__) .'#', __DIR__, $class) |
|
- | 15 | ) . '.php'; |
|
- | 16 | }
|
|
- | 17 | ||
- | 18 | \spl_autoload_register(__NAMESPACE__ . '\\autoload'); |
|
7 | 19 | ||
8 | /**
|
20 | /**
|
9 | * Basic application class
|
21 | * Basic application class
|
10 | *
|
22 | *
|
11 | * @author Thomas Lahn
|
23 | * @author Thomas Lahn
|
12 | */
|
24 | */
|
13 | class Application
|
25 | class Application
|
14 | {
|
26 | {
|
15 | /**
|
27 | /**
|
16 | * Relative path to the controllers directory
|
28 | * Relative path to the controllers directory
|
17 | * @var string
|
29 | * @var string
|
18 | */
|
30 | */
|
19 | protected $_controllerPath = 'application/controllers'; |
31 | protected $_controllerPath = 'application/controllers'; |
20 | 32 | ||
21 | /**
|
33 | /**
|
22 | * Default controller of the application
|
34 | * Default controller of the application
|
23 | * @var string
|
35 | * @var string
|
24 | */
|
36 | */
|
25 | protected $_defaultController = 'Index'; |
37 | protected $_defaultController = 'Index'; |
26 | 38 | ||
27 | /**
|
39 | /**
|
28 | * Registry key for the default database of the application
|
40 | * Registry key for the default database of the application
|
29 | * @var string
|
41 | * @var string
|
30 | */
|
42 | */
|
31 | protected $_defaultDatabase; |
43 | protected $_defaultDatabase; |
32 | 44 | ||
33 | /**
|
45 | /**
|
34 | * Currently active controller of this application
|
46 | * Currently active controller of this application
|
35 | * @var Controller
|
47 | * @var Controller
|
36 | */
|
48 | */
|
37 | protected $_currentController; |
49 | protected $_currentController; |
38 | 50 | ||
39 | /**
|
51 | /**
|
40 | * Singleton
|
52 | * Singleton
|
41 | *
|
53 | *
|
42 | * @var Application
|
54 | * @var Application
|
43 | */
|
55 | */
|
44 | private static $_instance; |
56 | private static $_instance; |
45 | 57 | ||
46 | protected function __construct() |
58 | protected function __construct () |
47 | {
|
59 | {
|
48 | /* Singleton pattern */
|
60 | /* Singleton pattern */
|
49 | }
|
61 | }
|
50 | 62 | ||
51 | /**
|
63 | /**
|
52 | * Gets a reference to the <code>Application</code> instance
|
64 | * Gets a reference to the <code>Application</code> instance
|
53 | *
|
65 | *
|
54 | * @param Application $instance
|
66 | * @param Application $instance
|
55 | * The instance to be used as application. The default is a new
|
67 | * The instance to be used as application. The default is a new
|
56 | * application. This parameter is ignored if the application was
|
68 | * application. This parameter is ignored if the application was
|
57 | * already initialized.
|
69 | * already initialized.
|
58 | * @return Application
|
70 | * @return Application
|
59 | */
|
71 | */
|
60 | public static function getInstance(Application $instance = null) |
72 | public static function getInstance (Application $instance = null) |
61 | {
|
73 | {
|
62 | if (self::$_instance === null) |
74 | if (self::$_instance === null) |
63 | {
|
75 | {
|
64 | self::$_instance = ($instance === null) ? new self() : $instance; |
76 | self::$_instance = ($instance === null) ? new self() : $instance; |
65 | }
|
77 | }
|
66 | 78 | ||
67 | return self::$_instance; |
79 | return self::$_instance; |
68 | }
|
80 | }
|
69 | 81 | ||
70 | /**
|
82 | /**
|
71 | * Getter for properties
|
83 | * Getter for properties
|
72 | *
|
84 | *
|
73 | * @param string $name
|
85 | * @param string $name
|
74 | * @throws ModelPropertyException
|
86 | * @throws ModelPropertyException
|
75 | * @return mixed
|
87 | * @return mixed
|
76 | */
|
88 | */
|
77 | public function __get($name) |
89 | public function __get ($name) |
78 | {
|
90 | {
|
79 | /* Support for Object-Relational Mappers */
|
91 | /* Support for Object-Relational Mappers */
|
80 | if (strpos($name, 'persistent') === 0) |
92 | if (\strpos($name, 'persistent') === 0) |
81 | {
|
93 | {
|
82 | $class = get_class($this); |
94 | $class = \get_class($this); |
83 | return $class::${$name}; |
95 | return $class::${$name}; |
84 | }
|
96 | }
|
85 | 97 | ||
86 | $method = 'get' . ucfirst($name); |
98 | $method = 'get' . \ucfirst($name); |
87 | 99 | ||
88 | if (method_exists($this, $method)) |
100 | if (\method_exists($this, $method)) |
89 | {
|
101 | {
|
90 | return $this->$method(); |
102 | return $this->$method(); |
91 | }
|
103 | }
|
92 | 104 | ||
93 | if (property_exists($this, "_$name")) |
105 | if (\property_exists($this, "_$name")) |
94 | {
|
106 | {
|
95 | return $this->{"_$name"}; |
107 | return $this->{"_$name"}; |
96 | }
|
108 | }
|
97 | 109 | ||
98 | return $this->$name; |
110 | return $this->$name; |
99 | }
|
111 | }
|
100 | 112 | ||
101 | /**
|
113 | /**
|
102 | * Setter for properties
|
114 | * Setter for properties
|
103 | *
|
115 | *
|
104 | * @param string $name
|
116 | * @param string $name
|
105 | * @param mixed $value The new property value before assignment
|
117 | * @param mixed $value The new property value before assignment
|
106 | * @throws ModelPropertyException
|
118 | * @throws ModelPropertyException
|
107 | */
|
119 | */
|
108 | public function __set($name, $value) |
120 | public function __set ($name, $value) |
109 | {
|
121 | {
|
110 | $method = 'set' . ucfirst($name); |
122 | $method = 'set' . \ucfirst($name); |
111 | 123 | ||
112 | if (method_exists($this, $method)) |
124 | if (\method_exists($this, $method)) |
113 | {
|
125 | {
|
114 | return $this->$method($value); |
126 | return $this->$method($value); |
115 | }
|
127 | }
|
116 | 128 | ||
117 | if (property_exists($this, "_$name")) |
129 | if (\property_exists($this, "_$name")) |
118 | {
|
130 | {
|
119 | $this->{"_$name"} = $value; |
131 | $this->{"_$name"} = $value; |
120 | return $this->{"_$name"}; |
132 | return $this->{"_$name"}; |
121 | }
|
133 | }
|
122 | 134 | ||
123 | /* NOTE: Attempts to set other properties are _silently_ _ignored_ */
|
135 | /* NOTE: Attempts to set other properties are _silently_ _ignored_ */
|
124 | }
|
136 | }
|
125 | 137 | ||
126 | /**
|
138 | /**
|
127 | * Runs the application, setting up session management and
|
139 | * Runs the application, setting up session management and
|
128 | * constructing the controller indicated by the URI
|
140 | * constructing the controller indicated by the URI
|
129 | */
|
141 | */
|
130 | public function run() |
142 | public function run () |
131 | {
|
143 | {
|
132 | $this->startSession(); |
144 | $this->startSession(); |
133 | 145 | ||
134 | $controller = self::getParam('controller', $_REQUEST); |
146 | $controller = self::getParam('controller', $_REQUEST); |
135 | if (!$controller) |
147 | if (!$controller) |
136 | {
|
148 | {
|
137 | $controller = $this->_defaultController; |
149 | $controller = $this->_defaultController; |
138 | }
|
150 | }
|
139 | 151 | ||
140 | $controller = ucfirst($controller); |
152 | $controller = \ucfirst($controller); |
141 | 153 | ||
142 | $controller = $controller . 'Controller'; |
154 | $controller = $controller . 'Controller'; |
143 | require_once "{$this->_controllerPath}/{$controller}.php"; |
155 | require_once "{$this->_controllerPath}/{$controller}.php"; |
144 | $this->_currentController = new $controller(); |
156 | $this->_currentController = new $controller(); |
145 | 157 | ||
146 | return $this; |
158 | return $this; |
147 | }
|
159 | }
|
148 | 160 | ||
149 | protected function startSession() |
161 | protected function startSession () |
150 | {
|
162 | {
|
151 | session_start(); |
163 | \session_start(); |
152 | }
|
164 | }
|
153 | 165 | ||
154 | /**
|
166 | /**
|
155 | * Gets a request parameter
|
167 | * Gets a request parameter
|
156 | *
|
168 | *
|
157 | * @param string $key
|
169 | * @param string $key
|
158 | * Key to look up in the array
|
170 | * Key to look up in the array
|
159 | * @param array $array
|
171 | * @param array $array
|
160 | * Array where to look up <var>$key</var>.
|
172 | * Array where to look up <var>$key</var>.
|
161 | * The default is <code>$_GET</code>.
|
173 | * The default is <code>$_GET</code>.
|
162 | * @return mixed
|
174 | * @return mixed
|
163 | * <code>null</code> if there is no such <var>$key</var>
|
175 | * <code>null</code> if there is no such <var>$key</var>
|
164 | * in <var>$array</var>
|
176 | * in <var>$array</var>
|
165 | */
|
177 | */
|
166 | public static function getParam($key, array $array = null) |
178 | public static function getParam ($key, array $array = null) |
167 | {
|
179 | {
|
168 | if ($array === null) |
180 | if ($array === null) |
169 | {
|
181 | {
|
170 | $array = $_GET; |
182 | $array = $_GET; |
171 | }
|
183 | }
|
172 | 184 | ||
173 | return isset($array[$key]) ? $array[$key] : null; |
185 | return isset($array[$key]) ? $array[$key] : null; |
174 | }
|
186 | }
|
175 | 187 | ||
176 | /**
|
188 | /**
|
177 | * Registers a database
|
189 | * Registers a database
|
178 | *
|
190 | *
|
179 | * @param string $key
|
191 | * @param string $key
|
180 | * @param Database $database
|
192 | * @param Database $database
|
181 | * @return string Registry key
|
193 | * @return string Registry key
|
182 | * @see Application::setDefaultDatabase()
|
194 | * @see Application::setDefaultDatabase()
|
183 | */
|
195 | */
|
184 | public function registerDatabase ($key, Db\Database $database) |
196 | public function registerDatabase ($key, Db\Database $database) |
185 | {
|
197 | {
|
186 | Registry::set($key, $database); |
198 | Registry::set($key, $database); |
187 | return $key; |
199 | return $key; |
188 | }
|
200 | }
|
189 | 201 | ||
190 | /**
|
202 | /**
|
191 | * Sets the default database
|
203 | * Sets the default database
|
192 | * @param string Registry key to refer to the {@link Database}
|
204 | * @param string Registry key to refer to the {@link Database}
|
193 | */
|
205 | */
|
194 | public function setDefaultDatabase ($key) |
206 | public function setDefaultDatabase ($key) |
195 | {
|
207 | {
|
196 | $this->_defaultDatabase = $key; |
208 | $this->_defaultDatabase = $key; |
197 | }
|
209 | }
|
198 | 210 | ||
199 | /**
|
211 | /**
|
200 | * Sets the current controller for this application
|
212 | * Sets the current controller for this application
|
201 | *
|
213 | *
|
202 | * @param Controller $controller
|
214 | * @param Controller $controller
|
203 | * @return Application
|
215 | * @return Application
|
204 | */
|
216 | */
|
205 | public function setCurrentController(Controller $controller) |
217 | public function setCurrentController (Controller $controller) |
206 | {
|
218 | {
|
207 | $this->_currentController = $controller; |
219 | $this->_currentController = $controller; |
208 | return $this; |
220 | return $this; |
209 | }
|
221 | }
|
210 | 222 | ||
211 | /**
|
223 | /**
|
212 | * Returns the current controller for this application
|
224 | * Returns the current controller for this application
|
213 | *
|
225 | *
|
214 | * @return Controller
|
226 | * @return Controller
|
215 | */
|
227 | */
|
216 | public function getCurrentController() |
228 | public function getCurrentController () |
217 | {
|
229 | {
|
218 | return $this->_currentController; |
230 | return $this->_currentController; |
219 | }
|
231 | }
|
220 | 232 | ||
221 | /**
|
233 | /**
|
222 | * Returns the default database for this application
|
234 | * Returns the default database for this application
|
223 | *
|
235 | *
|
224 | * @return Database
|
236 | * @return Database
|
225 | */
|
237 | */
|
226 | public function getDefaultDatabase() |
238 | public function getDefaultDatabase () |
227 | {
|
239 | {
|
228 | return Registry::get($this->_defaultDatabase); |
240 | return Registry::get($this->_defaultDatabase); |
229 | }
|
241 | }
|
230 | 242 | ||
231 | /**
|
243 | /**
|
232 | * Returns a relative URI-reference for an action of the
|
244 | * Returns a relative URI-reference for an action of the
|
233 | * application
|
245 | * application
|
234 | *
|
246 | *
|
235 | * @param string[optional] $controller
|
247 | * @param string[optional] $controller
|
236 | * @param string[optional] $action
|
248 | * @param string[optional] $action
|
237 | * @param int[optional] $id
|
249 | * @param int[optional] $id
|
238 | */
|
250 | */
|
239 | public function getURL($controller = null, $action = null, $id = null) |
251 | public function getURL ($controller = null, $action = null, $id = null) |
240 | {
|
252 | {
|
241 | /* Apache module */
|
253 | /* Apache module */
|
242 | $url = self::getParam('SCRIPT_URL', $_SERVER); |
254 | $url = self::getParam('SCRIPT_URL', $_SERVER); |
243 | if ($url === null) |
255 | if ($url === null) |
244 | {
|
256 | {
|
245 | /* FastCGI */
|
257 | /* FastCGI */
|
246 | $url = self::getParam('URL', $_SERVER); |
258 | $url = self::getParam('URL', $_SERVER); |
247 | if ($url === null) |
259 | if ($url === null) |
248 | {
|
260 | {
|
249 | /* Server/PHP too old, compute URI */
|
261 | /* Server/PHP too old, compute URI */
|
250 | $url = self::getParam('REQUEST_URI', $_SERVER); |
262 | $url = self::getParam('REQUEST_URI', $_SERVER); |
251 | if (preg_match('/^[^?]+/', $url, $matches) > 0) |
263 | if (\preg_match('/^[^?]+/', $url, $matches) > 0) |
252 | {
|
264 | {
|
253 | $url = $matches[0]; |
265 | $url = $matches[0]; |
254 | }
|
266 | }
|
255 | else
|
267 | else
|
256 | {
|
268 | {
|
257 | /* Has .php in it, but at least it works */
|
269 | /* Has .php in it, but at least it works */
|
258 | $url = self::getParam('SCRIPT_NAME', $_SERVER); |
270 | $url = self::getParam('SCRIPT_NAME', $_SERVER); |
259 | if ($url === null) |
271 | if ($url === null) |
260 | {
|
272 | {
|
261 | throw new Exception( |
273 | throw new \Exception( |
262 | 'None of $_SERVER["SCRIPT_URL"], $_SERVER["URL"],'
|
274 | 'None of $_SERVER["SCRIPT_URL"], $_SERVER["URL"],'
|
263 | . ' $_SERVER["REQUEST_URI"], or $_SERVER["SCRIPT_NAME"]' |
275 | . ' $_SERVER["REQUEST_URI"], or $_SERVER["SCRIPT_NAME"]' |
264 | . ' is available, cannot continue.'); |
276 | . ' is available, cannot continue.'); |
265 | }
|
277 | }
|
266 | }
|
278 | }
|
267 | }
|
279 | }
|
268 | }
|
280 | }
|
269 | 281 | ||
270 | $query = (($controller !== null) ? 'controller=' . $controller : '') |
282 | $query = (($controller !== null) ? 'controller=' . $controller : '') |
271 | . (($action !== null) ? '&action=' . $action : '') |
283 | . (($action !== null) ? '&action=' . $action : '') |
272 | . (($id !== null) ? '&id=' . $id : ''); |
284 | . (($id !== null) ? '&id=' . $id : ''); |
273 | 285 | ||
274 | return $url . ($query ? '?' . $query : ''); |
286 | return $url . ($query ? '?' . $query : ''); |
275 | }
|
287 | }
|
276 | 288 | ||
277 | /**
|
289 | /**
|
278 | * Performs a server-side redirect within the application
|
290 | * Performs a server-side redirect within the application
|
279 | */
|
291 | */
|
280 | public static function redirect($query = '') |
292 | public static function redirect ($query = '') |
281 | {
|
293 | {
|
282 | $script_uri = self::getParam('SCRIPT_URI', $_SERVER); |
294 | $script_uri = self::getParam('SCRIPT_URI', $_SERVER); |
283 | if ($script_uri === null) |
295 | if ($script_uri === null) |
284 | {
|
296 | {
|
285 | /* Server/PHP too old, compute URI */
|
297 | /* Server/PHP too old, compute URI */
|
286 | if (preg_match('/^[^?]+/', |
298 | if (\preg_match('/^[^?]+/', |
287 | self::getParam('REQUEST_URI', $_SERVER), $matches) > 0) |
299 | self::getParam('REQUEST_URI', $_SERVER), $matches) > 0) |
288 | {
|
300 | {
|
289 | $query_prefix = $matches[0]; |
301 | $query_prefix = $matches[0]; |
290 | }
|
302 | }
|
291 | else
|
303 | else
|
292 | {
|
304 | {
|
293 | /* Has .php in it, but at least it works */
|
305 | /* Has .php in it, but at least it works */
|
294 | $query_prefix = self::getParam('SCRIPT_NAME', $_SERVER); |
306 | $query_prefix = self::getParam('SCRIPT_NAME', $_SERVER); |
295 | }
|
307 | }
|
296 | 308 | ||
297 | /* TODO: Let user decide which ports map to which URI scheme */
|
309 | /* TODO: Let user decide which ports map to which URI scheme */
|
298 | $script_uri = (self::getParam('SERVER_PORT', $_SERVER) == 443 |
310 | $script_uri = (self::getParam('SERVER_PORT', $_SERVER) == 443 |
299 | ? 'https://'
|
311 | ? 'https://'
|
300 | : 'http://') |
312 | : 'http://') |
301 | . self::getParam('HTTP_HOST', $_SERVER) |
313 | . self::getParam('HTTP_HOST', $_SERVER) |
302 | . $query_prefix; |
314 | . $query_prefix; |
303 | }
|
315 | }
|
304 | 316 | ||
305 | header('Location: ' . $script_uri |
317 | \header('Location: ' . $script_uri |
306 | . ($query ? (substr($query, 0, 1) === '?' ? '' : '?') . $query : '')); |
318 | . ($query ? (substr($query, 0, 1) === '?' ? '' : '?') . $query : '')); |
307 | }
|
319 | }
|
308 | }
|
320 | }
|
309 | 321 |