diff options
Diffstat (limited to 'src/application/actions/ctheme/get.php')
| -rw-r--r-- | src/application/actions/ctheme/get.php | 75 | 
1 files changed, 75 insertions, 0 deletions
| diff --git a/src/application/actions/ctheme/get.php b/src/application/actions/ctheme/get.php new file mode 100644 index 0000000..f58b0bf --- /dev/null +++ b/src/application/actions/ctheme/get.php @@ -0,0 +1,75 @@ +<?php + +// options +$enableLogging = true; +$etag_strip_gzip_suffix = true; + +$cssFatal = function(string $msg): never { +    if (!headers_sent()) +        http_response_code(500); +    echo "/*!FATAL $msg */\n"; +    exit; +}; +$cssError = function(string &$buffer, string $msg) use($enableLogging): void { +    if ($enableLogging) +        $buffer .= "/*!ERROR $msg */\n"; +}; +$cssWarning = function(string &$buffer, string $msg) use ($enableLogging): void { +    if ($enableLogging) +        $buffer .= "/*!WARN $msg */\n"; +}; + +$buffer = ""; + +header("Content-Type: text/css; charset=UTF-8"); +header("Cache-Control: no-cache"); +// Disable Apache's gzip filter, as it interferes with our ETag +// (Apache adds '-gzip' as a ETag suffix) +if (!$etag_strip_gzip_suffix) +    apache_setenv('no-gzip', '1'); + +$themeName = $_GET["theme"] ?? $_COOKIE["theme"] ?? env("MYSTIC_FORUM_THEME") ?? "default"; +if (!preg_match('/^[a-z0-9_-]+$/i', $themeName)) { +    $cssWarning($buffer, "Invalid theme '" . str_replace('*/', '*\\/', $themeName) . "'"); +    $cssWarning($buffer, "Loading default theme"); +    $themeName = "default"; +} +$themePath = __ROOT__ . '/themes/' . $themeName . '/theme.json'; +$themeDefaultPath = __ROOT__ . '/themes/default/theme.json'; +if (!is_file($themePath) && is_file($themeDefaultPath)) { +    $cssWarning($buffer, "Invalid theme '" . str_replace('*/', '*\\/', $themeName) . "'"); +    $cssWarning($buffer, "Loading default theme"); +    $themePath = $themeDefaultPath; +} elseif (!is_file($themePath) && !is_file($themeDefaultPath)) { +    $cssFatal("Failed to load default theme"); +} +$themeDir = dirname($themePath); +$theme = json_decode(file_get_contents($themePath)); +if ($theme->{'$format'} !== 1) +    $cssFatal("Invalid theme format"); +foreach ($theme->files as $file) { +    if (is_array($file)) { +        if ($enableLogging) $buffer .= "/*!INLINE start */\n"; +        $buffer .= implode("\n", $file); +        if ($enableLogging) $buffer .= "/*!INLINE end */\n"; +    } elseif (is_file($filePath = $themeDir . "/" . $file)) { +        if ($enableLogging) $buffer .= "/*!INCLUDE " . basename($file) . " */\n"; +        $buffer .= file_get_contents($filePath); +        if ($enableLogging) $buffer .= "/*!INCLUDE end */\n"; +    } else +        $cssError($buffer, "Could not include file $file"); +} +$etag = md5($buffer); + +$ifNoneMatch = $_SERVER["HTTP_IF_NONE_MATCH"] ?? null; +if ($ifNoneMatch !== null) { +    $ifNoneMatch = trim($ifNoneMatch, '"'); +    if ($etag_strip_gzip_suffix) +        $ifNoneMatch = preg_replace('/-gzip$/', '', $ifNoneMatch); +} + +header("ETag: \"$etag\""); +if ($ifNoneMatch === $etag) +    http_response_code(304); +else +    echo $buffer; |