xref: /template/mikio/css.php (revision 8e1564a6729d1aff3eface1dde3a6b6ebf867777)
1<?php
2/**
3 * Mikio CSS/LESS Engine
4 *
5 * @link    http://dokuwiki.org/template:mikio
6 * @author  James Collins <james.collins@outlook.com.au>
7 * @license GPLv2 (http://www.gnu.org/licenses/gpl-2.0.html)
8 */
9
10if(!function_exists('getallheaders')) {
11	function getallheaders() {
12		$headers = [];
13		foreach($_SERVER as $name => $value) {
14			if(substr($name, 0, 5) == 'HTTP_') {
15				$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
16			}
17		}
18		return $headers;
19	}
20}
21
22
23try {
24    $lesscLib = '../../../vendor/marcusschwarz/lesserphp/lessc.inc.php';
25    if(file_exists($lesscLib)) {
26        require_once($lesscLib);
27
28        if(isset($_GET['css'])) {
29            $baseDir = dirname(__FILE__) . '/';
30            $cssFile = realpath($baseDir . $_GET['css']);
31
32            if(strpos($cssFile, $baseDir) === 0 && file_exists($cssFile)) {
33                $lastModified = filemtime($cssFile);
34                $eTagFile = md5_file($cssFile);
35                $eTagHeader = (isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE);
36
37                header('Content-Type: text/css; charset=utf-8');
38                header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
39                header('Etag: ' . $eTagFile);
40                header('Cache-Control: public, max-age=604800, immutable');
41
42                if(@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified || $eTagHeader == $eTagFile) {
43                    header('HTTP/1.1 304 Not Modified');
44                    exit;
45                }
46
47                $css = file_get_contents($cssFile);
48
49                $less = new lessc();
50                $less->setPreserveComments(false);
51
52                if(file_exists('style.ini')) {
53                    $overrideStyle = '../../../conf/tpl/mikio/style.ini';
54
55                    $vars = Array();
56                    $rawVars = parse_ini_file('style.ini', TRUE);
57
58                    if(file_exists($overrideStyle)) {
59                        $userVars = parse_ini_file($overrideStyle, TRUE);
60                        $rawVars = associativeMerge($rawVars, $userVars);
61                    }
62
63                  if(isset($rawVars['replacements'])) {
64                    foreach($rawVars['replacements'] as $key=>$val) {
65                      if(substr($key, 0, 2) == '__' && substr($key, -2) == '__') {
66                        $vars['ini_' . substr($key, 2, -2)] = $val;
67                      }
68                    }
69                  }
70
71                  if(count($vars) > 0) {
72                    $less->setVariables($vars);
73                  }
74                }
75
76                $css = $less->compile($css);
77
78				$accept_encoding = @getallheaders()['Accept-Encoding'];
79     	        if($accept_encoding && preg_match('/ *gzip *,?/', $accept_encoding)) {
80               	    header('Content-Encoding: gzip');
81                		echo gzencode($css);
82            	} else {
83                		echo $css;
84                }
85            } else {
86                header('HTTP/1.1 404 Not Found');
87                echo "The requested file could not be found";
88            }
89        } else {
90            header('HTTP/1.1 404 Not Found');
91            echo "The requested file could not be found";
92        }
93    } else {
94        throw new Exception('Lessc library not found');
95    }
96}
97catch(Exception $e) {
98    header('HTTP/1.500 Internal Server Error');
99    echo $e;
100}
101
102function associativeMerge($base, $addition)
103{
104    $result = $base;
105
106    // if(is_array($base) && is_array($addition)) {
107    //     foreach($addition as $key=>$value) {
108    //         if(is_array($value)) {
109    //             $result[$key] = associativeMerge($result[$key], $value);
110	// 		} else {
111	// 			$result[$key] = $value;
112	// 		}
113    //     }
114    // }
115
116    return $result;
117}
118
119