Browse Source

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

master
Anton Terekhov 12 years ago
parent
commit
e1c3da8019
  1. 51
      app/ErrorAction.php
  2. 6
      app/FrontController.php
  3. 45
      tests/app/ErrorActionTest.php
  4. 43
      tests/app/FrontControllerTest.php

51
app/ErrorAction.php

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

6
app/FrontController.php

@ -142,7 +142,11 @@ class FrontController
*/
$layout = new $layout_class();
$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);
}
}
}

45
tests/app/ErrorActionTest.php

@ -12,6 +12,9 @@
require_once dirname(__FILE__) . '/Action_TestCase.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
{
@ -24,10 +27,9 @@ class ErrorActionTest extends Action_TestCase
$this->log = ini_get('error_log');
ini_set('error_log', '/dev/null');
set_exit_overload(function()
{
return false;
});
set_exit_overload(function () {
return false;
});
}
/**
@ -96,13 +98,15 @@ class ErrorActionTest extends Action_TestCase
public function testError404WithAjax()
{
$this->setConstants(false);
$exception = $this->getMock('Error404Exception', array('getMessage', 'getFile', 'getLine', 'getTrace'));
$exception->expects($this->once())
->method('getTrace')
->will($this->returnValue(array('one' => array('class' => 'AjaxAction'))));
$exception = new Error404Exception('Some message');
$controller = FrontController::getInstance();
$controller->setView('SomeView');
$action = new ErrorAction($exception);
$action->setAjaxError();
$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()
{
$this->setConstants(false);
$exception = $this->getMock('Error404Exception', array('getMessage', 'getFile', 'getLine', 'getTrace'));
$exception->expects($this->once())
->method('getTrace')
->will($this->returnValue(array('one' => array('class' => 'Action'))));
$exception = new Error404Exception('Some message');
$controller = FrontController::getInstance();
$controller->setView('SomeView');
$action = new ErrorAction($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)

43
tests/app/FrontControllerTest.php

@ -26,10 +26,9 @@ require_once dirname(__FILE__) . '/../../app/FrontController.php';
require_once dirname(__FILE__) . '/../../app/Action.php';
require_once dirname(__FILE__) . '/../../app/AjaxAction.php';
class FrontControllerTest extends PHPUnit_Framework_TestCase
{
public function run(PHPUnit_Framework_TestResult $result = NULL)
{
$this->setPreserveGlobalState(false);
@ -133,6 +132,8 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
{
$this->setConstants(false);
$controller = FrontController::getInstance();
$result = $controller->execute();
$controller = FrontController::getInstance();
$this->assertNull($controller->execute());
}
@ -193,6 +194,24 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
$result = $controller->execute();
$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
*/
@ -209,6 +228,23 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
$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)
{
@ -237,6 +273,9 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
}
}
/**
* Used in testExecuteWithAjaxAction
*/
class NewAjaxAction extends AjaxAction{
protected function execute() {}
}
Loading…
Cancel
Save