mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
I've merged in the changes by scharfie@gmail.com. For more information please see http://www.bluemargin.com/cake_custom_errors.zip. Olle, can you extract some information from the app/views/pages/home.thtml of that file?
The point is to provide custom error messages for Cake. As you will see, the quality of documentation is astounding. git-svn-id: https://svn.cakephp.org/repo/trunk/cake@255 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
parent
6fa1c1b3d4
commit
37e42105c6
9 changed files with 363 additions and 85 deletions
22
app/views/errors/missing_action.thtml
Normal file
22
app/views/errors/missing_action.thtml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<h1>Missing action</h1>
|
||||
|
||||
<p class="error">You are seeing this error because the action <em><?=$this->missing_action;?></em>
|
||||
is not defined in controller <em><?=Inflector::camelize($this->name);?></em>
|
||||
</p>
|
||||
|
||||
|
||||
<p>
|
||||
<span class="notice"><strong>Notice:</strong> this error is being rendered by the <code>app/views/errors/missing_action.thtml</code>
|
||||
view file, a user-customizable error page for handling invalid action dispatches.</span>
|
||||
</p>
|
||||
|
||||
|
||||
<p>
|
||||
<strong>Error</strong>: Unable to execute action <em><?=$this->missing_action;?></em> on
|
||||
<em><?=Inflector::camelize($this->name);?></em>
|
||||
</p>
|
||||
|
||||
<h2>Controller dump:</h2>
|
||||
<pre>
|
||||
<? print_r($this); ?>
|
||||
</pre>
|
20
app/views/errors/missing_controller.thtml
Normal file
20
app/views/errors/missing_controller.thtml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<h1>Missing controller</h1>
|
||||
|
||||
<p class="error">You are seeing this error because controller <em><?=$this->missing_controller;?></em>
|
||||
could not be found.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<span class="notice"><strong>Notice:</strong> this error is being rendered by the <code>app/views/errors/missing_controller.thtml</code>
|
||||
view file, a user-customizable error page for handling invalid controller dispatches.</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Fatal</strong>: Unable to load controller <em><?=$this->missing_controller;?></em>
|
||||
</p>
|
||||
|
||||
|
||||
<h2>Controller dump:</h2>
|
||||
<pre>
|
||||
<? print_r($this); ?>
|
||||
</pre>
|
22
app/views/errors/missing_view.thtml
Normal file
22
app/views/errors/missing_view.thtml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<h1>Missing view</h1>
|
||||
|
||||
<p class="error">You are seeing this error because the view <em><?=$this->missing_view;?></em>
|
||||
for action <em><?=$this->params['action'];?></em>
|
||||
in controller <em><?=Inflector::camelize($this->name);?></em> could not be found.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<span class="notice"><strong>Notice:</strong> this error is being rendered by the <code>app/views/errors/missing_view.thtml</code>
|
||||
view file, a user-customizable error page for handling missing/invalid views during rendering.</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Fatal</strong>: Unable to load view file <em><?=$this->missing_view;?></em> for
|
||||
action <em><?=$this->params['controller'];?>::<?=$this->params['action'];?></em>
|
||||
</p>
|
||||
|
||||
|
||||
<h2>Controller dump:</h2>
|
||||
<pre>
|
||||
<? print_r($this); ?>
|
||||
</pre>
|
|
@ -7,10 +7,10 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1><?=$title_for_layout?></h1>
|
||||
|
||||
<?=$content_for_layout?>
|
||||
|
||||
<div id="container">
|
||||
<div id="content">
|
||||
<?=$content_for_layout?>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<h2>Cake works!</h2>
|
||||
<h1>Cake works!</h1>
|
||||
|
||||
<p>Your installation of Cake is functional. Edit <code>/app/views/pages/home.thtml</code> to change the contents of this page.</p>
|
||||
|
||||
|
@ -8,13 +8,13 @@
|
|||
|
||||
<h2>Features</h2>
|
||||
|
||||
<p><ul>
|
||||
<ul>
|
||||
<li>compatibile with PHP4 and PHP5</li>
|
||||
<li>supplies integrated <acronym title="Create, Read, Update, Delete">CRUD</acronym> for database and simplified querying so you shouldn't need to write SQL for basic operations (although <em>some</em> familiarity with SQL is strongly recommended)</li>
|
||||
<li>request dispatcher with good-looking, custom URLs</li>
|
||||
<li>fast, flexible templating (PHP syntax with helper methods)</li>
|
||||
<li>works from a website subdirectory, with very little Apache configuration involved (requires <code>.htaccess</code> files and <code>mod_rewrite</code> to work; these are available on most web servers)</li>
|
||||
</ul></p>
|
||||
</ul>
|
||||
|
||||
<p>Cake is in its early infancy, but it works and I'm using it on a few projects. Currently the Dispatcher is working, the Model has <acronym title="Create, Read, Update, Delete">CRUD</acronym> functionality but with no joins between tables yet. The Controller is working and has most basic functions (including <code>render()</code> for templating).</p>
|
||||
|
||||
|
@ -22,6 +22,6 @@
|
|||
|
||||
<p><b>NEW! <?=$this->linkOut('My Amazon Wishlish','http://www.amazon.com/gp/registry/registry.html?id=NODP8QT6LFTO')?></b> for when you'll want to show your appreciation.</p>
|
||||
|
||||
<p><?=$this->linkOut('Cake PHP Google Group','http://groups-beta.google.com/group/cake-php')?> · <?=$this->linkOut('Cake Wiki (temporary)','http://cake.bplusf.net/')?> · <?=$this->linkOut('Cake TRAC (SVN repository, etc.)','https://developers.nextco.com/cake')?><a href=""></a></p>
|
||||
<p><?=$this->linkOut('Cake PHP Google Group','http://groups-beta.google.com/group/cake-php')?> · <?=$this->linkOut('Cake Wiki (temporary)','http://cake.bplusf.net/')?> · <?=$this->linkOut('Cake TRAC (SVN repository, etc.)','https://developers.nextco.com/cake')?></p>
|
||||
|
||||
<p>See <?=$this->linkOut('Cake website','http://sputnik.pl/cake')?> for more information.</p>
|
||||
|
|
|
@ -143,6 +143,24 @@ class Controller extends Template
|
|||
parent::__construct();
|
||||
}
|
||||
|
||||
function missing_controller()
|
||||
{
|
||||
$this->autoRender = false;
|
||||
$this->render('../errors/missing_controller');
|
||||
}
|
||||
|
||||
function missing_action()
|
||||
{
|
||||
$this->autoRender = false;
|
||||
$this->render('../errors/missing_action');
|
||||
}
|
||||
|
||||
function missing_view()
|
||||
{
|
||||
$this->autoRender = false;
|
||||
$this->render('../errors/missing_view');
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects to given $url, after turning off $this->autoRender.
|
||||
*
|
||||
|
|
|
@ -35,6 +35,12 @@
|
|||
* Dispatches the request, creating appropriate models and controllers.
|
||||
*/
|
||||
|
||||
define('DISPATCH_NO_CONTROLLER', 'missing_controller');
|
||||
define('DISPATCH_UNKNOWN_CONTROLLER', 'missing_controller');
|
||||
define('DISPATCH_NO_ACTION', 'missing_action');
|
||||
define('DISPATCH_UNKNOWN_ACTION', 'missing_action');
|
||||
define('DISPATCHER_UNKNOWN_VIEW', 'missing_view');
|
||||
|
||||
uses('error_messages', 'object', 'router', 'controller');
|
||||
|
||||
/**
|
||||
|
@ -44,7 +50,8 @@ uses('error_messages', 'object', 'router', 'controller');
|
|||
* @subpackage cake.libs
|
||||
* @since Cake v 0.2.9
|
||||
*/
|
||||
class Dispatcher extends Object {
|
||||
class Dispatcher extends Object
|
||||
{
|
||||
|
||||
/**
|
||||
* Base URL
|
||||
|
@ -61,67 +68,100 @@ class Dispatcher extends Object {
|
|||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
function __construct () {
|
||||
function __construct ()
|
||||
{
|
||||
$this->base = $this->baseUrl();
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @param unknown_type $url
|
||||
* @return unknown
|
||||
*/
|
||||
function dispatch($url)
|
||||
{
|
||||
$params = $this->parseParams($url);
|
||||
$result = $this->invoke($url);
|
||||
|
||||
return $result === true? $params: array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @param string $url
|
||||
* @return unknown
|
||||
*/
|
||||
function dispatch ($url)
|
||||
function invoke ($url)
|
||||
{
|
||||
global $_POST, $_GET, $_FILES, $_SESSION;
|
||||
|
||||
$params = $this->parseParams($url);
|
||||
$missing_controller = false;
|
||||
$missing_action = false;
|
||||
$missing_view = false;
|
||||
|
||||
// die if no controller set
|
||||
if (empty($params['controller']))
|
||||
$this->errorNoController($url);
|
||||
|
||||
{
|
||||
$missing_controller = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ctrl_name = Inflector::camelize($params['controller']);
|
||||
$ctrl_class = $ctrl_name.'Controller';
|
||||
|
||||
/**
|
||||
* Find out if the specified controller exists, and die if not.
|
||||
*/
|
||||
if (!loadController($ctrl_name) || !class_exists($ctrl_class))
|
||||
$this->errorUnknownController($url, $ctrl_name);
|
||||
{
|
||||
$missing_controller = true;
|
||||
}
|
||||
}
|
||||
|
||||
$ctrl_methods = get_class_methods($ctrl_class);
|
||||
$ctrl_vars = get_class_vars($ctrl_class);
|
||||
if ($missing_controller)
|
||||
{
|
||||
$ctrl_class = 'AppController';
|
||||
$controller = new $ctrl_class($this);
|
||||
$params['action'] = 'missing_controller';
|
||||
$controller->missing_controller = $params['controller'];
|
||||
}
|
||||
else
|
||||
{
|
||||
// create controller
|
||||
$controller = new $ctrl_class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* If _no_action_is set, check if the default action, index() exists. If it doesn't, die.
|
||||
*/
|
||||
// if action is not set, and the default Controller::index() method doesn't exist
|
||||
if (empty($params['action']))
|
||||
{
|
||||
if (in_array('index', $ctrl_methods))
|
||||
if (method_exists($controller, 'index'))
|
||||
{
|
||||
$params['action'] = 'index';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errorNoAction($url);
|
||||
$missing_action = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the specified action really exists.
|
||||
*/
|
||||
if (!in_array($params['action'], $ctrl_methods))
|
||||
// if the requested action doesn't exist
|
||||
if (!method_exists($controller, $params['action']))
|
||||
{
|
||||
$this->errorUnknownAction($url, $ctrl_class, $params['action']);
|
||||
$missing_action = true;
|
||||
}
|
||||
|
||||
$controller = new $ctrl_class ($params);
|
||||
if ($missing_action)
|
||||
{
|
||||
$controller->missing_action = $params['action'];
|
||||
$params['action'] = 'missing_action';
|
||||
}
|
||||
|
||||
// initialize the controller
|
||||
$controller->base = $this->base;
|
||||
$controller->here = $this->base.'/'.$url;
|
||||
$controller->params = $params;
|
||||
$controller->action = $params['action'];
|
||||
$controller->data = empty($params['data'])? null: $params['data'];
|
||||
$controller->passed_args = empty($params['pass'])? null: $params['pass'];
|
||||
|
@ -129,10 +169,28 @@ class Dispatcher extends Object {
|
|||
// EXECUTE THE REQUESTED ACTION
|
||||
call_user_func_array(array(&$controller, $params['action']), empty($params['pass'])? null: $params['pass']);
|
||||
|
||||
if ($controller->autoRender)
|
||||
$controller->render();
|
||||
$isFatal = isset($controller->isFatal) ? $controller->isFatal : false;
|
||||
|
||||
return $params;
|
||||
if ($isFatal)
|
||||
{
|
||||
switch($params['action'])
|
||||
{
|
||||
case 'missing_controller':
|
||||
$this->errorUnknownController($url, $ctrl_name);
|
||||
break;
|
||||
|
||||
case 'missing_action':
|
||||
$this->errorUnknownAction($url, $ctrl_class, $controller->missing_action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($controller->autoRender)
|
||||
{
|
||||
$controller->render();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -166,7 +224,8 @@ class Dispatcher extends Object {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function baseUrl () {
|
||||
function baseUrl ()
|
||||
{
|
||||
global $_SERVER;
|
||||
|
||||
//non mod_rewrite use:
|
||||
|
@ -191,7 +250,8 @@ class Dispatcher extends Object {
|
|||
* @param string $name Name of the error message (e.g. Not found)
|
||||
* @param string $message
|
||||
*/
|
||||
function error ($code, $name, $message) {
|
||||
function error ($code, $name, $message)
|
||||
{
|
||||
$controller = new Controller ($this);
|
||||
$controller->base = $this->base;
|
||||
$controller->error($code, $name, $message);
|
||||
|
@ -203,7 +263,8 @@ class Dispatcher extends Object {
|
|||
* @param unknown_type $url
|
||||
* @param unknown_type $message
|
||||
*/
|
||||
function error404 ($url, $message) {
|
||||
function error404 ($url, $message)
|
||||
{
|
||||
$this->error('404', 'Not found', sprintf(ERROR_404, $url, $message));
|
||||
}
|
||||
|
||||
|
@ -212,7 +273,8 @@ class Dispatcher extends Object {
|
|||
*
|
||||
* @param string $url
|
||||
*/
|
||||
function errorNoController ($url) {
|
||||
function errorNoController ($url)
|
||||
{
|
||||
DEBUG?
|
||||
trigger_error (ERROR_NO_CONTROLLER_SET, E_USER_ERROR):
|
||||
$this->error404($url, "no controller set");
|
||||
|
@ -225,7 +287,8 @@ class Dispatcher extends Object {
|
|||
* @param string $url
|
||||
* @param string $controller_class
|
||||
*/
|
||||
function errorUnknownController ($url, $controller_class) {
|
||||
function errorUnknownController ($url, $controller_class)
|
||||
{
|
||||
DEBUG?
|
||||
trigger_error (sprintf(ERROR_UNKNOWN_CONTROLLER, $controller_class), E_USER_ERROR):
|
||||
$this->error404($url, "missing controller \"{$controller_class}\"");
|
||||
|
@ -237,7 +300,8 @@ class Dispatcher extends Object {
|
|||
*
|
||||
* @param string $url
|
||||
*/
|
||||
function errorNoAction ($url) {
|
||||
function errorNoAction ($url)
|
||||
{
|
||||
DEBUG?
|
||||
trigger_error (ERROR_NO_ACTION_SET, E_USER_ERROR):
|
||||
$this->error404(sprintf(ERROR_404, $url, "no action set"));
|
||||
|
@ -251,7 +315,8 @@ class Dispatcher extends Object {
|
|||
* @param string $controller_class
|
||||
* @param string $action
|
||||
*/
|
||||
function errorUnknownAction ($url,$controller_class, $action) {
|
||||
function errorUnknownAction ($url,$controller_class, $action)
|
||||
{
|
||||
DEBUG?
|
||||
trigger_error (sprintf(ERROR_NO_ACTION, $action, $controller_class), E_USER_ERROR):
|
||||
$this->error404($url, "missing controller \"{$controller_class}\"");
|
||||
|
|
|
@ -163,31 +163,109 @@ class Template extends Object
|
|||
* @param string $layout
|
||||
* @param string $file Custom filename for view
|
||||
*/
|
||||
function render ($action=null, $layout=null, $file=null) {
|
||||
function render ($action=null, $layout=null, $file=null)
|
||||
{
|
||||
if (isset($this->hasRendered) && $this->hasRendered)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->hasRendered = false;
|
||||
}
|
||||
|
||||
$this->autoRender = false;
|
||||
|
||||
if (!$action) $action = $this->action;
|
||||
if ($layout) $this->setLayout($layout);
|
||||
|
||||
//$isFatal = isset($this->isFatal) ? $this->isFatal : false;
|
||||
|
||||
$view_fn = $file? $file: $this->_getViewFn($action);
|
||||
|
||||
if (!is_file($view_fn)) {
|
||||
DEBUG? trigger_error (sprintf(ERROR_NO_VIEW, $action, $view_fn), E_USER_ERROR)
|
||||
: $this->error('404', 'Not found', sprintf(ERROR_404, '', "missing view \"{$action}\""));
|
||||
if (!is_file($view_fn))
|
||||
{
|
||||
if (strtolower(get_class($this)) == 'template')
|
||||
{
|
||||
return array('action' => $action, 'layout' => $layout, 'view_fn' => $view_fn);
|
||||
}
|
||||
|
||||
// check to see if the missing view is due to a custom missing_action
|
||||
if (strpos($action, 'missing_action') !== false)
|
||||
{
|
||||
$error_action = 'missing_action';
|
||||
}
|
||||
else
|
||||
{
|
||||
$error_action = 'missing_view';
|
||||
}
|
||||
|
||||
|
||||
// check for controller-level view handler
|
||||
foreach(array($this->name, 'errors') as $view_dir)
|
||||
{
|
||||
$missing_view_fn = VIEWS.$view_dir.DS.$error_action.'.thtml';
|
||||
$missing_view_exists = is_file($missing_view_fn);
|
||||
if ($missing_view_exists)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($action, 'missing_view') === false)
|
||||
{
|
||||
$controller =& $this;
|
||||
$controller->missing_view = $view_fn;
|
||||
$controller->action = $action;
|
||||
call_user_func_array(array(&$controller, 'missing_view'), empty($params['pass'])? null: $params['pass']);
|
||||
$isFatal = isset($this->isFatal) ? $this->isFatal : false;
|
||||
if (!$isFatal)
|
||||
{
|
||||
$view_fn = $missing_view_fn;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$missing_view_exists = false;
|
||||
}
|
||||
|
||||
if (!$missing_view_exists || $isFatal)
|
||||
{
|
||||
// app/errors/missing_view.thtml view is missing!
|
||||
if (DEBUG)
|
||||
{
|
||||
trigger_error (sprintf(ERROR_NO_VIEW, $action, $view_fn), E_USER_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error('404', 'Not found', sprintf(ERROR_404, '', "missing view \"{$action}\""));
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
$out = $this->_render($view_fn, $this->_view_vars, 0);
|
||||
|
||||
if ($out !== false) {
|
||||
if ($this->layout && $this->autoLayout)
|
||||
$out = $this->renderLayout($out);
|
||||
print $out;
|
||||
}
|
||||
else {
|
||||
|
||||
if ($view_fn && !$this->hasRendered)
|
||||
{
|
||||
$out = $this->_render($view_fn, $this->_view_vars, 0);
|
||||
if ($out !== false)
|
||||
{
|
||||
if ($this->layout && $this->autoLayout)
|
||||
{
|
||||
$out = $this->renderLayout($out);
|
||||
}
|
||||
|
||||
print $out;
|
||||
$this->hasRendered = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$out = $this->_render($view_fn, $this->_view_vars, false);
|
||||
trigger_error (sprintf(ERROR_IN_VIEW, $view_fn, $out), E_USER_ERROR);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
BODY {
|
||||
font-size:.9em;
|
||||
font-size: 76%;
|
||||
}
|
||||
|
||||
BODY, INPUT, TEXTAREA {
|
||||
|
@ -8,15 +8,28 @@ font-family:sans-serif;
|
|||
|
||||
H1 {
|
||||
font-size:2.1em;
|
||||
text-align:center;
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
padding-left: 15%;
|
||||
top: 0.35em;
|
||||
left: 0;
|
||||
height: 4em;
|
||||
}
|
||||
|
||||
H2 {
|
||||
font-size:1.7em;
|
||||
color: #383;
|
||||
}
|
||||
|
||||
H3 {
|
||||
font-size:1.4em;
|
||||
color: #553;
|
||||
}
|
||||
|
||||
H4 {
|
||||
font-size:1.15em;
|
||||
color: #338;
|
||||
}
|
||||
|
||||
P {
|
||||
|
@ -29,6 +42,10 @@ white-space:nowrap;
|
|||
text-decoration:underline;
|
||||
}
|
||||
|
||||
A:HOVER {
|
||||
background-color:#EEE;
|
||||
}
|
||||
|
||||
CODE, PRE {
|
||||
font-family:monospace;
|
||||
font-size:1.1em !important;
|
||||
|
@ -55,3 +72,39 @@ HR {
|
|||
height:0;
|
||||
border-top:1px solid #AAA;
|
||||
}
|
||||
|
||||
|
||||
#container {
|
||||
margin: 0 auto;
|
||||
border-top: solid 5em #69c;
|
||||
color: #333;
|
||||
font: normal 1.1em Verdana;
|
||||
padding: 0 15%;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding-top: 1em;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
line-height: 170%;
|
||||
}
|
||||
|
||||
.notice {
|
||||
padding: 1em;
|
||||
background: #ffd;
|
||||
border: solid 2px #eeb;
|
||||
display: block;
|
||||
font-family: Verdana;
|
||||
}
|
||||
|
||||
.tip {
|
||||
background: #efe;
|
||||
padding: 1em;
|
||||
border: solid 2px #cdc;
|
||||
}
|
||||
|
||||
.error {
|
||||
background: #fee;
|
||||
padding: 1em;
|
||||
border: solid 2px #dcc;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue