summaryrefslogtreecommitdiff
path: root/src/application/actions/ctheme/get.php
blob: f58b0bfcf6ab18b93c4e8b64cfcb3af203dd78d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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;