Reworked AJax action HTTP code and HTTP content. Added new HTTP template to process HTTP code output

This commit is contained in:
Anton Terekhov
2012-11-11 20:42:48 +04:00
parent 618f12224e
commit e1c3da8019
4 changed files with 106 additions and 39 deletions

View File

@ -5,18 +5,18 @@
* @package Majestic * @package Majestic
* @subpackage app * @subpackage app
* @since 2010-02-25 * @since 2010-02-25
* @version SVN: $Id$
* @filesource $URL$
*/ */
class ErrorAction extends Action class ErrorAction extends Action
{ {
/** /**
* @var ErrorException * @var ErrorException|ErrorHTTPException
*/ */
public $exception; public $exception;
protected $ajax_error = false;
public function __construct($exception) public function __construct($exception)
{ {
$this->exception = $exception; $this->exception = $exception;
@ -27,18 +27,22 @@ class ErrorAction extends Action
{ {
$this->template = 500; $this->template = 500;
if ($this->exception instanceof Error404Exception) { if ($this->exception instanceof Error404Exception) {
if ($this->isAjaxActionError()) {
if (!headers_sent()) {
header('HTTP/1.0 404 Not Found');
die();
}
}
$this->template = 404; $this->template = 404;
} elseif ($this->exception instanceof ErrorHTTPException) {
$this->template = 'HTTP';
} }
$this->logError(); $this->logError();
$this->sendHTTPCode(); $this->sendHTTPCode();
} }
public function fetch()
{
if ($this->isAjaxActionError()) {
return $this->exception->getMessage();
}
return parent::fetch();
}
protected function getTemplate() protected function getTemplate()
{ {
return '/actions/' . $this->template; return '/actions/' . $this->template;
@ -46,12 +50,10 @@ class ErrorAction extends Action
protected function sendHttpCode() protected function sendHttpCode()
{ {
if (headers_sent()) {
return;
}
switch ($this->template) { switch ($this->template) {
case 404: case 404:
header('HTTP/1.0 404 Not Found'); case 'HTTP':
header($this->exception->getHTTPHeader());
break; break;
default: default:
header('HTTP/1.0 500 Internal Server Error'); header('HTTP/1.0 500 Internal Server Error');
@ -61,7 +63,6 @@ class ErrorAction extends Action
protected function logError() protected function logError()
{ {
if ($this->template == 500) { if ($this->template == 500) {
$error = 0; $error = 0;
$ex = $this->exception; $ex = $this->exception;
if ($ex instanceof ErrorException) { if ($ex instanceof ErrorException) {
@ -94,12 +95,14 @@ class ErrorAction extends Action
*/ */
protected function isAjaxActionError() protected function isAjaxActionError()
{ {
$trace = $this->exception->getTrace(); return $this->ajax_error;
foreach ($trace as $line) { }
if (isset($line['class']) && $line['class'] === 'AjaxAction') {
return true; /**
} * Set if exception was thrown from AjaxAction subclass
} */
return false; public function setAjaxError()
{
$this->ajax_error = true;
} }
} }

View File

@ -142,7 +142,11 @@ class FrontController
*/ */
$layout = new $layout_class(); $layout = new $layout_class();
$layout->setException($e); $layout->setException($e);
return $layout->fetch(new ErrorAction($e)); $error_action = new ErrorAction($e);
if (isset($action) && is_subclass_of($action, 'AjaxAction')) {
$error_action->setAjax();
}
return $layout->fetch($error_action);
} }
} }
} }

View File

@ -12,6 +12,9 @@
require_once dirname(__FILE__) . '/Action_TestCase.php'; require_once dirname(__FILE__) . '/Action_TestCase.php';
require_once dirname(__FILE__) . '/../../app/ErrorAction.php'; require_once dirname(__FILE__) . '/../../app/ErrorAction.php';
require_once dirname(__FILE__) . '/../../exception/GeneralException.php';
require_once dirname(__FILE__) . '/../../exception/ErrorHTTPException.php';
require_once dirname(__FILE__) . '/../../exception/Error404Exception.php';
class ErrorActionTest extends Action_TestCase class ErrorActionTest extends Action_TestCase
{ {
@ -24,8 +27,7 @@ class ErrorActionTest extends Action_TestCase
$this->log = ini_get('error_log'); $this->log = ini_get('error_log');
ini_set('error_log', '/dev/null'); ini_set('error_log', '/dev/null');
set_exit_overload(function() set_exit_overload(function () {
{
return false; return false;
}); });
} }
@ -96,13 +98,15 @@ class ErrorActionTest extends Action_TestCase
public function testError404WithAjax() public function testError404WithAjax()
{ {
$this->setConstants(false); $this->setConstants(false);
$exception = $this->getMock('Error404Exception', array('getMessage', 'getFile', 'getLine', 'getTrace')); $exception = new Error404Exception('Some message');
$exception->expects($this->once())
->method('getTrace')
->will($this->returnValue(array('one' => array('class' => 'AjaxAction'))));
$controller = FrontController::getInstance();
$controller->setView('SomeView');
$action = new ErrorAction($exception); $action = new ErrorAction($exception);
$action->setAjaxError();
$this->assertSame($exception, $action->exception); $this->assertSame($exception, $action->exception);
$result = $action->fetch();
$this->assertSame('Some message', $result);
} }
/** /**
@ -111,13 +115,30 @@ class ErrorActionTest extends Action_TestCase
public function testError404NoAjax() public function testError404NoAjax()
{ {
$this->setConstants(false); $this->setConstants(false);
$exception = $this->getMock('Error404Exception', array('getMessage', 'getFile', 'getLine', 'getTrace')); $exception = new Error404Exception('Some message');
$exception->expects($this->once())
->method('getTrace')
->will($this->returnValue(array('one' => array('class' => 'Action'))));
$controller = FrontController::getInstance();
$controller->setView('SomeView');
$action = new ErrorAction($exception); $action = new ErrorAction($exception);
$this->assertSame($exception, $action->exception); $this->assertSame($exception, $action->exception);
$result = $action->fetch();
$this->assertSame('/actions/404', $result['template']);
}
/**
* @runInSeparateProcess
*/
public function testErrorHTTP()
{
$this->setConstants(false);
$exception = new ErrorHTTPException('Some message', 410);
$controller = FrontController::getInstance();
$controller->setView('SomeView');
$action = new ErrorAction($exception);
$this->assertSame($exception, $action->exception);
$result = $action->fetch();
$this->assertSame('/actions/HTTP', $result['template']);
} }
private function setConstants($val = false) private function setConstants($val = false)

View File

@ -26,7 +26,6 @@ require_once dirname(__FILE__) . '/../../app/FrontController.php';
require_once dirname(__FILE__) . '/../../app/Action.php'; require_once dirname(__FILE__) . '/../../app/Action.php';
require_once dirname(__FILE__) . '/../../app/AjaxAction.php'; require_once dirname(__FILE__) . '/../../app/AjaxAction.php';
class FrontControllerTest extends PHPUnit_Framework_TestCase class FrontControllerTest extends PHPUnit_Framework_TestCase
{ {
@ -133,6 +132,8 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
{ {
$this->setConstants(false); $this->setConstants(false);
$controller = FrontController::getInstance(); $controller = FrontController::getInstance();
$result = $controller->execute();
$controller = FrontController::getInstance();
$this->assertNull($controller->execute()); $this->assertNull($controller->execute());
} }
@ -193,6 +194,24 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
$result = $controller->execute(); $result = $controller->execute();
$this->assertNull($result); $this->assertNull($result);
} }
/**
* @runInSeparateProcess
*/
public function testExecuteWithLayoutProfiler()
{
Config::set('PROFILER', true);
$this->getMock('userAction');
$this->getMock('DefaultLayout', array('fetch'), array(), 'DefaultLayoutMock');
$_SERVER['REQUEST_URI'] = '/user/account/213';
$this->setConstants(true);
$controller = FrontController::getInstance();
$router = $controller->getRouter();
$router->add('user', 'user/account/:id', 'user');
$result = $controller->execute();
$this->assertNull($result);
}
/** /**
* @runInSeparateProcess * @runInSeparateProcess
*/ */
@ -209,6 +228,23 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
$this->assertNull($result); $this->assertNull($result);
} }
/**
* @runInSeparateProcess
*/
public function testExecuteWithAjaxActionProfiler()
{
Config::set('PROFILER', true);
$this->getMock('userAction');
$this->getMock('DefaultLayout', array('fetch'), array(), 'DefaultLayoutMock');
$_SERVER['REQUEST_URI'] = '/user/account/213';
$this->setConstants(true);
$controller = FrontController::getInstance();
$router = $controller->getRouter();
$router->add('user', 'user/account/:id', 'NewAjax');
$result = $controller->execute();
$this->assertNull($result);
}
private function setConstants($val = false) private function setConstants($val = false)
{ {
@ -237,6 +273,9 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
} }
} }
/**
* Used in testExecuteWithAjaxAction
*/
class NewAjaxAction extends AjaxAction{ class NewAjaxAction extends AjaxAction{
protected function execute() {} protected function execute() {}
} }