MDL-22955 theme: Added ability to use SVG format for icons

This commit is contained in:
Sam Hemelryk
2012-10-08 09:16:14 +13:00
parent ccd90e765e
commit 436dbeecda
11 changed files with 370 additions and 29 deletions
+95 -17
View File
@@ -334,6 +334,12 @@ class theme_config {
*/
public $supportscssoptimisation = true;
/**
* Used to determine whether we can serve SVG images or not.
* @var bool
*/
private $usesvg = null;
/**
* Load the config.php file for a particular theme, and return an instance
* of this class. (That is, this is a factory method.)
@@ -977,6 +983,7 @@ class theme_config {
global $CFG;
$params = array('theme'=>$this->name);
$svg = $this->use_svg_icons();
if (empty($component) or $component === 'moodle' or $component === 'core') {
$params['component'] = 'core';
@@ -991,11 +998,22 @@ class theme_config {
$params['image'] = $imagename;
$url = new moodle_url("$CFG->httpswwwroot/theme/image.php");
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);
$path = '/'.$params['theme'].'/'.$params['component'].'/'.$params['rev'].'/'.$params['image'];
if (!$svg) {
// We add a simple /_s to the start of the path.
// The underscore is used to ensure that it isn't a valid theme name.
$path = '/_s'.$path;
}
$url->set_slashargument($path, 'noparam', true);
} else {
$url = new moodle_url("$CFG->httpswwwroot/theme/image.php", $params);
if (!$svg) {
// We add an SVG param so that we know not to serve SVG images.
// We do this because all modern browsers support SVG and this param will one day be removed.
$params['svg'] = '0';
}
$url->params($params);
}
return $url;
@@ -1003,26 +1021,41 @@ class theme_config {
/**
* Resolves the real image location.
*
* $svg was introduced as an arg in 2.4. It is important because not all supported browsers support the use of SVG
* and we need a way in which to turn it off.
* By default SVG won't be used unless asked for. This is done for two reasons:
* 1. It ensures that we don't serve svg images unless we really want to. The admin has selected to force them, of the users
* browser supports SVG.
* 2. We only serve SVG images from locations we trust. This must NOT include any areas where the image may have been uploaded
* by the user due to security concerns.
*
* @param string $image name of image, may contain relative path
* @param string $component
* @param bool $svg If set to true SVG images will also be looked for.
* @return string full file path
*/
public function resolve_image_location($image, $component) {
public function resolve_image_location($image, $component, $svg = false) {
global $CFG;
if (!is_bool($svg)) {
// If $svg isn't a bool then we need to decide for ourselves.
$svg = $this->use_svg_icons();
}
if ($component === 'moodle' or $component === 'core' or empty($component)) {
if ($imagefile = $this->image_exists("$this->dir/pix_core/$image")) {
if ($imagefile = $this->image_exists("$this->dir/pix_core/$image", $svg)) {
return $imagefile;
}
foreach (array_reverse($this->parent_configs) as $parent_config) { // base first, the immediate parent last
if ($imagefile = $this->image_exists("$parent_config->dir/pix_core/$image")) {
if ($imagefile = $this->image_exists("$parent_config->dir/pix_core/$image", $svg)) {
return $imagefile;
}
}
if ($imagefile = $this->image_exists("$CFG->dataroot/pix/$image")) {
if ($imagefile = $this->image_exists("$CFG->dataroot/pix/$image", $svg)) {
return $imagefile;
}
if ($imagefile = $this->image_exists("$CFG->dirroot/pix/$image")) {
if ($imagefile = $this->image_exists("$CFG->dirroot/pix/$image", $svg)) {
return $imagefile;
}
return null;
@@ -1031,11 +1064,11 @@ class theme_config {
if ($image === 'favicon') {
return "$this->dir/pix/favicon.ico";
}
if ($imagefile = $this->image_exists("$this->dir/pix/$image")) {
if ($imagefile = $this->image_exists("$this->dir/pix/$image", $svg)) {
return $imagefile;
}
foreach (array_reverse($this->parent_configs) as $parent_config) { // base first, the immediate parent last
if ($imagefile = $this->image_exists("$parent_config->dir/pix/$image")) {
if ($imagefile = $this->image_exists("$parent_config->dir/pix/$image", $svg)) {
return $imagefile;
}
}
@@ -1047,36 +1080,81 @@ class theme_config {
}
list($type, $plugin) = explode('_', $component, 2);
if ($imagefile = $this->image_exists("$this->dir/pix_plugins/$type/$plugin/$image")) {
if ($imagefile = $this->image_exists("$this->dir/pix_plugins/$type/$plugin/$image", $svg)) {
return $imagefile;
}
foreach (array_reverse($this->parent_configs) as $parent_config) { // base first, the immediate parent last
if ($imagefile = $this->image_exists("$parent_config->dir/pix_plugins/$type/$plugin/$image")) {
if ($imagefile = $this->image_exists("$parent_config->dir/pix_plugins/$type/$plugin/$image", $svg)) {
return $imagefile;
}
}
if ($imagefile = $this->image_exists("$CFG->dataroot/pix_plugins/$type/$plugin/$image")) {
if ($imagefile = $this->image_exists("$CFG->dataroot/pix_plugins/$type/$plugin/$image", $svg)) {
return $imagefile;
}
$dir = get_plugin_directory($type, $plugin);
if ($imagefile = $this->image_exists("$dir/pix/$image")) {
if ($imagefile = $this->image_exists("$dir/pix/$image", $svg)) {
return $imagefile;
}
return null;
}
}
/**
* Return true if we should look for SVG images as well.
*
* @staticvar bool $svg
* @return bool
*/
public function use_svg_icons() {
global $CFG;
if ($this->usesvg === null) {
if (!isset($CFG->svgicons) || !is_bool($CFG->svgicons)) {
// IE 5 - 8 don't support SVG at all.
if (empty($_SERVER['HTTP_USER_AGENT'])) {
// Can't be sure, just say no.
$this->usesvg = false;
} else if (preg_match('#MSIE +[5-8]\.#', $_SERVER['HTTP_USER_AGENT'])) {
// IE < 9 doesn't support SVG. Say no.
$this->usesvg = false;
} else if (preg_match('#Android +[0-2]\.#', $_SERVER['HTTP_USER_AGENT'])) {
// Android < 3 doesn't support SVG. Say no.
$this->usesvg = false;
} else {
// Presumed fine.
$this->usesvg = true;
}
} else {
// Force them on/off depending upon the setting.
$this->usesvg = $CFG->svgicons;
}
}
return $this->usesvg;
}
/**
* Checks if file with any image extension exists.
*
* The order to these images was adjusted prior to the release of 2.4
* At that point the were the following image counts in Moodle core:
*
* - png = 667 in pix dirs (1499 total)
* - gif = 385 in pix dirs (606 total)
* - jpg = 62 in pix dirs (74 total)
* - jpeg = 0 in pix dirs (1 total)
*
* There is work in progress to move towards SVG presently hence that has been prioritiesed.
*
* @param string $filepath
* @param bool $svg If set to true SVG images will also be looked for.
* @return string image name with extension
*/
private static function image_exists($filepath) {
if (file_exists("$filepath.gif")) {
return "$filepath.gif";
private static function image_exists($filepath, $svg = false) {
if ($svg && file_exists("$filepath.svg")) {
return "$filepath.svg";
} else if (file_exists("$filepath.png")) {
return "$filepath.png";
} else if (file_exists("$filepath.gif")) {
return "$filepath.gif";
} else if (file_exists("$filepath.jpg")) {
return "$filepath.jpg";
} else if (file_exists("$filepath.jpeg")) {