MDL-25505 Tasks: Fix for scheduled task bug on the last day of the month.
[moodle.git] / theme / styles.php
CommitLineData
b7009474 1<?php
b7009474 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.
13//
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/>.
16
17/**
78946b9b 18 * This file is responsible for serving the one huge CSS of each theme.
b7009474 19 *
574909ef 20 * @package core
78946b9b 21 * @copyright 2009 Petr Skoda (skodak) {@link http://skodak.org}
b7009474 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
73e504bc 25
c198390a
PS
26// disable moodle specific debug messages and any errors in output,
27// comment out when debugging or better look into error log!
28define('NO_DEBUG_DISPLAY', true);
29
78946b9b
PS
30// we need just the values from config.php and minlib.php
31define('ABORT_AFTER_CONFIG', true);
32require('../config.php'); // this stops immediately at the beginning of lib/setup.php
0e641c74 33require_once($CFG->dirroot.'/lib/csslib.php');
b7009474 34
ef201c96
PS
35if (!defined('THEME_DESIGNER_CACHE_LIFETIME')) {
36 define('THEME_DESIGNER_CACHE_LIFETIME', 4); // this can be also set in config.php
37}
38
7070b7f2
PS
39if ($slashargument = min_get_slash_argument()) {
40 $slashargument = ltrim($slashargument, '/');
41 if (substr_count($slashargument, '/') < 2) {
e1075027 42 css_send_css_not_found();
7070b7f2 43 }
383b89a1
SH
44
45 if (strpos($slashargument, '_s/') === 0) {
46 // Can't use SVG
47 $slashargument = substr($slashargument, 3);
48 $usesvg = false;
49 } else {
50 $usesvg = true;
51 }
52
e1075027
SH
53 $chunk = null;
54 if (preg_match('#/(chunk(\d+)(/|$))#', $slashargument, $matches)) {
55 $chunk = (int)$matches[2];
56 $slashargument = str_replace($matches[1], '', $slashargument);
57 }
58
7070b7f2
PS
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');
63
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');
e1075027 68 $chunk = min_optional_param('chunk', null, 'INT');
383b89a1 69 $usesvg = (bool)min_optional_param('svg', '1', 'INT');
7070b7f2 70}
b7009474 71
1eb2b517
SH
72if ($type === 'editor') {
73 // The editor CSS is never chunked.
74 $chunk = null;
75} else if ($type === 'all') {
76 // We're fine.
77} else {
ef201c96 78 css_send_css_not_found();
b7009474 79}
80
73e504bc
PS
81if (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 {
78946b9b
PS
86 header('HTTP/1.0 404 not found');
87 die('Theme was not found, sorry.');
88}
b7009474 89
cb8108dd 90$candidatedir = "$CFG->localcachedir/theme/$rev/$themename/css";
ef201c96 91$etag = "$rev/$themename/$type";
e1075027 92$candidatename = $type;
383b89a1
SH
93if (!$usesvg) {
94 // Add to the sheet name, one day we'll be able to just drop this.
95 $candidatedir .= '/nosvg';
96 $etag .= '/nosvg';
97}
1eb2b517 98
e1075027
SH
99if ($chunk !== null) {
100 $etag .= '/chunk'.$chunk;
101 $candidatename .= '.'.$chunk;
102}
103$candidatesheet = "$candidatedir/$candidatename.css";
383b89a1 104$etag = sha1($etag);
b7009474 105
78946b9b 106if (file_exists($candidatesheet)) {
aa603b14 107 if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) || !empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
78946b9b
PS
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
869b1255 110 css_send_unmodified(filemtime($candidatesheet), $etag);
78946b9b 111 }
2c61e7cc 112 css_send_cached_css($candidatesheet, $etag);
b7009474 113}
114
78946b9b
PS
115//=================================================================================
116// ok, now we need to start normal moodle script, we need to load all libs and $DB
117define('ABORT_AFTER_CONFIG_CANCEL', true);
fdeb7fa1 118
78946b9b
PS
119define('NO_MOODLE_COOKIES', true); // Session not used here
120define('NO_UPGRADE_CHECK', true); // Ignore upgrade check
fdeb7fa1 121
78946b9b 122require("$CFG->dirroot/lib/setup.php");
b7009474 123
78946b9b 124$theme = theme_config::load($themename);
383b89a1 125$theme->force_svg_use($usesvg);
fdeb7fa1 126
ef201c96 127$themerev = theme_get_revision();
383b89a1 128
ef201c96
PS
129$cache = true;
130if ($themerev <= 0 or $themerev != $rev) {
131 $rev = $themerev;
132 $cache = false;
133
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';
141 }
142
143 if ($chunk !== null) {
144 $etag .= '/chunk'.$chunk;
145 $candidatename .= '.'.$chunk;
146 }
147 $candidatesheet = "$candidatedir/$candidatename.css";
148 $etag = sha1($etag);
383b89a1 149}
ef201c96 150
cb8108dd 151make_localcache_directory('theme', false);
2c61e7cc 152
78946b9b 153if ($type === 'editor') {
7e08c95f 154 $cssfiles = $theme->editor_css_files();
ef201c96
PS
155 css_store_css($theme, "$candidatedir/editor.css", $cssfiles, false);
156
78946b9b 157} else {
ef201c96 158 // Older IEs require smaller chunks.
045f492c 159 $css = $theme->css_files();
e1075027 160 $relroot = preg_replace('|^http.?://[^/]+|', '', $CFG->wwwroot);
1eb2b517
SH
161 if (!empty($slashargument)) {
162 if ($usesvg) {
163 $chunkurl = "{$relroot}/theme/styles.php/{$themename}/{$rev}/all";
e1075027 164 } else {
1eb2b517
SH
165 $chunkurl = "{$relroot}/theme/styles.php/_s/{$themename}/{$rev}/all";
166 }
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";
e1075027 172 }
1eb2b517
SH
173 }
174 $cssfiles = array();
ef201c96
PS
175 foreach ($css as $key => $value) {
176 foreach ($value as $val) {
78946b9b 177 if (is_array($val)) {
e10f304d 178 foreach ($val as $k=>$v) {
045f492c 179 $cssfiles[] = $v;
e10f304d 180 }
78946b9b 181 } else {
045f492c 182 $cssfiles[] = $val;
78946b9b
PS
183 }
184 }
fdeb7fa1 185 }
ef201c96 186 css_store_css($theme, "$candidatedir/all.css", $cssfiles, true, $chunkurl);
045f492c 187}
979d3207
PS
188
189// verify nothing failed in cache file creation
190clearstatcache();
191if (!file_exists($candidatesheet)) {
ef201c96
PS
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";
196 }
197 css_send_uncached_css($css, false);
198
199} else if (!$cache) {
200 // Do not pollute browser caches if invalid revision requested.
201 css_send_uncached_css(file_get_contents($candidatesheet), false);
979d3207 202
ef201c96
PS
203} else {
204 // This is the expected result!
205 css_send_cached_css($candidatesheet, $etag);
206}