Browse Source

Refactored the way of sending response in controller actions.

tags/2.0.0-beta
Qiang Xue 12 years ago
parent
commit
420637443c
  1. 10
      apps/advanced/backend/controllers/SiteController.php
  2. 2
      apps/advanced/environments/dev/yii
  3. 2
      apps/advanced/environments/prod/yii
  4. 16
      apps/advanced/frontend/controllers/SiteController.php
  5. 16
      apps/basic/controllers/SiteController.php
  6. 2
      apps/basic/yii
  7. 2
      apps/benchmark/protected/controllers/SiteController.php
  8. 8
      docs/guide/performance.md
  9. 4
      framework/yii/base/Action.php
  10. 136
      framework/yii/base/Application.php
  11. 23
      framework/yii/base/Controller.php
  12. 82
      framework/yii/base/ErrorHandler.php
  13. 4
      framework/yii/base/InlineAction.php
  14. 12
      framework/yii/base/Module.php
  15. 75
      framework/yii/base/Response.php
  16. 40
      framework/yii/base/ResponseEvent.php
  17. 31
      framework/yii/console/Application.php
  18. 66
      framework/yii/views/errorHandler/error.php
  19. 3
      framework/yii/views/errorHandler/exception.php
  20. 25
      framework/yii/web/Application.php
  21. 21
      framework/yii/web/CaptchaAction.php
  22. 56
      framework/yii/web/Response.php
  23. 4
      framework/yii/web/User.php

10
apps/advanced/backend/controllers/SiteController.php

@ -10,16 +10,16 @@ class SiteController extends Controller
{
public function actionIndex()
{
echo $this->render('index');
return $this->render('index');
}
public function actionLogin()
{
$model = new LoginForm();
if ($this->populate($_POST, $model) && $model->login()) {
Yii::$app->response->redirect(array('site/index'));
return Yii::$app->response->redirect(array('site/index'));
} else {
echo $this->render('login', array(
return $this->render('login', array(
'model' => $model,
));
}
@ -27,7 +27,7 @@ class SiteController extends Controller
public function actionLogout()
{
Yii::$app->getUser()->logout();
Yii::$app->getResponse()->redirect(array('site/index'));
Yii::$app->user->logout();
return Yii::$app->response->redirect(array('site/index'));
}
}

2
apps/advanced/environments/dev/yii

@ -22,4 +22,4 @@ $config = yii\helpers\ArrayHelper::merge(
);
$application = new yii\console\Application($config);
$application->run();
return $application->run();

2
apps/advanced/environments/prod/yii

@ -22,4 +22,4 @@ $config = yii\helpers\ArrayHelper::merge(
);
$application = new yii\console\Application($config);
$application->run();
return $application->run();

16
apps/advanced/frontend/controllers/SiteController.php

@ -20,16 +20,16 @@ class SiteController extends Controller
public function actionIndex()
{
echo $this->render('index');
return $this->render('index');
}
public function actionLogin()
{
$model = new LoginForm();
if ($this->populate($_POST, $model) && $model->login()) {
Yii::$app->response->redirect(array('site/index'));
return Yii::$app->response->redirect(array('site/index'));
} else {
echo $this->render('login', array(
return $this->render('login', array(
'model' => $model,
));
}
@ -37,8 +37,8 @@ class SiteController extends Controller
public function actionLogout()
{
Yii::$app->getUser()->logout();
Yii::$app->getResponse()->redirect(array('site/index'));
Yii::$app->user->logout();
return Yii::$app->response->redirect(array('site/index'));
}
public function actionContact()
@ -46,9 +46,9 @@ class SiteController extends Controller
$model = new ContactForm;
if ($this->populate($_POST, $model) && $model->contact(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('contactFormSubmitted');
Yii::$app->response->refresh();
return Yii::$app->response->refresh();
} else {
echo $this->render('contact', array(
return $this->render('contact', array(
'model' => $model,
));
}
@ -56,6 +56,6 @@ class SiteController extends Controller
public function actionAbout()
{
echo $this->render('about');
return $this->render('about');
}
}

16
apps/basic/controllers/SiteController.php

@ -20,16 +20,16 @@ class SiteController extends Controller
public function actionIndex()
{
echo $this->render('index');
return $this->render('index');
}
public function actionLogin()
{
$model = new LoginForm();
if ($this->populate($_POST, $model) && $model->login()) {
Yii::$app->response->redirect(array('site/index'));
return Yii::$app->response->redirect(array('site/index'));
} else {
echo $this->render('login', array(
return $this->render('login', array(
'model' => $model,
));
}
@ -37,8 +37,8 @@ class SiteController extends Controller
public function actionLogout()
{
Yii::$app->getUser()->logout();
Yii::$app->getResponse()->redirect(array('site/index'));
Yii::$app->user->logout();
return Yii::$app->response->redirect(array('site/index'));
}
public function actionContact()
@ -46,9 +46,9 @@ class SiteController extends Controller
$model = new ContactForm;
if ($this->populate($_POST, $model) && $model->contact(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('contactFormSubmitted');
Yii::$app->response->refresh();
return Yii::$app->response->refresh();
} else {
echo $this->render('contact', array(
return $this->render('contact', array(
'model' => $model,
));
}
@ -56,6 +56,6 @@ class SiteController extends Controller
public function actionAbout()
{
echo $this->render('about');
return $this->render('about');
}
}

2
apps/basic/yii

@ -19,4 +19,4 @@ require(__DIR__ . '/vendor/autoload.php');
$config = require(__DIR__ . '/config/console.php');
$application = new yii\console\Application($config);
$application->run();
return $application->run();

2
apps/benchmark/protected/controllers/SiteController.php

@ -8,6 +8,6 @@ class SiteController extends Controller
public function actionHello()
{
echo 'hello world';
return 'hello world';
}
}

8
docs/guide/performance.md

@ -97,7 +97,7 @@ return array(
```
You can use `CacheSession` to store sessions using cache. Note that some
cache storages such as memcached has no guaranteee that session data will not
cache storage such as memcached has no guarantee that session data will not
be lost leading to unexpected logouts.
Improving application
@ -152,14 +152,14 @@ class PostController extends Controller
public function actionIndex()
{
$posts = Post::find()->orderBy('id DESC')->limit(100)->asArray()->all();
echo $this->render('index', array(
return $this->render('index', array(
'posts' => $posts,
));
}
}
```
In the view you should access fields of each invidual record from `$posts` as array:
In the view you should access fields of each individual record from `$posts` as array:
```php
foreach ($posts as $post) {
@ -178,4 +178,4 @@ request later if there's no need for immediate response.
- Cron jobs + console.
- queues + handlers.
TBD
TBD

4
framework/yii/base/Action.php

@ -66,7 +66,7 @@ class Action extends Component
* Runs this action with the specified parameters.
* This method is mainly invoked by the controller.
* @param array $params the parameters to be bound to the action's run() method.
* @return integer the exit status (0 means normal, non-zero means abnormal).
* @return mixed the result of the action
* @throws InvalidConfigException if the action class does not have a run() method
*/
public function runWithParams($params)
@ -75,6 +75,6 @@ class Action extends Component
throw new InvalidConfigException(get_class($this) . ' must define a "run()" method.');
}
$args = $this->controller->bindActionParams($this, $params);
return (int)call_user_func_array(array($this, 'run'), $args);
return call_user_func_array(array($this, 'run'), $args);
}
}

136
framework/yii/base/Application.php

@ -16,16 +16,12 @@ use yii\web\HttpException;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Application extends Module
abstract class Application extends Module
{
/**
* @event Event an event that is triggered at the beginning of [[run()]].
* @event ResponseEvent an event that is triggered after [[handle()]] returns a response.
*/
const EVENT_BEFORE_RUN = 'beforeRun';
/**
* @event Event an event that is triggered at the end of [[run()]].
*/
const EVENT_AFTER_RUN = 'afterRun';
const EVENT_RESPONSE = 'response';
/**
* @var string the application name.
*/
@ -54,7 +50,7 @@ class Application extends Module
*/
public $preload = array();
/**
* @var \yii\web\Controller|\yii\console\Controller the currently active controller instance
* @var Controller the currently active controller instance
*/
public $controller;
/**
@ -63,8 +59,6 @@ class Application extends Module
*/
public $layout = 'main';
private $_ended = false;
/**
* @var string Used to reserve memory for fatal error handler.
*/
@ -143,67 +137,32 @@ class Application extends Module
}
/**
* Terminates the application.
* This method replaces PHP's exit() function by calling [[afterRequest()]] before exiting.
* @param integer $status exit status (value 0 means normal exit while other values mean abnormal exit).
* @param boolean $exit whether to exit the current request.
* It defaults to true, meaning the PHP's exit() function will be called at the end of this method.
*/
public function end($status = 0, $exit = true)
{
if (!$this->_ended) {
$this->_ended = true;
$this->getResponse()->end();
$this->afterRun();
}
if ($exit) {
exit($status);
}
}
/**
* Runs the application.
* This is the main entrance of an application.
* @return integer the exit status (0 means normal, non-zero values mean abnormal)
*/
public function run()
{
$this->beforeRun();
$response = $this->getResponse();
$response->begin();
register_shutdown_function(array($this, 'end'), 0, false);
$status = $this->processRequest();
$response->end();
$this->afterRun();
return $status;
}
$response = $this->handle($this->getRequest());
/**
* Raises the [[EVENT_BEFORE_RUN]] event right BEFORE the application processes the request.
*/
public function beforeRun()
{
$this->trigger(self::EVENT_BEFORE_RUN);
}
$event = new ResponseEvent($response);
$this->trigger(self::EVENT_RESPONSE, $event);
$event->response->send();
/**
* Raises the [[EVENT_AFTER_RUN]] event right AFTER the application processes the request.
*/
public function afterRun()
{
$this->trigger(self::EVENT_AFTER_RUN);
return $response->exitStatus;
}
/**
* Processes the request.
* Child classes should override this method with actual request processing logic.
* @return integer the exit status of the controller action (0 means normal, non-zero values mean abnormal)
* Handles the specified request.
*
* This method should return an instance of [[Response]] or its child class
* which represents the handling result of the request.
*
* @param Request $request the request to be handled
* @return Response the resulting response
*/
public function processRequest()
{
return 0;
}
abstract public function handle($request);
private $_runtimePath;
@ -325,15 +284,6 @@ class Application extends Module
}
/**
* Returns the response component.
* @return \yii\web\Response|\yii\console\Response the response component
*/
public function getResponse()
{
return $this->getComponent('response');
}
/**
* Returns the view object.
* @return View the view object that is used to render various view files.
*/
@ -400,7 +350,7 @@ class Application extends Module
* This method is implemented as a PHP exception handler. It requires
* that constant YII_ENABLE_ERROR_HANDLER be defined true.
*
* @param \Exception $exception exception that is not caught
* @param \Exception $exception the exception that is not caught
*/
public function handleException($exception)
{
@ -410,17 +360,13 @@ class Application extends Module
try {
$this->logException($exception);
if (($handler = $this->getErrorHandler()) !== null) {
$handler->handle($exception);
} else {
$this->renderException($exception);
echo $this->renderException($exception);
}
$this->end(1);
} catch (\Exception $e) {
// exception could be thrown in end() or ErrorHandler::handle()
// exception could be thrown in ErrorHandler::handle()
$msg = (string)$e;
$msg .= "\nPrevious exception:\n";
$msg .= (string)$exception;
@ -468,29 +414,28 @@ class Application extends Module
*/
public function handleFatalError()
{
if (YII_ENABLE_ERROR_HANDLER) {
$error = error_get_last();
if (ErrorException::isFatalError($error)) {
unset($this->_memoryReserve);
$exception = new ErrorException($error['message'], $error['type'], $error['type'], $error['file'], $error['line']);
// use error_log because it's too late to use Yii log
error_log($exception);
if (($handler = $this->getErrorHandler()) !== null) {
$handler->handle($exception);
} else {
$this->renderException($exception);
}
$error = error_get_last();
if (ErrorException::isFatalError($error)) {
unset($this->_memoryReserve);
$exception = new ErrorException($error['message'], $error['type'], $error['type'], $error['file'], $error['line']);
// use error_log because it's too late to use Yii log
error_log($exception);
exit(1);
if (($handler = $this->getErrorHandler()) !== null) {
$handler->handle($exception);
} else {
echo $this->renderException($exception);
}
exit(1);
}
}
/**
* Renders an exception without using rich format.
* @param \Exception $exception the exception to be rendered.
* @return string the rendering result
*/
public function renderException($exception)
{
@ -499,14 +444,17 @@ class Application extends Module
} else {
$message = YII_DEBUG ? (string)$exception : 'Error: ' . $exception->getMessage();
}
if (PHP_SAPI) {
echo $message . "\n";
if (PHP_SAPI === 'cli') {
return $message . "\n";
} else {
echo '<pre>' . htmlspecialchars($message, ENT_QUOTES, $this->charset) . '</pre>';
return '<pre>' . htmlspecialchars($message, ENT_QUOTES, $this->charset) . '</pre>';
}
}
// todo: to be polished
/**
* Logs the given exception
* @param \Exception $exception the exception to be logged
*/
protected function logException($exception)
{
$category = get_class($exception);

23
framework/yii/base/Controller.php

@ -100,7 +100,7 @@ class Controller extends Component
* If the action ID is empty, the method will use [[defaultAction]].
* @param string $id the ID of the action to be executed.
* @param array $params the parameters (name-value pairs) to be passed to the action.
* @return integer the status of the action execution. 0 means normal, other values mean abnormal.
* @return mixed the result of the action
* @throws InvalidRouteException if the requested action ID cannot be resolved into an action successfully.
* @see createAction
*/
@ -110,16 +110,16 @@ class Controller extends Component
if ($action !== null) {
$oldAction = $this->action;
$this->action = $action;
$status = 1;
$result = null;
if ($this->module->beforeAction($action)) {
if ($this->beforeAction($action)) {
$status = $action->runWithParams($params);
$result = $action->runWithParams($params);
$this->afterAction($action);
}
$this->module->afterAction($action);
}
$this->action = $oldAction;
return $status;
return $result;
} else {
throw new InvalidRouteException('Unable to resolve the request: ' . $this->getUniqueId() . '/' . $id);
}
@ -161,21 +161,6 @@ class Controller extends Component
}
/**
* Forwards the current execution flow to handle a new request specified by a route.
* The only difference between this method and [[run()]] is that after calling this method,
* the application will exit.
* @param string $route the route to be handled, e.g., 'view', 'comment/view', '/admin/comment/view'.
* @param array $params the parameters to be passed to the action.
* @return integer the status code returned by the action execution. 0 means normal, and other values mean abnormal.
* @see run
*/
public function forward($route, $params = array())
{
$status = $this->run($route, $params);
Yii::$app->end($status);
}
/**
* Creates an action based on the given action ID.
* The method first checks if the action ID has been declared in [[actions()]]. If so,
* it will use the configuration declared there to create the action object.

82
framework/yii/base/ErrorHandler.php

@ -9,6 +9,7 @@ namespace yii\base;
use Yii;
use yii\web\HttpException;
use yii\web\Response;
/**
* ErrorHandler handles uncaught PHP errors and exceptions.
@ -42,9 +43,13 @@ class ErrorHandler extends Component
*/
public $errorAction;
/**
* @var string the path of the view file for rendering exceptions and errors.
* @var string the path of the view file for rendering exceptions without call stack information.
*/
public $mainView = '@yii/views/errorHandler/main.php';
public $errorView = '@yii/views/errorHandler/error.php';
/**
* @var string the path of the view file for rendering exceptions.
*/
public $exceptionView = '@yii/views/errorHandler/exception.php';
/**
* @var string the path of the view file for rendering exceptions and errors call stack element.
*/
@ -73,26 +78,31 @@ class ErrorHandler extends Component
}
/**
* Renders exception.
* @param \Exception $exception to be handled.
* Renders the exception.
* @param \Exception $exception the exception to be handled.
*/
protected function renderException($exception)
{
if ($this->errorAction !== null) {
Yii::$app->runAction($this->errorAction);
} elseif (!(Yii::$app instanceof \yii\web\Application)) {
Yii::$app->renderException($exception);
} else {
$response = Yii::$app->getResponse();
if (!headers_sent()) {
if ($exception instanceof HttpException) {
$response->setStatusCode($exception->statusCode);
} else {
$response->setStatusCode(500);
}
if (Yii::$app instanceof \yii\console\Application) {
echo Yii::$app->renderException($exception);
return;
}
$useErrorView = !YII_DEBUG || $exception instanceof UserException;
if ($useErrorView && $this->errorAction !== null) {
$result = Yii::$app->runAction($this->errorAction);
if ($result instanceof Response) {
$response = $result;
} else {
$response = new Response;
$response->content = $result;
}
} else {
$response = new Response;
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
Yii::$app->renderException($exception);
// AJAX request
$response->content = Yii::$app->renderException($exception);
} else {
// if there is an error during error rendering it's useful to
// display PHP error in debug mode instead of a blank screen
@ -101,19 +111,20 @@ class ErrorHandler extends Component
}
$view = new View();
$request = '';
foreach (array('_GET', '_POST', '_SERVER', '_FILES', '_COOKIE', '_SESSION', '_ENV') as $name) {
if (!empty($GLOBALS[$name])) {
$request .= '$' . $name . ' = ' . var_export($GLOBALS[$name], true) . ";\n\n";
}
}
$request = rtrim($request, "\n\n");
$response->content = $view->renderFile($this->mainView, array(
$file = $useErrorView ? $this->errorView : $this->exceptionView;
$response->content = $view->renderFile($file, array(
'exception' => $exception,
'request' => $request,
), $this);
}
}
if ($exception instanceof HttpException) {
$response->setStatusCode($exception->statusCode);
} else {
$response->setStatusCode(500);
}
$response->send();
}
/**
@ -133,7 +144,9 @@ class ErrorHandler extends Component
{
// the following manual level counting is to deal with zlib.output_compression set to On
for ($level = ob_get_level(); $level > 0; --$level) {
@ob_end_clean();
if (!@ob_end_clean()) {
ob_clean();
}
}
}
@ -230,6 +243,21 @@ class ErrorHandler extends Component
}
/**
* Renders the request information.
* @return string the rendering result
*/
public function renderRequest()
{
$request = '';
foreach (array('_GET', '_POST', '_SERVER', '_FILES', '_COOKIE', '_SESSION', '_ENV') as $name) {
if (!empty($GLOBALS[$name])) {
$request .= '$' . $name . ' = ' . var_export($GLOBALS[$name], true) . ";\n\n";
}
}
return '<pre>' . rtrim($request, "\n") . '</pre>';
}
/**
* Determines whether given name of the file belongs to the framework.
* @param string $file name to be checked.
* @return boolean whether given name of the file belongs to the framework.

4
framework/yii/base/InlineAction.php

@ -39,11 +39,11 @@ class InlineAction extends Action
* Runs this action with the specified parameters.
* This method is mainly invoked by the controller.
* @param array $params action parameters
* @return integer the exit status (0 means normal, non-zero means abnormal).
* @return mixed the result of the action
*/
public function runWithParams($params)
{
$args = $this->controller->bindActionParams($this, $params);
return (int)call_user_func_array(array($this->controller, $this->actionMethod), $args);
return call_user_func_array(array($this->controller, $this->actionMethod), $args);
}
}

12
framework/yii/base/Module.php

@ -571,20 +571,20 @@ abstract class Module extends Component
* If the route is empty, the method will use [[defaultRoute]].
* @param string $route the route that specifies the action.
* @param array $params the parameters to be passed to the action
* @return integer the status code returned by the action execution. 0 means normal, and other values mean abnormal.
* @return mixed the result of the action.
* @throws InvalidRouteException if the requested route cannot be resolved into an action successfully
*/
public function runAction($route, $params = array())
{
$result = $this->createController($route);
if (is_array($result)) {
$parts = $this->createController($route);
if (is_array($parts)) {
/** @var $controller Controller */
list($controller, $actionID) = $result;
list($controller, $actionID) = $parts;
$oldController = Yii::$app->controller;
Yii::$app->controller = $controller;
$status = $controller->runAction($actionID, $params);
$result = $controller->runAction($actionID, $params);
Yii::$app->controller = $oldController;
return $status;
return $result;
} else {
throw new InvalidRouteException('Unable to resolve the request "' . trim($this->getUniqueId() . '/' . $route, '/') . '".');
}

75
framework/yii/base/Response.php

@ -14,79 +14,12 @@ namespace yii\base;
class Response extends Component
{
/**
* @event Event an event raised when the application begins to generate the response.
* @var integer the exit status. Exit statuses should be in the range 0 to 254.
* The status 0 means the program terminates successfully.
*/
const EVENT_BEGIN_RESPONSE = 'beginResponse';
/**
* @event Event an event raised when the generation of the response finishes.
*/
const EVENT_END_RESPONSE = 'endResponse';
/**
* Starts output buffering
*/
public function beginBuffer()
{
ob_start();
ob_implicit_flush(false);
}
public $exitStatus = 0;
/**
* Returns contents of the output buffer and stops the buffer.
* @return string output buffer contents
*/
public function endBuffer()
{
return ob_get_clean();
}
/**
* Returns contents of the output buffer
* @return string output buffer contents
*/
public function getBuffer()
{
return ob_get_contents();
}
/**
* Discards the output buffer
* @param boolean $all if true, it will discards all output buffers.
*/
public function cleanBuffer($all = true)
{
if ($all) {
for ($level = ob_get_level(); $level > 0; --$level) {
if (!@ob_end_clean()) {
ob_clean();
}
}
} else {
ob_end_clean();
}
}
/**
* Begins generating the response.
* This method is called at the beginning of [[Application::run()]].
* The default implementation will trigger the [[EVENT_BEGIN_RESPONSE]] event.
* If you overwrite this method, make sure you call the parent implementation so that
* the event can be triggered.
*/
public function begin()
{
$this->trigger(self::EVENT_BEGIN_RESPONSE);
}
/**
* Ends generating the response.
* This method is called at the end of [[Application::run()]].
* The default implementation will trigger the [[EVENT_END_RESPONSE]] event.
* If you overwrite this method, make sure you call the parent implementation so that
* the event can be triggered.
*/
public function end()
public function send()
{
$this->trigger(self::EVENT_END_RESPONSE);
}
}

40
framework/yii/base/ResponseEvent.php

@ -0,0 +1,40 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\base;
/**
* ResponseEvent represents the event data for the [[Application::EVENT_RESPONSE]] event.
*
* Event handlers can modify the content in [[response]] or replace [[response]]
* with a new response object. The updated or new response will
* be used as the final out of the application.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class ResponseEvent extends Event
{
/**
* @var Response the response object associated with this event.
* You may modify the content in this response or replace it
* with a new response object. The updated or new response will
* be used as the final out.
*/
public $response;
/**
* Constructor.
* @param Response $response the response object associated with this event.
* @param array $config the configuration array for initializing the newly created object.
*/
public function __construct($response, $config = array())
{
$this->response = $response;
parent::__construct($config);
}
}

31
framework/yii/console/Application.php

@ -60,6 +60,10 @@ class Application extends \yii\base\Application
* Defaults to true.
*/
public $enableCoreCommands = true;
/**
* @var Controller the currently active controller instance
*/
public $controller;
/**
* Initialize the application.
@ -81,6 +85,24 @@ class Application extends \yii\base\Application
}
/**
* Handles the specified request.
* @param Request $request the request to be handled
* @return Response the resulting response
*/
public function handle($request)
{
list ($route, $params) = $request->resolve();
$result = $this->runAction($route, $params);
if ($result instanceof Response) {
return $result;
} else {
$response = $this->getResponse();
$response->exitStatus = (int)$result;
return $response;
}
}
/**
* Processes the request.
* The request is represented in terms of a controller route and action parameters.
* @return integer the exit status of the controller action (0 means normal, non-zero values mean abnormal)
@ -99,6 +121,15 @@ class Application extends \yii\base\Application
}
/**
* Returns the response component.
* @return Response the response component
*/
public function getResponse()
{
return $this->getComponent('response');
}
/**
* Runs a controller action specified by a route.
* This method parses the specified route and creates the corresponding child module(s), controller and action
* instances. It then calls [[Controller::runAction()]] to run the action with the given parameters.

66
framework/yii/views/errorHandler/error.php

@ -0,0 +1,66 @@
<?php
/**
* @var \Exception $exception
* @var \yii\base\ErrorHandler $context
*/
$context = $this->context;
$title = $context->htmlEncode($exception instanceof \yii\base\Exception ? $exception->getName() : get_class($exception));
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title><?php echo $title?></title>
<style>
body {
font: normal 9pt "Verdana";
color: #000;
background: #fff;
}
h1 {
font: normal 18pt "Verdana";
color: #f00;
margin-bottom: .5em;
}
h2 {
font: normal 14pt "Verdana";
color: #800000;
margin-bottom: .5em;
}
h3 {
font: bold 11pt "Verdana";
}
p {
font: normal 9pt "Verdana";
color: #000;
}
.version {
color: gray;
font-size: 8pt;
border-top: 1px solid #aaa;
padding-top: 1em;
margin-bottom: 1em;
}
</style>
</head>
<body>
<h1><?php echo $title?></h1>
<h2><?php echo nl2br($context->htmlEncode($exception->getMessage()))?></h2>
<p>
The above error occurred while the Web server was processing your request.
</p>
<p>
Please contact us if you think this is a server error. Thank you.
</p>
<div class="version">
<?php echo date('Y-m-d H:i:s', time())?>
</div>
</body>
</html>

3
framework/yii/views/errorHandler/main.php → framework/yii/views/errorHandler/exception.php

@ -2,7 +2,6 @@
/**
* @var \yii\base\View $this
* @var \Exception $exception
* @var string $request
* @var \yii\base\ErrorHandler $context
*/
$context = $this->context;
@ -389,7 +388,7 @@ pre .diff .change{
<div class="request">
<div class="code">
<pre><?php echo $context->htmlEncode($request); ?></pre>
<?php echo $context->renderRequest(); ?>
</div>
</div>

25
framework/yii/web/Application.php

@ -42,18 +42,23 @@ class Application extends \yii\base\Application
* Defaults to null, meaning catch-all is not effective.
*/
public $catchAll;
/**
* @var Controller the currently active controller instance
*/
public $controller;
/**
* Processes the request.
* @return integer the exit status of the controller action (0 means normal, non-zero values mean abnormal)
* @throws HttpException if the request cannot be resolved.
* Handles the specified request.
* @param Request $request the request to be handled
* @return Response the resulting response
* @throws HttpException if the requested route is invalid
*/
public function processRequest()
public function handle($request)
{
$request = $this->getRequest();
Yii::setAlias('@wwwroot', dirname($request->getScriptFile()));
Yii::setAlias('@www', $request->getBaseUrl());
if (empty($this->catchAll)) {
list ($route, $params) = $request->resolve();
} else {
@ -61,10 +66,18 @@ class Application extends \yii\base\Application
$params = array_splice($this->catchAll, 1);
}
try {
return $this->runAction($route, $params);
$result = $this->runAction($route, $params);
if ($result instanceof Response) {
return $result;
} else {
$response = $this->getResponse();
$response->content = $result;
return $response;
}
} catch (InvalidRouteException $e) {
throw new HttpException(404, $e->getMessage(), $e->getCode(), $e);
}
}
private $_homeUrl;

21
framework/yii/web/CaptchaAction.php

@ -116,7 +116,7 @@ class CaptchaAction extends Action
if (isset($_GET[self::REFRESH_GET_VAR])) {
// AJAX request for regenerating code
$code = $this->getVerifyCode(true);
echo json_encode(array(
return json_encode(array(
'hash1' => $this->generateValidationHash($code),
'hash2' => $this->generateValidationHash(strtolower($code)),
// we add a random 'v' parameter so that FireFox can refresh the image
@ -124,9 +124,9 @@ class CaptchaAction extends Action
'url' => $this->controller->createUrl($this->id, array('v' => uniqid())),
));
} else {
$this->renderImage($this->getVerifyCode());
$this->setHttpHeaders();
return $this->renderImage($this->getVerifyCode());
}
Yii::$app->end();
}
/**
@ -230,9 +230,9 @@ class CaptchaAction extends Action
protected function renderImage($code)
{
if (Captcha::checkRequirements() === 'gd') {
$this->renderImageByGD($code);
return $this->renderImageByGD($code);
} else {
$this->renderImageByImagick($code);
return $this->renderImageByImagick($code);
}
}
@ -277,10 +277,10 @@ class CaptchaAction extends Action
imagecolordeallocate($image, $foreColor);
$this->sendHttpHeaders();
ob_start();
imagepng($image);
imagedestroy($image);
return ob_get_clean();
}
/**
@ -317,14 +317,13 @@ class CaptchaAction extends Action
}
$image->setImageFormat('png');
Yii::$app->getResponse()->content = (string)$image;
$this->sendHttpHeaders();
return $image;
}
/**
* Sends the HTTP headers needed by image response.
* Sets the HTTP headers needed by image response.
*/
protected function sendHttpHeaders()
protected function setHttpHeaders()
{
Yii::$app->getResponse()->getHeaders()
->set('Pragma', 'public')

56
framework/yii/web/Response.php

@ -39,13 +39,10 @@ class Response extends \yii\base\Response
*/
public $statusText;
/**
* @var string the charset to use. If not set, [[\yii\base\Application::charset]] will be used.
* @var string the version of the HTTP protocol to use. If not set, it will be determined via `$_SERVER['SERVER_PROTOCOL']`,
* or '1.1' if that is not available.
*/
public $charset;
/**
* @var string the version of the HTTP protocol to use
*/
public $version = '1.0';
public $version;
/**
* @var array list of HTTP status codes and the corresponding texts
*/
@ -129,24 +126,15 @@ class Response extends \yii\base\Response
public function init()
{
if ($this->charset === null) {
$this->charset = Yii::$app->charset;
if ($this->version === null) {
if (isset($_SERVER['SERVER_PROTOCOL']) && $_SERVER['SERVER_PROTOCOL'] === '1.0') {
$this->version = '1.0';
} else {
$this->version = '1.1';
}
}
}
public function begin()
{
parent::begin();
$this->beginBuffer();
}
public function end()
{
$this->content .= $this->endBuffer();
$this->send();
parent::end();
}
/**
* @return integer the HTTP status code to send with the response.
*/
@ -204,15 +192,10 @@ class Response extends \yii\base\Response
{
$this->sendHeaders();
$this->sendContent();
for ($level = ob_get_level(); $level > 0; --$level) {
if (!@ob_end_flush()) {
ob_clean();
}
}
flush();
$this->clear();
}
public function reset()
public function clear()
{
$this->_headers = null;
$this->_statusCode = null;
@ -239,7 +222,6 @@ class Response extends \yii\base\Response
header("$name: $value", false);
}
}
$headers->removeAll();
}
$this->sendCookies();
}
@ -272,7 +254,6 @@ class Response extends \yii\base\Response
protected function sendContent()
{
echo $this->content;
$this->content = null;
}
/**
@ -298,6 +279,7 @@ class Response extends \yii\base\Response
* @param string $content the content to be sent. The existing [[content]] will be discarded.
* @param string $attachmentName the file name shown to the user.
* @param string $mimeType the MIME type of the content.
* @throws HttpException if the requested range is not satisfiable
*/
public function sendContentAsFile($content, $attachmentName, $mimeType = 'application/octet-stream')
{
@ -509,9 +491,9 @@ class Response extends \yii\base\Response
* for normal requests, and [[ajaxRedirectCode]] for AJAX requests.
* See [[http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html]]
* for details about HTTP status code
* @param boolean $terminate whether to terminate the current application
* @return Response the response object itself
*/
public function redirect($url, $statusCode = null, $terminate = true)
public function redirect($url, $statusCode = null)
{
$url = Html::url($url);
if (strpos($url, '/') === 0 && strpos($url, '//') !== 0) {
@ -522,22 +504,20 @@ class Response extends \yii\base\Response
}
$this->getHeaders()->set('Location', $url);
$this->setStatusCode($statusCode);
if ($terminate) {
Yii::$app->end();
}
return $this;
}
/**
* Refreshes the current page.
* The effect of this method call is the same as the user pressing the refresh button of his browser
* (without re-posting data).
* @param boolean $terminate whether to terminate the current application after calling this method
* @param string $anchor the anchor that should be appended to the redirection URL.
* Defaults to empty. Make sure the anchor starts with '#' if you want to specify it.
* @return Response the response object itself
*/
public function refresh($terminate = true, $anchor = '')
public function refresh($anchor = '')
{
$this->redirect(Yii::$app->getRequest()->getUrl() . $anchor, $terminate);
return $this->redirect(Yii::$app->getRequest()->getUrl() . $anchor);
}
private $_cookies;

4
framework/yii/web/User.php

@ -284,7 +284,9 @@ class User extends Component
$this->setReturnUrl($request->getUrl());
}
if ($this->loginUrl !== null) {
Yii::$app->getResponse()->redirect($this->loginUrl);
$response = Yii::$app->getResponse();
$response->redirect($this->loginUrl)->send();
exit();
} else {
throw new HttpException(403, Yii::t('yii', 'Login Required'));
}

Loading…
Cancel
Save