Update version.php to 3.3.0
[isso.git] / Functions.php
index b735043d719ae48eb97b31d0e4ae2e9e2c01f40e..fcd14f9ac8360e60ce7bfd3e01087e9878ccadbd 100644 (file)
@@ -1,12 +1,12 @@
 <?php
 /*=====================================================================*\
 || ###################################################################
-|| # Blue Static ISSO Framework [#]issoversion[#]
-|| # Copyright ©2002-[#]year[#] Blue Static
+|| # Blue Static ISSO Framework
+|| # Copyright (c)2005-2009 Blue Static
 || #
 || # This program is free software; you can redistribute it and/or modify
 || # it under the terms of the GNU General Public License as published by
-|| # the Free Software Foundation; version [#]gpl[#] of the License.
+|| # the Free Software Foundation; version 2 of the License.
 || #
 || # This program is distributed in the hope that it will be useful, but
 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 \*=====================================================================*/
 
 /**
-* Static functions (Functions.php)
-*
-* @package     ISSO
-*/
+ * Static functions (Functions.php)
+ *
+ * @package    ISSO
+ */
 
 /**
-* Functions
-*
-* This is a bunch of static functions. This class is singleton so it
-* can store data while remaining static.
-*
-* @author              Blue Static
-* @copyright   Copyright ©2002 - [#]year[#], Blue Static
-* @version             $Revision$
-* @package             ISSO
-* 
-*/
+ * Functions
+ *
+ * This is a bunch of static functions wrapped in a class for modularity and
+ * namespace collisions.
+ *
+ * @author             Blue Static
+ * @copyright  Copyright (c)2005 - 2009, Blue Static
+ * @package            ISSO
+ * 
+ */
 class BSFunctions
 {
        /**
-       * Singleton instance
-       * @var  object
-       */
-       private static $instance;
-       
-       /**
-       * Cookie path
-       * @var  string
-       */
-       private $cookiePath = '/';
-       
-       /**
-       * Cookie domain setting
-       * @var  string
-       */
-       private $cookieDomain = '';
-       
-       /**
-       * Cookie expiration time
-       * @var  integer
-       */
-       private $cookieTimeout = 900;
-       
-       /**
-       * Current swapped CSS class
-       * @var  string
-       */
-       public static $cssClass = '';
-       
-       // ###################################################################
-       /**
-       * Constructor
-       */
+        * Make class static
+        */
        private function __construct()
-       {       }
-       
-       // ###################################################################
-       /**
-       * Returns the shared instance for singleton
-       *
-       * @return       object  Shared instance
-       */
-       private function SharedInstance()
-       {
-               if (!self::$instance)
-               {
-                       self::$instance = new BSFunctions;
-               }               
-               return self::$instance;
-       }
-       
-       // ###################################################################
-       /**
-       * Sets the cookie path
-       *
-       * @param        string  New path
-       */
-       public static function SetCookiePath($path)
-       {
-               self::SharedInstance()->cookiePath = $path;
-       }
-       
-       // ###################################################################
-       /**
-       * Sets the cookie domain setting
-       *
-       * @param        string  Cookie domain
-       */
-       public static function SetCookieDomain($domain)
-       {
-               self::SharedInstance()->cookieDomain = $domain;
-       }
+       {}
        
-       // ###################################################################
        /**
-       * Sets the cookie timeout
-       *
-       * @param        integer Cookie timeout
-       */
-       public static function SetCookieTimeout($timeout)
-       {
-               self::SharedInstance()->cookieTimeout = intval($timeout);
-       }
+        * Sets a cookie in the user's computer/browing session
+        *
+        * @param       string  Name of the cookie
+        * @param       string  Value of the cookie
+        * @param       integer Timeout in seconds for non-sticky cookies. Can also be ::COOKIE_EXPIRE or ::COOKIE_STICKY
+        * @param       string  Cookie path
+        * @param       string  Domain
+        */
+       const COOKIE_EXPIRE = -1;
+       const COOKIE_STICKY = -2;
        
-       // ###################################################################
-       /**
-       * Sets a cookie in the user's computer/browing session
-       *
-       * @param        string  Name of the cookie
-       * @param        string  Value of the cookie, FALSE to clear
-       * @param        bool    Is the cookie permanent?
-       */
-       public static function Cookie($name, $value, $sticky = true)
+       public static function cookie($name, $value, $timeout = 900, $path = '/', $domain = '')
        {
                // expire the cookie
-               if ($value === false)
+               if ($timeout == self::COOKIE_EXPIRE)
                {
-                       setcookie($name, $value, time() - (2 * self::SharedInstance()->cookieTimeout), self::SharedInstance()->cookiePath, self::SharedInstance()->cookieDomain);
+                       setcookie($name, $value, time() - 1800, $path, $domain);
                }
                // set the cookie
                else
                {
-                       if ($sticky)
+                       // it's sticky so keep it around for a while
+                       if ($timeout == self::COOKIE_STICKY)
                        {
                                $expire = time() + 60 * 60 * 24 * 365;
                        }
                        else
                        {
-                               $expire = time() + self::SharedInstance()->cookieTimeout;
+                               $expire = time() + $timeout;
                        }
                        
-                       setcookie($name, $value, $expire, self::SharedInstance()->cookiePath, self::SharedInstance()->cookieDomain);
+                       setcookie($name, $value, $expire, $path, $domain);
                }
        }
        
-       // ###################################################################
        /**
-       * Alternate between two CSS classes
-       *
-       * @param        string  First CSS class name
-       * @param        string  Second CSS class name
-       */
-       public function SwapCssClasses($class1 = 'alt1', $class2 = 'alt2')
+        * Alternate between two CSS classes
+        *
+        * @param       string  First CSS class name
+        * @param       string  Second CSS class name
+        */
+       public static function swap_css_classes($class1 = 'alt1', $class2 = 'alt2')
        {
                static $count;
-               
-               self::$cssClass = ($count % 2) ? $class1 : $class2;
-               $count++;
+               return ($count++ % 2) ? $class1 : $class2;
        }
        
-       // ###################################################################
        /**
-       * Returns the 'source path' version of a file path. It adds a
-       * directory separator to the end of a string if it does not already
-       * exist.
-       *
-       * @param        string  Path
-       *
-       * @return       string  Path with directory separator ending
-       */
-       public static function FetchSourcePath($source)
+        * Returns the 'source path' version of a file path. It adds a
+        * directory separator to the end of a string if it does not already
+        * exist.
+        *
+        * @param       string  Path
+        *
+        * @return      string  Path with directory separator ending
+        */
+       public static function fetch_source_path($source)
        {
                if (substr($source, strlen($source) - 1) != DIRECTORY_SEPARATOR)
                {
@@ -189,26 +110,17 @@ class BSFunctions
                return $source;
        }
        
-       // ###################################################################
        /**
-       * Force-download a file by sending application/octetstream
-       *
-       * @param        string  The text of the file to be streamed
-       * @param        string  File name of the new file
-       * @param        bool    Whether or not to die after stringeaming the file
-       */
-       public static function DownloadFile($file, $name, $exit = true)
+        * Force-download a file by sending application/octetstream
+        *
+        * @param       string  The text of the file to be streamed
+        * @param       string  File name of the new file
+        * @param       bool    Whether or not to die after stringeaming the file
+        */
+       public static function download_file($file, $name, $exit = true)
        {
-               if (self::IsBrowser('ie') OR self::IsBrowser('opera') OR self::IsBrowser('safari'))
-               {
-                       $mime = 'application/octetstream';
-               }
-               else
-               {
-                       $mime = 'application/octet-stream';
-               }
-               
-               header("Content-Type: $mime");
+               header("Content-Type: application/octetstream");
+               header("Content-Type: application/octet-stream");
                header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
                header('Content-Disposition: attachment; filename="' . $name . '"');
                header('Content-length: ' . strlen($file));
@@ -223,257 +135,65 @@ class BSFunctions
                }
        }
        
-       // ###################################################################
        /**
-       * Verify that an email address is valid via regex
-       *
-       * @param        string  An email address
-       *
-       * @return       bool    Validity of the email address
-       */
-       public static function IsValidEmail($email)
+        * Verify that an email address is valid via regex
+        *
+        * @param       string  An email address
+        *
+        * @return      bool    Validity of the email address
+        */
+       public static function is_valid_email($email)
        {
-               if (preg_match('#^[a-z0-9\.\-\+_]+?@(.*?\.)*?[a-z0-9\-_]+?\.[a-z]{2,4}$#i', $email))
-               {
-                       return true;
-               }
-               else
-               {
-                       return false;
-               }
+               return (preg_match('#^[a-z0-9\.\-\+_]+?@(.*?\.)*?[a-z0-9\-_]+?\.[a-z]{2,4}$#i', $email));
        }
        
-       // ###################################################################
        /**
-       * Check a browser's user agent against a pre-determined list
-       *
-       * @param        string  Browser name
-       * @param        string  The browser's version
-       *
-       * @param        mixed   False if there is no match, the version if there is
-       */
-       public static function IsBrowser($check, $version = '')
+        * Generates a random string of random length (unless otherwise
+        * specified)
+        *
+        * @param       integer Optional length
+        *
+        * @return      string  A random string
+        */
+       public static function random($length = 0)
        {
-               $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
-               $browser = array();
-               $matches = array();
-               
-               // -------------------------------------------------------------------
-               // -- Opera
-               // -------------------------------------------------------------------
-               # Opera/6.05 (Windows 98; U) [en]
-               # Mozilla/4.0 (compatible; MSIE 5.0; Windows 98) Opera 6.0 [en]
-               # Mozilla/5.0 (Windows 98; U) Opera 6.0 [en]
-               # Mozilla/4.0 (compatible; MSIE, 6.0; Windows 98) Opera 7.0 [en]
-               if (preg_match('#opera ([0-9\.]+)#', $useragent, $matches) !== false)
-               {
-                       if (isset($matches[1]))
-                       {
-                               $browser['opera'] = $matches[1];
-                       }
-               }
-               
-               // -------------------------------------------------------------------
-               // -- Mac browser
-               // -------------------------------------------------------------------
-               if (strpos($useragent, 'mac') !== false)
+               // length wasn't provided, so create our own
+               if ($length < 1)
                {
-                       $browser['mac'] = true;
-               }
-               
-               // -------------------------------------------------------------------
-               // -- Internet explorer
-               // -------------------------------------------------------------------
-               # Mozilla/4.0 (compatible; MSIE 6.0b; Windows NT 5.1; .NET CLR 1.0.2914)
-               # Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
-               if (preg_match('#msie ([0-9\.]+)#', $useragent, $matches) !== false AND !isset($browser['opera']))
-               {
-                       if (isset($matches[1]))
-                       {
-                               $browser['ie'] = $matches[1];
-                       }
-               }
-               
-               // -------------------------------------------------------------------
-               // -- Safari
-               // -------------------------------------------------------------------
-               # Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/125.4 (KHTML, like Gecko) Safari/125.9
-               if (preg_match('#safari/([0-9\.]+)#', $useragent, $matches) !== false)
-               {
-                       if (isset($matches[1]))
-                       {
-                               $browser['safari'] = $matches[1];
-                       }
-               }
-               
-               // -------------------------------------------------------------------
-               // -- Konqueror
-               // -------------------------------------------------------------------
-               # Mozilla/5.0 (compatible; Konqueror/3)
-               # Mozilla/5.0 (compatible; Konqueror/3.1; i686 Linux; 20020628)
-               if (preg_match('#konqueror/([0-9\.]+)#', $useragent, $matches) !== false)
-               {
-                       if (isset($matches[1]))
-                       {
-                               $browser['konqueror'] = $matches[1];
-                       }
+                       $length = rand(20, 65);
                }
                
-               // -------------------------------------------------------------------
-               // -- Mozilla
-               // -------------------------------------------------------------------
-               # Mozilla/5.001 (windows; U; NT4.0; en-us) Gecko/25250101
-               # Mozilla/5.001 (Macintosh; N; PPC; ja) Gecko/25250101 MegaCorpBrowser/1.0 (MegaCorp, Inc.)
-               if (preg_match('#gecko/([0-9]+)#', $useragent, $matches) !== false AND !isset($browser['safari']))
+               $string = '';
+               while (strlen($string) < $length)
                {
-                       if (isset($matches[1]))
-                       {
-                               $browser['mozilla'] = $matches[1];
-                       }
-                       
-                       // -------------------------------------------------------------------
-                       // -- Firefox
-                       // -------------------------------------------------------------------
-                       # Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7) Gecko/20040628 Firefox/0.9.1
-                       # Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4a) Gecko/20030423 Firebird Browser/0.6
-                       if (preg_match('#(firebird|firefox)( browser)?/([0-9\.]+)#', $useragent, $matches) !== false)
-                       {
-                               if (isset($matches[3]))
-                               {
-                                       $browser['firefox'] = $matches[3];
-                               }
-                       }
-                       
-                       // -------------------------------------------------------------------
-                       // -- Netscape
-                       // -------------------------------------------------------------------
-                       # Mozilla/5.0 (Macintosh; U; PPC; en-US; rv:0.9.4.1) Gecko/20020318 Netscape6/6.2.2
-                       if (preg_match('#netscape([0-9].*?)?/([0-9\.]+)#', $useragent, $matches) !== false)
+                       $type = rand(0, 300);
+                       if ($type < 100)
                        {
-                               if (isset($matches[2]))
-                               {
-                                       $browser['netscape'] = $matches[2];
-                               }
+                               $string .= rand(0, 9);
                        }
-                       
-                       // -------------------------------------------------------------------
-                       // -- Camino
-                       // -------------------------------------------------------------------
-                       # Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7) Gecko/20040623 Camino/0.8
-                       if (preg_match('#camino/([0-9\.]+)#', $useragent, $matches) !== false)
-                       {
-                               if (isset($matches[1]))
-                               {
-                                       $browser['camino'] = $matches[1];
-                               }
-                       }
-               }
-               
-               if (isset($browser["$check"]))
-               {
-                       if ($version)
+                       else if ($type < 200)
                        {
-                               if ($browser["$check"] >= $version)
-                               {
-                                       return $browser["$check"];
-                               }
-                               else
-                               {
-                                       return false;
-                               }
+                               $string .= chr(rand(65, 90));
                        }
                        else
                        {
-                               return $browser["$check"];
+                               $string .= chr(rand(97, 122));
                        }
                }
-               else
-               {
-                       return false;
-               }
-       }
-       
-       // ###################################################################
-       /**
-       * Generates a random string of random length (unless otherwise
-       * specified)
-       *
-       * @param        integer Optional length
-       *
-       * @return       string  A random string
-       */
-       public static function Random($length = 0)
-       {
-               // custom high and lows
-               if (is_array($length))
-               {
-                       $length = rand($length[0], $length[1]);
-               }
-               else if (!$length)
-               {
-                       // Gimme a length!
-                       $length = rand(20, 65);
-               }
-               
-               // Number of ints in our salt
-               $intcount = rand(1, intval($length / 2));
-               
-               // Number of chars
-               $charcount = $length - $intcount;
-               
-               // Upper-case chars
-               $upperchars = rand(1, intval($charcount / 2));
-               
-               // Lower-case chars
-               $lowerchars = $charcount - $upperchars;
-               
-               // Generate ints
-               for ($i = 0; $i < $intcount; $i++)
-               {
-                       $string[ mt_rand() ] = rand(0, 9);
-               }
-               
-               // Generate upper chars
-               for ($i = 0; $i < $upperchars; $i++)
-               {
-                       $string[ mt_rand() ] = chr(rand(65, 90));
-               }
-               
-               // Generate lower chars
-               for ($i = 0; $i < $lowerchars; $i++)
-               {
-                       $string[ mt_rand() ] = chr(rand(97, 122));
-               }
-               
-               if ($length != sizeof($string))
-               {
-                       return $this->rand($length);
-               }
                
-               // Sort the chars by thier random assignment
-               ksort($string);
-               
-               // Flatten the array
-               $return = '';
-               foreach ($string AS $char)
-               {
-                       $return .= $char;
-               }
-               
-               return $return;
+               return $string;
        }
        
-       // ###################################################################
        /**
-       * Sets the current array position to be the specified key. This
-       * function should be avoided on large arrays.
-       *
-       * @param        array   The array whose counter is to be updated
-       * @param        mixed   The key of the element of the array that the counter is to be set to
-       *
-       * @return       mixed   Return the elelment of the array that we just put the counter to
-       */
-       public static function ArraySetCurrent(&$array, $key)
+        * Sets the current array position to be the specified key. This
+        * function should be avoided on large arrays.
+        *
+        * @param       array   The array whose counter is to be updated
+        * @param       mixed   The key of the element of the array that the counter is to be set to
+        *
+        * @return      mixed   Return the elelment of the array that we just put the counter to
+        */
+       public static function array_set_current(&$array, $key)
        {
                reset($array);
                while (current($array) !== false)
@@ -487,33 +207,31 @@ class BSFunctions
                return current($array);
        }
        
-       // ###################################################################
        /**
-       * Calculates the microtime difference by taking a given microtime and
-       * subtracting it from the current one
-       *
-       * @param        string  The start microtime
-       *
-       * @return       float   Microtime difference
-       */
-       public static function FetchMicrotimeDiff($mtstart)
+        * Calculates the microtime difference by taking a given microtime and
+        * subtracting it from the current one
+        *
+        * @param       string  The start microtime
+        *
+        * @return      float   Microtime difference
+        */
+       public static function fetch_microtime_diff($mtstart)
        {
                $mtend = microtime();
-               list ($starttime['micro'], $starttime['sec']) = explode(' ', $mtstart);
-               list ($endtime['micro'], $endtime['sec']) = explode(' ', $mtend);
-               return ($endtime['micro'] + $endtime['sec']) - ($starttime['micro'] + $starttime['sec']);
+               list($startMicro, $startSec) = explode(' ', $mtstart);
+               list($endMicro, $endSec) = explode(' ', $mtend);
+               return ($endMicro + $endSec) - ($startMicro + $startSec);
        }
        
-       // ###################################################################
        /**
-       * Fetches the extension of a file by extracting everything after the
-       * last period
-       *
-       * @param        string  Filename
-       *
-       * @return       string  The extension for the specifid file name
-       */
-       public static function FetchExtension($filename)
+        * Fetches the extension of a file by extracting everything after the
+        * last period
+        *
+        * @param       string  Filename
+        *
+        * @return      string  The extension for the specifid file name
+        */
+       public static function fetch_extension($filename)
        {
                $array = explode('.', $filename);
                
@@ -525,15 +243,14 @@ class BSFunctions
                return strval(end($array));
        }
        
-       // ###################################################################
        /**
-       * Gets the maximum file size for attachment uploading, as specified by
-       * PHP. If no value is present, 10 MB (represented in bytes) is
-       * returned.
-       *
-       * @return       integer The maximum file upload size in bytes
-       */
-       public static function FetchMaxPhpFileSize()
+        * Gets the maximum file size for attachment uploading, as specified by
+        * PHP. If no value is present, 10 MB (represented in bytes) is
+        * returned.
+        *
+        * @return      integer The maximum file upload size in bytes
+        */
+       public static function fetch_max_php_file_size()
        {
                if ($size = @ini_get('upload_max_filesize'))
                {
@@ -552,71 +269,67 @@ class BSFunctions
                }
        }
        
-       // ###################################################################
        /**
-       * Scans a specified directory path and returns an array of all the
-       * items in that directory. Directories found by this are end in a "/"
-       *
-       * @param        string  Path to scan
-       * @param        bool    Whether or not to recursively scan the directories encountered
-       * @param        bool    Ignore files beginning with a dot
-       * @param        bool    Ignore 'CVS' dirctories
-       *
-       * @return       array   A list of all the files in the specified path
-       */
-       public static function ScanDirectory($path, $recurse = true, $ignoredot = true, $ignorecvs = true, $basepath = '', $unset = 1)
+        * Scans a specified directory path and returns an array of all the
+        * items in that directory. Directories found by this are end in a "/"
+        *
+        * @param       string  Path to scan
+        * @param       bool    Whether or not to recursively scan the directories encountered
+        * @param       bool    Ignore files beginning with a dot
+        *
+        * @return      array   A list of all the files in the specified path
+        */
+       public static function scan_directory($path, $recurse = true, $ignoreDot = true)
        {
-               static $filelist;
-               
-               if ($unset)
-               {
-                       $filelist = array();
-               }
-               
-               if (substr($path, (strlen($path) - 1), 1) != '/')
-               {
-                       $path .= '/';
-               }
+               return self::_help_scan_directory($path, $recurse, $ignoreDot, '');
+       }
+       
+       /**
+        * Scans a specified directory path and returns an array of all the
+        * items in that directory. Directories found by this are end in a "/"
+        *
+        * @param       string  Path to scan
+        * @param       bool    Whether or not to recursively scan the directories encountered
+        * @param       bool    Ignore files beginning with a dot
+        * @param       string  Add to the beginning of the path
+        *
+        * @return      array   A list of all the files in the specified path
+        */
+       private static function _help_scan_directory($path, $recurse = true, $ignoreDot = true, $pathAdd = '')
+       {
+               $filelist = array();
+               $path = self::fetch_source_path($path);
                
-               if ($handle = opendir($path))
+               $dir = new DirectoryIterator($path);
+               foreach ($dir as $file)
                {
-                       while (($file = readdir($handle)) !== false)
+                       $name = $file->getFilename();
+                       if (($file->isDot() || $name[0] == '.') && $ignoreDot)
                        {
-                               $isdot = ((substr($file, 0, 1) == '.') ? true : false);
-                               $isdot = (($ignoredot) ? $isdot : true);
-                               $iscvs = (($file == 'CVS') ? true : false);
-                               $iscvs = (($ignorecvs) ? $iscvs : true);
-                               if (!$isdot AND !$iscvs)
-                               {
-                                       if (is_dir($path . $file))
-                                       {
-                                               $filelist["$basepath"][] = "$file/";
-                                               if ($recurse)
-                                               {
-                                                       self::ScanDirectory("$path$file", true, $ignoredot, $ignorecvs, "$basepath$file/", 0);
-                                               }
-                                       }
-                                       else
-                                       {
-                                               $filelist["$basepath"][] = $file;
-                                       }
-                               }
+                               continue;
+                       }
+                       
+                       if ($file->isDir() && $recurse)
+                       {
+                               $filelist = array_merge($filelist, self::_help_scan_directory($path . $name, $recurse, $ignoreDot, $pathAdd . BSFunctions::fetch_source_path(str_replace($path, '', $file->getPathname()))));
+                               continue;
                        }
-                       closedir($handle);
+                       
+                       $filelist[] = $pathAdd . $name;
                }
+               
                return $filelist;
        }
        
-       // ###################################################################
        /**
-       * Changes line breaks into one format
-       *
-       * @param        string  Text
-       * @param        string  New line break (default is UNIX \n format)
-       *
-       * @return       string  Text with one type of line break
-       */
-       public static function ConvertLineBreaks($text, $convert_to = "\n")
+        * Changes line breaks into one format
+        *
+        * @param       string  Text
+        * @param       string  New line break (default is UNIX \n format)
+        *
+        * @return      string  Text with one type of line break
+        */
+       public static function convert_line_breaks($text, $convert_to = "\n")
        {
                $text = trim($text);
                $text = str_replace(array("\r\n", "\r", "\n"), "\n", $text);
@@ -624,36 +337,120 @@ class BSFunctions
                return $text;
        }
        
-       // ###################################################################
        /**
-       * Removes all empty() [by PHP's standards] elements in an array. This
-       * can be used in place of using PREG_SPLIT_NO_EMPTY.
-       *
-       * @param        array   An array to strip empties from
-       *
-       * @return       array   Full-valued array
-       */
-       public static function ArrayStripEmpty($array)
+        * Removes all empty() [by PHP's standards] elements in an array. This
+        * can be used in place of using PREG_SPLIT_NO_EMPTY.
+        *
+        * @param       array   An array to strip empties from
+        *
+        * @return      array   Full-valued array
+        */
+       public static function array_strip_empty($array)
        {
-               foreach ($array AS $key => $value)
+               foreach ($array as $key => $value)
                {
                        if (is_array($array["$key"]))
                        {
-                               $array["$key"] = self::ArrayStripEmpty($array["$key"]);
+                               $array["$key"] = self::array_strip_empty($array["$key"]);
                        }
-                       else if (empty($value) OR is_null($value))
+                       else if (empty($value) || is_null($value))
                        {
                                unset($array["$key"]);
                        }
                }
                return $array;
        }
+       
+       /**
+        * A backtrace formatter.
+        *
+        * This is very slightly modified from PEAR/PHP_Compat (PHP license)
+        *
+        * @author      Laurent Laville <pear@laurent-laville.org>
+        * @author      Aidan Lister <aidan@php.net>
+        *
+        * @param       array   The backtrace from debug_backtrace() to format
+        *
+        * @return      string  Formatted output
+        */
+       public static function format_backtrace($backtrace)
+       {
+               // Unset call to debug_print_backtrace
+               array_shift($backtrace);
+               if (empty($backtrace))
+               {
+                       return '';
+               }
+
+               // Iterate backtrace
+               $calls = array();
+               foreach ($backtrace as $i => $call)
+               {
+                       if (!isset($call['file']))
+                       {
+                               $call['file'] = '(null)';
+                       }
+                       if (!isset($call['line']))
+                       {
+                               $call['line'] = '0';
+                       }
+                       $location = $call['file'] . ':' . $call['line'];
+                       $function = (isset($call['class'])) ? $call['class'] . (isset($call['type']) ? $call['type'] : '.') . $call['function'] : $call['function'];
+                       
+                       $params = '';
+                       if (isset($call['args']))
+                       {
+                               $args = array();
+                               foreach ($call['args'] as $arg)
+                               {
+                                       if (is_array($arg))
+                                       {
+                                               $args[] = 'Array';
+                                       }
+                                       elseif (is_object($arg))
+                                       {
+                                               $args[] = get_class($arg);
+                                       }
+                                       else
+                                       {
+                                               $args[] = $arg;
+                                       }
+                               }
+                               $params = implode(', ', $args);
+                       }
+
+                       $calls[] = sprintf('#%d  %s(%s) called at [%s]', $i, $function, $params, $location);
+               }
+
+               return implode("\n", $calls);
+       }
+       
+       /**
+        * A variation of PHP's substr() method that takes in the start
+        * and end position of a string, rather than a start and length. This
+        * mimics Java's String.substring() method.
+        *
+        * @param       string  The string
+        * @param       integer Start position
+        * @param       integer End position
+        *
+        * @return      string  Part of a string
+        */
+       public static function substring($string, $start, $end)
+       {
+               return substr($string, $start, $end - $start);
+       }
+       
+       /**
+        * Converts a boolean value into the string 'Yes' or 'No'
+        *
+        * @param       boolean
+        * @return      string
+        */
+       public static function bool_to_string($bool)
+       {
+               return ($bool ? _('Yes') : _('No'));
+       }
 }
 
-/*=====================================================================*\
-|| ###################################################################
-|| # $HeadURL$
-|| # $Id$
-|| ###################################################################
-\*=====================================================================*/
 ?>
\ No newline at end of file