summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes2
-rw-r--r--framework/Exceptions/TErrorHandler.php102
-rw-r--r--framework/Exceptions/TException.php41
-rw-r--r--framework/Exceptions/error.en27
-rw-r--r--framework/Exceptions/error404.en29
-rw-r--r--framework/Exceptions/exception.en37
-rw-r--r--framework/Exceptions/messages.en3
-rw-r--r--framework/Web/Services/TPageService.php6
-rw-r--r--framework/Web/THttpResponse.php17
9 files changed, 209 insertions, 55 deletions
diff --git a/.gitattributes b/.gitattributes
index e6ac9fcb..a052d5d9 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -40,6 +40,8 @@ framework/Data/TXmlDocument.php -text
framework/Exceptions/TErrorHandler.php -text
framework/Exceptions/TException.php -text
framework/Exceptions/error.en -text
+framework/Exceptions/error404.en -text
+framework/Exceptions/exception.en -text
framework/Exceptions/messages.en -text
framework/IO/TTextWriter.php -text
framework/Security/TAuthManager.php -text
diff --git a/framework/Exceptions/TErrorHandler.php b/framework/Exceptions/TErrorHandler.php
index 9af83d5e..687351d5 100644
--- a/framework/Exceptions/TErrorHandler.php
+++ b/framework/Exceptions/TErrorHandler.php
@@ -10,6 +10,10 @@ class TErrorHandler extends TComponent implements IModule
* @var TApplication application instance
*/
private $_application;
+ /**
+ * @var array list of pages for displaying various HTTP errors
+ */
+ private $_errorPages=array();
/**
* Initializes the module.
@@ -22,6 +26,8 @@ class TErrorHandler extends TComponent implements IModule
$this->_application=$application;
$application->attachEventHandler('Error',array($this,'handleError'));
$application->setErrorHandler($this);
+ foreach($config->getElementsByTagName('error') as $node)
+ $this->_errorPages[$node->getAttribute('code')]=$node->getAttribute('page');
}
/**
@@ -42,19 +48,83 @@ class TErrorHandler extends TComponent implements IModule
public function handleError($sender,$param)
{
- if(($response=Prado::getApplication()->getResponse())!==null)
- $response->clear();
- switch(Prado::getApplication()->getMode())
+ static $handling=false;
+ if($handling)
+ $this->handleRecursiveError($param);
+ else
{
- case 'Off':
- case 'Debug':
+ $handling=true;
+ if(($response=Prado::getApplication()->getResponse())!==null)
+ $response->clear();
+ if($param instanceof THttpException)
+ $this->handleExternalError($param->getStatusCode(),$param);
+ else if(Prado::getApplication()->getMode()==='Debug')
$this->displayException($param);
- exit(1);
- case 'Normal':
- case 'Performance':
- error_log($param->__toString());
- header("HTTP/1.0 500 Internal Error");
- exit(1);
+ else
+ $this->handleExternalError(500,$param);
+ }
+ exit(1);
+ }
+
+ protected function handleExternalError($statusCode,$exception)
+ {
+ if(!($exception instanceof THttpException))
+ error_log($exception->__toString());
+ if(isset($this->_errorPages["$statusCode"]))
+ {
+ $page=Prado::createComponent($this->_errorPages["$statusCode"]);
+ $writer=new THtmlTextWriter($this->_application->getResponse());
+ $page->run($writer);
+ $writer->flush();
+ }
+ else
+ {
+ $base=dirname(__FILE__).'/error';
+ $languages=Prado::getUserLanguages();
+ $lang=$languages[0];
+ if(is_file("$base$statusCode.$lang"))
+ $errorFile="$base$statusCode.$lang";
+ else if(is_file("$base$statusCode.en"))
+ $errorFile="$base$statusCode.en";
+ else if(is_file("$base.$lang"))
+ $errorFile="$base.$lang";
+ else
+ $errorFile="$base.en";
+ if(($content=@file_get_contents($errorFile))===false)
+ die("Unable to open error template file '$errorFile'.");
+
+ $serverAdmin=isset($_SERVER['SERVER_ADMIN'])?$_SERVER['SERVER_ADMIN']:'';
+ $fields=array(
+ '%%StatusCode%%',
+ '%%ErrorMessage%%',
+ '%%ServerAdmin%%',
+ '%%Version%%',
+ '%%Time%%'
+ );
+ $values=array(
+ "$statusCode",
+ htmlspecialchars($exception->getMessage()),
+ $serverAdmin,
+ $_SERVER['SERVER_SOFTWARE'].' <a href="http://www.pradosoft.com/">PRADO</a>/'.Prado::getVersion(),
+ strftime('%Y-%m-%d %H:%m',time())
+ );
+ echo str_replace($fields,$values,$content);
+ }
+ }
+
+ protected function handleRecursiveError($exception)
+ {
+ if(Prado::getApplication()->getMode()==='Debug')
+ {
+ echo "<html><head><title>Recursive Error</title></head>\n";
+ echo "<body><h1>Recursive Error</h1>\n";
+ echo "<pre>".$exception."</pre>\n";
+ echo "</body></html>";
+ }
+ else
+ {
+ error_log("Error happened while processing an existing error:\n".$param->__toString());
+ header('HTTP/1.0 500 Internal Error');
}
}
@@ -94,11 +164,11 @@ class TErrorHandler extends TComponent implements IModule
strftime('%Y-%m-%d %H:%m',time())
);
$languages=Prado::getUserLanguages();
- $errorFile=dirname(__FILE__).'/error.'.$languages[0];
- if(!is_file($errorFile))
- $errorFile=dirname(__FILE__).'/error.en';
- if(($content=@file_get_contents($errorFile))===false)
- die("Unable to open error template file '$errorFile'.");
+ $exceptionFile=dirname(__FILE__).'/exception.'.$languages[0];
+ if(!is_file($exceptionFile))
+ $exceptionFile=dirname(__FILE__).'/exception.en';
+ if(($content=@file_get_contents($exceptionFile))===false)
+ die("Unable to open exception template file '$errorFile'.");
echo str_replace($fields,$values,$content);
}
}
diff --git a/framework/Exceptions/TException.php b/framework/Exceptions/TException.php
index 0bc963f8..a90c14dd 100644
--- a/framework/Exceptions/TException.php
+++ b/framework/Exceptions/TException.php
@@ -40,16 +40,16 @@ class TException extends Exception
{
private $_errorCode='';
- public function __construct($errorCode)
+ public function __construct($errorMessage)
{
- $this->_errorCode=$errorCode;
+ $this->_errorCode=$errorMessage;
$args=func_get_args();
- $args[0]=$this->translateErrorCode($errorCode);
+ $args[0]=$this->translateErrorMessage($errorMessage);
$str=call_user_func_array('sprintf',$args);
parent::__construct($str);
}
- protected function translateErrorCode($key)
+ protected function translateErrorMessage($key)
{
$languages=Prado::getUserLanguages();
$msgFile=dirname(__FILE__).'/messages.'.$languages[0];
@@ -74,20 +74,10 @@ class TException extends Exception
return $this->_errorCode;
}
- public function setErrorCode($errorCode)
- {
- $this->_errorCode=$errorCode;
- }
-
public function getErrorMessage()
{
return $this->getMessage();
}
-
- public function setErrorMessage($msg)
- {
- $this->message=$msg;
- }
}
class TSystemException extends TException
@@ -142,10 +132,6 @@ class TSecurityException extends TException
{
}
-class THttpException extends TException
-{
-}
-
class TNotSupportedException extends TException
{
}
@@ -173,4 +159,23 @@ class TPhpErrorException extends TException
}
}
+
+class THttpException extends TException
+{
+ private $_statusCode;
+
+ public function __construct($statusCode,$errorMessage)
+ {
+ $args=func_get_args();
+ array_shift($args);
+ call_user_func_array(array('parent', '__construct'), $args);
+ $this->_statusCode=TPropertyValue::ensureInteger($statusCode);
+ }
+
+ public function getStatusCode()
+ {
+ return $this->_statusCode;
+ }
+}
+
?> \ No newline at end of file
diff --git a/framework/Exceptions/error.en b/framework/Exceptions/error.en
index 1d76c7f2..cff0f910 100644
--- a/framework/Exceptions/error.en
+++ b/framework/Exceptions/error.en
@@ -1,34 +1,25 @@
<html>
<head>
-<title>%%ErrorType%%</title>
+<title>%%ErrorMessage%%</title>
<style>
body {font-family:"Verdana";font-weight:normal;color:black;}
h1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
h2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
h3 {font-family:"Verdana";font-weight:bold;font-size:11pt}
p {font-family:"Verdana";font-weight:normal;color:black;font-size:9pt;margin-top: -5px}
-code,pre {font-family:"Lucida Console";}
-td,.version {color: gray;font-size:8pt;border-top:1px solid #aaaaaa;}
-.source {font-family:"Lucida Console";font-weight:normal;background-color:#ffffee;}
+.version {color: gray;font-size:8pt;border-top:1px solid #aaaaaa;}
</style>
</head>
<body bgcolor="white">
-<h1>%%ErrorType%%</h1>
-<h3>Description</h3>
-<p style="color:maroon">%%ErrorMessage%%</p>
+<h1>Error %%StatusCode%%</h1>
+<h2>%%ErrorMessage%%</h2>
<p>
-<h3>Source File</h3>
-<p>%%SourceFile%%</p>
-<div class="source">
-%%SourceCode%%
-</div>
-<h3>Stack Trace</h3>
-<div class="source">
-<code><pre>
-%%StackTrace%%
-</pre></code>
-</div>
+The above error happened when the server was processing your request.
+</p>
+<p>
+If you think this is a server error, please contact the <a href="mailto:%%ServerAdmin%%">webmaster</a>.
+</p>
<div class="version">
%%Version%%<br/>
%%Time%%
diff --git a/framework/Exceptions/error404.en b/framework/Exceptions/error404.en
new file mode 100644
index 00000000..11585661
--- /dev/null
+++ b/framework/Exceptions/error404.en
@@ -0,0 +1,29 @@
+<html>
+<head>
+<title>Page Not Found</title>
+<style>
+body {font-family:"Verdana";font-weight:normal;color:black;}
+h1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
+h2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
+h3 {font-family:"Verdana";font-weight:bold;font-size:11pt}
+p {font-family:"Verdana";font-weight:normal;color:black;font-size:9pt;margin-top: -5px}
+.version {color: gray;font-size:8pt;border-top:1px solid #aaaaaa;}
+</style>
+</head>
+
+<body bgcolor="white">
+<h1>%%ErrorMessage%%</h1>
+<h2>Error 404</h2>
+<p>
+The requested URL was not found on this server.
+If you entered the URL manually please check your spelling and try again.
+</p>
+<p>
+If you think this is a server error, please contact the <a href="mailto:%%ServerAdmin%%">webmaster</a>.
+</p>
+<div class="version">
+%%Version%%<br/>
+%%Time%%
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/framework/Exceptions/exception.en b/framework/Exceptions/exception.en
new file mode 100644
index 00000000..1d76c7f2
--- /dev/null
+++ b/framework/Exceptions/exception.en
@@ -0,0 +1,37 @@
+<html>
+<head>
+<title>%%ErrorType%%</title>
+<style>
+body {font-family:"Verdana";font-weight:normal;color:black;}
+h1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
+h2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
+h3 {font-family:"Verdana";font-weight:bold;font-size:11pt}
+p {font-family:"Verdana";font-weight:normal;color:black;font-size:9pt;margin-top: -5px}
+code,pre {font-family:"Lucida Console";}
+td,.version {color: gray;font-size:8pt;border-top:1px solid #aaaaaa;}
+.source {font-family:"Lucida Console";font-weight:normal;background-color:#ffffee;}
+</style>
+</head>
+
+<body bgcolor="white">
+<h1>%%ErrorType%%</h1>
+<h3>Description</h3>
+<p style="color:maroon">%%ErrorMessage%%</p>
+<p>
+<h3>Source File</h3>
+<p>%%SourceFile%%</p>
+<div class="source">
+%%SourceCode%%
+</div>
+<h3>Stack Trace</h3>
+<div class="source">
+<code><pre>
+%%StackTrace%%
+</pre></code>
+</div>
+<div class="version">
+%%Version%%<br/>
+%%Time%%
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/framework/Exceptions/messages.en b/framework/Exceptions/messages.en
index 9c5dae1c..688901c2 100644
--- a/framework/Exceptions/messages.en
+++ b/framework/Exceptions/messages.en
@@ -43,6 +43,9 @@ assetmanager_basepath_invalid = TAssetManager.BasePath '%s' is invalid. Make s
assetmanager_basepath_unchangeable = TAssetManager.BasePath cannot be modified after the module is initialized.
assetmanager_baseurl_unchangeable = TAssetManager.BaseUrl cannot be modified after the module is initialized.
+pageservice_page_unknown = Page not found: %s
+
+
body_contents_not_allowed = %s: body contents are not allowed.
control_id_not_unique = Control ID '%s' is not unique for control type '%s'.
control_not_found = Unable to find a control with ID '%s'.
diff --git a/framework/Web/Services/TPageService.php b/framework/Web/Services/TPageService.php
index 0ed4c67f..df239088 100644
--- a/framework/Web/Services/TPageService.php
+++ b/framework/Web/Services/TPageService.php
@@ -97,7 +97,7 @@ class TPageService extends TComponent implements IService
if(empty($this->_pagePath))
$this->_pagePath=$this->_defaultPage;
if(empty($this->_pagePath))
- throw new THttpException('pageservice_page_required');
+ throw new THttpException(400,'pageservice_page_required');
if(($cache=$application->getCache())===null)
{
@@ -328,7 +328,7 @@ class TPageService extends TComponent implements IService
if(class_exists($className,false))
$page=new $className($this->_properties);
else
- throw new THttpException('pageservice_page_unknown',$this->_pageType);
+ throw new THttpException(404,'pageservice_page_unknown',$this->_pageType);
$writer=new THtmlTextWriter($this->_application->getResponse());
$page->run($writer);
$writer->flush();
@@ -653,7 +653,7 @@ class TPageConfiguration extends TComponent
}
}
if($page!==null && $this->_pageType===null)
- throw new THttpException('pageservice_page_inexistent',$page);
+ throw new THttpException(404,'pageservice_page_unknown',$page);
}
}
diff --git a/framework/Web/THttpResponse.php b/framework/Web/THttpResponse.php
index 7f70de63..94f02b7c 100644
--- a/framework/Web/THttpResponse.php
+++ b/framework/Web/THttpResponse.php
@@ -34,6 +34,23 @@
*/
class THttpResponse extends TComponent implements IModule, ITextWriter
{
+ const STATUS_CONTINUE=100;
+ const STATUS_SWITCHINGPROTOCOLS=101;
+ const STATUS_OK=200;
+ const STATUS_CREATED=201;
+ const STATUS_ACCEPTED=202;
+ const STATUS_NONAUTHORITATIVEINFORMATION=203;
+ const STATUS_NOCONTENT=204;
+ const STATUS_RESETCONTENT=205;
+ const STATUS_PARTIALCONTENT=206;
+ const STATUS_MULTIPLE_CHOICES=300;
+ const STATUS_MOVEDPERMANENTLY=301;
+ const STATUS_FOUND=302;
+ const STATUS_SEEOTHER=303;
+ const STATUS_NOTMODIFIED=304;
+ const STATUS_USEPROXY=305;
+ const STATUS_TEMPORARYREDIRECT=306;
+ const STATUS_BADREQUEST=400;
/**
* @var string id of this module (response)
*/