Test Failed
Pull Request — master (#313)
by Jean-Christophe
28:33
created

Twig   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 148
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 19
eloc 58
dl 0
loc 148
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A addFilter() 0 2 1
A setTheme() 0 4 1
A exists() 0 2 1
A getBlockNames() 0 7 2
A addExtension() 0 2 1
A __construct() 0 26 5
A render() 0 9 2
A addPath() 0 2 1
A getCode() 0 2 1
A addFunction() 0 2 1
A setPaths() 0 2 1
A addFunctions() 0 19 1
A getGenerator() 0 2 1
1
<?php
2
3
namespace Ubiquity\views\engine\twig;
4
5
use Twig\Environment;
6
use Twig\Loader\FilesystemLoader;
7
use Twig\TwigFilter;
8
use Twig\TwigFunction;
9
use Twig\TwigTest;
10
use Ubiquity\cache\CacheManager;
11
use Ubiquity\controllers\Startup;
12
use Ubiquity\events\EventsManager;
13
use Ubiquity\events\ViewEvents;
14
use Ubiquity\exceptions\ThemesException;
15
use Ubiquity\themes\ThemesManager;
16
use Ubiquity\translation\TranslatorManager;
17
use Ubiquity\utils\base\UFileSystem;
18
use Ubiquity\views\engine\TemplateEngine;
19
use Ubiquity\views\engine\TemplateGenerator;
20
21
/**
22
 * Ubiquity Twig template engine.
23
 *
24
 * Ubiquity\views\engine$Twig
25
 * This class is part of Ubiquity
26
 *
27
 * @author jcheron <[email protected]>
28
 * @version 1.0.13
29
 *
30
 */
31
class Twig extends TemplateEngine {
32
	private $twig;
33
	private $loader;
34
35
	public function __construct($options = []) {
36
		$loader = new FilesystemLoader (\ROOT . \DS . 'views' . \DS);
37
		$loader->addPath(Startup::getFrameworkDir() . '/../core/views/engines/twig', 'framework');
38
		$this->loader = $loader;
39
40
		if (($options ['cache'] ?? false) === true) {
41
			$options ['cache'] = CacheManager::getCacheSubDirectory('views');
42
		}
43
44
		$this->twig = new Environment ($loader, $options);
45
46
		if (isset($options['extensions'])) {
47
			foreach ($options['extensions'] as $ext) {
48
				$this->twig->addExtension(new $ext());
49
			}
50
		}
51
52
		if (isset ($options ['activeTheme'])) {
53
			ThemesManager::setActiveThemeFromTwig($options ['activeTheme']);
54
			$this->setTheme($options ['activeTheme'], ThemesManager::THEMES_FOLDER);
55
			unset ($options ['activeTheme']);
56
		} else {
57
			$this->loader->setPaths([\ROOT . \DS . 'views'], 'activeTheme');
58
		}
59
60
		$this->addFunctions();
61
	}
62
63
	protected function addFunctions(): void {
64
		parent::addFunctions();
65
		$t = new TwigFunction ('t', function ($context, $id, array $parameters = array(), $domain = null, $locale = null) {
66
			$trans = TranslatorManager::trans($id, $parameters, $domain, $locale);
67
			return $this->twig->createTemplate($trans)->render($context);
68
		}, ['needs_context' => true]);
69
70
		$tc = new TwigFunction ('tc', function ($context, $id, array $choice, array $parameters = array(), $domain = null, $locale = null) {
71
			$trans = TranslatorManager::transChoice($id, $choice, $parameters, $domain, $locale);
72
			return $this->twig->createTemplate($trans)->render($context);
73
		}, ['needs_context' => true]);
74
		$this->twig->addFunction($t);
75
		$this->twig->addFunction($tc);
76
77
		$test = new TwigTest ('instanceOf', function ($var, $class) {
78
			return $var instanceof $class;
79
		});
80
		$this->twig->addTest($test);
81
		$this->twig->addGlobal('app', $this->fw);
82
	}
83
84
	public function addFunction(string $name, $callback, array $options = []): void {
85
		$this->twig->addFunction(new TwigFunction ($name, $callback, $options));
86
	}
87
88
	protected function addFilter(string $name, $callback, array $options = []): void {
89
		$this->twig->addFilter(new TwigFilter($name, $callback, $options));
90
	}
91
92
	protected function addExtension($extension): void {
93
		$this->twig->addExtension($extension);
94
	}
95
96
	/*
97
	 * (non-PHPdoc)
98
	 * @see TemplateEngine::render()
99
	 */
100
	public function render(string $viewName, ?array $pData = [], bool $asString = false) {
101
		$pData ['config'] = Startup::getConfig();
102
		EventsManager::trigger(ViewEvents::BEFORE_RENDER, $viewName, $pData);
103
		$render = $this->twig->render($viewName, $pData);
104
		EventsManager::trigger(ViewEvents::AFTER_RENDER, $render, $viewName, $pData);
105
		if ($asString) {
106
			return $render;
107
		} else {
108
			echo $render;
109
		}
110
	}
111
112
	/**
113
	 *
114
	 * {@inheritdoc}
115
	 * @see \Ubiquity\views\engine\TemplateEngine::getBlockNames()
116
	 */
117
	public function getBlockNames(string $templateName): array {
118
		try {
119
			$result = $this->twig->load($templateName)->getBlockNames();
120
		} catch (\Error $e) {
121
			$result = [];
122
		}
123
		return $result;
124
	}
125
126
	/**
127
	 *
128
	 * {@inheritdoc}
129
	 * @see \Ubiquity\views\engine\TemplateEngine::getCode()
130
	 */
131
	public function getCode(string $templateName): string {
132
		return UFileSystem::load($this->twig->load($templateName)->getSourceContext()->getPath());
0 ignored issues
show
Bug Best Practice introduced by
The expression return Ubiquity\utils\ba...ceContext()->getPath()) could return the type false which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
133
	}
134
135
	/**
136
	 * Adds a new path in a namespace
137
	 *
138
	 * @param string $path The path to add
139
	 * @param string $namespace The namespace to use
140
	 */
141
	public function addPath(string $path, string $namespace) {
142
		$this->loader->addPath($path, $namespace);
143
	}
144
145
	/**
146
	 * Sets a path in a namespace
147
	 *
148
	 * @param array $paths The paths to add
149
	 * @param string $namespace The namespace to use
150
	 */
151
	public function setPaths(array $paths, string $namespace) {
152
		$this->loader->setPaths($paths, $namespace);
153
	}
154
155
	/**
156
	 * @param string $theme
157
	 * @param string $themeFolder
158
	 * @return string|void
159
	 * @throws ThemesException
160
	 */
161
	public function setTheme(string $theme, string $themeFolder = ThemesManager::THEMES_FOLDER): string {
162
		$path = parent::setTheme($theme, $themeFolder);
163
		$this->loader->setPaths([$path], 'activeTheme');
164
		return $path;
165
	}
166
167
	/**
168
	 * Checks if we have the source code of a template, given its name.
169
	 *
170
	 * @param string $name
171
	 * @return boolean
172
	 */
173
	public function exists(string $name): bool {
174
		return $this->twig->getLoader()->exists($name);
175
	}
176
177
	public function getGenerator(): ?TemplateGenerator {
178
		return null;
179
	}
180
181
}
182