Template.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. declare(strict_types=1);
  3. namespace PhpMyAdmin;
  4. use PhpMyAdmin\Twig\CoreExtension;
  5. use PhpMyAdmin\Twig\I18nExtension;
  6. use PhpMyAdmin\Twig\MessageExtension;
  7. use PhpMyAdmin\Twig\PluginsExtension;
  8. use PhpMyAdmin\Twig\RelationExtension;
  9. use PhpMyAdmin\Twig\SanitizeExtension;
  10. use PhpMyAdmin\Twig\TableExtension;
  11. use PhpMyAdmin\Twig\TrackerExtension;
  12. use PhpMyAdmin\Twig\TransformationsExtension;
  13. use PhpMyAdmin\Twig\UrlExtension;
  14. use PhpMyAdmin\Twig\UtilExtension;
  15. use RuntimeException;
  16. use Throwable;
  17. use Twig\Environment;
  18. use Twig\Error\LoaderError;
  19. use Twig\Error\RuntimeError;
  20. use Twig\Error\SyntaxError;
  21. use Twig\Extension\DebugExtension;
  22. use Twig\Loader\FilesystemLoader;
  23. use Twig\TemplateWrapper;
  24. use const DIRECTORY_SEPARATOR;
  25. use const E_USER_WARNING;
  26. use function sprintf;
  27. use function trigger_error;
  28. use function is_array;
  29. /**
  30. * Handle front end templating
  31. */
  32. class Template
  33. {
  34. /**
  35. * Twig environment
  36. *
  37. * @var Environment
  38. */
  39. protected static $twig;
  40. public const BASE_PATH = ROOT_PATH . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR;
  41. public function __construct()
  42. {
  43. global $cfg;
  44. /** @var Config|null $config */
  45. $config = $GLOBALS['PMA_Config'];
  46. if (static::$twig !== null) {
  47. return;
  48. }
  49. $loader = new FilesystemLoader(self::BASE_PATH);
  50. $cache_dir = $config !== null ? $config->getTempDir('twig') : null;
  51. /* Twig expects false when cache is not configured */
  52. if ($cache_dir === null) {
  53. $cache_dir = false;
  54. }
  55. $twig = new Environment($loader, [
  56. 'auto_reload' => true,
  57. 'cache' => $cache_dir,
  58. ]);
  59. // It was reported that the config could not be loaded correctly
  60. if (is_array($cfg) && $cfg['environment'] === 'development') {
  61. $twig->enableDebug();
  62. $twig->addExtension(new DebugExtension());
  63. }
  64. $twig->addExtension(new CoreExtension());
  65. $twig->addExtension(new I18nExtension());
  66. $twig->addExtension(new MessageExtension());
  67. $twig->addExtension(new PluginsExtension());
  68. $twig->addExtension(new RelationExtension());
  69. $twig->addExtension(new SanitizeExtension());
  70. $twig->addExtension(new TableExtension());
  71. $twig->addExtension(new TrackerExtension());
  72. $twig->addExtension(new TransformationsExtension());
  73. $twig->addExtension(new UrlExtension());
  74. $twig->addExtension(new UtilExtension());
  75. static::$twig = $twig;
  76. }
  77. /**
  78. * Loads a template.
  79. *
  80. * @param string $templateName Template path name
  81. *
  82. * @throws LoaderError
  83. * @throws RuntimeError
  84. * @throws SyntaxError
  85. */
  86. private function load(string $templateName): TemplateWrapper
  87. {
  88. try {
  89. $template = static::$twig->load($templateName . '.twig');
  90. } catch (RuntimeException $e) {
  91. /* Retry with disabled cache */
  92. static::$twig->setCache(false);
  93. $template = static::$twig->load($templateName . '.twig');
  94. /*
  95. * The trigger error is intentionally after second load
  96. * to avoid triggering error when disabling cache does not
  97. * solve it.
  98. */
  99. trigger_error(
  100. sprintf(
  101. __('Error while working with template cache: %s'),
  102. $e->getMessage()
  103. ),
  104. E_USER_WARNING
  105. );
  106. }
  107. return $template;
  108. }
  109. /**
  110. * @param string $template Template path name
  111. * @param array $data Associative array of template variables
  112. *
  113. * @throws Throwable
  114. * @throws LoaderError
  115. * @throws RuntimeError
  116. * @throws SyntaxError
  117. */
  118. public function render(string $template, array $data = []): string
  119. {
  120. return $this->load($template)->render($data);
  121. }
  122. }