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 View |
||||
11 | * |
||||
12 | * @copyright Copyright (c) 2005 - 2023 KumbiaPHP Team (http://www.kumbiaphp.com) |
||||
13 | * @license https://github.com/KumbiaPHP/KumbiaPHP/blob/master/LICENSE New BSD License |
||||
14 | */ |
||||
15 | |||||
16 | /** |
||||
17 | * Renderer de vistas. |
||||
18 | * |
||||
19 | * @category View |
||||
20 | */ |
||||
21 | class KumbiaView |
||||
22 | { |
||||
23 | /** |
||||
24 | * Contenido. |
||||
25 | * |
||||
26 | * @var string|null |
||||
27 | */ |
||||
28 | protected static $_content; |
||||
29 | /** |
||||
30 | * Vista a renderizar. |
||||
31 | * |
||||
32 | * @var string |
||||
33 | * */ |
||||
34 | protected static $_view; |
||||
35 | /** |
||||
36 | * Template. |
||||
37 | * |
||||
38 | * @var string|null |
||||
39 | */ |
||||
40 | protected static $_template = 'default'; |
||||
41 | /** |
||||
42 | * Indica el tipo de salida generada por el controlador. |
||||
43 | * |
||||
44 | * @var string |
||||
45 | */ |
||||
46 | protected static $_response; |
||||
47 | /** |
||||
48 | * Indica el path al que se le añadira la constante correspondiente. |
||||
49 | * |
||||
50 | * @var string |
||||
51 | */ |
||||
52 | protected static $_path; |
||||
53 | /** |
||||
54 | * Número de minutos que será cacheada la vista actual. |
||||
55 | * |
||||
56 | * type: tipo de cache (view, template) |
||||
57 | * time: tiempo de vida de cache |
||||
58 | * |
||||
59 | * @var array |
||||
60 | */ |
||||
61 | protected static $_cache = ['type' => false, 'time' => false, 'group' => false]; |
||||
62 | |||||
63 | /** |
||||
64 | * Datos del Controlador actual. |
||||
65 | * |
||||
66 | * @var array |
||||
67 | */ |
||||
68 | protected static $_controller; |
||||
69 | |||||
70 | /** |
||||
71 | * Initialize view |
||||
72 | * |
||||
73 | * @param string $view |
||||
74 | * @param string $path |
||||
75 | * @return void |
||||
76 | */ |
||||
77 | public static function init($view, $path) |
||||
78 | { |
||||
79 | self::$_view = $view; |
||||
80 | self::$_path = $path.'/'; |
||||
81 | //self::$init = true; |
||||
82 | // TODO add defaults if init executed (workerman, ngx-php,...) |
||||
83 | } |
||||
84 | |||||
85 | /** |
||||
86 | * Cambia el view y opcionalmente el template. |
||||
87 | * |
||||
88 | * @param string|null $view nombre del view a utilizar sin .phtml |
||||
89 | * @param string|null $template opcional nombre del template a utilizar sin .phtml |
||||
90 | * |
||||
91 | * @return void |
||||
92 | */ |
||||
93 | public static function select($view, $template = '') |
||||
94 | { |
||||
95 | self::$_view = $view; |
||||
96 | |||||
97 | // verifica si se indico template |
||||
98 | if ($template !== '') { |
||||
99 | self::$_template = $template; |
||||
100 | } |
||||
101 | } |
||||
102 | |||||
103 | /** |
||||
104 | * Asigna el template para la vista. |
||||
105 | * |
||||
106 | * @param string|null $template nombre del template a utilizar sin .phtml |
||||
107 | * |
||||
108 | * @return void |
||||
109 | */ |
||||
110 | public static function template($template) |
||||
111 | { |
||||
112 | self::$_template = $template; |
||||
113 | } |
||||
114 | |||||
115 | /** |
||||
116 | * Indica el tipo de Respuesta dada por el controlador |
||||
117 | * buscando el view con esa extension. |
||||
118 | * ej. View::response('xml'); |
||||
119 | * buscara: views/controller/action.xml.phtml. |
||||
120 | * |
||||
121 | * @param string $response |
||||
122 | * @param string|null $template Opcional nombre del template sin .phtml |
||||
123 | * |
||||
124 | * @return void |
||||
125 | */ |
||||
126 | public static function response($response, $template = null) |
||||
127 | { |
||||
128 | self::$_response = $response; |
||||
129 | |||||
130 | // verifica si se indico template |
||||
131 | if ($template !== null) { |
||||
132 | self::$_template = $template; |
||||
133 | } |
||||
134 | } |
||||
135 | |||||
136 | /** |
||||
137 | * Asigna el path de la vista. |
||||
138 | * |
||||
139 | * @param string $path path de la vista sin extension .phtml |
||||
140 | * |
||||
141 | * @return void |
||||
142 | */ |
||||
143 | public static function setPath($path) |
||||
144 | { |
||||
145 | self::$_path = $path.'/'; |
||||
146 | } |
||||
147 | |||||
148 | /** |
||||
149 | * Obtiene el path para vista incluyendo la extension .phtml. |
||||
150 | * |
||||
151 | * @return string |
||||
152 | */ |
||||
153 | public static function getPath() |
||||
154 | { |
||||
155 | if (self::$_response) { |
||||
156 | return self::$_path.self::$_view.'.'.self::$_response.'.phtml'; |
||||
157 | } |
||||
158 | |||||
159 | return self::$_path.self::$_view.'.phtml'; |
||||
160 | } |
||||
161 | |||||
162 | /** |
||||
163 | * Obtiene un atributo de KumbiaView. |
||||
164 | * |
||||
165 | * @param string $atribute nombre de atributo (template, response, path, etc) |
||||
166 | * |
||||
167 | * @return mixed |
||||
168 | */ |
||||
169 | public static function get($atribute) |
||||
170 | { |
||||
171 | return self::${"_$atribute"}; |
||||
172 | } |
||||
173 | |||||
174 | /** |
||||
175 | * Asigna cacheo de vistas o template. |
||||
176 | * |
||||
177 | * @param string|null $time Tiempo de vida de cache |
||||
178 | * @param string $type Tipo de cache (view, template) |
||||
179 | * @param string $group Grupo de pertenencia de cache |
||||
180 | * |
||||
181 | * @return bool En producción y cache de view |
||||
182 | */ |
||||
183 | public static function cache($time, $type = 'view', $group = 'kumbia.view') |
||||
184 | { |
||||
185 | if ($time === null) { //TODO borrar cache |
||||
186 | return self::$_cache['type'] = false; |
||||
187 | } |
||||
188 | self::$_cache['type'] = $type; |
||||
189 | self::$_cache['time'] = $time; |
||||
190 | self::$_cache['group'] = $group; |
||||
191 | //Si está en producción para view |
||||
192 | if (PRODUCTION && $type === 'view') { |
||||
193 | return self::getCache(); //TRUE si está cacheada |
||||
194 | } |
||||
195 | |||||
196 | return false; |
||||
197 | } |
||||
198 | |||||
199 | /** |
||||
200 | * Obtiene la cache de view. |
||||
201 | * |
||||
202 | * @return bool |
||||
203 | */ |
||||
204 | protected static function getCache() |
||||
205 | { |
||||
206 | // el contenido permanece nulo si no hay nada cacheado o la cache expiro |
||||
207 | self::$_content = Cache::driver()->get(Router::get('route'), self::$_cache['group']); |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
208 | |||||
209 | return self::$_content !== null; |
||||
210 | } |
||||
211 | |||||
212 | /** |
||||
213 | * Obtiene el view. |
||||
214 | * |
||||
215 | * @return string path del view |
||||
216 | */ |
||||
217 | protected static function getView() |
||||
218 | { |
||||
219 | $file = APP_PATH.'views/'.self::getPath(); |
||||
220 | //Si no existe el view y es scaffold |
||||
221 | if (!is_file($file) && ($scaffold = self::$_controller['scaffold'] ?? null)) { |
||||
222 | $file = APP_PATH."views/_shared/scaffolds/$scaffold/".self::$_view.'.phtml'; |
||||
223 | } |
||||
224 | |||||
225 | return $file; |
||||
226 | } |
||||
227 | |||||
228 | /** |
||||
229 | * Cachea el view o template. |
||||
230 | * |
||||
231 | * @param string $type view o template |
||||
232 | * |
||||
233 | * @return void |
||||
234 | */ |
||||
235 | protected static function saveCache($type) |
||||
236 | { |
||||
237 | // si esta en produccion y se cachea la vista |
||||
238 | if (PRODUCTION && self::$_cache['type'] === $type) { |
||||
239 | Cache::driver()->save(ob_get_contents(), self::$_cache['time'], Router::get('route'), self::$_cache['group']); |
||||
0 ignored issues
–
show
It seems like
Router::get('route') can also be of type array ; however, parameter $id of Cache::save() does only seem to accept null|string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
240 | } |
||||
241 | } |
||||
242 | |||||
243 | /** |
||||
244 | * Renderiza la vista. |
||||
245 | * |
||||
246 | * @param Controller $controller |
||||
247 | * |
||||
248 | * @return void |
||||
249 | */ |
||||
250 | public static function render(Controller $controller) |
||||
251 | { |
||||
252 | if (!self::$_view && !self::$_template) { |
||||
253 | ob_end_flush(); |
||||
254 | |||||
255 | return; |
||||
256 | } |
||||
257 | |||||
258 | // Guarda los datos del controlador y los envia |
||||
259 | self::generate(self::$_controller = get_object_vars($controller)); |
||||
260 | } |
||||
261 | |||||
262 | /** |
||||
263 | * Genera la vista. |
||||
264 | * |
||||
265 | * @param array $controller |
||||
266 | * |
||||
267 | * @return void |
||||
268 | */ |
||||
269 | protected static function generate($controller) |
||||
270 | { |
||||
271 | // Registra la autocarga de helpers |
||||
272 | spl_autoload_register('kumbia_autoload_helper', true, true); |
||||
273 | // Mapea los atributos del controller en el scope |
||||
274 | extract($controller, EXTR_OVERWRITE); |
||||
275 | |||||
276 | // carga la vista si tiene view y no esta cacheada |
||||
277 | if (self::$_view && self::$_content === null) { |
||||
278 | // Carga el contenido del buffer de salida |
||||
279 | self::$_content = ob_get_clean(); |
||||
280 | // Renderizar vista |
||||
281 | ob_start(); |
||||
282 | |||||
283 | // carga la vista |
||||
284 | if (!include self::getView()) { |
||||
285 | throw new KumbiaException('Vista "'.self::getPath().'" no encontrada', 'no_view'); |
||||
286 | } |
||||
287 | |||||
288 | // si esta en produccion y se cachea la vista |
||||
289 | self::saveCache('view'); |
||||
290 | |||||
291 | // Verifica si hay template |
||||
292 | if (!self::$_template) { |
||||
293 | ob_end_flush(); |
||||
294 | |||||
295 | return; |
||||
296 | } |
||||
297 | |||||
298 | self::$_content = ob_get_clean(); |
||||
299 | } |
||||
300 | |||||
301 | // Renderizar template |
||||
302 | if ($__template = self::$_template) { |
||||
303 | ob_start(); |
||||
304 | |||||
305 | // carga el template |
||||
306 | if (!include APP_PATH."views/_shared/templates/$__template.phtml") { |
||||
307 | throw new KumbiaException("Template $__template no encontrado"); |
||||
308 | } |
||||
309 | |||||
310 | // si esta en produccion y se cachea template |
||||
311 | self::saveCache('template'); |
||||
312 | ob_end_flush(); |
||||
313 | |||||
314 | return; |
||||
315 | } |
||||
316 | |||||
317 | echo self::$_content; |
||||
318 | } |
||||
319 | |||||
320 | /** |
||||
321 | * Imprime el contenido del buffer. |
||||
322 | * |
||||
323 | * @return void |
||||
324 | */ |
||||
325 | public static function content() |
||||
326 | { |
||||
327 | if (isset($_SESSION['KUMBIA.CONTENT'])) { |
||||
328 | echo $_SESSION['KUMBIA.CONTENT']; |
||||
329 | unset($_SESSION['KUMBIA.CONTENT']); |
||||
330 | } |
||||
331 | echo self::$_content; |
||||
332 | } |
||||
333 | |||||
334 | /** |
||||
335 | * Renderiza una vista parcial. |
||||
336 | * |
||||
337 | * @throw KumbiaException |
||||
338 | * @param string $partial vista a renderizar |
||||
339 | * @param string $__time tiempo de cache |
||||
340 | * @param array|string|null $params variables para el partial |
||||
341 | * @param string $group grupo de cache |
||||
342 | * @return void |
||||
343 | */ |
||||
344 | public static function partial($partial, $__time = '', $params = null, $group = 'kumbia.partials') |
||||
345 | { |
||||
346 | if (PRODUCTION && $__time && !Cache::driver()->start($__time, $partial, $group)) { |
||||
347 | return; |
||||
348 | } |
||||
349 | |||||
350 | //Verificando el partials en el dir app |
||||
351 | $__file = APP_PATH."views/_shared/partials/$partial.phtml"; |
||||
352 | |||||
353 | if (!is_file($__file)) { |
||||
354 | //Verificando el partials en el dir core |
||||
355 | $__file = CORE_PATH."views/partials/$partial.phtml"; |
||||
356 | } |
||||
357 | |||||
358 | if ($params) { |
||||
359 | if (is_string($params)) { |
||||
360 | $params = Util::getParams(explode(',', $params)); |
||||
361 | } |
||||
362 | |||||
363 | // carga los parametros en el scope |
||||
364 | extract($params, EXTR_OVERWRITE); |
||||
365 | } |
||||
366 | |||||
367 | // carga la vista parcial |
||||
368 | if (!include $__file) { |
||||
369 | throw new KumbiaException('Vista Parcial "'.$__file.'" no encontrada', 'no_partial'); |
||||
370 | } |
||||
371 | |||||
372 | // se guarda en la cache de ser requerido |
||||
373 | if (PRODUCTION && $__time) { |
||||
374 | Cache::driver()->end(); |
||||
375 | } |
||||
376 | } |
||||
377 | |||||
378 | /** |
||||
379 | * Obtiene el valor de un atributo público o todos del controlador. |
||||
380 | * |
||||
381 | * @param string $var nombre de variable |
||||
382 | * |
||||
383 | * @return mixed valor de la variable |
||||
384 | */ |
||||
385 | public static function getVar($var = '') |
||||
386 | { |
||||
387 | if (!$var) { |
||||
388 | return self::$_controller; |
||||
389 | } |
||||
390 | |||||
391 | return self::$_controller[$var] ?? null; |
||||
392 | } |
||||
393 | } |
||||
394 | |||||
395 | /** |
||||
396 | * Atajo para htmlspecialchars, por defecto toma el charset de la |
||||
397 | * aplicacion. |
||||
398 | * |
||||
399 | * @param string $string |
||||
400 | * @param string $charset |
||||
401 | * |
||||
402 | * @return string |
||||
403 | */ |
||||
404 | function h($string, $charset = APP_CHARSET) |
||||
405 | { |
||||
406 | return htmlspecialchars($string, ENT_QUOTES, $charset); |
||||
407 | } |
||||
408 |