|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00027 // disable moodle specific debug messages and any errors in output, 00028 // comment out when debugging or better look into error log! 00029 define('NO_DEBUG_DISPLAY', true); 00030 00031 // we need just the values from config.php and minlib.php 00032 define('ABORT_AFTER_CONFIG', true); 00033 require('../config.php'); // this stops immediately at the beginning of lib/setup.php 00034 00035 $themename = min_optional_param('theme', 'standard', 'SAFEDIR'); 00036 $component = min_optional_param('component', 'moodle', 'SAFEDIR'); 00037 $image = min_optional_param('image', '', 'SAFEPATH'); 00038 $rev = min_optional_param('rev', -1, 'INT'); 00039 00040 if (empty($component) or empty($image)) { 00041 image_not_found(); 00042 } 00043 00044 if (file_exists("$CFG->dirroot/theme/$themename/config.php")) { 00045 // exists 00046 } else if (!empty($CFG->themedir) and file_exists("$CFG->themedir/$themename/config.php")) { 00047 // exists 00048 } else { 00049 image_not_found(); 00050 } 00051 00052 $candidatelocation = "$CFG->cachedir/theme/$themename/pix/$component"; 00053 00054 if ($rev > -1) { 00055 if (file_exists("$candidatelocation/$image.error")) { 00056 // this is a major speedup if there are multiple missing images, 00057 // the only problem is that random requests may pollute our cache. 00058 image_not_found(); 00059 } 00060 $cacheimage = false; 00061 if (file_exists("$candidatelocation/$image.gif")) { 00062 $cacheimage = "$candidatelocation/$image.gif"; 00063 $ext = 'gif'; 00064 } else if (file_exists("$candidatelocation/$image.png")) { 00065 $cacheimage = "$candidatelocation/$image.png"; 00066 $ext = 'png'; 00067 } else if (file_exists("$candidatelocation/$image.jpg")) { 00068 $cacheimage = "$candidatelocation/$image.jpg"; 00069 $ext = 'jpg'; 00070 } else if (file_exists("$candidatelocation/$image.jpeg")) { 00071 $cacheimage = "$candidatelocation/$image.jpeg"; 00072 $ext = 'jpeg'; 00073 } else if (file_exists("$candidatelocation/$image.ico")) { 00074 $cacheimage = "$candidatelocation/$image.ico"; 00075 $ext = 'ico'; 00076 } 00077 if ($cacheimage) { 00078 if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) || !empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { 00079 // we do not actually need to verify the etag value because our files 00080 // never change in cache because we increment the rev parameter 00081 $lifetime = 60*60*24*30; // 30 days 00082 $mimetype = get_contenttype_from_ext($ext); 00083 header('HTTP/1.1 304 Not Modified'); 00084 header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .' GMT'); 00085 header('Cache-Control: max-age='.$lifetime); 00086 header('Content-Type: '.$mimetype); 00087 die; 00088 } 00089 send_cached_image($cacheimage, $rev); 00090 } 00091 } 00092 00093 //================================================================================= 00094 // ok, now we need to start normal moodle script, we need to load all libs and $DB 00095 define('ABORT_AFTER_CONFIG_CANCEL', true); 00096 00097 define('NO_MOODLE_COOKIES', true); // Session not used here 00098 define('NO_UPGRADE_CHECK', true); // Ignore upgrade check 00099 00100 require("$CFG->dirroot/lib/setup.php"); 00101 00102 $theme = theme_config::load($themename); 00103 $imagefile = $theme->resolve_image_location($image, $component); 00104 00105 $rev = theme_get_revision(); 00106 00107 if (empty($imagefile) or !is_readable($imagefile)) { 00108 if ($rev > -1) { 00109 // make note we can not find this file 00110 $cacheimage = "$candidatelocation/$image.error"; 00111 $fp = fopen($cacheimage, 'w'); 00112 fclose($fp); 00113 } 00114 image_not_found(); 00115 } 00116 00117 00118 if ($rev > -1) { 00119 $pathinfo = pathinfo($imagefile); 00120 $cacheimage = "$candidatelocation/$image.".$pathinfo['extension']; 00121 if (!file_exists($cacheimage)) { 00122 // note: cache reset might have purged our cache dir structure, 00123 // make sure we do not use stale file stat cache in the next check_dir_exists() 00124 clearstatcache(); 00125 check_dir_exists(dirname($cacheimage)); 00126 copy($imagefile, $cacheimage); 00127 } 00128 send_cached_image($cacheimage, $rev); 00129 00130 } else { 00131 send_uncached_image($imagefile); 00132 } 00133 00134 00135 //================================================================================= 00136 //=== utility functions == 00137 // we are not using filelib because we need to fine tune all header 00138 // parameters to get the best performance. 00139 00140 function send_cached_image($imagepath, $rev) { 00141 $lifetime = 60*60*24*30; // 30 days 00142 $pathinfo = pathinfo($imagepath); 00143 $imagename = $pathinfo['filename'].'.'.$pathinfo['extension']; 00144 00145 $mimetype = get_contenttype_from_ext($pathinfo['extension']); 00146 00147 header('Etag: '.md5("$rev/$imagepath")); 00148 header('Content-Disposition: inline; filename="'.$imagename.'"'); 00149 header('Last-Modified: '. gmdate('D, d M Y H:i:s', time()) .' GMT'); 00150 header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .' GMT'); 00151 header('Pragma: '); 00152 header('Cache-Control: max-age='.$lifetime); 00153 header('Accept-Ranges: none'); 00154 header('Content-Type: '.$mimetype); 00155 header('Content-Length: '.filesize($imagepath)); 00156 00157 // no need to gzip already compressed images ;-) 00158 00159 readfile($imagepath); 00160 die; 00161 } 00162 00163 function send_uncached_image($imagepath) { 00164 $pathinfo = pathinfo($imagepath); 00165 $imagename = $pathinfo['filename'].'.'.$pathinfo['extension']; 00166 00167 $mimetype = get_contenttype_from_ext($pathinfo['extension']); 00168 00169 header('Content-Disposition: inline; filename="'.$imagename.'"'); 00170 header('Last-Modified: '. gmdate('D, d M Y H:i:s', time()) .' GMT'); 00171 header('Expires: '. gmdate('D, d M Y H:i:s', time() + 15) .' GMT'); 00172 header('Pragma: '); 00173 header('Accept-Ranges: none'); 00174 header('Content-Type: '.$mimetype); 00175 header('Content-Length: '.filesize($imagepath)); 00176 00177 readfile($imagepath); 00178 die; 00179 } 00180 00181 function image_not_found() { 00182 header('HTTP/1.0 404 not found'); 00183 die('Image was not found, sorry.'); 00184 } 00185 00186 function get_contenttype_from_ext($ext) { 00187 switch ($ext) { 00188 case 'gif': 00189 return 'image/gif'; 00190 case 'png': 00191 return 'image/png'; 00192 case 'jpg': 00193 case 'jpeg': 00194 return 'image/jpeg'; 00195 case 'ico': 00196 return 'image/vnd.microsoft.icon'; 00197 } 00198 return 'document/unknown'; 00199 }