1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: namespace Pry\Controller;
14:
15: use Pry\Net\Request;
16:
17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
33: class Router
34: {
35:
36: 37: 38: 39: 40:
41: static private $instance;
42:
43: 44: 45: 46:
47: private $controller;
48:
49: 50: 51: 52:
53: private $action;
54:
55: 56: 57: 58:
59: private $params;
60:
61: 62: 63: 64:
65: private $rules;
66:
67: 68: 69: 70:
71: private $path;
72:
73: 74: 75: 76:
77: private $view;
78:
79: 80: 81: 82:
83: private $file;
84:
85: 86: 87: 88:
89: private $defaultController;
90:
91: 92: 93: 94:
95: private $defaultAction;
96:
97: 98: 99: 100:
101: private $errorController;
102:
103: 104: 105: 106:
107: private $errorAction;
108:
109: 110: 111: 112:
113: private $isMultiLangue = false;
114:
115: 116: 117: 118:
119: private $codeLangue = '';
120:
121: 122: 123: 124:
125: private $tradController;
126:
127: 128: 129: 130:
131: private $request;
132:
133: 134: 135: 136:
137: public static function getInstance()
138: {
139: if (!isset(self::$instance))
140: self::$instance = new Router();
141: return self::$instance;
142: }
143:
144: 145: 146: 147:
148: public function load()
149: {
150: $this->request = new Request();
151: $tmp = $this->request->url;
152:
153: $url = !empty($tmp) ? $tmp : '';
154: $tabUrl = explode('/', $url);
155: $isCustom = false;
156:
157:
158: $this->clear_empty_value($tabUrl);
159:
160: if (!empty($this->rules))
161: {
162: foreach ($this->rules as $key => $data) {
163: $params = $this->matchRules($key, $tabUrl);
164: if ($params)
165: {
166: $this->controller = $data['controller'];
167: $this->action = $data['action'];
168: $this->params = $params;
169: $isCustom = true;
170: break;
171: }
172: }
173: }
174:
175: if (!$isCustom)
176: $this->getRoute($tabUrl);
177:
178: $this->controller = (!empty($this->controller)) ? $this->controller : $this->defaultController;
179: $this->action = (!empty($this->action)) ? $this->action : $this->defaultAction;
180: $ctrlPath = str_replace('_', '/', $this->controller);
181: $this->file = realpath($this->path) . DIRECTORY_SEPARATOR . $ctrlPath . '.php';
182:
183:
184: $this->params['action'] = $this->action;
185: $this->params['controller'] = $this->controller;
186: $this->request->add($this->params);
187:
188:
189: if (!is_file($this->file))
190: {
191: header("Status: 404 Not Found");
192: $this->controller = $this->errorController;
193: $this->action = $this->errorAction;
194: $this->file = $this->path . $this->controller . '.php';
195: }
196:
197:
198: include $this->file;
199:
200: $class = $this->controller . 'Controller';
201:
202: if (!empty($this->codeLangue))
203: {
204: $controller = new $class($this->request, $this->codeLangue);
205: }
206: else
207: {
208: $controller = new $class($this->request);
209: }
210:
211: if (!empty($this->view))
212: $controller->setView($this->view);
213:
214: if (!is_callable(array($controller, $this->action)))
215: {
216: $action = $this->defaultAction;
217: }
218: else
219: {
220: $action = $this->action;
221: }
222:
223: $controller->$action();
224: }
225:
226: 227: 228: 229: 230: 231:
232: public function addRule($rule, $target)
233: {
234: if ($rule[0] != '/')
235: $rule = '/' . $rule;
236:
237: $this->rules[$rule] = $target;
238: }
239:
240: 241: 242: 243: 244: 245: 246:
247: public function matchRules($rule, $dataItems)
248: {
249: $ruleItems = explode('/', $rule);
250: $this->clear_empty_value($ruleItems);
251:
252: if (count($ruleItems) == count($dataItems))
253: {
254: $result = array();
255: foreach ($ruleItems as $rKey => $rValue) {
256: if ($rValue[0] == ':')
257: {
258: $rValue = substr($rValue, 1);
259: $result[$rValue] = $dataItems[$rKey];
260: }
261: else
262: {
263: if ($rValue != $dataItems[$rKey])
264: return false;
265: }
266: }
267: if (!empty($result))
268: return $result;
269:
270: unset($result);
271: }
272: return false;
273: }
274:
275: 276: 277: 278:
279: public function getAction()
280: {
281: return $this->action;
282: }
283:
284: 285: 286: 287:
288: public function getController()
289: {
290: return $this->controller;
291: }
292:
293: 294: 295: 296:
297: private function getRoute($url)
298: {
299: $items = $url;
300:
301: if (!empty($items))
302: {
303: if ($this->isMultiLangue)
304: $this->codeLangue = array_shift($items);
305:
306: $this->controller = array_shift($items);
307: $this->action = array_shift($items);
308: $size = count($items);
309: if ($size >= 2)
310: for ($i = 0; $i < $size; $i += 2) {
311: $key = (isset($items[$i])) ? $items[$i] : $i;
312: $value = (isset($items[$i + 1])) ? $items[$i + 1] : null;
313: $this->params[$key] = $value;
314: }
315: else
316: $this->params = $items;
317:
318:
319:
320:
321: if (!empty($this->tradController))
322: {
323: if (isset($this->tradController[$this->codeLangue][$this->controller]['controllerName']))
324: {
325: $controller = $this->tradController[$this->codeLangue][$this->controller]['controllerName'];
326: if (!empty($controller))
327: $this->controller = $controller;
328: }
329:
330: if (isset($this->tradController[$this->codeLangue][$this->controller]['actionsNames'][$this->action]))
331: {
332: $action = $this->tradController[$this->codeLangue][$this->controller]['actionsNames'][$this->action];
333: if (!empty($action))
334: $this->action = $action;
335: }
336: }
337: }
338: }
339:
340: 341: 342: 343:
344: public function setPath($path)
345: {
346: if (is_dir($path) === false)
347: {
348: throw new \InvalidArgumentException('Controller invalide : ' . $path);
349: }
350:
351: $this->path = $path;
352: }
353:
354: public function setView($view)
355: {
356: $this->view = $view;
357: }
358:
359: 360: 361: 362:
363: public function setMultiLangue($is)
364: {
365: $this->isMultiLangue = $is;
366: }
367:
368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385:
386: public function setControllerTraduction($trad)
387: {
388: $this->tradController = $trad;
389: }
390:
391: 392: 393: 394: 395:
396: public function setDefaultControllerAction($controller, $action)
397: {
398: $this->defaultController = $controller;
399: $this->defaultAction = $action;
400: }
401:
402: 403: 404: 405: 406:
407: public function setErrorControllerAction($controller, $action)
408: {
409: $this->errorController = $controller;
410: $this->errorAction = $action;
411: }
412:
413: 414: 415: 416:
417: public function getParameters()
418: {
419: return $this->params;
420: }
421:
422: 423: 424:
425: private function __construct()
426: {
427: $this->rules = array();
428: $this->defaultController = 'index';
429: $this->defaultAction = 'index';
430: $this->errorController = 'error';
431: $this->errorAction = 'index';
432: }
433:
434: 435: 436: 437:
438: private function clear_empty_value(&$array)
439: {
440: foreach ($array as $key => $value) {
441: if (empty($value) && $value != 0)
442: unset($array[$key]);
443: }
444: $array = array_values($array);
445: }
446:
447: }
448: