Test Failed
Push — master ( fc5a43...510786 )
by Fran
04:03
created

Template   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 378
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 15

Test Coverage

Coverage 27.15%

Importance

Changes 0
Metric Value
dl 0
loc 378
ccs 41
cts 151
cp 0.2715
rs 7.4918
c 0
b 0
f 0
wmc 46
lcom 1
cbo 15

29 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A getLoader() 0 4 1
A setPublicZone() 0 5 1
A render() 0 8 1
A addPath() 0 5 1
A dump() 0 14 2
A addTemplateFunction() 0 6 1
A addAssetFunction() 0 4 1
A addFormsFunction() 0 4 1
A addFormWidgetFunction() 0 4 1
A addFormButtonFunction() 0 4 1
A addConfigFunction() 0 4 1
A addRouteFunction() 0 4 1
A addResourceFunction() 0 4 1
A addSessionFunction() 0 4 1
A addExistsFlashFunction() 0 4 1
A addGetFlashFunction() 0 4 1
A regenerateTemplates() 0 11 2
A generateTemplate() 0 15 4
A extractPath() 0 9 2
A getDomains() 0 12 4
A addTemplateFunctions() 0 14 1
A getTemplateEngine() 0 4 1
A loadDomains() 0 9 3
A setup() 0 10 1
A addTemplateTokens() 0 6 1
A optimizeTemplates() 0 5 1
B parsePathTranslations() 0 14 5
A generateTemplatesCache() 0 11 3

How to fix   Complexity   

Complex Class

Complex classes like Template often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Template, and based on these observations, apply Extract Interface, too.

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
    public function __construct()
33
    {
34
        $this->setup();
35
        $this->addTemplateFunctions();
36
        $this->addTemplateTokens();
37 1
        $this->optimizeTemplates();
38
    }
39 1
40 1
    /**
41 1
     * Método que devuelve el loader del Template
42 1
     * @return \Twig_LoaderInterface
43 1
     */
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
    public function render($tpl, array $vars = array(), array $cookies = array())
71
    {
72
        Logger::log('Start render response');
73
        $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
    public function addPath($path, $domain = '')
87
    {
88
        $this->tpl->getLoader()->addPath($path, $domain);
89
        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 1
        } catch (\Exception $e) {
108
            Logger::log($e->getMessage(), LOG_ERR);
109 1
        }
110 1
        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
    protected function addTemplateFunction($templateFunction, $functionName)
121 1
    {
122
        $function = new \Twig_SimpleFunction($templateFunction, $functionName);
123
        $this->tpl->addFunction($function);
124
        return $this;
125
    }
126 1
127 1
    /**
128 1
     * Funcion Twig para los assets en las plantillas
129 1
     * @return Template
130
     */
131
    private function addAssetFunction()
132
    {
133
        return $this->addTemplateFunction("asset", TemplateFunctions::ASSETS_FUNCTION);
134
    }
135
136
    /**
137
     * Función que pinta un formulario
138
     * @return Template
139
     */
140
    private function addFormsFunction()
141
    {
142
        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
    private function addFormWidgetFunction()
150
    {
151
        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
    private function addFormButtonFunction()
159
    {
160
        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
    private function addConfigFunction()
168
    {
169
        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
    private function addRouteFunction()
177
    {
178
        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
    private function addResourceFunction()
186
    {
187
        return $this->addTemplateFunction("resource", TemplateFunctions::RESOURCE_FUNCTION);
188
    }
189
190
    /**
191
     * @return Template
192
     */
193
    private function addSessionFunction()
194
    {
195
        return $this->addTemplateFunction("session", TemplateFunctions::SESSION_FUNCTION);
196
    }
197
198
    /**
199
     * @return Template
200
     */
201
    private function addExistsFlashFunction()
202
    {
203
        return $this->addTemplateFunction("existsFlash", TemplateFunctions::EXISTS_FLASH_FUNCTION);
204
    }
205
206 1
    /**
207
     * @return Template
208 1
     */
209 1
    private function addGetFlashFunction()
210
    {
211
        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 1
            // force compilation
241
            if ($file->isFile()) {
242 1
                try {
243 1
                    $this->tpl->load(str_replace($tplDir . '/', '', $file));
244 1
                } 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 1
252
    /**
253 1
     * 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 1
        $explodePath = explode(DIRECTORY_SEPARATOR, $path);
261
        $realPath = array();
262 1
        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 1
     * Método que devuelve los dominios de una plataforma
270
     * @param bool $append
271 1
     * @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 1
                foreach ($domain as &$path) {
279
                    $path .= DIRECTORY_SEPARATOR;
280 1
                }
281
            }
282
        }
283
        return $domains;
284
    }
285
286
    /**
287 1
     * Método que añade todas las funciones de las plantillas
288
     */
289 1
    private function addTemplateFunctions()
290
    {
291
        //Asignamos las funciones especiales
292
        $this->addAssetFunction()
293
            ->addFormsFunction()
294
            ->addFormWidgetFunction()
295
            ->addFormButtonFunction()
296 1
            ->addConfigFunction()
297
            ->addRouteFunction()
298 1
            ->addSessionFunction()
299
            ->addExistsFlashFunction()
300
            ->addGetFlashFunction()
301
            ->addResourceFunction();
302
    }
303
304
    /**
305 1
     * Método que devuelve el motod de plantillas
306
     * @return \Twig_Environment
307 1
     */
308
    public function getTemplateEngine()
309
    {
310
        return $this->tpl;
311
    }
312
313 1
    /**
314
     * Method that extract all domains for using them with the templates
315 1
     */
316
    private function loadDomains()
317
    {
318
        $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
        if (null !== $domains) {
320
            foreach ($domains as $domain => $paths) {
321 1
                $this->addPath($paths['template'], preg_replace('/(@|\/)/', '', $domain));
322
            }
323 1
        }
324
    }
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
        $this->tpl = new \Twig_Environment($loader, array(
333
            'cache' => CACHE_DIR . DIRECTORY_SEPARATOR . 'twig',
334
            'debug' => (bool)$this->debug,
335
            'auto_reload' => Config::getParam('twig.auto_reload', TRUE),
336
        ));
337
        $this->loadDomains();
338
    }
339
340
    /**
341
     * Método que inyecta los parseadores
342
     */
343
    private function addTemplateTokens()
344
    {
345
        //Añadimos las extensiones de los tags
346
        $this->tpl->addTokenParser(new AssetsTokenParser("css"));
347
        $this->tpl->addTokenParser(new AssetsTokenParser("js"));
348
    }
349
350
    /**
351
     * Método que inyecta las optimizaciones al motor de la plantilla
352
     */
353
    private function optimizeTemplates()
354
    {
355
        //Optimizamos
356
        $this->tpl->addExtension(new \Twig_Extensions_Extension_I18n());
357
    }
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