One+Two --(you)--> One Two). * * @param array $pParamHash array to be cleaned * @param bool $pHtml set true to escape HTML code as well * @param bool $pUrldecode set true to urldecode as well * @access public * @return void */ public static function detoxify( array &$pParamHash, bool $pHtml = false, bool $pUrldecode = true): void { if( !empty( $pParamHash ) && is_array( $pParamHash ) ) { foreach( $pParamHash as $key => $value ) { if( isset( $value ) && is_array( $value ) ) { KernelTools::detoxify( $value, $pHtml, $pUrldecode ); } else { if( $pHtml ) { $newValue = $pUrldecode ? urldecode( $value ) : $value; $pParamHash[$key] = htmlspecialchars( $newValue, ENT_NOQUOTES ); } elseif( preg_match( "/]*>/i", urldecode( $value ?? '' ) ) ) { unset( $pParamHash[$key] ); } } } } } /** * file_name_to_title * * @param string $pFileName * @access public * @return string clean file name that can be used as title */ public static function file_name_to_title( $pFileName ): string { if( preg_match( '/^[A-Z]:\\\/', $pFileName ) ) { // MSIE shit file names if passthrough via gigaupload, etc. // basename will not work - see http://us3.php.net/manual/en/function.basename.php $tmp = preg_split("[\\\]",$pFileName); $defaultName = $tmp[count($tmp) - 1]; } elseif( strpos( '.', $pFileName ) ) { list( $defaultName, $ext ) = explode( '.', $pFileName ); } else { $defaultName = $pFileName; } return str_replace( '_', ' ', substr( $defaultName, 0, strrpos( $defaultName, '.' ) ) ); } /** * path_to_url * * @param string $pPath Relative path starting in the bitweaver root directory * @access public * @return string A valid url based on the given path */ public static function storage_path_to_url( $pPath ) { global $gBitSystem; return STORAGE_HOST_URI.STORAGE_PKG_URL.str_replace( '//', '/', str_replace( '+', '%20', str_replace( '%2F', '/', urlencode( $pPath )))); } /** * simple function to include in deprecated function calls. makes the developer replace with newer code * * @param string $pReplace code that needs replacing * @return void */ public static function deprecated( ?string $pReplace = null ): void { $trace = debug_backtrace(); $function = !empty( $trace[1]['class'] ) ? $trace[1]['class']."::".$trace[1]['function'] : $trace[1]['function']; $out = "Deprecated function call:\n\tfunction: $function()\n\tfile: ".$trace[1]['file']."\n\tline: ".$trace[1]['line']; if( !empty( $pReplace ) ) { $out .= "\n\t".str_replace( "\n", "\n\t", $pReplace ); } if( !defined( 'IS_LIVE' ) || IS_LIVE == false ) { vd( $out, false, true ); } else { error_log( $out ); } } /** * Check that function is enabled on server. * @access public * @return bool true if function is enabled on server, false otherwise */ public static function function_enabled ( $pName ) { static $disabled = null; if( $disabled == null ) { $functions = @ini_get( 'disable_functions' ); $functions = str_replace( ' ', '', $functions ); $disabled = explode( ',', $functions ); } return !( in_array( $pName, $disabled )); } public static function verify_hex_color( $pColor ) { $ret = null; if( preg_match('/^#[a-f0-9][6]$/i', $pColor) ) { $ret = $pColor; } elseif( preg_match('/^[a-f0-9][6]$/i', $pColor)) { //Check for a hex color string without hash 'c1c2b4' $ret = '#' . $pColor; } elseif( preg_match('/^#[a-f0-9][3]$/i', $pColor) ) { $ret = $pColor; } elseif( preg_match('/^[a-f0-9][3]$/i', $pColor)) { //Check for a hex color string without hash 'fff' $ret = '#' . $pColor; } return $ret; } /** * html encode all characters * taken from: http://www.bbsinc.com/iso8859.html * * @param string $pData string that might contain an email address * @access public * @return string encoded email address * $note email regex taken from: http://www.regular-expressions.info/regexbuddy/email.html */ public static function encode_email_addresses( $pData ) { $trans = [ // Upper case 'A' => 'A', 'B' => 'B', 'C' => 'C', 'D' => 'D', 'E' => 'E', 'F' => 'F', 'G' => 'G', 'H' => 'H', 'I' => 'I', 'J' => 'J', 'K' => 'K', 'L' => 'L', 'M' => 'M', 'N' => 'N', 'O' => 'O', 'P' => 'P', 'Q' => 'Q', 'R' => 'R', 'S' => 'S', 'T' => 'T', 'U' => 'U', 'V' => 'V', 'W' => 'W', 'X' => 'X', 'Y' => 'Y', 'Z' => 'Z', // lower case 'a' => 'a', 'b' => 'b', 'c' => 'c', 'd' => 'd', 'e' => 'e', 'f' => 'f', 'g' => 'g', 'h' => 'h', 'i' => 'i', 'j' => 'j', 'k' => 'k', 'l' => 'l', 'm' => 'm', 'n' => 'n', 'o' => 'o', 'p' => 'p', 'q' => 'q', 'r' => 'r', 's' => 's', 't' => 't', 'u' => 'u', 'v' => 'v', 'w' => 'w', 'x' => 'x', 'y' => 'y', 'z' => 'z', // digits '0' => '0', '1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', // special chars '_' => '_', '-' => '-', '.' => '.', '@' => '@', //'[' => '[', //']' => ']', //'|' => '|', //'{' => '{', //'}' => '}', //'~' => '~', ]; preg_match_all( "!\b".EMAIL_ADDRESS_REGEX."\b!", $pData, $addresses ); foreach( $addresses[0] as $address ) { $encoded = strtr( $address, $trans ); $pData = preg_replace( "/\b".preg_quote( $address )."\b/", $encoded, $pData ); } return $pData; } /** * validate email syntax * php include as a string * * @param $pEmail the file to include * @return string A string with the results of the file **/ public static function validate_email_syntax( $pEmail ) { return preg_match( "!^".EMAIL_ADDRESS_REGEX."$!", trim( $pEmail )); } /** * get_include_contents -- handy function for getting the contents of a * php include as a string * * @param $pFile the file to include * @return string A string with the results of the file **/ public static function get_include_contents($pFile) { if( is_file( $pFile )) { ob_start(); global $gContent, $gBitSystem, $gBitSmarty, $gLibertySystem, $gBitUser; include $pFile; $contents = ob_get_contents(); ob_end_clean(); return $contents; } return false; } /** * Translate a string * * @param string $pString String that needs to be translated * @access public * @return string */ public static function tra( $pString ) { global $gBitLanguage; return $gBitLanguage->translate( $pString ); } /** * recursively remove files and directories * * @param string $pPath directory we want to remove * @param boolean $pFollowLinks follow symlinks or not * @access public * @return bool true on success, false on failure */ public static function unlink_r( $pPath, $pFollowLinks = false ) { if( !empty( $pPath ) && is_dir( $pPath ) ) { if( $dir = opendir( $pPath ) ) { while( false !== ( $entry = readdir( $dir ) ) ) { if( is_file( "$pPath/$entry" ) || ( !$pFollowLinks && is_link( "$pPath/$entry" ) ) ) { @unlink( "$pPath/$entry" ); } elseif( is_dir( "$pPath/$entry" ) && $entry != '.' && $entry != '..' ) { KernelTools::unlink_r( "$pPath/$entry" ) ; } } closedir( $dir ) ; } return @rmdir( $pPath ); } return false; } /** * recursively copy the contents of a directory to a new location akin to copy -r * * @param string $pSource source directory * @param string $pTarget target directory * @access public * @return void */ public static function copy_r( $pSource, $pTarget ) { if( is_dir( $pSource )) { @KernelTools::mkdir_p( $pTarget ); $d = dir( $pSource ); while( false !== ( $entry = $d->read() )) { if( $entry == '.' || $entry == '..' ) { continue; } $source = $pSource.'/'.$entry; if( is_dir( $source )) { KernelTools::copy_r( $source, $pTarget.'/'.$entry ); continue; } copy( $source, $pTarget.'/'.$entry ); } $d->close(); } else { copy( $pSource, $pTarget ); } } /** * Fetch the contents of a file on a remote host * * @param string $pUrl url to file to fetch * @param boolean $pNoCurl skip the use of curl if this causes problems * @access public * @return false on failure, contents of file on success */ public static function bit_http_request( $pUrl, $pNoCurl = false ) { global $gBitSystem; $ret = false; if( !empty( $pUrl )) { $pUrl = trim( $pUrl ); // rewrite url if sloppy # added a case for https urls if( !preg_match( "!^https?://!", $pUrl )) { $pUrl = "http://".$pUrl; } if( !preg_match("/^[-_a-zA-Z0-9:\/\.\?&;%=\+]*$/", $pUrl )) { return false; } // try using curl first as it allows the use of a proxy if( !$pNoCurl && function_exists( 'curl_init' )) { $curl = curl_init(); curl_setopt( $curl, CURLOPT_URL, $pUrl ); curl_setopt( $curl, CURLOPT_HEADER, 0 ); curl_setopt( $curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT'] ); curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, 1 ); curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt( $curl, CURLOPT_TIMEOUT, 5 ); // Proxy settings if( $gBitSystem->isFeatureActive( 'site_use_proxy' )) { curl_setopt( $curl, CURLOPT_PROXY, $gBitSystem->getConfig( 'site_proxy_host' )); curl_setopt( $curl, CURLOPT_PROXYPORT, $gBitSystem->getConfig( 'site_proxy_port' )); curl_setopt( $curl, CURLOPT_HTTPPROXYTUNNEL, 1); } $ret = curl_exec( $curl ); curl_close( $curl ); } else { // try using fsock now $parsed = parse_url( $pUrl ); if( $fsock = @fsockopen( $parsed['host'], 80, $error['number'], $error['string'], 5 )) { @fwrite( $fsock, "GET ".$parsed['path'].( !empty( $parsed['query'] ) ? '?'.$parsed['query'] : '' )." HTTP/1.1\r\n" ); @fwrite( $fsock, "HOST: {$parsed['host']}\r\n" ); @fwrite( $fsock, "Connection: close\r\n\r\n" ); $get_info = false; while( !@feof( $fsock )) { if( $get_info ) { $ret .= @fread( $fsock, 1024 ); } else { if( @fgets( $fsock, 1024 ) == "\r\n" ) { $get_info = true; } } } @fclose( $fsock ); if( !empty( $error['string'] )) { return false; } } } } return $ret; } /** * Parse XML Attributes and return an array * * this function has a whopper of a RegEx. * I nabbed it from http://www.phpbuilder.com/annotate/message.php3?id=1000234 - XOXO spiderr * * @param string $pString XML type string of parameters * @access public * @return array */ public static function parse_xml_attributes( string $pString ): array { //$parameters = [ '', '' ]; $parameters = []; $regexp_str = "/([A-Za-z0-9_-]+)(?:\\s*=\\s*(?:(\"|\')((?:[\\\\].|[^\\\\]?)*?)(?:\\2)|([^=\\s]*)))?/"; preg_match_all( $regexp_str, $pString, $matches, PREG_SET_ORDER ); foreach( $matches as $key => $match ) { $attrib = $match[1]; $value = $match[sizeof( $match )-1]; // The value can be at different indexes because of optional quotes, but we know it's always at the end. $value = preg_replace( "/\\\\(.)/","\\1",$value ); $parameters[$attrib] = trim( $value, '\"' ); } return $parameters; } /** * XML Entity Mandatory Escape Characters * * @param string $string * @param int $quote_style * @access public * @return string */ public static function xmlentities( string $string, int $quote_style=ENT_QUOTES ): string { static $trans; if( !isset( $trans )) { $trans = get_html_translation_table( HTML_ENTITIES, $quote_style ); foreach( $trans as $key => $value ) { $trans[$key] = '&#'.ord( $key ).';'; } // dont translate the '&' in case it is part of &xxx; $trans[chr(38)] = '&'; } // after the initial translation, _do_ map standalone '&' into '&' return preg_replace( "/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,5};)/","&" , strtr( $string, $trans )); } /** * Redirect to another page or site * @param string The url to redirect to */ public static function bit_redirect( $pUrl, $pStatusCode=HttpStatusCodes::HTTP_FOUND ) { // Handle non-3xx codes separately if( $pStatusCode && isset( $errors[$pStatusCode] ) ) { header( HttpStatusCodes::httpHeaderFor( $pStatusCode ) ); $pStatusCode = null; } global $gBitUser; if( is_object( $gBitUser ) ) { // apache_setenv( 'USERID', $gBitUser->getField('login', '-'), true ); } if( empty($pUrl) ) { return; } // clean up URL before executing it while( strstr( $pUrl, '&&' ) ) { $pUrl = str_replace( '&&', '&', $pUrl ); } while( strstr( $pUrl, '&&' ) ) { $pUrl = str_replace( '&&', '&', $pUrl ); } // header locates should not have the & in the address it breaks things while( strstr( $pUrl, '&' ) ) { $pUrl = str_replace( '&', '&', $pUrl ); } if( $pStatusCode ) { header( 'Location: ' . $pUrl, true, $pStatusCode ); } else { header( 'Location: ' . $pUrl ); } session_write_close(); exit(); } /** * array_diff_keys * * @access public */ public static function array_diff_keys() { $args = func_get_args(); $res = $args[0]; if( !is_array( $res )) { return []; } for( $i = 1; $i < count( $args ); $i++ ) { if( !is_array( $args[$i] )) { continue; } foreach( $args[$i] as $key => $data ) { unset( $res[$key] ); } } return $res; } /** * trim_array * * @param array $pArray * @access public */ public static function trim_array( &$pArray ) { if( is_array( $pArray ) ) { foreach( array_keys( $pArray ) as $key ) { if( is_string( $pArray[$key] ) ) { $pArray[$key] = trim( $pArray[$key] ); } } } } /** * ordinalize * * @param numeric $num Number to append th, st, nd, rd to - only makes sense when languages is english * @access public */ public static function ordinalize( $num ) { $ord = ''; if( is_numeric( $num ) ) { if( $num >= 11 and $num <= 19 ) { $ord = KernelTools::tra( "th" ); } elseif( $num % 10 == 1 ) { $ord = KernelTools::tra( "st" ); } elseif( $num % 10 == 2 ) { $ord = KernelTools::tra( "nd" ); } elseif( $num % 10 == 3 ) { $ord = KernelTools::tra( "rd" ); } else { $ord = KernelTools::tra( "th" ); } } return $num.$ord; } /** * Cleans file path according to system we're on * * @param string $pPath * @access public * @return string */ public static function clean_file_path( string $pPath ): string { $pPath = !empty($_SERVER["SERVER_SOFTWARE"]) && strpos($_SERVER["SERVER_SOFTWARE"],"IIS") ? str_replace( '\/', '\\', $pPath) : $pPath; return $pPath; } public static function httpScheme() { return 'http'.( ( isset($_SERVER['HTTPS'] ) && ( $_SERVER['HTTPS'] == 'on' ) ) ? 's' : '' ); } public static function httpPrefix() { return KernelTools::httpScheme().'://'.$_SERVER['HTTP_HOST']; } /** * If an unrecoverable error has occurred, this method should be invoked. script exist occurs * * @param string $ pMsg error message to be displayed * @return void this function will DIE DIE DIE!!! * @access public */ public static function install_error( $pMsg = null ) { global $gBitDbType; // here we decide where to go. if there are no db settings yet, we go the welcome page. $step = isset( $gBitDbType ) ? 1 : 0; header( "Location: ".KernelTools::httpPrefix().BIT_ROOT_URL."install/install.php?step=".$step ); die; } /** * pear_check will check to see if a given PEAR module is installed * * @param string $pPearModule The name of the module in the format: Image/GraphViz.php * @access public * @return string with error message on failure, null on success */ public static function pear_check( $pPearModule = null ) { if( !@include_once "PEAR.php") { return KernelTools::tra( "PEAR is not installed." ); } elseif( !empty( $pPearModule ) && !@include_once $pPearModule ) { $module = str_replace( ".php", "", str_replace( "/", "_", $pPearModule )); return KernelTools::tra( "The PEAR plugin $module is not installed. Install it with 'pear install $module' or use your distribution's package manager."); } return null; } /** * A set of compare functions that can be used in conjunction with usort() type functions * * @param array $ar1 * @param array $ar2 * @access public * @return bool true on success, false on failure */ public static function usort_by_title( $ar1, $ar2 ) { if( !empty( $ar1['title'] ) && !empty( $ar2['title'] ) ) { return strcasecmp( $ar1['title'], $ar2['title'] ); } return 0; } public static function compare_links( $ar1, $ar2 ) { return $ar1["links"] - $ar2["links"]; } public static function compare_backlinks( $ar1, $ar2 ) { return $ar1["backlinks"] - $ar2["backlinks"]; } public static function r_compare_links( $ar1, $ar2 ) { return $ar2["links"] - $ar1["links"]; } public static function r_compare_backlinks( $ar1, $ar2 ) { return $ar2["backlinks"] - $ar1["backlinks"]; } public static function compare_images( $ar1, $ar2 ) { return $ar1["images"] - $ar2["images"]; } public static function r_compare_images( $ar1, $ar2 ) { return $ar2["images"] - $ar1["images"]; } public static function compare_files( $ar1, $ar2 ) { return $ar1["files"] - $ar2["files"]; } public static function r_compare_files( $ar1, $ar2 ) { return $ar2["files"] - $ar1["files"]; } public static function compare_versions( $ar1, $ar2 ) { return $ar1["versions"] - $ar2["versions"]; } public static function r_compare_versions( $ar1, $ar2 ) { return $ar2["versions"] - $ar1["versions"]; } public static function compare_changed( $ar1, $ar2 ) { return $ar1["lastChanged"] - $ar2["lastChanged"]; } public static function r_compare_changed( $ar1, $ar2 ) { return $ar2["lastChanged"] - $ar1["lastChanged"]; } // ======================= deprecated functions ======================= /** * @deprecated deprecated since version 2.1.0-beta */ public static function chkgd2() { KernelTools::deprecated( 'Please use get_gd_version() instead' ); } }