summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--framework/Exceptions/TErrorHandler.php4
-rw-r--r--framework/Exceptions/templates/error-fr.html17
-rw-r--r--framework/Exceptions/templates/error-zh.html17
-rw-r--r--framework/Exceptions/templates/error.html59
-rw-r--r--framework/Exceptions/templates/error404-en.html61
-rw-r--r--framework/Exceptions/templates/error404-fr.html17
-rw-r--r--framework/Exceptions/templates/error404-zh.html17
-rw-r--r--framework/Exceptions/templates/error404.html17
-rw-r--r--framework/Exceptions/templates/error500-en.html17
-rw-r--r--framework/Exceptions/templates/error500-fr.html17
-rw-r--r--framework/Exceptions/templates/error500-zh.html17
-rw-r--r--framework/Exceptions/templates/error500.html17
-rw-r--r--framework/Exceptions/templates/error503-en.html17
-rw-r--r--framework/Exceptions/templates/error503-fr.html17
-rw-r--r--framework/Exceptions/templates/error503-zh.html17
-rw-r--r--framework/Exceptions/templates/error503.html17
-rw-r--r--framework/Exceptions/templates/exception-en.html19
-rw-r--r--framework/Exceptions/templates/exception-fr.html18
-rw-r--r--framework/Exceptions/templates/exception-zh.html17
-rw-r--r--framework/Exceptions/templates/exception.html19
-rw-r--r--framework/TApplication.php1816
-rw-r--r--framework/prado.php117
22 files changed, 1201 insertions, 1150 deletions
diff --git a/framework/Exceptions/TErrorHandler.php b/framework/Exceptions/TErrorHandler.php
index ebdaf41c..87d5d342 100644
--- a/framework/Exceptions/TErrorHandler.php
+++ b/framework/Exceptions/TErrorHandler.php
@@ -178,7 +178,7 @@ class TErrorHandler extends TModule
'%%ErrorMessage%%' => htmlspecialchars($exception->getMessage()),
'%%ServerAdmin%%' => $serverAdmin,
'%%Version%%' => $_SERVER['SERVER_SOFTWARE'].' <a href="http://www.pradosoft.com/">PRADO</a>/'.Prado::getVersion(),
- '%%Time%%' => strftime('%Y-%m-%d %H:%m',time())
+ '%%Time%%' => @strftime('%Y-%m-%d %H:%M',time())
);
echo strtr($content,$tokens);
}
@@ -240,7 +240,7 @@ class TErrorHandler extends TModule
'%%SourceCode%%' => $source,
'%%StackTrace%%' => htmlspecialchars($exception->getTraceAsString()),
'%%Version%%' => $_SERVER['SERVER_SOFTWARE'].' <a href="http://www.pradosoft.com/">PRADO</a>/'.Prado::getVersion(),
- '%%Time%%' => strftime('%Y-%m-%d %H:%m',time())
+ '%%Time%%' => @strftime('%Y-%m-%d %H:%M',time())
);
$lang=Prado::getPreferredLanguage();
$exceptionFile=Prado::getFrameworkPath().'/Exceptions/templates/'.self::EXCEPTION_FILE_NAME.'-'.$lang.'.html';
diff --git a/framework/Exceptions/templates/error-fr.html b/framework/Exceptions/templates/error-fr.html
index 5546dcdb..47b681de 100644
--- a/framework/Exceptions/templates/error-fr.html
+++ b/framework/Exceptions/templates/error-fr.html
@@ -1,19 +1,20 @@
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="fr"/>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<title>%%ErrorMessage%%</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>Erreur %%StatusCode%%</h1>
<h2>%%ErrorMessage%%</h2>
<p>
diff --git a/framework/Exceptions/templates/error-zh.html b/framework/Exceptions/templates/error-zh.html
index 545f057c..f69d0e49 100644
--- a/framework/Exceptions/templates/error-zh.html
+++ b/framework/Exceptions/templates/error-zh.html
@@ -1,19 +1,22 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh" lang="zh">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="zh"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>%%ErrorMessage%%</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>错误%%StatusCode%%</h1>
<h2>%%ErrorMessage%%</h2>
<p>
diff --git a/framework/Exceptions/templates/error.html b/framework/Exceptions/templates/error.html
index 931f96a3..482da4cd 100644
--- a/framework/Exceptions/templates/error.html
+++ b/framework/Exceptions/templates/error.html
@@ -1,29 +1,32 @@
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="en"/>
-<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}
-.version {color: gray;font-size:8pt;border-top:1px solid #aaaaaa;}
-</style>
-</head>
-
-<body bgcolor="white">
-<h1>Error %%StatusCode%%</h1>
-<h2>%%ErrorMessage%%</h2>
-<p>
-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">
-%%Time%% %%Version%%
-</div>
-</body>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<title>%%ErrorMessage%%</title>
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
+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>
+<h1>Error %%StatusCode%%</h1>
+<h2>%%ErrorMessage%%</h2>
+<p>
+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">
+%%Time%% %%Version%%
+</div>
+</body>
</html> \ No newline at end of file
diff --git a/framework/Exceptions/templates/error404-en.html b/framework/Exceptions/templates/error404-en.html
index 92ac65b1..abbc84a6 100644
--- a/framework/Exceptions/templates/error404-en.html
+++ b/framework/Exceptions/templates/error404-en.html
@@ -1,30 +1,33 @@
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="en"/>
-<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">
-%%Time%% %%Version%%
-</div>
-</body>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<title>Page Not Found</title>
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
+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>
+<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">
+%%Time%% %%Version%%
+</div>
+</body>
</html> \ No newline at end of file
diff --git a/framework/Exceptions/templates/error404-fr.html b/framework/Exceptions/templates/error404-fr.html
index 181bd8a7..c353d7c1 100644
--- a/framework/Exceptions/templates/error404-fr.html
+++ b/framework/Exceptions/templates/error404-fr.html
@@ -1,19 +1,20 @@
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="fr"/>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<title>Page Introuvable</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>%%ErrorMessage%%</h1>
<h2>Erreur 404</h2>
<p>
diff --git a/framework/Exceptions/templates/error404-zh.html b/framework/Exceptions/templates/error404-zh.html
index ae5d8275..c834f9b1 100644
--- a/framework/Exceptions/templates/error404-zh.html
+++ b/framework/Exceptions/templates/error404-zh.html
@@ -1,19 +1,22 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh" lang="zh">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="zh"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>无法找到页面</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>%%ErrorMessage%%</h1>
<h2>错误代码404</h2>
<p>
diff --git a/framework/Exceptions/templates/error404.html b/framework/Exceptions/templates/error404.html
index 92ac65b1..1ad3c0ac 100644
--- a/framework/Exceptions/templates/error404.html
+++ b/framework/Exceptions/templates/error404.html
@@ -1,19 +1,22 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="en"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Page Not Found</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>%%ErrorMessage%%</h1>
<h2>Error 404</h2>
<p>
diff --git a/framework/Exceptions/templates/error500-en.html b/framework/Exceptions/templates/error500-en.html
index 25d4ad92..76427f43 100644
--- a/framework/Exceptions/templates/error500-en.html
+++ b/framework/Exceptions/templates/error500-en.html
@@ -1,19 +1,22 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="en"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Internal Server Error</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>Internal Server Error</h1>
<h2>%%ErrorMessage%%</h2>
<p>
diff --git a/framework/Exceptions/templates/error500-fr.html b/framework/Exceptions/templates/error500-fr.html
index 804425ef..0454e27d 100644
--- a/framework/Exceptions/templates/error500-fr.html
+++ b/framework/Exceptions/templates/error500-fr.html
@@ -1,19 +1,20 @@
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="fr"/>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<title>Erreur Interne du Serveur</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>Erreur Interne du Serveur</h1>
<h2>%%ErrorMessage%%</h2>
<p>
diff --git a/framework/Exceptions/templates/error500-zh.html b/framework/Exceptions/templates/error500-zh.html
index a10dbba4..d655601f 100644
--- a/framework/Exceptions/templates/error500-zh.html
+++ b/framework/Exceptions/templates/error500-zh.html
@@ -1,19 +1,22 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh" lang="zh">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="zh"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>服务器内部错误</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>服务器内部错误</h1>
<h2>%%ErrorMessage%%</h2>
<p>
diff --git a/framework/Exceptions/templates/error500.html b/framework/Exceptions/templates/error500.html
index 25d4ad92..76427f43 100644
--- a/framework/Exceptions/templates/error500.html
+++ b/framework/Exceptions/templates/error500.html
@@ -1,19 +1,22 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="en"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Internal Server Error</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>Internal Server Error</h1>
<h2>%%ErrorMessage%%</h2>
<p>
diff --git a/framework/Exceptions/templates/error503-en.html b/framework/Exceptions/templates/error503-en.html
index 718dd4ea..3a5390de 100644
--- a/framework/Exceptions/templates/error503-en.html
+++ b/framework/Exceptions/templates/error503-en.html
@@ -1,19 +1,22 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="en"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Service Unavailable</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>Service Unavailable</h1>
<p>
Our system is currently under maintenance. Please come back later.
diff --git a/framework/Exceptions/templates/error503-fr.html b/framework/Exceptions/templates/error503-fr.html
index 699114de..ddc7d537 100644
--- a/framework/Exceptions/templates/error503-fr.html
+++ b/framework/Exceptions/templates/error503-fr.html
@@ -1,19 +1,20 @@
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="fr"/>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<title>Service Indisponible</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>Service Indisponible</h1>
<p>
Le service est actuellement en maintenance et indisponible. Merci de réessayer prochainement.
diff --git a/framework/Exceptions/templates/error503-zh.html b/framework/Exceptions/templates/error503-zh.html
index 5babac19..b7457d68 100644
--- a/framework/Exceptions/templates/error503-zh.html
+++ b/framework/Exceptions/templates/error503-zh.html
@@ -1,19 +1,22 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh" lang="zh">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="zh"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>系统无法提供服务</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>系统无法提供服务</h1>
<p>
系统维护中,请稍后再来访问。
diff --git a/framework/Exceptions/templates/error503.html b/framework/Exceptions/templates/error503.html
index 718dd4ea..3a5390de 100644
--- a/framework/Exceptions/templates/error503.html
+++ b/framework/Exceptions/templates/error503.html
@@ -1,19 +1,22 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="en"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Service Unavailable</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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">
+<body>
<h1>Service Unavailable</h1>
<p>
Our system is currently under maintenance. Please come back later.
diff --git a/framework/Exceptions/templates/exception-en.html b/framework/Exceptions/templates/exception-en.html
index 45fc264c..2de7f5f1 100644
--- a/framework/Exceptions/templates/exception-en.html
+++ b/framework/Exceptions/templates/exception-en.html
@@ -1,10 +1,13 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="en"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>%%ErrorType%%</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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}
@@ -12,15 +15,13 @@ p {font-family:"Verdana";font-weight:normal;color:black;font-size:9pt;margin-top
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;}
-.error {background-color: #ffeeee;}
+.error {background-color: #ffeeee;}/*]]>*/
</style>
</head>
-
-<body bgcolor="white">
+<body>
<h1>%%ErrorType%%</h1>
<h3>Description</h3>
<p style="color:maroon">%%ErrorMessage%%</p>
-<p>
<h3>Source File</h3>
<p>%%SourceFile%%</p>
<div class="source">
diff --git a/framework/Exceptions/templates/exception-fr.html b/framework/Exceptions/templates/exception-fr.html
index b6f1369b..002a4583 100644
--- a/framework/Exceptions/templates/exception-fr.html
+++ b/framework/Exceptions/templates/exception-fr.html
@@ -1,10 +1,11 @@
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="fr"/>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<title>%%ErrorType%%</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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}
@@ -13,14 +14,13 @@ 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;}
.error {background-color: #ffeeee;}
+/*]]>*/
</style>
</head>
-
-<body bgcolor="white">
+<body>
<h1>%%ErrorType%%</h1>
<h3>Description</h3>
<p style="color:maroon">%%ErrorMessage%%</p>
-<p>
<h3>Fichier Source</h3>
<p>%%SourceFile%%</p>
<div class="source">
diff --git a/framework/Exceptions/templates/exception-zh.html b/framework/Exceptions/templates/exception-zh.html
index 8568dde1..e4c8cbcc 100644
--- a/framework/Exceptions/templates/exception-zh.html
+++ b/framework/Exceptions/templates/exception-zh.html
@@ -1,10 +1,13 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh" lang="zh">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="zh"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>%%ErrorType%%</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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}
@@ -13,10 +16,10 @@ 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;}
.error {background-color: #ffeeee;}
+/*]]>*/
</style>
</head>
-
-<body bgcolor="white">
+<body>
<h1>%%ErrorType%%</h1>
<h3>错误信息</h3>
<p style="color:maroon">%%ErrorMessage%%</p>
diff --git a/framework/Exceptions/templates/exception.html b/framework/Exceptions/templates/exception.html
index 45fc264c..2de7f5f1 100644
--- a/framework/Exceptions/templates/exception.html
+++ b/framework/Exceptions/templates/exception.html
@@ -1,10 +1,13 @@
-<html>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
-<meta http-equiv="Content-Type" content="text/html; charset="utf-8"/>
-<meta http-equiv="content-language" content="en"/>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>%%ErrorType%%</title>
-<style>
-body {font-family:"Verdana";font-weight:normal;color:black;}
+<style type="text/css">
+/*<![CDATA[*/
+body {font-family:"Verdana";font-weight:normal;color:black;background-color:white;}
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}
@@ -12,15 +15,13 @@ p {font-family:"Verdana";font-weight:normal;color:black;font-size:9pt;margin-top
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;}
-.error {background-color: #ffeeee;}
+.error {background-color: #ffeeee;}/*]]>*/
</style>
</head>
-
-<body bgcolor="white">
+<body>
<h1>%%ErrorType%%</h1>
<h3>Description</h3>
<p style="color:maroon">%%ErrorMessage%%</p>
-<p>
<h3>Source File</h3>
<p>%%SourceFile%%</p>
<div class="source">
diff --git a/framework/TApplication.php b/framework/TApplication.php
index 3f9457ea..9051ea23 100644
--- a/framework/TApplication.php
+++ b/framework/TApplication.php
@@ -1,902 +1,916 @@
-<?php
-/**
- * TApplication class file
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Revision: $ $Date: $
- * @package System
- */
-
-/**
- * Includes TErrorHandler class
- */
-require_once(PRADO_DIR.'/Exceptions/TErrorHandler.php');
-/**
- * Includes THttpRequest class
- */
-require_once(PRADO_DIR.'/Web/THttpRequest.php');
-/**
- * Includes THttpResponse class
- */
-require_once(PRADO_DIR.'/Web/THttpResponse.php');
-/**
- * Includes THttpSession class
- */
-require_once(PRADO_DIR.'/Web/THttpSession.php');
-/**
- * Includes TAuthorizationRule class
- */
-require_once(PRADO_DIR.'/Security/TAuthorizationRule.php');
-/**
- * Includes TPageService class (default service)
- */
-require_once(PRADO_DIR.'/Web/Services/TPageService.php');
-
-/**
- * TApplication class.
- *
- * TApplication coordinates modules and services, and serves as a configuration
- * context for all Prado components.
- *
- * TApplication uses a configuration file to specify the settings of
- * the application, the modules, the services, the parameters, and so on.
- *
- * TApplication adopts a modular structure. A TApplication instance is a composition
- * of multiple modules. A module is an instance of class implementing
- * {@link IModule} interface. Each module accomplishes certain functionalities
- * that are shared by all Prado components in an application.
- * There are default modules and user-defined modules. The latter offers extreme
- * flexibility of extending TApplication in a plug-and-play fashion.
- * Modules cooperate with each other to serve a user request by following
- * a sequence of lifecycles predefined in TApplication.
- *
- * TApplication has four modes that can be changed by setting {@link setMode Mode}
- * property (in the application configuration file).
- * - <b>Off</b> mode will prevent the application from serving user requests.
- * - <b>Debug</b> mode is mainly used during application development. It ensures
- * the cache is always up-to-date if caching is enabled. It also allows
- * exceptions are displayed with rich context information if they occur.
- * - <b>Normal</b> mode is mainly used during production stage. Exception information
- * will only be recorded in system error logs. The cache is ensured to be
- * up-to-date if it is enabled.
- * - <b>Performance</b> mode is similar to <b>Normal</b> mode except that it
- * does not ensure the cache is up-to-date.
- *
- * TApplication dispatches each user request to a particular service which
- * finishes the actual work for the request with the aid from the application
- * modules.
- *
- * TApplication maintains a lifecycle with the following stages:
- * - [construct] : construction of the application instance
- * - [initApplication] : load application configuration and instantiate modules and the requested service
- * - BeginRequest : this event happens right after application initialization
- * - Authentication : this event happens when authentication is needed for the current request
- * - PostAuthentication : this event happens right after the authentication is done for the current request
- * - Authorization : this event happens when authorization is needed for the current request
- * - PostAuthorization : this event happens right after the authorization is done for the current request
- * - LoadState : this event happens when application state needs to be loaded
- * - PostLoadState : this event happens right after the application state is loaded
- * - PreRunService : this event happens right before the requested service is to run
- * - RunService : this event happens when the requested service runs
- * - PostRunService : this event happens right after the requested service finishes running
- * - SaveState : this event happens when application needs to save its state
- * - PostSaveState : this event happens right after the application saves its state
- * - EndRequest : this is the last stage an application runs
- * - [destruct] : destruction of the application instance
- * Modules and services can attach their methods to one or several of the above
- * events and do appropriate processing when the events are raised. By this way,
- * the application is able to coordinate the activities of modules and services
- * in the above order. To terminate an application before the whole lifecycle
- * completes, call {@link completeRequest}.
- *
- * Examples:
- * - Create and run a Prado application:
- * <code>
- * $application=new TApplication($configFile);
- * $application->run();
- * </code>
- * - The parsed application configuration file is cached.
- * <code>
- * $application=new TApplication($configFile,$cacheFile);
- * $application->run();
- * </code>
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Revision: $ $Date: $
- * @package System
- * @since 3.0
- */
-class TApplication extends TComponent
-{
- /**
- * Default service ID
- */
- const DEFAULT_SERVICE='page';
- /**
- * @var array list of events that define application lifecycles
- */
- private static $_steps=array(
- 'BeginRequest',
- 'Authentication',
- 'PostAuthentication',
- 'Authorization',
- 'PostAuthorization',
- 'LoadState',
- 'PostLoadState',
- 'PreRunService',
- 'RunService',
- 'PostRunService',
- 'SaveState',
- 'PostSaveState',
- 'EndRequest'
- );
-
- /**
- * @var string application ID
- */
- private $_id;
- /**
- * @var string unique application ID
- */
- private $_uniqueID;
- /**
- * @var boolean whether the request is completed
- */
- private $_requestCompleted=false;
- /**
- * @var integer application state
- */
- private $_step;
- /**
- * @var IService current service instance
- */
- private $_service;
- /**
- * @var array list of application modules
- */
- private $_modules;
- /**
- * @var TMap list of application parameters
- */
- private $_parameters;
- /**
- * @var string configuration file
- */
- private $_configFile;
- /**
- * @var string cache file
- */
- private $_cacheFile;
- /**
- * @var TErrorHandler error handler module
- */
- private $_errorHandler=null;
- /**
- * @var THttpRequest request module
- */
- private $_request=null;
- /**
- * @var THttpResponse response module
- */
- private $_response=null;
- /**
- * @var THttpSession session module, could be null
- */
- private $_session=null;
- /**
- * @var ICache cache module, could be null
- */
- private $_cache=null;
- /**
- * @var IUser user instance, could be null
- */
- private $_user=null;
- /**
- * @var TAuthorizationRuleCollection collection of authorization rules
- */
- private $_authRules=null;
- /**
- * @var string application mode
- */
- private $_mode='Debug';
-
- /**
- * Constructor.
- * Initializes the application singleton. This method ensures that users can
- * only create one application instance.
- * @param string configuration file path (absolute or relative to current running script)
- * @param string cache file path. This is optional. If it is present, it will
- * be used to store and load parsed application configuration (to improve performance).
- */
- public function __construct($configFile,$cacheFile=null)
- {
- parent::__construct();
- Prado::setApplication($this);
- if(($this->_configFile=realpath($configFile))===false || !is_file($this->_configFile))
- throw new TIOException('application_configfile_inexistent',$configFile);
- $this->_cacheFile=$cacheFile;
- // generates unique ID by hashing the configuration file path
- $this->_uniqueID=md5($this->_configFile);
- }
-
- /**
- * Executes the lifecycles of the application.
- * This is the main entry function that leads to the running of the whole
- * Prado application.
- */
- public function run()
- {
- try
- {
- $this->initApplication($this->_configFile,$this->_cacheFile);
- $n=count(self::$_steps);
- $this->_step=0;
- $this->_requestCompleted=false;
- while($this->_step<$n)
- {
- if($this->_mode==='Off')
- throw new THttpException(503,'application_service_unavailable');
- $method='on'.self::$_steps[$this->_step];
- $this->$method($this);
- if($this->_requestCompleted && $this->_step<$n-1)
- $this->_step=$n-1;
- else
- $this->_step++;
- }
- }
- catch(Exception $e)
- {
- $this->onError($e);
- }
- }
-
- /**
- * Completes current request processing.
- * This method can be used to exit the application lifecycles after finishing
- * the current cycle.
- */
- public function completeRequest()
- {
- $this->_requestCompleted=true;
- }
-
- /**
- * @return string application ID
- */
- public function getID()
- {
- return $this->_id;
- }
-
- /**
- * @param string application ID
- */
- public function setID($value)
- {
- $this->_id=$value;
- }
-
- /**
- * @return string an ID that unique identifies this Prado application from the others
- */
- public function getUniqueID()
- {
- return $this->_uniqueID;
- }
-
- /**
- * @return string application mode (Off|Debug|Normal|Peformance), defaults to Debug.
- */
- public function getMode()
- {
- return $this->_mode;
- }
-
- /**
- * @param string application mode. Valid values include Off, Debug, Normal, or Peformance
- */
- public function setMode($value)
- {
- $this->_mode=TPropertyValue::ensureEnum($value,array('Off','Debug','Normal','Performance'));
- }
-
- /**
- * @return string configuration file path
- */
- public function getConfigurationFile()
- {
- return $this->_configFile;
- }
-
- /**
- * @return IService the currently requested service
- */
- public function getService()
- {
- return $this->_service;
- }
-
- /**
- * Adds a module to application.
- * Note, this method does not do module initialization.
- * @param string ID of the module
- * @param IModule module object
- */
- public function setModule($id,IModule $module)
- {
- $this->_modules[$id]=$module;
- }
-
- /**
- * @return IModule the module with the specified ID, null if not found
- */
- public function getModule($id)
- {
- return isset($this->_modules[$id])?$this->_modules[$id]:null;
- }
-
- /**
- * @return array list of loaded application modules, indexed by module IDs
- */
- public function getModules()
- {
- return $this->_modules;
- }
-
- /**
- * Returns the list of application parameters.
- * Since the parameters are returned as a {@link TMap} object, you may use
- * the returned result to access, add or remove individual parameters.
- * @return TMap the list of application parameters
- */
- public function getParameters()
- {
- return $this->_parameters;
- }
-
- /**
- * @return THttpRequest the request module
- */
- public function getRequest()
- {
- if(!$this->_request)
- {
- $this->_request=new THttpRequest;
- $this->_request->init($this,null);
- }
- return $this->_request;
- }
-
- /**
- * @param THttpRequest the request module
- */
- public function setRequest(THttpRequest $request)
- {
- $this->_request=$request;
- }
-
- /**
- * @return THttpResponse the response module
- */
- public function getResponse()
- {
- if(!$this->_response)
- {
- $this->_response=new THttpResponse;
- $this->_response->init($this,null);
- }
- return $this->_response;
- }
-
- /**
- * @param THttpRequest the request module
- */
- public function setResponse(THttpResponse $response)
- {
- $this->_response=$response;
- }
-
- /**
- * @return THttpSession the session module, null if session module is not installed
- */
- public function getSession()
- {
- if(!$this->_session)
- {
- $this->_session=new THttpSession;
- $this->_session->init($this,null);
- }
- return $this->_session;
- }
-
- /**
- * @param THttpSession the session module
- */
- public function setSession(THttpSession $session)
- {
- $this->_session=$session;
- }
-
- /**
- * @return TErrorHandler the error hanlder module
- */
- public function getErrorHandler()
- {
- if(!$this->_errorHandler)
- {
- $this->_errorHandler=new TErrorHandler;
- $this->_errorHandler->init($this,null);
- }
- return $this->_errorHandler;
- }
-
- /**
- * @param TErrorHandler the error hanlder module
- */
- public function setErrorHandler(TErrorHandler $handler)
- {
- $this->_errorHandler=$handler;
- }
-
- /**
- * @return ICache the cache module, null if cache module is not installed
- */
- public function getCache()
- {
- return $this->_cache;
- }
-
- /**
- * @param ICache the cache module
- */
- public function setCache(ICache $cache)
- {
- $this->_cache=$cache;
- }
-
- /**
- * @return IUser the application user
- */
- public function getUser()
- {
- return $this->_user;
- }
-
- /**
- * @param IUser the application user
- */
- public function setUser(IUser $user)
- {
- $this->_user=$user;
- }
-
- /**
- * @return TAuthorizationRuleCollection list of authorization rules for the current request
- */
- public function getAuthorizationRules()
- {
- if($this->_authRules===null)
- $this->_authRules=new TAuthorizationRuleCollection;
- return $this->_authRules;
- }
-
- /**
- * Loads configuration and initializes application.
- * Configuration file will be read and parsed (if a valid cached version exists,
- * it will be used instead). Then, modules are created and initialized;
- * Afterwards, the requested service is created and initialized.
- * @param string configuration file path (absolute or relative to current executing script)
- * @param string cache file path, empty if no present or needed
- * @throws TConfigurationException if module is redefined of invalid type, or service not defined or of invalid type
- */
- protected function initApplication($configFile,$cacheFile)
- {
- if($cacheFile===null || @filemtime($cacheFile)<filemtime($configFile))
- {
- $config=new TApplicationConfiguration;
- $config->loadFromFile($configFile);
- if($cacheFile!==null)
- {
- if(($fp=fopen($cacheFile,'wb'))!==false)
- {
- fputs($fp,Prado::serialize($config));
- fclose($fp);
- }
- else
- syslog(LOG_WARNING,'Prado application config cache file "'.$cacheFile.'" cannot be created.');
- }
- }
- else
- {
- $config=Prado::unserialize(file_get_contents($cacheFile));
- }
-
- // set path aliases and using namespaces
- foreach($config->getAliases() as $alias=>$path)
- Prado::setPathOfAlias($alias,$path);
- foreach($config->getUsings() as $using)
- Prado::using($using);
-
- // set application properties
- foreach($config->getProperties() as $name=>$value)
- $this->setSubProperty($name,$value);
-
- // load parameters
- $this->_parameters=new TMap;
- foreach($config->getParameters() as $id=>$parameter)
- {
- if(is_string($parameter))
- $this->_parameters->add($id,$parameter);
- else
- {
- $component=Prado::createComponent($parameter[0]);
- foreach($parameter[1] as $name=>$value)
- $component->setSubProperty($name,$value);
- $this->_parameters->add($id,$component);
- }
- }
-
- // load and init modules specified in app config
- $this->_modules=array();
- foreach($config->getModules() as $id=>$moduleConfig)
- {
- $module=Prado::createComponent($moduleConfig[0]);
- $this->_modules[$id]=$module;
- foreach($moduleConfig[1] as $name=>$value)
- $module->setSubProperty($name,$value);
- $module->init($this,$moduleConfig[2]);
- }
-
- if(($serviceID=$this->getRequest()->getServiceID())===null)
- $serviceID=self::DEFAULT_SERVICE;
- if(($serviceConfig=$config->getService($serviceID))!==null)
- {
- $service=Prado::createComponent($serviceConfig[0]);
- if(!($service instanceof IService))
- throw new TConfigurationException('application_service_invalid',$serviceID);
- $this->_service=$service;
- foreach($serviceConfig[1] as $name=>$value)
- $service->setSubProperty($name,$value);
- $service->init($this,$serviceConfig[2]);
- $this->attachEventHandler('RunService',array($service,'run'));
- }
- else
- throw new TConfigurationException('application_service_unknown',$serviceID);
- }
-
- /**
- * Raises Error event.
- * This method is invoked when an exception is raised during the lifecycles
- * of the application.
- * @param mixed event parameter
- */
- public function onError($param)
- {
- if($this->hasEventHandler('Error'))
- $this->raiseEvent('Error',$this,$param);
- else
- $this->getErrorHandler()->handleError($this,$param);
- }
-
- /**
- * Raises BeginRequest event.
- * At the time when this method is invoked, application modules are loaded
- * and initialized, user request is resolved and the corresponding service
- * is loaded and initialized. The application is about to start processing
- * the user request.
- * @param mixed event parameter
- */
- public function onBeginRequest($param)
- {
- $this->raiseEvent('BeginRequest',$this,$param);
- }
-
- /**
- * Raises Authentication event.
- * This method is invoked when the user request needs to be authenticated.
- * @param mixed event parameter
- */
- public function onAuthentication($param)
- {
- $this->raiseEvent('Authentication',$this,$param);
- }
-
- /**
- * Raises PostAuthentication event.
- * This method is invoked right after the user request is authenticated.
- * @param mixed event parameter
- */
- public function onPostAuthentication($param)
- {
- $this->raiseEvent('PostAuthentication',$this,$param);
- }
-
- /**
- * Raises Authorization event.
- * This method is invoked when the user request needs to be authorized.
- * @param mixed event parameter
- */
- public function onAuthorization($param)
- {
- $this->raiseEvent('Authorization',$this,$param);
- }
-
- /**
- * Raises PostAuthorization event.
- * This method is invoked right after the user request is authorized.
- * @param mixed event parameter
- */
- public function onPostAuthorization($param)
- {
- $this->raiseEvent('PostAuthorization',$this,$param);
- }
-
- /**
- * Raises LoadState event.
- * This method is invoked when the application needs to load state (probably stored in session).
- * @param mixed event parameter
- */
- public function onLoadState($param)
- {
- $this->raiseEvent('LoadState',$this,$param);
- }
-
- /**
- * Raises PostLoadState event.
- * This method is invoked right after the application state has been loaded.
- * @param mixed event parameter
- */
- public function onPostLoadState($param)
- {
- $this->raiseEvent('PostLoadState',$this,$param);
- }
-
- /**
- * Raises PreRunService event.
- * This method is invoked right before the service is to be run.
- * @param mixed event parameter
- */
- public function onPreRunService($param)
- {
- $this->raiseEvent('PreRunService',$this,$param);
- }
-
- /**
- * Raises RunService event.
- * This method is invoked when the service runs.
- * @param mixed event parameter
- */
- public function onRunService($param)
- {
- $this->raiseEvent('RunService',$this,$param);
- }
-
- /**
- * Raises PostRunService event.
- * This method is invoked right after the servie is run.
- * @param mixed event parameter
- */
- public function onPostRunService($param)
- {
- $this->raiseEvent('PostRunService',$this,$param);
- }
-
- /**
- * Raises SaveState event.
- * This method is invoked when the application needs to save state (probably stored in session).
- * @param mixed event parameter
- */
- public function onSaveState($param)
- {
- $this->raiseEvent('SaveState',$this,$param);
- }
-
- /**
- * Raises PostSaveState event.
- * This method is invoked right after the application state has been saved.
- * @param mixed event parameter
- */
- public function onPostSaveState($param)
- {
- $this->raiseEvent('PostSaveState',$this,$param);
- }
-
- /**
- * Raises EndRequest event.
- * This method is invoked when the application completes the processing of the request.
- * @param mixed event parameter
- */
- public function onEndRequest($param)
- {
- $this->raiseEvent('EndRequest',$this,$param);
- }
-}
-
-
-/**
- * TApplicationConfiguration class.
- *
- * This class is used internally by TApplication to parse and represent application configuration.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Revision: $ $Date: $
- * @package System
- * @since 3.0
- */
-class TApplicationConfiguration extends TComponent
-{
- /**
- * @var array list of application initial property values, indexed by property names
- */
- private $_properties=array();
- /**
- * @var array list of namespaces to be used
- */
- private $_usings=array();
- /**
- * @var array list of path aliases, indexed by alias names
- */
- private $_aliases=array();
- /**
- * @var array list of module configurations
- */
- private $_modules=array();
- /**
- * @var array list of service configurations
- */
- private $_services=array(
- 'page'=>array('TPageService',array(),null)
- );
- /**
- * @var array list of parameters
- */
- private $_parameters=array();
-
- /**
- * Parses the application configuration file.
- * @param string configuration file name
- * @throws TConfigurationException if there is any parsing error
- */
- public function loadFromFile($fname)
- {
- $configPath=dirname($fname);
- $dom=new TXmlDocument;
- $dom->loadFromFile($fname);
-
- // application properties
- foreach($dom->getAttributes() as $name=>$value)
- $this->_properties[$name]=$value;
-
- // paths
- if(($pathsNode=$dom->getElementByTagName('paths'))!==null)
- {
- foreach($pathsNode->getElementsByTagName('alias') as $aliasNode)
- {
- if(($id=$aliasNode->getAttribute('id'))!==null && ($path=$aliasNode->getAttribute('path'))!==null)
- {
- $path=str_replace('\\','/',$path);
- if(preg_match('/^\\/|.:\\/|.:\\\\/',$path)) // if absolute path
- $p=realpath($path);
- else
- $p=realpath($configPath.'/'.$path);
- if($p===false || !is_dir($p))
- throw new TConfigurationException('appconfig_aliaspath_invalid',$id,$path);
- if(isset($this->_aliases[$id]))
- throw new TConfigurationException('appconfig_alias_redefined',$id);
- $this->_aliases[$id]=$p;
- }
- else
- throw new TConfigurationException('appconfig_alias_invalid');
- }
- foreach($pathsNode->getElementsByTagName('using') as $usingNode)
- {
- if(($namespace=$usingNode->getAttribute('namespace'))!==null)
- $this->_usings[]=$namespace;
- else
- throw new TConfigurationException('appconfig_using_invalid');
- }
- }
-
- // application modules
- if(($modulesNode=$dom->getElementByTagName('modules'))!==null)
- {
- foreach($modulesNode->getElementsByTagName('module') as $node)
- {
- $properties=$node->getAttributes();
- if(($id=$properties->itemAt('id'))===null)
- throw new TConfigurationException('appconfig_moduleid_required');
- if(($type=$properties->remove('class'))===null && isset($this->_modules[$id]) && $this->_modules[$id][2]===null)
- $type=$this->_modules[$id][0];
- if($type===null)
- throw new TConfigurationException('appconfig_moduletype_required',$id);
- $node->setParent(null);
- $this->_modules[$id]=array($type,$properties->toArray(),$node);
- }
- }
-
- // services
- if(($servicesNode=$dom->getElementByTagName('services'))!==null)
- {
- foreach($servicesNode->getElementsByTagName('service') as $node)
- {
- $properties=$node->getAttributes();
- if(($id=$properties->itemAt('id'))===null)
- throw new TConfigurationException('appconfig_serviceid_required');
- if(($type=$properties->remove('class'))===null && isset($this->_services[$id]) && $this->_services[$id][2]===null)
- $type=$this->_services[$id][0];
- if($type===null)
- throw new TConfigurationException('appconfig_servicetype_required',$id);
- $node->setParent(null);
- $this->_services[$id]=array($type,$properties->toArray(),$node);
- }
- }
-
- // parameters
- if(($parametersNode=$dom->getElementByTagName('parameters'))!==null)
- {
- foreach($parametersNode->getElementsByTagName('parameter') as $node)
- {
- $properties=$node->getAttributes();
- if(($id=$properties->remove('id'))===null)
- throw new TConfigurationException('appconfig_parameterid_required');
- if(($type=$properties->remove('class'))===null)
- $this->_parameters[$id]=$node->getValue();
- else
- $this->_parameters[$id]=array($type,$properties->toArray());
- }
- }
- }
-
- /**
- * @return array list of application initial property values, indexed by property names
- */
- public function getProperties()
- {
- return $this->_properties;
- }
-
- /**
- * @return array list of path aliases, indexed by alias names
- */
- public function getAliases()
- {
- return $this->_aliases;
- }
-
- /**
- * @return array list of namespaces to be used
- */
- public function getUsings()
- {
- return $this->_usings;
- }
-
- /**
- * @return array list of module configurations
- */
- public function getModules()
- {
- return $this->_modules;
- }
-
- /**
- * @return array list of service configurations
- */
- public function getService($id)
- {
- return isset($this->_services[$id])?$this->_services[$id]:null;
- }
-
- /**
- * @return array list of parameters
- */
- public function getParameters()
- {
- return $this->_parameters;
- }
-}
-
+<?php
+/**
+ * TApplication class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $Date: $
+ * @package System
+ */
+
+/**
+ * Includes TErrorHandler class
+ */
+require_once(PRADO_DIR.'/Exceptions/TErrorHandler.php');
+/**
+ * Includes THttpRequest class
+ */
+require_once(PRADO_DIR.'/Web/THttpRequest.php');
+/**
+ * Includes THttpResponse class
+ */
+require_once(PRADO_DIR.'/Web/THttpResponse.php');
+/**
+ * Includes THttpSession class
+ */
+require_once(PRADO_DIR.'/Web/THttpSession.php');
+/**
+ * Includes TAuthorizationRule class
+ */
+require_once(PRADO_DIR.'/Security/TAuthorizationRule.php');
+/**
+ * Includes TPageService class (default service)
+ */
+require_once(PRADO_DIR.'/Web/Services/TPageService.php');
+
+/**
+ * TApplication class.
+ *
+ * TApplication coordinates modules and services, and serves as a configuration
+ * context for all Prado components.
+ *
+ * TApplication uses a configuration file to specify the settings of
+ * the application, the modules, the services, the parameters, and so on.
+ *
+ * TApplication adopts a modular structure. A TApplication instance is a composition
+ * of multiple modules. A module is an instance of class implementing
+ * {@link IModule} interface. Each module accomplishes certain functionalities
+ * that are shared by all Prado components in an application.
+ * There are default modules and user-defined modules. The latter offers extreme
+ * flexibility of extending TApplication in a plug-and-play fashion.
+ * Modules cooperate with each other to serve a user request by following
+ * a sequence of lifecycles predefined in TApplication.
+ *
+ * TApplication has four modes that can be changed by setting {@link setMode Mode}
+ * property (in the application configuration file).
+ * - <b>Off</b> mode will prevent the application from serving user requests.
+ * - <b>Debug</b> mode is mainly used during application development. It ensures
+ * the cache is always up-to-date if caching is enabled. It also allows
+ * exceptions are displayed with rich context information if they occur.
+ * - <b>Normal</b> mode is mainly used during production stage. Exception information
+ * will only be recorded in system error logs. The cache is ensured to be
+ * up-to-date if it is enabled.
+ * - <b>Performance</b> mode is similar to <b>Normal</b> mode except that it
+ * does not ensure the cache is up-to-date.
+ *
+ * TApplication dispatches each user request to a particular service which
+ * finishes the actual work for the request with the aid from the application
+ * modules.
+ *
+ * TApplication maintains a lifecycle with the following stages:
+ * - [construct] : construction of the application instance
+ * - [initApplication] : load application configuration and instantiate modules and the requested service
+ * - BeginRequest : this event happens right after application initialization
+ * - Authentication : this event happens when authentication is needed for the current request
+ * - PostAuthentication : this event happens right after the authentication is done for the current request
+ * - Authorization : this event happens when authorization is needed for the current request
+ * - PostAuthorization : this event happens right after the authorization is done for the current request
+ * - LoadState : this event happens when application state needs to be loaded
+ * - PostLoadState : this event happens right after the application state is loaded
+ * - PreRunService : this event happens right before the requested service is to run
+ * - RunService : this event happens when the requested service runs
+ * - PostRunService : this event happens right after the requested service finishes running
+ * - SaveState : this event happens when application needs to save its state
+ * - PostSaveState : this event happens right after the application saves its state
+ * - EndRequest : this is the last stage an application runs
+ * - [destruct] : destruction of the application instance
+ * Modules and services can attach their methods to one or several of the above
+ * events and do appropriate processing when the events are raised. By this way,
+ * the application is able to coordinate the activities of modules and services
+ * in the above order. To terminate an application before the whole lifecycle
+ * completes, call {@link completeRequest}.
+ *
+ * Examples:
+ * - Create and run a Prado application:
+ * <code>
+ * $application=new TApplication($configFile);
+ * $application->run();
+ * </code>
+ * - The parsed application configuration file is cached.
+ * <code>
+ * $application=new TApplication($configFile,$cacheFile);
+ * $application->run();
+ * </code>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $ $Date: $
+ * @package System
+ * @since 3.0
+ */
+class TApplication extends TComponent
+{
+ /**
+ * Default service ID
+ */
+ const DEFAULT_SERVICE='page';
+ /**
+ * @var array list of events that define application lifecycles
+ */
+ private static $_steps=array(
+ 'BeginRequest',
+ 'Authentication',
+ 'PostAuthentication',
+ 'Authorization',
+ 'PostAuthorization',
+ 'LoadState',
+ 'PostLoadState',
+ 'PreRunService',
+ 'RunService',
+ 'PostRunService',
+ 'SaveState',
+ 'PostSaveState',
+ 'EndRequest'
+ );
+
+ /**
+ * @var string application ID
+ */
+ private $_id;
+ /**
+ * @var string unique application ID
+ */
+ private $_uniqueID;
+ /**
+ * @var boolean whether the request is completed
+ */
+ private $_requestCompleted=false;
+ /**
+ * @var integer application state
+ */
+ private $_step;
+ /**
+ * @var IService current service instance
+ */
+ private $_service;
+ /**
+ * @var array list of application modules
+ */
+ private $_modules;
+ /**
+ * @var TMap list of application parameters
+ */
+ private $_parameters;
+ /**
+ * @var string configuration file
+ */
+ private $_configFile;
+ /**
+ * @var string cache file
+ */
+ private $_cacheFile;
+ /**
+ * @var TErrorHandler error handler module
+ */
+ private $_errorHandler=null;
+ /**
+ * @var THttpRequest request module
+ */
+ private $_request=null;
+ /**
+ * @var THttpResponse response module
+ */
+ private $_response=null;
+ /**
+ * @var THttpSession session module, could be null
+ */
+ private $_session=null;
+ /**
+ * @var ICache cache module, could be null
+ */
+ private $_cache=null;
+ /**
+ * @var IUser user instance, could be null
+ */
+ private $_user=null;
+ /**
+ * @var TAuthorizationRuleCollection collection of authorization rules
+ */
+ private $_authRules=null;
+ /**
+ * @var string application mode
+ */
+ private $_mode='Debug';
+
+ /**
+ * Constructor.
+ * Initializes the application singleton. This method ensures that users can
+ * only create one application instance.
+ * @param string configuration file path (absolute or relative to current running script)
+ * @param string cache file path. This is optional. If it is present, it will
+ * be used to store and load parsed application configuration (to improve performance).
+ */
+ public function __construct($configFile,$cacheFile=null)
+ {
+ parent::__construct();
+ Prado::setApplication($this);
+ if(($this->_configFile=realpath($configFile))===false || !is_file($this->_configFile))
+ throw new TIOException('application_configfile_inexistent',$configFile);
+ $this->_cacheFile=$cacheFile;
+ // generates unique ID by hashing the configuration file path
+ $this->_uniqueID=md5($this->_configFile);
+ }
+
+
+ /**
+ * Executes the lifecycles of the application.
+ * This is the main entry function that leads to the running of the whole
+ * Prado application.
+ */
+ public function run()
+ {
+ //init the error handlers
+ $this->applyDefaultExceptionHandlers();
+ try
+ {
+ $this->initApplication($this->_configFile,$this->_cacheFile);
+ $n=count(self::$_steps);
+ $this->_step=0;
+ $this->_requestCompleted=false;
+ while($this->_step<$n)
+ {
+ if($this->_mode==='Off')
+ throw new THttpException(503,'application_service_unavailable');
+ $method='on'.self::$_steps[$this->_step];
+ $this->$method($this);
+ if($this->_requestCompleted && $this->_step<$n-1)
+ $this->_step=$n-1;
+ else
+ $this->_step++;
+ }
+ }
+ catch(Exception $e)
+ {
+ $this->onError($e);
+ }
+ }
+
+ /**
+ * Sets up error handler to convert PHP errors into exceptions that can be caught.
+ */
+ protected function applyDefaultExceptionHandlers()
+ {
+ set_error_handler(array('Prado','phpErrorHandler'),error_reporting());
+ set_exception_handler(array('Prado','exceptionHandler'));
+ }
+
+ /**
+ * Completes current request processing.
+ * This method can be used to exit the application lifecycles after finishing
+ * the current cycle.
+ */
+ public function completeRequest()
+ {
+ $this->_requestCompleted=true;
+ }
+
+ /**
+ * @return string application ID
+ */
+ public function getID()
+ {
+ return $this->_id;
+ }
+
+ /**
+ * @param string application ID
+ */
+ public function setID($value)
+ {
+ $this->_id=$value;
+ }
+
+ /**
+ * @return string an ID that unique identifies this Prado application from the others
+ */
+ public function getUniqueID()
+ {
+ return $this->_uniqueID;
+ }
+
+ /**
+ * @return string application mode (Off|Debug|Normal|Peformance), defaults to Debug.
+ */
+ public function getMode()
+ {
+ return $this->_mode;
+ }
+
+ /**
+ * @param string application mode. Valid values include Off, Debug, Normal, or Peformance
+ */
+ public function setMode($value)
+ {
+ $this->_mode=TPropertyValue::ensureEnum($value,array('Off','Debug','Normal','Performance'));
+ }
+
+ /**
+ * @return string configuration file path
+ */
+ public function getConfigurationFile()
+ {
+ return $this->_configFile;
+ }
+
+ /**
+ * @return IService the currently requested service
+ */
+ public function getService()
+ {
+ return $this->_service;
+ }
+
+ /**
+ * Adds a module to application.
+ * Note, this method does not do module initialization.
+ * @param string ID of the module
+ * @param IModule module object
+ */
+ public function setModule($id,IModule $module)
+ {
+ $this->_modules[$id]=$module;
+ }
+
+ /**
+ * @return IModule the module with the specified ID, null if not found
+ */
+ public function getModule($id)
+ {
+ return isset($this->_modules[$id])?$this->_modules[$id]:null;
+ }
+
+ /**
+ * @return array list of loaded application modules, indexed by module IDs
+ */
+ public function getModules()
+ {
+ return $this->_modules;
+ }
+
+ /**
+ * Returns the list of application parameters.
+ * Since the parameters are returned as a {@link TMap} object, you may use
+ * the returned result to access, add or remove individual parameters.
+ * @return TMap the list of application parameters
+ */
+ public function getParameters()
+ {
+ return $this->_parameters;
+ }
+
+ /**
+ * @return THttpRequest the request module
+ */
+ public function getRequest()
+ {
+ if(!$this->_request)
+ {
+ $this->_request=new THttpRequest;
+ $this->_request->init($this,null);
+ }
+ return $this->_request;
+ }
+
+ /**
+ * @param THttpRequest the request module
+ */
+ public function setRequest(THttpRequest $request)
+ {
+ $this->_request=$request;
+ }
+
+ /**
+ * @return THttpResponse the response module
+ */
+ public function getResponse()
+ {
+ if(!$this->_response)
+ {
+ $this->_response=new THttpResponse;
+ $this->_response->init($this,null);
+ }
+ return $this->_response;
+ }
+
+ /**
+ * @param THttpRequest the request module
+ */
+ public function setResponse(THttpResponse $response)
+ {
+ $this->_response=$response;
+ }
+
+ /**
+ * @return THttpSession the session module, null if session module is not installed
+ */
+ public function getSession()
+ {
+ if(!$this->_session)
+ {
+ $this->_session=new THttpSession;
+ $this->_session->init($this,null);
+ }
+ return $this->_session;
+ }
+
+ /**
+ * @param THttpSession the session module
+ */
+ public function setSession(THttpSession $session)
+ {
+ $this->_session=$session;
+ }
+
+ /**
+ * @return TErrorHandler the error hanlder module
+ */
+ public function getErrorHandler()
+ {
+ if(!$this->_errorHandler)
+ {
+ $this->_errorHandler=new TErrorHandler;
+ $this->_errorHandler->init($this,null);
+ }
+ return $this->_errorHandler;
+ }
+
+ /**
+ * @param TErrorHandler the error hanlder module
+ */
+ public function setErrorHandler(TErrorHandler $handler)
+ {
+ $this->_errorHandler=$handler;
+ }
+
+ /**
+ * @return ICache the cache module, null if cache module is not installed
+ */
+ public function getCache()
+ {
+ return $this->_cache;
+ }
+
+ /**
+ * @param ICache the cache module
+ */
+ public function setCache(ICache $cache)
+ {
+ $this->_cache=$cache;
+ }
+
+ /**
+ * @return IUser the application user
+ */
+ public function getUser()
+ {
+ return $this->_user;
+ }
+
+ /**
+ * @param IUser the application user
+ */
+ public function setUser(IUser $user)
+ {
+ $this->_user=$user;
+ }
+
+ /**
+ * @return TAuthorizationRuleCollection list of authorization rules for the current request
+ */
+ public function getAuthorizationRules()
+ {
+ if($this->_authRules===null)
+ $this->_authRules=new TAuthorizationRuleCollection;
+ return $this->_authRules;
+ }
+
+ /**
+ * Loads configuration and initializes application.
+ * Configuration file will be read and parsed (if a valid cached version exists,
+ * it will be used instead). Then, modules are created and initialized;
+ * Afterwards, the requested service is created and initialized.
+ * @param string configuration file path (absolute or relative to current executing script)
+ * @param string cache file path, empty if no present or needed
+ * @throws TConfigurationException if module is redefined of invalid type, or service not defined or of invalid type
+ */
+ protected function initApplication($configFile,$cacheFile)
+ {
+ if($cacheFile===null || @filemtime($cacheFile)<filemtime($configFile))
+ {
+ $config=new TApplicationConfiguration;
+ $config->loadFromFile($configFile);
+ if($cacheFile!==null)
+ {
+ if(($fp=fopen($cacheFile,'wb'))!==false)
+ {
+ fputs($fp,Prado::serialize($config));
+ fclose($fp);
+ }
+ else
+ syslog(LOG_WARNING,'Prado application config cache file "'.$cacheFile.'" cannot be created.');
+ }
+ }
+ else
+ {
+ $config=Prado::unserialize(file_get_contents($cacheFile));
+ }
+
+
+ // set path aliases and using namespaces
+ foreach($config->getAliases() as $alias=>$path)
+ Prado::setPathOfAlias($alias,$path);
+ foreach($config->getUsings() as $using)
+ Prado::using($using);
+
+ // set application properties
+ foreach($config->getProperties() as $name=>$value)
+ $this->setSubProperty($name,$value);
+
+ // load parameters
+ $this->_parameters=new TMap;
+ foreach($config->getParameters() as $id=>$parameter)
+ {
+ if(is_string($parameter))
+ $this->_parameters->add($id,$parameter);
+ else
+ {
+ $component=Prado::createComponent($parameter[0]);
+ foreach($parameter[1] as $name=>$value)
+ $component->setSubProperty($name,$value);
+ $this->_parameters->add($id,$component);
+ }
+ }
+
+ // load and init modules specified in app config
+ $this->_modules=array();
+ foreach($config->getModules() as $id=>$moduleConfig)
+ {
+ $module=Prado::createComponent($moduleConfig[0]);
+ $this->_modules[$id]=$module;
+ foreach($moduleConfig[1] as $name=>$value)
+ $module->setSubProperty($name,$value);
+ $module->init($this,$moduleConfig[2]);
+ }
+
+ if(($serviceID=$this->getRequest()->getServiceID())===null)
+ $serviceID=self::DEFAULT_SERVICE;
+
+ if(($serviceConfig=$config->getService($serviceID))!==null)
+ {
+ $service=Prado::createComponent($serviceConfig[0]);
+ if(!($service instanceof IService))
+ throw new TConfigurationException('application_service_invalid',$serviceID);
+ $this->_service=$service;
+ foreach($serviceConfig[1] as $name=>$value)
+ $service->setSubProperty($name,$value);
+ $service->init($this,$serviceConfig[2]);
+ $this->attachEventHandler('RunService',array($service,'run'));
+ }
+ else
+ throw new TConfigurationException('application_service_unknown',$serviceID);
+ }
+
+ /**
+ * Raises Error event.
+ * This method is invoked when an exception is raised during the lifecycles
+ * of the application.
+ * @param mixed event parameter
+ */
+ public function onError($param)
+ {
+ if($this->hasEventHandler('Error'))
+ $this->raiseEvent('Error',$this,$param);
+ else
+ $this->getErrorHandler()->handleError($this,$param);
+ }
+
+ /**
+ * Raises BeginRequest event.
+ * At the time when this method is invoked, application modules are loaded
+ * and initialized, user request is resolved and the corresponding service
+ * is loaded and initialized. The application is about to start processing
+ * the user request.
+ * @param mixed event parameter
+ */
+ public function onBeginRequest($param)
+ {
+ $this->raiseEvent('BeginRequest',$this,$param);
+ }
+
+ /**
+ * Raises Authentication event.
+ * This method is invoked when the user request needs to be authenticated.
+ * @param mixed event parameter
+ */
+ public function onAuthentication($param)
+ {
+ $this->raiseEvent('Authentication',$this,$param);
+ }
+
+ /**
+ * Raises PostAuthentication event.
+ * This method is invoked right after the user request is authenticated.
+ * @param mixed event parameter
+ */
+ public function onPostAuthentication($param)
+ {
+ $this->raiseEvent('PostAuthentication',$this,$param);
+ }
+
+ /**
+ * Raises Authorization event.
+ * This method is invoked when the user request needs to be authorized.
+ * @param mixed event parameter
+ */
+ public function onAuthorization($param)
+ {
+ $this->raiseEvent('Authorization',$this,$param);
+ }
+
+ /**
+ * Raises PostAuthorization event.
+ * This method is invoked right after the user request is authorized.
+ * @param mixed event parameter
+ */
+ public function onPostAuthorization($param)
+ {
+ $this->raiseEvent('PostAuthorization',$this,$param);
+ }
+
+ /**
+ * Raises LoadState event.
+ * This method is invoked when the application needs to load state (probably stored in session).
+ * @param mixed event parameter
+ */
+ public function onLoadState($param)
+ {
+ $this->raiseEvent('LoadState',$this,$param);
+ }
+
+ /**
+ * Raises PostLoadState event.
+ * This method is invoked right after the application state has been loaded.
+ * @param mixed event parameter
+ */
+ public function onPostLoadState($param)
+ {
+ $this->raiseEvent('PostLoadState',$this,$param);
+ }
+
+ /**
+ * Raises PreRunService event.
+ * This method is invoked right before the service is to be run.
+ * @param mixed event parameter
+ */
+ public function onPreRunService($param)
+ {
+ $this->raiseEvent('PreRunService',$this,$param);
+ }
+
+ /**
+ * Raises RunService event.
+ * This method is invoked when the service runs.
+ * @param mixed event parameter
+ */
+ public function onRunService($param)
+ {
+ $this->raiseEvent('RunService',$this,$param);
+ }
+
+ /**
+ * Raises PostRunService event.
+ * This method is invoked right after the servie is run.
+ * @param mixed event parameter
+ */
+ public function onPostRunService($param)
+ {
+ $this->raiseEvent('PostRunService',$this,$param);
+ }
+
+ /**
+ * Raises SaveState event.
+ * This method is invoked when the application needs to save state (probably stored in session).
+ * @param mixed event parameter
+ */
+ public function onSaveState($param)
+ {
+ $this->raiseEvent('SaveState',$this,$param);
+ }
+
+ /**
+ * Raises PostSaveState event.
+ * This method is invoked right after the application state has been saved.
+ * @param mixed event parameter
+ */
+ public function onPostSaveState($param)
+ {
+ $this->raiseEvent('PostSaveState',$this,$param);
+ }
+
+ /**
+ * Raises EndRequest event.
+ * This method is invoked when the application completes the processing of the request.
+ * @param mixed event parameter
+ */
+ public function onEndRequest($param)
+ {
+ $this->raiseEvent('EndRequest',$this,$param);
+ }
+}
+
+
+/**
+ * TApplicationConfiguration class.
+ *
+ * This class is used internally by TApplication to parse and represent application configuration.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $ $Date: $
+ * @package System
+ * @since 3.0
+ */
+class TApplicationConfiguration extends TComponent
+{
+ /**
+ * @var array list of application initial property values, indexed by property names
+ */
+ private $_properties=array();
+ /**
+ * @var array list of namespaces to be used
+ */
+ private $_usings=array();
+ /**
+ * @var array list of path aliases, indexed by alias names
+ */
+ private $_aliases=array();
+ /**
+ * @var array list of module configurations
+ */
+ private $_modules=array();
+ /**
+ * @var array list of service configurations
+ */
+ private $_services=array(
+ 'page'=>array('TPageService',array(),null)
+ );
+ /**
+ * @var array list of parameters
+ */
+ private $_parameters=array();
+
+ /**
+ * Parses the application configuration file.
+ * @param string configuration file name
+ * @throws TConfigurationException if there is any parsing error
+ */
+ public function loadFromFile($fname)
+ {
+ $configPath=dirname($fname);
+ $dom=new TXmlDocument;
+ $dom->loadFromFile($fname);
+
+ // application properties
+ foreach($dom->getAttributes() as $name=>$value)
+ $this->_properties[$name]=$value;
+
+ // paths
+ if(($pathsNode=$dom->getElementByTagName('paths'))!==null)
+ {
+ foreach($pathsNode->getElementsByTagName('alias') as $aliasNode)
+ {
+ if(($id=$aliasNode->getAttribute('id'))!==null && ($path=$aliasNode->getAttribute('path'))!==null)
+ {
+ $path=str_replace('\\','/',$path);
+ if(preg_match('/^\\/|.:\\/|.:\\\\/',$path)) // if absolute path
+ $p=realpath($path);
+ else
+ $p=realpath($configPath.'/'.$path);
+ if($p===false || !is_dir($p))
+ throw new TConfigurationException('appconfig_aliaspath_invalid',$id,$path);
+ if(isset($this->_aliases[$id]))
+ throw new TConfigurationException('appconfig_alias_redefined',$id);
+ $this->_aliases[$id]=$p;
+ }
+ else
+ throw new TConfigurationException('appconfig_alias_invalid');
+ }
+ foreach($pathsNode->getElementsByTagName('using') as $usingNode)
+ {
+ if(($namespace=$usingNode->getAttribute('namespace'))!==null)
+ $this->_usings[]=$namespace;
+ else
+ throw new TConfigurationException('appconfig_using_invalid');
+ }
+ }
+
+ // application modules
+ if(($modulesNode=$dom->getElementByTagName('modules'))!==null)
+ {
+ foreach($modulesNode->getElementsByTagName('module') as $node)
+ {
+ $properties=$node->getAttributes();
+ if(($id=$properties->itemAt('id'))===null)
+ throw new TConfigurationException('appconfig_moduleid_required');
+ if(($type=$properties->remove('class'))===null && isset($this->_modules[$id]) && $this->_modules[$id][2]===null)
+ $type=$this->_modules[$id][0];
+ if($type===null)
+ throw new TConfigurationException('appconfig_moduletype_required',$id);
+ $node->setParent(null);
+ $this->_modules[$id]=array($type,$properties->toArray(),$node);
+ }
+ }
+
+ // services
+ if(($servicesNode=$dom->getElementByTagName('services'))!==null)
+ {
+ foreach($servicesNode->getElementsByTagName('service') as $node)
+ {
+ $properties=$node->getAttributes();
+ if(($id=$properties->itemAt('id'))===null)
+ throw new TConfigurationException('appconfig_serviceid_required');
+ if(($type=$properties->remove('class'))===null && isset($this->_services[$id]) && $this->_services[$id][2]===null)
+ $type=$this->_services[$id][0];
+ if($type===null)
+ throw new TConfigurationException('appconfig_servicetype_required',$id);
+ $node->setParent(null);
+ $this->_services[$id]=array($type,$properties->toArray(),$node);
+ }
+ }
+
+ // parameters
+ if(($parametersNode=$dom->getElementByTagName('parameters'))!==null)
+ {
+ foreach($parametersNode->getElementsByTagName('parameter') as $node)
+ {
+ $properties=$node->getAttributes();
+ if(($id=$properties->remove('id'))===null)
+ throw new TConfigurationException('appconfig_parameterid_required');
+ if(($type=$properties->remove('class'))===null)
+ $this->_parameters[$id]=$node->getValue();
+ else
+ $this->_parameters[$id]=array($type,$properties->toArray());
+ }
+ }
+ }
+
+ /**
+ * @return array list of application initial property values, indexed by property names
+ */
+ public function getProperties()
+ {
+ return $this->_properties;
+ }
+
+ /**
+ * @return array list of path aliases, indexed by alias names
+ */
+ public function getAliases()
+ {
+ return $this->_aliases;
+ }
+
+ /**
+ * @return array list of namespaces to be used
+ */
+ public function getUsings()
+ {
+ return $this->_usings;
+ }
+
+ /**
+ * @return array list of module configurations
+ */
+ public function getModules()
+ {
+ return $this->_modules;
+ }
+
+ /**
+ * @return array list of service configurations
+ */
+ public function getService($id)
+ {
+ return isset($this->_services[$id])?$this->_services[$id]:null;
+ }
+
+ /**
+ * @return array list of parameters
+ */
+ public function getParameters()
+ {
+ return $this->_parameters;
+ }
+}
+
?> \ No newline at end of file
diff --git a/framework/prado.php b/framework/prado.php
index d4ecb8eb..a76f4d16 100644
--- a/framework/prado.php
+++ b/framework/prado.php
@@ -1,62 +1,57 @@
-<?php
-/**
- * Prado bootstrap file.
- *
- * This file is intended to be included in the entry script of Prado applications.
- * It defines Prado class by extending PradoBase, a static class providing globally
- * available functionalities to Prado applications. It also sets PHP error and
- * exception handler functions, and provides a __autoload function which automatically
- * loads a class file if the class is not defined.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Revision: $ $Date: $
- * @package System
- */
-
-/**
- * Includes the Prado core header file
- */
-require_once(dirname(__FILE__).'/core.php');
-
-/**
- * Defines Prado class if not defined.
- */
-if(!class_exists('Prado',false))
-{
- class Prado extends PradoBase
- {
- }
-}
-
-/**
- * Defines __autoload function if not defined.
- */
-if(!function_exists('__autoload'))
-{
- function __autoload($className)
- {
- include_once($className.Prado::CLASS_FILE_EXT);
- if(!class_exists($className,false))
- Prado::fatalError("Class file for '$className' cannot be found.");
- }
-}
-
-/**
- * Sets up error handler to convert PHP errors into exceptions that can be caught.
- */
-set_error_handler(array('Prado','phpErrorHandler'),error_reporting());
-
-/**
- * Sets up handler to handle uncaught exceptions.
- */
-set_exception_handler(array('Prado','exceptionHandler'));
-
-/**
- * Includes TApplication class file
- */
-require_once(dirname(__FILE__).'/TApplication.php');
-
+<?php
+/**
+ * Prado bootstrap file.
+ *
+ * This file is intended to be included in the entry script of Prado applications.
+ * It defines Prado class by extending PradoBase, a static class providing globally
+ * available functionalities to Prado applications. It also sets PHP error and
+ * exception handler functions, and provides a __autoload function which automatically
+ * loads a class file if the class is not defined.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $Date: $
+ * @package System
+ */
+
+/**
+ * Includes the Prado core header file
+ */
+require_once(dirname(__FILE__).'/core.php');
+
+/**
+ * Defines Prado class if not defined.
+ */
+if(!class_exists('Prado',false))
+{
+ class Prado extends PradoBase
+ {
+ }
+}
+
+/**
+ * Defines __autoload function if not defined.
+ */
+if(!function_exists('__autoload'))
+{
+ function __autoload($className)
+ {
+ include_once($className.Prado::CLASS_FILE_EXT);
+ if(!class_exists($className,false))
+ Prado::fatalError("Class file for '$className' cannot be found.");
+ }
+}
+
+//Error handlers are set during TApplication::run(),
+//Exception stack is empty if set error handlers requires TApplication
+//and TApplication then causes an exception during instantiation.
+//see TApplication::initDefaultExceptionHandlers()
+
+/**
+ * Includes TApplication class file
+ */
+require_once(dirname(__FILE__).'/TApplication.php');
+
?> \ No newline at end of file