. */ /** * This file contains the Util helper class. * * @author Dinu Florin * @package Core */ /** * Utility class. * This class contains some static methods to help you with some common functions. * * @author Dinu Florin * @package Core */ final class Util { /** * Convert a URL to a path on the server. * Eg: http://example.com/image.jpg becomes /home/www/image.jpg where /home/www is the document root for example.com. * * @param string $url The URL to convert. It must be on the same server as the script. * @return string */ public static function makePathFromURL($url) { assert('is_string($url)'); assert('preg_match("/^https?:\/\//i", $url)'); //Check the that the string looks like an URL return self::makeStdPath($_SERVER['DOCUMENT_ROOT']).str_replace(Request::getBaseUrl(), '', $url); } /** * Convert a path or filename to a URL. * Eg: /home/www/image.jpg becomes http://example.com/image.jpg where /home/www is the document root for example.com. * * @param string $path The path to convert. * @return string */ public static function makeURLFromPath($path) { assert('is_string($path)'); $url = Request::getBaseUrl().str_replace(self::makeStdPath($_SERVER['DOCUMENT_ROOT']), '', self::makeStdPath($path)); $url = str_replace('\\', '/', $url); //Correct windows paths return $url; } /** * Standardize a path. * This function standardizes a filesystem path, it makes it absolute and removes any slashes from the end of it. * * @param string $path The path to standardize. * @return string Standardized path. */ public static function makeStdPath($path) { assert('is_string($path)'); if(!file_exists($path)) { trigger_error("Invalid filesystem path passed to Core::makeStdPath(): {$path}.", E_USER_WARNING); } $p = realpath($path); $p = rtrim($p, '/\\'); return $p; } /** * Return the system's temporary directory. * * @return string */ public static function getTempDir() { //Cache the result, this function will only run once per request, for subsequent calls just return the cached value. static $tempDir = null; if(!is_null($tempDir)) { return $tempDir; } $tempDir = getenv('PT_TEMP_DIR'); if(!$tempDir && function_exists('sys_get_temp_dir')) //Try the new PHP 5 way, it's simpler and more reliable. { $tempDir = sys_get_temp_dir(); } elseif(!$tempDir) { // Try to get the temp dir from environment variable. if(!empty($_ENV['TMP'])) { $tempDir = Util::makeStdPath($_ENV['TMP']); } elseif(!empty($_ENV['TMPDIR'])) { $tempDir = Util::makeStdPath($_ENV['TMPDIR']); } elseif(!empty($_ENV['TEMP'])) { $tempDir = Util::makeStdPath($_ENV['TEMP']); } else //Detect the temp dir by creating a temporary file, this is the worst case.. it's slow and a little awkward { trigger_error('Util::getTempDir() is resorting to a tempnam hack to determine the system\'s temporary directory, please consider setting the TMP or TMPDIR environment variable', E_USER_NOTICE); //Try to use system's temporary directory as the random name shouldn't exist $tempFile = tempnam(md5(uniqid(rand(), true)), ''); if ($tempFile) { $tempDir = Util::makeStdPath(dirname($temp_file)); unlink($tempFile); } else { throw new GenericException('Can\'t determine the system\'s temporary directory'); } } } if(!file_exists($tempDir)) { throw new GenericException('Can\'t determine the system\'s temporary directory'); } if(!is_readable($tempDir)) { throw new GenericException("The temporary directory {$tempDir} is not readable"); } if(!is_writable($tempDir)) { throw new GenericException("The temporary directory {$tempDir} is not writable"); } $tempDir .= DIRECTORY_SEPARATOR.'pt'; if(!file_exists($tempDir)) { if(!@mkdir($tempDir, 0777) && !file_exists($tempDir)) { throw new GenericException("Can't create temp dir {$tempDir}"); } } return $tempDir; } /** * Return an integer generated from the given string. * * @param string $string String to generate the key from. * @return integer. */ public static function makeIntFromString($string) { assert('is_string($string)'); $key = abs(crc32($string)); //TODO: find a better method... return $key; } /** * Execute a php file and return it's output. * The file will be executed in the script's context. It is not sandboxed in any way and it can access the global scope. * * @param string $file The file to execute. * @param array &$context An optional array of name=>value pairs to define additional context. * @return string The file's output. */ public static function execFile($file, &$context=NULL) { if(is_array($context)) { extract($context, EXTR_SKIP); } ob_start(); include self::makeStdPath($file); $ret = ob_get_contents(); ob_end_clean(); return $ret; } /** * Create a new directory with 0777 permissions and an index.html file in it. * If the directory exists this function will not do anything. * * @param string $dir The path to the directory. It will try to create the whole path. */ public static function makePublicDir($dir) { assert('is_string($dir) and strlen($dir)>0'); if(!file_exists($dir)) { $oldMask = umask(0); mkdir($dir, 0777, true); touch($dir.DIRECTORY_SEPARATOR.'index.html'); umask($oldMask); } } /** * Get the Pt root path. * The root path is the filesystem path to the directory containing the toolkit. * * @return string */ public static function getPtPath() { return self::makeStdPath(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'); } /** * Extended array_search(). * * @param mixed $needle Value to search for. * @param array $haystack The array to search in. * @param boolean &$ignoreCase Tf true the search will be case insensitive. This only applies to strings. (pass NULL to skip). * @param boolean $strict Tf this is true the types will also be compared. * @return mixed The key for the value if needle is found in haystack or false. This will return the first match. */ public static function arraySearch($needle, &$haystack, $ignoreCase=false, $strict=false) { assert('is_array($haystack)'); foreach($haystack as $key=>$val) { if($strict) { if($needle === $val || (is_string($val) && is_string($needle) && $ignoreCase && strcasecmp($needle, $val) === 0) ) { return $key; } } else { if($needle == $val || (is_string($val) && $ignoreCase && strcasecmp($needle, $val) === 0) ) { return $key; } } } return false; } /** * Extended in_array(). * * @param mixed $needle The value to search for, it will be converted to string. * @param array &$haystack The array to search in. * @param boolean $ignoreCase If true the search will be case insensitive. This only applies to strings. (pass NULL to skip). * @param boolean $recursive If true the the function will recurse inside the array (aka deep search). * @param boolean $strict If this is true the types will also be compared. * @return boolean */ public static function inArray($needle, &$haystack, $ignoreCase=false, $recursive=false, $strict=false) { assert('is_array($haystack)'); foreach($haystack as $val) { if($strict) { if($needle === $val || (is_string($val) && is_string($needle) && $ignoreCase && strcasecmp($needle, $val) === 0) ) { return true; } elseif(is_array($val) && $recursive) { return Util::inArray($needle, $val, $ignoreCase, $recursive, $strict); } } else { if($needle == $val || (is_string($val) && $ignoreCase && strcasecmp($needle, $val) === 0) ) { return true; } elseif(is_array($val) && $recursive) { return Util::inArray($needle, $val, $ignoreCase, $recursive, $strict); } } } return false; } /** * Checks if an array contains $needle. * If $needle is an array this checks that $haystack contains at least one of it's values. * * @param mixed $needle The values to search for. * @param array $haystack The array to search. * @return boolean */ public static function arrayContains($needle, $haystack) { if(!is_array($haystack)) { trigger_error('Wrong parameter passed to Util::arrayContains(). Parameter 2 must be an array.', E_USER_ERROR); } if(is_array($needle)) { $res = array_intersect($needle, $haystack); return !empty($res); } else { return in_array($needle, $haystack, true); } } /** * Recursively trim all strings in an array. * * @param array $array The array to trim. * @param string $charlist An optional string containing the characters to trim. * @return array */ public static function trimArray($array, $charlist=NULL) { assert('is_array($array)'); assert('is_string($charlist) or is_null($charlist)'); function _trim(&$val, $key, $charlist) { if(is_string($val)) $val = trim($val, $charlist); } array_walk_recursive($array, '_trim', $charlist); return $array; } /** * Clean the quotes inserted when magic_quotes is on. * If magic_quotes is off this does nothing. * * @param array &$a The array to clean (eg. $_GET/$_POST). */ public static function cleanMagicQuotes(&$a) { if(get_magic_quotes_gpc()) { assert('is_array($a)'); foreach($a as $key=>$val) { if(is_array($val)) { $a[$key] = self::cleanMagicQuotes($val); } elseif(is_string($val)) { $a[$key] = stripslashes($val); } } } } /** * Constructor. * It's private because this class is static. */ private function __construct() { } } ?>