Commit 165bb02a by Qiang Xue

...

parent 6caad53a
<?php
/**
* CAction class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
/**
* CAction is the base class for all controller action classes.
*
* CAction provides a way to divide a complex controller into
* smaller actions in separate class files.
*
* Derived classes must implement {@link run()} which is invoked by
* controller when the action is requested.
*
* An action instance can access its controller via {@link getController controller} property.
*
* @property CController $controller The controller who owns this action.
* @property string $id Id of this action.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package system.web.actions
* @since 1.0
*/
abstract class CAction extends CComponent implements IAction
{
private $_id;
private $_controller;
/**
* Constructor.
* @param CController $controller the controller who owns this action.
* @param string $id id of the action.
*/
public function __construct($controller,$id)
{
$this->_controller=$controller;
$this->_id=$id;
}
/**
* @return CController the controller who owns this action.
*/
public function getController()
{
return $this->_controller;
}
/**
* @return string id of this action
*/
public function getId()
{
return $this->_id;
}
/**
* Runs the action with the supplied request parameters.
* This method is internally called by {@link CController::runAction()}.
* @param array $params the request parameters (name=>value)
* @return boolean whether the request parameters are valid
* @since 1.1.7
*/
public function runWithParams($params)
{
$method=new ReflectionMethod($this, 'run');
if($method->getNumberOfParameters()>0)
return $this->runWithParamsInternal($this, $method, $params);
else
return $this->run();
}
/**
* Executes a method of an object with the supplied named parameters.
* This method is internally used.
* @param mixed $object the object whose method is to be executed
* @param ReflectionMethod $method the method reflection
* @param array $params the named parameters
* @return boolean whether the named parameters are valid
* @since 1.1.7
*/
protected function runWithParamsInternal($object, $method, $params)
{
$ps=array();
foreach($method->getParameters() as $i=>$param)
{
$name=$param->getName();
if(isset($params[$name]))
{
if($param->isArray())
$ps[]=is_array($params[$name]) ? $params[$name] : array($params[$name]);
else if(!is_array($params[$name]))
$ps[]=$params[$name];
else
return false;
}
else if($param->isDefaultValueAvailable())
$ps[]=$param->getDefaultValue();
else
return false;
}
$method->invokeArgs($object,$ps);
return true;
}
}
<?php
/**
* CFilter class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
/**
* CFilter is the base class for all filters.
*
* A filter can be applied before and after an action is executed.
* It can modify the context that the action is to run or decorate the result that the
* action generates.
*
* Override {@link preFilter()} to specify the filtering logic that should be applied
* before the action, and {@link postFilter()} for filtering logic after the action.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package system.web.filters
* @since 1.0
*/
class CFilter extends CComponent implements IFilter
{
/**
* Performs the filtering.
* The default implementation is to invoke {@link preFilter}
* and {@link postFilter} which are meant to be overridden
* child classes. If a child class needs to override this method,
* make sure it calls <code>$filterChain->run()</code>
* if the action should be executed.
* @param CFilterChain $filterChain the filter chain that the filter is on.
*/
public function filter($filterChain)
{
if($this->preFilter($filterChain))
{
$filterChain->run();
$this->postFilter($filterChain);
}
}
/**
* Initializes the filter.
* This method is invoked after the filter properties are initialized
* and before {@link preFilter} is called.
* You may override this method to include some initialization logic.
* @since 1.1.4
*/
public function init()
{
}
/**
* Performs the pre-action filtering.
* @param CFilterChain $filterChain the filter chain that the filter is on.
* @return boolean whether the filtering process should continue and the action
* should be executed.
*/
protected function preFilter($filterChain)
{
return true;
}
/**
* Performs the post-action filtering.
* @param CFilterChain $filterChain the filter chain that the filter is on.
*/
protected function postFilter($filterChain)
{
}
}
\ No newline at end of file
......@@ -73,7 +73,7 @@ use yii\base\Exception;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
abstract class Application extends Module
class Application extends Module
{
/**
* @var string the application name. Defaults to 'My Application'.
......@@ -91,25 +91,16 @@ abstract class Application extends Module
public $sourceLanguage = 'en_us';
public $preload = array('errorHandler');
public $localeDataPath = '@yii/i18n/data';
private $_runtimePath;
private $_ended = false;
private $_language;
/**
* Processes the request.
* This is the place where the actual request processing work is done.
* Derived classes should override this method.
*/
abstract public function processRequest();
/**
* Constructor.
* @param mixed $config application configuration.
* If a string, it is treated as the path of the file that contains the configuration;
* If an array, it is the actual configuration information.
* Please make sure you specify the {@link getBasePath basePath} property in the configuration,
* which should point to the directory containing all application logic, template and data.
* If not, the directory will be defaulted to 'protected'.
* @param string $basePath the base path of this application. This should point to
* the directory containing all application logic, template and data.
*/
public function __construct($basePath)
{
......@@ -169,6 +160,15 @@ abstract class Application extends Module
}
/**
* Processes the request.
* This is the place where the actual request processing work is done.
* Derived classes should override this method.
*/
public function processRequest()
{
}
/**
* Raises the [[afterRequest]] event right AFTER the application processes the request.
*/
public function afterRequest()
......@@ -306,24 +306,6 @@ abstract class Application extends Module
}
/**
* Returns the directory that contains the locale data.
* @return string the directory that contains the locale data. It defaults to 'framework/i18n/data'.
*/
public function getLocaleDataPath()
{
return CLocale::$dataPath === null ? \Yii::getPathOfAlias('system.i18n.data') : CLocale::$dataPath;
}
/**
* Sets the directory that contains the locale data.
* @param string $value the directory that contains the locale data.
*/
public function setLocaleDataPath($value)
{
CLocale::$dataPath = $value;
}
/**
* @return CNumberFormatter the locale-dependent number formatter.
* The current {@link getLocale application locale} will be used.
*/
......@@ -415,232 +397,6 @@ abstract class Application extends Module
}
/**
* Handles uncaught PHP exceptions.
*
* This method is implemented as a PHP exception handler. It requires
* that constant YII_ENABLE_EXCEPTION_HANDLER be defined true.
*
* This method will first raise an `exception` event.
* If the exception is not handled by any event handler, it will call
* {@link getErrorHandler errorHandler} to process the exception.
*
* The application will be terminated by this method.
*
* @param Exception $exception exception that is not caught
*/
public function handleException($exception)
{
// disable error capturing to avoid recursive errors
restore_error_handler();
restore_exception_handler();
$category = 'exception.' . get_class($exception);
if ($exception instanceof \yii\web\HttpException) {
$category .= '.' . $exception->statusCode;
}
// php <5.2 doesn't support string conversion auto-magically
$message = $exception->__toString();
if (isset($_SERVER['REQUEST_URI'])) {
$message .= ' REQUEST_URI=' . $_SERVER['REQUEST_URI'];
}
\Yii::error($message, $category);
try
{
// TODO: do we need separate exception class as it was in 1.1?
//$event = new CExceptionEvent($this, $exception);
$event = new Event($this, array('exception' => $exception));
$this->onException($event);
if (!$event->handled) {
// try an error handler
if (($handler = $this->getErrorHandler()) !== null) {
$handler->handle($event);
} else
{
$this->displayException($exception);
}
}
}
catch (Exception $e)
{
$this->displayException($e);
}
try
{
$this->end(1);
}
catch (Exception $e)
{
// use the most primitive way to log error
$msg = get_class($e) . ': ' . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")\n";
$msg .= $e->getTraceAsString() . "\n";
$msg .= "Previous exception:\n";
$msg .= get_class($exception) . ': ' . $exception->getMessage() . ' (' . $exception->getFile() . ':' . $exception->getLine() . ")\n";
$msg .= $exception->getTraceAsString() . "\n";
$msg .= '$_SERVER=' . var_export($_SERVER, true);
error_log($msg);
exit(1);
}
}
/**
* Handles PHP execution errors such as warnings, notices.
*
* This method is implemented as a PHP error handler. It requires
* that constant YII_ENABLE_ERROR_HANDLER be defined true.
*
* This method will first raise an `error` event.
* If the error is not handled by any event handler, it will call
* {@link getErrorHandler errorHandler} to process the error.
*
* The application will be terminated by this method.
*
* @param integer $code the level of the error raised
* @param string $message the error message
* @param string $file the filename that the error was raised in
* @param integer $line the line number the error was raised at
*/
public function handleError($code, $message, $file, $line)
{
if ($code & error_reporting()) {
// disable error capturing to avoid recursive errors
restore_error_handler();
restore_exception_handler();
$log = "$message ($file:$line)\nStack trace:\n";
$trace = debug_backtrace();
// skip the first 3 stacks as they do not tell the error position
if (count($trace) > 3) {
$trace = array_slice($trace, 3);
}
foreach ($trace as $i => $t)
{
if (!isset($t['file'])) {
$t['file'] = 'unknown';
}
if (!isset($t['line'])) {
$t['line'] = 0;
}
if (!isset($t['function'])) {
$t['function'] = 'unknown';
}
$log .= "#$i {$t['file']}( {$t['line']}): ";
if (isset($t['object']) && is_object($t['object'])) {
$log .= get_class($t['object']) . '->';
}
$log .= " {$t['function']}()\n";
}
if (isset($_SERVER['REQUEST_URI'])) {
$log .= 'REQUEST_URI=' . $_SERVER['REQUEST_URI'];
}
\Yii::error($log, 'php');
try
{
\Yii::import('CErrorEvent', true);
$event = new CErrorEvent($this, $code, $message, $file, $line);
$this->onError($event);
if (!$event->handled) {
// try an error handler
if (($handler = $this->getErrorHandler()) !== null) {
$handler->handle($event);
} else
{
$this->displayError($code, $message, $file, $line);
}
}
}
catch (Exception $e)
{
$this->displayException($e);
}
try
{
$this->end(1);
}
catch (Exception $e)
{
// use the most primitive way to log error
$msg = get_class($e) . ': ' . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")\n";
$msg .= $e->getTraceAsString() . "\n";
$msg .= "Previous error:\n";
$msg .= $log . "\n";
$msg .= '$_SERVER=' . var_export($_SERVER, true);
error_log($msg);
exit(1);
}
}
}
/**
* Displays the captured PHP error.
* This method displays the error in HTML when there is
* no active error handler.
* @param integer $code error code
* @param string $message error message
* @param string $file error file
* @param string $line error line
*/
public function displayError($code, $message, $file, $line)
{
if (YII_DEBUG) {
echo "<h1>PHP Error [$code]</h1>\n";
echo "<p>$message ($file:$line)</p>\n";
echo '<pre>';
$trace = debug_backtrace();
// skip the first 3 stacks as they do not tell the error position
if (count($trace) > 3) {
$trace = array_slice($trace, 3);
}
foreach ($trace as $i => $t)
{
if (!isset($t['file'])) {
$t['file'] = 'unknown';
}
if (!isset($t['line'])) {
$t['line'] = 0;
}
if (!isset($t['function'])) {
$t['function'] = 'unknown';
}
echo "#$i {$t['file']}( {$t['line']}): ";
if (isset($t['object']) && is_object($t['object'])) {
echo get_class($t['object']) . '->';
}
echo " {$t['function']}()\n";
}
echo '</pre>';
} else
{
echo "<h1>PHP Error [$code]</h1>\n";
echo "<p>$message</p>\n";
}
}
/**
* Displays the uncaught PHP exception.
* This method displays the exception in HTML when there is
* no active error handler.
* @param Exception $exception the uncaught exception
*/
public function displayException($exception)
{
if (YII_DEBUG) {
echo '<h1>' . get_class($exception) . "</h1>\n";
echo '<p>' . $exception->getMessage() . ' (' . $exception->getFile() . ':' . $exception->getLine() . ')</p>';
echo '<pre>' . $exception->getTraceAsString() . '</pre>';
} else
{
echo '<h1>' . get_class($exception) . "</h1>\n";
echo '<p>' . $exception->getMessage() . '</p>';
}
}
/**
* Registers the core application components.
* @see setComponents
*/
......@@ -654,7 +410,7 @@ abstract class Application extends Module
'class' => 'yii\base\Request',
),
'response' => array(
'class' => 'yii\base\Request',
'class' => 'yii\base\Response',
),
'format' => array(
'class' => 'yii\base\Formatter',
......@@ -662,7 +418,7 @@ abstract class Application extends Module
'coreMessages' => array(
'class' => 'yii\i18n\PhpMessageSource',
'language' => 'en_us',
'basePath' => YII_PATH . DIRECTORY_SEPARATOR . 'messages',
'basePath' => '@yii/messages',
),
'messages' => array(
'class' => 'yii\i18n\PhpMessageSource',
......
......@@ -12,9 +12,16 @@ namespace yii\base;
/**
* ErrorHandler handles uncaught PHP errors and exceptions.
*
* It displays these errors using appropriate views based on the
* nature of the error and the mode the application runs at.
* It also chooses the most preferred language for displaying the error.
* ErrorHandler displays these errors using appropriate views based on the
* nature of the errors and the mode the application runs at.
*
* ErrorHandler does the following when the application encounters an error or exception:
*
* - If it is a PHP error, warning or notice, an ErrorException will be thrown which
* if not caught, will be handled in the next few steps
* - If it is an uncaught exception, it will invoke the action defined by [[errorAction]]
* to handle the exception;
* - If [[errorAction]] is not defined, it will
*
* ErrorHandler uses two sets of views:
* <ul>
......@@ -58,7 +65,6 @@ class ErrorHandler extends ApplicationComponent
* @var integer maximum number of source code lines to be displayed. Defaults to 25.
*/
public $maxSourceLines = 25;
/**
* @var integer maximum number of trace source code lines to be displayed. Defaults to 10.
*/
......@@ -90,7 +96,7 @@ class ErrorHandler extends ApplicationComponent
/**
* Handles PHP execution errors such as warnings, notices.
*
* This method is implemented as a PHP error handler. It requires
* This method is used as a PHP error handler. It requires
* that constant YII_ENABLE_ERROR_HANDLER be defined true.
*
* This method will first raise an `error` event.
......@@ -135,19 +141,17 @@ class ErrorHandler extends ApplicationComponent
protected function render($exception)
{
if (\Yii::$application instanceof \yii\web\Application) {
if ($this->errorAction !== null) {
\Yii::$application->runController($this->errorAction);
if ($this->errorAction !== null) {
\Yii::$application->runController($this->errorAction);
} elseif (\Yii::$application instanceof \yii\web\Application) {
if (!headers_sent()) {
$errorCode = $exception instanceof HttpException ? $exception->statusCode : 500;
header("HTTP/1.0 $errorCode " . get_class($exception));
}
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
$this->renderAsText($exception);
} else {
if (!headers_sent()) {
$errorCode = $exception instanceof HttpException ? $exception->statusCode : 500;
header("HTTP/1.0 $errorCode " . get_class($exception));
}
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
$this->renderAsText($exception);
} else {
$this->renderAsHtml($exception);
}
$this->renderAsHtml($exception);
}
} else {
$this->renderAsText($exception);
......
<?php
/**
* CInlineAction class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
/**
* CInlineAction represents an action that is defined as a controller method.
*
* The method name is like 'actionXYZ' where 'XYZ' stands for the action name.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package system.web.actions
* @since 1.0
*/
class CInlineAction extends CAction
{
/**
* Runs the action.
* The action method defined in the controller is invoked.
* This method is required by {@link CAction}.
*/
public function run()
{
$method='action'.$this->getId();
$this->getController()->$method();
}
/**
* Runs the action with the supplied request parameters.
* This method is internally called by {@link CController::runAction()}.
* @param array $params the request parameters (name=>value)
* @return boolean whether the request parameters are valid
* @since 1.1.7
*/
public function runWithParams($params)
{
$methodName='action'.$this->getId();
$controller=$this->getController();
$method=new ReflectionMethod($controller, $methodName);
if($method->getNumberOfParameters()>0)
return $this->runWithParamsInternal($controller, $method, $params);
else
return $controller->$methodName();
}
}
<?php
/**
* CInlineFilter class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
/**
* CInlineFilter represents a filter defined as a controller method.
*
* CInlineFilter executes the 'filterXYZ($action)' method defined
* in the controller, where the name 'XYZ' can be retrieved from the {@link name} property.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package system.web.filters
* @since 1.0
*/
class CInlineFilter extends CFilter
{
/**
* @var string name of the filter. It stands for 'XYZ' in the filter method name 'filterXYZ'.
*/
public $name;
/**
* Creates an inline filter instance.
* The creation is based on a string describing the inline method name
* and action names that the filter shall or shall not apply to.
* @param CController $controller the controller who hosts the filter methods
* @param string $filterName the filter name
* @return CInlineFilter the created instance
* @throws CException if the filter method does not exist
*/
public static function create($controller,$filterName)
{
if(method_exists($controller,'filter'.$filterName))
{
$filter=new CInlineFilter;
$filter->name=$filterName;
return $filter;
}
else
throw new CException(Yii::t('yii','Filter "{filter}" is invalid. Controller "{class}" does not have the filter method "filter{filter}".',
array('{filter}'=>$filterName, '{class}'=>get_class($controller))));
}
/**
* Performs the filtering.
* This method calls the filter method defined in the controller class.
* @param CFilterChain $filterChain the filter chain that the filter is on.
*/
public function filter($filterChain)
{
$method='filter'.$this->name;
$filterChain->controller->$method($filterChain);
}
}
......@@ -136,10 +136,11 @@ abstract class Module extends Component implements Initable
*/
public function setBasePath($path)
{
if (($p = realpath($path)) === false || !is_dir($p)) {
$p = \Yii::getAlias($path);
if ($p === false || !is_dir($p)) {
throw new Exception('Invalid base path: ' . $path);
} else {
$this->_basePath = $p;
$this->_basePath = realpath($p);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment