Commit e585c69f by Qiang Xue

working on error handler.

parent 0fd82123
......@@ -22,14 +22,6 @@ defined('YII_DEBUG') or define('YII_DEBUG', false);
*/
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', 0);
/**
* This constant defines whether exception handling should be enabled. Defaults to true.
*/
defined('YII_ENABLE_EXCEPTION_HANDLER') or define('YII_ENABLE_EXCEPTION_HANDLER', true);
/**
* This constant defines whether error handling should be enabled. Defaults to true.
*/
defined('YII_ENABLE_ERROR_HANDLER') or define('YII_ENABLE_ERROR_HANDLER', true);
/**
* This constant defines the framework installation directory.
*/
defined('YII_PATH') or define('YII_PATH', __DIR__);
......
......@@ -91,8 +91,6 @@ abstract class Application extends Module
public $sourceLanguage = 'en_us';
private $_runtimePath;
private $_globalState;
private $_stateChanged;
private $_ended = false;
private $_language;
......@@ -417,95 +415,6 @@ abstract class Application extends Module
}
/**
* Returns a global value.
*
* A global value is one that is persistent across users sessions and requests.
* @param string $key the name of the value to be returned
* @param mixed $defaultValue the default value. If the named global value is not found, this will be returned instead.
* @return mixed the named global value
* @see setGlobalState
*/
public function getGlobalState($key, $defaultValue = null)
{
if ($this->_globalState === null) {
$this->loadGlobalState();
}
return isset($this->_globalState[$key]) ? $this->_globalState[$key] : $defaultValue;
}
/**
* Sets a global value.
*
* A global value is one that is persistent across users sessions and requests.
* Make sure that the value is serializable and unserializable.
* @param string $key the name of the value to be saved
* @param mixed $value the global value to be saved. It must be serializable.
* @param mixed $defaultValue the default value. If the named global value is the same as this value, it will be cleared from the current storage.
* @see getGlobalState
*/
public function setGlobalState($key, $value, $defaultValue = null)
{
if ($this->_globalState === null) {
$this->loadGlobalState();
}
$changed = $this->_stateChanged;
if ($value === $defaultValue) {
if (isset($this->_globalState[$key])) {
unset($this->_globalState[$key]);
$this->_stateChanged = true;
}
} elseif (!isset($this->_globalState[$key]) || $this->_globalState[$key] !== $value) {
$this->_globalState[$key] = $value;
$this->_stateChanged = true;
}
if ($this->_stateChanged !== $changed) {
$this->on('afterRequest', array($this, 'saveGlobalState'));
}
}
/**
* Clears a global value.
*
* The value cleared will no longer be available in this request and the following requests.
* @param string $key the name of the value to be cleared
*/
public function clearGlobalState($key)
{
$this->setGlobalState($key, null);
}
/**
* Loads the global state data from persistent storage.
* @see getStatePersister
* @throws \yii\base\Exception if the state persister is not available
*/
public function loadGlobalState()
{
$persister = $this->getStatePersister();
if (($this->_globalState = $persister->load()) === null) {
$this->_globalState = array();
}
$this->_stateChanged = false;
$this->off('afterRequest', array($this, 'saveGlobalState'));
}
/**
* Saves the global state data into persistent storage.
* @see getStatePersister
* @throws \yii\base\Exception if the state persister is not available
*/
public function saveGlobalState()
{
if ($this->_stateChanged) {
$this->_stateChanged = false;
$this->off('afterRequest', array($this, 'saveGlobalState'));
$this->getStatePersister()->save($this->_globalState);
}
}
/**
* Handles uncaught PHP exceptions.
*
* This method is implemented as a PHP exception handler. It requires
......@@ -666,36 +575,6 @@ abstract class Application extends Module
}
/**
* Raised when an uncaught PHP exception occurs.
*
* An event handler can set the {@link ExceptionEvent::handled handled}
* property of the event parameter to be true to indicate no further error
* handling is needed. Otherwise, the {@link getErrorHandler errorHandler}
* application component will continue processing the error.
*
* @param ExceptionEvent $event event parameter
*/
public function onException($event)
{
$this->trigger('exception', $event);
}
/**
* Raised when a PHP execution error occurs.
*
* An event handler can set the {@link ErrorEvent::handled handled}
* property of the event parameter to be true to indicate no further error
* handling is needed. Otherwise, the {@link getErrorHandler errorHandler}
* application component will continue processing the error.
*
* @param ErrorEvent $event event parameter
*/
public function onError($event)
{
$this->trigger('error', $event);
}
/**
* Displays the captured PHP error.
* This method displays the error in HTML when there is
* no active error handler.
......
<?php
/**
* StatePersister class file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\base;
/**
* CStatePersister implements a file-based persistent data storage.
*
* It can be used to keep data available through multiple requests and sessions.
*
* By default, CStatePersister stores data in a file named 'state.bin' that is located
* under the application {@link CApplication::getRuntimePath runtime path}.
* You may change the location by setting the {@link stateFile} property.
*
* To retrieve the data from CStatePersister, call {@link load()}. To save the data,
* call {@link save()}.
*
* Comparison among state persister, session and cache is as follows:
* <ul>
* <li>session: data persisting within a single user session.</li>
* <li>state persister: data persisting through all requests/sessions (e.g. hit counter).</li>
* <li>cache: volatile and fast storage. It may be used as storage medium for session or state persister.</li>
* </ul>
*
* Since server resource is often limited, be cautious if you plan to use CStatePersister
* to store large amount of data. You should also consider using database-based persister
* to improve the throughput.
*
* CStatePersister is a core application component used to store global application state.
* It may be accessed via {@link CApplication::getStatePersister()}.
* page state persistent method based on cache.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class StatePersister extends ApplicationComponent
{
/**
* @var string the file path for keeping the state data. Make sure the directory containing
* the file exists and is writable by the Web server process. If using relative path, also
* make sure the path is correct. You may use a path alias here. If not set, it defaults
* to the `state.bin` file under the application's runtime directory.
*/
public $dataFile;
/**
* Loads state data from persistent storage.
* @return mixed state data. Null if no state data available.
*/
public function load()
{
$dataFile = \Yii::getAlias($this->dataFile);
if (is_file($dataFile) && ($data = file_get_contents($dataFile)) !== false) {
return unserialize($data);
} else {
return null;
}
}
/**
* Saves application state in persistent storage.
* @param mixed $state state data (must be serializable).
*/
public function save($state)
{
file_put_contents(\Yii::getAlias($this->dataFile), serialize($state), LOCK_EX);
}
}
<?php
/**
* View class file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\base;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class View extends Component
{
public function render($context, $_file_, $_data_ = array())
{
// we use special variable names here to avoid conflict with extracted variables
extract($_data_, EXTR_PREFIX_SAME, 'data');
ob_start();
ob_implicit_flush(false);
require($_file_);
return ob_get_clean();
}
}
\ No newline at end of file
......@@ -91,8 +91,7 @@ class ActiveQuery extends BaseActiveQuery implements \IteratorAggregate, \ArrayA
*/
public function value()
{
$finder = new ActiveFinder($this->getDbConnection());
return $finder->find($this, true);
return $this->createFinder()->find($this, true);
}
public function exists()
......@@ -234,7 +233,11 @@ class ActiveQuery extends BaseActiveQuery implements \IteratorAggregate, \ArrayA
protected function findRecords()
{
$finder = new ActiveFinder($this->getDbConnection());
return $finder->find($this);
return $this->createFinder()->find($this);
}
protected function createFinder()
{
return new ActiveFinder($this->getDbConnection());
}
}
......@@ -89,7 +89,9 @@ abstract class ActiveRecord extends Model
* // find all customers
* $customers = Customer::find()->all();
* // find a single customer whose primary key value is 10
* $customer = Customer::find(10)->one();
* $customer = Customer::find(10);
* // the above is equivalent to:
* Customer::find()->where(array('id' => 10))->one();
* // find all active customers and order them by their age:
* $customers = Customer::find()
* ->where(array('status' => 1))
......@@ -107,7 +109,9 @@ abstract class ActiveRecord extends Model
* - a scalar value (integer or string): query by a single primary key value.
* - an array of name-value pairs: it will be used to configure the [[ActiveQuery]] object.
*
* @return ActiveQuery the [[ActiveQuery]] instance for query purpose.
* @return ActiveQuery|ActiveRecord|null the [[ActiveQuery]] instance for query purpose, or
* the ActiveRecord object when a scalar is passed to this method which is considered to be a
* primary key value (null will be returned if no record is found in this case.)
*/
public static function find($q = null)
{
......@@ -119,7 +123,7 @@ abstract class ActiveRecord extends Model
} elseif ($q !== null) {
// query by primary key
$primaryKey = static::getMetaData()->table->primaryKey;
$query->where(array($primaryKey[0] => $q));
return $query->where(array($primaryKey[0] => $q))->one();
}
return $query;
}
......
......@@ -152,7 +152,7 @@ class Logger extends \yii\base\Component
$count = 0;
foreach ($traces as $trace) {
if (isset($trace['file'], $trace['line']) && strpos($trace['file'], YII_PATH) !== 0) {
$message .= "\nin " . $trace['file'] . ' (' . $trace['line'] . ')';
$message .= "\nin {$trace['file']} ({$trace['line']})";
if (++$count >= YII_TRACE_LEVEL) {
break;
}
......@@ -174,20 +174,14 @@ class Logger extends \yii\base\Component
*/
public function flush($export = false)
{
$this->onFlush(new \yii\base\Event($this, array('export' => $export, 'flush' => true)));
$this->trigger('flush', new \yii\base\Event($this, array(
'export' => $export,
'flush' => true,
)));
$this->messages = array();
}
/**
* Raises a `flush` event.
* @param \yii\base\Event $event the event parameter
*/
public function onFlush($event)
{
$this->trigger('flush', $event);
}
/**
* Returns the total elapsed time since the start of the current request.
* This method calculates the difference between now and the timestamp
* defined by constant `YII_BEGIN_TIME` which is evaluated at the beginning
......
......@@ -56,6 +56,9 @@ namespace yii\logging;
*/
class Router extends \yii\base\ApplicationComponent
{
/**
* @var \yii\base\Dictionary
*/
private $_targets;
/**
......@@ -69,15 +72,15 @@ class Router extends \yii\base\ApplicationComponent
/**
* Initializes this application component.
* This method is invoked when the Router component is created by the application.
* The method attaches the [[processLogs]] method to both the [[Logger::onFlush]] event
* and the [[\yii\base\Application::onEndRequest]] event.
* The method attaches the [[processLogs]] method to both the [[Logger::flush]] event
* and the [[\yii\base\Application::afterRequest]] event.
*/
public function init()
{
parent::init();
\Yii::getLogger()->attachEventHandler('onFlush', array($this, 'processMessages'));
\Yii::getLogger()->on('flush', array($this, 'processMessages'));
if (($app = \Yii::$application) !== null) {
$app->attachEventHandler('onEndRequest', array($this, 'processMessages'));
$app->on('afterRequest', array($this, 'processMessages'));
}
}
......@@ -100,7 +103,7 @@ class Router extends \yii\base\ApplicationComponent
* Sets the log targets.
* @param array $config list of log target configurations. Each array element
* represents the configuration for creating a single log target. It will be
* passed to [[\Yii::createObject]] to create the target instance.
* passed to [[\Yii::createObject()]] to create the target instance.
*/
public function setTargets($config)
{
......@@ -124,8 +127,8 @@ class Router extends \yii\base\ApplicationComponent
public function processMessages($event)
{
$messages = \Yii::getLogger()->messages;
$export = !isset($event->params['export']) || $event->params['export'];
$final = !isset($event->params['flush']) || !$event->params['flush'];
$export = !isset($event->data['export']) || $event->data['export'];
$final = !isset($event->data['flush']) || !$event->data['flush'];
foreach ($this->_targets as $target) {
if ($target->enabled) {
$target->processMessages($messages, $export, $final);
......
<?php
/**
* HttpException class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\web;
/**
* CHttpException represents an exception caused by invalid operations of end-users.
*
* The HTTP error code can be obtained via {@link statusCode}.
* Error handlers may use this status code to decide how to format the error page.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class HttpException extends \yii\base\Exception
{
/**
* @var integer HTTP status code, such as 403, 404, 500, etc.
*/
public $statusCode;
/**
* Constructor.
* @param integer $status HTTP status code, such as 404, 500, etc.
* @param string $message error message
* @param integer $code error code
*/
public function __construct($status,$message=null,$code=0)
{
$this->statusCode=$status;
parent::__construct($message,$code);
}
}
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