1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8//this script may only be included - so its better to die if called directly. 9if (strpos($_SERVER["SCRIPT_NAME"], basename(__FILE__)) !== false) { 10 header("location: index.php"); 11 exit; 12} 13 14/* 15 * smarty_function_icon: Display a Tiki icon, using theme icons if they exists 16 * 17 * params will be used as params for the HTML tag (e.g. border, class, ...), except special params starting with '_' : 18 * - _id: [deprecated] short name (i.e. 'page_edit') or relative file path (i.e. 'img/icons/page_edit.png'). 19 * Will not work with iconsets. 20 * - name: name of icon from themes/base_files/iconsets file, which allows for choosing different iconsets. 21 * Use instead of _id. 22 * - size: size of icon when name is used 23 * - style: style supported by the current iconset, e.g. for FA5: default, outline, light (pro only), brands 24 * - class: set custom class (otherwise default classes are applied). When using icon sets, this class will apply to 25 * anchor element 26 * - iclass: set custom class for the icon itself (not the link) 27 * - ititle: set custom title for the icon itself (not the link) 28 * - istyle: set custom style for the icon itself (not the link) 29 * - _type: type of URL to use (e.g. 'absolute_uri', 'absolute_path'). Defaults to a relative URL. 30 * - _tag: type of HTML tag to use (e.g. 'img', 'input_image'). Defaults to 'img' tag. 31 * - _notag: if set to 'y', will only return the URL (which also handles theme icons). 32 * - _menu_text: if set to 'y', will use the 'title' argument as text after the icon and place the whole 33 * content between div tags with a 'icon_menu' class (not compatible with '_notag' param set to 'y'). 34 * - _menu_icon: if set to 'n', will not show icon image when _menu_text is 'y'. 35 * - _confirm: text to use in a popup requesting the user to confirm its action (yet only available with javascript) 36 * - _defaultdir: directory to use when the _id param does not include the path 37 * - _extension: Filename extension - default 'png' 38 */ 39function smarty_function_icon($params, $smarty) 40{ 41 if (! is_array($params)) { 42 $params = []; 43 } 44 45 global $prefs, $tc_theme, $tc_theme_option, $url_path, $base_url, $tikipath, $iconset; 46 $cachelib = TikiLib::lib('cache'); 47 48 if (empty($tc_theme)) { 49 $current_theme = ! empty($prefs['theme']) ? $prefs['theme'] : ''; 50 $current_theme_option = isset($prefs['theme_option']) ? $prefs['theme_option'] : ''; 51 } else { 52 $current_theme = $tc_theme; 53 $current_theme_option = ! empty($tc_theme_option) ? $tc_theme_option : ''; 54 } 55 56 if (isset($params['_type'])) { 57 if ($params['_type'] === 'absolute_uri') { 58 $params['path_prefix'] = $base_url; 59 } elseif ($params['_type'] === 'absolute_path') { 60 $params['path_prefix'] = $url_path; 61 } 62 } 63 64 $serialized_params = serialize(array_merge($params, [$current_theme, $current_theme_option, isset($_SERVER['HTTPS'])])); 65 $cache_key = TikiLib::contextualizeKey('icons_' . '_' . md5($serialized_params), 'language', 'external'); 66 if ($cached = $cachelib->getCached($cache_key)) { 67 return $cached; 68 } 69 70 $basedirs = ['img/icons', 'img/icons/mime']; 71 $icons_extension = empty($params['_extension']) ? '.png' : '.' . $params['_extension']; 72 $tag = 'img'; 73 $notag = false; 74 $default_class = 'icon'; 75 $default_width = 16; 76 $default_height = 16; 77 $menu_text = false; 78 $menu_icon = false; 79 $confirm = ''; 80 $html = ''; 81 82 if (empty($params['_id'])) { 83 if (isset($params['_defaultdir']) && $params['_defaultdir'] == 'img/icons/large') { 84 $params['_id'] = 'green_question48x48'; 85 } else { 86 $params['_id'] = 'green_question'; 87 } 88 } 89 if (! empty($params['_defaultdir'])) { 90 array_unshift($basedirs, $params['_defaultdir']); 91 if ($params['_defaultdir'] == 'img/icons/large') { 92 $default_width = $default_height = ( strpos($params['_id'], '48x48') !== false ) ? 48 : 32; 93 } 94 } 95 // ICONSET START, work-in-progress, more information: dev.tiki.org/icons. $iconset array is prepared by lib/setup/theme.php 96 // N.B. In some contexts such as the console $iconset may not be set up 97 if (! empty($params['name']) && empty($params['_tag']) && ! empty($iconset)) { 98 $name = $params['name']; 99 $html = $iconset->getHtml($name, $params); 100 $menu_text = (isset($params['_menu_text']) && $params['_menu_text'] == 'y'); 101 if (! empty($params['href']) || ! empty($params['title']) || $menu_text) { 102 /* Generate a link for the icon if href or title (for tips) parameter is set. 103 * This will produce a link element (<a>) around the icon. 104 * If you want a button element (<button>), use the {button} smarty_tiki function */ 105 106 //collect link components 107 if (! empty($params['title'])) { //add title if not empty 108 $a_title = $params['title']; 109 } elseif (! empty($params['alt'])) { 110 $a_title = $params['alt']; 111 } else { 112 $a_title = ''; 113 } 114 if (! empty($a_title)) { 115 $title_attr = $menu_text ? '' : 'title="' . $a_title . '"'; 116 } else { 117 $title_attr = ''; 118 } 119 if (isset($params['class'])) { //if set, use these classes instead of the default bootstrap 120 $a_class = $params['class']; 121 } else { 122 $a_class = 'btn btn-link'; //the default classes to be used 123 } 124 125 if (! empty($params['href'])) { //use href if not empty 126 $a_href = 'href="' . $params['href'] . '"'; 127 } else { 128 $a_href = ''; 129 } 130 131 if (isset($params['data-toggle'])) { //add data-toggle if set 132 $a_datatoggle = 'data-toggle="' . $params['data-toggle'] . '"'; 133 } else { 134 $a_datatoggle = ''; 135 } 136 137 if (isset($params['onclick'])) { //add onclick if set 138 $a_onclick = 'onclick="' . $params['onclick'] . '"'; 139 } elseif (isset($params['_confirm'])) { 140 $a_onclick = 'onclick="return confirm(\'' . $params['_confirm'] . '\');"'; 141 } else { 142 $a_onclick = ''; 143 } 144 145 //assemble the link from the components 146 if ($menu_text) { 147 $icon = isset($params['_menu_icon']) && $params['_menu_icon'] === 'y' ? $html : ''; 148 $html = '<div class="iconmenu">' . $icon . '<span class="iconmenutext"> ' . $a_title . '</span></div>'; 149 } else { 150 $html = "<a class='$a_class' $title_attr $a_href $a_datatoggle $a_onclick>$html</a>"; 151 } 152 } 153 //return the icon 154 return $html; 155 } //ICONSET END 156 157 // Handle _ids that contains the real filename and path 158 if (strpos($params['_id'], '/') !== false || strpos($params['_id'], '.') !== false) { 159 if (($icons_basedir = dirname($params['_id'])) == '') { 160 $icons_basedir = $basedirs[0]; 161 } 162 163 $icons_basedir .= '/'; 164 165 if (($pos = strrpos($params['_id'], '.')) !== false) { 166 $icons_extension = substr($params['_id'], $pos); 167 } 168 169 $params['_id'] = preg_replace( 170 '/^' . str_replace('/', '\/', $icons_basedir) . '|' . $icons_extension . '$/', 171 '', 172 $params['_id'] 173 ); 174 } else { 175 $icons_basedir = $basedirs[0] . '/'; 176 } 177 178 if (! preg_match('/^[a-z0-9_-]+$/i', $params['_id'])) { 179 return; 180 } 181 182 183 // Include smarty functions used below 184 $smarty->loadPlugin('smarty_function_html_image'); 185 186 // auto-detect 'alt' param if not set 187 if (! isset($params['alt'])) { 188 $alt_pos = ( ($alt_pos = strrpos($params['_id'], '_')) === false ) ? 0 : $alt_pos + 1; 189 $params['alt'] = tra(ucfirst(substr($params['_id'], $alt_pos))); 190 } 191 192 // handle special params and clean unrecognized params 193 foreach ($params as $k => $v) { 194 if ($k[0] == '_') { 195 switch ($k) { 196 case '_id': 197 $img_file = $v . $icons_extension; 198 $v = $icons_basedir . $img_file; 199 $themelib = TikiLib::lib('theme'); 200 $v2 = $themelib->get_theme_path($current_theme, $current_theme_option, $img_file, 'icons/'); 201 202 if (! empty($v2)) { 203 $params['file'] = $v2; 204 } else { 205 $params['file'] = $v; 206 } 207 break; 208 209 case '_notag': 210 $notag = ($v == 'y'); 211 break; 212 213 case '_menu_text': 214 $menu_text = ($v == 'y'); 215 $menu_icon = ( isset($params['_menu_icon']) && $params['_menu_icon'] == 'y' ); 216 break; 217 218 case '_tag': 219 $tag = $v; 220 break; 221 222 case '_confirm': 223 if ($prefs['javascript_enabled'] == 'y') { 224 $params['onclick'] = "return confirm('" . str_replace("'", "\'", $v) . "');"; 225 } 226 break; 227 } 228 229 unset($params[$k]); 230 } 231 } 232 233 // default values for some params 234 235 if (isset($params['path_prefix'])) { 236 $params['basedir'] = $tikipath; 237 $params['file'] = '/' . $params['file']; 238 } 239 240 if ($tag == 'img' && is_readable($params['file'])) { 241 $dim = getimagesize($params['file']); 242 243 if (! isset($params['width'])) { 244 $params['width'] = $dim[0] ? $dim[0] : $default_width; 245 } 246 if (! isset($params['height'])) { 247 $params['height'] = $dim[1] ? $dim[1] : $default_height; 248 } 249 } 250 251 if ($notag) { 252 $html = (isset($params['path_prefix']) ? $params['path_prefix'] : '') . $params['file']; 253 } else { 254 // use 'alt' as 'title' if not set 255 if (! isset($params['title'])) { 256 $params['title'] = $params['alt']; 257 } 258 // use default class if not set 259 if (! isset($params['class'])) { 260 $params['class'] = $default_class; 261 } 262 263 // remove empty arguments 264 foreach ($params as $k => $v) { 265 if ($v == '') { 266 unset($params[$k]); 267 } 268 } 269 270 // No need to add a title on a menu icon since there will be the same text just after the icon 271 if ($menu_text) { 272 $menu_text_val = $params['title']; 273 unset($params['title']); 274 } 275 276 if ($tag != 'img') { 277 $params['src'] = TikiLib::tikiUrlOpt($params['file']); 278 unset($params['file']); 279 foreach ($params as $k => $v) { 280 $html .= ' ' . htmlspecialchars($k, ENT_QUOTES, 'UTF-8') . '="' . htmlspecialchars($v, ENT_QUOTES, 'UTF-8') . '"'; 281 } 282 } 283 284 if (! empty($params['file'])) { 285 $headerlib = TikiLib::lib('header'); 286 $params['file'] = $headerlib->convert_cdn($params['file']); 287 $params['file'] = TikiLib::tikiUrlOpt($params['file']); 288 } 289 290 switch ($tag) { 291 case 'input_image': 292 $html = '<input type="image"' . $html . ' />'; 293 break; 294 case 'img': 295 default: 296 try { 297 $html = smarty_function_html_image($params, $smarty->getEmptyInternalTemplate()); 298 } catch (Exception $e) { 299 $html = '<span class="icon error" title="' . tra('Error:') . ' ' . $e->getMessage() . '">?</span>'; 300 } 301 } 302 303 if ($tag != 'img') { 304 // Add a span tag to be able to apply a CSS style on hover for the icon 305 $html = "<span>$html</span>"; 306 } 307 308 if ($menu_text) { 309 if (! $menu_icon) { 310 $html = ''; 311 } 312 $html = '<div class="iconmenu">' . $html . '<span class="iconmenutext"> ' . $menu_text_val . '</span></div>'; 313 } 314 } 315 316 $cachelib->cacheItem($cache_key, $html); 317 return $html; 318} 319