|
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 // we need just the values from config.php and minlib.php 00028 define('ABORT_AFTER_CONFIG', true); 00029 require('../config.php'); // this stops immediately at the beginning of lib/setup.php 00030 00031 // get special url parameters 00032 if (!$parts = combo_params()) { 00033 combo_not_found(); 00034 } 00035 00036 $parts = trim($parts, '&'); 00037 00038 // find out what we are serving - only one type per request 00039 $content = ''; 00040 if (substr($parts, -3) === '.js') { 00041 $mimetype = 'application/javascript'; 00042 } else if (substr($parts, -4) === '.css') { 00043 $mimetype = 'text/css'; 00044 } else { 00045 combo_not_found(); 00046 } 00047 00048 // if they are requesting a revision that's not -1, and they have supplied an 00049 // If-Modified-Since header, we can send back a 304 Not Modified since the 00050 // content never changes (the rev number is increased any time the content changes) 00051 if (strpos($parts, '/-1/') === false and (!empty($_SERVER['HTTP_IF_NONE_MATCH']) || !empty($_SERVER['HTTP_IF_MODIFIED_SINCE']))) { 00052 $lifetime = 60*60*24*30; // 30 days 00053 header('HTTP/1.1 304 Not Modified'); 00054 header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .' GMT'); 00055 header('Cache-Control: max-age='.$lifetime); 00056 header('Content-Type: '.$mimetype); 00057 die; 00058 } 00059 00060 $parts = explode('&', $parts); 00061 $cache = true; 00062 00063 foreach ($parts as $part) { 00064 if (empty($part)) { 00065 continue; 00066 } 00067 $part = min_clean_param($part, 'SAFEPATH'); 00068 $bits = explode('/', $part); 00069 if (count($bits) < 2) { 00070 $content .= "\n// Wrong combo resource $part!\n"; 00071 continue; 00072 } 00073 //debug($bits); 00074 $version = array_shift($bits); 00075 if ($version == 'moodle') { 00076 //TODO: this is a ugly hack because we should not load any libs here! 00077 if (!defined('MOODLE_INTERNAL')) { 00078 define('MOODLE_INTERNAL', true); 00079 require_once($CFG->libdir.'/moodlelib.php'); 00080 } 00081 $revision = (int)array_shift($bits); 00082 if ($revision === -1) { 00083 // Revision -1 says please don't cache the JS 00084 $cache = false; 00085 } 00086 $frankenstyle = array_shift($bits); 00087 $filename = array_pop($bits); 00088 $dir = get_component_directory($frankenstyle); 00089 if ($mimetype == 'text/css') { 00090 $bits[] = 'assets'; 00091 $bits[] = 'skins'; 00092 $bits[] = 'sam'; 00093 } 00094 $contentfile = $dir.'/yui/'.join('/', $bits).'/'.$filename; 00095 } else { 00096 if ($version != $CFG->yui3version and $version != $CFG->yui2version and $version != 'gallery') { 00097 $content .= "\n// Wrong yui version $part!\n"; 00098 continue; 00099 } 00100 $contentfile = "$CFG->libdir/yui/$part"; 00101 } 00102 if (!file_exists($contentfile) or !is_file($contentfile)) { 00103 $content .= "\n// Combo resource $part not found!\n"; 00104 continue; 00105 } 00106 $filecontent = file_get_contents($contentfile); 00107 00108 if ($mimetype === 'text/css') { 00109 if ($version == 'moodle') { 00110 $filecontent = preg_replace('/([a-z0-9_-]+)\.(png|gif)/', 'yui_image.php?file='.$version.'/'.$frankenstyle.'/'.array_shift($bits).'/$1.$2', $filecontent); 00111 } else if ($version == 'gallery') { 00112 // search for all images in gallery module CSS and serve them through the yui_image.php script 00113 $filecontent = preg_replace('/([a-z0-9_-]+)\.(png|gif)/', 'yui_image.php?file='.$version.'/'.$bits[0].'/'.$bits[1].'/$1.$2', $filecontent); 00114 } else { 00115 // First we need to remove relative paths to images. These are used by YUI modules to make use of global assets. 00116 // I've added this as a separate regex so it can be easily removed once 00117 // YUI standardise there CSS methods 00118 $filecontent = preg_replace('#(\.\./\.\./\.\./\.\./assets/skins/sam/)?([a-z0-9_-]+)\.(png|gif)#', '$2.$3', $filecontent); 00119 00120 // search for all images in yui2 CSS and serve them through the yui_image.php script 00121 $filecontent = preg_replace('/([a-z0-9_-]+)\.(png|gif)/', 'yui_image.php?file='.$version.'/$1.$2', $filecontent); 00122 } 00123 } 00124 00125 $content .= $filecontent; 00126 } 00127 00128 if ($cache) { 00129 combo_send_cached($content, $mimetype); 00130 } else { 00131 combo_send_uncached($content, $mimetype); 00132 } 00133 00134 00140 function combo_send_cached($content, $mimetype) { 00141 $lifetime = 60*60*24*30; // 30 days 00142 00143 header('Content-Disposition: inline; filename="combo"'); 00144 header('Last-Modified: '. gmdate('D, d M Y H:i:s', time()) .' GMT'); 00145 header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .' GMT'); 00146 header('Pragma: '); 00147 header('Cache-Control: max-age='.$lifetime); 00148 header('Accept-Ranges: none'); 00149 header('Content-Type: '.$mimetype); 00150 if (!min_enable_zlib_compression()) { 00151 header('Content-Length: '.strlen($content)); 00152 } 00153 00154 echo $content; 00155 die; 00156 } 00157 00163 function combo_send_uncached($content, $mimetype) { 00164 header('Content-Disposition: inline; filename="combo"'); 00165 header('Last-Modified: '. gmdate('D, d M Y H:i:s', time()) .' GMT'); 00166 header('Expires: '. gmdate('D, d M Y H:i:s', time() + 2) .' GMT'); 00167 header('Pragma: '); 00168 header('Accept-Ranges: none'); 00169 header('Content-Type: '.$mimetype); 00170 if (!min_enable_zlib_compression()) { 00171 header('Content-Length: '.strlen($content)); 00172 } 00173 00174 echo $content; 00175 die; 00176 } 00177 00178 function combo_not_found($message = '') { 00179 header('HTTP/1.0 404 not found'); 00180 if ($message) { 00181 echo $message; 00182 } else { 00183 echo 'Combo resource not found, sorry.'; 00184 } 00185 die; 00186 } 00187 00188 function combo_params() { 00189 // note: buggy or misconfigured IIS does return the query string in REQUEST_URL 00190 if (isset($_SERVER['REQUEST_URI']) and strpos($_SERVER['REQUEST_URI'], '?') !== false) { 00191 $parts = explode('?', $_SERVER['REQUEST_URI'], 2); 00192 return $parts[1]; 00193 00194 } else if (isset($_SERVER['QUERY_STRING'])) { 00195 return $_SERVER['QUERY_STRING']; 00196 00197 } else { 00198 // unsupported server, sorry! 00199 combo_not_found('Unsupported server - query string can not be determined, try disabling YUI combo loading in admin settings.'); 00200 } 00201 }