kernel
[ class tree: kernel ] [ index: kernel ] [ all elements ]

Source for file kernel_lib.php

Documentation is available at kernel_lib.php

  1. <?php
  2. /**
  3.  * @version $Header$
  4.  * @package kernel
  5.  * @subpackage functions
  6.  */
  7.  
  8. /**
  9.  * some PHP compatability issues need to be dealt with
  10.  * array_fill
  11.  */
  12. if( !function_exists( 'array_fill' )) {
  13.     require_once( KERNEL_PKG_PATH.'array_fill.func.php' );
  14. }
  15.  
  16. // str_split
  17. include_once( UTIL_PKG_PATH.'PHP_Compat/Compat/Function/str_split.php' );
  18.  
  19. /** \brief  substr with a utf8 string - works only with $start and $length positive or nuls
  20.  * This function is the same as substr but works with multibyte
  21.  * In a multybyte sequence, the first byte of a multibyte sequence that represents a non-ASCII character is always in the range 0xC0 to 0xFD
  22.  * and it indicates how many bytes follow for this character.
  23.  * All further bytes in a multibyte sequence are in the range 0x80 to 0xBF.
  24.  */
  25. /**
  26.  * Check mb_substr availability
  27.  */
  28. if( function_exists( 'mb_substr' )) {
  29.     mb_internal_encoding( "UTF-8" );
  30. } else {
  31.     function mb_substr( $str, $start, $len = '', $encoding = "UTF-8" ) {
  32.         $limit = strlen( $str );
  33.         for( $s = 0; $start > 0;--$start ) {
  34.             if( $s >= $limit ) {
  35.                 break;
  36.             }
  37.  
  38.             if( $str[$s] <= "\x7F" ) {
  39.                 ++$s;
  40.             } else {
  41.                 ++$s; // skip length
  42.                 while( $str[$s] >= "\x80" && $str[$s] <= "\xBF" ) {
  43.                     ++$s;
  44.                 }
  45.             }
  46.         }
  47.         if( $len == '' ) {
  48.             return substr( $str, $s );
  49.         }
  50.         else {
  51.             // found the real end
  52.             for( $e = $s; $len > 0; --$len ) {
  53.                 if( $e >= $limit ) {
  54.                     break;
  55.                 }
  56.  
  57.                 if( $str[$e] <= "\x7F" ) {
  58.                     ++$e;
  59.                 } else {
  60.                     ++$e; //skip length
  61.                     while( $str[$e] >= "\x80" && $str[$e] <= "\xBF" && $e < $limit ) {
  62.                         ++$e;
  63.                     }
  64.                 }
  65.             }
  66.         }
  67.         return substr( $str, $s, $e - $s );
  68.     }
  69. }
  70.  
  71. if( !function_exists( 'file_get_contents' )) {
  72.     function file_get_contents( $pFile ) {
  73.         ob_start();
  74.  
  75.         $retval = @readfile( $pFile );
  76.  
  77.         if( false !== $retval ) { // no readfile error
  78.             $retval = ob_get_contents();
  79.         }
  80.  
  81.         ob_end_clean();
  82.         return $retval;
  83.     }
  84. }
  85.  
  86. /**
  87.  * Return system defined temporary directory.
  88.  * In Unix, this is usually /tmp
  89.  * In Windows, this is usually c:\windows\temp or c:\winnt\temp
  90.  *
  91.  * @access public
  92.  * @return system defined temporary directory.
  93.  */
  94. function get_temp_dir() {
  95.     static $tempdir;
  96.     if( !$tempdir ) {
  97.         global $gTempDir;
  98.         if( !empty( $gTempDir ) ) {
  99.             $tempdir = $gTempDir;
  100.         } else {
  101.             if( !is_windows() ) {
  102.                 $tempfile = tempnam((( @ini_get( 'safe_mode' ))
  103.                             ?( $_SERVER['DOCUMENT_ROOT'] . '/temp/' )
  104.                             :( FALSE )), 'foo' );
  105.                 $tempdir = dirname( $tempfile );
  106.                 @unlink( $tempfile );
  107.             } else {
  108.                 $tempdir = getenv( "TMP" );
  109.             }
  110.         }
  111.     }
  112.     return $tempdir;
  113. }
  114.  
  115. /**
  116.  * is_windows
  117.  *
  118.  * @access public
  119.  * @return TRUE if we are on windows, FALSE otherwise
  120.  */
  121. function is_windows() {
  122.     static $sWindows;
  123.     if( !isset( $sWindows )) {
  124.         $sWindows = substr( PHP_OS, 0, 3 ) == 'WIN';
  125.     }
  126.     return $sWindows;
  127. }
  128.  
  129. /**
  130.  * Recursively create directories
  131.  *
  132.  * @param array $pTarget target directory
  133.  * @param float $pPerms octal permissions
  134.  * @access public
  135.  * @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
  136.  */
  137. function mkdir_p( $pTarget, $pPerms = 0755 ) {
  138.     // clean up input
  139.     $pTarget = str_replace( "//", "/", trim( $pTarget ));
  140.  
  141.     if( empty( $pTarget ) || $pTarget == ';' || $pTarget == "/" ) {
  142.         return FALSE;
  143.     }
  144.  
  145.     if( ini_get( 'safe_mode' )) {
  146.         $pTarget = preg_replace( '/^\/tmp/', $_SERVER['DOCUMENT_ROOT'].'/temp', $pTarget );
  147.     }
  148.  
  149.     if( file_exists( $pTarget ) || is_dir( $pTarget )) {
  150.         return FALSE;
  151.     }
  152.  
  153.     if( !is_windows() ) {
  154.         if( substr( $pTarget, 0, 1 ) != '/' ) {
  155.             $pTarget = "/$pTarget";
  156.         }
  157.  
  158.         if( preg_match( '#\.\.#', $pTarget )) {
  159.             bitdebug( "mkdir_p() - We don't allow '..' in path for security reasons: $pTarget" );
  160.             return FALSE;
  161.         }
  162.     }
  163.  
  164.     $oldu = umask( 0 );
  165.     // make use of PHP5 recursive mkdir feature
  166.     if( version_compare( phpversion(), "5.0.0", ">=" )) {
  167.         @mkdir( $pTarget, $pPerms, TRUE );
  168.         umask( $oldu );
  169.         return TRUE;
  170.     } else {
  171.         if( @mkdir( $pTarget, $pPerms )) {
  172.             bitdebug( "mkdir_p() - creating $pTarget" );
  173.             umask( $oldu );
  174.             return TRUE;
  175.         } else {
  176.             umask( $oldu );
  177.             $parent = substr( $pTarget, 0, ( strrpos( $pTarget, '/' )));
  178.  
  179.             // recursively create parents
  180.             if( mkdir_p( $parent, $pPerms )) {
  181.                 // make the actual target!
  182.                 if( @mkdir( $pTarget, $pPerms )) {
  183.                     return TRUE;
  184.                 } elseif( !is_dir( $pTarget ) ) {
  185.                     error_log( "mkdir() - could not create $pTarget" );
  186.                 }
  187.             }
  188.         }
  189.     }
  190. }
  191.  
  192. /**
  193.  * check to see if particular directories are wroteable by bitweaver
  194.  * added check for Windows - wolff_borg - see http://bugs.php.net/bug.php?id=27609
  195.  *
  196.  * @param array $pPath path to file or dir
  197.  * @access public
  198.  * @return TRUE on success, FALSE on failure
  199.  */
  200. function bw_is_writeable( $pPath ) {
  201.     if( !is_windows() ) {
  202.         return is_writeable( $pPath );
  203.     } else {
  204.         $writeable = FALSE;
  205.         if( is_dir( $pPath )) {
  206.             $rnd = rand();
  207.             $writeable = @fopen( $pPath."/".$rnd, "a" );
  208.             if( $writeable ) {
  209.                 fclose( $writeable );
  210.                 unlink( $pPath."/".$rnd );
  211.                 $writeable = TRUE;
  212.             }
  213.         } else {
  214.             $writeable = @fopen( $pPath,"a" );
  215.             if( $writeable ) {
  216.                 fclose( $writeable );
  217.                 $writeable = TRUE;
  218.             }
  219.         }
  220.         return $writeable;
  221.     }
  222. }
  223.  
  224. /**
  225.  * clean up an array of values and remove any dangerous html - particularly useful for cleaning up $_GET and $_REQUEST.
  226.  * Turn off urldecode when detoxifying $_GET or $_REQUEST - these two are always urldecoded done by PHP itself (check docs).
  227.  * If you urldecode $_GET twice there might be unexpected consequences (like page One%2BTwo --(PHP)--> One+Two --(you)--> One Two).
  228.  *
  229.  * @param array $pParamHash array to be cleaned
  230.  * @param boolean $pHtml set true to escape HTML code as well
  231.  * @param boolean $pUrldecode set true to urldecode as well
  232.  * @access public
  233.  * @return void 
  234.  */
  235. function detoxify( &$pParamHash, $pHtml = FALSE, $pUrldecode = TRUE) {
  236.     if( !empty( $pParamHash ) && is_array( $pParamHash ) ) {
  237.         foreach( $pParamHash as $key => $value ) {
  238.             if( isset( $value ) && is_array( $value ) ) {
  239.                 detoxify( $value, $pHtml, $pUrldecode );
  240.             } else {
  241.                 if( $pHtml ) {
  242.                     $newValue = $pUrldecode ? urldecode( $value ) : $value;
  243.                     $pParamHash[$key] = htmlspecialchars( ( $newValue ), ENT_NOQUOTES );
  244.                 } elseif( preg_match( "/<script[^>]*>/i", urldecode( $value ) ) ) {
  245.                     unset( $pParamHash[$key] );
  246.                 }
  247.             }
  248.         }
  249.     }
  250. }
  251.  
  252. /**
  253.  * file_name_to_title
  254.  *
  255.  * @param string $pFileName 
  256.  * @access public
  257.  * @return clean file name that can be used as title
  258.  */
  259. function file_name_to_title( $pFileName ) {
  260.     if( preg_match( '/^[A-Z]:\\\/', $pFileName ) ) {
  261.             // MSIE shit file names if passthrough via gigaupload, etc.
  262.             // basename will not work - see http://us3.php.net/manual/en/function.basename.php
  263.             $tmp = preg_split("[\\\]",$pFileName);
  264.             $defaultName = $tmp[count($tmp) - 1];
  265.     } elseif( strpos( '.', $pFileName ) ) {
  266.             list( $defaultName, $ext ) = explode( '.', $pFileName );
  267.     } else {
  268.             $defaultName = $pFileName;
  269.     }
  270.     return( str_replace( '_', ' ', substr( $defaultName, 0, strrpos( $defaultName, '.' ) ) ) );
  271. }
  272.  
  273. /**
  274.  * path_to_url
  275.  *
  276.  * @param string $pPath Relative path starting in the bitweaver root directory
  277.  * @access public
  278.  * @return a valid url based on the given path
  279.  */
  280. function storage_path_to_url( $pPath ) {
  281.     global $gBitSystem;
  282.     return( STORAGE_HOST_URI.STORAGE_PKG_URL.str_replace( '//', '/', str_replace( '+', '%20', str_replace( '%2F', '/', urlencode( $pPath )))));
  283. }
  284.  
  285. /**
  286.  * simple function to include in deprecated function calls. makes the developer replace with newer code
  287.  *
  288.  * @param array $pReplace code that needs replacing
  289.  * @access public
  290.  * @return void 
  291.  */
  292. function deprecated( $pReplace = NULL ) {
  293.     $trace = debug_backtrace();
  294.     if( !empty( $trace[1]['class'] )) {
  295.         $function = $trace[1]['class']."::".$trace[1]['function'];
  296.     } else {
  297.         $function = $trace[1]['function'];
  298.     }
  299.     $out = "Deprecated function call:\n\tfunction: $function()\n\tfile: ".$trace[1]['file']."\n\tline: ".$trace[1]['line'];
  300.  
  301.     if( !empty( $pReplace ) ) {
  302.         $out .= "\n\t".str_replace( "\n", "\n\t", $pReplace );
  303.     }
  304.  
  305.     if( !defined( 'IS_LIVE' ) || IS_LIVE == FALSE ) {
  306.         vd( $out, FALSE, TRUE );
  307.     } else {
  308.         error_log( $out );
  309.     }
  310. }
  311.  
  312. /**
  313.  * Check that function is enabled on server.
  314.  * @access public
  315.  * @return TRUE if function is enabled on server, FALSE otherwise
  316.  */
  317. function function_enabled ( $pName ) {
  318.     static $disabled = NULL;
  319.  
  320.     if( $disabled == NULL ) {
  321.         $functions = @ini_get( 'disable_functions' );
  322.         $functions = str_replace( ' ', '', $functions );
  323.         $disabled = explode( ',', $functions );
  324.     }
  325.  
  326.     return !( in_array( $pName, $disabled ));
  327. }
  328.  
  329.  
  330. function verify_hex_color( $pColor ) {
  331.     $ret = NULL;
  332.     
  333.     if( preg_match('/^#[a-f0-9]{6}$/i', $pColor) ) {
  334.         $ret = $pColor;
  335.     } elseif( preg_match('/^[a-f0-9]{6}$/i', $pColor)) {
  336.         //Check for a hex color string without hash 'c1c2b4'
  337.         $ret = '#' . $pColor;
  338.     } elseif( preg_match('/^#[a-f0-9]{3}$/i', $pColor) ) {
  339.         $ret = $pColor;
  340.     } elseif( preg_match('/^[a-f0-9]{3}$/i', $pColor)) {
  341.         //Check for a hex color string without hash 'fff'
  342.         $ret = '#' . $pColor;
  343.     } 
  344.     return $ret;
  345. }
  346.  
  347.  
  348. /**
  349.  * html encode all characters
  350.  * taken from: http://www.bbsinc.com/iso8859.html
  351.  *
  352.  * @param sting $pData string that might contain an email address
  353.  * @access public
  354.  * @return encoded email address
  355.  *  $note email regex taken from: http://www.regular-expressions.info/regexbuddy/email.html
  356.  */
  357. define( 'EMAIL_ADDRESS_REGEX', '[-a-zA-Z0-9._%+]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}' );
  358. function encode_email_addresses( $pData ) {
  359.     $trans = array(
  360.         // Upper case
  361.         'A' => '&#065;',
  362.         'B' => '&#066;',
  363.         'C' => '&#067;',
  364.         'D' => '&#068;',
  365.         'E' => '&#069;',
  366.         'F' => '&#070;',
  367.         'G' => '&#071;',
  368.         'H' => '&#072;',
  369.         'I' => '&#073;',
  370.         'J' => '&#074;',
  371.         'K' => '&#075;',
  372.         'L' => '&#076;',
  373.         'M' => '&#077;',
  374.         'N' => '&#078;',
  375.         'O' => '&#079;',
  376.         'P' => '&#080;',
  377.         'Q' => '&#081;',
  378.         'R' => '&#082;',
  379.         'S' => '&#083;',
  380.         'T' => '&#084;',
  381.         'U' => '&#085;',
  382.         'V' => '&#086;',
  383.         'W' => '&#087;',
  384.         'X' => '&#088;',
  385.         'Y' => '&#089;',
  386.         'Z' => '&#090;',
  387.  
  388.         // lower case
  389.         'a' => '&#097;',
  390.         'b' => '&#098;',
  391.         'c' => '&#099;',
  392.         'd' => '&#100;',
  393.         'e' => '&#101;',
  394.         'f' => '&#102;',
  395.         'g' => '&#103;',
  396.         'h' => '&#104;',
  397.         'i' => '&#105;',
  398.         'j' => '&#106;',
  399.         'k' => '&#107;',
  400.         'l' => '&#108;',
  401.         'm' => '&#109;',
  402.         'n' => '&#110;',
  403.         'o' => '&#111;',
  404.         'p' => '&#112;',
  405.         'q' => '&#113;',
  406.         'r' => '&#114;',
  407.         's' => '&#115;',
  408.         't' => '&#116;',
  409.         'u' => '&#117;',
  410.         'v' => '&#118;',
  411.         'w' => '&#119;',
  412.         'x' => '&#120;',
  413.         'y' => '&#121;',
  414.         'z' => '&#122;',
  415.  
  416.         // digits
  417.         '0' => '&#048;',
  418.         '1' => '&#049;',
  419.         '2' => '&#050;',
  420.         '3' => '&#051;',
  421.         '4' => '&#052;',
  422.         '5' => '&#053;',
  423.         '6' => '&#054;',
  424.         '7' => '&#055;',
  425.         '8' => '&#056;',
  426.         '9' => '&#057;',
  427.  
  428.         // special chars
  429.         '_' => '&#095;',
  430.         '-' => '&#045;',
  431.         '.' => '&#046;',
  432.         '@' => '&#064;',
  433.  
  434.         //'[' => '&#091;',
  435.         //']' => '&#093;',
  436.         //'|' => '&#124;',
  437.         //'{' => '&#123;',
  438.         //'}' => '&#125;',
  439.         //'~' => '&#126;',
  440.     );
  441.     preg_match_all( "!\b".EMAIL_ADDRESS_REGEX."\b!", $pData, $addresses );
  442.     foreach( $addresses[0] as $address ) {
  443.         $encoded = strtr( $address, $trans );
  444.         $pData = preg_replace( "/\b".preg_quote( $address )."\b/", $encoded, $pData );
  445.     }
  446.  
  447.     return $pData;
  448. }
  449.  
  450. /**
  451.  * validate email syntax
  452.  * php include as a string
  453.  *
  454.  * @param $pEmail the file to include
  455.  * @return a string with the results of the file
  456.  ***/
  457. function validate_email_syntax( $pEmail ) {
  458.     return( preg_match( "!^".EMAIL_ADDRESS_REGEX."$!", trim( $pEmail )));
  459. }
  460.  
  461. /**
  462.  * get_include_contents -- handy function for getting the contents of a
  463.  * php include as a string
  464.  *
  465.  * @param $pFile the file to include
  466.  * @return a string with the results of the file
  467.  ***/
  468. function get_include_contents($pFile) {
  469.     if( is_file( $pFile )) {
  470.         ob_start();
  471.         global $gContent, $gBitSystem, $gBitSmarty, $gLibertySystem, $gBitUser;
  472.         include $pFile;
  473.         $contents = ob_get_contents();
  474.         ob_end_clean();
  475.         return $contents;
  476.     }
  477.     return FALSE;
  478. }
  479.  
  480. /**
  481.  * Translate a string
  482.  *
  483.  * @param string $pString String that needs to be translated
  484.  * @access public
  485.  * @return void 
  486.  */
  487. function tra( $pString ) {
  488.     global $gBitLanguage;
  489.     return( $gBitLanguage->translate( $pString ) );
  490. }
  491.  
  492. /**
  493.  * recursively remove files and directories
  494.  *
  495.  * @param string $pPath directory we want to remove
  496.  * @param boolean $pFollowLinks follow symlinks or not
  497.  * @access public
  498.  * @return TRUE on success, FALSE on failure
  499.  */
  500. function unlink_r( $pPath, $pFollowLinks = FALSE ) {
  501.     if( is_dir( $pPath ) ) {
  502.         if( $dir = opendir( $pPath ) ) {
  503.             while( FALSE !== ( $entry = readdir( $dir ) ) ) {
  504.                 if( is_file( "$pPath/$entry" ) || ( !$pFollowLinks && is_link( "$pPath/$entry" ) ) ) {
  505.                     unlink( "$pPath/$entry" );
  506.                 } elseif( is_dir( "$pPath/$entry" ) && $entry != '.' && $entry != '..' ) {
  507.                     unlink_r( "$pPath/$entry" ) ;
  508.                 }
  509.             }
  510.             closedir( $dir ) ;
  511.         }
  512.         return @rmdir( $pPath );
  513.     }
  514. }
  515.  
  516. /**
  517.  * recursively copy the contents of a directory to a new location akin to copy -r
  518.  *
  519.  * @param array $pSource source directory
  520.  * @param array $pTarget target directory
  521.  * @access public
  522.  * @return void 
  523.  */
  524. function copy_r( $pSource, $pTarget ) {
  525.     if( is_dir( $pSource )) {
  526.         @mkdir_p( $pTarget );
  527.         $d = dir( $pSource );
  528.  
  529.         while( FALSE !== ( $entry = $d->read() )) {
  530.             if( $entry == '.' || $entry == '..' ) {
  531.                 continue;
  532.             }
  533.  
  534.             $source = $pSource.'/'.$entry;
  535.             if( is_dir( $source )) {
  536.                 copy_r( $source, $pTarget.'/'.$entry );
  537.                 continue;
  538.             }
  539.             copy( $source, $pTarget.'/'.$entry );
  540.         }
  541.  
  542.         $d->close();
  543.     } else {
  544.         copy( $pSource, $pTarget );
  545.     }
  546. }
  547.  
  548. /**
  549.  * Fetch the contents of a file on a remote host
  550.  *
  551.  * @param string $pUrl url to file to fetch
  552.  * @param boolean $pNoCurl skip the use of curl if this causes problems
  553.  * @access public
  554.  * @return FALSE on failure, contents of file on success
  555.  */
  556. function bit_http_request( $pUrl, $pNoCurl = FALSE ) {
  557.     global $gBitSystem;
  558.     $ret = FALSE;
  559.  
  560.     if( !empty( $pUrl )) {
  561.         $pUrl = trim( $pUrl );
  562.  
  563.         // rewrite url if sloppy # added a case for https urls
  564.         if( !preg_match( "!^https?://!", $pUrl )) {
  565.             $pUrl = "http://".$pUrl;
  566.         }
  567.  
  568.         if( !preg_match("/^[-_a-zA-Z0-9:\/\.\?&;%=\+]*$/", $pUrl )) {
  569.             return FALSE;
  570.         }
  571.  
  572.         // try using curl first as it allows the use of a proxy
  573.         if( !$pNoCurl && function_exists( 'curl_init' )) {
  574.             $curl = curl_init();
  575.             curl_setopt( $curl, CURLOPT_URL, $pUrl );
  576.             curl_setopt( $curl, CURLOPT_HEADER, 0 );
  577.             curl_setopt( $curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT'] );
  578.             curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, 1 );
  579.             curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 );
  580.             curl_setopt( $curl, CURLOPT_TIMEOUT, 5 );
  581.  
  582.             // Proxy settings
  583.             if( $gBitSystem->isFeatureActive( 'site_use_proxy' )) {
  584.                 curl_setopt( $curl, CURLOPT_PROXY, $gBitSystem->getConfig( 'site_proxy_host' ));
  585.                 curl_setopt( $curl, CURLOPT_PROXYPORT, $gBitSystem->getConfig( 'site_proxy_port' ));
  586.                 curl_setopt( $curl, CURLOPT_HTTPPROXYTUNNEL, 1);
  587.             }
  588.  
  589.             $ret = curl_exec( $curl );
  590.             curl_close( $curl );
  591.         } else {
  592.             // try using fsock now
  593.             $parsed = parse_url( $pUrl );
  594.             if( $fsock = @fsockopen( $parsed['host'], 80, $error['number'], $error['string'], 5 )) {
  595.                 @fwrite( $fsock, "GET ".$parsed['path'].( !empty( $parsed['query'] ) ? '?'.$parsed['query'] : '' )." HTTP/1.1\r\n" );
  596.                 @fwrite( $fsock, "HOST: {$parsed['host']}\r\n" );
  597.                 @fwrite( $fsock, "Connection: close\r\n\r\n" );
  598.  
  599.                 $get_info = FALSE;
  600.                 while( !@feof( $fsock )) {
  601.                     if( $get_info ) {
  602.                         $ret .= @fread( $fsock, 1024 );
  603.                     } else {
  604.                         if( @fgets( $fsock, 1024 ) == "\r\n" ) {
  605.                             $get_info = TRUE;
  606.                         }
  607.                     }
  608.                 }
  609.                 @fclose( $fsock );
  610.                 if( !empty( $error['string'] )) {
  611.                     return FALSE;
  612.                 }
  613.             }
  614.         }
  615.     }
  616.  
  617.     return $ret;
  618. }
  619.  
  620. /**
  621.  * Parse XML Attributes and return an array
  622.  *
  623.  * this function has a whopper of a RegEx.
  624.  * I nabbed it from http://www.phpbuilder.com/annotate/message.php3?id=1000234 - XOXO spiderr
  625.  *
  626.  * @param array $pString XML type string of parameters
  627.  * @access public
  628.  * @return TRUE on success, FALSE on failure
  629.  */
  630. function parse_xml_attributes( $pString ) {
  631.     //$parameters = array( '', '' );
  632.     $parameters = array();
  633.     $regexp_str = "/([A-Za-z0-9_-]+)(?:\\s*=\\s*(?:(\"|\')((?:[\\\\].|[^\\\\]?)*?)(?:\\2)|([^=\\s]*)))?/";
  634.     preg_match_all( $regexp_str, $pString, $matches, PREG_SET_ORDER );
  635.     while( list( $key, $match ) = each( $matches ) ) {
  636.         $attrib = $match[1];
  637.         $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.
  638.         $value = preg_replace( "/\\\\(.)/","\\1",$value );
  639.         $parameters[$attrib] = trim( $value, '\"' );
  640.     }
  641.     return $parameters;
  642. }
  643.  
  644. /**
  645.  * XML Entity Mandatory Escape Characters
  646.  *
  647.  * @param array $string 
  648.  * @param array $quote_style 
  649.  * @access public
  650.  * @return TRUE on success, FALSE on failure
  651.  */
  652. function xmlentities( $string, $quote_style=ENT_QUOTES ) {
  653.     static $trans;
  654.     if( !isset( $trans )) {
  655.         $trans = get_html_translation_table( HTML_ENTITIES, $quote_style );
  656.         foreach( $trans as $key => $value ) {
  657.             $trans[$key] = '&#'.ord( $key ).';';
  658.         }
  659.  
  660.         // dont translate the '&' in case it is part of &xxx;
  661.         $trans[chr(38)] = '&';
  662.     }
  663.  
  664.     // after the initial translation, _do_ map standalone '&' into '&#38;'
  665.     return preg_replace( "/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,5};)/","&#38;" , strtr( $string, $trans ));
  666. }
  667.  
  668. /**
  669.  * Redirect to another page or site
  670.  * @param string The url to redirect to
  671.  */
  672. function bit_redirect( $pUrl, $pStatusCode=HttpStatusCodes::HTTP_FOUND ) {
  673.     // Handle non-3xx codes separately
  674.     if( $pStatusCode && isset( $errors[$pStatusCode] ) ) {
  675.         header( HttpStatusCodes::httpHeaderFor( $pStatusCode ) );
  676.         $pStatusCode = NULL;
  677.     }
  678.  
  679.     // clean up URL before executing it
  680.     while( strstr( $pUrl, '&&' ) ) {
  681.         $pUrl = str_replace( '&&', '&', $pUrl );
  682.     }
  683.  
  684.     while( strstr( $pUrl, '&amp;&amp;' ) ) {
  685.         $pUrl = str_replace( '&amp;&amp;', '&amp;', $pUrl );
  686.     }
  687.  
  688.     // header locates should not have the &amp; in the address it breaks things
  689.     while( strstr( $pUrl, '&amp;' ) ) {
  690.         $pUrl = str_replace( '&amp;', '&', $pUrl );
  691.     }
  692.  
  693.     if( $pStatusCode ) {
  694.         header( 'Location: ' . $pUrl, TRUE, $pStatusCode );
  695.     } else {
  696.         header( 'Location: ' . $pUrl );
  697.     }
  698.     exit();
  699. }
  700.  
  701. /**
  702.  * array_diff_keys
  703.  *
  704.  * @access public
  705.  */
  706. function array_diff_keys() {
  707.     $args = func_get_args();
  708.  
  709.     $res = $args[0];
  710.     if( !is_array( $res )) {
  711.         return array();
  712.     }
  713.  
  714.     for( $i = 1; $i < count( $args ); $i++ ) {
  715.         if( !is_array( $args[$i] )) {
  716.             continue;
  717.         }
  718.         foreach( $args[$i] as $key => $data ) {
  719.             unset( $res[$key] );
  720.         }
  721.     }
  722.     return $res;
  723. }
  724.  
  725. /**
  726.  * trim_array
  727.  *
  728.  * @param array $pArray 
  729.  * @access public
  730.  */
  731. function trim_array( &$pArray ) {
  732.     if( is_array( $pArray ) ) {
  733.         foreach( array_keys( $pArray ) as $key ) {
  734.             if( is_string( $pArray[$key] ) ) {
  735.                 $pArray[$key] = trim( $pArray[$key] );
  736.             }
  737.         }
  738.     }
  739. }
  740.  
  741.  
  742. /**
  743.  * ordinalize
  744.  *
  745.  * @param numeric $num Number to append th, st, nd, rd to - only makes sense when languages is english
  746.  * @access public
  747.  */
  748. function ordinalize( $num ) {
  749.     $ord = '';
  750.     if( is_numeric( $num ) ) {
  751.         if( $num >= 11 and $num <= 19 ) {
  752.             $ord = tra( "th" );
  753.         } elseif( $num % 10 == 1 ) {
  754.             $ord = tra( "st" );
  755.         } elseif( $num % 10 == 2 ) {
  756.             $ord = tra( "nd" );
  757.         } elseif( $num % 10 == 3 ) {
  758.             $ord = tra( "rd" );
  759.         } else {
  760.             $ord = tra( "th" );
  761.         }
  762.     }
  763.  
  764.     return $num.$ord;
  765. }
  766.  
  767. /**
  768.  * Cleans file path according to system we're on
  769.  *
  770.  * @param array $pPath 
  771.  * @access public
  772.  * @return TRUE on success, FALSE on failure
  773.  */
  774. function clean_file_path( $pPath ) {
  775.     $pPath = (!empty($_SERVER["SERVER_SOFTWARE"]) && strpos($_SERVER["SERVER_SOFTWARE"],"IIS") ? str_replace( '\/', '\\', $pPath) : $pPath);
  776.     return $pPath;
  777. }
  778.  
  779. function httpScheme() {
  780.     return 'http'.( ( isset($_SERVER['HTTPS'] ) && ( $_SERVER['HTTPS'] == 'on' ) ) ? 's' : '' );
  781. }
  782.  
  783. function httpPrefix() {
  784.     return httpScheme().'://'.$_SERVER['HTTP_HOST'];
  785. }
  786.  
  787. /**
  788. * If an unrecoverable error has occurred, this method should be invoked. script exist occurs
  789. *
  790. * @param string $ pMsg error message to be displayed
  791. * @return none this function will DIE DIE DIE!!!
  792. * @access public
  793. */
  794. function install_error( $pMsg = null ) {
  795.     global $gBitDbType;
  796.     // here we decide where to go. if there are no db settings yet, we go the welcome page.
  797.     if( isset( $gBitDbType )) {
  798.         $step = 1;
  799.     } else {
  800.         $step = 0;
  801.     }
  802.  
  803.     header( "Location: ".httpPrefix().BIT_ROOT_URL."install/install.php?step=".$step );
  804.     die;
  805. }
  806.  
  807. /**
  808.  * pear_check will check to see if a given PEAR module is installed
  809.  *
  810.  * @param string $pPearModule The name of the module in the format: Image/GraphViz.php
  811.  * @access public
  812.  * @return string with error message on failure, NULL on success
  813.  */
  814. function pear_check( $pPearModule = NULL ) {
  815.     if( !@include_once( "PEAR.php" )) {
  816.         return tra( "PEAR is not installed." );
  817.     } elseif( !empty( $pPearModule ) && !@include_once( $pPearModule )) {
  818.         $module = str_replace( ".php", "", str_replace( "/", "_", $pPearModule ));
  819.         return tra( "The PEAR plugin <strong>$module</strong> is not installed. Install it with '<strong>pear install $module</strong>' or use your distribution's package manager.");
  820.     } else {
  821.         return NULL;
  822.     }
  823. }
  824.  
  825. /**
  826.  * A set of compare functions that can be used in conjunction with usort() type functions
  827.  *
  828.  * @param array $ar1 
  829.  * @param array $ar2 
  830.  * @access public
  831.  * @return TRUE on success, FALSE on failure
  832.  */
  833. function usort_by_title( $ar1, $ar2 ) {
  834.     if( !empty( $ar1['title'] ) && !empty( $ar2['title'] ) ) {
  835.         return strcasecmp( $ar1['title'], $ar2['title'] );
  836.     } else {
  837.         return 0;
  838.     }
  839. }
  840.  
  841. function compare_links( $ar1, $ar2 ) {
  842.     return $ar1["links"] - $ar2["links"];
  843. }
  844.  
  845. function compare_backlinks( $ar1, $ar2 ) {
  846.     return $ar1["backlinks"] - $ar2["backlinks"];
  847. }
  848.  
  849. function r_compare_links( $ar1, $ar2 ) {
  850.     return $ar2["links"] - $ar1["links"];
  851. }
  852.  
  853. function r_compare_backlinks( $ar1, $ar2 ) {
  854.     return $ar2["backlinks"] - $ar1["backlinks"];
  855. }
  856.  
  857. function compare_images( $ar1, $ar2 ) {
  858.     return $ar1["images"] - $ar2["images"];
  859. }
  860.  
  861. function r_compare_images( $ar1, $ar2 ) {
  862.     return $ar2["images"] - $ar1["images"];
  863. }
  864.  
  865. function compare_files( $ar1, $ar2 ) {
  866.     return $ar1["files"] - $ar2["files"];
  867. }
  868.  
  869. function r_compare_files( $ar1, $ar2 ) {
  870.     return $ar2["files"] - $ar1["files"];
  871. }
  872.  
  873. function compare_versions( $ar1, $ar2 ) {
  874.     return $ar1["versions"] - $ar2["versions"];
  875. }
  876.  
  877. function r_compare_versions( $ar1, $ar2 ) {
  878.     return $ar2["versions"] - $ar1["versions"];
  879. }
  880.  
  881. function compare_changed( $ar1, $ar2 ) {
  882.     return $ar1["lastChanged"] - $ar2["lastChanged"];
  883. }
  884.  
  885. function r_compare_changed( $ar1, $ar2 ) {
  886.     return $ar2["lastChanged"] - $ar1["lastChanged"];
  887. }
  888.  
  889.  
  890. // ======================= deprecated functions =======================
  891. /**
  892.  * @deprecated deprecated since version 2.1.0-beta
  893.  */
  894. function chkgd2() {
  895.     deprecated( 'Please use get_gd_version() instead' );
  896. }
  897.  
  898. ?>

Documentation generated on Wed, 29 Jul 2015 13:56:46 +0000 by phpDocumentor 1.5.0-lsces