diff options
Diffstat (limited to 'framework')
-rw-r--r-- | framework/PradoBase.php | 1238 |
1 files changed, 619 insertions, 619 deletions
diff --git a/framework/PradoBase.php b/framework/PradoBase.php index ead66e1b..4a64d6dd 100644 --- a/framework/PradoBase.php +++ b/framework/PradoBase.php @@ -1,619 +1,619 @@ -<?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$
- * @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$
- * @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.3a';
- }
-
- /**
- * 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>';
- }
-
- public static function metaGenerator()
- {
- return 'PRADO - http://www.pradosoft.com/';
- }
-
- /**
- * 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;
- }
- else
- return 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());
- else
- throw $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());
- else
- throw $e;
- }
- }
- }
- }
- else
- throw 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);
- else
- return 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;
- else
- throw new TInvalidDataValueException('prado_aliasname_invalid',$alias);
- }
- else
- throw 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 function
- continue;
- echo '#'.$index.' ';
- if(isset($t['file']))
- echo basename($t['file']) . ':' . $t['line'];
- else
- echo '<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) . "...'";
- else
- echo "'" . $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 provided
- if($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 back
- if(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$
- * @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');
-
-?>
+<?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$ + * @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$ + * @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.4a'; + } + + /** + * 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>'; + } + + public static function metaGenerator() + { + return 'PRADO - http://www.pradosoft.com/'; + } + + /** + * 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; + } + else + return 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()); + else + throw $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()); + else + throw $e; + } + } + } + } + else + throw 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); + else + return 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; + else + throw new TInvalidDataValueException('prado_aliasname_invalid',$alias); + } + else + throw 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 function + continue; + echo '#'.$index.' '; + if(isset($t['file'])) + echo basename($t['file']) . ':' . $t['line']; + else + echo '<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) . "...'"; + else + echo "'" . $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 provided + if($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 back + if(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$ + * @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'); + +?> |