Router::dispatch()   B
last analyzed

Complexity

Conditions 9
Paths 6

Size

Total Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
nc 6
nop 1
dl 0
loc 41
rs 7.7084
c 0
b 0
f 0
1
<?php
2
/**
3
 * KumbiaPHP web & app Framework
4
 *
5
 * LICENSE
6
 *
7
 * This source file is subject to the new BSD license that is bundled
8
 * with this package in the file LICENSE.
9
 *
10
 * @category   Kumbia
11
 * @package    Router
12
 *
13
 * @copyright  Copyright (c) 2005 - 2019 KumbiaPHP Team (http://www.kumbiaphp.com)
14
 * @license    https://github.com/KumbiaPHP/KumbiaPHP/blob/master/LICENSE   New BSD License
15
 */
16
17
/**
18
 * Clase que Actua como router del Front-Controller
19
 *
20
 * Manejo de redirecciones de peticiones
21
 * Contiene información referente a la url de
22
 * la petición ( modudo, controlador, acción, parametros, etc )
23
 *
24
 * @category   Kumbia
25
 * @package    Router
26
 */
27
class Router
28
{
29
30
    /**
31
     * Array estático con las variables del router
32
     *
33
     * @var array
34
     */
35
    protected static $vars = array(
36
        'method'          => '', //Método usado GET, POST, ...
37
        'route'           => '', //Ruta pasada en el GET
38
        'module'          => '', //Nombre del módulo actual
39
        'controller'      => 'index', //Nombre del controlador actual
40
        'action'          => 'index', //Nombre de la acción actual, por defecto index
41
        'parameters'      => [], //Lista los parámetros adicionales de la URL
42
        'controller_path' => 'index',
43
        'default_path'    => APP_PATH, //Path donde se encuentran los controller
44
        'suffix'          => '_controller.php', //suffix for controler
45
        'dir'             => 'controllers', //dir of controller
46
    );
47
48
    /**
49
     * This is the name of router class
50
     * @var String
51
     */
52
    protected static $router = 'KumbiaRouter';
53
    //Es el router por defecto
54
55
    /**
56
     * Indica si esta pendiente la ejecución de una ruta por parte del dispatcher
57
     *
58
     * @var boolean
59
     */
60
    protected static $routed = false;
61
62
    /**
63
     * Procesamiento basico del router
64
     * @param string $url
65
     * 
66
     * @throws KumbiaException
67
     * @return void
68
     */
69
    public static function init($url)
70
    {
71
        // Se miran los parámetros por seguridad
72
        if (stripos($url, '/../') !== false) {
73
            throw new KumbiaException("Posible intento de hack en URL: '$url'");
74
        }
75
        // Si hay intento de hack TODO: añadir la ip y referer en el log
76
        self::$vars['route'] = $url;
77
        //Método usado
78
        self::$vars['method'] = $_SERVER['REQUEST_METHOD'];
79
    }
80
81
    /**
82
     * Ejecuta una url
83
     *
84
     * @param string $url
85
     * 
86
     * @throws KumbiaException
87
     * @return Controller
88
     */
89
    public static function execute($url)
90
    {
91
        self::init($url);
92
        //alias
93
        $router = self::$router;
94
        $conf   = Config::get('config.application.routes');
95
        //Si config.ini tiene routes activados, mira si esta routed
96
        if ($conf) {
97
            /*Esta activado el router*/
98
            /* This if for back compatibility*/
99
            if ($conf === '1') {
100
                $url = $router::ifRouted($url);
101
            } else {
102
                /*Es otra clase de router*/
103
                $router = self::$router = $conf;
104
            }
105
        }
106
107
        // Descompone la url
108
        self::$vars = $router::rewrite($url) + self::$vars;
109
110
        // Despacha la ruta actual
111
        return self::dispatch($router::getController(self::$vars));
112
    }
113
114
    /**
115
     * Realiza el dispatch de la ruta actual
116
     * 
117
     * @param Controller $cont  Controlador a usar
118
     *
119
     * @throws KumbiaException
120
     * @return Controller
121
     */
122
    private static function dispatch($cont)
123
    {
124
        // Se ejecutan los filtros initialize y before
125
        if ($cont->k_callback(true) === false) {
126
            return $cont;
127
        }
128
129
        //Obteniendo el metodo
130
        try {
131
            $reflectionMethod = new ReflectionMethod($cont, $cont->action_name);
132
        } catch (ReflectionException $e) {
133
            throw new KumbiaException($cont->action_name, 'no_action');//TODO: enviar a un método del controller
134
        }
135
136
        //k_callback y __constructor metodo reservado
137
        if ($cont->action_name === 'k_callback' || $reflectionMethod->isConstructor()) {
138
            throw new KumbiaException('Esta intentando ejecutar un método reservado de KumbiaPHP');
139
        }
140
141
        //se verifica que los parametros que recibe
142
        //la action sea la cantidad correcta
143
        $num_params = count($cont->parameters);
144
        if ($cont->limit_params && ($num_params < $reflectionMethod->getNumberOfRequiredParameters() ||
145
                $num_params > $reflectionMethod->getNumberOfParameters())) {
146
            throw new KumbiaException(null, 'num_params');
147
        }
148
149
        try {
150
            $reflectionMethod->invokeArgs($cont, $cont->parameters);
151
        } catch (ReflectionException $e) {
152
            throw new KumbiaException(null, 'no_action');//TODO: mejor no_public
153
        }
154
155
        //Corre los filtros after y finalize
156
        $cont->k_callback();
157
158
        //Si esta routed internamente volver a ejecutar
159
        self::isRouted();
160
161
        return $cont;
162
    }
163
164
    /**
165
     * Redirecciona la ejecución internamente
166
     * 
167
     * @throws KumbiaException
168
     * @return void
169
     */
170
    protected static function isRouted()
171
    {
172
        if (self::$routed) {
173
            self::$routed = false;
174
            $router = self::$router;
175
            // Despacha la ruta actual
176
            self::dispatch($router::getController(self::$vars));
177
        }
178
    }
179
180
    /**
181
     * Envia el valor de un atributo o el array con todos los atributos y sus valores del router
182
     * Mirar el atributo vars del router
183
     * ej.
184
     * <code>Router::get()</code>
185
     *
186
     * ej.
187
     * <code>Router::get('controller')</code>
188
     *
189
     * @param string $var (opcional) un atributo: route, module, controller, action, parameters o routed
190
     * 
191
     * @return array|string con el valor del atributo
192
     */
193
    public static function get($var = '')
194
    {
195
        return ($var) ? self::$vars[$var] : self::$vars;
196
    }
197
198
    /**
199
     * Redirecciona la ejecución internamente o externamente con un routes propio
200
     *
201
     * @param array $params array de $vars (móddulo, controller, action, params, ...)
202
     * @param boolean $intern si la redirección es interna
203
     * 
204
     * @return void
205
     */
206
    public static function to($params, $intern = false)
207
    {
208
        if ($intern) {
209
            self::$routed = true;
210
        }
211
        self::$vars = $params + self::$vars;
212
    }
213
}
214