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; |