From 9d473266a7c045ab6e2f46e34c6ce1545ca00207 Mon Sep 17 00:00:00 2001 From: Petr Skoda Date: Sat, 5 May 2012 14:45:26 +0200 Subject: [PATCH] MDL-32683 use slashargument urls for theme images --- lib/configonlylib.php | 33 ++++++++++++++++++++++++++++++++- lib/javascript-static.js | 11 ++++++----- lib/outputlib.php | 22 +++++++++++++++++----- lib/outputrequirementslib.php | 1 + theme/image.php | 28 +++++++++++++++++++++++----- 5 files changed, 79 insertions(+), 16 deletions(-) diff --git a/lib/configonlylib.php b/lib/configonlylib.php index 185415d1f37..9ceee1e58fd 100644 --- a/lib/configonlylib.php +++ b/lib/configonlylib.php @@ -108,4 +108,35 @@ function min_enable_zlib_compression() { @ini_set('zlib.output_compression', 65536); return true; -} \ No newline at end of file +} + +/** + * Returns the slashargument part of the URL. + * Note: ".php" is NOT allowed in slasharguments! + * + * @return string + */ +function min_get_slash_argument() { + // Note: This code has to work in the same cases as normal get_slash_argument(), + // but at the same time it may be simpler because we do not have to deal + // with encodings and other tricky stuff. + + $relativepath = ''; + + if (stripos($_SERVER['SERVER_SOFTWARE'], 'iis') !== false) { + if (isset($_SERVER['PATH_INFO']) and $_SERVER['PATH_INFO'] !== '') { + $relativepath = urldecode($_SERVER['PATH_INFO']); + } + } else { + if (isset($_SERVER['PATH_INFO'])) { + $relativepath = $_SERVER['PATH_INFO']; + } + } + + $matches = null; + if (preg_match('|^.+\.php(.*)$|i', $relativepath, $matches)) { + $relativepath = $matches[1]; + } + + return $relativepath; +} diff --git a/lib/javascript-static.js b/lib/javascript-static.js index f2666474058..961a2da023e 100644 --- a/lib/javascript-static.js +++ b/lib/javascript-static.js @@ -33,14 +33,15 @@ M.str = M.str || {}; * @return {String} */ M.util.image_url = function(imagename, component) { - var url = M.cfg.wwwroot + '/theme/image.php?theme=' + M.cfg.theme + '&image=' + imagename; - if (M.cfg.themerev > 0) { - url = url + '&rev=' + M.cfg.themerev; + if (component == '' || component == 'moodle' || component == 'core') { + component = 'core'; } - if (component && component != '' && component != 'moodle' && component != 'core') { - url = url + '&component=' + component; + if (M.cfg.themerev > 0 && M.cfg.slasharguments == 1) { + var url = M.cfg.wwwroot + '/theme/image.php/' + M.cfg.theme + '/' + component + '/' + M.cfg.themerev + '/' + imagename; + } else { + var url = M.cfg.wwwroot + '/theme/image.php?theme=' + M.cfg.theme + '&component=' + component + '&rev=' + M.cfg.themerev + '&image=' + imagename; } return url; diff --git a/lib/outputlib.php b/lib/outputlib.php index 280e19f53e8..e9599f64325 100644 --- a/lib/outputlib.php +++ b/lib/outputlib.php @@ -886,7 +886,7 @@ class theme_config { $component = rtrim($match[1], '|'); $imageurl = $this->pix_url($imagename, $component)->out(false); // we do not need full url because the image.php is always in the same dir - $imageurl = str_replace("$CFG->httpswwwroot/theme/", '', $imageurl); + $imageurl = preg_replace('|^http.?://[^/]+|', '', $imageurl); $css = str_replace($match[0], $imageurl, $css); } } @@ -910,17 +910,29 @@ class theme_config { public function pix_url($imagename, $component) { global $CFG; - $params = array('theme'=>$this->name, 'image'=>$imagename); + $params = array('theme'=>$this->name); + + if (empty($component) or $component === 'moodle' or $component === 'core') { + $params['component'] = 'core'; + } else { + $params['component'] = $component; + } $rev = theme_get_revision(); if ($rev != -1) { $params['rev'] = $rev; } - if (!empty($component) and $component !== 'moodle'and $component !== 'core') { - $params['component'] = $component; + + $params['image'] = $imagename; + + if (!empty($CFG->slasharguments) and $rev > 0) { + $url = new moodle_url("$CFG->httpswwwroot/theme/image.php"); + $url->set_slashargument('/'.$params['theme'].'/'.$params['component'].'/'.$params['rev'].'/'.$params['image'], 'noparam', true); + } else { + $url = new moodle_url("$CFG->httpswwwroot/theme/image.php", $params); } - return new moodle_url("$CFG->httpswwwroot/theme/image.php", $params); + return $url; } /** diff --git a/lib/outputrequirementslib.php b/lib/outputrequirementslib.php index 8dc60055c17..af7a5d4236d 100644 --- a/lib/outputrequirementslib.php +++ b/lib/outputrequirementslib.php @@ -316,6 +316,7 @@ class page_requirements_manager { 'sesskey' => sesskey(), 'loadingicon' => $renderer->pix_url('i/loading_small', 'moodle')->out(false), 'themerev' => theme_get_revision(), + 'slasharguments' => (int)(!empty($CFG->slasharguments)), 'theme' => $page->theme->name, 'jsrev' => ((empty($CFG->cachejs) or empty($CFG->jsrev)) ? -1 : $CFG->jsrev), ); diff --git a/theme/image.php b/theme/image.php index d13aabbb2e6..9659b91ed01 100644 --- a/theme/image.php +++ b/theme/image.php @@ -32,12 +32,30 @@ define('NO_DEBUG_DISPLAY', true); define('ABORT_AFTER_CONFIG', true); require('../config.php'); // this stops immediately at the beginning of lib/setup.php -$themename = min_optional_param('theme', 'standard', 'SAFEDIR'); -$component = min_optional_param('component', 'moodle', 'SAFEDIR'); -$image = min_optional_param('image', '', 'SAFEPATH'); -$rev = min_optional_param('rev', -1, 'INT'); +if ($slashargument = min_get_slash_argument()) { + $slashargument = ltrim($slashargument, '/'); + if (substr_count($slashargument, '/') < 3) { + image_not_found(); + } + // image must be last because it may contain "/" + list($themename, $component, $rev, $image) = explode('/', $slashargument, 4); + $themename = min_clean_param($themename, 'SAFEDIR'); + $component = min_clean_param($component, 'SAFEDIR'); + $rev = min_clean_param($rev, 'INT'); + $image = min_clean_param($image, 'SAFEPATH'); -if (empty($component) or empty($image)) { +} else { + $themename = min_optional_param('theme', 'standard', 'SAFEDIR'); + $component = min_optional_param('component', 'core', 'SAFEDIR'); + $rev = min_optional_param('rev', -1, 'INT'); + $image = min_optional_param('image', '', 'SAFEPATH'); +} + +if (empty($component) or $component === 'moodle' or $component === 'core') { + $component = 'moodle'; +} + +if (empty($image)) { image_not_found(); }