Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/*** PradoBase class file.** This is the file that establishes the PRADO component model* and error handling mechanism.** @author Qiang Xue <qiang.xue@gmail.com>* @link http://www.pradosoft.com/* @copyright Copyright © 2005-2008 PradoSoft* @license http://www.pradosoft.com/license/* @version $Id: PradoBase.php 2602 2009-01-12 01:08:39Z qiang.xue $* @package System*//*** Defines the PRADO framework installation path.*/if(!defined('PRADO_DIR'))define('PRADO_DIR',dirname(__FILE__));/*** Defines the default permission for writable directories and files*/if(!defined('PRADO_CHMOD'))define('PRADO_CHMOD',0777);/*** PradoBase class.** PradoBase implements a few fundamental static methods.** To use the static methods, Use Prado as the class name rather than PradoBase.* PradoBase is meant to serve as the base class of Prado. The latter might be* rewritten for customization.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: PradoBase.php 2602 2009-01-12 01:08:39Z qiang.xue $* @package System* @since 3.0*/class PradoBase{/*** File extension for Prado class files.*/const CLASS_FILE_EXT='.php';/*** @var array list of path aliases*/private static $_aliases=array('System'=>PRADO_DIR);/*** @var array list of namespaces currently in use*/private static $_usings=array();/*** @var TApplication the application instance*/private static $_application=null;/*** @var TLogger logger instance*/private static $_logger=null;/*** @return string the version of Prado framework*/public static function getVersion(){return '3.1.4';}/*** Initializes error handlers.* This method set error and exception handlers to be functions* defined in this class.*/public static function initErrorHandlers(){/*** Sets error handler to be Prado::phpErrorHandler*/set_error_handler(array('PradoBase','phpErrorHandler'),error_reporting());/*** Sets exception handler to be Prado::exceptionHandler*/set_exception_handler(array('PradoBase','exceptionHandler'));}/*** Class autoload loader.* This method is provided to be invoked within an __autoload() magic method.* @param string class name*/public static function autoload($className){include_once($className.self::CLASS_FILE_EXT);if(!class_exists($className,false) && !interface_exists($className,false))self::fatalError("Class file for '$className' cannot be found.");}/*** @param integer the type of "powered logo". Valid values include 0 and 1.* @return string a string that can be displayed on your Web page showing powered-by-PRADO information*/public static function poweredByPrado($logoType=0){$logoName=$logoType==1?'powered2':'powered';if(self::$_application!==null){$am=self::$_application->getAssetManager();$url=$am->publishFilePath(self::getPathOfNamespace('System.'.$logoName,'.gif'));}else$url='http://www.pradosoft.com/images/'.$logoName.'.gif';return '<a title="Powered by PRADO" href="http://www.pradosoft.com/" target="_blank"><img src="'.$url.'" style="border-width:0px;" alt="Powered by PRADO" /></a>';}/*** PHP error handler.* This method should be registered as PHP error handler using* {@link set_error_handler}. The method throws an exception that* contains the error information.* @param integer the level of the error raised* @param string the error message* @param string the filename that the error was raised in* @param integer the line number the error was raised at*/public static function phpErrorHandler($errno,$errstr,$errfile,$errline){if(error_reporting()!=0)throw new TPhpErrorException($errno,$errstr,$errfile,$errline);}/*** Default exception handler.* This method should be registered as default exception handler using* {@link set_exception_handler}. The method tries to use the errorhandler* module of the Prado application to handle the exception.* If the application or the module does not exist, it simply echoes the* exception.* @param Exception exception that is not caught*/public static function exceptionHandler($exception){if(self::$_application!==null && ($errorHandler=self::$_application->getErrorHandler())!==null){$errorHandler->handleError(null,$exception);}else{echo $exception;}exit(1);}/*** Stores the application instance in the class static member.* This method helps implement a singleton pattern for TApplication.* Repeated invocation of this method or the application constructor* will cause the throw of an exception.* This method should only be used by framework developers.* @param TApplication the application instance* @throws TInvalidOperationException if this method is invoked twice or more.*/public static function setApplication($application){if(self::$_application!==null)throw new TInvalidOperationException('prado_application_singleton_required');self::$_application=$application;}/*** @return TApplication the application singleton, null if the singleton has not be created yet.*/public static function getApplication(){return self::$_application;}/*** @return string the path of the framework*/public static function getFrameworkPath(){return PRADO_DIR;}/*** Serializes a data.* The original PHP serialize function has a bug that may not serialize* properly an object.* @param mixed data to be serialized* @return string the serialized data*/public static function serialize($data){$arr[0]=$data;return serialize($arr);}/*** Unserializes a data.* The original PHP unserialize function has a bug that may not unserialize* properly an object.* @param string data to be unserialized* @return mixed unserialized data, null if unserialize failed*/public static function unserialize($str){$arr=unserialize($str);return isset($arr[0])?$arr[0]:null;}/*** Creates a component with the specified type.* A component type can be either the component class name* or a namespace referring to the path of the component class file.* For example, 'TButton', 'System.Web.UI.WebControls.TButton' are both* valid component type.* This method can also pass parameters to component constructors.* All parameters passed to this method except the first one (the component type)* will be supplied as component constructor parameters.* @param string component type* @return TComponent component instance of the specified type* @throws TInvalidDataValueException if the component type is unknown*/public static function createComponent($type){self::using($type);if(($pos=strrpos($type,'.'))!==false)$type=substr($type,$pos+1);if(($n=func_num_args())>1){$args=func_get_args();$s='$args[1]';for($i=2;$i<$n;++$i)$s.=",\$args[$i]";eval("\$component=new $type($s);");return $component;}elsereturn new $type;}/*** Uses a namespace.* A namespace ending with an asterisk '*' refers to a directory, otherwise it represents a PHP file.* If the namespace corresponds to a directory, the directory will be appended* to the include path. If the namespace corresponds to a file, it will be included (include_once).* @param string namespace to be used* @param boolean whether to check the existence of the class after the class file is included* @throws TInvalidDataValueException if the namespace is invalid*/public static function using($namespace,$checkClassExistence=true){if(isset(self::$_usings[$namespace]) || class_exists($namespace,false))return;if(($pos=strrpos($namespace,'.'))===false) // a class name{try{include_once($namespace.self::CLASS_FILE_EXT);}catch(Exception $e){if($checkClassExistence && !class_exists($namespace,false))throw new TInvalidOperationException('prado_component_unknown',$namespace,$e->getMessage());elsethrow $e;}}else if(($path=self::getPathOfNamespace($namespace,self::CLASS_FILE_EXT))!==null){$className=substr($namespace,$pos+1);if($className==='*') // a directory{self::$_usings[$namespace]=$path;set_include_path(get_include_path().PATH_SEPARATOR.$path);}else // a file{self::$_usings[$namespace]=$path;if(!$checkClassExistence || !class_exists($className,false)){try{include_once($path);}catch(Exception $e){if($checkClassExistence && !class_exists($className,false))throw new TInvalidOperationException('prado_component_unknown',$className,$e->getMessage());elsethrow $e;}}}}elsethrow new TInvalidDataValueException('prado_using_invalid',$namespace);}/*** Translates a namespace into a file path.* The first segment of the namespace is considered as a path alias* which is replaced with the actual path. The rest segments are* subdirectory names appended to the aliased path.* If the namespace ends with an asterisk '*', it represents a directory;* Otherwise it represents a file whose extension name is specified by the second parameter (defaults to empty).* Note, this method does not ensure the existence of the resulting file path.* @param string namespace* @param string extension to be appended if the namespace refers to a file* @return string file path corresponding to the namespace, null if namespace is invalid*/public static function getPathOfNamespace($namespace,$ext=''){if(isset(self::$_usings[$namespace]))return self::$_usings[$namespace];else if(isset(self::$_aliases[$namespace]))return self::$_aliases[$namespace];else{$segs=explode('.',$namespace);$alias=array_shift($segs);if(($file=array_pop($segs))!==null && ($root=self::getPathOfAlias($alias))!==null)return rtrim($root.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR ,$segs),'/\\').(($file==='*')?'':DIRECTORY_SEPARATOR.$file.$ext);elsereturn null;}}/*** @param string alias to the path* @return string the path corresponding to the alias, null if alias not defined.*/public static function getPathOfAlias($alias){return isset(self::$_aliases[$alias])?self::$_aliases[$alias]:null;}protected static function getPathAliases(){return self::$_aliases;}/*** @param string alias to the path* @param string the path corresponding to the alias* @throws TInvalidOperationException if the alias is already defined* @throws TInvalidDataValueException if the path is not a valid file path*/public static function setPathOfAlias($alias,$path){if(isset(self::$_aliases[$alias]))throw new TInvalidOperationException('prado_alias_redefined',$alias);else if(($rp=realpath($path))!==false && is_dir($rp)){if(strpos($alias,'.')===false)self::$_aliases[$alias]=$rp;elsethrow new TInvalidDataValueException('prado_aliasname_invalid',$alias);}elsethrow new TInvalidDataValueException('prado_alias_invalid',$alias,$path);}/*** Fatal error handler.* This method displays an error message together with the current call stack.* The application will exit after calling this method.* @param string error message*/public static function fatalError($msg){echo '<h1>Fatal Error</h1>';echo '<p>'.$msg.'</p>';if(!function_exists('debug_backtrace'))return;echo '<h2>Debug Backtrace</h2>';echo '<pre>';$index=-1;foreach(debug_backtrace() as $t){$index++;if($index==0) // hide the backtrace of this functioncontinue;echo '#'.$index.' ';if(isset($t['file']))echo basename($t['file']) . ':' . $t['line'];elseecho '<PHP inner-code>';echo ' -- ';if(isset($t['class']))echo $t['class'] . $t['type'];echo $t['function'] . '(';if(isset($t['args']) && sizeof($t['args']) > 0){$count=0;foreach($t['args'] as $item){if(is_string($item)){$str=htmlentities(str_replace("\r\n", "", $item), ENT_QUOTES);if (strlen($item) > 70)echo "'". substr($str, 0, 70) . "...'";elseecho "'" . $str . "'";}else if (is_int($item) || is_float($item))echo $item;else if (is_object($item))echo get_class($item);else if (is_array($item))echo 'array(' . count($item) . ')';else if (is_bool($item))echo $item ? 'true' : 'false';else if ($item === null)echo 'NULL';else if (is_resource($item))echo get_resource_type($item);$count++;if (count($t['args']) > $count)echo ', ';}}echo ")\n";}echo '</pre>';exit(1);}/*** Returns a list of user preferred languages.* The languages are returned as an array. Each array element* represents a single language preference. The languages are ordered* according to user preferences. The first language is the most preferred.* @return array list of user preferred languages.*/public static function getUserLanguages(){static $languages=null;if($languages===null){if(!isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))$languages[0]='en';else{$languages=array();foreach(explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']) as $language){$array=split(';q=',trim($language));$languages[trim($array[0])]=isset($array[1])?(float)$array[1]:1.0;}arsort($languages);$languages=array_keys($languages);if(empty($languages))$languages[0]='en';}}return $languages;}/*** Returns the most preferred language by the client user.* @return string the most preferred language by the client user, defaults to English.*/public static function getPreferredLanguage(){static $language=null;if($language===null){$langs=Prado::getUserLanguages();$lang=explode('-',$langs[0]);if(empty($lang[0]) || !ctype_alpha($lang[0]))$language='en';else$language=$lang[0];}return $language;}/*** Writes a log message.* This method wraps {@link log()} by checking the application mode.* When the application is in Debug mode, debug backtrace information is appended* to the message and the message is logged at DEBUG level.* When the application is in Performance mode, this method does nothing.* Otherwise, the message is logged at INFO level.* @param string message to be logged* @param string category of the message* @see log, getLogger*/public static function trace($msg,$category='Uncategorized'){if(self::$_application && self::$_application->getMode()===TApplicationMode::Performance)return;if(!self::$_application || self::$_application->getMode()===TApplicationMode::Debug){$trace=debug_backtrace();if(isset($trace[0]['file']) && isset($trace[0]['line']))$msg.=" (line {$trace[0]['line']}, {$trace[0]['file']})";$level=TLogger::DEBUG;}else$level=TLogger::INFO;self::log($msg,$level,$category);}/*** Logs a message.* Messages logged by this method may be retrieved via {@link TLogger::getLogs}* and may be recorded in different media, such as file, email, database, using* {@link TLogRouter}.* @param string message to be logged* @param integer level of the message. Valid values include* TLogger::DEBUG, TLogger::INFO, TLogger::NOTICE, TLogger::WARNING,* TLogger::ERROR, TLogger::ALERT, TLogger::FATAL.* @param string category of the message*/public static function log($msg,$level=TLogger::INFO,$category='Uncategorized'){if(self::$_logger===null)self::$_logger=new TLogger;self::$_logger->log($msg,$level,$category);}/*** @return TLogger message logger*/public static function getLogger(){if(self::$_logger===null)self::$_logger=new TLogger;return self::$_logger;}/*** Converts a variable into a string representation.* This method achieves the similar functionality as var_dump and print_r* but is more robust when handling complex objects such as PRADO controls.* @param mixed variable to be dumped* @param integer maximum depth that the dumper should go into the variable. Defaults to 10.* @param boolean whether to syntax highlight the output. Defaults to false.* @return string the string representation of the variable*/public static function varDump($var,$depth=10,$highlight=false){Prado::using('System.Util.TVarDumper');return TVarDumper::dump($var,$depth,$highlight);}/*** Localize a text to the locale/culture specified in the globalization handler.* @param string text to be localized.* @param array a set of parameters to substitute.* @param string a different catalogue to find the localize text.* @param string the input AND output charset.* @return string localized text.* @see TTranslate::formatter()* @see TTranslate::init()*/public static function localize($text, $parameters=array(), $catalogue=null, $charset=null){Prado::using('System.I18N.Translation');$app = Prado::getApplication()->getGlobalization(false);$params = array();foreach($parameters as $key => $value)$params['{'.$key.'}'] = $value;//no translation handler providedif($app===null || ($config = $app->getTranslationConfiguration())===null)return strtr($text, $params);if ($catalogue===null)$catalogue=isset($config['catalogue'])?$config['catalogue']:'messages';Translation::init($catalogue);//globalization charset$appCharset = $app===null ? '' : $app->getCharset();//default charset$defaultCharset = ($app===null) ? 'UTF-8' : $app->getDefaultCharset();//fall backif(empty($charset)) $charset = $appCharset;if(empty($charset)) $charset = $defaultCharset;return Translation::formatter($catalogue)->format($text,$params,$catalogue,$charset);}}/*** TReflectionClass class.* This class was originally written to cope with the incompatibility between different PHP versions.* It is equivalent to ReflectionClass for PHP version >= 5.1.0* @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: PradoBase.php 2602 2009-01-12 01:08:39Z qiang.xue $* @package System* @since 3.0*/class TReflectionClass extends ReflectionClass{}/*** Includes the classes essential for PradoBase class*/PradoBase::using('System.TComponent');PradoBase::using('System.Exceptions.TException');PradoBase::using('System.Util.TLogger');?>