on success
*/
function biticon_output( $pParams, $pFile ) {
global $gBitSystem;
$iexplain = isset( $pParams["iexplain"] ) ? KernelTools::tra( $pParams["iexplain"] ) : 'please set iexplain';
if( empty( $pParams['iforce'] )) {
$pParams['iforce'] = 'none';
}
if( isset( $pParams["url"] )) {
$outstr = $pFile;
} else {
if( (empty( $pFile ) || $gBitSystem->getConfig( 'site_biticon_display_style' ) == 'text' || $pParams['iforce'] == 'text') && $pParams['iforce'] != 'icon' ) {
$outstr = $iexplain;
} else {
$outstr='
$val ) {
if( !in_array( $name, $ommit ) ) {
$outstr .= ' '.$name.'="'.$val.'"';
}
}
if( !isset( $pParams["iclass"] ) ) {
$outstr .= ' class="icon"';
} else {
$outstr .= ' class="'.$pParams["iclass"].'"';
}
if( isset( $pParams["onclick"] ) ) {
$outstr .= ' onclick="'.$pParams["onclick"].'"';
}
if( str_ends_with( $pFile, '.svg' ) ) {
$svgSizes = ['small' => 16, 'medium' => 24, 'large' => 32];
$h = $svgSizes[$pParams['isize'] ?? 'small'] ?? 16;
$w = ($pParams['istyle'] ?? '') === 'flag' ? (int)round( $h * 4 / 3 ) : $h;
$outstr .= " width=\"$w\" height=\"$h\"";
}
$outstr .= " />";
if( $gBitSystem->getConfig( 'site_biticon_display_style' ) == 'icon_text' && $pParams['iforce'] != 'icon' || $pParams['iforce'] == 'icon_text' ) {
$outstr .= ' '.$iexplain;
}
}
}
if( !preg_match( "#^broken\.#", $pFile )) {
if( !biticon_write_cache( $pParams, $outstr )) {
echo KernelTools::tra( 'There was a problem writing the icon cache file' );
}
}
return $outstr;
}
/**
* smarty_function_biticon
*
* @param array $pParams
* @var boolean ['url'] set to true if you only want the url and nothing else
* @var string ['iexplain'] Explanation of what the icon represents
* @var string ['iclass']
* @var string ['iforce'] override site-wide setting how to display icons (can be set to 'icon', 'text' or 'icon_text')
* @param bool $pCheckSmall look for a small render of the image
* @access public
* @return string final
*/
function smarty_function_biticon( $pParams, $pSmall = false ) {
global $gBitSystem, $gBitThemes, $gSniffer;
// this is needed in case everything goes horribly wrong
$copyParams = $pParams;
// ensure that ipath has a leading and trailing slash
$pParams['ipath'] = !empty( $pParams['ipath'] ) ? str_replace( "//", "/", "/".$pParams['ipath']."/" ) : '/';
// try to separate iname from ipath if we've been given some sloppy naming
if( strstr( $pParams['iname'], '/' )) {
$pParams['iname'] = $pParams['ipath'].$pParams['iname'];
$boom = explode( '/', $pParams['iname'] );
$pParams['iname'] = array_pop( $boom );
$pParams['ipath'] = str_replace( "//", "/", "/".implode( '/', $boom )."/" );
}
// if we don't have an ipath yet, we will set it here
if( $pParams['ipath'] == '/' ) {
$configSize = !empty( $pParams['isize'] ) ? $pParams['isize'] : $gBitSystem->getConfig( 'site_icon_size', 'small' );
if( !empty( $pParams['ilocation'] )) {
if( $pParams['ilocation'] == 'menu' ) {
$pParams['ipath'] .= $configSize.'/';
$pParams['iforce'] = 'icon_text';
} elseif( $pParams['ilocation'] == 'quicktag' ) {
$pParams['ipath'] .= $configSize.'/';
$pParams['iforce'] = 'icon';
$pParams['iclass'] = 'quicktag icon';
}
} else {
$pParams['ipath'] .= $configSize.'/';
}
}
// we have one special case: pkg_icons don't have a size variant
if( strstr( $pParams['iname'], 'pkg_' ) && !strstr( $pParams['ipath'], 'small' )) {
$pParams['ipath'] = preg_replace( "!/.*?/$!", "/", $pParams['ipath'] );
}
// make sure ipackage is set correctly
$pParams['ipackage'] = !empty( $pParams['ipackage'] ) ? strtolower( $pParams['ipackage'] ?? '' ) :'icons';
// if the user is using a text-browser we force text instead of icons
if( $gSniffer->_browser_info['browser'] == 'lx' || $gSniffer->_browser_info['browser'] == 'li' ) {
$pParams['iforce'] = 'text';
}
// get out of here as quickly as possible if we've already cached the icon information before
if(( $ret = biticon_read_cache( $pParams )) && !( defined( 'TEMPLATE_DEBUG' ) && TEMPLATE_DEBUG == true )) {
return $ret;
}
// first deal with most common scenario: icon style ( a selected iconset from util/iconsets/ )
if( $pParams['ipackage'] == 'icons' ) {
// get the current icon style
// istyle is a private parameter!!! - only used on theme manager page for icon preview!!!
// violators will be poked with soft cushions by the Cardinal himself!!!
$icon_style = !empty( $pParams['istyle'] ) ? $pParams['istyle'] : $gBitSystem->getConfig( 'site_icon_style', DEFAULT_ICON_STYLE );
// Iconsets are SVG-only: serve from scalable/ at ipath-derived dimensions.
// ipath (/small/, /medium/, /large/) is preserved for cache key differentiation.
$pParams['isize'] = trim( $pParams['ipath'], '/' );
if( false !== ( $matchFile = biticon_first_match( UTIL_PKG_PATH."iconsets/$icon_style/scalable/", $pParams['iname'], ['svg'] ))) {
return biticon_output( $pParams, UTIL_PKG_URL."iconsets/$icon_style/scalable/".$matchFile );
}
if( $icon_style != DEFAULT_ICON_STYLE && false !== ( $matchFile = biticon_first_match( UTIL_PKG_PATH."iconsets/".DEFAULT_ICON_STYLE."/scalable/", $pParams['iname'], ['svg'] ))) {
return biticon_output( $pParams, UTIL_PKG_URL."iconsets/".DEFAULT_ICON_STYLE."/scalable/".$matchFile );
}
// if that didn't work, we'll try liberty
$pParams['ipath'] = '/'.$gBitSystem->getConfig( 'site_icon_size', 'small' ).'/';
$pParams['ipackage'] = 'liberty';
}
// since package icons reside in /icons/ we don't need the small/ subdir
if( strstr( "/small/", $pParams['ipath'] )) {
$pParams['ipath'] = str_replace( "small/", "", $pParams['ipath'] );
$small = true;
}
// first check themes/force
if( false !== ( $matchFile = biticon_first_match( THEMES_PKG_PATH."force/icons/".$pParams['ipackage'].$pParams['ipath'], $pParams['iname'] ))) {
return biticon_output( $pParams, BIT_ROOT_URL."themes/force/icons/".$pParams['ipackage'].$pParams['ipath'].$matchFile );
}
//if we have site styles, look there
if( false !== ( $matchFile = biticon_first_match( $gBitThemes->getStylePath().'icons/'.$pParams['ipackage'].$pParams['ipath'], $pParams['iname'] ))) {
return biticon_output( $pParams, $gBitThemes->getStyleUrl().'icons/'.$pParams['ipackage'].$pParams['ipath'].$matchFile );
}
//Well, then lets look in the package location
if( false !== ( $matchFile = biticon_first_match( constant( strtoupper( $pParams['ipackage'] ).'_PKG_PATH' )."icons".$pParams['ipath'], $pParams['iname'] ))) {
return biticon_output( $pParams, constant( strtoupper( $pParams['ipackage'] ).'_PKG_URL' )."icons".$pParams['ipath'].$matchFile );
}
// Still didn't find it! Well lets output something (return empty string if only the url is requested)
if( isset( $pParams['url'] )) {
return '';
}
if( empty( $pSmall ) ) {
// if we were looking for the large icon, we'll try the whole kaboodle again, looking for the small icon
$copyParams['ipath'] = preg_replace( "!/.*?/$!", "/small/", $pParams['ipath'] );
return smarty_function_biticon( $copyParams, true );
}
return biticon_output( $pParams, '' );
}
/**
* biticon_cache
*
* @param array $pParams
* @access public
* @return string cached icon string on sucess, false on failure
*/
function biticon_read_cache( $pParams ) {
$ret = false;
$cacheFile = biticon_get_cache_file( $pParams );
if( is_readable( $cacheFile )) {
if( $h = fopen( $cacheFile, 'r' )) {
$ret = fread( $h, filesize( $cacheFile ));
fclose( $h );
}
}
return $ret;
}
/**
* biticon_write_cache
*
* @param array $pParams
* @access public
* @return bool true on success, false on failure
*/
function biticon_write_cache( $pParams, $pCacheString ) {
$ret = false;
if( $cacheFile = biticon_get_cache_file( $pParams )) {
if( $h = fopen( $cacheFile, 'w' )) {
$ret = fwrite( $h, $pCacheString );
fclose( $h );
}
}
return $ret;
}
/**
* will get the path to the cache files based on the stuff in $pParams
*
* @param array $pParams
* @access public
* @return string full path to cachefile
*/
function biticon_get_cache_file( $pParams ) {
global $gBitThemes, $gBitSystem;
// create a hash filename based on the parameters given
$hashstring = '';
$ihash = [ 'iforce', 'ipath', 'iname', 'iexplain', 'ipackage', 'url', 'istyle', 'id', 'style', 'onclick' ];
foreach( $pParams as $param => $value ) {
if( in_array( $param, $ihash )) {
$hashstring .= strtolower( $value ?? '' );
}
}
// return path to cache file
return $gBitThemes->getIconCachePath().md5( $hashstring.$gBitSystem->getConfig( 'site_biticon_display_style', 'icon' ));
}