diff options
| author | Jonas Kohl | 2024-10-17 10:56:01 +0200 | 
|---|---|---|
| committer | Jonas Kohl | 2024-10-17 10:56:01 +0200 | 
| commit | fe0f414dc0211a4014581dc03fcfd514ed7ed02d (patch) | |
| tree | cd86fc00cd9b7a97eabb9668e0a39e2b4b3e5357 /src/index.php | |
| parent | e0e89b9fdbf301e0ead944636023947a67aca57d (diff) | |
Transition templating to Twig
Diffstat (limited to 'src/index.php')
| -rw-r--r-- | src/index.php | 104 | 
1 files changed, 76 insertions, 28 deletions
| diff --git a/src/index.php b/src/index.php index 0c5cc3b..2403a9b 100644 --- a/src/index.php +++ b/src/index.php @@ -8,8 +8,13 @@ use mystic\forum\orm\Post;  use mystic\forum\orm\Topic;  use mystic\forum\orm\TopicLogMessage;  use mystic\forum\orm\User; +use mystic\forum\orm\UserPermissions;  use mystic\forum\utils\RequestUtils;  use mystic\forum\utils\StringUtils; +use Twig\Environment; +use Twig\Loader\FilesystemLoader; +use Twig\TwigFilter; +use Twig\TwigFunction;  header_remove("X-Powered-By"); @@ -39,23 +44,17 @@ $_action = $_GET["_action"] ?? null;  $GLOBALS["action"] = $_action;  function msg_error(string $err, bool $skipLoginCheck = false): void { -    _view("template_start", ["_title" => __("Error")]); -    _view("template_navigation_start"); -    if (!$skipLoginCheck) -        _view("template_navigation", ["user" => RequestUtils::getAuthorizedUser($GLOBALS["db"])]); -    _view("template_navigation_end"); -    _view("alert_error", ["message" => $err]); -    _view("template_end", [...getThemeAndLangInfo()]); +    render("error_page.twig", [ +        "message" => $err, +        "skipLoginCheck" => $skipLoginCheck, +    ]);  }  function msg_info(string $msg, bool $skipLoginCheck = false): void { -    _view("template_start", ["_title" => __("Information")]); -    _view("template_navigation_start"); -    if (!$skipLoginCheck) -        _view("template_navigation", ["user" => RequestUtils::getAuthorizedUser($GLOBALS["db"])]); -    _view("template_navigation_end"); -    _view("alert_info", ["message" => $msg]); -    _view("template_end", [...getThemeAndLangInfo()]); +    render("info_page.twig", [ +        "message" => $msg, +        "skipLoginCheck" => $skipLoginCheck, +    ]);  }  function generateCaptchaText(): string { @@ -129,20 +128,6 @@ function getThemeAndLangInfo(): array {      ];  } -function _view(string $___NAME, array $___PARAMS = []): void { -    $___PATH = __DIR__ . "/application/views/" . $___NAME . ".php"; -    if (!is_file($___PATH)) { -        echo "<!--!ERROR Failed to include {" . htmlentities($___NAME) . "}-->\n"; -        echo "<br><p><strong style=\"color:red !important\">Failed to include <em>" . htmlentities($___NAME) . "</em></strong></p><br>\n"; -        echo "<!--/ERROR-->\n"; -    } else { -        extract($___PARAMS); -        echo "<!--{" . htmlentities($___NAME) . "}-->\n"; -        include $___PATH; -        echo "<!--{/" . htmlentities($___NAME) . "}-->\n"; -    } -} -  function isTrue(string $str): bool {      $str = strtolower($str);      return in_array($str, ["yes","true","y","t","on","enabled","1","?1"]); @@ -164,6 +149,69 @@ function reArrayFiles(&$file_post) {      return $file_ary;  } +function render(string $page, array $context = []): void { +    $defaultTemplate = "bootstrap-3"; // bootstrap-3 is the default for backwards compatibility +    $templateDir = __ROOT__ . "/application/templates"; + +    [ +        "availableThemes" => $availableThemes, +        "currentTheme" => $currentTheme, +    ] = getThemeAndLangInfo(); + +    $currentThemeInfo = $availableThemes[$currentTheme] ?? (object)[]; +    $currentTemplate = $currentThemeInfo->template ?? $defaultTemplate; + +    $availableTemplates = array_values(array_filter(scandir($templateDir), function($theme) use ($templateDir) { +        return $theme[0] !== "." && is_dir($templateDir . "/" . $theme); +    })); + +    if (!in_array($currentTemplate, $availableTemplates)) +        $currentTemplate = $defaultTemplate; + +    $loader = new FilesystemLoader([ +        $templateDir . "/" . $currentTemplate, +    ]); +    $twig = new Environment($loader, [ +        // TODO Enable caching +    ]); + +    $twig->addFunction(new TwigFunction("__", __(...), [ "is_safe" => ["html"] ])); +    $twig->addFunction(new TwigFunction("___", ___(...), [ "is_safe" => ["html"] ])); +    $twig->addFunction(new TwigFunction("renderPost", renderPost(...), [ "is_safe" => ["html"] ])); +    $twig->addFunction(new TwigFunction("renderPostSummary", renderPostSummary(...), [ "is_safe" => ["html"] ])); +    $twig->addFunction(new TwigFunction("permission", fn(string $name): int => constant(UserPermissions::class . "::" . $name))); +    $twig->addFunction(new TwigFunction("getAndClearFormError", RequestUtils::getAndClearFormError(...))); +    $twig->addFunction(new TwigFunction("lastFormField", function(string $formId, string $field): ?string { +        $lastFormId = ""; +        $lastForm = RequestUtils::getLastForm($lastFormId) ?? null; +        if ($lastForm === null || $lastFormId !== $formId) +            return null; +        return $lastForm[$field] ?? null; +    })); + +    $twig->addFilter(new TwigFilter("hash", fn(string $data, string $algo, bool $binary = false, array $options = []) => hash($algo, $data, $binary, $options))); +    $twig->addFilter(new TwigFilter("base64_encode", base64_encode(...))); +    $twig->addFilter(new TwigFilter("base64_decode", base64_decode(...))); + +    echo $twig->render($page, [ +        "g" => [ +            "get" => &$_GET, +            "post" => &$_POST, +            "request" => &$_REQUEST, +            "session" => &$_SESSION, +            "cookie" => &$_COOKIE, +            "env" => &$_ENV, +            "server" => &$_SERVER, +            "globals" => $GLOBALS, +        ], +        "ctx" => &$context, + +        "currentUser" => &$GLOBALS["currentUser"], +        ...getThemeAndLangInfo(), +    ]); +    RequestUtils::clearLastForm(); +} +  const TAGS_REGEX = '/\[(b|i|u|s|\\^|_|spoiler)\](.+?)\[\/\1\]/s';  function expandTags(string $contents): string { |