MDL-20204 first batch of major theme changes, some regressions are still there, expec...
[moodle.git] / theme / image.php
CommitLineData
78946b9b
PS
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * This file is responsible for serving the one theme and plugin images.
20 *
21 * @package moodlecore
22 * @copyright 2009 Petr Skoda (skodak) {@link http://skodak.org}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26// we need just the values from config.php and minlib.php
27define('ABORT_AFTER_CONFIG', true);
28require('../config.php'); // this stops immediately at the beginning of lib/setup.php
29
30$themename = min_optional_param('theme', 'standard', 'SAFEDIR');
31$component = min_optional_param('component', 'moodle', 'SAFEDIR');
32$image = min_optional_param('image', '', 'SAFEPATH');
33$rev = min_optional_param('rev', -1, 'INT');
34
35if (empty($component) or empty($image)) {
36 image_not_found();
37}
38
39if (!file_exists("$CFG->dirroot/theme/$themename/config.php") and !file_exists("$CFG->dataroot/theme/$themename/config.php")) {
40 image_not_found();
41}
42
43$candidatelocation = "$CFG->dataroot/cache/theme/$themename/pix/$component";
44
45if ($rev > -1) {
46 if (file_exists("$candidatelocation/$image.error")) {
47 // this is a major speedup if there are multiple missing images,
48 // the only problem is that random requests may pollute our cache.
49 image_not_found();
50 }
51 $cacheimage = false;
52 if (file_exists("$candidatelocation/$image.gif")) {
53 $cacheimage = "$candidatelocation/$image.gif";
54 } else if (file_exists("$candidatelocation/$image.png")) {
55 $cacheimage = "$candidatelocation/$image.png";
56 } else if (file_exists("$candidatelocation/$image.jpg")) {
57 $cacheimage = "$candidatelocation/$image.jpg";
58 } else if (file_exists("$candidatelocation/$image.jpeg")) {
59 $cacheimage = "$candidatelocation/$image.jpeg";
60 } else if (file_exists("$candidatelocation/$image.ico")) {
61 $cacheimage = "$candidatelocation/$image.ico";
62 }
63 if ($cacheimage) {
64 if (!empty($_SERVER['HTTP_IF_NONE_MATCH'])) {
65 // we do not actually need to verify the etag value because our files
66 // never change in cache because we increment the rev parameter
67 header('HTTP/1.1 304 Not Modified');
68 die;
69 }
70 send_cached_image($cacheimage, $rev);
71 }
72}
73
74//=================================================================================
75// ok, now we need to start normal moodle script, we need to load all libs and $DB
76define('ABORT_AFTER_CONFIG_CANCEL', true);
77
78define('NO_MOODLE_COOKIES', true); // Session not used here
79define('NO_UPGRADE_CHECK', true); // Ignore upgrade check
80
81require("$CFG->dirroot/lib/setup.php");
82
83$theme = theme_config::load($themename);
84$imagefile = $theme->resolve_image_location($image, $component);
85
86$rev = theme_get_revision();
87
88if (empty($imagefile) or !is_readable($imagefile)) {
89 if ($rev > -1) {
90 // make note we can not find this file
91 $cacheimage = "$candidatelocation/$image.error";
92 $fp = fopen($cacheimage, 'w');
93 fclose($fp);
94 }
95 image_not_found();
96}
97
98
99if ($rev > -1) {
100 $pathinfo = pathinfo($imagefile);
101 $cacheimage = "$candidatelocation/$image.".$pathinfo['extension'];
102 if (!file_exists($cacheimage)) {
103 check_dir_exists(dirname($cacheimage), true, true);
104 copy($imagefile, $cacheimage);
105 }
106 send_cached_image($cacheimage, $rev);
107
108} else {
109 send_uncached_image($imagefile);
110}
111
112
113//=================================================================================
114//=== utility functions ==
115// we are not using filelib because we need to fine tune all header
116// parameters to get the best performance.
117
118function send_cached_image($imagepath, $rev) {
119 $lifetime = 60*60*24*3;
120 $pathinfo = pathinfo($imagepath);
121 $imagename = $pathinfo['filename'].'.'.$pathinfo['extension'];
122
123 switch($pathinfo['extension']) {
124 case 'gif' : $mimetype = 'image/gif'; break;
125 case 'png' : $mimetype = 'image/png'; break;
126 case 'jpg' : $mimetype = 'image/jpeg'; break;
127 case 'jpeg' : $mimetype = 'image/jpeg'; break;
128 case 'ico' : $mimetype = 'image/vnd.microsoft.icon'; break;
129 default: $mimetype = 'document/unknown';
130 }
131
132 header('Etag: '.md5("$rev/$imagepath"));
133 header('Content-Disposition: inline; filename="'.$imagename.'"');
134 header('Last-Modified: '. gmdate('D, d M Y H:i:s', filemtime($imagepath)) .' GMT');
135 header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .' GMT');
136 header('Pragma: ');
137 header('Accept-Ranges: none');
138 header('Content-Type: '.$mimetype);
139 header('Content-Length: '.filesize($imagepath));
140
141 while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite
142 readfile($imagepath);
143 die;
144}
145
146function send_uncached_image($imagepath) {
147 $pathinfo = pathinfo($imagepath);
148 $imagename = $pathinfo['filename'].'.'.$pathinfo['extension'];
149
150 switch($pathinfo['extension']) {
151 case 'gif' : $mimetype = 'image/gif'; break;
152 case 'png' : $mimetype = 'image/png'; break;
153 case 'jpg' : $mimetype = 'image/jpeg'; break;
154 case 'jpeg' : $mimetype = 'image/jpeg'; break;
155 case 'ico' : $mimetype = 'image/vnd.microsoft.icon'; break;
156 default: $mimetype = 'document/unknown';
157 }
158
159 header('Content-Disposition: inline; filename="'.$imagename.'"');
160 header('Last-Modified: '. gmdate('D, d M Y H:i:s', time()) .' GMT');
161 header('Expires: '. gmdate('D, d M Y H:i:s', time() + 2) .' GMT');
162 header('Pragma: ');
163 header('Accept-Ranges: none');
164 header('Content-Type: '.$mimetype);
165 header('Content-Length: '.filesize($imagepath));
166
167 while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite
168 readfile($imagepath);
169 die;
170}
171
172function image_not_found() {
173 header('HTTP/1.0 404 not found');
174 die('Image was not found, sorry.');
175}