3 declare(strict_types
=1);
7 use PhpMyAdmin\Twig\AssetExtension
;
8 use PhpMyAdmin\Twig\CoreExtension
;
9 use PhpMyAdmin\Twig\Extensions\Node\TransNode
;
10 use PhpMyAdmin\Twig\FlashMessagesExtension
;
11 use PhpMyAdmin\Twig\I18nExtension
;
12 use PhpMyAdmin\Twig\MessageExtension
;
13 use PhpMyAdmin\Twig\RelationExtension
;
14 use PhpMyAdmin\Twig\SanitizeExtension
;
15 use PhpMyAdmin\Twig\TableExtension
;
16 use PhpMyAdmin\Twig\TrackerExtension
;
17 use PhpMyAdmin\Twig\TransformationsExtension
;
18 use PhpMyAdmin\Twig\UrlExtension
;
19 use PhpMyAdmin\Twig\UtilExtension
;
23 use Twig\Error\LoaderError
;
24 use Twig\Error\RuntimeError
;
25 use Twig\Error\SyntaxError
;
26 use Twig\Extension\DebugExtension
;
27 use Twig\Loader\FilesystemLoader
;
28 use Twig\RuntimeLoader\ContainerRuntimeLoader
;
29 use Twig\TemplateWrapper
;
32 use function is_array
;
34 use function trigger_error
;
36 use const E_USER_WARNING
;
39 * Handle front end templating
48 protected static $twig;
50 public const TEMPLATES_FOLDER
= ROOT_PATH
. 'templates';
52 public function __construct()
54 if (static::$twig !== null) {
58 /** @var Config|null $config */
59 $config = $GLOBALS['config'];
60 $cacheDir = $config !== null ?
$config->getTempDir('twig') : null;
62 static::$twig = self
::getTwigEnvironment($cacheDir);
65 public static function getTwigEnvironment(?
string $cacheDir): Environment
67 /* Twig expects false when cache is not configured */
68 if ($cacheDir === null) {
72 $loader = new FilesystemLoader(self
::TEMPLATES_FOLDER
);
73 $twig = new Environment($loader, [
74 'auto_reload' => true,
78 $twig->addRuntimeLoader(new ContainerRuntimeLoader($GLOBALS['containerBuilder']));
80 if (is_array($GLOBALS['cfg']) && ($GLOBALS['cfg']['environment'] ??
'') === 'development') {
82 $twig->addExtension(new DebugExtension());
83 // This will enable debug for the extension to print lines
84 // It is used in po file lines re-mapping
85 TransNode
::$enableAddDebugInfo = true;
88 if ($GLOBALS['cfg']['environment'] === 'production') {
89 $twig->disableDebug();
90 TransNode
::$enableAddDebugInfo = false;
93 $twig->addExtension(new AssetExtension());
94 $twig->addExtension(new CoreExtension());
95 $twig->addExtension(new FlashMessagesExtension());
96 $twig->addExtension(new I18nExtension());
97 $twig->addExtension(new MessageExtension());
98 $twig->addExtension(new RelationExtension());
99 $twig->addExtension(new SanitizeExtension());
100 $twig->addExtension(new TableExtension());
101 $twig->addExtension(new TrackerExtension());
102 $twig->addExtension(new TransformationsExtension());
103 $twig->addExtension(new UrlExtension());
104 $twig->addExtension(new UtilExtension());
112 * @param string $templateName Template path name
114 * @throws LoaderError
115 * @throws RuntimeError
116 * @throws SyntaxError
118 private function load(string $templateName): TemplateWrapper
121 $template = static::$twig->load($templateName . '.twig');
122 } catch (RuntimeException
$e) {
123 /* Retry with disabled cache */
124 static::$twig->setCache(false);
125 $template = static::$twig->load($templateName . '.twig');
127 * The trigger error is intentionally after second load
128 * to avoid triggering error when disabling cache does not
133 __('Error while working with template cache: %s'),
144 * @param string $template Template path name
145 * @param array $data Associative array of template variables
148 * @throws LoaderError
149 * @throws RuntimeError
150 * @throws SyntaxError
152 public function render(string $template, array $data = []): string
154 return $this->load($template)->render($data);