Passed
Push — master ( 510786...275623 )
by Fran
04:26
created

Template::setup()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 0
dl 0
loc 10
ccs 9
cts 9
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace PSFS\base;
3
4
use PSFS\base\config\Config;
5
use PSFS\base\extension\AssetsTokenParser;
6
use PSFS\base\extension\TemplateFunctions;
7
use PSFS\base\types\helpers\GeneratorHelper;
8
use PSFS\base\types\helpers\ResponseHelper;
9
use PSFS\base\types\traits\OutputTrait;
10
use PSFS\base\types\traits\RouteTrait;
11
use PSFS\base\types\traits\SingletonTrait;
12
13
/**
14
 * Class Template
15
 * @package PSFS\base
16
 */
17
class Template
18
{
19
    use SingletonTrait;
20
    use OutputTrait;
21
    use RouteTrait;
22
    const STATUS_OK = 'HTTP/1.0 200 OK';
23
    /**
24
     * @var \Twig_Environment tpl
25
     */
26
    protected $tpl;
27
    protected $filters = array();
28
29
    /**
30
     * Constructor por defecto
31
     */
32 1
    public function __construct()
33
    {
34 1
        $this->setup();
35 1
        $this->addTemplateFunctions();
36 1
        $this->addTemplateTokens();
37 1
        $this->optimizeTemplates();
38 1
    }
39
40
    /**
41
     * Método que devuelve el loader del Template
42
     * @return \Twig_LoaderInterface
43
     */
44
    public function getLoader()
45
    {
46
        return $this->tpl->getLoader();
47
    }
48
49
    /**
50
     * Método que activa la zona pública
51
     * @param bool $public
52
     *
53
     * @return Template
54
     */
55
    public function setPublicZone($public = true)
56
    {
57
        $this->public_zone = $public;
58
        return $this;
59
    }
60
61
    /**
62
     * Método que procesa la plantilla
63
     *
64
     * @param string $tpl
65
     * @param array $vars
66
     * @param array $cookies
67
     *
68
     * @return string HTML
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

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.

Loading history...
69
     */
70 1
    public function render($tpl, array $vars = array(), array $cookies = array())
71
    {
72 1
        Logger::log('Start render response');
73 1
        $vars = ResponseHelper::setDebugHeaders($vars);
74
        $output = $this->dump($tpl, $vars);
75
76
        return $this->output($output, 'text/html', $cookies);
77
    }
78
79
    /**
80
     * Método que añade una nueva ruta al path de Twig
81
     * @param $path
82
     * @param $domain
83
     *
84
     * @return Template
85
     */
86 1
    public function addPath($path, $domain = '')
87
    {
88 1
        $this->tpl->getLoader()->addPath($path, $domain);
89 1
        return $this;
90
    }
91
92
    /**
93
     * Método que devuelve el contenido de una plantilla
94
     * @param string $tpl
95
     * @param array $vars
96
     * @return string
97
     */
98
    public function dump($tpl, array $vars = array())
99
    {
100
        $vars["__user__"] = Security::getInstance()->getUser();
101
        $vars["__admin__"] = Security::getInstance()->getAdmin();
102
        $vars["__profiles__"] = Security::getCleanProfiles();
103
        $vars["__flash__"] = Security::getInstance()->getFlashes();
104
        $dump = '';
105
        try {
106
            $dump = $this->tpl->render($tpl, $vars);
107
        } catch (\Exception $e) {
108
            Logger::log($e->getMessage(), LOG_ERR);
109
        }
110
        return $dump;
111
    }
112
113
    /**
114
     * Método que añade una función al motor de plantillas
115
     * @param string $templateFunction
116
     * @param $functionName
117
     *
118
     * @return Template
119
     */
120 1
    protected function addTemplateFunction($templateFunction, $functionName)
121
    {
122 1
        $function = new \Twig_SimpleFunction($templateFunction, $functionName);
123 1
        $this->tpl->addFunction($function);
124 1
        return $this;
125
    }
126
127
    /**
128
     * Funcion Twig para los assets en las plantillas
129
     * @return Template
130
     */
131 1
    private function addAssetFunction()
132
    {
133 1
        return $this->addTemplateFunction("asset", TemplateFunctions::ASSETS_FUNCTION);
134
    }
135
136
    /**
137
     * Función que pinta un formulario
138
     * @return Template
139
     */
140 1
    private function addFormsFunction()
141
    {
142 1
        return $this->addTemplateFunction("form", TemplateFunctions::FORM_FUNCTION);
143
    }
144
145
    /**
146
     * Función que pinta un campo de un formulario
147
     * @return Template
148
     */
149 1
    private function addFormWidgetFunction()
150
    {
151 1
        return $this->addTemplateFunction("form_widget", TemplateFunctions::WIDGET_FUNCTION);
152
    }
153
154
    /**
155
     * Función que pinta un botón de un formulario
156
     * @return Template
157
     */
158 1
    private function addFormButtonFunction()
159
    {
160 1
        return $this->addTemplateFunction("form_button", TemplateFunctions::BUTTON_FUNCTION);
161
    }
162
163
    /**
164
     * Método que devuelve un parámetro de configuración en la plantilla
165
     * @return Template
166
     */
167 1
    private function addConfigFunction()
168
    {
169 1
        return $this->addTemplateFunction("get_config", TemplateFunctions::CONFIG_FUNCTION);
170
    }
171
172
    /**
173
     * Método que añade la función path a Twig
174
     * @return Template
175
     */
176 1
    private function addRouteFunction()
177
    {
178 1
        return $this->addTemplateFunction("path", TemplateFunctions::ROUTE_FUNCTION);
179
    }
180
181
    /**
182
     * Método que copia directamente el recurso solicitado a la carpeta pública
183
     * @return Template
184
     */
185 1
    private function addResourceFunction()
186
    {
187 1
        return $this->addTemplateFunction("resource", TemplateFunctions::RESOURCE_FUNCTION);
188
    }
189
190
    /**
191
     * @return Template
192
     */
193 1
    private function addSessionFunction()
194
    {
195 1
        return $this->addTemplateFunction("session", TemplateFunctions::SESSION_FUNCTION);
196
    }
197
198
    /**
199
     * @return Template
200
     */
201 1
    private function addExistsFlashFunction()
202
    {
203 1
        return $this->addTemplateFunction("existsFlash", TemplateFunctions::EXISTS_FLASH_FUNCTION);
204
    }
205
206
    /**
207
     * @return Template
208
     */
209 1
    private function addGetFlashFunction()
210
    {
211 1
        return $this->addTemplateFunction("getFlash", TemplateFunctions::GET_FLASH_FUNCTION);
212
    }
213
214
    /**
215
     * Servicio que regenera todas las plantillas
216
     * @return array
217
     */
218
    public function regenerateTemplates()
219
    {
220
        $this->generateTemplatesCache();
221
        $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 127 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...
222
        $translations = [];
223
        if (is_array($domains)) {
224
            $translations = $this->parsePathTranslations($domains);
225
        }
226
        $translations[] = _("Plantillas regeneradas correctamente");
227
        return $translations;
228
    }
229
230
    /**
231
     * @param $tplDir
232
     * @param string $domain
233
     *
234
     * @return mixed
235
     */
236
    protected function generateTemplate($tplDir, $domain = '')
237
    {
238
        $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...
239
        foreach ($templatesDir as $file) {
240
            // force compilation
241
            if ($file->isFile()) {
242
                try {
243
                    $this->tpl->load(str_replace($tplDir . '/', '', $file));
244
                } catch (\Exception $e) {
245
                    Logger::log($e->getMessage(), LOG_ERR, ['file' => $e->getFile(), 'line' => $e->getLine()]);
246
                }
247
            }
248
        }
249
        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...
250
    }
251
252
    /**
253
     * Método que extrae el path de un string
254
     * @param $path
255
     *
256
     * @return string
257
     */
258
    public static function extractPath($path)
259
    {
260
        $explodePath = explode(DIRECTORY_SEPARATOR, $path);
261
        $realPath = array();
262
        for ($i = 0, $parts = count($explodePath) - 1; $i < $parts; $i++) {
263
            $realPath[] = $explodePath[$i];
264
        }
265
        return implode(DIRECTORY_SEPARATOR, $realPath);
266
    }
267
268
    /**
269
     * Método que devuelve los dominios de una plataforma
270
     * @param bool $append
271
     * @return array
272
     */
273
    static public function getDomains($append = false)
274
    {
275
        $domains = Router::getInstance()->getDomains();
276
        if ($append) {
277
            foreach ($domains as &$domain) {
278
                foreach ($domain as &$path) {
279
                    $path .= DIRECTORY_SEPARATOR;
280
                }
281
            }
282
        }
283
        return $domains;
284
    }
285
286
    /**
287
     * Método que añade todas las funciones de las plantillas
288
     */
289 1
    private function addTemplateFunctions()
290
    {
291
        //Asignamos las funciones especiales
292 1
        $this->addAssetFunction()
293 1
            ->addFormsFunction()
294 1
            ->addFormWidgetFunction()
295 1
            ->addFormButtonFunction()
296 1
            ->addConfigFunction()
297 1
            ->addRouteFunction()
298 1
            ->addSessionFunction()
299 1
            ->addExistsFlashFunction()
300 1
            ->addGetFlashFunction()
301 1
            ->addResourceFunction();
302 1
    }
303
304
    /**
305
     * Método que devuelve el motod de plantillas
306
     * @return \Twig_Environment
307
     */
308
    public function getTemplateEngine()
309
    {
310
        return $this->tpl;
311
    }
312
313
    /**
314
     * Method that extract all domains for using them with the templates
315
     */
316 1
    private function loadDomains()
317
    {
318 1
        $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 127 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...
319 1
        if (null !== $domains) {
320 1
            foreach ($domains as $domain => $paths) {
321 1
                $this->addPath($paths['template'], preg_replace('/(@|\/)/', '', $domain));
322 1
            }
323 1
        }
324 1
    }
325
326
    /**
327
     * Método que inicializa el motor de plantillas
328
     */
329 1
    private function setup()
330
    {
331 1
        $loader = new \Twig_Loader_Filesystem(GeneratorHelper::getTemplatePath());
332 1
        $this->tpl = new \Twig_Environment($loader, array(
333 1
            'cache' => CACHE_DIR . DIRECTORY_SEPARATOR . 'twig',
334 1
            'debug' => (bool)$this->debug,
335 1
            'auto_reload' => Config::getParam('twig.auto_reload', TRUE),
336 1
        ));
337 1
        $this->loadDomains();
338 1
    }
339
340
    /**
341
     * Método que inyecta los parseadores
342
     */
343 1
    private function addTemplateTokens()
344
    {
345
        //Añadimos las extensiones de los tags
346 1
        $this->tpl->addTokenParser(new AssetsTokenParser("css"));
347 1
        $this->tpl->addTokenParser(new AssetsTokenParser("js"));
348 1
    }
349
350
    /**
351
     * Método que inyecta las optimizaciones al motor de la plantilla
352
     */
353 1
    private function optimizeTemplates()
354
    {
355
        //Optimizamos
356 1
        $this->tpl->addExtension(new \Twig_Extensions_Extension_I18n());
357 1
    }
358
359
    /**
360
     * Method that extract all path tag for extracting translations
361
     * @param array $domains
362
     *
363
     * @return array
364
     */
365
    private function parsePathTranslations($domains)
366
    {
367
        $translations = array();
368
        if (!empty($domains)) {
369
            foreach ($domains as $domain => $paths) {
370
                if (strlen($domain) && array_key_exists("template", $paths)) {
371
                    $this->addPath($paths["template"], $domain);
372
                    $translations[] = $this->generateTemplate($paths["template"], $domain);
373
                }
374
            }
375
        }
376
377
        return $translations;
378
    }
379
380
    /**
381
     * Method that generate all template caches
382
     */
383
    private function generateTemplatesCache()
384
    {
385
        /** @var \Twig_Loader_Filesystem $loader */
386
        $loader = $this->tpl->getLoader();
387
        $availablePaths = $loader->getPaths();
388
        if (!empty($availablePaths)) {
389
            foreach ($availablePaths as $path) {
390
                $this->generateTemplate($path);
391
            }
392
        }
393
    }
394
}
395