1<?php 2# MantisBT - A PHP based bugtracking system 3 4# MantisBT is free software: you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation, either version 2 of the License, or 7# (at your option) any later version. 8# 9# MantisBT is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with MantisBT. If not, see <http://www.gnu.org/licenses/>. 16 17/** 18 * Utility API 19 * 20 * Utility functions are *small* functions that are used often and therefore 21 * have *no* prefix, to keep their names short. 22 * 23 * Utility functions have *no* dependencies on any other APIs, since they are 24 * included first in order to make them available to all the APIs. 25 * Miscellaneous functions that provide functionality on top of other APIS 26 * are found in the helper_api. 27 * 28 * @package CoreAPI 29 * @subpackage UtilityAPI 30 * @copyright Copyright 2000 - 2002 Kenzaburo Ito - kenito@300baud.org 31 * @copyright Copyright 2002 MantisBT Team - mantisbt-dev@lists.sourceforge.net 32 * @link http://www.mantisbt.org 33 * 34 * @uses config_api.php 35 * @uses constant_inc.php 36 * @uses error_api.php 37 */ 38 39require_api( 'config_api.php' ); 40require_api( 'constant_inc.php' ); 41require_api( 'error_api.php' ); 42 43/** 44 * converts a 1 value to X 45 * converts a 0 value to a space 46 * @param integer $p_num A numeric to translate as a boolean for display. 47 * @return string X or space 48 * @access public 49 */ 50function trans_bool( $p_num ) { 51 if( 0 == $p_num ) { 52 return ' '; 53 } else { 54 return icon_get( 'fa-check', 'fa-lg' ); 55 } 56} 57 58/** 59 * Add a trailing DIRECTORY_SEPARATOR to a string if it isn't present 60 * @param string $p_path A string representing a file system path. 61 * @return string 62 * @access public 63 */ 64function terminate_directory_path( $p_path ) { 65 return rtrim( $p_path, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR; 66} 67 68/** 69 * Return true if the parameter is an empty string or a string 70 * containing only whitespace, false otherwise 71 * @param string $p_var String to test whether it is blank. 72 * @return boolean 73 * @access public 74 */ 75function is_blank( $p_var ) { 76 $p_var = trim( $p_var ); 77 $t_str_len = strlen( $p_var ); 78 if( 0 == $t_str_len ) { 79 return true; 80 } 81 return false; 82} 83 84/** 85 * Get the named php ini variable but return it as a boolean 86 * @param string $p_name A php.ini variable to evaluate. 87 * @return boolean 88 * @access public 89 */ 90function ini_get_bool( $p_name ) { 91 $t_result = ini_get( $p_name ); 92 93 if( is_string( $t_result ) ) { 94 switch( strtolower( $t_result ) ) { 95 case 'off': 96 case 'false': 97 case 'no': 98 case 'none': 99 case '': 100 case '0': 101 return false; 102 break; 103 case 'on': 104 case 'true': 105 case 'yes': 106 case '1': 107 return true; 108 break; 109 } 110 } 111 return (bool)$t_result; 112} 113 114/** 115 * Get the named php.ini variable but return it as a number after converting 116 * the giga (g/G), mega (m/M) and kilo (k/K) postfixes. These postfixes do not 117 * adhere to IEEE 1541 in that k=1024, not k=1000. For more information see 118 * http://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes 119 * @param string $p_name Name of the configuration option to read. 120 * @return int Integer value of the configuration option. 121 * @access public 122 */ 123function ini_get_number( $p_name ) { 124 $t_value = ini_get( $p_name ); 125 126 switch( substr( $t_value, -1 ) ) { 127 case 'G': 128 case 'g': 129 $t_result = (int)$t_value * 1073741824; 130 break; 131 case 'M': 132 case 'm': 133 $t_result = (int)$t_value * 1048576; 134 break; 135 case 'K': 136 case 'k': 137 $t_result = (int)$t_value * 1024; 138 break; 139 default: 140 $t_result = (int)$t_value; 141 break; 142 } 143 return $t_result; 144} 145 146/** 147 * Sort a multi-dimensional array by one of its keys 148 * @param array $p_array Array to sort. 149 * @param string $p_key Array key to sort array on. 150 * @param integer $p_direction Sort direction. 151 * @return array sorted array 152 * @access public 153 */ 154function multi_sort( array $p_array, $p_key, $p_direction = ASCENDING ) { 155 if( DESCENDING == $p_direction ) { 156 $t_factor = -1; 157 } else { 158 # might as well allow everything else to mean ASC rather than erroring 159 $t_factor = 1; 160 } 161 162 if( empty( $p_array ) ) { 163 return $p_array; 164 } 165 if( !is_array( current( $p_array ) ) ) { 166 error_parameters( 'tried to multisort an invalid multi-dimensional array' ); 167 trigger_error( ERROR_GENERIC, ERROR ); 168 } 169 170 # Security measure: see http://www.mantisbt.org/bugs/view.php?id=9704 for details 171 if( array_key_exists( $p_key, current( $p_array ) ) ) { 172 uasort( 173 $p_array, 174 function( $a, $b ) use( $t_factor, $p_key ) { 175 return $t_factor * strnatcasecmp( $a[$p_key], $b[$p_key] ); 176 } 177 ); 178 } else { 179 trigger_error( ERROR_INVALID_SORT_FIELD, ERROR ); 180 } 181 return $p_array; 182} 183 184/** 185 * Return GD version 186 * It doesn't use gd_info() so it works with PHP < 4.3.0 as well 187 * @return int represents gd version 188 * @access public 189 */ 190function get_gd_version() { 191 $t_GDfuncList = get_extension_funcs( 'gd' ); 192 if( !is_array( $t_GDfuncList ) ) { 193 return 0; 194 } else { 195 if( in_array( 'imagegd2', $t_GDfuncList ) ) { 196 return 2; 197 } else { 198 return 1; 199 } 200 } 201} 202 203/** 204 * return true or false if string matches current page name 205 * @param string $p_string To test against the php script name. 206 * @return boolean 207 * @access public 208 */ 209function is_page_name( $p_string ) { 210 return isset( $_SERVER['SCRIPT_NAME'] ) && ( 0 < strpos( $_SERVER['SCRIPT_NAME'], $p_string ) ); 211} 212 213/** 214 * return true or false if the host operating system is windows 215 * @return boolean 216 * @access public 217 */ 218function is_windows_server() { 219 if( defined( 'PHP_WINDOWS_VERSION_MAJOR' ) ) { 220 return (PHP_WINDOWS_VERSION_MAJOR > 0); 221 } 222 return ('WIN' == substr( PHP_OS, 0, 3 ) ); 223} 224 225/** 226 * return array of class properties (via reflection api) 227 * @param string $p_classname Class name. 228 * @param string $p_type Property type - public/private/protected/static. 229 * @param boolean $p_return_object Whether to return array of property objects. 230 * @param boolean $p_include_parent Whether to include properties of parent classes. 231 * @return array 232 * @access public 233 */ 234function getClassProperties( $p_classname, $p_type = 'public', $p_return_object = false, $p_include_parent = false ) { 235 $t_ref = new ReflectionClass( $p_classname ); 236 $t_props = $t_ref->getProperties(); 237 $t_props_arr = array(); 238 foreach( $t_props as $t_prop ){ 239 $t_name = $t_prop->getName(); 240 if( $t_prop->isPublic() and (stripos( $p_type, 'public' ) === false) ) { 241 continue; 242 } 243 if( $t_prop->isPrivate() and (stripos( $p_type, 'private' ) === false) ) { 244 continue; 245 } 246 if( $t_prop->isProtected() and (stripos( $p_type, 'protected' ) === false) ) { 247 continue; 248 } 249 if( $t_prop->isStatic() and (stripos( $p_type, 'static' ) === false) ) { 250 continue; 251 } 252 if( $p_return_object ) { 253 $t_props_arr[$t_name] = $t_prop; 254 } else { 255 $t_props_arr[$t_name] = true; 256 } 257 } 258 if( $p_include_parent ) { 259 if( $t_parentclass = $t_ref->getParentClass() ) { 260 $t_parent_props_arr = getClassProperties( $t_parentclass->getName() ); 261 if( count( $t_parent_props_arr ) > 0 ) { 262 $t_props_arr = array_merge( $t_parent_props_arr, $t_props_arr ); 263 } 264 } 265 } 266 return $t_props_arr; 267} 268 269/** 270 * return string of system font path 271 * @access public 272 * @return string representing system path to font location 273 */ 274function get_font_path() { 275 $t_font_path = config_get_global( 'system_font_folder' ); 276 if( $t_font_path == '' ) { 277 if( is_windows_server() ) { 278 $t_system_root = $_SERVER['SystemRoot']; 279 if( empty( $t_system_root ) ) { 280 return ''; 281 } else { 282 $t_font_path = $t_system_root . '/fonts/'; 283 } 284 } else { 285 if( file_exists( '/usr/share/fonts/corefonts/' ) ) { 286 $t_font_path = '/usr/share/fonts/corefonts/'; 287 } else if( file_exists( '/usr/share/fonts/truetype/msttcorefonts/' ) ) { 288 $t_font_path = '/usr/share/fonts/truetype/msttcorefonts/'; 289 } else if( file_exists( '/usr/share/fonts/msttcorefonts/' ) ) { 290 $t_font_path = '/usr/share/fonts/msttcorefonts/'; 291 } else { 292 $t_font_path = '/usr/share/fonts/truetype/'; 293 } 294 } 295 } 296 return $t_font_path; 297} 298 299/** 300 * unserialize() with Exception instead of PHP notice. 301 * 302 * When given invalid data, unserialize() throws a PHP notice; this function 303 * relies on a custom error handler to throw an Exception instead. 304 * 305 * @param string $p_string The serialized string. 306 * @return mixed The converted value 307 * 308 * @throws ErrorException 309 */ 310function safe_unserialize( $p_string ) { 311 set_error_handler( 'error_convert_to_exception' ); 312 try { 313 $t_data = unserialize( $p_string ); 314 } 315 catch( ErrorException $e ) { 316 restore_error_handler(); 317 throw $e; 318 } 319 restore_error_handler(); 320 return $t_data; 321} 322