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 if(!function_exists('cctype_digit')) { 25 if(isset($_GET['css'])) { 26 $baseDir = dirname(__FILE__) . '/'; 27 $cssFile = realpath($baseDir . $_GET['css']); 28 if(strtolower(substr($cssFile, -5)) == '.less') { 29 $cssFile = substr($cssFile, 0, -5) . '.css'; 30 if(file_exists($cssFile)) { 31 echo file_get_contents($cssFile); 32 exit; 33 } 34 } 35 } 36 37 throw new Exception('ctype extension not installed'); 38 } 39 40 $lesscLib = '../../../vendor/marcusschwarz/lesserphp/lessc.inc.php'; 41 if(!file_exists($lesscLib)) 42 $lesscLib = '../../../../../app/dokuwiki/vendor/marcusschwarz/lesserphp/lessc.inc.php'; 43 44 if(file_exists($lesscLib)) { 45 require_once($lesscLib); 46 47 if(isset($_GET['css'])) { 48 $baseDir = dirname(__FILE__) . '/'; 49 $cssFile = realpath($baseDir . $_GET['css']); 50 51 if(strpos($cssFile, $baseDir) === 0 && file_exists($cssFile)) { 52 $lastModified = filemtime($cssFile); 53 $eTagFile = md5_file($cssFile); 54 $eTagHeader = (isset($_SERVER['HTTP_IF_NONE_MATCH']) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE); 55 56 header('Content-Type: text/css; charset=utf-8'); 57 header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT'); 58 header('Etag: ' . $eTagFile); 59 header('Cache-Control: public, max-age=604800, immutable'); 60 61 if(@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified || $eTagHeader == $eTagFile) { 62 header('HTTP/1.1 304 Not Modified'); 63 exit; 64 } 65 66 $css = file_get_contents($cssFile); 67 68 $less = new lessc(); 69 $less->setPreserveComments(false); 70 71 if(file_exists('style.ini')) { 72 $overrideStyle = '../../../conf/tpl/mikio/style.ini'; 73 74 $vars = Array(); 75 $rawVars = parse_ini_file('style.ini', TRUE); 76 77 if(file_exists($overrideStyle)) { 78 $userVars = parse_ini_file($overrideStyle, TRUE); 79 $rawVars = associativeMerge($rawVars, $userVars); 80 } 81 82 if(isset($rawVars['replacements'])) { 83 foreach($rawVars['replacements'] as $key=>$val) { 84 if(substr($key, 0, 2) == '__' && substr($key, -2) == '__') { 85 $vars['ini_' . substr($key, 2, -2)] = $val; 86 } 87 } 88 } 89 90 if(count($vars) > 0) { 91 $less->setVariables($vars); 92 } 93 } 94 95 $css = $less->compile($css); 96 97 $accept_encoding = @getallheaders()['Accept-Encoding']; 98 if($accept_encoding && preg_match('/ *gzip *,?/', $accept_encoding)) { 99 header('Content-Encoding: gzip'); 100 echo gzencode($css); 101 } else { 102 echo $css; 103 } 104 } else { 105 header('HTTP/1.1 404 Not Found'); 106 echo "The requested file could not be found"; 107 } 108 } else { 109 header('HTTP/1.1 404 Not Found'); 110 echo "The requested file could not be found"; 111 } 112 } else { 113 throw new Exception('Lessc library not found'); 114 } 115} 116catch(Exception $e) { 117 header('HTTP/1.1 500 Internal Server Error'); 118 echo $e; 119} 120 121function associativeMerge($base, $addition) 122{ 123 $result = $base; 124 125 // if(is_array($base) && is_array($addition)) { 126 // foreach($addition as $key=>$value) { 127 // if(is_array($value)) { 128 // $result[$key] = associativeMerge($result[$key], $value); 129 // } else { 130 // $result[$key] = $value; 131 // } 132 // } 133 // } 134 135 return $result; 136} 137 138