MDL-41806 Add assessors to moodle_url class
[moodle.git] / theme / styles.php
blob0279b5177ea51cc88438433362ee64cb286e599e
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 /**
18 * This file is responsible for serving the one huge CSS of each theme.
20 * @package core
21 * @copyright 2009 Petr Skoda (skodak) {@link http://skodak.org}
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 // disable moodle specific debug messages and any errors in output,
27 // comment out when debugging or better look into error log!
28 define('NO_DEBUG_DISPLAY', true);
30 // we need just the values from config.php and minlib.php
31 define('ABORT_AFTER_CONFIG', true);
32 require('../config.php'); // this stops immediately at the beginning of lib/setup.php
33 require_once($CFG->dirroot.'/lib/csslib.php');
35 if (!defined('THEME_DESIGNER_CACHE_LIFETIME')) {
36 define('THEME_DESIGNER_CACHE_LIFETIME', 4); // this can be also set in config.php
39 if ($slashargument = min_get_slash_argument()) {
40 $slashargument = ltrim($slashargument, '/');
41 if (substr_count($slashargument, '/') < 2) {
42 css_send_css_not_found();
45 if (strpos($slashargument, '_s/') === 0) {
46 // Can't use SVG
47 $slashargument = substr($slashargument, 3);
48 $usesvg = false;
49 } else {
50 $usesvg = true;
53 $chunk = null;
54 if (preg_match('#/(chunk(\d+)(/|$))#', $slashargument, $matches)) {
55 $chunk = (int)$matches[2];
56 $slashargument = str_replace($matches[1], '', $slashargument);
59 list($themename, $rev, $type) = explode('/', $slashargument, 3);
60 $themename = min_clean_param($themename, 'SAFEDIR');
61 $rev = min_clean_param($rev, 'INT');
62 $type = min_clean_param($type, 'SAFEDIR');
64 } else {
65 $themename = min_optional_param('theme', 'standard', 'SAFEDIR');
66 $rev = min_optional_param('rev', 0, 'INT');
67 $type = min_optional_param('type', 'all', 'SAFEDIR');
68 $chunk = min_optional_param('chunk', null, 'INT');
69 $usesvg = (bool)min_optional_param('svg', '1', 'INT');
72 if ($type === 'editor') {
73 // The editor CSS is never chunked.
74 $chunk = null;
75 } else if ($type === 'all') {
76 // We're fine.
77 } else {
78 css_send_css_not_found();
81 if (file_exists("$CFG->dirroot/theme/$themename/config.php")) {
82 // exists
83 } else if (!empty($CFG->themedir) and file_exists("$CFG->themedir/$themename/config.php")) {
84 // exists
85 } else {
86 header('HTTP/1.0 404 not found');
87 die('Theme was not found, sorry.');
90 $candidatedir = "$CFG->localcachedir/theme/$rev/$themename/css";
91 $etag = "$rev/$themename/$type";
92 $candidatename = $type;
93 if (!$usesvg) {
94 // Add to the sheet name, one day we'll be able to just drop this.
95 $candidatedir .= '/nosvg';
96 $etag .= '/nosvg';
99 if ($chunk !== null) {
100 $etag .= '/chunk'.$chunk;
101 $candidatename .= '.'.$chunk;
103 $candidatesheet = "$candidatedir/$candidatename.css";
104 $etag = sha1($etag);
106 if (file_exists($candidatesheet)) {
107 if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) || !empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
108 // we do not actually need to verify the etag value because our files
109 // never change in cache because we increment the rev parameter
110 css_send_unmodified(filemtime($candidatesheet), $etag);
112 css_send_cached_css($candidatesheet, $etag);
115 //=================================================================================
116 // ok, now we need to start normal moodle script, we need to load all libs and $DB
117 define('ABORT_AFTER_CONFIG_CANCEL', true);
119 define('NO_MOODLE_COOKIES', true); // Session not used here
120 define('NO_UPGRADE_CHECK', true); // Ignore upgrade check
122 require("$CFG->dirroot/lib/setup.php");
124 $theme = theme_config::load($themename);
125 $theme->force_svg_use($usesvg);
127 $themerev = theme_get_revision();
129 $cache = true;
130 if ($themerev <= 0 or $themerev != $rev) {
131 $rev = $themerev;
132 $cache = false;
134 $candidatedir = "$CFG->cachedir/theme/$rev/$themename/css";
135 $etag = "$rev/$themename/$type";
136 $candidatename = $type;
137 if (!$usesvg) {
138 // Add to the sheet name, one day we'll be able to just drop this.
139 $candidatedir .= '/nosvg';
140 $etag .= '/nosvg';
143 if ($chunk !== null) {
144 $etag .= '/chunk'.$chunk;
145 $candidatename .= '.'.$chunk;
147 $candidatesheet = "$candidatedir/$candidatename.css";
148 $etag = sha1($etag);
151 make_localcache_directory('theme', false);
153 if ($type === 'editor') {
154 $cssfiles = $theme->editor_css_files();
155 css_store_css($theme, "$candidatedir/editor.css", $cssfiles, false);
157 } else {
158 // Older IEs require smaller chunks.
159 $css = $theme->css_files();
160 $relroot = preg_replace('|^http.?://[^/]+|', '', $CFG->wwwroot);
161 if (!empty($slashargument)) {
162 if ($usesvg) {
163 $chunkurl = "{$relroot}/theme/styles.php/{$themename}/{$rev}/all";
164 } else {
165 $chunkurl = "{$relroot}/theme/styles.php/_s/{$themename}/{$rev}/all";
167 } else {
168 if ($usesvg) {
169 $chunkurl = "{$relroot}/theme/styles.php?theme={$themename}&rev={$rev}&type=all";
170 } else {
171 $chunkurl = "{$relroot}/theme/styles.php?theme={$themename}&rev={$rev}&type=all&svg=0";
174 $cssfiles = array();
175 foreach ($css as $key => $value) {
176 foreach ($value as $val) {
177 if (is_array($val)) {
178 foreach ($val as $k=>$v) {
179 $cssfiles[] = $v;
181 } else {
182 $cssfiles[] = $val;
186 css_store_css($theme, "$candidatedir/all.css", $cssfiles, true, $chunkurl);
189 // verify nothing failed in cache file creation
190 clearstatcache();
191 if (!file_exists($candidatesheet)) {
192 // We need to send at least something, IE does not get it chunked properly but who cares.
193 $css = '';
194 foreach ($cssfiles as $file) {
195 $css .= file_get_contents($file)."\n";
197 css_send_uncached_css($css, false);
199 } else if (!$cache) {
200 // Do not pollute browser caches if invalid revision requested.
201 css_send_uncached_css(file_get_contents($candidatesheet), false);
203 } else {
204 // This is the expected result!
205 css_send_cached_css($candidatesheet, $etag);