web-base/Core/Elements/TemplateDocument.class.php

147 lines
4.7 KiB
PHP
Raw Normal View History

2021-12-08 16:53:43 +01:00
<?php
2022-11-18 18:06:46 +01:00
namespace Core\Elements;
2021-12-08 16:53:43 +01:00
2022-11-18 18:06:46 +01:00
use Core\Objects\CustomTwigFunctions;
use Core\Objects\Router\DocumentRoute;
use Core\Objects\Router\Router;
use Core\Objects\Search\Searchable;
use Core\Objects\Search\SearchQuery;
use Core\Objects\Search\SearchResult;
2021-12-08 16:53:43 +01:00
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
use Twig\Loader\FilesystemLoader;
class TemplateDocument extends Document {
private string $templateName;
protected array $parameters;
private Environment $twigEnvironment;
private FilesystemLoader $twigLoader;
2022-02-20 16:53:26 +01:00
protected string $title;
2021-12-08 16:53:43 +01:00
2023-01-15 00:32:17 +01:00
private static function getTemplatePaths(): array {
return [
implode(DIRECTORY_SEPARATOR, [WEBROOT, 'Site', 'Templates']),
implode(DIRECTORY_SEPARATOR, [WEBROOT, 'Core', 'Templates']),
];
}
private static function getTemplatePath(string $templateName): ?string {
foreach (self::getTemplatePaths() as $path) {
$filePath = implode(DIRECTORY_SEPARATOR, [$path, $templateName]);
if (is_file($filePath)) {
return $filePath;
}
}
return null;
}
2022-06-01 12:28:50 +02:00
public function __construct(Router $router, string $templateName, array $params = []) {
parent::__construct($router);
2022-08-20 22:17:17 +02:00
$this->title = "Untitled Document";
2021-12-08 16:53:43 +01:00
$this->templateName = $templateName;
2022-05-31 16:14:49 +02:00
$this->parameters = $params;
2023-01-15 00:32:17 +01:00
$this->twigLoader = new FilesystemLoader(self::getTemplatePaths());
2021-12-08 16:53:43 +01:00
$this->twigEnvironment = new Environment($this->twigLoader, [
2022-12-04 13:21:40 +01:00
'cache' => WEBROOT . '/Site/Cache/Templates/',
2021-12-08 16:53:43 +01:00
'auto_reload' => true
]);
2022-08-20 22:17:17 +02:00
$this->twigEnvironment->addExtension(new CustomTwigFunctions());
}
public function getTitle(): string {
return $this->title;
2021-12-08 16:53:43 +01:00
}
protected function getTemplateName(): string {
return $this->templateName;
}
protected function loadParameters() {
}
2022-08-20 22:17:17 +02:00
protected function setTemplate(string $file) {
$this->templateName = $file;
}
2022-05-31 16:14:49 +02:00
public function getCode(array $params = []): string {
2021-12-08 16:53:43 +01:00
$this->loadParameters();
return $this->renderTemplate($this->templateName, $this->parameters);
}
public function renderTemplate(string $name, array $params = []): string {
try {
2022-06-20 19:52:31 +02:00
$context = $this->getContext();
$session = $context->getSession();
2022-06-01 12:28:50 +02:00
$settings = $this->getSettings();
2022-08-20 22:17:17 +02:00
$language = $context->getLanguage();
2024-04-23 14:05:29 +02:00
$captchaProvider = $settings->getCaptchaProvider();
2022-08-20 22:17:17 +02:00
$urlParts = parse_url($this->getRouter()->getRequestedUri());
$params = array_replace_recursive([
"user" => [
"lang" => $language->getShortCode(),
"loggedIn" => $session !== null,
"session" => ($session ? [
"csrfToken" => $session->getCsrfToken()
] : null)
2021-12-08 16:53:43 +01:00
],
2022-08-20 22:17:17 +02:00
"site" => [
"name" => $settings->getSiteName(),
"url" => [
"base" => $settings->getBaseUrl(),
"path" => $urlParts["path"],
"query" => $urlParts["query"] ?? "",
"fragment" => $urlParts["fragment"] ?? ""
],
"lastModified" => date(L('general.date_time_format'), @filemtime(self::getTemplatePath($name))),
2022-08-20 22:17:17 +02:00
"registrationEnabled" => $settings->isRegistrationAllowed(),
"title" => $this->title,
2024-04-23 14:05:29 +02:00
"captcha" => [
"provider" => $captchaProvider?->getName(),
"site_key" => $captchaProvider?->getSiteKey(),
"enabled" => $captchaProvider !== null,
2022-08-20 22:17:17 +02:00
],
"csp" => [
"nonce" => $this->getCSPNonce(),
"enabled" => $this->isCSPEnabled()
2022-11-30 16:42:24 +01:00
],
"language" => [
"code" => $language->getCode(),
"shortCode" => $language->getShortCode(),
"name" => $language->getName(),
"entries" => $language->getEntries()
2022-08-20 22:17:17 +02:00
]
2021-12-08 16:53:43 +01:00
]
2022-08-20 22:17:17 +02:00
], $params);
2021-12-08 16:53:43 +01:00
return $this->twigEnvironment->render($name, $params);
} catch (LoaderError | RuntimeError | SyntaxError $e) {
return "<b>Error rendering twig template: " . htmlspecialchars($e->getMessage()) . "</b>";
}
}
2022-08-20 22:17:17 +02:00
protected function loadView(string $class): array {
$view = new $class($this);
$view->loadParameters($this->parameters);
if ($view->getTitle()) {
$this->title = $view->getTitle();
}
return $this->parameters;
}
public function doSearch(SearchQuery $query, DocumentRoute $route): array {
$this->loadParameters();
$viewParams = $this->parameters["view"] ?? [];
$siteTitle = $this->parameters["site"]["title"] ?? $this->title;
$results = Searchable::searchArray($viewParams, $query);
return array_map(function ($res) use ($siteTitle, $route) {
return new SearchResult($route->getUrl(), $siteTitle, $res["text"]);
}, $results);
}
2021-12-08 16:53:43 +01:00
}