Overview

Packages

  • Auth
  • Config
  • Controller
  • Date
  • Db
  • Feed
    • Abstract
    • Writers
  • File
    • Decorator
  • Form
    • Element
  • Image
  • Log
    • Writer
  • Net
    • Exception
  • None
  • PHP
  • PHPMailer
  • Session
  • Util
  • Validate
    • Validator
  • Zend
    • Registry

Classes

  • Controller_BaseController
  • Controller_Router
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * Pry Framework
  5:  *
  6:  * LICENSE
  7:  *
  8:  * This source file is subject to the new BSD license that is bundled
  9:  * with this package in the file LICENSE.txt.
 10:  * 
 11:  * @version $Revision: 276 $
 12:  */
 13: 
 14: /**
 15:  * Router permettant la mise en place du pattern MVC
 16:  * Gère les routes classiques ainsi que les règles de routages
 17:  * <code>
 18:  * $router = Controller_Router::getInstance();
 19:  * $router->setPath(ROOT_PATH.'includes/controllers/'); // Chemin vers les controlleurs
 20:  * $router->addRule('test/regles/:id/hello',array('controller'=>'index','action'=>'withRule'));
 21:  * </code>
 22:  * Nécessite une règle de routage du type RewriteRule ^(.*)$ index.php?url=$1 [QSA,L] dans le serveur web
 23:  * 
 24:  * @category Pry
 25:  * @package Controller
 26:  * @version 1.3.1
 27:  * @author Olivier ROGER <oroger.fr>
 28:  *
 29:  */
 30: class Controller_Router
 31: {
 32: 
 33:     /**
 34:      * Instance du router
 35:      * @static
 36:      * @var Controller_Router
 37:      */
 38:     static private $instance;
 39: 
 40:     /**
 41:      * Controller à utiliser. Par defaut index
 42:      * @var string
 43:      */
 44:     private $controller;
 45: 
 46:     /**
 47:      * Action du controller. Par défaut index
 48:      * @var string
 49:      */
 50:     private $action;
 51: 
 52:     /**
 53:      * Tableau des paramètres
 54:      * @var array
 55:      */
 56:     private $params;
 57: 
 58:     /**
 59:      * Liste des règles de routage
 60:      * @var array
 61:      */
 62:     private $rules;
 63: 
 64:     /**
 65:      * Chemin vers le dossier contenant les controllers
 66:      * @var string
 67:      */
 68:     private $path;
 69: 
 70:     /**
 71:      * Fichier à inclure
 72:      * @var string
 73:      */
 74:     private $file;
 75: 
 76:     /**
 77:      * Controller par defaut (index)
 78:      * @var string
 79:      */
 80:     private $defaultController;
 81: 
 82:     /**
 83:      * Action par defaut (index)
 84:      * @var string
 85:      */
 86:     private $defaultAction;
 87: 
 88:     /**
 89:      * Controller à appelé en cas d'erreur. Par defaut error
 90:      * @var string
 91:      */
 92:     private $errorController;
 93: 
 94:     /**
 95:      * Action à appelé en cas d'erreur. par defaut index
 96:      * @var string
 97:      */
 98:     private $errorAction;
 99:     
100:     /**
101:      * Le router gère t'il les url du type site.com/fr/controller/action
102:      * @var boolean 
103:      */
104:     private $isMultiLangue  = false;
105:     
106:     /**
107:      * Code langue choisie
108:      * @var string 
109:      */
110:     private $codeLangue     = '';
111:     
112:     /**
113:      * Liste des traduction d'url
114:      * @var array 
115:      */
116:     private $tradController;
117: 
118:     /**
119:      * Singleton de la classe
120:      * @return Controller_Router
121:      */
122:     public static function getInstance()
123:     {
124:         if (!isset(self::$instance))
125:             self::$instance = new Controller_Router();
126:         return self::$instance;
127:     }
128: 
129:     /**
130:      * Charge le controller demandé.
131:      * Prend en compte les règles de routages si nécessaire
132:      */
133:     public function load()
134:     {
135:         $url        = (!empty($_GET['url'])) ? $_GET['url'] : '';
136:         $tabUrl     = explode('/',$url);
137:         $isCustom   = false;
138:         
139:         //Suppression des éventuelles partie vide de l'url
140:         $this->clear_empty_value($tabUrl);
141: 
142:         if (!empty($this->rules))
143:         {
144:             foreach ($this->rules as $key => $data) {
145:                 $params = $this->matchRules($key, $tabUrl);
146:                 if ($params)
147:                 {
148:                     $this->controller   = $data['controller'];
149:                     $this->action       = $data['action'];
150:                     $this->params       = $params;
151:                     $isCustom           = true;
152:                     break;
153:                 }
154:             }
155:         }
156: 
157:         if (!$isCustom)
158:             $this->getRoute($tabUrl);
159: 
160:         $this->controller   = (!empty($this->controller)) ? $this->controller : $this->defaultController;
161:         $this->action       = (!empty($this->action)) ? $this->action : $this->defaultAction;
162:         $ctrlPath           = str_replace('_', '/', $this->controller); // Gestion des sous dossiers dans les controllers
163:         $this->file         = realpath($this->path) . DIRECTORY_SEPARATOR . $ctrlPath . '.php';
164:         
165:         //is_file bien plus rapide que file_exists
166:         if (!is_file($this->file))
167:         {
168:             header("Status: 404 Not Found");
169:             $this->controller   = $this->errorController;
170:             $this->action       = $this->errorAction;
171:             $this->file         = $this->path . $this->controller . '.php';
172:         }
173: 
174:         //Inclusion du controller
175:         include $this->file;
176: 
177:         $class      = $this->controller . 'Controller';
178:         if(!empty($this->codeLangue))
179:             $controller = new $class($this->getParameters(),$this->codeLangue);
180:         else
181:             $controller = new $class($this->getParameters());
182: 
183:         if (!is_callable(array($controller, $this->action)))
184:             $action = $this->defaultAction;
185:         else
186:             $action = $this->action;
187: 
188:         $controller->$action();
189:     }
190: 
191:     /**
192:      * Ajoute une règle de routage.
193:      *
194:      * @param string $rule Règles de routage : /bla/:param1/blabla/:param2/blabla
195:      * @param array $target Cible de la règle : array('controller'=>'index','action'=>'test')
196:      */
197:     public function addRule($rule, $target)
198:     {
199:         if ($rule[0] != '/')
200:             $rule = '/' . $rule; //Ajout du slashe de début si absent
201: 
202:             $this->rules[$rule] = $target;
203:     }
204: 
205:     /**
206:      * Vérifie si l'url correspond à une règle de routage
207:      * @link http://blog.sosedoff.com/2009/07/04/simpe-php-url-routing-controller/
208:      * @param string $rule
209:      * @param array $dataItems
210:      * @return boolean|array
211:      */
212:     public function matchRules($rule, $dataItems)
213:     {
214:         $ruleItems = explode('/', $rule);
215:         $this->clear_empty_value($ruleItems);
216: 
217:         if (count($ruleItems) == count($dataItems))
218:         {
219:             $result = array();
220:             foreach ($ruleItems as $rKey => $rValue) {
221:                 if ($rValue[0] == ':')
222:                 {
223:                     $rValue = substr($rValue, 1); //Supprime les : de la clé
224:                     $result[$rValue] = $dataItems[$rKey];
225:                 }
226:                 else
227:                 {
228:                     if ($rValue != $dataItems[$rKey])
229:                         return false;
230:                 }
231:             }
232:             if (!empty($result))
233:                 return $result;
234: 
235:             unset($result);
236:         }
237:         return false;
238:     }
239:     
240:     /**
241:      * Retourne l'action
242:      * @return string 
243:      */
244:     public function getAction()
245:     {
246:         return $this->action;
247:     }
248:     
249:     /**
250:      * Retourne le controller
251:      * @return string
252:      */
253:     public function getController()
254:     {
255:         return $this->controller;
256:     }
257: 
258:     /**
259:      * Défini une route simple
260:      * @param array $url
261:      */
262:     private function getRoute($url)
263:     {
264:         $items = $url;
265: 
266:         if (!empty($items))
267:         {
268:             if($this->isMultiLangue)
269:                 $this->codeLangue = array_shift ($items);
270:             
271:             $this->controller   = array_shift($items);
272:             $this->action       = array_shift($items);
273:             $size = count($items);
274:             if($size >= 2)
275:                 for($i=0; $i< $size; $i += 2) {
276:                     $key    = (isset($items[$i])) ? $items[$i] : $i;
277:                     $value  = (isset($items[$i+1])) ? $items[$i+1] : null;
278:                     $this->params[$key] = $value;
279:                 }
280:             else
281:                 $this->params = $items;
282:             
283:             //Permet d'avoir des URL multilangue
284:             if(!empty($this->tradController))
285:             {
286:                 if(isset($this->tradController[$this->codeLangue][$this->controller]['controllerName']))
287:                 {
288:                     $controller = $this->tradController[$this->codeLangue][$this->controller]['controllerName'];
289:                     if(!empty($controller))
290:                         $this->controller = $controller;
291:                 }
292:                 
293:                 if(isset($this->tradController[$this->codeLangue][$this->controller]['actionsNames'][$this->action]))
294:                 {
295:                     $action = $this->tradController[$this->codeLangue][$this->controller]['actionsNames'][$this->action];
296:                     if(!empty($action))
297:                         $this->action = $action;
298:                 }
299:             }
300:         }
301:     }
302: 
303:     /**
304:      * Défini le chemin des controllers
305:      * @param string $path
306:      */
307:     public function setPath($path)
308:     {
309:         if (is_dir($path) === false)
310:         {
311:             throw new InvalidArgumentException('Controller invalide : ' . $path);
312:         }
313: 
314:         $this->path = $path;
315:     }
316:     
317:     /**
318:      * Défini le router comme pouvant gérer ou non le multinlangue
319:      * @param boolean $is 
320:      */
321:     public function setMultiLangue($is)
322:     {
323:         $this->isMultiLangue = $is;
324:     }
325:     
326:     /**
327:      * Défini un tableau permettant d'avoir des URL multi langue.
328:      * Format du tableau : 
329:      * 
330:      * @param array $trad format : 
331:      * $urlTraduction = array(
332:         'fr'=>array(
333:             'accueil'=>array(
334:                 'controllerName'    => 'index',
335:                 'actionsNames'      => array(
336:                     'presentation'  => 'index',
337:                     'liste'         => 'list',
338:                     'recherche'     => 'search'
339:                 )
340:             )
341:         ),
342:         'en'=>array(...));
343:      */
344:     public function setControllerTraduction($trad)
345:     {
346:         $this->tradController = $trad;
347:     }
348: 
349:     /**
350:      * Défini le controller et l'action par défaut
351:      * @param string $controller
352:      * @param string $action
353:      */
354:     public function setDefaultControllerAction($controller, $action)
355:     {
356:         $this->defaultController    = $controller;
357:         $this->defaultAction        = $action;
358:     }
359: 
360:     /**
361:      * Défini le controller et l'actionen cas d'erreur
362:      * @param string $controler
363:      * @param string $action
364:      */
365:     public function setErrorControllerAction($controller, $action)
366:     {
367:         $this->errorController  = $controller;
368:         $this->errorAction      = $action;
369:     }
370: 
371:     /**
372:      * Renvoi les paramètres disponibles
373:      * @return array
374:      */
375:     public function getParameters()
376:     {
377:         return $this->params;
378:     }
379: 
380:     /**
381:      * Constructeur
382:      */
383:     private function __construct()
384:     {
385:         $this->rules = array();
386:         $this->defaultController    = 'index';
387:         $this->defaultAction        = 'index';
388:         $this->errorController      = 'error';
389:         $this->errorAction          = 'index';
390:     }
391: 
392:     /**
393:      * Supprime d'un tableau tous les élements vide
394:      * @param array $array
395:      */
396:     private function clear_empty_value(&$array)
397:     {
398:         foreach ($array as $key => $value) {
399:             if (empty($value) && $value != 0)
400:                 unset($array[$key]);
401:         }
402:         $array = array_values($array); // Réorganise les clés
403:     }
404: }
405: 
Pry Framework API documentation generated by ApiGen 2.6.1