diff --git a/contrib/smarty/plugins/function.iconPath.php b/contrib/smarty/plugins/function.iconPath.php new file mode 100644 index 0000000000000000000000000000000000000000..31ae49ef26fd0c785823f05b1bdb49ae8961be28 --- /dev/null +++ b/contrib/smarty/plugins/function.iconPath.php @@ -0,0 +1,18 @@ +<?php + +function smarty_function_iconPath($params, &$smarty) +{ + $config = session::global_get('config'); + + /* Set theme */ + $theme = "default"; + if (isset ($config)) { + $theme = $config->get_cfg_value("theme", "default"); + if (!isset(IconTheme::$themes[$theme])) { + $theme = 'default'; + } + } + + return IconTheme::$themes[$theme]->FindIcon($params['context'], $params['icon'], $params['size']); +} +?> diff --git a/html/main.php b/html/main.php index 5f00ea170865e0e8d7fc8ffed7f723d373c260c1..31eef91df3da5742e449349214a64ae83f48f788 100644 --- a/html/main.php +++ b/html/main.php @@ -62,6 +62,7 @@ if ($_SERVER['REMOTE_ADDR'] != $ui->ip) { exit; } $config = session::global_get('config'); +IconTheme::loadThemes('themes'); /* If SSL is forced, just forward to the SSL enabled site */ if (($config->get_cfg_value("forcessl") == "TRUE") && ($ssl != '')) { diff --git a/include/class_IconTheme.inc b/include/class_IconTheme.inc new file mode 100644 index 0000000000000000000000000000000000000000..5aaa40cf843ac5806f44b885a5f2e3031ceb1788 --- /dev/null +++ b/include/class_IconTheme.inc @@ -0,0 +1,155 @@ +<?php + +class IconThemeDir +{ + private $Size; + private $MinSize; + private $MaxSize; + private $Type = 'Threshold'; + private $Threshold = 2; + + function __construct($infos) + { + $this->Size = $infos['Size']; + $this->MinSize = $infos['Size']; + $this->MaxSize = $infos['Size']; + foreach (array('Type', 'MaxSize', 'MinSize', 'Threshold') as $key) { + if (isset($infos[$key])) { + $this->$key = $infos[$key]; + } + } + /* Thanks to this Threshold and Scaled are the same */ + if ($this->Type == 'Threshold') { + $this->MinSize = $this->Size - $this->Threshold; + $this->MaxSize = $this->Size + $this->Threshold; + } + } + + function MatchesSize($size) + { + switch ($this->Type) { + case 'Fixed': + return ($this->Size == $size); + case 'Threshold': + case 'Scalable': + return (($this->MinSize <= $size) && ($size <= $this->MaxSize)); + } + } + + function SizeDistance($size) + { + switch ($this->Type) { + case 'Fixed': + return abs($this->Size - $size); + case 'Threshold': + case 'Scalable': + if ($size < $this->MinSize) { + return $this->MinSize - $size; + } + if ($size > $this->MaxSize) { + return $size - $this->MaxSize; + } + return 0; + } + } +} + +class IconTheme +{ + private $subdirs = array(); + private $path; + private $parent; + + function __construct($folder, $default_parent = 'default') + { + $this->path = $folder; + $datas = parse_ini_file($folder.'/index.theme', TRUE, INI_SCANNER_RAW); + if ($datas === FALSE) { + throw new Exception('Error while parsing theme file'); + } + $dirs = preg_split('/,/', $datas['Icon Theme']['Directories']); + foreach ($dirs as $name) { + $this->subdirs[strtolower($datas[$name]['Context'])][$name] = new IconThemeDir($datas[$name]); + } + + if (isset($datas['Inherits'])) { + $this->parent = $datas['Inherits']; + } else { + $this->parent = $default_parent; + } + } + + function FindIcon($context, $icon, $size) + { + $context = strtolower($context); + return $this->FindIconHelper($context, $icon, $size); + } + + function FindIconHelper($context, $icon, $size) + { + $filename = $this->LookupIcon($context, $icon, $size); + if ($filename != NULL) { + return $filename; + } + + if ($this->parent !== NULL) { + if (isset(self::$themes[$this->parent])) { + $parent = self::$themes[$this->parent]; + } else { + $parent = self::$themes['default']; + } + return $parent->FindIconHelper($context, $icon, $size); + } + + return NULL; + } + + function LookupIcon($context, $iconname, $size) + { + foreach ($this->subdirs[$context] as $path => &$subdir) { + if ($subdir->MatchesSize($size)) { + foreach (array('png', 'svg', 'xpm') as $extension) { + $filename = $this->path.'/'.$path.'/'.$iconname.'.'.$extension; + if (file_exists($filename)) { + return $filename; + } + } + } + } + unset($subdir); + $minimal_size = PHP_INT_MAX; + foreach ($this->subdirs[$context] as $path => &$subdir) { + if (($sizedistance = $subdir->SizeDistance($size)) < $minimal_size) { + foreach (array('png', 'svg', 'xpm') as $extension) { + $filename = $this->path.'/'.$path.'/'.$iconname.'.'.$extension; + if (file_exists($filename)) { + $closest_filename = $filename; + $minimal_size = $sizedistance; + } + } + } + } + unset($subdir); + if (isset($closest_filename)) { + return $closest_filename; + } + return NULL; + } + + static public $themes; + static public function loadThemes($path) + { + if ($dir = opendir("$path")) { + while (($file = readdir($dir)) !== FALSE) { + if (file_exists("$path/$file/index.theme") && !preg_match("/^\./", $file)) { + try { + self::$themes[$file] = new IconTheme("$path/$file"); + } catch (Exception $e) { + } + } + } + } + } +} + +?> diff --git a/plugins/config/class_configInLdap.inc b/plugins/config/class_configInLdap.inc index aed43469e2399caeafff848cf2e25ec700e6a8f0..4ba2a69bca5e4ef8d7dd2e3757e2e792c7a02e78 100644 --- a/plugins/config/class_configInLdap.inc +++ b/plugins/config/class_configInLdap.inc @@ -495,7 +495,7 @@ class configInLdap extends simplePlugin static function get_themes() { $themesdir = '../ihtml/themes/'; - $themes = array(); + $themes = array_keys(IconTheme::$themes); if ($dir = opendir("$themesdir")) { while (($file = readdir($dir)) !== FALSE) { if (is_dir("$themesdir/$file") && !preg_match("/^\./", $file)) { @@ -503,7 +503,7 @@ class configInLdap extends simplePlugin } } } - return $themes; + return array_unique($themes); } } ?>