summaryrefslogtreecommitdiff
path: root/src/application/actions/ctheme
diff options
context:
space:
mode:
Diffstat (limited to 'src/application/actions/ctheme')
-rw-r--r--src/application/actions/ctheme/get.php75
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;