Passed
Push — master ( e8f56b...3a2a94 )
by Jean-Christophe
23:12
created

Twig::exists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 2
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Ubiquity\views\engine;
4
5
use Twig\Environment;
6
use Twig\TwigFunction;
7
use Twig\TwigTest;
8
use Twig\Loader\FilesystemLoader;
9
use Ubiquity\cache\CacheManager;
10
use Ubiquity\controllers\Router;
11
use Ubiquity\controllers\Startup;
12
use Ubiquity\core\Framework;
13
use Ubiquity\events\EventsManager;
14
use Ubiquity\events\ViewEvents;
15
use Ubiquity\exceptions\ThemesException;
16
use Ubiquity\translation\TranslatorManager;
17
use Ubiquity\utils\base\UFileSystem;
18
use Ubiquity\themes\ThemesManager;
19
use Ubiquity\assets\AssetsManager;
20
use Ubiquity\domains\DDDManager;
21
22
/**
23
 * Ubiquity Twig template engine.
24
 *
25
 * Ubiquity\views\engine$Twig
26
 * This class is part of Ubiquity
27
 *
28
 * @author jcheron <[email protected]>
29
 * @version 1.0.12
30
 *
31
 */
32
class Twig extends TemplateEngine {
33
	private $twig;
34
	private $loader;
35
	
36 66
	public function __construct($options = []) {
37 66
		$loader = new FilesystemLoader (\ROOT . \DS . 'views' . \DS);
38 66
		$loader->addPath(Startup::getFrameworkDir().\DS .'..'.\DS .'core'.\DS.'views', 'framework');
39 66
		$this->loader = $loader;
40
		
41 66
		if (($options ['cache'] ?? false) === true) {
42
			$options ['cache'] = CacheManager::getCacheSubDirectory('views');
43
		}
44
		
45 66
		$this->twig = new Environment ($loader, $options);
46
		
47 66
		if (isset($options['extensions'])) {
48
			foreach ($options['extensions'] as $ext) {
49
				$this->twig->addExtension(new $ext());
50
			}
51
		}
52
		
53 66
		if (isset ($options ['activeTheme'])) {
54 64
			ThemesManager::setActiveThemeFromTwig($options ['activeTheme']);
55 64
			$this->setTheme($options ['activeTheme'], ThemesManager::THEMES_FOLDER);
56 64
			unset ($options ['activeTheme']);
57
		} else {
58 3
			$this->loader->setPaths([\ROOT . \DS . 'views'], 'activeTheme');
59
		}
60
		
61 66
		$this->addHelpers();
62
	}
63
	
64 66
	protected function addHelpers() {
65 66
		$this->addFunction('path', function ($name, $params = [], $absolute = false) {
66 2
			return Router::path($name, $params, $absolute);
67
		});
68
			
69 66
		$this->addFunction('url', function ($name, $params = []) {
70
			return Router::url($name, $params);
71
		});
72
				
73 66
		if (\class_exists('\\Ubiquity\\security\\csrf\\UCsrfHttp')) {
74
			$this->addFunction('csrfMeta', function ($name) {
75
				return \Ubiquity\security\csrf\UCsrfHttp::getTokenMeta($name);
76
			}, true);
77
				$this->addFunction('csrf', function ($name) {
78
					return \Ubiquity\security\csrf\UCsrfHttp::getTokenField($name);
79
				}, true);
80
		}
81
		
82 66
		if (\class_exists('\\Ubiquity\security\\acl\\AclManager')) {
83
			$this->addFunction('isAllowedRoute', function ($role, $routeName) {
84
				return \Ubiquity\security\acl\AclManager::isAllowedRoute($role, $routeName);
85
			}, true);
86
		}
87
		
88 66
		$this->addFunction('css', function ($resource, $parameters = [], $absolute = false) {
89 18
			if ($this->hasThemeResource($resource)) {
90 18
				return AssetsManager::css_($resource, $parameters, $absolute);
91
			}
92
			return AssetsManager::css($resource, $parameters, $absolute);
93
		}, true);
94
			
95 66
		$this->addFunction('js', function ($resource, $parameters = [], $absolute = false) {
96 1
			if ($this->hasThemeResource($resource)) {
97 1
				return AssetsManager::js_($resource, $parameters, $absolute);
98
			}
99
			return AssetsManager::js($resource, $parameters, $absolute);
100
		}, true);
101
		
102 66
		$this->addFunction('img', function ($resource, $parameters = [], $absolute = false) {
103
			if ($this->hasThemeResource($resource)) {
104
				return AssetsManager::img_($resource, $parameters, $absolute);
105
			}
106
			return AssetsManager::img($resource, $parameters, $absolute);
107
		}, true);
108
			
109 66
		$t = new TwigFunction ('t', function ($context, $id, array $parameters = array(), $domain = null, $locale = null) {
110 1
			$trans = TranslatorManager::trans($id, $parameters, $domain, $locale);
111 1
			return $this->twig->createTemplate($trans)->render($context);
112 66
		}, ['needs_context' => true]);
113
			
114 66
		$tc = new TwigFunction ('tc', function ($context, $id, array $choice, array $parameters = array(), $domain = null, $locale = null) {
115 1
			$trans = TranslatorManager::transChoice($id, $choice, $parameters, $domain, $locale);
116 1
			return $this->twig->createTemplate($trans)->render($context);
117 66
		}, ['needs_context' => true]);
118 66
		$this->twig->addFunction($t);
119 66
		$this->twig->addFunction($tc);
120
		
121 66
		$test = new TwigTest ('instanceOf', function ($var, $class) {
122
			return $var instanceof $class;
123
		});
124 66
		$this->twig->addTest($test);
125 66
		$this->twig->addGlobal('app', new Framework ());
126
	}
127
	
128 18
	protected function hasThemeResource(&$resource) {
129 18
		$resource = \str_replace('@activeTheme/', '', $resource, $count);
130 18
		return $count > 0;
131
	}
132
	
133 66
	protected function addFunction($name, $callback, $safe = false) {
134 66
		$options = ($safe) ? ['is_safe' => ['html']] : [];
135 66
		$this->twig->addFunction(new TwigFunction ($name, $callback, $options));
136
	}
137
	
138
	/*
139
	 * (non-PHPdoc)
140
	 * @see TemplateEngine::render()
141
	 */
142 31
	public function render($viewName, $pData, $asString) {
143 31
		$pData ['config'] = Startup::getConfig();
144 31
		EventsManager::trigger(ViewEvents::BEFORE_RENDER, $viewName, $pData);
145 31
		$render = $this->twig->render($viewName, $pData);
146 31
		EventsManager::trigger(ViewEvents::AFTER_RENDER, $render, $viewName, $pData);
147 31
		if ($asString) {
148 6
			return $render;
149
		} else {
150 31
			echo $render;
151
		}
152
	}
153
	
154
	/**
155
	 *
156
	 * {@inheritdoc}
157
	 * @see \Ubiquity\views\engine\TemplateEngine::getBlockNames()
158
	 */
159
	public function getBlockNames($templateName) {
160
		try {
161
			$result = $this->twig->load($templateName)->getBlockNames();
162
		} catch (\Error $e) {
163
			$result = [];
164
		}
165
		return $result;
166
	}
167
	
168
	/**
169
	 *
170
	 * {@inheritdoc}
171
	 * @see \Ubiquity\views\engine\TemplateEngine::getCode()
172
	 */
173 3
	public function getCode($templateName) {
174 3
		return UFileSystem::load($this->twig->load($templateName)->getSourceContext()->getPath());
175
	}
176
	
177
	/**
178
	 * Adds a new path in a namespace
179
	 *
180
	 * @param string $path The path to add
181
	 * @param string $namespace The namespace to use
182
	 */
183 17
	public function addPath(string $path, string $namespace) {
184 17
		$this->loader->addPath($path, $namespace);
185
	}
186
187
	/**
188
	 * Sets a path in a namespace
189
	 *
190
	 * @param array $paths The paths to add
191
	 * @param string $namespace The namespace to use
192
	 */
193
	public function setPaths(array $paths, string $namespace) {
194
		$this->loader->setPaths($paths, $namespace);
195
	}
196
	
197
	/**
198
	 * Defines the activeTheme.
199
	 * **activeTheme** namespace is @activeTheme
200
	 *
201
	 * @param string $theme
202
	 * @param string $themeFolder
203
	 * @throws ThemesException
204
	 */
205 64
	public function setTheme($theme, $themeFolder = ThemesManager::THEMES_FOLDER) {
206 64
		$root=DDDManager::getActiveViewFolder();
207 64
		$path = $root . $themeFolder . \DS . $theme;
208 64
		if ($theme == '') {
209
			$path = $root;
210
		}
211 64
		if (\file_exists($path)) {
212 64
			$this->loader->setPaths([$path], 'activeTheme');
213
		} else {
214
			throw new ThemesException (sprintf('The path `%s` does not exists!', $path));
215
		}
216
	}
217
	
218
	/**
219
	 * Checks if we have the source code of a template, given its name.
220
	 *
221
	 * @param string $name
222
	 * @return boolean
223
	 */
224 1
	public function exists($name) {
225 1
		return $this->twig->getLoader()->exists($name);
226
	}
227
}
228