Passed
Push — master ( 43cce1...1a30b3 )
by Fran
02:56
created

Template::addTemplateFunctions()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 16
nc 2
nop 0
dl 0
loc 20
ccs 18
cts 18
cp 1
crap 2
rs 9.7333
c 0
b 0
f 0
1
<?php
2
3
namespace PSFS\base;
4
5
use PSFS\base\config\Config;
6
use PSFS\base\extension\AssetsTokenParser;
7
use PSFS\base\extension\CustomTranslateExtension;
8
use PSFS\base\extension\TemplateFunctions;
9
use PSFS\base\types\helpers\GeneratorHelper;
10
use PSFS\base\types\helpers\ResponseHelper;
11
use PSFS\base\types\traits\OutputTrait;
12
use PSFS\base\types\traits\RouteTrait;
13
use PSFS\base\types\traits\SingletonTrait;
14
use Twig\Environment;
15
use Twig\Loader\FilesystemLoader;
16
use Twig\TwigFunction;
17
18
/**
19
 * Class Template
20
 * @package PSFS\base
21
 */
22
class Template
23
{
24
    use SingletonTrait;
25
    use OutputTrait;
26
    use RouteTrait;
27
28
    const STATUS_OK = 'HTTP/1.0 200 OK';
29
    /**
30
     * @var \Twig\Environment tpl
31
     */
32
    protected $tpl;
33
    protected $filters = array();
34
35
    /**
36
     * Constructor por defecto
37
     */
38 1
    public function __construct()
39
    {
40 1
        $this->setup();
41 1
        $this->addTemplateFunctions();
42 1
        $this->addTemplateTokens();
43 1
        $this->optimizeTemplates();
44
    }
45
46
    /**
47
     * Método que devuelve el loader del Template
48
     * @return \Twig\Loader\LoaderInterface
49
     */
50 1
    public function getLoader()
51
    {
52 1
        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 1
    public function setPublicZone($public = true)
62
    {
63 1
        $this->public_zone = $public;
64 1
        return $this;
65
    }
66
67
    /**
68
     * @return bool
69
     */
70 1
    public function isPublicZone()
71
    {
72 1
        return $this->public_zone;
73
    }
74
75
    /**
76
     * @param string $tpl
77
     * @param array $vars
78
     * @param array $cookies
79
     * @return string HTML
80
     * @throws exception\GeneratorException
81
     */
82 1
    public function render($tpl, array $vars = array(), array $cookies = array())
83
    {
84 1
        Logger::log('Start render response');
85 1
        $vars = ResponseHelper::setDebugHeaders($vars);
86 1
        $output = $this->dump($tpl, $vars);
87
88 1
        return $this->output($output, 'text/html', $cookies);
89
    }
90
91
    /**
92
     * Método que añade una nueva ruta al path de Twig
93
     * @param $path
94
     * @param $domain
95
     *
96
     * @return Template
97
     */
98 2
    public function addPath($path, $domain = '')
99
    {
100 2
        if (file_exists($path)) {
101 2
            $this->tpl->getLoader()->addPath($path, $domain);
0 ignored issues
show
Bug introduced by
The method addPath() does not exist on Twig\Loader\LoaderInterface. It seems like you code against a sub-type of Twig\Loader\LoaderInterface such as Twig\Loader\FilesystemLoader. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

101
            $this->tpl->getLoader()->/** @scrutinizer ignore-call */ addPath($path, $domain);
Loading history...
102
        }
103 2
        return $this;
104
    }
105
106
    /**
107
     * Método que devuelve el contenido de una plantilla
108
     * @param string $tpl
109
     * @param array $vars
110
     * @return string
111
     */
112 5
    public function dump($tpl, array $vars = array())
113
    {
114 5
        $vars['__user__'] = Security::getInstance()->getUser();
115 5
        $vars['__admin__'] = Security::getInstance()->getAdmin();
116 5
        $vars['__profiles__'] = Security::getCleanProfiles();
117 5
        $vars['__flash__'] = Security::getInstance()->getFlashes();
118 5
        $vars['__get__'] = Request::getInstance()->getQueryParams();
119 5
        $vars['__post__'] = Request::getInstance()->getData();
120 5
        $dump = '';
121
        try {
122 5
            $dump = $this->tpl->render($tpl, $vars);
123
        } catch (\Exception $e) {
124
            Logger::log($e->getMessage(), LOG_ERR);
125
        }
126 5
        return $dump;
127
    }
128
129
    /**
130
     * Método que añade una función al motor de plantillas
131
     * @param string $templateFunction
132
     * @param $functionName
133
     *
134
     * @return Template
135
     */
136 1
    protected function addTemplateFunction($templateFunction, $functionName)
137
    {
138 1
        $function = new TwigFunction($templateFunction, $functionName);
139 1
        $this->tpl->addFunction($function);
140 1
        return $this;
141
    }
142
143
    /**
144
     * Servicio que regenera todas las plantillas
145
     * @return array
146
     */
147 1
    public function regenerateTemplates()
148
    {
149 1
        $this->generateTemplatesCache();
150 1
        $domains = Cache::getInstance()->getDataFromFile(CONFIG_DIR . DIRECTORY_SEPARATOR . 'domains.json', Cache::JSON, true);
151 1
        $translations = [];
152 1
        if (is_array($domains)) {
153 1
            $translations = $this->parsePathTranslations($domains);
154
        }
155 1
        $translations[] = t('Plantillas regeneradas correctamente');
156 1
        return $translations;
157
    }
158
159
    /**
160
     * @param $tplDir
161
     * @param string $domain
162
     *
163
     * @return mixed
164
     */
165 1
    protected function generateTemplate($tplDir, $domain = '')
166
    {
167 1
        if (!file_exists($tplDir)) {
168
            return str_replace(array('%s', '%d'), array($tplDir, $domain), t('Path "%s" no existe para el dominio "%d"'));
169
        }
170 1
        $templatesDir = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($tplDir), \RecursiveIteratorIterator::LEAVES_ONLY);
171 1
        foreach ($templatesDir as $file) {
172
            // force compilation
173 1
            if ($file->isFile()) {
174
                try {
175 1
                    $this->tpl->load(str_replace($tplDir . '/', '', $file));
176 1
                } catch (\Exception $e) {
177 1
                    Logger::log($e->getMessage(), LOG_ERR, ['file' => $e->getFile(), 'line' => $e->getLine()]);
178
                }
179
            }
180
        }
181 1
        return str_replace(array('%s', '%d'), array($tplDir, $domain), t('Generando plantillas en path "%s" para el dominio "%d"'));
182
    }
183
184
    /**
185
     * Método que extrae el path de un string
186
     * @param $path
187
     *
188
     * @return string
189
     */
190 1
    public static function extractPath($path)
191
    {
192 1
        $explodePath = explode(DIRECTORY_SEPARATOR, $path);
193 1
        $realPath = array();
194 1
        for ($i = 0, $parts = count($explodePath) - 1; $i < $parts; $i++) {
195 1
            $realPath[] = $explodePath[$i];
196
        }
197 1
        return implode(DIRECTORY_SEPARATOR, $realPath);
198
    }
199
200
    /**
201
     * Método que devuelve los dominios de una plataforma
202
     * @param bool $append
203
     * @return array
204
     */
205 2
    static public function getDomains($append = false)
206
    {
207 2
        $domains = Router::getInstance()->getDomains();
208 2
        if ($append) {
209 2
            foreach ($domains as &$domain) {
210 2
                foreach ($domain as &$path) {
211 2
                    $path .= DIRECTORY_SEPARATOR;
212
                }
213
            }
214
        }
215 2
        return $domains;
216
    }
217
218
    /**
219
     * Método que añade todas las funciones de las plantillas
220
     */
221 1
    private function addTemplateFunctions()
222
    {
223
        //Asignamos las funciones especiales
224 1
        $functions = [
225 1
            'asset' => TemplateFunctions::ASSETS_FUNCTION,
226 1
            'form' => TemplateFunctions::FORM_FUNCTION,
227 1
            'form_widget' => TemplateFunctions::WIDGET_FUNCTION,
228 1
            'form_button' => TemplateFunctions::BUTTON_FUNCTION,
229 1
            'get_config' => TemplateFunctions::CONFIG_FUNCTION,
230 1
            'path' => TemplateFunctions::ROUTE_FUNCTION,
231 1
            'resource' => TemplateFunctions::RESOURCE_FUNCTION,
232 1
            'session' => TemplateFunctions::SESSION_FUNCTION,
233 1
            'existsFlash' => TemplateFunctions::EXISTS_FLASH_FUNCTION,
234 1
            'getFlash' => TemplateFunctions::GET_FLASH_FUNCTION,
235 1
            'getQuery' => TemplateFunctions::GET_QUERY_FUNCTION,
236 1
            'encrypt' => TemplateFunctions::ENCRYPT_FUNCTION,
237 1
            'generate_auth_token' => TemplateFunctions::AUTH_TOKEN_FUNCTION,
238 1
        ];
239 1
        foreach ($functions as $name => $function) {
240 1
            $this->addTemplateFunction($name, $function);
241
        }
242
    }
243
244
    /**
245
     * Método que devuelve el motod de plantillas
246
     * @return \Twig\Environment
247
     */
248 1
    public function getTemplateEngine()
249
    {
250 1
        return $this->tpl;
251
    }
252
253
    /**
254
     * Method that extract all domains for using them with the templates
255
     */
256 1
    private function loadDomains()
257
    {
258 1
        $domains = Cache::getInstance()->getDataFromFile(CONFIG_DIR . DIRECTORY_SEPARATOR . 'domains.json', Cache::JSON, true);
259 1
        if (null !== $domains) {
260
            foreach ($domains as $domain => $paths) {
261
                $this->addPath($paths['template'], preg_replace('/(@|\/)/', '', $domain));
262
            }
263
        }
264
    }
265
266
    /**
267
     * Método que inicializa el motor de plantillas
268
     */
269 1
    private function setup()
270
    {
271 1
        $loader = new FilesystemLoader(GeneratorHelper::getTemplatePath());
272 1
        $this->tpl = new Environment($loader, array(
273 1
            'cache' => CACHE_DIR . DIRECTORY_SEPARATOR . 'twig',
274 1
            'debug' => (bool)$this->debug,
275 1
            'auto_reload' => Config::getParam('twig.autoreload', TRUE),
276 1
        ));
277 1
        $this->loadDomains();
278
    }
279
280
    /**
281
     * Método que inyecta los parseadores
282
     */
283 1
    private function addTemplateTokens()
284
    {
285
        //Añadimos las extensiones de los tags
286 1
        $this->tpl->addTokenParser(new AssetsTokenParser('css'));
287 1
        $this->tpl->addTokenParser(new AssetsTokenParser('js'));
288
    }
289
290
    /**
291
     * Método que inyecta las optimizaciones al motor de la plantilla
292
     */
293 1
    private function optimizeTemplates()
294
    {
295
        //Optimizamos
296 1
        $this->tpl->addExtension(new CustomTranslateExtension());
297
    }
298
299
    /**
300
     * Method that extract all path tag for extracting translations
301
     * @param array $domains
302
     *
303
     * @return array
304
     */
305 1
    private function parsePathTranslations($domains)
306
    {
307 1
        $translations = array();
308 1
        if (!empty($domains)) {
309 1
            foreach ($domains as $domain => $paths) {
310 1
                if (strlen($domain) && array_key_exists('template', $paths)) {
311 1
                    $this->addPath($paths['template'], $domain);
312 1
                    $translations[] = $this->generateTemplate($paths['template'], $domain);
313
                }
314
            }
315
        }
316
317 1
        return $translations;
318
    }
319
320
    /**
321
     * Method that generate all template caches
322
     */
323 1
    private function generateTemplatesCache()
324
    {
325
        /** @var \Twig\Loader\FilesystemLoader $loader */
326 1
        $loader = $this->tpl->getLoader();
327 1
        $availablePaths = $loader->getPaths();
328 1
        if (!empty($availablePaths)) {
329 1
            foreach ($availablePaths as $path) {
330 1
                $this->generateTemplate($path);
331
            }
332
        }
333
    }
334
}
335