KumbiaPHP  beta2
Framework PHP
 Todo Estructuras de Datos Namespaces Archivos Funciones Variables Páginas
router.php
Ir a la documentación de este archivo.
1 <?php
31 final class Router
32 {
38  private static $_vars = array(
39  'method' => NULL, //Método usado GET, POST, ...
40  'route' => NULL, //Ruta pasada en el GET
41  'module' => NULL, //Nombre del módulo actual
42  'controller' => 'index', //Nombre del controlador actual
43  'action' => 'index', //Nombre de la acción actual, por defecto index
44  'parameters' => array(), //Lista los parámetros adicionales de la URL
45  'controller_path' => 'index'
46  );
47 
53  private static $_routed = FALSE;
54 
61  public static function execute($url)
62  {
63 
64  // Se miran los parámetros por seguridad
65  if (stripos($url, '/../') !== false)
66  throw new KumbiaException("Posible intento de hack en URL: '$url'");
67  // Si hay intento de hack TODO: añadir la ip y referer en el log
68 
69  self::$_vars['route'] = $url;
70  //Método usado
71  self::$_vars['method'] = $_SERVER['REQUEST_METHOD'];
72  //Si config.ini tiene routes activados, mira si esta routed
73  if (Config::get('config.application.routes')) {
74  $url = self::_ifRouted($url);
75  }
76  // Descompone la url
77  self::_rewrite($url);
78  // Despacha la ruta actual
79  return self::_dispatch();
80  }
81 
89  private static function _ifRouted($url)
90  {
91  $routes = Config::read('routes');
92  $routes = $routes['routes'];
93 
94  // Si existe una ruta exacta la devuelve
95  if (isset($routes[$url])) {
96  return $routes[$url];
97  }
98 
99  // Si existe una ruta con el comodin * crea la nueva ruta
100  foreach ($routes as $key => $val) {
101  if ($key == '/*') {
102  return rtrim($val, '*') . $url;
103  }
104 
105  if (strripos($key, '*', -1)) {
106  $key = rtrim($key, '*');
107  if (strncmp($url, $key, strlen($key)) == 0)
108  return str_replace($key, rtrim($val, '*'), $url);
109  }
110  }
111 
112  return $url;
113  }
114 
120  private static function _rewrite($url)
121  {
122  //Valor por defecto
123  if ($url == '/') return;
124 
125  //Se limpia la url, en caso de que la hallan escrito con el último parámetro sin valor, es decir controller/action/
126  // Obtiene y asigna todos los parámetros de la url
127  $url_items = explode('/', trim($url, '/'));
128 
129  // El primer parametro de la url es un módulo?
130  if (is_dir(APP_PATH . "controllers/$url_items[0]")) {
131  self::$_vars['module'] = $url_items[0];
132 
133  // Si no hay mas parametros sale
134  if (next($url_items) === false) {
135  self::$_vars['controller_path'] = "$url_items[0]/index";
136  return;
137  }
138  }
139 
140  // Controlador
141  self::$_vars['controller'] = current($url_items);
142  self::$_vars['controller_path'] = (self::$_vars['module']) ? "$url_items[0]/$url_items[1]" : current($url_items);
143 
144  // Si no hay mas parametros sale
145  if (next($url_items) === false) return;
146 
147  // Acción
148  self::$_vars['action'] = current($url_items);
149 
150  // Si no hay mas parametros sale
151  if (next($url_items) === false) return;
152 
153  // Crea los parámetros y los pasa
154  self::$_vars['parameters'] = array_slice($url_items, key($url_items));
155  }
156 
162  private static function _dispatch()
163  {
164  // Extrae las variables para manipularlas facilmente
165  extract(self::$_vars, EXTR_OVERWRITE);
166 
167  if (!include_once APP_PATH . "controllers/$controller_path" . '_controller.php')
168  throw new KumbiaException(null, 'no_controller');
169 
170  View::select($action); //TODO: mover al constructor del controller base las 2 lineas
171  View::setPath($controller_path);
172  //Asigna el controlador activo
173  $app_controller = Util::camelcase($controller) . 'Controller';
174  $cont = new $app_controller($module, $controller, $action, $parameters);
175 
176  // Se ejecutan los filtros initialize y before
177  if ($cont->k_callback(true) === false) {
178  return $cont;
179  }
180 
181  //Obteniendo el metodo
182  try {
183  $reflectionMethod = new ReflectionMethod($cont, $cont->action_name);
184  } catch (ReflectionException $e) {
185  throw new KumbiaException(null, 'no_action'); //TODO: enviar a un método del controller
186  }
187 
188  //k_callback y __constructor metodo reservado
189  if ($cont->action_name == 'k_callback' || $reflectionMethod->isConstructor()) {
190  throw new KumbiaException('Esta intentando ejecutar un método reservado de KumbiaPHP');
191  }
192 
193  //se verifica que los parametros que recibe
194  //la action sea la cantidad correcta
195  $num_params = count($cont->parameters);
196  if ($cont->limit_params && ($num_params < $reflectionMethod->getNumberOfRequiredParameters() ||
197  $num_params > $reflectionMethod->getNumberOfParameters())) {
198  throw new KumbiaException(NULL,'num_params');
199  }
200 
201  try {
202  $reflectionMethod->invokeArgs($cont, $cont->parameters);
203  } catch (ReflectionException $e) {
204  throw new KumbiaException(null, 'no_action'); //TODO: mejor no_public
205  }
206 
207  //Corre los filtros after y finalize
208  $cont->k_callback();
209 
210  //Si esta routed internamente volver a ejecutar
211  if (self::$_routed) {
212  self::$_routed = FALSE;
213  return self::_dispatch(); // Vuelve a ejecutar el dispatcher
214  }
215 
216  return $cont;
217  }
218 
225  public static function route_to()
226  {
227  call_user_func_array(array('Redirect', 'route_to'), func_get_args());
228  }
229 
242  public static function get($var = null)
243  {
244  if ($var) {
245  return self::$_vars[$var];
246  } else {
247  return self::$_vars;
248  }
249  }
250 
259  public static function redirect($route = null, $seconds = null)
260  {
261  Redirect::to($route, $seconds);
262  }
263 
272  public static function toAction($action, $seconds = null)
273  {
274  Redirect::toAction($action, $seconds);
275  }
276 
283  public static function to($params, $intern = FALSE)
284  {
285  if($intern) self::$_routed = TRUE;
286  self::$_vars = $params + self::$_vars;
287  }
288 }