"Fossies" - the Fresh Open Source Software Archive

Member "yii-1.1.22.bf1d26/framework/yiilite.php" (16 Jan 2020, 316476 Bytes) of package /linux/www/yii-1.1.22.bf1d26.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "yiilite.php" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.1.21.733ac5_vs_1.1.22.bf1d26.

    1 <?php
    2 /**
    3  * Yii bootstrap file.
    4  *
    5  * This file is automatically generated using 'build lite' command.
    6  * It is the result of merging commonly used Yii class files with
    7  * comments and trace statements removed away.
    8  *
    9  * By using this file instead of yii.php, an Yii application may
   10  * improve performance due to the reduction of PHP parsing time.
   11  * The performance improvement is especially obvious when PHP APC extension
   12  * is enabled.
   13  *
   14  * DO NOT modify this file manually.
   15  *
   16  * @author Qiang Xue <qiang.xue@gmail.com>
   17  * @link http://www.yiiframework.com/
   18  * @copyright 2008-2013 Yii Software LLC
   19  * @license http://www.yiiframework.com/license/
   20  * @version $Id: $
   21  * @since 1.0
   22  */
   23 
   24 
   25 defined('YII_BEGIN_TIME') or define('YII_BEGIN_TIME',microtime(true));
   26 defined('YII_DEBUG') or define('YII_DEBUG',false);
   27 defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',0);
   28 defined('YII_ENABLE_EXCEPTION_HANDLER') or define('YII_ENABLE_EXCEPTION_HANDLER',true);
   29 defined('YII_ENABLE_ERROR_HANDLER') or define('YII_ENABLE_ERROR_HANDLER',true);
   30 defined('YII_PATH') or define('YII_PATH',dirname(__FILE__));
   31 defined('YII_ZII_PATH') or define('YII_ZII_PATH',YII_PATH.DIRECTORY_SEPARATOR.'zii');
   32 class YiiBase
   33 {
   34     public static $autoloaderFilters=array();
   35     public static $classMap=array();
   36     public static $enableIncludePath=true;
   37     private static $_aliases=array('system'=>YII_PATH,'zii'=>YII_ZII_PATH); // alias => path
   38     private static $_imports=array();                   // alias => class name or directory
   39     private static $_includePaths;                      // list of include paths
   40     private static $_app;
   41     private static $_logger;
   42     public static function getVersion()
   43     {
   44         return '1.1.22';
   45     }
   46     public static function createWebApplication($config=null)
   47     {
   48         return self::createApplication('CWebApplication',$config);
   49     }
   50     public static function createConsoleApplication($config=null)
   51     {
   52         return self::createApplication('CConsoleApplication',$config);
   53     }
   54     public static function createApplication($class,$config=null)
   55     {
   56         return new $class($config);
   57     }
   58     public static function app()
   59     {
   60         return self::$_app;
   61     }
   62     public static function setApplication($app)
   63     {
   64         if(self::$_app===null || $app===null)
   65             self::$_app=$app;
   66         else
   67             throw new CException(Yii::t('yii','Yii application can only be created once.'));
   68     }
   69     public static function getFrameworkPath()
   70     {
   71         return YII_PATH;
   72     }
   73     public static function createComponent($config)
   74     {
   75         $args = func_get_args();
   76         if(is_string($config))
   77         {
   78             $type=$config;
   79             $config=array();
   80         }
   81         elseif(isset($config['class']))
   82         {
   83             $type=$config['class'];
   84             unset($config['class']);
   85         }
   86         else
   87             throw new CException(Yii::t('yii','Object configuration must be an array containing a "class" element.'));
   88         if(!class_exists($type,false))
   89             $type=Yii::import($type,true);
   90         if(($n=func_num_args())>1)
   91         {
   92             if($n===2)
   93                 $object=new $type($args[1]);
   94             elseif($n===3)
   95                 $object=new $type($args[1],$args[2]);
   96             elseif($n===4)
   97                 $object=new $type($args[1],$args[2],$args[3]);
   98             else
   99             {
  100                 unset($args[0]);
  101                 $class=new ReflectionClass($type);
  102                 // Note: ReflectionClass::newInstanceArgs() is available for PHP 5.1.3+
  103                 // $object=$class->newInstanceArgs($args);
  104                 $object=call_user_func_array(array($class,'newInstance'),$args);
  105             }
  106         }
  107         else
  108             $object=new $type;
  109         foreach($config as $key=>$value)
  110             $object->$key=$value;
  111         return $object;
  112     }
  113     public static function import($alias,$forceInclude=false)
  114     {
  115         if(isset(self::$_imports[$alias]))  // previously imported
  116             return self::$_imports[$alias];
  117         if(class_exists($alias,false) || interface_exists($alias,false))
  118             return self::$_imports[$alias]=$alias;
  119         if(($pos=strrpos($alias,'\\'))!==false) // a class name in PHP 5.3 namespace format
  120         {
  121             $namespace=str_replace('\\','.',ltrim(substr($alias,0,$pos),'\\'));
  122             if(($path=self::getPathOfAlias($namespace))!==false)
  123             {
  124                 $classFile=$path.DIRECTORY_SEPARATOR.substr($alias,$pos+1).'.php';
  125                 if($forceInclude)
  126                 {
  127                     if(is_file($classFile))
  128                         require($classFile);
  129                     else
  130                         throw new CException(Yii::t('yii','Alias "{alias}" is invalid. Make sure it points to an existing PHP file and the file is readable.',array('{alias}'=>$alias)));
  131                     self::$_imports[$alias]=$alias;
  132                 }
  133                 else
  134                     self::$classMap[$alias]=$classFile;
  135                 return $alias;
  136             }
  137             else
  138             {
  139                 // try to autoload the class with an autoloader
  140                 if (class_exists($alias,true))
  141                     return self::$_imports[$alias]=$alias;
  142                 else
  143                     throw new CException(Yii::t('yii','Alias "{alias}" is invalid. Make sure it points to an existing directory or file.',
  144                         array('{alias}'=>$namespace)));
  145             }
  146         }
  147         if(($pos=strrpos($alias,'.'))===false)  // a simple class name
  148         {
  149             // try to autoload the class with an autoloader if $forceInclude is true
  150             if($forceInclude && (Yii::autoload($alias,true) || class_exists($alias,true)))
  151                 self::$_imports[$alias]=$alias;
  152             return $alias;
  153         }
  154         $className=(string)substr($alias,$pos+1);
  155         $isClass=$className!=='*';
  156         if($isClass && (class_exists($className,false) || interface_exists($className,false)))
  157             return self::$_imports[$alias]=$className;
  158         if(($path=self::getPathOfAlias($alias))!==false)
  159         {
  160             if($isClass)
  161             {
  162                 if($forceInclude)
  163                 {
  164                     if(is_file($path.'.php'))
  165                         require($path.'.php');
  166                     else
  167                         throw new CException(Yii::t('yii','Alias "{alias}" is invalid. Make sure it points to an existing PHP file and the file is readable.',array('{alias}'=>$alias)));
  168                     self::$_imports[$alias]=$className;
  169                 }
  170                 else
  171                     self::$classMap[$className]=$path.'.php';
  172                 return $className;
  173             }
  174             else  // a directory
  175             {
  176                 if(self::$_includePaths===null)
  177                 {
  178                     self::$_includePaths=array_unique(explode(PATH_SEPARATOR,get_include_path()));
  179                     if(($pos=array_search('.',self::$_includePaths,true))!==false)
  180                         unset(self::$_includePaths[$pos]);
  181                 }
  182                 array_unshift(self::$_includePaths,$path);
  183                 if(self::$enableIncludePath && set_include_path('.'.PATH_SEPARATOR.implode(PATH_SEPARATOR,self::$_includePaths))===false)
  184                     self::$enableIncludePath=false;
  185                 return self::$_imports[$alias]=$path;
  186             }
  187         }
  188         else
  189             throw new CException(Yii::t('yii','Alias "{alias}" is invalid. Make sure it points to an existing directory or file.',
  190                 array('{alias}'=>$alias)));
  191     }
  192     public static function getPathOfAlias($alias)
  193     {
  194         if(isset(self::$_aliases[$alias]))
  195             return self::$_aliases[$alias];
  196         elseif(($pos=strpos($alias,'.'))!==false)
  197         {
  198             $rootAlias=substr($alias,0,$pos);
  199             if(isset(self::$_aliases[$rootAlias]))
  200                 return self::$_aliases[$alias]=rtrim(self::$_aliases[$rootAlias].DIRECTORY_SEPARATOR.str_replace('.',DIRECTORY_SEPARATOR,substr($alias,$pos+1)),'*'.DIRECTORY_SEPARATOR);
  201             elseif(self::$_app instanceof CWebApplication)
  202             {
  203                 if(self::$_app->findModule($rootAlias)!==null)
  204                     return self::getPathOfAlias($alias);
  205             }
  206         }
  207         return false;
  208     }
  209     public static function setPathOfAlias($alias,$path)
  210     {
  211         if(empty($path))
  212             unset(self::$_aliases[$alias]);
  213         else
  214             self::$_aliases[$alias]=rtrim($path,'\\/');
  215     }
  216     public static function autoload($className,$classMapOnly=false)
  217     {
  218         foreach (self::$autoloaderFilters as $filter)
  219         {
  220             if (is_array($filter)
  221                 && isset($filter[0]) && isset($filter[1])
  222                 && is_string($filter[0]) && is_string($filter[1])
  223                 && true === call_user_func(array($filter[0], $filter[1]), $className)
  224             )
  225             {
  226                 return true;
  227             }
  228             elseif (is_string($filter)
  229                 && true === call_user_func($filter, $className)
  230             )
  231             {
  232                 return true;
  233             }
  234             elseif (is_callable($filter)
  235                 && true === $filter($className)
  236             )
  237             {
  238                 return true;
  239             }
  240         }
  241         // use include so that the error PHP file may appear
  242         if(isset(self::$classMap[$className]))
  243             include(self::$classMap[$className]);
  244         elseif(isset(self::$_coreClasses[$className]))
  245             include(YII_PATH.self::$_coreClasses[$className]);
  246         elseif($classMapOnly)
  247             return false;
  248         else
  249         {
  250             // include class file relying on include_path
  251             if(strpos($className,'\\')===false)  // class without namespace
  252             {
  253                 if(self::$enableIncludePath===false)
  254                 {
  255                     foreach(self::$_includePaths as $path)
  256                     {
  257                         $classFile=$path.DIRECTORY_SEPARATOR.$className.'.php';
  258                         if(is_file($classFile))
  259                         {
  260                             include($classFile);
  261                             if(YII_DEBUG && basename(realpath($classFile))!==$className.'.php')
  262                                 throw new CException(Yii::t('yii','Class name "{class}" does not match class file "{file}".', array(
  263                                     '{class}'=>$className,
  264                                     '{file}'=>$classFile,
  265                                 )));
  266                             break;
  267                         }
  268                     }
  269                 }
  270                 else
  271                     include($className.'.php');
  272             }
  273             else  // class name with namespace in PHP 5.3
  274             {
  275                 $namespace=str_replace('\\','.',ltrim($className,'\\'));
  276                 if(($path=self::getPathOfAlias($namespace))!==false && is_file($path.'.php'))
  277                     include($path.'.php');
  278                 else
  279                     return false;
  280             }
  281             return class_exists($className,false) || interface_exists($className,false);
  282         }
  283         return true;
  284     }
  285     public static function trace($msg,$category='application')
  286     {
  287         if(YII_DEBUG)
  288             self::log($msg,CLogger::LEVEL_TRACE,$category);
  289     }
  290     public static function log($msg,$level=CLogger::LEVEL_INFO,$category='application')
  291     {
  292         if(self::$_logger===null)
  293             self::$_logger=new CLogger;
  294         if(YII_DEBUG && YII_TRACE_LEVEL>0 && $level!==CLogger::LEVEL_PROFILE)
  295         {
  296             $traces=debug_backtrace();
  297             $count=0;
  298             foreach($traces as $trace)
  299             {
  300                 if(isset($trace['file'],$trace['line']) && strpos($trace['file'],YII_PATH)!==0)
  301                 {
  302                     $msg.="\nin ".$trace['file'].' ('.$trace['line'].')';
  303                     if(++$count>=YII_TRACE_LEVEL)
  304                         break;
  305                 }
  306             }
  307         }
  308         self::$_logger->log($msg,$level,$category);
  309     }
  310     public static function beginProfile($token,$category='application')
  311     {
  312         self::log('begin:'.$token,CLogger::LEVEL_PROFILE,$category);
  313     }
  314     public static function endProfile($token,$category='application')
  315     {
  316         self::log('end:'.$token,CLogger::LEVEL_PROFILE,$category);
  317     }
  318     public static function getLogger()
  319     {
  320         if(self::$_logger!==null)
  321             return self::$_logger;
  322         else
  323             return self::$_logger=new CLogger;
  324     }
  325     public static function setLogger($logger)
  326     {
  327         self::$_logger=$logger;
  328     }
  329     public static function powered()
  330     {
  331         return Yii::t('yii','Powered by {yii}.', array('{yii}'=>'<a href="http://www.yiiframework.com/" rel="external">Yii Framework</a>'));
  332     }
  333     public static function t($category,$message,$params=array(),$source=null,$language=null)
  334     {
  335         if(self::$_app!==null)
  336         {
  337             if($source===null)
  338                 $source=($category==='yii'||$category==='zii')?'coreMessages':'messages';
  339             if(($source=self::$_app->getComponent($source))!==null)
  340                 $message=$source->translate($category,$message,$language);
  341         }
  342         if($params===array())
  343             return $message;
  344         if(!is_array($params))
  345             $params=array($params);
  346         if(isset($params[0])) // number choice
  347         {
  348             if(strpos($message,'|')!==false)
  349             {
  350                 if(strpos($message,'#')===false)
  351                 {
  352                     $chunks=explode('|',$message);
  353                     $expressions=self::$_app->getLocale($language)->getPluralRules();
  354                     if($n=min(count($chunks),count($expressions)))
  355                     {
  356                         for($i=0;$i<$n;$i++)
  357                             $chunks[$i]=$expressions[$i].'#'.$chunks[$i];
  358                         $message=implode('|',$chunks);
  359                     }
  360                 }
  361                 $message=CChoiceFormat::format($message,$params[0]);
  362             }
  363             if(!isset($params['{n}']))
  364                 $params['{n}']=$params[0];
  365             unset($params[0]);
  366         }
  367         return $params!==array() ? strtr($message,$params) : $message;
  368     }
  369     public static function registerAutoloader($callback, $append=false)
  370     {
  371         if($append)
  372         {
  373             self::$enableIncludePath=false;
  374             spl_autoload_register($callback);
  375         }
  376         else
  377         {
  378             spl_autoload_unregister(array('YiiBase','autoload'));
  379             spl_autoload_register($callback);
  380             spl_autoload_register(array('YiiBase','autoload'));
  381         }
  382     }
  383     private static $_coreClasses=array(
  384         'CApplication' => '/base/CApplication.php',
  385         'CApplicationComponent' => '/base/CApplicationComponent.php',
  386         'CBehavior' => '/base/CBehavior.php',
  387         'CComponent' => '/base/CComponent.php',
  388         'CDbStatePersister' => '/base/CDbStatePersister.php',
  389         'CErrorEvent' => '/base/CErrorEvent.php',
  390         'CErrorHandler' => '/base/CErrorHandler.php',
  391         'CException' => '/base/CException.php',
  392         'CExceptionEvent' => '/base/CExceptionEvent.php',
  393         'CHttpException' => '/base/CHttpException.php',
  394         'CModel' => '/base/CModel.php',
  395         'CModelBehavior' => '/base/CModelBehavior.php',
  396         'CModelEvent' => '/base/CModelEvent.php',
  397         'CModule' => '/base/CModule.php',
  398         'CSecurityManager' => '/base/CSecurityManager.php',
  399         'CStatePersister' => '/base/CStatePersister.php',
  400         'CApcCache' => '/caching/CApcCache.php',
  401         'CCache' => '/caching/CCache.php',
  402         'CDbCache' => '/caching/CDbCache.php',
  403         'CDummyCache' => '/caching/CDummyCache.php',
  404         'CEAcceleratorCache' => '/caching/CEAcceleratorCache.php',
  405         'CFileCache' => '/caching/CFileCache.php',
  406         'CMemCache' => '/caching/CMemCache.php',
  407         'CRedisCache' => '/caching/CRedisCache.php',
  408         'CWinCache' => '/caching/CWinCache.php',
  409         'CXCache' => '/caching/CXCache.php',
  410         'CZendDataCache' => '/caching/CZendDataCache.php',
  411         'CCacheDependency' => '/caching/dependencies/CCacheDependency.php',
  412         'CChainedCacheDependency' => '/caching/dependencies/CChainedCacheDependency.php',
  413         'CDbCacheDependency' => '/caching/dependencies/CDbCacheDependency.php',
  414         'CDirectoryCacheDependency' => '/caching/dependencies/CDirectoryCacheDependency.php',
  415         'CExpressionDependency' => '/caching/dependencies/CExpressionDependency.php',
  416         'CFileCacheDependency' => '/caching/dependencies/CFileCacheDependency.php',
  417         'CGlobalStateCacheDependency' => '/caching/dependencies/CGlobalStateCacheDependency.php',
  418         'CAttributeCollection' => '/collections/CAttributeCollection.php',
  419         'CConfiguration' => '/collections/CConfiguration.php',
  420         'CList' => '/collections/CList.php',
  421         'CListIterator' => '/collections/CListIterator.php',
  422         'CMap' => '/collections/CMap.php',
  423         'CMapIterator' => '/collections/CMapIterator.php',
  424         'CQueue' => '/collections/CQueue.php',
  425         'CQueueIterator' => '/collections/CQueueIterator.php',
  426         'CStack' => '/collections/CStack.php',
  427         'CStackIterator' => '/collections/CStackIterator.php',
  428         'CTypedList' => '/collections/CTypedList.php',
  429         'CTypedMap' => '/collections/CTypedMap.php',
  430         'CConsoleApplication' => '/console/CConsoleApplication.php',
  431         'CConsoleCommand' => '/console/CConsoleCommand.php',
  432         'CConsoleCommandBehavior' => '/console/CConsoleCommandBehavior.php',
  433         'CConsoleCommandEvent' => '/console/CConsoleCommandEvent.php',
  434         'CConsoleCommandRunner' => '/console/CConsoleCommandRunner.php',
  435         'CHelpCommand' => '/console/CHelpCommand.php',
  436         'CDbCommand' => '/db/CDbCommand.php',
  437         'CDbConnection' => '/db/CDbConnection.php',
  438         'CDbDataReader' => '/db/CDbDataReader.php',
  439         'CDbException' => '/db/CDbException.php',
  440         'CDbMigration' => '/db/CDbMigration.php',
  441         'CDbTransaction' => '/db/CDbTransaction.php',
  442         'CActiveFinder' => '/db/ar/CActiveFinder.php',
  443         'CActiveRecord' => '/db/ar/CActiveRecord.php',
  444         'CActiveRecordBehavior' => '/db/ar/CActiveRecordBehavior.php',
  445         'CDbColumnSchema' => '/db/schema/CDbColumnSchema.php',
  446         'CDbCommandBuilder' => '/db/schema/CDbCommandBuilder.php',
  447         'CDbCriteria' => '/db/schema/CDbCriteria.php',
  448         'CDbExpression' => '/db/schema/CDbExpression.php',
  449         'CDbSchema' => '/db/schema/CDbSchema.php',
  450         'CDbTableSchema' => '/db/schema/CDbTableSchema.php',
  451         'CCubridColumnSchema' => '/db/schema/cubrid/CCubridColumnSchema.php',
  452         'CCubridSchema' => '/db/schema/cubrid/CCubridSchema.php',
  453         'CCubridTableSchema' => '/db/schema/cubrid/CCubridTableSchema.php',
  454         'CMssqlColumnSchema' => '/db/schema/mssql/CMssqlColumnSchema.php',
  455         'CMssqlCommandBuilder' => '/db/schema/mssql/CMssqlCommandBuilder.php',
  456         'CMssqlPdoAdapter' => '/db/schema/mssql/CMssqlPdoAdapter.php',
  457         'CMssqlSchema' => '/db/schema/mssql/CMssqlSchema.php',
  458         'CMssqlSqlsrvPdoAdapter' => '/db/schema/mssql/CMssqlSqlsrvPdoAdapter.php',
  459         'CMssqlTableSchema' => '/db/schema/mssql/CMssqlTableSchema.php',
  460         'CMysqlColumnSchema' => '/db/schema/mysql/CMysqlColumnSchema.php',
  461         'CMysqlCommandBuilder' => '/db/schema/mysql/CMysqlCommandBuilder.php',
  462         'CMysqlSchema' => '/db/schema/mysql/CMysqlSchema.php',
  463         'CMysqlTableSchema' => '/db/schema/mysql/CMysqlTableSchema.php',
  464         'COciColumnSchema' => '/db/schema/oci/COciColumnSchema.php',
  465         'COciCommandBuilder' => '/db/schema/oci/COciCommandBuilder.php',
  466         'COciSchema' => '/db/schema/oci/COciSchema.php',
  467         'COciTableSchema' => '/db/schema/oci/COciTableSchema.php',
  468         'CPgsqlColumnSchema' => '/db/schema/pgsql/CPgsqlColumnSchema.php',
  469         'CPgsqlCommandBuilder' => '/db/schema/pgsql/CPgsqlCommandBuilder.php',
  470         'CPgsqlSchema' => '/db/schema/pgsql/CPgsqlSchema.php',
  471         'CPgsqlTableSchema' => '/db/schema/pgsql/CPgsqlTableSchema.php',
  472         'CSqliteColumnSchema' => '/db/schema/sqlite/CSqliteColumnSchema.php',
  473         'CSqliteCommandBuilder' => '/db/schema/sqlite/CSqliteCommandBuilder.php',
  474         'CSqliteSchema' => '/db/schema/sqlite/CSqliteSchema.php',
  475         'CChoiceFormat' => '/i18n/CChoiceFormat.php',
  476         'CDateFormatter' => '/i18n/CDateFormatter.php',
  477         'CDbMessageSource' => '/i18n/CDbMessageSource.php',
  478         'CGettextMessageSource' => '/i18n/CGettextMessageSource.php',
  479         'CLocale' => '/i18n/CLocale.php',
  480         'CMessageSource' => '/i18n/CMessageSource.php',
  481         'CNumberFormatter' => '/i18n/CNumberFormatter.php',
  482         'CPhpMessageSource' => '/i18n/CPhpMessageSource.php',
  483         'CGettextFile' => '/i18n/gettext/CGettextFile.php',
  484         'CGettextMoFile' => '/i18n/gettext/CGettextMoFile.php',
  485         'CGettextPoFile' => '/i18n/gettext/CGettextPoFile.php',
  486         'CChainedLogFilter' => '/logging/CChainedLogFilter.php',
  487         'CDbLogRoute' => '/logging/CDbLogRoute.php',
  488         'CEmailLogRoute' => '/logging/CEmailLogRoute.php',
  489         'CFileLogRoute' => '/logging/CFileLogRoute.php',
  490         'CLogFilter' => '/logging/CLogFilter.php',
  491         'CLogRoute' => '/logging/CLogRoute.php',
  492         'CLogRouter' => '/logging/CLogRouter.php',
  493         'CLogger' => '/logging/CLogger.php',
  494         'CProfileLogRoute' => '/logging/CProfileLogRoute.php',
  495         'CSysLogRoute' => '/logging/CSysLogRoute.php',
  496         'CWebLogRoute' => '/logging/CWebLogRoute.php',
  497         'CDateTimeParser' => '/utils/CDateTimeParser.php',
  498         'CFileHelper' => '/utils/CFileHelper.php',
  499         'CFormatter' => '/utils/CFormatter.php',
  500         'CLocalizedFormatter' => '/utils/CLocalizedFormatter.php',
  501         'CMarkdownParser' => '/utils/CMarkdownParser.php',
  502         'CPasswordHelper' => '/utils/CPasswordHelper.php',
  503         'CPropertyValue' => '/utils/CPropertyValue.php',
  504         'CTimestamp' => '/utils/CTimestamp.php',
  505         'CVarDumper' => '/utils/CVarDumper.php',
  506         'CBooleanValidator' => '/validators/CBooleanValidator.php',
  507         'CCaptchaValidator' => '/validators/CCaptchaValidator.php',
  508         'CCompareValidator' => '/validators/CCompareValidator.php',
  509         'CDateValidator' => '/validators/CDateValidator.php',
  510         'CDefaultValueValidator' => '/validators/CDefaultValueValidator.php',
  511         'CEmailValidator' => '/validators/CEmailValidator.php',
  512         'CExistValidator' => '/validators/CExistValidator.php',
  513         'CFileValidator' => '/validators/CFileValidator.php',
  514         'CFilterValidator' => '/validators/CFilterValidator.php',
  515         'CInlineValidator' => '/validators/CInlineValidator.php',
  516         'CNumberValidator' => '/validators/CNumberValidator.php',
  517         'CRangeValidator' => '/validators/CRangeValidator.php',
  518         'CRegularExpressionValidator' => '/validators/CRegularExpressionValidator.php',
  519         'CRequiredValidator' => '/validators/CRequiredValidator.php',
  520         'CSafeValidator' => '/validators/CSafeValidator.php',
  521         'CStringValidator' => '/validators/CStringValidator.php',
  522         'CTypeValidator' => '/validators/CTypeValidator.php',
  523         'CUniqueValidator' => '/validators/CUniqueValidator.php',
  524         'CUnsafeValidator' => '/validators/CUnsafeValidator.php',
  525         'CUrlValidator' => '/validators/CUrlValidator.php',
  526         'CValidator' => '/validators/CValidator.php',
  527         'CActiveDataProvider' => '/web/CActiveDataProvider.php',
  528         'CArrayDataProvider' => '/web/CArrayDataProvider.php',
  529         'CAssetManager' => '/web/CAssetManager.php',
  530         'CBaseController' => '/web/CBaseController.php',
  531         'CCacheHttpSession' => '/web/CCacheHttpSession.php',
  532         'CClientScript' => '/web/CClientScript.php',
  533         'CController' => '/web/CController.php',
  534         'CDataProvider' => '/web/CDataProvider.php',
  535         'CDataProviderIterator' => '/web/CDataProviderIterator.php',
  536         'CDbHttpSession' => '/web/CDbHttpSession.php',
  537         'CExtController' => '/web/CExtController.php',
  538         'CFormModel' => '/web/CFormModel.php',
  539         'CHttpCookie' => '/web/CHttpCookie.php',
  540         'CHttpRequest' => '/web/CHttpRequest.php',
  541         'CHttpSession' => '/web/CHttpSession.php',
  542         'CHttpSessionIterator' => '/web/CHttpSessionIterator.php',
  543         'COutputEvent' => '/web/COutputEvent.php',
  544         'CPagination' => '/web/CPagination.php',
  545         'CSort' => '/web/CSort.php',
  546         'CSqlDataProvider' => '/web/CSqlDataProvider.php',
  547         'CTheme' => '/web/CTheme.php',
  548         'CThemeManager' => '/web/CThemeManager.php',
  549         'CUploadedFile' => '/web/CUploadedFile.php',
  550         'CUrlManager' => '/web/CUrlManager.php',
  551         'CWebApplication' => '/web/CWebApplication.php',
  552         'CWebModule' => '/web/CWebModule.php',
  553         'CWidgetFactory' => '/web/CWidgetFactory.php',
  554         'CAction' => '/web/actions/CAction.php',
  555         'CInlineAction' => '/web/actions/CInlineAction.php',
  556         'CViewAction' => '/web/actions/CViewAction.php',
  557         'CAccessControlFilter' => '/web/auth/CAccessControlFilter.php',
  558         'CAuthAssignment' => '/web/auth/CAuthAssignment.php',
  559         'CAuthItem' => '/web/auth/CAuthItem.php',
  560         'CAuthManager' => '/web/auth/CAuthManager.php',
  561         'CBaseUserIdentity' => '/web/auth/CBaseUserIdentity.php',
  562         'CDbAuthManager' => '/web/auth/CDbAuthManager.php',
  563         'CPhpAuthManager' => '/web/auth/CPhpAuthManager.php',
  564         'CUserIdentity' => '/web/auth/CUserIdentity.php',
  565         'CWebUser' => '/web/auth/CWebUser.php',
  566         'CFilter' => '/web/filters/CFilter.php',
  567         'CFilterChain' => '/web/filters/CFilterChain.php',
  568         'CHttpCacheFilter' => '/web/filters/CHttpCacheFilter.php',
  569         'CInlineFilter' => '/web/filters/CInlineFilter.php',
  570         'CForm' => '/web/form/CForm.php',
  571         'CFormButtonElement' => '/web/form/CFormButtonElement.php',
  572         'CFormElement' => '/web/form/CFormElement.php',
  573         'CFormElementCollection' => '/web/form/CFormElementCollection.php',
  574         'CFormInputElement' => '/web/form/CFormInputElement.php',
  575         'CFormStringElement' => '/web/form/CFormStringElement.php',
  576         'CGoogleApi' => '/web/helpers/CGoogleApi.php',
  577         'CHtml' => '/web/helpers/CHtml.php',
  578         'CJSON' => '/web/helpers/CJSON.php',
  579         'CJavaScript' => '/web/helpers/CJavaScript.php',
  580         'CJavaScriptExpression' => '/web/helpers/CJavaScriptExpression.php',
  581         'CPradoViewRenderer' => '/web/renderers/CPradoViewRenderer.php',
  582         'CViewRenderer' => '/web/renderers/CViewRenderer.php',
  583         'CWebService' => '/web/services/CWebService.php',
  584         'CWebServiceAction' => '/web/services/CWebServiceAction.php',
  585         'CWsdlGenerator' => '/web/services/CWsdlGenerator.php',
  586         'CActiveForm' => '/web/widgets/CActiveForm.php',
  587         'CAutoComplete' => '/web/widgets/CAutoComplete.php',
  588         'CClipWidget' => '/web/widgets/CClipWidget.php',
  589         'CContentDecorator' => '/web/widgets/CContentDecorator.php',
  590         'CFilterWidget' => '/web/widgets/CFilterWidget.php',
  591         'CFlexWidget' => '/web/widgets/CFlexWidget.php',
  592         'CHtmlPurifier' => '/web/widgets/CHtmlPurifier.php',
  593         'CInputWidget' => '/web/widgets/CInputWidget.php',
  594         'CMarkdown' => '/web/widgets/CMarkdown.php',
  595         'CMaskedTextField' => '/web/widgets/CMaskedTextField.php',
  596         'CMultiFileUpload' => '/web/widgets/CMultiFileUpload.php',
  597         'COutputCache' => '/web/widgets/COutputCache.php',
  598         'COutputProcessor' => '/web/widgets/COutputProcessor.php',
  599         'CStarRating' => '/web/widgets/CStarRating.php',
  600         'CTabView' => '/web/widgets/CTabView.php',
  601         'CTextHighlighter' => '/web/widgets/CTextHighlighter.php',
  602         'CTreeView' => '/web/widgets/CTreeView.php',
  603         'CWidget' => '/web/widgets/CWidget.php',
  604         'CCaptcha' => '/web/widgets/captcha/CCaptcha.php',
  605         'CCaptchaAction' => '/web/widgets/captcha/CCaptchaAction.php',
  606         'CBasePager' => '/web/widgets/pagers/CBasePager.php',
  607         'CLinkPager' => '/web/widgets/pagers/CLinkPager.php',
  608         'CListPager' => '/web/widgets/pagers/CListPager.php',
  609     );
  610 }
  611 spl_autoload_register(array('YiiBase','autoload'));
  612 if(!class_exists('YiiBase', false))
  613     require(dirname(__FILE__).'/YiiBase.php');
  614 class Yii extends YiiBase
  615 {
  616 }
  617 class CComponent
  618 {
  619     private $_e;
  620     private $_m;
  621     public function __get($name)
  622     {
  623         $getter='get'.$name;
  624         if(method_exists($this,$getter))
  625             return $this->$getter();
  626         elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
  627         {
  628             // duplicating getEventHandlers() here for performance
  629             $name=strtolower($name);
  630             if(!isset($this->_e[$name]))
  631                 $this->_e[$name]=new CList;
  632             return $this->_e[$name];
  633         }
  634         elseif(isset($this->_m[$name]))
  635             return $this->_m[$name];
  636         elseif(is_array($this->_m))
  637         {
  638             foreach($this->_m as $object)
  639             {
  640                 if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
  641                     return $object->$name;
  642             }
  643         }
  644         throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
  645             array('{class}'=>get_class($this), '{property}'=>$name)));
  646     }
  647     public function __set($name,$value)
  648     {
  649         $setter='set'.$name;
  650         if(method_exists($this,$setter))
  651             return $this->$setter($value);
  652         elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
  653         {
  654             // duplicating getEventHandlers() here for performance
  655             $name=strtolower($name);
  656             if(!isset($this->_e[$name]))
  657                 $this->_e[$name]=new CList;
  658             return $this->_e[$name]->add($value);
  659         }
  660         elseif(is_array($this->_m))
  661         {
  662             foreach($this->_m as $object)
  663             {
  664                 if($object->getEnabled() && (property_exists($object,$name) || $object->canSetProperty($name)))
  665                     return $object->$name=$value;
  666             }
  667         }
  668         if(method_exists($this,'get'.$name))
  669             throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',
  670                 array('{class}'=>get_class($this), '{property}'=>$name)));
  671         else
  672             throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
  673                 array('{class}'=>get_class($this), '{property}'=>$name)));
  674     }
  675     public function __isset($name)
  676     {
  677         $getter='get'.$name;
  678         if(method_exists($this,$getter))
  679             return $this->$getter()!==null;
  680         elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
  681         {
  682             $name=strtolower($name);
  683             return isset($this->_e[$name]) && $this->_e[$name]->getCount();
  684         }
  685         elseif(is_array($this->_m))
  686         {
  687             if(isset($this->_m[$name]))
  688                 return true;
  689             foreach($this->_m as $object)
  690             {
  691                 if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
  692                     return $object->$name!==null;
  693             }
  694         }
  695         return false;
  696     }
  697     public function __unset($name)
  698     {
  699         $setter='set'.$name;
  700         if(method_exists($this,$setter))
  701             $this->$setter(null);
  702         elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
  703             unset($this->_e[strtolower($name)]);
  704         elseif(is_array($this->_m))
  705         {
  706             if(isset($this->_m[$name]))
  707                 $this->detachBehavior($name);
  708             else
  709             {
  710                 foreach($this->_m as $object)
  711                 {
  712                     if($object->getEnabled())
  713                     {
  714                         if(property_exists($object,$name))
  715                             return $object->$name=null;
  716                         elseif($object->canSetProperty($name))
  717                             return $object->$setter(null);
  718                     }
  719                 }
  720             }
  721         }
  722         elseif(method_exists($this,'get'.$name))
  723             throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',
  724                 array('{class}'=>get_class($this), '{property}'=>$name)));
  725     }
  726     public function __call($name,$parameters)
  727     {
  728         if($this->_m!==null)
  729         {
  730             foreach($this->_m as $object)
  731             {
  732                 if($object->getEnabled() && method_exists($object,$name))
  733                     return call_user_func_array(array($object,$name),$parameters);
  734             }
  735         }
  736         if(class_exists('Closure', false) && ($this->canGetProperty($name) || property_exists($this, $name)) && $this->$name instanceof Closure)
  737             return call_user_func_array($this->$name, $parameters);
  738         throw new CException(Yii::t('yii','{class} and its behaviors do not have a method or closure named "{name}".',
  739             array('{class}'=>get_class($this), '{name}'=>$name)));
  740     }
  741     public function asa($behavior)
  742     {
  743         return isset($this->_m[$behavior]) ? $this->_m[$behavior] : null;
  744     }
  745     public function attachBehaviors($behaviors)
  746     {
  747         foreach($behaviors as $name=>$behavior)
  748             $this->attachBehavior($name,$behavior);
  749     }
  750     public function detachBehaviors()
  751     {
  752         if($this->_m!==null)
  753         {
  754             foreach($this->_m as $name=>$behavior)
  755                 $this->detachBehavior($name);
  756             $this->_m=null;
  757         }
  758     }
  759     public function attachBehavior($name,$behavior)
  760     {
  761         if(!($behavior instanceof IBehavior))
  762             $behavior=Yii::createComponent($behavior);
  763         $behavior->setEnabled(true);
  764         $behavior->attach($this);
  765         return $this->_m[$name]=$behavior;
  766     }
  767     public function detachBehavior($name)
  768     {
  769         if(isset($this->_m[$name]))
  770         {
  771             $this->_m[$name]->detach($this);
  772             $behavior=$this->_m[$name];
  773             unset($this->_m[$name]);
  774             return $behavior;
  775         }
  776     }
  777     public function enableBehaviors()
  778     {
  779         if($this->_m!==null)
  780         {
  781             foreach($this->_m as $behavior)
  782                 $behavior->setEnabled(true);
  783         }
  784     }
  785     public function disableBehaviors()
  786     {
  787         if($this->_m!==null)
  788         {
  789             foreach($this->_m as $behavior)
  790                 $behavior->setEnabled(false);
  791         }
  792     }
  793     public function enableBehavior($name)
  794     {
  795         if(isset($this->_m[$name]))
  796             $this->_m[$name]->setEnabled(true);
  797     }
  798     public function disableBehavior($name)
  799     {
  800         if(isset($this->_m[$name]))
  801             $this->_m[$name]->setEnabled(false);
  802     }
  803     public function hasProperty($name)
  804     {
  805         return method_exists($this,'get'.$name) || method_exists($this,'set'.$name);
  806     }
  807     public function canGetProperty($name)
  808     {
  809         return method_exists($this,'get'.$name);
  810     }
  811     public function canSetProperty($name)
  812     {
  813         return method_exists($this,'set'.$name);
  814     }
  815     public function hasEvent($name)
  816     {
  817         return !strncasecmp($name,'on',2) && method_exists($this,$name);
  818     }
  819     public function hasEventHandler($name)
  820     {
  821         $name=strtolower($name);
  822         return isset($this->_e[$name]) && $this->_e[$name]->getCount()>0;
  823     }
  824     public function getEventHandlers($name)
  825     {
  826         if($this->hasEvent($name))
  827         {
  828             $name=strtolower($name);
  829             if(!isset($this->_e[$name]))
  830                 $this->_e[$name]=new CList;
  831             return $this->_e[$name];
  832         }
  833         else
  834             throw new CException(Yii::t('yii','Event "{class}.{event}" is not defined.',
  835                 array('{class}'=>get_class($this), '{event}'=>$name)));
  836     }
  837     public function attachEventHandler($name,$handler)
  838     {
  839         $this->getEventHandlers($name)->add($handler);
  840     }
  841     public function detachEventHandler($name,$handler)
  842     {
  843         if($this->hasEventHandler($name))
  844             return $this->getEventHandlers($name)->remove($handler)!==false;
  845         else
  846             return false;
  847     }
  848     public function raiseEvent($name,$event)
  849     {
  850         $name=strtolower($name);
  851         if(isset($this->_e[$name]))
  852         {
  853             foreach($this->_e[$name] as $handler)
  854             {
  855                 if(is_string($handler))
  856                     call_user_func($handler,$event);
  857                 elseif(is_callable($handler,true))
  858                 {
  859                     if(is_array($handler))
  860                     {
  861                         // an array: 0 - object, 1 - method name
  862                         list($object,$method)=$handler;
  863                         if(is_string($object))  // static method call
  864                             call_user_func($handler,$event);
  865                         elseif(method_exists($object,$method))
  866                             $object->$method($event);
  867                         else
  868                             throw new CException(Yii::t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
  869                                 array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>$handler[1])));
  870                     }
  871                     else // PHP 5.3: anonymous function
  872                         call_user_func($handler,$event);
  873                 }
  874                 else
  875                     throw new CException(Yii::t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
  876                         array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>gettype($handler))));
  877                 // stop further handling if param.handled is set true
  878                 if(($event instanceof CEvent) && $event->handled)
  879                     return;
  880             }
  881         }
  882         elseif(YII_DEBUG && !$this->hasEvent($name))
  883             throw new CException(Yii::t('yii','Event "{class}.{event}" is not defined.',
  884                 array('{class}'=>get_class($this), '{event}'=>$name)));
  885     }
  886     public function evaluateExpression($_expression_,$_data_=array())
  887     {
  888         if(is_string($_expression_))
  889         {
  890             extract($_data_);
  891             try
  892             {
  893                 return eval('return ' . $_expression_ . ';');
  894             }
  895             catch (ParseError $e)
  896             {
  897                 return false;
  898             }
  899         }
  900         else
  901         {
  902             $_data_[]=$this;
  903             return call_user_func_array($_expression_, $_data_);
  904         }
  905     }
  906 }
  907 class CEvent extends CComponent
  908 {
  909     public $sender;
  910     public $handled=false;
  911     public $params;
  912     public function __construct($sender=null,$params=null)
  913     {
  914         $this->sender=$sender;
  915         $this->params=$params;
  916     }
  917 }
  918 class CEnumerable
  919 {
  920 }
  921 abstract class CModule extends CComponent
  922 {
  923     public $preload=array();
  924     public $behaviors=array();
  925     private $_id;
  926     private $_parentModule;
  927     private $_basePath;
  928     private $_modulePath;
  929     private $_params;
  930     private $_modules=array();
  931     private $_moduleConfig=array();
  932     private $_components=array();
  933     private $_componentConfig=array();
  934     public function __construct($id,$parent,$config=null)
  935     {
  936         $this->_id=$id;
  937         $this->_parentModule=$parent;
  938         // set basePath as early as possible to avoid trouble
  939         if(is_string($config))
  940             $config=require($config);
  941         if(isset($config['basePath']))
  942         {
  943             $this->setBasePath($config['basePath']);
  944             unset($config['basePath']);
  945         }
  946         Yii::setPathOfAlias($id,$this->getBasePath());
  947         $this->preinit();
  948         $this->configure($config);
  949         $this->attachBehaviors($this->behaviors);
  950         $this->preloadComponents();
  951         $this->init();
  952     }
  953     public function __get($name)
  954     {
  955         if($this->hasComponent($name))
  956             return $this->getComponent($name);
  957         else
  958             return parent::__get($name);
  959     }
  960     public function __isset($name)
  961     {
  962         if($this->hasComponent($name))
  963             return $this->getComponent($name)!==null;
  964         else
  965             return parent::__isset($name);
  966     }
  967     public function getId()
  968     {
  969         return $this->_id;
  970     }
  971     public function setId($id)
  972     {
  973         $this->_id=$id;
  974     }
  975     public function getBasePath()
  976     {
  977         if($this->_basePath===null)
  978         {
  979             $class=new ReflectionClass(get_class($this));
  980             $this->_basePath=dirname($class->getFileName());
  981         }
  982         return $this->_basePath;
  983     }
  984     public function setBasePath($path)
  985     {
  986         if(($this->_basePath=realpath($path))===false || !is_dir($this->_basePath))
  987             throw new CException(Yii::t('yii','Base path "{path}" is not a valid directory.',
  988                 array('{path}'=>$path)));
  989     }
  990     public function getParams()
  991     {
  992         if($this->_params!==null)
  993             return $this->_params;
  994         else
  995         {
  996             $this->_params=new CAttributeCollection;
  997             $this->_params->caseSensitive=true;
  998             return $this->_params;
  999         }
 1000     }
 1001     public function setParams($value)
 1002     {
 1003         $params=$this->getParams();
 1004         foreach($value as $k=>$v)
 1005             $params->add($k,$v);
 1006     }
 1007     public function getModulePath()
 1008     {
 1009         if($this->_modulePath!==null)
 1010             return $this->_modulePath;
 1011         else
 1012             return $this->_modulePath=$this->getBasePath().DIRECTORY_SEPARATOR.'modules';
 1013     }
 1014     public function setModulePath($value)
 1015     {
 1016         if(($this->_modulePath=realpath($value))===false || !is_dir($this->_modulePath))
 1017             throw new CException(Yii::t('yii','The module path "{path}" is not a valid directory.',
 1018                 array('{path}'=>$value)));
 1019     }
 1020     public function setImport($aliases)
 1021     {
 1022         foreach($aliases as $alias)
 1023             Yii::import($alias);
 1024     }
 1025     public function setAliases($mappings)
 1026     {
 1027         foreach($mappings as $name=>$alias)
 1028         {
 1029             if(($path=Yii::getPathOfAlias($alias))!==false)
 1030                 Yii::setPathOfAlias($name,$path);
 1031             else
 1032                 Yii::setPathOfAlias($name,$alias);
 1033         }
 1034     }
 1035     public function getParentModule()
 1036     {
 1037         return $this->_parentModule;
 1038     }
 1039     public function getModule($id)
 1040     {
 1041         if(isset($this->_modules[$id]) || array_key_exists($id,$this->_modules))
 1042             return $this->_modules[$id];
 1043         elseif(isset($this->_moduleConfig[$id]))
 1044         {
 1045             $config=$this->_moduleConfig[$id];
 1046             if(!isset($config['enabled']) || $config['enabled'])
 1047             {
 1048                 $class=$config['class'];
 1049                 unset($config['class'], $config['enabled']);
 1050                 if($this===Yii::app())
 1051                     $module=Yii::createComponent($class,$id,null,$config);
 1052                 else
 1053                     $module=Yii::createComponent($class,$this->getId().'/'.$id,$this,$config);
 1054                 return $this->_modules[$id]=$module;
 1055             }
 1056         }
 1057     }
 1058     public function hasModule($id)
 1059     {
 1060         return isset($this->_moduleConfig[$id]) || isset($this->_modules[$id]);
 1061     }
 1062     public function getModules()
 1063     {
 1064         return $this->_moduleConfig;
 1065     }
 1066     public function setModules($modules,$merge=true)
 1067     {
 1068         foreach($modules as $id=>$module)
 1069         {
 1070             if(is_int($id))
 1071             {
 1072                 $id=$module;
 1073                 $module=array();
 1074             }
 1075             if(isset($this->_moduleConfig[$id]) && $merge)
 1076                 $this->_moduleConfig[$id]=CMap::mergeArray($this->_moduleConfig[$id],$module);
 1077             else
 1078             {
 1079                 if(!isset($module['class']))
 1080                 {
 1081                     if (Yii::getPathOfAlias($id)===false)
 1082                         Yii::setPathOfAlias($id,$this->getModulePath().DIRECTORY_SEPARATOR.$id);
 1083                     $module['class']=$id.'.'.ucfirst($id).'Module';
 1084                 }
 1085                 $this->_moduleConfig[$id]=$module;
 1086             }
 1087         }
 1088     }
 1089     public function hasComponent($id)
 1090     {
 1091         return isset($this->_components[$id]) || isset($this->_componentConfig[$id]);
 1092     }
 1093     public function getComponent($id,$createIfNull=true)
 1094     {
 1095         if(isset($this->_components[$id]))
 1096             return $this->_components[$id];
 1097         elseif(isset($this->_componentConfig[$id]) && $createIfNull)
 1098         {
 1099             $config=$this->_componentConfig[$id];
 1100             if(!isset($config['enabled']) || $config['enabled'])
 1101             {
 1102                 unset($config['enabled']);
 1103                 $component=Yii::createComponent($config);
 1104                 $component->init();
 1105                 return $this->_components[$id]=$component;
 1106             }
 1107         }
 1108     }
 1109     public function setComponent($id,$component,$merge=true)
 1110     {
 1111         if($component===null)
 1112         {
 1113             unset($this->_components[$id]);
 1114             return;
 1115         }
 1116         elseif($component instanceof IApplicationComponent)
 1117         {
 1118             $this->_components[$id]=$component;
 1119             if(!$component->getIsInitialized())
 1120                 $component->init();
 1121             return;
 1122         }
 1123         elseif(isset($this->_components[$id]))
 1124         {
 1125             if(isset($component['class']) && get_class($this->_components[$id])!==$component['class'])
 1126             {
 1127                 unset($this->_components[$id]);
 1128                 $this->_componentConfig[$id]=$component; //we should ignore merge here
 1129                 return;
 1130             }
 1131             foreach($component as $key=>$value)
 1132             {
 1133                 if($key!=='class')
 1134                     $this->_components[$id]->$key=$value;
 1135             }
 1136         }
 1137         elseif(isset($this->_componentConfig[$id]['class'],$component['class'])
 1138             && $this->_componentConfig[$id]['class']!==$component['class'])
 1139         {
 1140             $this->_componentConfig[$id]=$component; //we should ignore merge here
 1141             return;
 1142         }
 1143         if(isset($this->_componentConfig[$id]) && $merge)
 1144             $this->_componentConfig[$id]=CMap::mergeArray($this->_componentConfig[$id],$component);
 1145         else
 1146             $this->_componentConfig[$id]=$component;
 1147     }
 1148     public function getComponents($loadedOnly=true)
 1149     {
 1150         if($loadedOnly)
 1151             return $this->_components;
 1152         else
 1153             return array_merge($this->_componentConfig, $this->_components);
 1154     }
 1155     public function setComponents($components,$merge=true)
 1156     {
 1157         foreach($components as $id=>$component)
 1158             $this->setComponent($id,$component,$merge);
 1159     }
 1160     public function configure($config)
 1161     {
 1162         if(is_array($config))
 1163         {
 1164             foreach($config as $key=>$value)
 1165                 $this->$key=$value;
 1166         }
 1167     }
 1168     protected function preloadComponents()
 1169     {
 1170         foreach($this->preload as $id)
 1171             $this->getComponent($id);
 1172     }
 1173     protected function preinit()
 1174     {
 1175     }
 1176     protected function init()
 1177     {
 1178     }
 1179 }
 1180 abstract class CApplication extends CModule
 1181 {
 1182     public $name='My Application';
 1183     public $charset='UTF-8';
 1184     public $sourceLanguage='en_us';
 1185     public $localeClass='CLocale';
 1186     private $_id;
 1187     private $_basePath;
 1188     private $_runtimePath;
 1189     private $_extensionPath;
 1190     private $_globalState;
 1191     private $_stateChanged;
 1192     private $_ended=false;
 1193     private $_language;
 1194     private $_homeUrl;
 1195     abstract public function processRequest();
 1196     public function __construct($config=null)
 1197     {
 1198         Yii::setApplication($this);
 1199         // set basePath as early as possible to avoid trouble
 1200         if(is_string($config))
 1201             $config=require($config);
 1202         if(isset($config['basePath']))
 1203         {
 1204             $this->setBasePath($config['basePath']);
 1205             unset($config['basePath']);
 1206         }
 1207         else
 1208             $this->setBasePath('protected');
 1209         Yii::setPathOfAlias('application',$this->getBasePath());
 1210         Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME']));
 1211         if(isset($config['extensionPath']))
 1212         {
 1213             $this->setExtensionPath($config['extensionPath']);
 1214             unset($config['extensionPath']);
 1215         }
 1216         else
 1217             Yii::setPathOfAlias('ext',$this->getBasePath().DIRECTORY_SEPARATOR.'extensions');
 1218         if(isset($config['aliases']))
 1219         {
 1220             $this->setAliases($config['aliases']);
 1221             unset($config['aliases']);
 1222         }
 1223         $this->preinit();
 1224         $this->initSystemHandlers();
 1225         $this->registerCoreComponents();
 1226         $this->configure($config);
 1227         $this->attachBehaviors($this->behaviors);
 1228         $this->preloadComponents();
 1229         $this->init();
 1230     }
 1231     public function run()
 1232     {
 1233         if($this->hasEventHandler('onBeginRequest'))
 1234             $this->onBeginRequest(new CEvent($this));
 1235         register_shutdown_function(array($this,'end'),0,false);
 1236         $this->processRequest();
 1237         if($this->hasEventHandler('onEndRequest'))
 1238             $this->onEndRequest(new CEvent($this));
 1239     }
 1240     public function end($status=0,$exit=true)
 1241     {
 1242         if($this->hasEventHandler('onEndRequest'))
 1243             $this->onEndRequest(new CEvent($this));
 1244         if($exit)
 1245             exit($status);
 1246     }
 1247     public function onBeginRequest($event)
 1248     {
 1249         $this->raiseEvent('onBeginRequest',$event);
 1250     }
 1251     public function onEndRequest($event)
 1252     {
 1253         if(!$this->_ended)
 1254         {
 1255             $this->_ended=true;
 1256             $this->raiseEvent('onEndRequest',$event);
 1257         }
 1258     }
 1259     public function getId()
 1260     {
 1261         if($this->_id!==null)
 1262             return $this->_id;
 1263         else
 1264             return $this->_id=sprintf('%x',crc32($this->getBasePath().$this->name));
 1265     }
 1266     public function setId($id)
 1267     {
 1268         $this->_id=$id;
 1269     }
 1270     public function getBasePath()
 1271     {
 1272         return $this->_basePath;
 1273     }
 1274     public function setBasePath($path)
 1275     {
 1276         if(($this->_basePath=realpath($path))===false || !is_dir($this->_basePath))
 1277             throw new CException(Yii::t('yii','Application base path "{path}" is not a valid directory.',
 1278                 array('{path}'=>$path)));
 1279     }
 1280     public function getRuntimePath()
 1281     {
 1282         if($this->_runtimePath!==null)
 1283             return $this->_runtimePath;
 1284         else
 1285         {
 1286             $this->setRuntimePath($this->getBasePath().DIRECTORY_SEPARATOR.'runtime');
 1287             return $this->_runtimePath;
 1288         }
 1289     }
 1290     public function setRuntimePath($path)
 1291     {
 1292         if(($runtimePath=realpath($path))===false || !is_dir($runtimePath) || !is_writable($runtimePath))
 1293             throw new CException(Yii::t('yii','Application runtime path "{path}" is not valid. Please make sure it is a directory writable by the Web server process.',
 1294                 array('{path}'=>$path)));
 1295         $this->_runtimePath=$runtimePath;
 1296     }
 1297     public function getExtensionPath()
 1298     {
 1299         return Yii::getPathOfAlias('ext');
 1300     }
 1301     public function setExtensionPath($path)
 1302     {
 1303         if(($extensionPath=realpath($path))===false || !is_dir($extensionPath))
 1304             throw new CException(Yii::t('yii','Extension path "{path}" does not exist.',
 1305                 array('{path}'=>$path)));
 1306         Yii::setPathOfAlias('ext',$extensionPath);
 1307     }
 1308     public function getLanguage()
 1309     {
 1310         return $this->_language===null ? $this->sourceLanguage : $this->_language;
 1311     }
 1312     public function setLanguage($language)
 1313     {
 1314         $this->_language=$language;
 1315     }
 1316     public function getTimeZone()
 1317     {
 1318         return date_default_timezone_get();
 1319     }
 1320     public function setTimeZone($value)
 1321     {
 1322         date_default_timezone_set($value);
 1323     }
 1324     public function findLocalizedFile($srcFile,$srcLanguage=null,$language=null)
 1325     {
 1326         if($srcLanguage===null)
 1327             $srcLanguage=$this->sourceLanguage;
 1328         if($language===null)
 1329             $language=$this->getLanguage();
 1330         if($language===$srcLanguage)
 1331             return $srcFile;
 1332         $desiredFile=dirname($srcFile).DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.basename($srcFile);
 1333         return is_file($desiredFile) ? $desiredFile : $srcFile;
 1334     }
 1335     public function getLocale($localeID=null)
 1336     {
 1337         return call_user_func_array(array($this->localeClass, 'getInstance'),array($localeID===null?$this->getLanguage():$localeID));
 1338     }
 1339     public function getLocaleDataPath()
 1340     {
 1341         $vars=get_class_vars($this->localeClass);
 1342         if(empty($vars['dataPath']))
 1343             return Yii::getPathOfAlias('system.i18n.data');
 1344         return $vars['dataPath'];
 1345     }
 1346     public function setLocaleDataPath($value)
 1347     {
 1348         $property=new ReflectionProperty($this->localeClass,'dataPath');
 1349         $property->setValue($value);
 1350     }
 1351     public function getNumberFormatter()
 1352     {
 1353         return $this->getLocale()->getNumberFormatter();
 1354     }
 1355     public function getDateFormatter()
 1356     {
 1357         return $this->getLocale()->getDateFormatter();
 1358     }
 1359     public function getDb()
 1360     {
 1361         return $this->getComponent('db');
 1362     }
 1363     public function getErrorHandler()
 1364     {
 1365         return $this->getComponent('errorHandler');
 1366     }
 1367     public function getSecurityManager()
 1368     {
 1369         return $this->getComponent('securityManager');
 1370     }
 1371     public function getStatePersister()
 1372     {
 1373         return $this->getComponent('statePersister');
 1374     }
 1375     public function getCache()
 1376     {
 1377         return $this->getComponent('cache');
 1378     }
 1379     public function getCoreMessages()
 1380     {
 1381         return $this->getComponent('coreMessages');
 1382     }
 1383     public function getMessages()
 1384     {
 1385         return $this->getComponent('messages');
 1386     }
 1387     public function getRequest()
 1388     {
 1389         return $this->getComponent('request');
 1390     }
 1391     public function getUrlManager()
 1392     {
 1393         return $this->getComponent('urlManager');
 1394     }
 1395     public function getFormat()
 1396     {
 1397         return $this->getComponent('format');
 1398     }
 1399     public function getController()
 1400     {
 1401         return null;
 1402     }
 1403     public function createUrl($route,$params=array(),$ampersand='&')
 1404     {
 1405         return $this->getUrlManager()->createUrl($route,$params,$ampersand);
 1406     }
 1407     public function createAbsoluteUrl($route,$params=array(),$schema='',$ampersand='&')
 1408     {
 1409         $url=$this->createUrl($route,$params,$ampersand);
 1410         if(strpos($url,'http')===0 || strpos($url,'//')===0)
 1411             return $url;
 1412         else
 1413             return $this->getRequest()->getHostInfo($schema).$url;
 1414     }
 1415     public function getBaseUrl($absolute=false)
 1416     {
 1417         return $this->getRequest()->getBaseUrl($absolute);
 1418     }
 1419     public function getHomeUrl()
 1420     {
 1421         if($this->_homeUrl===null)
 1422         {
 1423             if($this->getUrlManager()->showScriptName)
 1424                 return $this->getRequest()->getScriptUrl();
 1425             else
 1426                 return $this->getRequest()->getBaseUrl().'/';
 1427         }
 1428         else
 1429             return $this->_homeUrl;
 1430     }
 1431     public function setHomeUrl($value)
 1432     {
 1433         $this->_homeUrl=$value;
 1434     }
 1435     public function getGlobalState($key,$defaultValue=null)
 1436     {
 1437         if($this->_globalState===null)
 1438             $this->loadGlobalState();
 1439         if(isset($this->_globalState[$key]))
 1440             return $this->_globalState[$key];
 1441         else
 1442             return $defaultValue;
 1443     }
 1444     public function setGlobalState($key,$value,$defaultValue=null)
 1445     {
 1446         if($this->_globalState===null)
 1447             $this->loadGlobalState();
 1448         $changed=$this->_stateChanged;
 1449         if($value===$defaultValue)
 1450         {
 1451             if(isset($this->_globalState[$key]))
 1452             {
 1453                 unset($this->_globalState[$key]);
 1454                 $this->_stateChanged=true;
 1455             }
 1456         }
 1457         elseif(!isset($this->_globalState[$key]) || $this->_globalState[$key]!==$value)
 1458         {
 1459             $this->_globalState[$key]=$value;
 1460             $this->_stateChanged=true;
 1461         }
 1462         if($this->_stateChanged!==$changed)
 1463             $this->attachEventHandler('onEndRequest',array($this,'saveGlobalState'));
 1464     }
 1465     public function clearGlobalState($key)
 1466     {
 1467         $this->setGlobalState($key,true,true);
 1468     }
 1469     public function loadGlobalState()
 1470     {
 1471         $persister=$this->getStatePersister();
 1472         if(($this->_globalState=$persister->load())===null)
 1473             $this->_globalState=array();
 1474         $this->_stateChanged=false;
 1475         $this->detachEventHandler('onEndRequest',array($this,'saveGlobalState'));
 1476     }
 1477     public function saveGlobalState()
 1478     {
 1479         if($this->_stateChanged)
 1480         {
 1481             $this->_stateChanged=false;
 1482             $this->detachEventHandler('onEndRequest',array($this,'saveGlobalState'));
 1483             $this->getStatePersister()->save($this->_globalState);
 1484         }
 1485     }
 1486     public function handleException($exception)
 1487     {
 1488         // disable error capturing to avoid recursive errors
 1489         restore_error_handler();
 1490         restore_exception_handler();
 1491         $category='exception.'.get_class($exception);
 1492         if($exception instanceof CHttpException)
 1493             $category.='.'.$exception->statusCode;
 1494         // php <5.2 doesn't support string conversion auto-magically
 1495         $message=$exception->__toString();
 1496         if(isset($_SERVER['REQUEST_URI']))
 1497             $message.="\nREQUEST_URI=".$_SERVER['REQUEST_URI'];
 1498         if(isset($_SERVER['HTTP_REFERER']))
 1499             $message.="\nHTTP_REFERER=".$_SERVER['HTTP_REFERER'];
 1500         $message.="\n---";
 1501         Yii::log($message,CLogger::LEVEL_ERROR,$category);
 1502         try
 1503         {
 1504             $event=new CExceptionEvent($this,$exception);
 1505             $this->onException($event);
 1506             if(!$event->handled)
 1507             {
 1508                 // try an error handler
 1509                 if(($handler=$this->getErrorHandler())!==null)
 1510                     $handler->handle($event);
 1511                 else
 1512                     $this->displayException($exception);
 1513             }
 1514         }
 1515         catch(Exception $e)
 1516         {
 1517             $this->displayException($e);
 1518         }
 1519         try
 1520         {
 1521             $this->end(1);
 1522         }
 1523         catch(Exception $e)
 1524         {
 1525             // use the most primitive way to log error
 1526             $msg = get_class($e).': '.$e->getMessage().' ('.$e->getFile().':'.$e->getLine().")\n";
 1527             $msg .= $e->getTraceAsString()."\n";
 1528             $msg .= "Previous exception:\n";
 1529             $msg .= get_class($exception).': '.$exception->getMessage().' ('.$exception->getFile().':'.$exception->getLine().")\n";
 1530             $msg .= $exception->getTraceAsString()."\n";
 1531             $msg .= '$_SERVER='.var_export($_SERVER,true);
 1532             error_log($msg);
 1533             exit(1);
 1534         }
 1535     }
 1536     public function handleError($code,$message,$file,$line)
 1537     {
 1538         if($code & error_reporting())
 1539         {
 1540             // disable error capturing to avoid recursive errors
 1541             restore_error_handler();
 1542             restore_exception_handler();
 1543             $log="$message ($file:$line)\nStack trace:\n";
 1544             $trace=debug_backtrace();
 1545             // skip the first 3 stacks as they do not tell the error position
 1546             if(count($trace)>3)
 1547                 $trace=array_slice($trace,3);
 1548             foreach($trace as $i=>$t)
 1549             {
 1550                 if(!isset($t['file']))
 1551                     $t['file']='unknown';
 1552                 if(!isset($t['line']))
 1553                     $t['line']=0;
 1554                 if(!isset($t['function']))
 1555                     $t['function']='unknown';
 1556                 $log.="#$i {$t['file']}({$t['line']}): ";
 1557                 if(isset($t['object']) && is_object($t['object']))
 1558                     $log.=get_class($t['object']).'->';
 1559                 $log.="{$t['function']}()\n";
 1560             }
 1561             if(isset($_SERVER['REQUEST_URI']))
 1562                 $log.='REQUEST_URI='.$_SERVER['REQUEST_URI'];
 1563             Yii::log($log,CLogger::LEVEL_ERROR,'php');
 1564             try
 1565             {
 1566                 Yii::import('CErrorEvent',true);
 1567                 $event=new CErrorEvent($this,$code,$message,$file,$line);
 1568                 $this->onError($event);
 1569                 if(!$event->handled)
 1570                 {
 1571                     // try an error handler
 1572                     if(($handler=$this->getErrorHandler())!==null)
 1573                         $handler->handle($event);
 1574                     else
 1575                         $this->displayError($code,$message,$file,$line);
 1576                 }
 1577             }
 1578             catch(Exception $e)
 1579             {
 1580                 $this->displayException($e);
 1581             }
 1582             try
 1583             {
 1584                 $this->end(1);
 1585             }
 1586             catch(Exception $e)
 1587             {
 1588                 // use the most primitive way to log error
 1589                 $msg = get_class($e).': '.$e->getMessage().' ('.$e->getFile().':'.$e->getLine().")\n";
 1590                 $msg .= $e->getTraceAsString()."\n";
 1591                 $msg .= "Previous error:\n";
 1592                 $msg .= $log."\n";
 1593                 $msg .= '$_SERVER='.var_export($_SERVER,true);
 1594                 error_log($msg);
 1595                 exit(1);
 1596             }
 1597         }
 1598     }
 1599     public function onException($event)
 1600     {
 1601         $this->raiseEvent('onException',$event);
 1602     }
 1603     public function onError($event)
 1604     {
 1605         $this->raiseEvent('onError',$event);
 1606     }
 1607     public function displayError($code,$message,$file,$line)
 1608     {
 1609         if(YII_DEBUG)
 1610         {
 1611             echo "<h1>PHP Error [$code]</h1>\n";
 1612             echo "<p>$message ($file:$line)</p>\n";
 1613             echo '<pre>';
 1614             $trace=debug_backtrace();
 1615             // skip the first 3 stacks as they do not tell the error position
 1616             if(count($trace)>3)
 1617                 $trace=array_slice($trace,3);
 1618             foreach($trace as $i=>$t)
 1619             {
 1620                 if(!isset($t['file']))
 1621                     $t['file']='unknown';
 1622                 if(!isset($t['line']))
 1623                     $t['line']=0;
 1624                 if(!isset($t['function']))
 1625                     $t['function']='unknown';
 1626                 echo "#$i {$t['file']}({$t['line']}): ";
 1627                 if(isset($t['object']) && is_object($t['object']))
 1628                     echo get_class($t['object']).'->';
 1629                 echo "{$t['function']}()\n";
 1630             }
 1631             echo '</pre>';
 1632         }
 1633         else
 1634         {
 1635             echo "<h1>PHP Error [$code]</h1>\n";
 1636             echo "<p>$message</p>\n";
 1637         }
 1638     }
 1639     public function displayException($exception)
 1640     {
 1641         if(YII_DEBUG)
 1642         {
 1643             echo '<h1>'.get_class($exception)."</h1>\n";
 1644             echo '<p>'.$exception->getMessage().' ('.$exception->getFile().':'.$exception->getLine().')</p>';
 1645             echo '<pre>'.$exception->getTraceAsString().'</pre>';
 1646         }
 1647         else
 1648         {
 1649             echo '<h1>'.get_class($exception)."</h1>\n";
 1650             echo '<p>'.$exception->getMessage().'</p>';
 1651         }
 1652     }
 1653     protected function initSystemHandlers()
 1654     {
 1655         if(YII_ENABLE_EXCEPTION_HANDLER)
 1656             set_exception_handler(array($this,'handleException'));
 1657         if(YII_ENABLE_ERROR_HANDLER)
 1658             set_error_handler(array($this,'handleError'),error_reporting());
 1659     }
 1660     protected function registerCoreComponents()
 1661     {
 1662         $components=array(
 1663             'coreMessages'=>array(
 1664                 'class'=>'CPhpMessageSource',
 1665                 'language'=>'en_us',
 1666                 'basePath'=>YII_PATH.DIRECTORY_SEPARATOR.'messages',
 1667             ),
 1668             'db'=>array(
 1669                 'class'=>'CDbConnection',
 1670             ),
 1671             'messages'=>array(
 1672                 'class'=>'CPhpMessageSource',
 1673             ),
 1674             'errorHandler'=>array(
 1675                 'class'=>'CErrorHandler',
 1676             ),
 1677             'securityManager'=>array(
 1678                 'class'=>'CSecurityManager',
 1679             ),
 1680             'statePersister'=>array(
 1681                 'class'=>'CStatePersister',
 1682             ),
 1683             'urlManager'=>array(
 1684                 'class'=>'CUrlManager',
 1685             ),
 1686             'request'=>array(
 1687                 'class'=>'CHttpRequest',
 1688             ),
 1689             'format'=>array(
 1690                 'class'=>'CFormatter',
 1691             ),
 1692         );
 1693         $this->setComponents($components);
 1694     }
 1695 }
 1696 class CWebApplication extends CApplication
 1697 {
 1698     public $defaultController='site';
 1699     public $layout='main';
 1700     public $controllerMap=array();
 1701     public $catchAllRequest;
 1702     public $controllerNamespace;
 1703     private $_controllerPath;
 1704     private $_viewPath;
 1705     private $_systemViewPath;
 1706     private $_layoutPath;
 1707     private $_controller;
 1708     private $_theme;
 1709     public function processRequest()
 1710     {
 1711         if(is_array($this->catchAllRequest) && isset($this->catchAllRequest[0]))
 1712         {
 1713             $route=$this->catchAllRequest[0];
 1714             foreach(array_splice($this->catchAllRequest,1) as $name=>$value)
 1715                 $_GET[$name]=$value;
 1716         }
 1717         else
 1718             $route=$this->getUrlManager()->parseUrl($this->getRequest());
 1719         $this->runController($route);
 1720     }
 1721     protected function registerCoreComponents()
 1722     {
 1723         parent::registerCoreComponents();
 1724         $components=array(
 1725             'session'=>array(
 1726                 'class'=>'CHttpSession',
 1727             ),
 1728             'assetManager'=>array(
 1729                 'class'=>'CAssetManager',
 1730             ),
 1731             'user'=>array(
 1732                 'class'=>'CWebUser',
 1733             ),
 1734             'themeManager'=>array(
 1735                 'class'=>'CThemeManager',
 1736             ),
 1737             'authManager'=>array(
 1738                 'class'=>'CPhpAuthManager',
 1739             ),
 1740             'clientScript'=>array(
 1741                 'class'=>'CClientScript',
 1742             ),
 1743             'widgetFactory'=>array(
 1744                 'class'=>'CWidgetFactory',
 1745             ),
 1746         );
 1747         $this->setComponents($components);
 1748     }
 1749     public function getAuthManager()
 1750     {
 1751         return $this->getComponent('authManager');
 1752     }
 1753     public function getAssetManager()
 1754     {
 1755         return $this->getComponent('assetManager');
 1756     }
 1757     public function getSession()
 1758     {
 1759         return $this->getComponent('session');
 1760     }
 1761     public function getUser()
 1762     {
 1763         return $this->getComponent('user');
 1764     }
 1765     public function getViewRenderer()
 1766     {
 1767         return $this->getComponent('viewRenderer');
 1768     }
 1769     public function getClientScript()
 1770     {
 1771         return $this->getComponent('clientScript');
 1772     }
 1773     public function getWidgetFactory()
 1774     {
 1775         return $this->getComponent('widgetFactory');
 1776     }
 1777     public function getThemeManager()
 1778     {
 1779         return $this->getComponent('themeManager');
 1780     }
 1781     public function getTheme()
 1782     {
 1783         if(is_string($this->_theme))
 1784             $this->_theme=$this->getThemeManager()->getTheme($this->_theme);
 1785         return $this->_theme;
 1786     }
 1787     public function setTheme($value)
 1788     {
 1789         $this->_theme=$value;
 1790     }
 1791     public function runController($route)
 1792     {
 1793         if(($ca=$this->createController($route))!==null)
 1794         {
 1795             list($controller,$actionID)=$ca;
 1796             $oldController=$this->_controller;
 1797             $this->_controller=$controller;
 1798             $controller->init();
 1799             $controller->run($actionID);
 1800             $this->_controller=$oldController;
 1801         }
 1802         else
 1803             throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
 1804                 array('{route}'=>$route===''?$this->defaultController:$route)));
 1805     }
 1806     public function createController($route,$owner=null)
 1807     {
 1808         if($owner===null)
 1809             $owner=$this;
 1810         if((array)$route===$route || ($route=trim($route,'/'))==='')
 1811             $route=$owner->defaultController;
 1812         $caseSensitive=$this->getUrlManager()->caseSensitive;
 1813         $route.='/';
 1814         while(($pos=strpos($route,'/'))!==false)
 1815         {
 1816             $id=substr($route,0,$pos);
 1817             if(!preg_match('/^\w+$/',$id))
 1818                 return null;
 1819             if(!$caseSensitive)
 1820                 $id=strtolower($id);
 1821             $route=(string)substr($route,$pos+1);
 1822             if(!isset($basePath))  // first segment
 1823             {
 1824                 if(isset($owner->controllerMap[$id]))
 1825                 {
 1826                     return array(
 1827                         Yii::createComponent($owner->controllerMap[$id],$id,$owner===$this?null:$owner),
 1828                         $this->parseActionParams($route),
 1829                     );
 1830                 }
 1831                 if(($module=$owner->getModule($id))!==null)
 1832                     return $this->createController($route,$module);
 1833                 $basePath=$owner->getControllerPath();
 1834                 $controllerID='';
 1835             }
 1836             else
 1837                 $controllerID.='/';
 1838             $className=ucfirst($id).'Controller';
 1839             $classFile=$basePath.DIRECTORY_SEPARATOR.$className.'.php';
 1840             if($owner->controllerNamespace!==null)
 1841                 $className=$owner->controllerNamespace.'\\'.str_replace('/','\\',$controllerID).$className;
 1842             if(is_file($classFile))
 1843             {
 1844                 if(!class_exists($className,false))
 1845                     require($classFile);
 1846                 if(class_exists($className,false) && is_subclass_of($className,'CController'))
 1847                 {
 1848                     $id[0]=strtolower($id[0]);
 1849                     return array(
 1850                         new $className($controllerID.$id,$owner===$this?null:$owner),
 1851                         $this->parseActionParams($route),
 1852                     );
 1853                 }
 1854                 return null;
 1855             }
 1856             $controllerID.=$id;
 1857             $basePath.=DIRECTORY_SEPARATOR.$id;
 1858         }
 1859     }
 1860     protected function parseActionParams($pathInfo)
 1861     {
 1862         if(($pos=strpos($pathInfo,'/'))!==false)
 1863         {
 1864             $manager=$this->getUrlManager();
 1865             $manager->parsePathInfo((string)substr($pathInfo,$pos+1));
 1866             $actionID=substr($pathInfo,0,$pos);
 1867             return $manager->caseSensitive ? $actionID : strtolower($actionID);
 1868         }
 1869         else
 1870             return $pathInfo;
 1871     }
 1872     public function getController()
 1873     {
 1874         return $this->_controller;
 1875     }
 1876     public function setController($value)
 1877     {
 1878         $this->_controller=$value;
 1879     }
 1880     public function getControllerPath()
 1881     {
 1882         if($this->_controllerPath!==null)
 1883             return $this->_controllerPath;
 1884         else
 1885             return $this->_controllerPath=$this->getBasePath().DIRECTORY_SEPARATOR.'controllers';
 1886     }
 1887     public function setControllerPath($value)
 1888     {
 1889         if(($this->_controllerPath=realpath($value))===false || !is_dir($this->_controllerPath))
 1890             throw new CException(Yii::t('yii','The controller path "{path}" is not a valid directory.',
 1891                 array('{path}'=>$value)));
 1892     }
 1893     public function getViewPath()
 1894     {
 1895         if($this->_viewPath!==null)
 1896             return $this->_viewPath;
 1897         else
 1898             return $this->_viewPath=$this->getBasePath().DIRECTORY_SEPARATOR.'views';
 1899     }
 1900     public function setViewPath($path)
 1901     {
 1902         if(($this->_viewPath=realpath($path))===false || !is_dir($this->_viewPath))
 1903             throw new CException(Yii::t('yii','The view path "{path}" is not a valid directory.',
 1904                 array('{path}'=>$path)));
 1905     }
 1906     public function getSystemViewPath()
 1907     {
 1908         if($this->_systemViewPath!==null)
 1909             return $this->_systemViewPath;
 1910         else
 1911             return $this->_systemViewPath=$this->getViewPath().DIRECTORY_SEPARATOR.'system';
 1912     }
 1913     public function setSystemViewPath($path)
 1914     {
 1915         if(($this->_systemViewPath=realpath($path))===false || !is_dir($this->_systemViewPath))
 1916             throw new CException(Yii::t('yii','The system view path "{path}" is not a valid directory.',
 1917                 array('{path}'=>$path)));
 1918     }
 1919     public function getLayoutPath()
 1920     {
 1921         if($this->_layoutPath!==null)
 1922             return $this->_layoutPath;
 1923         else
 1924             return $this->_layoutPath=$this->getViewPath().DIRECTORY_SEPARATOR.'layouts';
 1925     }
 1926     public function setLayoutPath($path)
 1927     {
 1928         if(($this->_layoutPath=realpath($path))===false || !is_dir($this->_layoutPath))
 1929             throw new CException(Yii::t('yii','The layout path "{path}" is not a valid directory.',
 1930                 array('{path}'=>$path)));
 1931     }
 1932     public function beforeControllerAction($controller,$action)
 1933     {
 1934         return true;
 1935     }
 1936     public function afterControllerAction($controller,$action)
 1937     {
 1938     }
 1939     public function findModule($id)
 1940     {
 1941         if(($controller=$this->getController())!==null && ($module=$controller->getModule())!==null)
 1942         {
 1943             do
 1944             {
 1945                 if(($m=$module->getModule($id))!==null)
 1946                     return $m;
 1947             } while(($module=$module->getParentModule())!==null);
 1948         }
 1949         if(($m=$this->getModule($id))!==null)
 1950             return $m;
 1951     }
 1952     protected function init()
 1953     {
 1954         parent::init();
 1955         // preload 'request' so that it has chance to respond to onBeginRequest event.
 1956         $this->getRequest();
 1957     }
 1958 }
 1959 class CMap extends CComponent implements IteratorAggregate,ArrayAccess,Countable
 1960 {
 1961     private $_d=array();
 1962     private $_r=false;
 1963     public function __construct($data=null,$readOnly=false)
 1964     {
 1965         if($data!==null)
 1966             $this->copyFrom($data);
 1967         $this->setReadOnly($readOnly);
 1968     }
 1969     public function getReadOnly()
 1970     {
 1971         return $this->_r;
 1972     }
 1973     protected function setReadOnly($value)
 1974     {
 1975         $this->_r=$value;
 1976     }
 1977     public function getIterator()
 1978     {
 1979         return new CMapIterator($this->_d);
 1980     }
 1981     public function count()
 1982     {
 1983         return $this->getCount();
 1984     }
 1985     public function getCount()
 1986     {
 1987         return count($this->_d);
 1988     }
 1989     public function getKeys()
 1990     {
 1991         return array_keys($this->_d);
 1992     }
 1993     public function itemAt($key)
 1994     {
 1995         if(isset($this->_d[$key]))
 1996             return $this->_d[$key];
 1997         else
 1998             return null;
 1999     }
 2000     public function add($key,$value)
 2001     {
 2002         if(!$this->_r)
 2003         {
 2004             if($key===null)
 2005                 $this->_d[]=$value;
 2006             else
 2007                 $this->_d[$key]=$value;
 2008         }
 2009         else
 2010             throw new CException(Yii::t('yii','The map is read only.'));
 2011     }
 2012     public function remove($key)
 2013     {
 2014         if(!$this->_r)
 2015         {
 2016             if(isset($this->_d[$key]))
 2017             {
 2018                 $value=$this->_d[$key];
 2019                 unset($this->_d[$key]);
 2020                 return $value;
 2021             }
 2022             else
 2023             {
 2024                 // it is possible the value is null, which is not detected by isset
 2025                 unset($this->_d[$key]);
 2026                 return null;
 2027             }
 2028         }
 2029         else
 2030             throw new CException(Yii::t('yii','The map is read only.'));
 2031     }
 2032     public function clear()
 2033     {
 2034         foreach(array_keys($this->_d) as $key)
 2035             $this->remove($key);
 2036     }
 2037     public function contains($key)
 2038     {
 2039         return isset($this->_d[$key]) || array_key_exists($key,$this->_d);
 2040     }
 2041     public function toArray()
 2042     {
 2043         return $this->_d;
 2044     }
 2045     public function copyFrom($data)
 2046     {
 2047         if(is_array($data) || $data instanceof Traversable)
 2048         {
 2049             if($this->getCount()>0)
 2050                 $this->clear();
 2051             if($data instanceof CMap)
 2052                 $data=$data->_d;
 2053             foreach($data as $key=>$value)
 2054                 $this->add($key,$value);
 2055         }
 2056         elseif($data!==null)
 2057             throw new CException(Yii::t('yii','Map data must be an array or an object implementing Traversable.'));
 2058     }
 2059     public function mergeWith($data,$recursive=true)
 2060     {
 2061         if(is_array($data) || $data instanceof Traversable)
 2062         {
 2063             if($data instanceof CMap)
 2064                 $data=$data->_d;
 2065             if($recursive)
 2066             {
 2067                 if($data instanceof Traversable)
 2068                 {
 2069                     $d=array();
 2070                     foreach($data as $key=>$value)
 2071                         $d[$key]=$value;
 2072                     $this->_d=self::mergeArray($this->_d,$d);
 2073                 }
 2074                 else
 2075                     $this->_d=self::mergeArray($this->_d,$data);
 2076             }
 2077             else
 2078             {
 2079                 foreach($data as $key=>$value)
 2080                     $this->add($key,$value);
 2081             }
 2082         }
 2083         elseif($data!==null)
 2084             throw new CException(Yii::t('yii','Map data must be an array or an object implementing Traversable.'));
 2085     }
 2086     public static function mergeArray($a,$b)
 2087     {
 2088         $args=func_get_args();
 2089         $res=array_shift($args);
 2090         while(!empty($args))
 2091         {
 2092             $next=array_shift($args);
 2093             foreach($next as $k => $v)
 2094             {
 2095                 if(is_integer($k))
 2096                     isset($res[$k]) ? $res[]=$v : $res[$k]=$v;
 2097                 elseif(is_array($v) && isset($res[$k]) && is_array($res[$k]))
 2098                     $res[$k]=self::mergeArray($res[$k],$v);
 2099                 else
 2100                     $res[$k]=$v;
 2101             }
 2102         }
 2103         return $res;
 2104     }
 2105     public function offsetExists($offset)
 2106     {
 2107         return $this->contains($offset);
 2108     }
 2109     public function offsetGet($offset)
 2110     {
 2111         return $this->itemAt($offset);
 2112     }
 2113     public function offsetSet($offset,$item)
 2114     {
 2115         $this->add($offset,$item);
 2116     }
 2117     public function offsetUnset($offset)
 2118     {
 2119         $this->remove($offset);
 2120     }
 2121 }
 2122 class CLogger extends CComponent
 2123 {
 2124     const LEVEL_TRACE='trace';
 2125     const LEVEL_WARNING='warning';
 2126     const LEVEL_ERROR='error';
 2127     const LEVEL_INFO='info';
 2128     const LEVEL_PROFILE='profile';
 2129     public $autoFlush=10000;
 2130     public $autoDump=false;
 2131     private $_logs=array();
 2132     private $_logCount=0;
 2133     private $_levels;
 2134     private $_categories;
 2135     private $_except=array();
 2136     private $_timings;
 2137     private $_processing=false;
 2138     public function log($message,$level='info',$category='application')
 2139     {
 2140         $this->_logs[]=array($message,$level,$category,microtime(true));
 2141         $this->_logCount++;
 2142         if($this->autoFlush>0 && $this->_logCount>=$this->autoFlush && !$this->_processing)
 2143         {
 2144             $this->_processing=true;
 2145             $this->flush($this->autoDump);
 2146             $this->_processing=false;
 2147         }
 2148     }
 2149     public function getLogs($levels='',$categories=array(), $except=array())
 2150     {
 2151         $this->_levels=preg_split('/[\s,]+/',strtolower($levels),-1,PREG_SPLIT_NO_EMPTY);
 2152         if (is_string($categories))
 2153             $this->_categories=preg_split('/[\s,]+/',strtolower($categories),-1,PREG_SPLIT_NO_EMPTY);
 2154         else
 2155             $this->_categories=array_filter(array_map('strtolower',$categories));
 2156         if (is_string($except))
 2157             $this->_except=preg_split('/[\s,]+/',strtolower($except),-1,PREG_SPLIT_NO_EMPTY);
 2158         else
 2159             $this->_except=array_filter(array_map('strtolower',$except));
 2160         $ret=$this->_logs;
 2161         if(!empty($levels))
 2162             $ret=array_values(array_filter($ret,array($this,'filterByLevel')));
 2163         if(!empty($this->_categories) || !empty($this->_except))
 2164             $ret=array_values(array_filter($ret,array($this,'filterByCategory')));
 2165         return $ret;
 2166     }
 2167     private function filterByCategory($value)
 2168     {
 2169         return $this->filterAllCategories($value, 2);
 2170     }
 2171     private function filterTimingByCategory($value)
 2172     {
 2173         return $this->filterAllCategories($value, 1);
 2174     }
 2175     private function filterAllCategories($value, $index)
 2176     {
 2177         $cat=strtolower($value[$index]);
 2178         $ret=empty($this->_categories);
 2179         foreach($this->_categories as $category)
 2180         {
 2181             if($cat===$category || (($c=rtrim($category,'.*'))!==$category && strpos($cat,$c)===0))
 2182                 $ret=true;
 2183         }
 2184         if($ret)
 2185         {
 2186             foreach($this->_except as $category)
 2187             {
 2188                 if($cat===$category || (($c=rtrim($category,'.*'))!==$category && strpos($cat,$c)===0))
 2189                     $ret=false;
 2190             }
 2191         }
 2192         return $ret;
 2193     }
 2194     private function filterByLevel($value)
 2195     {
 2196         return in_array(strtolower($value[1]),$this->_levels);
 2197     }
 2198     public function getExecutionTime()
 2199     {
 2200         return microtime(true)-YII_BEGIN_TIME;
 2201     }
 2202     public function getMemoryUsage()
 2203     {
 2204         if(function_exists('memory_get_usage'))
 2205             return memory_get_usage();
 2206         else
 2207         {
 2208             $output=array();
 2209             if(strncmp(PHP_OS,'WIN',3)===0)
 2210             {
 2211                 exec('tasklist /FI "PID eq ' . getmypid() . '" /FO LIST',$output);
 2212                 return isset($output[5])?preg_replace('/[\D]/','',$output[5])*1024 : 0;
 2213             }
 2214             else
 2215             {
 2216                 $pid=getmypid();
 2217                 exec("ps -eo%mem,rss,pid | grep $pid", $output);
 2218                 $output=explode("  ",$output[0]);
 2219                 return isset($output[1]) ? $output[1]*1024 : 0;
 2220             }
 2221         }
 2222     }
 2223     public function getProfilingResults($token=null,$categories=null,$refresh=false)
 2224     {
 2225         if($this->_timings===null || $refresh)
 2226             $this->calculateTimings();
 2227         if($token===null && $categories===null)
 2228             return $this->_timings;
 2229         $timings = $this->_timings;
 2230         if($categories!==null) {
 2231             $this->_categories=preg_split('/[\s,]+/',strtolower($categories),-1,PREG_SPLIT_NO_EMPTY);
 2232             $timings=array_filter($timings,array($this,'filterTimingByCategory'));
 2233         }
 2234         $results=array();
 2235         foreach($timings as $timing)
 2236         {
 2237             if($token===null || $timing[0]===$token)
 2238                 $results[]=$timing[2];
 2239         }
 2240         return $results;
 2241     }
 2242     private function calculateTimings()
 2243     {
 2244         $this->_timings=array();
 2245         $stack=array();
 2246         foreach($this->_logs as $log)
 2247         {
 2248             if($log[1]!==CLogger::LEVEL_PROFILE)
 2249                 continue;
 2250             list($message,$level,$category,$timestamp)=$log;
 2251             if(!strncasecmp($message,'begin:',6))
 2252             {
 2253                 $log[0]=substr($message,6);
 2254                 $stack[]=$log;
 2255             }
 2256             elseif(!strncasecmp($message,'end:',4))
 2257             {
 2258                 $token=substr($message,4);
 2259                 if(($last=array_pop($stack))!==null && $last[0]===$token)
 2260                 {
 2261                     $delta=$log[3]-$last[3];
 2262                     $this->_timings[]=array($message,$category,$delta);
 2263                 }
 2264                 else
 2265                     throw new CException(Yii::t('yii','CProfileLogRoute found a mismatching code block "{token}". Make sure the calls to Yii::beginProfile() and Yii::endProfile() be properly nested.',
 2266                         array('{token}'=>$token)));
 2267             }
 2268         }
 2269         $now=microtime(true);
 2270         while(($last=array_pop($stack))!==null)
 2271         {
 2272             $delta=$now-$last[3];
 2273             $this->_timings[]=array($last[0],$last[2],$delta);
 2274         }
 2275     }
 2276     public function flush($dumpLogs=false)
 2277     {
 2278         $this->onFlush(new CEvent($this, array('dumpLogs'=>$dumpLogs)));
 2279         $this->_logs=array();
 2280         $this->_logCount=0;
 2281     }
 2282     public function onFlush($event)
 2283     {
 2284         $this->raiseEvent('onFlush', $event);
 2285     }
 2286 }
 2287 abstract class CApplicationComponent extends CComponent implements IApplicationComponent
 2288 {
 2289     public $behaviors=array();
 2290     private $_initialized=false;
 2291     public function init()
 2292     {
 2293         $this->attachBehaviors($this->behaviors);
 2294         $this->_initialized=true;
 2295     }
 2296     public function getIsInitialized()
 2297     {
 2298         return $this->_initialized;
 2299     }
 2300 }
 2301 class CHttpRequest extends CApplicationComponent
 2302 {
 2303     public $jsonAsArray = true;
 2304     public $enableCookieValidation=false;
 2305     public $enableCsrfValidation=false;
 2306     public $csrfTokenName='YII_CSRF_TOKEN';
 2307     public $csrfCookie;
 2308     private $_requestUri;
 2309     private $_pathInfo;
 2310     private $_scriptFile;
 2311     private $_scriptUrl;
 2312     private $_hostInfo;
 2313     private $_baseUrl;
 2314     private $_cookies;
 2315     private $_preferredAcceptTypes;
 2316     private $_preferredLanguages;
 2317     private $_csrfToken;
 2318     private $_restParams;
 2319     private $_httpVersion;
 2320     public function init()
 2321     {
 2322         parent::init();
 2323         $this->normalizeRequest();
 2324     }
 2325     protected function normalizeRequest()
 2326     {
 2327         // normalize request
 2328         if(version_compare(PHP_VERSION,'7.4.0','<'))
 2329         {
 2330             if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc())
 2331             {
 2332                 if(isset($_GET))
 2333                     $_GET=$this->stripSlashes($_GET);
 2334                 if(isset($_POST))
 2335                     $_POST=$this->stripSlashes($_POST);
 2336                 if(isset($_REQUEST))
 2337                     $_REQUEST=$this->stripSlashes($_REQUEST);
 2338                 if(isset($_COOKIE))
 2339                     $_COOKIE=$this->stripSlashes($_COOKIE);
 2340             }
 2341         }
 2342         if($this->enableCsrfValidation)
 2343             Yii::app()->attachEventHandler('onBeginRequest',array($this,'validateCsrfToken'));
 2344     }
 2345     public function stripSlashes(&$data)
 2346     {
 2347         if(is_array($data))
 2348         {
 2349             if(count($data) == 0)
 2350                 return $data;
 2351             $keys=array_map('stripslashes',array_keys($data));
 2352             $data=array_combine($keys,array_values($data));
 2353             return array_map(array($this,'stripSlashes'),$data);
 2354         }
 2355         else
 2356             return stripslashes($data);
 2357     }
 2358     public function getParam($name,$defaultValue=null)
 2359     {
 2360         return isset($_GET[$name]) ? $_GET[$name] : (isset($_POST[$name]) ? $_POST[$name] : $defaultValue);
 2361     }
 2362     public function getQuery($name,$defaultValue=null)
 2363     {
 2364         return isset($_GET[$name]) ? $_GET[$name] : $defaultValue;
 2365     }
 2366     public function getPost($name,$defaultValue=null)
 2367     {
 2368         return isset($_POST[$name]) ? $_POST[$name] : $defaultValue;
 2369     }
 2370     public function getDelete($name,$defaultValue=null)
 2371     {
 2372         if($this->getIsDeleteViaPostRequest())
 2373             return $this->getPost($name, $defaultValue);
 2374         if($this->getIsDeleteRequest())
 2375         {
 2376             $restParams=$this->getRestParams();
 2377             return isset($restParams[$name]) ? $restParams[$name] : $defaultValue;
 2378         }
 2379         else
 2380             return $defaultValue;
 2381     }
 2382     public function getPut($name,$defaultValue=null)
 2383     {
 2384         if($this->getIsPutViaPostRequest())
 2385             return $this->getPost($name, $defaultValue);
 2386         if($this->getIsPutRequest())
 2387         {
 2388             $restParams=$this->getRestParams();
 2389             return isset($restParams[$name]) ? $restParams[$name] : $defaultValue;
 2390         }
 2391         else
 2392             return $defaultValue;
 2393     }
 2394     public function getPatch($name,$defaultValue=null)
 2395     {
 2396         if($this->getIsPatchViaPostRequest())
 2397             return $this->getPost($name, $defaultValue);
 2398         if($this->getIsPatchRequest())
 2399         {
 2400             $restParams=$this->getRestParams();
 2401             return isset($restParams[$name]) ? $restParams[$name] : $defaultValue;
 2402         }
 2403         else
 2404             return $defaultValue;
 2405     }
 2406     public function getRestParams()
 2407     {
 2408         if($this->_restParams===null)
 2409         {
 2410             $result=array();
 2411             if (strncmp($this->getContentType(), 'application/json', 16) === 0)
 2412                 $result = CJSON::decode($this->getRawBody(), $this->jsonAsArray);
 2413             elseif(function_exists('mb_parse_str'))
 2414                 mb_parse_str($this->getRawBody(), $result);
 2415             else
 2416                 parse_str($this->getRawBody(), $result);
 2417             $this->_restParams=$result;
 2418         }
 2419         return $this->_restParams;
 2420     }
 2421     public function getRawBody()
 2422     {
 2423         static $rawBody;
 2424         if($rawBody===null)
 2425             $rawBody=file_get_contents('php://input');
 2426         return $rawBody;
 2427     }
 2428     public function getUrl()
 2429     {
 2430         return $this->getRequestUri();
 2431     }
 2432     public function getHostInfo($schema='')
 2433     {
 2434         if($this->_hostInfo===null)
 2435         {
 2436             if($secure=$this->getIsSecureConnection())
 2437                 $http='https';
 2438             else
 2439                 $http='http';
 2440             if(isset($_SERVER['HTTP_HOST']))
 2441                 $this->_hostInfo=$http.'://'.$_SERVER['HTTP_HOST'];
 2442             else
 2443             {
 2444                 $this->_hostInfo=$http.'://'.$_SERVER['SERVER_NAME'];
 2445                 $port=$secure ? $this->getSecurePort() : $this->getPort();
 2446                 if(($port!==80 && !$secure) || ($port!==443 && $secure))
 2447                     $this->_hostInfo.=':'.$port;
 2448             }
 2449         }
 2450         if($schema!=='')
 2451         {
 2452             $secure=$this->getIsSecureConnection();
 2453             if($secure && $schema==='https' || !$secure && $schema==='http')
 2454                 return $this->_hostInfo;
 2455             $port=$schema==='https' ? $this->getSecurePort() : $this->getPort();
 2456             if($port!==80 && $schema==='http' || $port!==443 && $schema==='https')
 2457                 $port=':'.$port;
 2458             else
 2459                 $port='';
 2460             $pos=strpos($this->_hostInfo,':');
 2461             return $schema.substr($this->_hostInfo,$pos,strcspn($this->_hostInfo,':',$pos+1)+1).$port;
 2462         }
 2463         else
 2464             return $this->_hostInfo;
 2465     }
 2466     public function setHostInfo($value)
 2467     {
 2468         $this->_hostInfo=rtrim($value,'/');
 2469     }
 2470     public function getBaseUrl($absolute=false)
 2471     {
 2472         if($this->_baseUrl===null)
 2473             $this->_baseUrl=rtrim(dirname($this->getScriptUrl()),'\\/');
 2474         return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl;
 2475     }
 2476     public function setBaseUrl($value)
 2477     {
 2478         $this->_baseUrl=$value;
 2479     }
 2480     public function getScriptUrl()
 2481     {
 2482         if($this->_scriptUrl===null)
 2483         {
 2484             $scriptName=basename($_SERVER['SCRIPT_FILENAME']);
 2485             if(basename($_SERVER['SCRIPT_NAME'])===$scriptName)
 2486                 $this->_scriptUrl=$_SERVER['SCRIPT_NAME'];
 2487             elseif(basename($_SERVER['PHP_SELF'])===$scriptName)
 2488                 $this->_scriptUrl=$_SERVER['PHP_SELF'];
 2489             elseif(isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME'])===$scriptName)
 2490                 $this->_scriptUrl=$_SERVER['ORIG_SCRIPT_NAME'];
 2491             elseif(($pos=strpos($_SERVER['PHP_SELF'],'/'.$scriptName))!==false)
 2492                 $this->_scriptUrl=substr($_SERVER['SCRIPT_NAME'],0,$pos).'/'.$scriptName;
 2493             elseif(isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['SCRIPT_FILENAME'],$_SERVER['DOCUMENT_ROOT'])===0)
 2494                 $this->_scriptUrl=str_replace('\\','/',str_replace($_SERVER['DOCUMENT_ROOT'],'',$_SERVER['SCRIPT_FILENAME']));
 2495             else
 2496                 throw new CException(Yii::t('yii','CHttpRequest is unable to determine the entry script URL.'));
 2497         }
 2498         return $this->_scriptUrl;
 2499     }
 2500     public function setScriptUrl($value)
 2501     {
 2502         $this->_scriptUrl='/'.trim($value,'/');
 2503     }
 2504     public function getPathInfo()
 2505     {
 2506         if($this->_pathInfo===null)
 2507         {
 2508             $pathInfo=$this->getRequestUri();
 2509             if(($pos=strpos($pathInfo,'?'))!==false)
 2510                $pathInfo=substr($pathInfo,0,$pos);
 2511             $pathInfo=$this->decodePathInfo($pathInfo);
 2512             $scriptUrl=$this->getScriptUrl();
 2513             $baseUrl=$this->getBaseUrl();
 2514             if(strpos($pathInfo,$scriptUrl)===0)
 2515                 $pathInfo=substr($pathInfo,strlen($scriptUrl));
 2516             elseif($baseUrl==='' || strpos($pathInfo,$baseUrl)===0)
 2517                 $pathInfo=substr($pathInfo,strlen($baseUrl));
 2518             elseif(strpos($_SERVER['PHP_SELF'],$scriptUrl)===0)
 2519                 $pathInfo=substr($_SERVER['PHP_SELF'],strlen($scriptUrl));
 2520             else
 2521                 throw new CException(Yii::t('yii','CHttpRequest is unable to determine the path info of the request.'));
 2522             if($pathInfo==='/' || $pathInfo===false)
 2523                 $pathInfo='';
 2524             elseif($pathInfo!=='' && $pathInfo[0]==='/')
 2525                 $pathInfo=substr($pathInfo,1);
 2526             if(($posEnd=strlen($pathInfo)-1)>0 && $pathInfo[$posEnd]==='/')
 2527                 $pathInfo=substr($pathInfo,0,$posEnd);
 2528             $this->_pathInfo=$pathInfo;
 2529         }
 2530         return $this->_pathInfo;
 2531     }
 2532     protected function decodePathInfo($pathInfo)
 2533     {
 2534         $pathInfo = urldecode($pathInfo);
 2535         // is it UTF-8?
 2536         // http://w3.org/International/questions/qa-forms-utf-8.html
 2537         if(preg_match('%^(?:
 2538            [\x09\x0A\x0D\x20-\x7E]            # ASCII
 2539          | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
 2540          | \xE0[\xA0-\xBF][\x80-\xBF]         # excluding overlongs
 2541          | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
 2542          | \xED[\x80-\x9F][\x80-\xBF]         # excluding surrogates
 2543          | \xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
 2544          | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
 2545          | \xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
 2546         )*$%xs', $pathInfo))
 2547         {
 2548             return $pathInfo;
 2549         }
 2550         else
 2551         {
 2552             return utf8_encode($pathInfo);
 2553         }
 2554     }
 2555     public function getRequestUri()
 2556     {
 2557         if($this->_requestUri===null)
 2558         {
 2559             if(isset($_SERVER['REQUEST_URI']))
 2560             {
 2561                 $this->_requestUri=$_SERVER['REQUEST_URI'];
 2562                 if(!empty($_SERVER['HTTP_HOST']))
 2563                 {
 2564                     if(strpos($this->_requestUri,$_SERVER['HTTP_HOST'])!==false)
 2565                         $this->_requestUri=preg_replace('/^\w+:\/\/[^\/]+/','',$this->_requestUri);
 2566                 }
 2567                 else
 2568                     $this->_requestUri=preg_replace('/^(http|https):\/\/[^\/]+/i','',$this->_requestUri);
 2569             }
 2570             elseif(isset($_SERVER['ORIG_PATH_INFO']))  // IIS 5.0 CGI
 2571             {
 2572                 $this->_requestUri=$_SERVER['ORIG_PATH_INFO'];
 2573                 if(!empty($_SERVER['QUERY_STRING']))
 2574                     $this->_requestUri.='?'.$_SERVER['QUERY_STRING'];
 2575             }
 2576             else
 2577                 throw new CException(Yii::t('yii','CHttpRequest is unable to determine the request URI.'));
 2578         }
 2579         return $this->_requestUri;
 2580     }
 2581     public function getQueryString()
 2582     {
 2583         return isset($_SERVER['QUERY_STRING'])?$_SERVER['QUERY_STRING']:'';
 2584     }
 2585     public function getIsSecureConnection()
 2586     {
 2587         return isset($_SERVER['HTTPS']) && (strcasecmp($_SERVER['HTTPS'],'on')===0 || $_SERVER['HTTPS']==1)
 2588             || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'],'https')===0;
 2589     }
 2590     public function getRequestType()
 2591     {
 2592         if(isset($_POST['_method']))
 2593             return strtoupper($_POST['_method']);
 2594         elseif(isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']))
 2595             return strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
 2596         return strtoupper(isset($_SERVER['REQUEST_METHOD'])?$_SERVER['REQUEST_METHOD']:'GET');
 2597     }
 2598     public function getIsPostRequest()
 2599     {
 2600         return isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'],'POST');
 2601     }
 2602     public function getIsDeleteRequest()
 2603     {
 2604         return (isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'],'DELETE')) || $this->getIsDeleteViaPostRequest();
 2605     }
 2606     protected function getIsDeleteViaPostRequest()
 2607     {
 2608         return isset($_POST['_method']) && !strcasecmp($_POST['_method'],'DELETE');
 2609     }
 2610     public function getIsPutRequest()
 2611     {
 2612         return (isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'],'PUT')) || $this->getIsPutViaPostRequest();
 2613     }
 2614     protected function getIsPutViaPostRequest()
 2615     {
 2616         return isset($_POST['_method']) && !strcasecmp($_POST['_method'],'PUT');
 2617     }
 2618     public function getIsPatchRequest()
 2619     {
 2620         return (isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'],'PATCH')) || $this->getIsPatchViaPostRequest();
 2621     }
 2622     protected function getIsPatchViaPostRequest()
 2623     {
 2624         return isset($_POST['_method']) && !strcasecmp($_POST['_method'],'PATCH');
 2625     }
 2626     public function getIsAjaxRequest()
 2627     {
 2628         return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';
 2629     }
 2630     public function getIsFlashRequest()
 2631     {
 2632         return isset($_SERVER['HTTP_USER_AGENT']) && (stripos($_SERVER['HTTP_USER_AGENT'],'Shockwave')!==false || stripos($_SERVER['HTTP_USER_AGENT'],'Flash')!==false);
 2633     }
 2634     public function getServerName()
 2635     {
 2636         return $_SERVER['SERVER_NAME'];
 2637     }
 2638     public function getServerPort()
 2639     {
 2640         return $_SERVER['SERVER_PORT'];
 2641     }
 2642     public function getUrlReferrer()
 2643     {
 2644         return isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:null;
 2645     }
 2646     public function getUserAgent()
 2647     {
 2648         return isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:null;
 2649     }
 2650     public function getUserHostAddress()
 2651     {
 2652         return isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:'127.0.0.1';
 2653     }
 2654     public function getUserHost()
 2655     {
 2656         return isset($_SERVER['REMOTE_HOST'])?$_SERVER['REMOTE_HOST']:null;
 2657     }
 2658     public function getScriptFile()
 2659     {
 2660         if($this->_scriptFile!==null)
 2661             return $this->_scriptFile;
 2662         else
 2663             return $this->_scriptFile=realpath($_SERVER['SCRIPT_FILENAME']);
 2664     }
 2665     public function getBrowser($userAgent=null)
 2666     {
 2667         return get_browser($userAgent,true);
 2668     }
 2669     public function getAcceptTypes()
 2670     {
 2671         return isset($_SERVER['HTTP_ACCEPT'])?$_SERVER['HTTP_ACCEPT']:null;
 2672     }
 2673     public function getContentType()
 2674     {
 2675         if (isset($_SERVER["CONTENT_TYPE"])) {
 2676             return $_SERVER["CONTENT_TYPE"];
 2677         } elseif (isset($_SERVER["HTTP_CONTENT_TYPE"])) {
 2678             //fix bug https://bugs.php.net/bug.php?id=66606
 2679             return $_SERVER["HTTP_CONTENT_TYPE"];
 2680         }
 2681         return null;
 2682     }
 2683     private $_port;
 2684     public function getPort()
 2685     {
 2686         if($this->_port===null)
 2687             $this->_port=!$this->getIsSecureConnection() && isset($_SERVER['SERVER_PORT']) ? (int)$_SERVER['SERVER_PORT'] : 80;
 2688         return $this->_port;
 2689     }
 2690     public function setPort($value)
 2691     {
 2692         $this->_port=(int)$value;
 2693         $this->_hostInfo=null;
 2694     }
 2695     private $_securePort;
 2696     public function getSecurePort()
 2697     {
 2698         if($this->_securePort===null)
 2699             $this->_securePort=$this->getIsSecureConnection() && isset($_SERVER['SERVER_PORT']) ? (int)$_SERVER['SERVER_PORT'] : 443;
 2700         return $this->_securePort;
 2701     }
 2702     public function setSecurePort($value)
 2703     {
 2704         $this->_securePort=(int)$value;
 2705         $this->_hostInfo=null;
 2706     }
 2707     public function getCookies()
 2708     {
 2709         if($this->_cookies!==null)
 2710             return $this->_cookies;
 2711         else
 2712             return $this->_cookies=new CCookieCollection($this);
 2713     }
 2714     public function redirect($url,$terminate=true,$statusCode=302)
 2715     {
 2716         if(strpos($url,'/')===0 && strpos($url,'//')!==0)
 2717             $url=$this->getHostInfo().$url;
 2718         header('Location: '.$url, true, $statusCode);
 2719         if($terminate)
 2720             Yii::app()->end();
 2721     }
 2722     public static function parseAcceptHeader($header)
 2723     {
 2724         $matches=array();
 2725         $accepts=array();
 2726         // get individual entries with their type, subtype, basetype and params
 2727         preg_match_all('/(?:\G\s?,\s?|^)(\w+|\*)\/(\w+|\*)(?:\+(\w+))?|(?<!^)\G(?:\s?;\s?(\w+)=([\w\.]+))/',$header,$matches);
 2728         // the regexp should (in theory) always return an array of 6 arrays
 2729         if(count($matches)===6)
 2730         {
 2731             $i=0;
 2732             $itemLen=count($matches[1]);
 2733             while($i<$itemLen)
 2734             {
 2735                 // fill out a content type
 2736                 $accept=array(
 2737                     'type'=>$matches[1][$i],
 2738                     'subType'=>$matches[2][$i],
 2739                     'baseType'=>null,
 2740                     'params'=>array(),
 2741                 );
 2742                 // fill in the base type if it exists
 2743                 if($matches[3][$i]!==null && $matches[3][$i]!=='')
 2744                     $accept['baseType']=$matches[3][$i];
 2745                 // continue looping while there is no new content type, to fill in all accompanying params
 2746                 for($i++;$i<$itemLen;$i++)
 2747                 {
 2748                     // if the next content type is null, then the item is a param for the current content type
 2749                     if($matches[1][$i]===null || $matches[1][$i]==='')
 2750                     {
 2751                         // if this is the quality param, convert it to a double
 2752                         if($matches[4][$i]==='q')
 2753                         {
 2754                             // sanity check on q value
 2755                             $q=(double)$matches[5][$i];
 2756                             if($q>1)
 2757                                 $q=(double)1;
 2758                             elseif($q<0)
 2759                                 $q=(double)0;
 2760                             $accept['params'][$matches[4][$i]]=$q;
 2761                         }
 2762                         else
 2763                             $accept['params'][$matches[4][$i]]=$matches[5][$i];
 2764                     }
 2765                     else
 2766                         break;
 2767                 }
 2768                 // q defaults to 1 if not explicitly given
 2769                 if(!isset($accept['params']['q']))
 2770                     $accept['params']['q']=(double)1;
 2771                 $accepts[] = $accept;
 2772             }
 2773         }
 2774         return $accepts;
 2775     }
 2776     public static function compareAcceptTypes($a,$b)
 2777     {
 2778         // check for equal quality first
 2779         if($a['params']['q']===$b['params']['q'])
 2780             if(!($a['type']==='*' xor $b['type']==='*'))
 2781                 if (!($a['subType']==='*' xor $b['subType']==='*'))
 2782                     // finally, higher number of parameters counts as greater precedence
 2783                     if(count($a['params'])===count($b['params']))
 2784                         return 0;
 2785                     else
 2786                         return count($a['params'])<count($b['params']) ? 1 : -1;
 2787                 // more specific takes precedence - whichever one doesn't have a * subType
 2788                 else
 2789                     return $a['subType']==='*' ? 1 : -1;
 2790             // more specific takes precedence - whichever one doesn't have a * type
 2791             else
 2792                 return $a['type']==='*' ? 1 : -1;
 2793         else
 2794             return ($a['params']['q']<$b['params']['q']) ? 1 : -1;
 2795     }
 2796     public function getPreferredAcceptTypes()
 2797     {
 2798         if($this->_preferredAcceptTypes===null)
 2799         {
 2800             $accepts=self::parseAcceptHeader($this->getAcceptTypes());
 2801             usort($accepts,array(get_class($this),'compareAcceptTypes'));
 2802             $this->_preferredAcceptTypes=$accepts;
 2803         }
 2804         return $this->_preferredAcceptTypes;
 2805     }
 2806     public function getPreferredAcceptType()
 2807     {
 2808         $preferredAcceptTypes=$this->getPreferredAcceptTypes();
 2809         return empty($preferredAcceptTypes) ? false : $preferredAcceptTypes[0];
 2810     }
 2811     private function stringCompare($a, $b)
 2812     {
 2813         if ($a[0] == $b[0]) {
 2814             return 0;
 2815         }
 2816         return ($a[0] < $b[0]) ? 1 : -1;
 2817     }
 2818     public function getPreferredLanguages()
 2819     {
 2820         if($this->_preferredLanguages===null)
 2821         {
 2822             $sortedLanguages=array();
 2823             if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) && $n=preg_match_all('/([\w\-_]+)(?:\s*;\s*q\s*=\s*(\d*\.?\d*))?/',$_SERVER['HTTP_ACCEPT_LANGUAGE'],$matches))
 2824             {
 2825                 $languages=array();
 2826                 for($i=0;$i<$n;++$i)
 2827                 {
 2828                     $q=$matches[2][$i];
 2829                     if($q==='')
 2830                         $q=1;
 2831                     if($q)
 2832                         $languages[]=array((float)$q,$matches[1][$i]);
 2833                 }
 2834                 usort($languages, array($this, 'stringCompare'));
 2835                 foreach($languages as $language)
 2836                     $sortedLanguages[]=$language[1];
 2837             }
 2838             $this->_preferredLanguages=$sortedLanguages;
 2839         }
 2840         return $this->_preferredLanguages;
 2841     }
 2842     public function getPreferredLanguage($languages=array())
 2843     {
 2844         $preferredLanguages=$this->getPreferredLanguages();
 2845         if(empty($languages)) {
 2846             return !empty($preferredLanguages) ? CLocale::getCanonicalID($preferredLanguages[0]) : false;
 2847         }
 2848         foreach ($preferredLanguages as $preferredLanguage) {
 2849             $preferredLanguage=CLocale::getCanonicalID($preferredLanguage);
 2850             foreach ($languages as $language) {
 2851                 $language=CLocale::getCanonicalID($language);
 2852                 // en_us==en_us, en==en_us, en_us==en
 2853                 if($language===$preferredLanguage || strpos($preferredLanguage,$language.'_')===0 || strpos($language,$preferredLanguage.'_')===0) {
 2854                     return $language;
 2855                 }
 2856             }
 2857         }
 2858         return reset($languages);
 2859     }
 2860     public function sendFile($fileName,$content,$mimeType=null,$terminate=true)
 2861     {
 2862         if($mimeType===null)
 2863         {
 2864             if(($mimeType=CFileHelper::getMimeTypeByExtension($fileName))===null)
 2865                 $mimeType='text/plain';
 2866         }
 2867         $fileSize=(function_exists('mb_strlen') ? mb_strlen($content,'8bit') : strlen($content));
 2868         $contentStart=0;
 2869         $contentEnd=$fileSize-1;
 2870         $httpVersion=$this->getHttpVersion();
 2871         if(isset($_SERVER['HTTP_RANGE']))
 2872         {
 2873             header('Accept-Ranges: bytes');
 2874             //client sent us a multibyte range, can not hold this one for now
 2875             if(strpos($_SERVER['HTTP_RANGE'],',')!==false)
 2876             {
 2877                 header("Content-Range: bytes $contentStart-$contentEnd/$fileSize");
 2878                 throw new CHttpException(416,'Requested Range Not Satisfiable');
 2879             }
 2880             $range=str_replace('bytes=','',$_SERVER['HTTP_RANGE']);
 2881             //range requests starts from "-", so it means that data must be dumped the end point.
 2882             if($range[0]==='-')
 2883                 $contentStart=$fileSize-substr($range,1);
 2884             else
 2885             {
 2886                 $range=explode('-',$range);
 2887                 $contentStart=$range[0];
 2888                 // check if the last-byte-pos presents in header
 2889                 if((isset($range[1]) && is_numeric($range[1])))
 2890                     $contentEnd=$range[1];
 2891             }
 2892             /* Check the range and make sure it's treated according to the specs.
 2893              * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
 2894              */
 2895             // End bytes can not be larger than $end.
 2896             $contentEnd=($contentEnd > $fileSize) ? $fileSize-1 : $contentEnd;
 2897             // Validate the requested range and return an error if it's not correct.
 2898             $wrongContentStart=($contentStart>$contentEnd || $contentStart>$fileSize-1 || $contentStart<0);
 2899             if($wrongContentStart)
 2900             {
 2901                 header("Content-Range: bytes $contentStart-$contentEnd/$fileSize");
 2902                 throw new CHttpException(416,'Requested Range Not Satisfiable');
 2903             }
 2904             header("HTTP/$httpVersion 206 Partial Content");
 2905             header("Content-Range: bytes $contentStart-$contentEnd/$fileSize");
 2906         }
 2907         else
 2908             header("HTTP/$httpVersion 200 OK");
 2909         $length=$contentEnd-$contentStart+1; // Calculate new content length
 2910         header('Pragma: public');
 2911         header('Expires: 0');
 2912         header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
 2913         header("Content-Type: $mimeType");
 2914         header('Content-Length: '.$length);
 2915         header("Content-Disposition: attachment; filename=\"$fileName\"");
 2916         header('Content-Transfer-Encoding: binary');
 2917         $content=function_exists('mb_substr') ? mb_substr($content,$contentStart,$length,'8bit') : substr($content,$contentStart,$length);
 2918         if($terminate)
 2919         {
 2920             // clean up the application first because the file downloading could take long time
 2921             // which may cause timeout of some resources (such as DB connection)
 2922             ob_start();
 2923             Yii::app()->end(0,false);
 2924             ob_end_clean();
 2925             echo $content;
 2926             exit(0);
 2927         }
 2928         else
 2929             echo $content;
 2930     }
 2931     public function xSendFile($filePath, $options=array())
 2932     {
 2933         if(!isset($options['forceDownload']) || $options['forceDownload'])
 2934             $disposition='attachment';
 2935         else
 2936             $disposition='inline';
 2937         if(!isset($options['saveName']))
 2938             $options['saveName']=basename($filePath);
 2939         if(!isset($options['mimeType']))
 2940         {
 2941             if(($options['mimeType']=CFileHelper::getMimeTypeByExtension($filePath))===null)
 2942                 $options['mimeType']='text/plain';
 2943         }
 2944         if(!isset($options['xHeader']))
 2945             $options['xHeader']='X-Sendfile';
 2946         if($options['mimeType']!==null)
 2947             header('Content-Type: '.$options['mimeType']);
 2948         header('Content-Disposition: '.$disposition.'; filename="'.$options['saveName'].'"');
 2949         if(isset($options['addHeaders']))
 2950         {
 2951             foreach($options['addHeaders'] as $header=>$value)
 2952                 header($header.': '.$value);
 2953         }
 2954         header(trim($options['xHeader']).': '.$filePath);
 2955         if(!isset($options['terminate']) || $options['terminate'])
 2956             Yii::app()->end();
 2957     }
 2958     public function getCsrfToken()
 2959     {
 2960         if($this->_csrfToken===null)
 2961         {
 2962             $cookie=$this->getCookies()->itemAt($this->csrfTokenName);
 2963             if(!$cookie || ($this->_csrfToken=$cookie->value)==null)
 2964             {
 2965                 $cookie=$this->createCsrfCookie();
 2966                 $this->_csrfToken=$cookie->value;
 2967                 $this->getCookies()->add($cookie->name,$cookie);
 2968             }
 2969         }
 2970         return $this->_csrfToken;
 2971     }
 2972     protected function createCsrfCookie()
 2973     {
 2974         $securityManager=Yii::app()->getSecurityManager();
 2975         $token=$securityManager->generateRandomBytes(32);
 2976         $maskedToken=$securityManager->maskToken($token);
 2977         $cookie=new CHttpCookie($this->csrfTokenName,$maskedToken);
 2978         if(is_array($this->csrfCookie))
 2979         {
 2980             foreach($this->csrfCookie as $name=>$value)
 2981                 $cookie->$name=$value;
 2982         }
 2983         return $cookie;
 2984     }
 2985     public function validateCsrfToken($event)
 2986     {
 2987         if ($this->getIsPostRequest() ||
 2988             $this->getIsPutRequest() ||
 2989             $this->getIsPatchRequest() ||
 2990             $this->getIsDeleteRequest())
 2991         {
 2992             $cookies=$this->getCookies();
 2993             $method=$this->getRequestType();
 2994             switch($method)
 2995             {
 2996                 case 'POST':
 2997                     $maskedUserToken=$this->getPost($this->csrfTokenName);
 2998                 break;
 2999                 case 'PUT':
 3000                     $maskedUserToken=$this->getPut($this->csrfTokenName);
 3001                 break;
 3002                 case 'PATCH':
 3003                     $maskedUserToken=$this->getPatch($this->csrfTokenName);
 3004                 break;
 3005                 case 'DELETE':
 3006                     $maskedUserToken=$this->getDelete($this->csrfTokenName);
 3007             }
 3008             if (!empty($maskedUserToken) && $cookies->contains($this->csrfTokenName))
 3009             {
 3010                 $securityManager=Yii::app()->getSecurityManager();
 3011                 $maskedCookieToken=$cookies->itemAt($this->csrfTokenName)->value;
 3012                 $cookieToken=$securityManager->unmaskToken($maskedCookieToken);
 3013                 $userToken=$securityManager->unmaskToken($maskedUserToken);
 3014                 $valid=$cookieToken===$userToken;
 3015             }
 3016             else
 3017                 $valid = false;
 3018             if (!$valid)
 3019                 throw new CHttpException(400,Yii::t('yii','The CSRF token could not be verified.'));
 3020         }
 3021     }
 3022     public function getHttpVersion()
 3023     {
 3024         if($this->_httpVersion===null)
 3025         {
 3026             if(isset($_SERVER['SERVER_PROTOCOL']) && $_SERVER['SERVER_PROTOCOL']==='HTTP/1.0')
 3027                 $this->_httpVersion='1.0';
 3028             else
 3029                 $this->_httpVersion='1.1';
 3030         }
 3031         return $this->_httpVersion;
 3032     }
 3033 }
 3034 class CCookieCollection extends CMap
 3035 {
 3036     private $_request;
 3037     private $_initialized=false;
 3038     public function __construct(CHttpRequest $request)
 3039     {
 3040         $this->_request=$request;
 3041         $this->copyfrom($this->getCookies());
 3042         $this->_initialized=true;
 3043     }
 3044     public function getRequest()
 3045     {
 3046         return $this->_request;
 3047     }
 3048     protected function getCookies()
 3049     {
 3050         $cookies=array();
 3051         if($this->_request->enableCookieValidation)
 3052         {
 3053             $sm=Yii::app()->getSecurityManager();
 3054             foreach($_COOKIE as $name=>$value)
 3055             {
 3056                 if(is_string($value) && ($value=$sm->validateData($value))!==false)
 3057                     $cookies[$name]=new CHttpCookie($name,@unserialize($value));
 3058             }
 3059         }
 3060         else
 3061         {
 3062             foreach($_COOKIE as $name=>$value)
 3063                 $cookies[$name]=new CHttpCookie($name,$value);
 3064         }
 3065         return $cookies;
 3066     }
 3067     public function add($name,$cookie)
 3068     {
 3069         if($cookie instanceof CHttpCookie)
 3070         {
 3071             $this->remove($name);
 3072             parent::add($name,$cookie);
 3073             if($this->_initialized)
 3074                 $this->addCookie($cookie);
 3075         }
 3076         else
 3077             throw new CException(Yii::t('yii','CHttpCookieCollection can only hold CHttpCookie objects.'));
 3078     }
 3079     public function remove($name,$options=array())
 3080     {
 3081         if(($cookie=parent::remove($name))!==null)
 3082         {
 3083             if($this->_initialized)
 3084             {
 3085                 $cookie->configure($options);
 3086                 $this->removeCookie($cookie);
 3087             }
 3088         }
 3089         return $cookie;
 3090     }
 3091     protected function addCookie($cookie)
 3092     {
 3093         $value=$cookie->value;
 3094         if($this->_request->enableCookieValidation)
 3095             $value=Yii::app()->getSecurityManager()->hashData(serialize($value));
 3096         if(version_compare(PHP_VERSION,'7.3.0','>='))
 3097             setcookie($cookie->name,$value,$this->getCookieOptions($cookie));
 3098         elseif(version_compare(PHP_VERSION,'5.2.0','>='))
 3099             setcookie($cookie->name,$value,$cookie->expire,$cookie->path,$cookie->domain,$cookie->secure,$cookie->httpOnly);
 3100         else
 3101             setcookie($cookie->name,$value,$cookie->expire,$cookie->path,$cookie->domain,$cookie->secure);
 3102     }
 3103     protected function removeCookie($cookie)
 3104     {
 3105         $cookie->expire=0;
 3106         if(version_compare(PHP_VERSION,'7.3.0','>='))
 3107             setcookie($cookie->name,'',$this->getCookieOptions($cookie));
 3108         elseif(version_compare(PHP_VERSION,'5.2.0','>='))
 3109             setcookie($cookie->name,'',$cookie->expire,$cookie->path,$cookie->domain,$cookie->secure,$cookie->httpOnly);
 3110         else
 3111             setcookie($cookie->name,'',$cookie->expire,$cookie->path,$cookie->domain,$cookie->secure);
 3112     }
 3113     protected function getCookieOptions($cookie)
 3114     {
 3115         return array(
 3116             'expires'=>$cookie->expire,
 3117             'path'=>$cookie->path,
 3118             'domain'=>$cookie->domain,
 3119             'secure'=>$cookie->secure,
 3120             'httpOnly'=>$cookie->httpOnly,
 3121             'sameSite'=>$cookie->sameSite
 3122         );
 3123     }
 3124 }
 3125 class CUrlManager extends CApplicationComponent
 3126 {
 3127     const CACHE_KEY='Yii.CUrlManager.rules';
 3128     const GET_FORMAT='get';
 3129     const PATH_FORMAT='path';
 3130     public $rules=array();
 3131     public $urlSuffix='';
 3132     public $showScriptName=true;
 3133     public $appendParams=true;
 3134     public $routeVar='r';
 3135     public $caseSensitive=true;
 3136     public $matchValue=false;
 3137     public $cacheID='cache';
 3138     public $useStrictParsing=false;
 3139     public $urlRuleClass='CUrlRule';
 3140     private $_urlFormat=self::GET_FORMAT;
 3141     private $_rules=array();
 3142     private $_baseUrl;
 3143     public function init()
 3144     {
 3145         parent::init();
 3146         $this->processRules();
 3147     }
 3148     protected function processRules()
 3149     {
 3150         if(empty($this->rules) || $this->getUrlFormat()===self::GET_FORMAT)
 3151             return;
 3152         if($this->cacheID!==false && ($cache=Yii::app()->getComponent($this->cacheID))!==null)
 3153         {
 3154             $hash=md5(serialize($this->rules));
 3155             if(($data=$cache->get(self::CACHE_KEY))!==false && isset($data[1]) && $data[1]===$hash)
 3156             {
 3157                 $this->_rules=$data[0];
 3158                 return;
 3159             }
 3160         }
 3161         foreach($this->rules as $pattern=>$route)
 3162             $this->_rules[]=$this->createUrlRule($route,$pattern);
 3163         if(isset($cache))
 3164             $cache->set(self::CACHE_KEY,array($this->_rules,$hash));
 3165     }
 3166     public function addRules($rules,$append=true)
 3167     {
 3168         if ($append)
 3169         {
 3170             foreach($rules as $pattern=>$route)
 3171                 $this->_rules[]=$this->createUrlRule($route,$pattern);
 3172         }
 3173         else
 3174         {
 3175             $rules=array_reverse($rules);
 3176             foreach($rules as $pattern=>$route)
 3177                 array_unshift($this->_rules, $this->createUrlRule($route,$pattern));
 3178         }
 3179     }
 3180     protected function createUrlRule($route,$pattern)
 3181     {
 3182         if(is_array($route) && isset($route['class']))
 3183             return $route;
 3184         else
 3185         {
 3186             $urlRuleClass=Yii::import($this->urlRuleClass,true);
 3187             return new $urlRuleClass($route,$pattern);
 3188         }
 3189     }
 3190     public function createUrl($route,$params=array(),$ampersand='&')
 3191     {
 3192         unset($params[$this->routeVar]);
 3193         foreach($params as $i=>$param)
 3194             if($param===null)
 3195                 $params[$i]='';
 3196         if(isset($params['#']))
 3197         {
 3198             $anchor='#'.$params['#'];
 3199             unset($params['#']);
 3200         }
 3201         else
 3202             $anchor='';
 3203         $route=trim($route,'/');
 3204         foreach($this->_rules as $i=>$rule)
 3205         {
 3206             if(is_array($rule))
 3207                 $this->_rules[$i]=$rule=Yii::createComponent($rule);
 3208             if(($url=$rule->createUrl($this,$route,$params,$ampersand))!==false)
 3209             {
 3210                 if($rule->hasHostInfo)
 3211                     return $url==='' ? '/'.$anchor : $url.$anchor;
 3212                 else
 3213                     return $this->getBaseUrl().'/'.$url.$anchor;
 3214             }
 3215         }
 3216         return $this->createUrlDefault($route,$params,$ampersand).$anchor;
 3217     }
 3218     protected function createUrlDefault($route,$params,$ampersand)
 3219     {
 3220         if($this->getUrlFormat()===self::PATH_FORMAT)
 3221         {
 3222             $url=rtrim($this->getBaseUrl().'/'.$route,'/');
 3223             if($this->appendParams)
 3224             {
 3225                 $url=rtrim($url.'/'.$this->createPathInfo($params,'/','/'),'/');
 3226                 return $route==='' ? $url : $url.$this->urlSuffix;
 3227             }
 3228             else
 3229             {
 3230                 if($route!=='')
 3231                     $url.=$this->urlSuffix;
 3232                 $query=$this->createPathInfo($params,'=',$ampersand);
 3233                 return $query==='' ? $url : $url.'?'.$query;
 3234             }
 3235         }
 3236         else
 3237         {
 3238             $url=$this->getBaseUrl();
 3239             if(!$this->showScriptName)
 3240                 $url.='/';
 3241             if($route!=='')
 3242             {
 3243                 $url.='?'.$this->routeVar.'='.$route;
 3244                 if(($query=$this->createPathInfo($params,'=',$ampersand))!=='')
 3245                     $url.=$ampersand.$query;
 3246             }
 3247             elseif(($query=$this->createPathInfo($params,'=',$ampersand))!=='')
 3248                 $url.='?'.$query;
 3249             return $url;
 3250         }
 3251     }
 3252     public function parseUrl($request)
 3253     {
 3254         if($this->getUrlFormat()===self::PATH_FORMAT)
 3255         {
 3256             $rawPathInfo=$request->getPathInfo();
 3257             $pathInfo=$this->removeUrlSuffix($rawPathInfo,$this->urlSuffix);
 3258             foreach($this->_rules as $i=>$rule)
 3259             {
 3260                 if(is_array($rule))
 3261                     $this->_rules[$i]=$rule=Yii::createComponent($rule);
 3262                 if(($r=$rule->parseUrl($this,$request,$pathInfo,$rawPathInfo))!==false)
 3263                     return isset($_GET[$this->routeVar]) ? $_GET[$this->routeVar] : $r;
 3264             }
 3265             if($this->useStrictParsing)
 3266                 throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
 3267                     array('{route}'=>$pathInfo)));
 3268             else
 3269                 return $pathInfo;
 3270         }
 3271         elseif(isset($_GET[$this->routeVar]))
 3272             return $_GET[$this->routeVar];
 3273         elseif(isset($_POST[$this->routeVar]))
 3274             return $_POST[$this->routeVar];
 3275         else
 3276             return '';
 3277     }
 3278     public function parsePathInfo($pathInfo)
 3279     {
 3280         if($pathInfo==='')
 3281             return;
 3282         $segs=explode('/',$pathInfo.'/');
 3283         $n=count($segs);
 3284         for($i=0;$i<$n-1;$i+=2)
 3285         {
 3286             $key=$segs[$i];
 3287             if($key==='') continue;
 3288             $value=$segs[$i+1];
 3289             if(($pos=strpos($key,'['))!==false && ($m=preg_match_all('/\[(.*?)\]/',$key,$matches))>0)
 3290             {
 3291                 $name=substr($key,0,$pos);
 3292                 for($j=$m-1;$j>=0;--$j)
 3293                 {
 3294                     if($matches[1][$j]==='')
 3295                         $value=array($value);
 3296                     else
 3297                         $value=array($matches[1][$j]=>$value);
 3298                 }
 3299                 if(isset($_GET[$name]) && is_array($_GET[$name]))
 3300                     $value=CMap::mergeArray($_GET[$name],$value);
 3301                 $_REQUEST[$name]=$_GET[$name]=$value;
 3302             }
 3303             else
 3304                 $_REQUEST[$key]=$_GET[$key]=$value;
 3305         }
 3306     }
 3307     public function createPathInfo($params,$equal,$ampersand, $key=null)
 3308     {
 3309         $pairs = array();
 3310         foreach($params as $k => $v)
 3311         {
 3312             if ($key!==null)
 3313                 $k = $key.'['.$k.']';
 3314             if (is_array($v))
 3315                 $pairs[]=$this->createPathInfo($v,$equal,$ampersand, $k);
 3316             else
 3317                 $pairs[]=urlencode($k).$equal.urlencode($v);
 3318         }
 3319         return implode($ampersand,$pairs);
 3320     }
 3321     public function removeUrlSuffix($pathInfo,$urlSuffix)
 3322     {
 3323         if($urlSuffix!=='' && substr($pathInfo,-strlen($urlSuffix))===$urlSuffix)
 3324             return substr($pathInfo,0,-strlen($urlSuffix));
 3325         else
 3326             return $pathInfo;
 3327     }
 3328     public function getBaseUrl()
 3329     {
 3330         if($this->_baseUrl!==null)
 3331             return $this->_baseUrl;
 3332         else
 3333         {
 3334             if($this->showScriptName)
 3335                 $this->_baseUrl=Yii::app()->getRequest()->getScriptUrl();
 3336             else
 3337                 $this->_baseUrl=Yii::app()->getRequest()->getBaseUrl();
 3338             return $this->_baseUrl;
 3339         }
 3340     }
 3341     public function setBaseUrl($value)
 3342     {
 3343         $this->_baseUrl=$value;
 3344     }
 3345     public function getUrlFormat()
 3346     {
 3347         return $this->_urlFormat;
 3348     }
 3349     public function setUrlFormat($value)
 3350     {
 3351         if($value===self::PATH_FORMAT || $value===self::GET_FORMAT)
 3352             $this->_urlFormat=$value;
 3353         else
 3354             throw new CException(Yii::t('yii','CUrlManager.UrlFormat must be either "path" or "get".'));
 3355     }
 3356 }
 3357 abstract class CBaseUrlRule extends CComponent
 3358 {
 3359     public $hasHostInfo=false;
 3360     abstract public function createUrl($manager,$route,$params,$ampersand);
 3361     abstract public function parseUrl($manager,$request,$pathInfo,$rawPathInfo);
 3362 }
 3363 class CUrlRule extends CBaseUrlRule
 3364 {
 3365     public $urlSuffix;
 3366     public $caseSensitive;
 3367     public $defaultParams=array();
 3368     public $matchValue;
 3369     public $verb;
 3370     public $parsingOnly=false;
 3371     public $route;
 3372     public $references=array();
 3373     public $routePattern;
 3374     public $pattern;
 3375     public $template;
 3376     public $params=array();
 3377     public $append;
 3378     public $hasHostInfo;
 3379     protected function escapeRegexpSpecialChars($matches)
 3380     {
 3381         return preg_quote($matches[0]);
 3382     }
 3383     public function __construct($route,$pattern)
 3384     {
 3385         if(is_array($route))
 3386         {
 3387             foreach(array('urlSuffix', 'caseSensitive', 'defaultParams', 'matchValue', 'verb', 'parsingOnly') as $name)
 3388             {
 3389                 if(isset($route[$name]))
 3390                     $this->$name=$route[$name];
 3391             }
 3392             if(isset($route['pattern']))
 3393                 $pattern=$route['pattern'];
 3394             $route=$route[0];
 3395         }
 3396         $this->route=trim($route,'/');
 3397         $tr2['/']=$tr['/']='\\/';
 3398         if(strpos($route,'<')!==false && preg_match_all('/<(\w+)>/',$route,$matches2))
 3399         {
 3400             foreach($matches2[1] as $name)
 3401                 $this->references[$name]="<$name>";
 3402         }
 3403         $this->hasHostInfo=!strncasecmp($pattern,'http://',7) || !strncasecmp($pattern,'https://',8);
 3404         if($this->verb!==null)
 3405             $this->verb=preg_split('/[\s,]+/',strtoupper($this->verb),-1,PREG_SPLIT_NO_EMPTY);
 3406         if(preg_match_all('/<(\w+):?(.*?)?>/',$pattern,$matches))
 3407         {
 3408             $tokens=array_combine($matches[1],$matches[2]);
 3409             foreach($tokens as $name=>$value)
 3410             {
 3411                 if($value==='')
 3412                     $value='[^\/]+';
 3413                 $tr["<$name>"]="(?P<$name>$value)";
 3414                 if(isset($this->references[$name]))
 3415                     $tr2["<$name>"]=$tr["<$name>"];
 3416                 else
 3417                     $this->params[$name]=$value;
 3418             }
 3419         }
 3420         $p=rtrim($pattern,'*');
 3421         $this->append=$p!==$pattern;
 3422         $p=trim($p,'/');
 3423         $this->template=preg_replace('/<(\w+):?.*?>/','<$1>',$p);
 3424         $p=$this->template;
 3425         if(!$this->parsingOnly)
 3426             $p=preg_replace_callback('/(?<=^|>)[^<]+(?=<|$)/',array($this,'escapeRegexpSpecialChars'),$p);
 3427         $this->pattern='/^'.strtr($p,$tr).'\/';
 3428         if($this->append)
 3429             $this->pattern.='/u';
 3430         else
 3431             $this->pattern.='$/u';
 3432         if($this->references!==array())
 3433             $this->routePattern='/^'.strtr($this->route,$tr2).'$/u';
 3434         if(YII_DEBUG && @preg_match($this->pattern,'test')===false)
 3435             throw new CException(Yii::t('yii','The URL pattern "{pattern}" for route "{route}" is not a valid regular expression.',
 3436                 array('{route}'=>$route,'{pattern}'=>$pattern)));
 3437     }
 3438     public function createUrl($manager,$route,$params,$ampersand)
 3439     {
 3440         if($this->parsingOnly)
 3441             return false;
 3442         if($manager->caseSensitive && $this->caseSensitive===null || $this->caseSensitive)
 3443             $case='';
 3444         else
 3445             $case='i';
 3446         $tr=array();
 3447         if($route!==$this->route)
 3448         {
 3449             if($this->routePattern!==null && preg_match($this->routePattern.$case,$route,$matches))
 3450             {
 3451                 foreach($this->references as $key=>$name)
 3452                     $tr[$name]=$matches[$key];
 3453             }
 3454             else
 3455                 return false;
 3456         }
 3457         foreach($this->defaultParams as $key=>$value)
 3458         {
 3459             if(isset($params[$key]))
 3460             {
 3461                 if($params[$key]==$value)
 3462                     unset($params[$key]);
 3463                 else
 3464                     return false;
 3465             }
 3466         }
 3467         foreach($this->params as $key=>$value)
 3468             if(!isset($params[$key]))
 3469                 return false;
 3470         if($manager->matchValue && $this->matchValue===null || $this->matchValue)
 3471         {
 3472             foreach($this->params as $key=>$value)
 3473             {
 3474                 if(!preg_match('/\A'.$value.'\z/u'.$case,$params[$key]))
 3475                     return false;
 3476             }
 3477         }
 3478         foreach($this->params as $key=>$value)
 3479         {
 3480             $tr["<$key>"]=urlencode($params[$key]);
 3481             unset($params[$key]);
 3482         }
 3483         $suffix=$this->urlSuffix===null ? $manager->urlSuffix : $this->urlSuffix;
 3484         $url=strtr($this->template,$tr);
 3485         if($this->hasHostInfo)
 3486         {
 3487             $hostInfo=Yii::app()->getRequest()->getHostInfo();
 3488             if(stripos($url,$hostInfo)===0)
 3489                 $url=substr($url,strlen($hostInfo));
 3490         }
 3491         if(empty($params))
 3492             return $url!=='' ? $url.$suffix : $url;
 3493         if($this->append)
 3494             $url.='/'.$manager->createPathInfo($params,'/','/').$suffix;
 3495         else
 3496         {
 3497             if($url!=='')
 3498                 $url.=$suffix;
 3499             $url.='?'.$manager->createPathInfo($params,'=',$ampersand);
 3500         }
 3501         return $url;
 3502     }
 3503     public function parseUrl($manager,$request,$pathInfo,$rawPathInfo)
 3504     {
 3505         if($this->verb!==null && !in_array($request->getRequestType(), $this->verb, true))
 3506             return false;
 3507         if($manager->caseSensitive && $this->caseSensitive===null || $this->caseSensitive)
 3508             $case='';
 3509         else
 3510             $case='i';
 3511         if($this->urlSuffix!==null)
 3512             $pathInfo=$manager->removeUrlSuffix($rawPathInfo,$this->urlSuffix);
 3513         // URL suffix required, but not found in the requested URL
 3514         if($manager->useStrictParsing && $pathInfo===$rawPathInfo)
 3515         {
 3516             $urlSuffix=$this->urlSuffix===null ? $manager->urlSuffix : $this->urlSuffix;
 3517             if($urlSuffix!='' && $urlSuffix!=='/')
 3518                 return false;
 3519         }
 3520         if($this->hasHostInfo)
 3521             $pathInfo=strtolower($request->getHostInfo()).rtrim('/'.$pathInfo,'/');
 3522         $pathInfo.='/';
 3523         if(preg_match($this->pattern.$case,$pathInfo,$matches))
 3524         {
 3525             foreach($this->defaultParams as $name=>$value)
 3526             {
 3527                 if(!isset($_GET[$name]))
 3528                     $_REQUEST[$name]=$_GET[$name]=$value;
 3529             }
 3530             $tr=array();
 3531             foreach($matches as $key=>$value)
 3532             {
 3533                 if(isset($this->references[$key]))
 3534                     $tr[$this->references[$key]]=$value;
 3535                 elseif(isset($this->params[$key]))
 3536                     $_REQUEST[$key]=$_GET[$key]=$value;
 3537             }
 3538             if($pathInfo!==$matches[0]) // there're additional GET params
 3539                 $manager->parsePathInfo(ltrim(substr($pathInfo,strlen($matches[0])),'/'));
 3540             if($this->routePattern!==null)
 3541                 return strtr($this->route,$tr);
 3542             else
 3543                 return $this->route;
 3544         }
 3545         else
 3546             return false;
 3547     }
 3548 }
 3549 abstract class CBaseController extends CComponent
 3550 {
 3551     private $_widgetStack=array();
 3552     abstract public function getViewFile($viewName);
 3553     public function renderFile($viewFile,$data=null,$return=false)
 3554     {
 3555         $widgetCount=count($this->_widgetStack);
 3556         if(($renderer=Yii::app()->getViewRenderer())!==null && $renderer->fileExtension==='.'.CFileHelper::getExtension($viewFile))
 3557             $content=$renderer->renderFile($this,$viewFile,$data,$return);
 3558         else
 3559             $content=$this->renderInternal($viewFile,$data,$return);
 3560         if(count($this->_widgetStack)===$widgetCount)
 3561             return $content;
 3562         else
 3563         {
 3564             $widget=end($this->_widgetStack);
 3565             throw new CException(Yii::t('yii','{controller} contains improperly nested widget tags in its view "{view}". A {widget} widget does not have an endWidget() call.',
 3566                 array('{controller}'=>get_class($this), '{view}'=>$viewFile, '{widget}'=>get_class($widget))));
 3567         }
 3568     }
 3569     public function renderInternal($_viewFile_,$_data_=null,$_return_=false)
 3570     {
 3571         // we use special variable names here to avoid conflict when extracting data
 3572         if(is_array($_data_))
 3573             extract($_data_,EXTR_PREFIX_SAME,'data');
 3574         else
 3575             $data=$_data_;
 3576         if($_return_)
 3577         {
 3578             ob_start();
 3579             ob_implicit_flush(false);
 3580             require($_viewFile_);
 3581             return ob_get_clean();
 3582         }
 3583         else
 3584             require($_viewFile_);
 3585     }
 3586     public function createWidget($className,$properties=array())
 3587     {
 3588         $widget=Yii::app()->getWidgetFactory()->createWidget($this,$className,$properties);
 3589         $widget->init();
 3590         return $widget;
 3591     }
 3592     public function widget($className,$properties=array(),$captureOutput=false)
 3593     {
 3594         if($captureOutput)
 3595         {
 3596             ob_start();
 3597             ob_implicit_flush(false);
 3598             try
 3599             {
 3600                 $widget=$this->createWidget($className,$properties);
 3601                 $widget->run();
 3602             }
 3603             catch(Exception $e)
 3604             {
 3605                 ob_end_clean();
 3606                 throw $e;
 3607             }
 3608             return ob_get_clean();
 3609         }
 3610         else
 3611         {
 3612             $widget=$this->createWidget($className,$properties);
 3613             $widget->run();
 3614             return $widget;
 3615         }
 3616     }
 3617     public function beginWidget($className,$properties=array())
 3618     {
 3619         $widget=$this->createWidget($className,$properties);
 3620         $this->_widgetStack[]=$widget;
 3621         return $widget;
 3622     }
 3623     public function endWidget($id='')
 3624     {
 3625         if(($widget=array_pop($this->_widgetStack))!==null)
 3626         {
 3627             $widget->run();
 3628             return $widget;
 3629         }
 3630         else
 3631             throw new CException(Yii::t('yii','{controller} has an extra endWidget({id}) call in its view.',
 3632                 array('{controller}'=>get_class($this),'{id}'=>$id)));
 3633     }
 3634     public function beginClip($id,$properties=array())
 3635     {
 3636         $properties['id']=$id;
 3637         $this->beginWidget('CClipWidget',$properties);
 3638     }
 3639     public function endClip()
 3640     {
 3641         $this->endWidget('CClipWidget');
 3642     }
 3643     public function beginCache($id,$properties=array())
 3644     {
 3645         $properties['id']=$id;
 3646         $cache=$this->beginWidget('COutputCache',$properties);
 3647         if($cache->getIsContentCached())
 3648         {
 3649             $this->endCache();
 3650             return false;
 3651         }
 3652         else
 3653             return true;
 3654     }
 3655     public function endCache()
 3656     {
 3657         $this->endWidget('COutputCache');
 3658     }
 3659     public function beginContent($view=null,$data=array())
 3660     {
 3661         $this->beginWidget('CContentDecorator',array('view'=>$view, 'data'=>$data));
 3662     }
 3663     public function endContent()
 3664     {
 3665         $this->endWidget('CContentDecorator');
 3666     }
 3667 }
 3668 class CController extends CBaseController
 3669 {
 3670     const STATE_INPUT_NAME='YII_PAGE_STATE';
 3671     public $layout;
 3672     public $defaultAction='index';
 3673     private $_id;
 3674     private $_action;
 3675     private $_pageTitle;
 3676     private $_cachingStack;
 3677     private $_clips;
 3678     private $_dynamicOutput;
 3679     private $_pageStates;
 3680     private $_module;
 3681     public function __construct($id,$module=null)
 3682     {
 3683         $this->_id=$id;
 3684         $this->_module=$module;
 3685         $this->attachBehaviors($this->behaviors());
 3686     }
 3687     public function init()
 3688     {
 3689     }
 3690     public function filters()
 3691     {
 3692         return array();
 3693     }
 3694     public function actions()
 3695     {
 3696         return array();
 3697     }
 3698     public function behaviors()
 3699     {
 3700         return array();
 3701     }
 3702     public function accessRules()
 3703     {
 3704         return array();
 3705     }
 3706     public function run($actionID)
 3707     {
 3708         if(($action=$this->createAction($actionID))!==null)
 3709         {
 3710             if(($parent=$this->getModule())===null)
 3711                 $parent=Yii::app();
 3712             if($parent->beforeControllerAction($this,$action))
 3713             {
 3714                 $this->runActionWithFilters($action,$this->filters());
 3715                 $parent->afterControllerAction($this,$action);
 3716             }
 3717         }
 3718         else
 3719             $this->missingAction($actionID);
 3720     }
 3721     public function runActionWithFilters($action,$filters)
 3722     {
 3723         if(empty($filters))
 3724             $this->runAction($action);
 3725         else
 3726         {
 3727             $priorAction=$this->_action;
 3728             $this->_action=$action;
 3729             CFilterChain::create($this,$action,$filters)->run();
 3730             $this->_action=$priorAction;
 3731         }
 3732     }
 3733     public function runAction($action)
 3734     {
 3735         $priorAction=$this->_action;
 3736         $this->_action=$action;
 3737         if($this->beforeAction($action))
 3738         {
 3739             if($action->runWithParams($this->getActionParams())===false)
 3740                 $this->invalidActionParams($action);
 3741             else
 3742                 $this->afterAction($action);
 3743         }
 3744         $this->_action=$priorAction;
 3745     }
 3746     public function getActionParams()
 3747     {
 3748         return $_GET;
 3749     }
 3750     public function invalidActionParams($action)
 3751     {
 3752         throw new CHttpException(400,Yii::t('yii','Your request is invalid.'));
 3753     }
 3754     public function processOutput($output)
 3755     {
 3756         Yii::app()->getClientScript()->render($output);
 3757         // if using page caching, we should delay dynamic output replacement
 3758         if($this->_dynamicOutput!==null && $this->isCachingStackEmpty())
 3759         {
 3760             $output=$this->processDynamicOutput($output);
 3761             $this->_dynamicOutput=null;
 3762         }
 3763         if($this->_pageStates===null)
 3764             $this->_pageStates=$this->loadPageStates();
 3765         if(!empty($this->_pageStates))
 3766             $this->savePageStates($this->_pageStates,$output);
 3767         return $output;
 3768     }
 3769     public function processDynamicOutput($output)
 3770     {
 3771         if($this->_dynamicOutput)
 3772         {
 3773             $output=preg_replace_callback('/<###dynamic-(\d+)###>/',array($this,'replaceDynamicOutput'),$output);
 3774         }
 3775         return $output;
 3776     }
 3777     protected function replaceDynamicOutput($matches)
 3778     {
 3779         $content=$matches[0];
 3780         if(isset($this->_dynamicOutput[$matches[1]]))
 3781         {
 3782             $content=$this->_dynamicOutput[$matches[1]];
 3783             $this->_dynamicOutput[$matches[1]]=null;
 3784         }
 3785         return $content;
 3786     }
 3787     public function createAction($actionID)
 3788     {
 3789         if($actionID==='')
 3790             $actionID=$this->defaultAction;
 3791         if(method_exists($this,'action'.$actionID) && strcasecmp($actionID,'s')) // we have actions method
 3792             return new CInlineAction($this,$actionID);
 3793         else
 3794         {
 3795             $action=$this->createActionFromMap($this->actions(),$actionID,$actionID);
 3796             if($action!==null && !method_exists($action,'run'))
 3797                 throw new CException(Yii::t('yii', 'Action class {class} must implement the "run" method.', array('{class}'=>get_class($action))));
 3798             return $action;
 3799         }
 3800     }
 3801     protected function createActionFromMap($actionMap,$actionID,$requestActionID,$config=array())
 3802     {
 3803         if(($pos=strpos($actionID,'.'))===false && isset($actionMap[$actionID]))
 3804         {
 3805             $baseConfig=is_array($actionMap[$actionID]) ? $actionMap[$actionID] : array('class'=>$actionMap[$actionID]);
 3806             return Yii::createComponent(empty($config)?$baseConfig:array_merge($baseConfig,$config),$this,$requestActionID);
 3807         }
 3808         elseif($pos===false)
 3809             return null;
 3810         // the action is defined in a provider
 3811         $prefix=substr($actionID,0,$pos+1);
 3812         if(!isset($actionMap[$prefix]))
 3813             return null;
 3814         $actionID=(string)substr($actionID,$pos+1);
 3815         $provider=$actionMap[$prefix];
 3816         if(is_string($provider))
 3817             $providerType=$provider;
 3818         elseif(is_array($provider) && isset($provider['class']))
 3819         {
 3820             $providerType=$provider['class'];
 3821             if(isset($provider[$actionID]))
 3822             {
 3823                 if(is_string($provider[$actionID]))
 3824                     $config=array_merge(array('class'=>$provider[$actionID]),$config);
 3825                 else
 3826                     $config=array_merge($provider[$actionID],$config);
 3827             }
 3828         }
 3829         else
 3830             throw new CException(Yii::t('yii','Object configuration must be an array containing a "class" element.'));
 3831         $class=Yii::import($providerType,true);
 3832         $map=call_user_func(array($class,'actions'));
 3833         return $this->createActionFromMap($map,$actionID,$requestActionID,$config);
 3834     }
 3835     public function missingAction($actionID)
 3836     {
 3837         throw new CHttpException(404,Yii::t('yii','The system is unable to find the requested action "{action}".',
 3838             array('{action}'=>$actionID==''?$this->defaultAction:$actionID)));
 3839     }
 3840     public function getAction()
 3841     {
 3842         return $this->_action;
 3843     }
 3844     public function setAction($value)
 3845     {
 3846         $this->_action=$value;
 3847     }
 3848     public function getId()
 3849     {
 3850         return $this->_id;
 3851     }
 3852     public function getUniqueId()
 3853     {
 3854         return $this->_module ? $this->_module->getId().'/'.$this->_id : $this->_id;
 3855     }
 3856     public function getRoute()
 3857     {
 3858         if(($action=$this->getAction())!==null)
 3859             return $this->getUniqueId().'/'.$action->getId();
 3860         else
 3861             return $this->getUniqueId();
 3862     }
 3863     public function getModule()
 3864     {
 3865         return $this->_module;
 3866     }
 3867     public function getViewPath()
 3868     {
 3869         if(($module=$this->getModule())===null)
 3870             $module=Yii::app();
 3871         return $module->getViewPath().DIRECTORY_SEPARATOR.$this->getId();
 3872     }
 3873     public function getViewFile($viewName)
 3874     {
 3875         if(($theme=Yii::app()->getTheme())!==null && ($viewFile=$theme->getViewFile($this,$viewName))!==false)
 3876             return $viewFile;
 3877         $moduleViewPath=$basePath=Yii::app()->getViewPath();
 3878         if(($module=$this->getModule())!==null)
 3879             $moduleViewPath=$module->getViewPath();
 3880         return $this->resolveViewFile($viewName,$this->getViewPath(),$basePath,$moduleViewPath);
 3881     }
 3882     public function getLayoutFile($layoutName)
 3883     {
 3884         if($layoutName===false)
 3885             return false;
 3886         if(($theme=Yii::app()->getTheme())!==null && ($layoutFile=$theme->getLayoutFile($this,$layoutName))!==false)
 3887             return $layoutFile;
 3888         if(empty($layoutName))
 3889         {
 3890             $module=$this->getModule();
 3891             while($module!==null)
 3892             {
 3893                 if($module->layout===false)
 3894                     return false;
 3895                 if(!empty($module->layout))
 3896                     break;
 3897                 $module=$module->getParentModule();
 3898             }
 3899             if($module===null)
 3900                 $module=Yii::app();
 3901             $layoutName=$module->layout;
 3902         }
 3903         elseif(($module=$this->getModule())===null)
 3904             $module=Yii::app();
 3905         return $this->resolveViewFile($layoutName,$module->getLayoutPath(),Yii::app()->getViewPath(),$module->getViewPath());
 3906     }
 3907     public function resolveViewFile($viewName,$viewPath,$basePath,$moduleViewPath=null)
 3908     {
 3909         if(empty($viewName))
 3910             return false;
 3911         if($moduleViewPath===null)
 3912             $moduleViewPath=$basePath;
 3913         if(($renderer=Yii::app()->getViewRenderer())!==null)
 3914             $extension=$renderer->fileExtension;
 3915         else
 3916             $extension='.php';
 3917         if($viewName[0]==='/')
 3918         {
 3919             if(strncmp($viewName,'//',2)===0)
 3920                 $viewFile=$basePath.$viewName;
 3921             else
 3922                 $viewFile=$moduleViewPath.$viewName;
 3923         }
 3924         elseif(strpos($viewName,'.'))
 3925             $viewFile=Yii::getPathOfAlias($viewName);
 3926         else
 3927             $viewFile=$viewPath.DIRECTORY_SEPARATOR.$viewName;
 3928         if(is_file($viewFile.$extension))
 3929             return Yii::app()->findLocalizedFile($viewFile.$extension);
 3930         elseif($extension!=='.php' && is_file($viewFile.'.php'))
 3931             return Yii::app()->findLocalizedFile($viewFile.'.php');
 3932         else
 3933             return false;
 3934     }
 3935     public function getClips()
 3936     {
 3937         if($this->_clips!==null)
 3938             return $this->_clips;
 3939         else
 3940             return $this->_clips=new CMap;
 3941     }
 3942     public function forward($route,$exit=true)
 3943     {
 3944         if(strpos($route,'/')===false)
 3945             $this->run($route);
 3946         else
 3947         {
 3948             if($route[0]!=='/' && ($module=$this->getModule())!==null)
 3949                 $route=$module->getId().'/'.$route;
 3950             Yii::app()->runController($route);
 3951         }
 3952         if($exit)
 3953             Yii::app()->end();
 3954     }
 3955     public function render($view,$data=null,$return=false)
 3956     {
 3957         if($this->beforeRender($view))
 3958         {
 3959             $output=$this->renderPartial($view,$data,true);
 3960             if(($layoutFile=$this->getLayoutFile($this->layout))!==false)
 3961                 $output=$this->renderFile($layoutFile,array('content'=>$output),true);
 3962             $this->afterRender($view,$output);
 3963             $output=$this->processOutput($output);
 3964             if($return)
 3965                 return $output;
 3966             else
 3967                 echo $output;
 3968         }
 3969     }
 3970     protected function beforeRender($view)
 3971     {
 3972         return true;
 3973     }
 3974     protected function afterRender($view, &$output)
 3975     {
 3976     }
 3977     public function renderText($text,$return=false)
 3978     {
 3979         if(($layoutFile=$this->getLayoutFile($this->layout))!==false)
 3980             $text=$this->renderFile($layoutFile,array('content'=>$text),true);
 3981         $text=$this->processOutput($text);
 3982         if($return)
 3983             return $text;
 3984         else
 3985             echo $text;
 3986     }
 3987     public function renderPartial($view,$data=null,$return=false,$processOutput=false)
 3988     {
 3989         if(($viewFile=$this->getViewFile($view))!==false)
 3990         {
 3991             $output=$this->renderFile($viewFile,$data,true);
 3992             if($processOutput)
 3993                 $output=$this->processOutput($output);
 3994             if($return)
 3995                 return $output;
 3996             else
 3997                 echo $output;
 3998         }
 3999         else
 4000             throw new CException(Yii::t('yii','{controller} cannot find the requested view "{view}".',
 4001                 array('{controller}'=>get_class($this), '{view}'=>$view)));
 4002     }
 4003     public function renderClip($name,$params=array(),$return=false)
 4004     {
 4005         $text=isset($this->clips[$name]) ? strtr($this->clips[$name], $params) : '';
 4006         if($return)
 4007             return $text;
 4008         else
 4009             echo $text;
 4010     }
 4011     public function renderDynamic($callback)
 4012     {
 4013         $n=($this->_dynamicOutput === null ? 0 : count($this->_dynamicOutput));
 4014         echo "<###dynamic-$n###>";
 4015         $params=func_get_args();
 4016         array_shift($params);
 4017         $this->renderDynamicInternal($callback,$params);
 4018     }
 4019     public function renderDynamicInternal($callback,$params)
 4020     {
 4021         $this->recordCachingAction('','renderDynamicInternal',array($callback,$params));
 4022         if(is_string($callback) && method_exists($this,$callback))
 4023             $callback=array($this,$callback);
 4024         $this->_dynamicOutput[]=call_user_func_array($callback,$params);
 4025     }
 4026     public function createUrl($route,$params=array(),$ampersand='&')
 4027     {
 4028         if($route==='')
 4029             $route=$this->getId().'/'.$this->getAction()->getId();
 4030         elseif(strpos($route,'/')===false)
 4031             $route=$this->getId().'/'.$route;
 4032         if($route[0]!=='/' && ($module=$this->getModule())!==null)
 4033             $route=$module->getId().'/'.$route;
 4034         return Yii::app()->createUrl(trim($route,'/'),$params,$ampersand);
 4035     }
 4036     public function createAbsoluteUrl($route,$params=array(),$schema='',$ampersand='&')
 4037     {
 4038         $url=$this->createUrl($route,$params,$ampersand);
 4039         if(strpos($url,'http')===0)
 4040             return $url;
 4041         else
 4042             return Yii::app()->getRequest()->getHostInfo($schema).$url;
 4043     }
 4044     public function getPageTitle()
 4045     {
 4046         if($this->_pageTitle!==null)
 4047             return $this->_pageTitle;
 4048         else
 4049         {
 4050             $name=ucfirst(basename($this->getId()));
 4051             if($this->getAction()!==null && strcasecmp($this->getAction()->getId(),$this->defaultAction))
 4052                 return $this->_pageTitle=Yii::app()->name.' - '.ucfirst($this->getAction()->getId()).' '.$name;
 4053             else
 4054                 return $this->_pageTitle=Yii::app()->name.' - '.$name;
 4055         }
 4056     }
 4057     public function setPageTitle($value)
 4058     {
 4059         $this->_pageTitle=$value;
 4060     }
 4061     public function redirect($url,$terminate=true,$statusCode=302)
 4062     {
 4063         if(is_array($url))
 4064         {
 4065             $route=isset($url[0]) ? $url[0] : '';
 4066             $url=$this->createUrl($route,array_splice($url,1));
 4067         }
 4068         Yii::app()->getRequest()->redirect($url,$terminate,$statusCode);
 4069     }
 4070     public function refresh($terminate=true,$anchor='')
 4071     {
 4072         $this->redirect(Yii::app()->getRequest()->getUrl().$anchor,$terminate);
 4073     }
 4074     public function recordCachingAction($context,$method,$params)
 4075     {
 4076         if($this->_cachingStack) // record only when there is an active output cache
 4077         {
 4078             foreach($this->_cachingStack as $cache)
 4079                 $cache->recordAction($context,$method,$params);
 4080         }
 4081     }
 4082     public function getCachingStack($createIfNull=true)
 4083     {
 4084         if(!$this->_cachingStack)
 4085             $this->_cachingStack=new CStack;
 4086         return $this->_cachingStack;
 4087     }
 4088     public function isCachingStackEmpty()
 4089     {
 4090         return $this->_cachingStack===null || !$this->_cachingStack->getCount();
 4091     }
 4092     protected function beforeAction($action)
 4093     {
 4094         return true;
 4095     }
 4096     protected function afterAction($action)
 4097     {
 4098     }
 4099     public function filterPostOnly($filterChain)
 4100     {
 4101         if(Yii::app()->getRequest()->getIsPostRequest())
 4102             $filterChain->run();
 4103         else
 4104             throw new CHttpException(400,Yii::t('yii','Your request is invalid.'));
 4105     }
 4106     public function filterAjaxOnly($filterChain)
 4107     {
 4108         if(Yii::app()->getRequest()->getIsAjaxRequest())
 4109             $filterChain->run();
 4110         else
 4111             throw new CHttpException(400,Yii::t('yii','Your request is invalid.'));
 4112     }
 4113     public function filterAccessControl($filterChain)
 4114     {
 4115         $filter=new CAccessControlFilter;
 4116         $filter->setRules($this->accessRules());
 4117         $filter->filter($filterChain);
 4118     }
 4119     public function getPageState($name,$defaultValue=null)
 4120     {
 4121         if($this->_pageStates===null)
 4122             $this->_pageStates=$this->loadPageStates();
 4123         return isset($this->_pageStates[$name])?$this->_pageStates[$name]:$defaultValue;
 4124     }
 4125     public function setPageState($name,$value,$defaultValue=null)
 4126     {
 4127         if($this->_pageStates===null)
 4128             $this->_pageStates=$this->loadPageStates();
 4129         if($value===$defaultValue)
 4130             unset($this->_pageStates[$name]);
 4131         else
 4132             $this->_pageStates[$name]=$value;
 4133         $params=func_get_args();
 4134         $this->recordCachingAction('','setPageState',$params);
 4135     }
 4136     public function clearPageStates()
 4137     {
 4138         $this->_pageStates=array();
 4139     }
 4140     protected function loadPageStates()
 4141     {
 4142         if(!empty($_POST[self::STATE_INPUT_NAME]))
 4143         {
 4144             if(($data=base64_decode($_POST[self::STATE_INPUT_NAME]))!==false)
 4145             {
 4146                 if(extension_loaded('zlib'))
 4147                     $data=@gzuncompress($data);
 4148                 if(($data=Yii::app()->getSecurityManager()->validateData($data))!==false)
 4149                     return unserialize($data);
 4150             }
 4151         }
 4152         return array();
 4153     }
 4154     protected function savePageStates($states,&$output)
 4155     {
 4156         $data=Yii::app()->getSecurityManager()->hashData(serialize($states));
 4157         if(extension_loaded('zlib'))
 4158             $data=gzcompress($data);
 4159         $value=base64_encode($data);
 4160         $output=str_replace(CHtml::pageStateField(''),CHtml::pageStateField($value),$output);
 4161     }
 4162 }
 4163 abstract class CAction extends CComponent implements IAction
 4164 {
 4165     private $_id;
 4166     private $_controller;
 4167     public function __construct($controller,$id)
 4168     {
 4169         $this->_controller=$controller;
 4170         $this->_id=$id;
 4171     }
 4172     public function getController()
 4173     {
 4174         return $this->_controller;
 4175     }
 4176     public function getId()
 4177     {
 4178         return $this->_id;
 4179     }
 4180     public function runWithParams($params)
 4181     {
 4182         $method=new ReflectionMethod($this, 'run');
 4183         if($method->getNumberOfParameters()>0)
 4184             return $this->runWithParamsInternal($this, $method, $params);
 4185         $this->run();
 4186         return true;
 4187     }
 4188     protected function runWithParamsInternal($object, $method, $params)
 4189     {
 4190         $ps=array();
 4191         foreach($method->getParameters() as $i=>$param)
 4192         {
 4193             $name=$param->getName();
 4194             if(isset($params[$name]))
 4195             {
 4196                 if($param->isArray())
 4197                     $ps[]=is_array($params[$name]) ? $params[$name] : array($params[$name]);
 4198                 elseif(!is_array($params[$name]))
 4199                     $ps[]=$params[$name];
 4200                 else
 4201                     return false;
 4202             }
 4203             elseif($param->isDefaultValueAvailable())
 4204                 $ps[]=$param->getDefaultValue();
 4205             else
 4206                 return false;
 4207         }
 4208         $method->invokeArgs($object,$ps);
 4209         return true;
 4210     }
 4211 }
 4212 class CInlineAction extends CAction
 4213 {
 4214     public function run()
 4215     {
 4216         $method='action'.$this->getId();
 4217         $this->getController()->$method();
 4218     }
 4219     public function runWithParams($params)
 4220     {
 4221         $methodName='action'.$this->getId();
 4222         $controller=$this->getController();
 4223         $method=new ReflectionMethod($controller, $methodName);
 4224         if($method->getNumberOfParameters()>0)
 4225             return $this->runWithParamsInternal($controller, $method, $params);
 4226         $controller->$methodName();
 4227         return true;
 4228     }
 4229 }
 4230 class CWebUser extends CApplicationComponent implements IWebUser
 4231 {
 4232     const FLASH_KEY_PREFIX='Yii.CWebUser.flash.';
 4233     const FLASH_COUNTERS='Yii.CWebUser.flashcounters';
 4234     const STATES_VAR='__states';
 4235     const AUTH_TIMEOUT_VAR='__timeout';
 4236     const AUTH_ABSOLUTE_TIMEOUT_VAR='__absolute_timeout';
 4237     public $allowAutoLogin=false;
 4238     public $guestName='Guest';
 4239     public $loginUrl=array('/site/login');
 4240     public $identityCookie;
 4241     public $authTimeout;
 4242     public $absoluteAuthTimeout;
 4243     public $autoRenewCookie=false;
 4244     public $autoUpdateFlash=true;
 4245     public $loginRequiredAjaxResponse;
 4246     private $_keyPrefix;
 4247     private $_access=array();
 4248     public function __get($name)
 4249     {
 4250         if($this->hasState($name))
 4251             return $this->getState($name);
 4252         else
 4253             return parent::__get($name);
 4254     }
 4255     public function __set($name,$value)
 4256     {
 4257         if($this->hasState($name))
 4258             $this->setState($name,$value);
 4259         else
 4260             parent::__set($name,$value);
 4261     }
 4262     public function __isset($name)
 4263     {
 4264         if($this->hasState($name))
 4265             return $this->getState($name)!==null;
 4266         else
 4267             return parent::__isset($name);
 4268     }
 4269     public function __unset($name)
 4270     {
 4271         if($this->hasState($name))
 4272             $this->setState($name,null);
 4273         else
 4274             parent::__unset($name);
 4275     }
 4276     public function init()
 4277     {
 4278         parent::init();
 4279         Yii::app()->getSession()->open();
 4280         if($this->getIsGuest() && $this->allowAutoLogin)
 4281             $this->restoreFromCookie();
 4282         elseif($this->autoRenewCookie && $this->allowAutoLogin)
 4283             $this->renewCookie();
 4284         if($this->autoUpdateFlash)
 4285             $this->updateFlash();
 4286         $this->updateAuthStatus();
 4287     }
 4288     public function login($identity,$duration=0)
 4289     {
 4290         $id=$identity->getId();
 4291         $states=$identity->getPersistentStates();
 4292         if($this->beforeLogin($id,$states,false))
 4293         {
 4294             $this->changeIdentity($id,$identity->getName(),$states);
 4295             if($duration>0)
 4296             {
 4297                 if($this->allowAutoLogin)
 4298                     $this->saveToCookie($duration);
 4299                 else
 4300                     throw new CException(Yii::t('yii','{class}.allowAutoLogin must be set true in order to use cookie-based authentication.',
 4301                         array('{class}'=>get_class($this))));
 4302             }
 4303             if ($this->absoluteAuthTimeout)
 4304                 $this->setState(self::AUTH_ABSOLUTE_TIMEOUT_VAR, time()+$this->absoluteAuthTimeout);
 4305             $this->afterLogin(false);
 4306         }
 4307         return !$this->getIsGuest();
 4308     }
 4309     public function logout($destroySession=true)
 4310     {
 4311         if($this->beforeLogout())
 4312         {
 4313             if($this->allowAutoLogin)
 4314             {
 4315                 Yii::app()->getRequest()->getCookies()->remove($this->getStateKeyPrefix());
 4316                 if($this->identityCookie!==null)
 4317                 {
 4318                     $cookie=$this->createIdentityCookie($this->getStateKeyPrefix());
 4319                     $cookie->value=null;
 4320                     $cookie->expire=0;
 4321                     Yii::app()->getRequest()->getCookies()->add($cookie->name,$cookie);
 4322                 }
 4323             }
 4324             if($destroySession)
 4325                 Yii::app()->getSession()->destroy();
 4326             else
 4327                 $this->clearStates();
 4328             $this->_access=array();
 4329             $this->afterLogout();
 4330         }
 4331     }
 4332     public function getIsGuest()
 4333     {
 4334         return $this->getState('__id')===null;
 4335     }
 4336     public function getId()
 4337     {
 4338         return $this->getState('__id');
 4339     }
 4340     public function setId($value)
 4341     {
 4342         $this->setState('__id',$value);
 4343     }
 4344     public function getName()
 4345     {
 4346         if(($name=$this->getState('__name'))!==null)
 4347             return $name;
 4348         else
 4349             return $this->guestName;
 4350     }
 4351     public function setName($value)
 4352     {
 4353         $this->setState('__name',$value);
 4354     }
 4355     public function getReturnUrl($defaultUrl=null)
 4356     {
 4357         if($defaultUrl===null)
 4358         {
 4359             $defaultReturnUrl=Yii::app()->getUrlManager()->showScriptName ? Yii::app()->getRequest()->getScriptUrl() : Yii::app()->getRequest()->getBaseUrl().'/';
 4360         }
 4361         else
 4362         {
 4363             $defaultReturnUrl=CHtml::normalizeUrl($defaultUrl);
 4364         }
 4365         return $this->getState('__returnUrl',$defaultReturnUrl);
 4366     }
 4367     public function setReturnUrl($value)
 4368     {
 4369         $this->setState('__returnUrl',$value);
 4370     }
 4371     public function loginRequired()
 4372     {
 4373         $app=Yii::app();
 4374         $request=$app->getRequest();
 4375         if(!$request->getIsAjaxRequest())
 4376         {
 4377             $this->setReturnUrl($request->getUrl());
 4378             if(($url=$this->loginUrl)!==null)
 4379             {
 4380                 if(is_array($url))
 4381                 {
 4382                     $route=isset($url[0]) ? $url[0] : $app->defaultController;
 4383                     $url=$app->createUrl($route,array_splice($url,1));
 4384                 }
 4385                 $request->redirect($url);
 4386             }
 4387         }
 4388         elseif(isset($this->loginRequiredAjaxResponse))
 4389         {
 4390             echo $this->loginRequiredAjaxResponse;
 4391             Yii::app()->end();
 4392         }
 4393         throw new CHttpException(403,Yii::t('yii','Login Required'));
 4394     }
 4395     protected function beforeLogin($id,$states,$fromCookie)
 4396     {
 4397         return true;
 4398     }
 4399     protected function afterLogin($fromCookie)
 4400     {
 4401     }
 4402     protected function beforeLogout()
 4403     {
 4404         return true;
 4405     }
 4406     protected function afterLogout()
 4407     {
 4408     }
 4409     protected function restoreFromCookie()
 4410     {
 4411         $app=Yii::app();
 4412         $request=$app->getRequest();
 4413         $cookie=$request->getCookies()->itemAt($this->getStateKeyPrefix