Completed
Push — master ( 4036d4...da82e8 )
by Fran
03:44
created

Template::addGetFlashFunction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace PSFS\base;
4
5
6
use PSFS\base\config\Config;
7
use PSFS\base\exception\ConfigException;
8
use PSFS\base\extension\AssetsTokenParser;
9
use PSFS\base\extension\TemplateFunctions;
10
use PSFS\base\types\SingletonTrait;
11
use PSFS\Dispatcher;
12
13
14
class Template {
15
16
    use SingletonTrait;
17
    /**
18
     * @var \Twig_Environment tpl
19
     */
20
    protected $tpl;
21
    protected $filters = array();
22
23
    protected $debug = false;
24
    protected $public_zone = true;
25
    private $status_code = 200;
26
27
    /**
28
     * @var \PSFS\base\Security $security
29
     */
30
    protected $security;
31
32
    /**
33
     * @var \PSFS\base\Cache $cache
34
     */
35
    protected $cache;
36
37
    /**
38
     * Constructor por defecto
39
     */
40
    public function __construct() {
41
        $this->setup();
42
        $this->addTemplateFunctions();
43
        $this->addTemplateTokens();
44
        $this->optimizeTemplates();
45
    }
46
47
    /**
48
     * Método que devuelve el loader del Template
49
     * @return \Twig_LoaderInterface
50
     */
51
    public function getLoader() {
52
        return $this->tpl->getLoader();
53
    }
54
55
    /**
56
     * Método que activa la zona pública
57
     * @param bool $public
58
     *
59
     * @return Template
60
     */
61
    public function setPublicZone($public = true) {
62
        $this->public_zone = $public;
63
        return $this;
64
    }
65
66
    /**
67
     * Método que establece un header de http status code
68
     * @param string $status
69
     *
70
     * @return Template
71
     */
72
    public function setStatus($status = null) {
73
        switch ($status)
74
        {
75
            //TODO implement all status codes
76
            case '500': $this->status_code = "HTTP/1.0 500 Internal Server Error"; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
77
            case '404': $this->status_code = "HTTP/1.0 404 Not Found"; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
78
            case '403': $this->status_code = "HTTP/1.0 403 Forbidden"; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
79
            case '402': $this->status_code = "HTTP/1.0 402 Payment Required"; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
80
            case '401': $this->status_code = "HTTP/1.0 401 Unauthorized"; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
81
            case '400': $this->status_code = "HTTP/1.0 400 Bad Request"; break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
82
        }
83
        return $this;
84
    }
85
86
    /**
87
     * Método que procesa la plantilla
88
     *
89
     * @param string $tpl
90
     * @param array $vars
91
     * @param array $cookies
92
     *
93
     * @return string HTML
94
     */
95
    public function render($tpl, array $vars = array(), array $cookies = array()) {
96
        Logger::log('Start render response');
97
        $vars = $this->setDebugHeaders($vars);
98
        $output = $this->dump($tpl, $vars);
99
100
        return $this->output($output, 'text/html', $cookies);
101
    }
102
103
    /**
104
     * Servicio que establece las cabeceras de la respuesta
105
     * @param string $contentType
106
     * @param array $cookies
107
     */
108
    private function setReponseHeaders($contentType = 'text/html', array $cookies = array()) {
109
        $config = Config::getInstance();
110
        $powered = $config->get("poweredBy");
111
        if (empty($powered)) {
112
            $powered = "@c15k0";
113
        }
114
        header("X-Powered-By: $powered");
115
        $this->setStatusHeader();
116
        $this->setAuthHeaders();
117
        $this->setCookieHeaders($cookies);
118
        header('Content-type: '.$contentType);
119
120
    }
121
122
    /**
123
     * Servicio que devuelve el output
124
     * @param string $output
125
     * @param string $contentType
126
     * @param array $cookies
127
     * @return string HTML
128
     */
129
    public function output($output = '', $contentType = 'text/html', array $cookies = array()) {
130
        Logger::log('Start output response');
131
        ob_start();
132
        $this->setReponseHeaders($contentType, $cookies);
133
        header('Content-length: '.strlen($output));
134
135
        $cache = Cache::needCache();
136
        if (false !== $cache && $this->status_code === 200 && $this->debug === false) {
137
            Logger::log('Saving output response into cache');
138
            $cacheName = $this->cache->getRequestCacheHash();
139
            $this->cache->storeData("json".DIRECTORY_SEPARATOR.$cacheName, $output);
140
            $this->cache->storeData("json".DIRECTORY_SEPARATOR.$cacheName.".headers", headers_list(), Cache::JSON);
141
        }
142
        echo $output;
143
144
        ob_flush();
145
        ob_end_clean();
146
        Logger::log('End output response');
147
        $this->closeRender();
148
    }
149
150
    /**
151
     * Método que cierra y limpia los buffers de salida
152
     */
153
    public function closeRender() {
154
        Logger::log('Close template render');
155
        $this->security->setSessionKey("lastRequest", array(
156
            "url" => Request::getInstance()->getRootUrl().Request::requestUri(),
157
            "ts" => microtime(true),
158
        ));
159
        $this->security->updateSession();
160
        exit;
161
    }
162
163
    /**
164
     * Método que devuelve los datos cacheados con las cabeceras que tenía por entonces
165
     * @param string $data
166
     * @param string|null $headers
0 ignored issues
show
Documentation introduced by
Should the type for parameter $headers not be string|null|array? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
167
     */
168
    public function renderCache($data, $headers = array()) {
169
        ob_start();
170
        for ($i = 0, $ct = count($headers); $i < $ct; $i++) {
171
            header($headers[$i]);
172
        }
173
        echo $data;
174
        ob_flush();
175
        ob_end_clean();
176
        $this->closeRender();
177
    }
178
179
    /**
180
     * Método que añade una nueva ruta al path de Twig
181
     * @param $path
182
     * @param $domain
183
     *
184
     * @return Template
185
     */
186
    public function addPath($path, $domain = '') {
187
        $this->tpl->getLoader()->addPath($path, $domain);
188
        return $this;
189
    }
190
191
    /**
192
     * Método que devuelve el contenido de una plantilla
193
     * @param string $tpl
194
     * @param array $vars
195
     * @return string
196
     */
197
    public function dump($tpl, array $vars = array()) {
198
        $vars["__user__"] = $this->security->getUser();
199
        $vars["__admin__"] = $this->security->getAdmin();
200
        $vars["__profiles__"] = Security::getCleanProfiles();
201
        $vars["__flash__"] = Security::getInstance()->getFlashes();
202
        $dump = '';
203
        try {
204
            $dump = $this->tpl->render($tpl, $vars);
205
        }catch (\Exception $e) {
206
            echo $e->getMessage()."<pre>".$e->getTraceAsString()."</pre>";
207
        }
208
        return $dump;
209
    }
210
211
    /**
212
     * Método que añade una función al motor de plantillas
213
     * @param string $templateFunction
214
     * @param $functionName
215
     *
216
     * @return Template
217
     */
218
    protected function addTemplateFunction($templateFunction, $functionName) {
219
        $function = new \Twig_SimpleFunction($templateFunction, $functionName);
220
        $this->tpl->addFunction($function);
221
        return $this;
222
    }
223
224
    /**
225
     * Funcion Twig para los assets en las plantillas
226
     * @return Template
227
     */
228
    private function addAssetFunction() {
229
        return $this->addTemplateFunction("asset", TemplateFunctions::ASSETS_FUNCTION);
230
    }
231
232
    /**
233
     * Función que pinta un formulario
234
     * @return Template
235
     */
236
    private function addFormsFunction() {
237
        return $this->addTemplateFunction("form", TemplateFunctions::FORM_FUNCTION);
238
    }
239
240
    /**
241
     * Función que pinta un campo de un formulario
242
     * @return Template
243
     */
244
    private function addFormWidgetFunction()
245
    {
246
        return $this->addTemplateFunction("form_widget", TemplateFunctions::WIDGET_FUNCTION);
247
    }
248
249
    /**
250
     * Función que pinta un botón de un formulario
251
     * @return Template
252
     */
253
    private function addFormButtonFunction() {
254
        return $this->addTemplateFunction("form_button", TemplateFunctions::BUTTON_FUNCTION);
255
    }
256
257
    /**
258
     * Método que devuelve un parámetro de configuración en la plantilla
259
     * @return Template
260
     */
261
    private function addConfigFunction() {
262
        return $this->addTemplateFunction("get_config", TemplateFunctions::CONFIG_FUNCTION);
263
    }
264
265
    /**
266
     * Método que añade la función path a Twig
267
     * @return Template
268
     */
269
    private function addRouteFunction() {
270
        return $this->addTemplateFunction("path", TemplateFunctions::ROUTE_FUNCTION);
271
    }
272
273
    /**
274
     * Método que copia directamente el recurso solicitado a la carpeta pública
275
     * @return Template
276
     */
277
    private function addResourceFunction() {
278
        return $this->addTemplateFunction("resource", TemplateFunctions::RESOURCE_FUNCTION);
279
    }
280
281
    /**
282
     * @return Template
283
     */
284
    private function addSessionFunction() {
285
        return $this->addTemplateFunction("session", TemplateFunctions::SESSION_FUNCTION);
286
    }
287
288
    /**
289
     * @return Template
290
     */
291
    private function addExistsFlashFunction() {
292
        return $this->addTemplateFunction("existsFlash", TemplateFunctions::EXISTS_FLASH_FUNCTION);
293
    }
294
295
    /**
296
     * @return Template
297
     */
298
    private function addGetFlashFunction() {
299
        return $this->addTemplateFunction("getFlash", TemplateFunctions::GET_FLASH_FUNCTION);
300
    }
301
302
    /**
303
     * Servicio que regenera todas las plantillas
304
     * @return array
305
     */
306
    public function regenerateTemplates() {
307
        $this->generateTemplatesCache();
308
        $domains = Cache::getInstance()->getDataFromFile(CONFIG_DIR.DIRECTORY_SEPARATOR."domains.json", Cache::JSON, true);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 123 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
309
        if (is_array($domains)) {
310
            $translations = $this->parsePathTranslations($domains);
311
        }
312
        $translations[] = _("Plantillas regeneradas correctamente");
0 ignored issues
show
Bug introduced by
The variable $translations does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
313
        return $translations;
314
    }
315
316
    /**
317
     * @param $tplDir
318
     * @param string $domain
319
     *
320
     * @return mixed
321
     */
322
    protected function generateTemplate($tplDir, $domain = '') {
323
        $templatesDir = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($tplDir), \RecursiveIteratorIterator::LEAVES_ONLY);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 138 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
324
        foreach ($templatesDir as $file) {
325
            // force compilation
326
            if ($file->isFile()) {
327
                try {
328
                    $this->tpl->loadTemplate(str_replace($tplDir.'/', '', $file));
329
                } catch (\Exception $e) {
330
                    Logger::log($e->getMessage(), LOG_ERR);
331
                }
332
            }
333
        }
334
        return str_replace("%d", $domain, str_replace("%s", $tplDir, _("Generando plantillas en path '%s' para el dominio '%d'")));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 131 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
335
    }
336
337
    /**
338
     * Método que extrae el path de un string
339
     * @param $path
340
     *
341
     * @return string
342
     */
343
    public static function extractPath($path) {
344
        $explodePath = explode(DIRECTORY_SEPARATOR, $path);
345
        $realPath = array();
346
        for ($i = 0, $parts = count($explodePath) - 1; $i < $parts; $i++) {
347
            $realPath[] = $explodePath[$i];
348
        }
349
        return implode(DIRECTORY_SEPARATOR, $realPath);
350
    }
351
352
    /**
353
     * Método que devuelve los dominios de una plataforma
354
     * @param bool $append
355
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
356
     */
357
    static public function getDomains($append = false) {
358
        $domains = Router::getInstance()->getDomains();
359
        if ($append) {
360
            foreach ($domains as &$domain) {
361
            foreach ($domain as &$path) {
362
                $path .= DIRECTORY_SEPARATOR;
363
        }
364
            }
365
        }
366
        return $domains;
367
    }
368
369
    /**
370
     * @param $cookies
371
     */
372
    protected function setCookieHeaders($cookies) {
373
        if (!empty($cookies) && is_array($cookies)) {
374
            foreach ($cookies as $cookie) {
375
            setcookie($cookie["name"],
376
                $cookie["value"],
377
                (array_key_exists('expire', $cookie)) ? $cookie["expire"] : NULL,
378
                (array_key_exists('path', $cookie)) ? $cookie["path"] : "/",
379
                (array_key_exists('domain', $cookie)) ? $cookie["domain"] : Request::getInstance()->getRootUrl(FALSE),
380
                (array_key_exists('secure', $cookie)) ? $cookie["secure"] : FALSE,
381
                (array_key_exists('http', $cookie)) ? $cookie["http"] : FALSE
382
            );
383
        }
384
        }
385
    }
386
387
    /**
388
     * Método que inyecta las cabeceras necesarias para la autenticación
389
     */
390
    protected function setAuthHeaders() {
391
        if ($this->public_zone) {
392
            unset($_SERVER["PHP_AUTH_USER"]);
393
            unset($_SERVER["PHP_AUTH_PW"]);
394
            header_remove("Authorization");
395
        }else {
396
            header('Authorization:');
397
        }
398
    }
399
400
    /**
401
     * Método que establece el status code
402
     */
403
    protected function setStatusHeader() {
404
        if (NULL !== $this->status_code) {
405
            header($this->status_code);
406
        }
407
    }
408
409
    /**
410
     * Método que mete en las variables de las plantillas las cabeceras de debug
411
     * @param array $vars
412
     *
413
     * @return array
414
     */
415
    protected function setDebugHeaders(array $vars)
416
    {
417
        if ($this->debug) {
418
            Logger::log('Adding debug headers to render response');
419
            $vars["__DEBUG__"]["includes"] = get_included_files();
420
            $vars["__DEBUG__"]["trace"] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
421
            header('X-PSFS-DEBUG-TS: '.Dispatcher::getInstance()->getTs().' s');
422
            header('X-PSFS-DEBUG-MEM: '.Dispatcher::getInstance()->getMem('MBytes').' MBytes');
423
            header('X-PSFS-DEBUG-FILES: '.count(get_included_files()).' files opened');
424
        }
425
426
        return $vars;
427
    }
428
429
    /**
430
     * Método que añade todas las funciones de las plantillas
431
     */
432
    private function addTemplateFunctions() {
433
        //Asignamos las funciones especiales
434
        $this->addAssetFunction()
435
            ->addFormsFunction()
436
            ->addFormWidgetFunction()
437
            ->addFormButtonFunction()
438
            ->addConfigFunction()
439
            ->addRouteFunction()
440
            ->addSessionFunction()
441
            ->addExistsFlashFunction()
442
            ->addGetFlashFunction()
443
            ->addResourceFunction()
444
        ;
445
    }
446
447
    /**
448
     * Método que devuelve el motod de plantillas
449
     * @return \Twig_Environment
450
     */
451
    public function getTemplateEngine() {
452
        return $this->tpl;
453
    }
454
455
    /**
456
     * Método que inicializa el motor de plantillas
457
     */
458
    private function setup() {
459
        $this->debug = Config::getInstance()->getDebugMode() ?: FALSE;
460
        $this->security = Security::getInstance();
461
        $this->cache = Cache::getInstance();
462
        $loader = new \Twig_Loader_Filesystem(Config::getInstance()->getTemplatePath());
463
        $this->tpl = new \Twig_Environment($loader, array(
464
            'cache'       => Config::getInstance()->getCachePath(),
465
            'debug'       => (bool)$this->debug,
466
            'auto_reload' => TRUE,
467
        ));
468
    }
469
470
    /**
471
     * Método que inyecta los parseadores
472
     */
473
    private function addTemplateTokens() {
474
        //Añadimos las extensiones de los tags
475
        $this->tpl->addTokenParser(new AssetsTokenParser("css"));
476
        $this->tpl->addTokenParser(new AssetsTokenParser("js"));
477
    }
478
479
    /**
480
     * Método que inyecta las optimizaciones al motor de la plantilla
481
     */
482
    private function optimizeTemplates() {
483
        //Optimizamos
484
        $this->tpl->addExtension(new \Twig_Extensions_Extension_I18n());
485
    }
486
487
    /**
488
     * Method that extract all path tag for extracting translations
489
     * @param array $domains
490
     *
491
     * @return array
492
     */
493
    private function parsePathTranslations($domains)
494
    {
495
        $translations = array();
496
        if (!empty($domains)) {
497
            foreach ($domains as $domain => $paths) {
498
                if (strlen($domain) && array_key_exists("template", $paths)) {
499
                    $this->addPath($paths["template"], $domain);
500
                    $translations[] = $this->generateTemplate($paths["template"], $domain);
501
                }
502
            }
503
        }
504
505
        return $translations;
506
    }
507
508
    /**
509
     * Method that generate all template caches
510
     */
511
    private function generateTemplatesCache()
512
    {
513
        /** @var \Twig_Loader_Filesystem $loader */
514
        $loader = $this->tpl->getLoader();
515
        $availablePaths = $loader->getPaths();
516
        if (!empty($availablePaths)) {
517
            foreach ($availablePaths as $path) {
518
                $this->generateTemplate($path);
519
            }
520
        }
521
    }
522
}
523