Permalink
Browse files

Refactored show_404 to always apply 404_override

  • Loading branch information...
dchill42 committed Aug 10, 2011
1 parent 7559d7e commit 374c2d25b1cf4acccf120695b49ef32b0435501b
Showing with 176 additions and 143 deletions.
  1. +39 −91 system/core/CodeIgniter.php
  2. +28 −4 system/core/Exceptions.php
  3. +6 −12 system/core/Loader.php
  4. +103 −36 system/core/Router.php
View
@@ -233,6 +233,7 @@ public static function &get_instance()
include($file);
}
+ // Instantiate CodeIgniter
function &get_instance()
{
return CodeIgniter::get_instance();
@@ -266,6 +267,18 @@ function &get_instance()
$CI->load_core('Utf8');
+/*
+ * ------------------------------------------------------
+ * Instantiate the output class
+ * ------------------------------------------------------
+ *
+ * Note: By instantiating Output before Router, we ensure
+ * it is available to support 404 overrides in case of a
+ * call to show_404().
+ *
+ */
+ $CI->load_core('Output');
+
/*
* ------------------------------------------------------
* Instantiate the URI class
@@ -287,13 +300,6 @@ function &get_instance()
$CI->router->_set_overrides($routing);
}
-/*
- * ------------------------------------------------------
- * Instantiate the output class
- * ------------------------------------------------------
- */
- $CI->load_core('Output');
-
/*
* ------------------------------------------------------
* Is there a valid cache file? If so, we're done...
@@ -336,49 +342,40 @@ function &get_instance()
$CI->load->ci_autoloader();
+ // Set a mark point for benchmarking
+ $BM->mark('loading_time:_base_classes_end');
+
/*
* ------------------------------------------------------
- * Load the local controller
+ * Is there a "pre_controller" hook?
* ------------------------------------------------------
*/
+ $EXT->_call_hook('pre_controller');
- // Load the Controller base class
- require BASEPATH.'core/Controller.php';
+/*
+ * ------------------------------------------------------
+ * Load the local controller
+ * ------------------------------------------------------
+ */
- // Load the Controller subclass, if found
- $file = 'core/'.$CI->config->item('subclass_prefix').'Controller.php';
- $packages = $CI->load->get_package_paths();
- foreach ($packages as $path)
- {
- if (file_exists($path.$file))
- {
- require $path.$file;
- break;
- }
- }
+ // Mark a start point so we can benchmark the controller
+ $BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');
- // Load the local application controller
- // Note: The Router class automatically validates the controller path using the router->_validate_request().
- // If this include fails it means that the default controller in the Routes.php file is not resolving to something valid.
- $file = 'controllers/'.$CI->router->fetch_directory().$CI->router->fetch_class().'.php';
- $found = FALSE;
- foreach ($packages as $path)
- {
- if (file_exists($path.$file))
- {
- include($path.$file);
- $found = TRUE;
- break;
- }
- }
+ // Get the routed directory, class, and method
+ $subdir = $CI->router->fetch_directory();
+ $class = $CI->router->fetch_class();
+ $method = $CI->router->fetch_method();
- if ( ! $found)
- {
- show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
- }
+ // Instantiate the controller object
+ $CI->load->controller($subdir.$class);
+ $CI->routed =& $CI->$class;
- // Set a mark point for benchmarking
- $BM->mark('loading_time:_base_classes_end');
+/*
+ * ------------------------------------------------------
+ * Is there a "post_controller_constructor" hook?
+ * ------------------------------------------------------
+ */
+ $EXT->_call_hook('post_controller_constructor');
/*
* ------------------------------------------------------
@@ -389,8 +386,6 @@ function &get_instance()
* loader class can be called via the URI, nor can
* controller functions that begin with an underscore
*/
- $class = $CI->router->fetch_class();
- $method = $CI->router->fetch_method();
if ( ! class_exists($class)
OR strncmp($method, '_', 1) == 0
@@ -400,32 +395,6 @@ function &get_instance()
show_404($class.'/'.$method);
}
-/*
- * ------------------------------------------------------
- * Is there a "pre_controller" hook?
- * ------------------------------------------------------
- */
- $EXT->_call_hook('pre_controller');
-
-/*
- * ------------------------------------------------------
- * Instantiate the requested controller
- * ------------------------------------------------------
- */
- // Mark a start point so we can benchmark the controller
- $BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');
-
- $CI->routed = new $class();
- $name = strtolower($class);
- $CI->$name = $CI->routed;
-
-/*
- * ------------------------------------------------------
- * Is there a "post_controller_constructor" hook?
- * ------------------------------------------------------
- */
- $EXT->_call_hook('post_controller_constructor');
-
/*
* ------------------------------------------------------
* Call the requested method
@@ -442,28 +411,7 @@ function &get_instance()
// methods, so we'll use this workaround for consistent behavior
if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI->routed))))
{
- // Check and see if we are using a 404 override and use it.
- if ( ! empty($CI->router->routes['404_override']))
- {
- $x = explode('/', $CI->router->routes['404_override']);
- $class = $x[0];
- $method = (isset($x[1]) ? $x[1] : 'index');
- if ( ! class_exists($class))
- {
- if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
- {
- show_404($class.'/'.$method);
- }
-
- include_once(APPPATH.'controllers/'.$class.'.php');
- unset($CI->routed);
- $CI->routed = new $class();
- }
- }
- else
- {
- show_404($class.'/'.$method);
- }
+ show_404($class.'/'.$method);
}
// Call the requested method.
View
@@ -83,22 +83,46 @@ function log_exception($severity, $message, $filepath, $line)
/**
* 404 Page Not Found Handler
*
+ * Calls the 404 override method if configured, or displays a generic 404 error.
+ * The 404 override method will get the requested page as its first argument,
+ * followed by any trailing segments of 404_override. So, if "foo/bar" triggered
+ * a 404, and 404_override was "my404/method/one/two", the effect would be to call:
+ * my404->method("foo/bar", "one", "two");
+ *
* @access private
* @param string
* @return string
*/
function show_404($page = '', $log_error = TRUE)
{
- $heading = "404 Page Not Found";
- $message = "The page you requested was not found.";
+ $heading = '404 Page Not Found';
+ $message = 'The page you requested was not found.';
// By default we log this, but allow a dev to skip it
if ($log_error)
{
log_message('error', '404 Page Not Found --> '.$page);
}
- echo $this->show_error($heading, $message, 'error_404', 404);
+ // Check Router for a 404 override
+ $CI =& get_instance();
+ $segments = $CI->router->override_404();
+ if ($segments === FALSE)
+ {
+ // Just display the generic 404
+ echo $this->show_error($heading, $message, 'error_404', 404);
+ }
+ else
+ {
+ // Pull off 404 class and method, and prepend requested page
+ $class = array_shift($segments);
+ $method = array_shift($segments);
+ array_unshift($segments, $page);
+
+ // Call 404 method and display output
+ call_user_func_array(array(&$CI->$class, $method), $segments);
+ $CI->output->_display();
+ }
exit;
}
@@ -175,4 +199,4 @@ function show_php_error($severity, $message, $filepath, $line)
// END Exceptions Class
/* End of file Exceptions.php */
-/* Location: ./system/core/Exceptions.php */
+/* Location: ./system/core/Exceptions.php */
View
@@ -217,6 +217,12 @@ public function controller($controller, $name = '')
show_error('The controller name you are loading is the name of a resource that is already being used: '.$name);
}
+ // Load base class(es) if not already done
+ if ( ! class_exists('CI_Controller'))
+ {
+ load_class('Controller', 'core');
+ }
+
// Search MVC paths for controller
$controller = strtolower($controller);
$file = 'controllers/'.$path.$controller.'.php';
@@ -318,19 +324,7 @@ public function model($model, $name = '', $db_conn = FALSE)
// Load base class(es) if not already done
if ( ! class_exists('CI_Model'))
{
- // Load core base class
load_class('Model', 'core');
-
- // Search for model subclass
- $file = 'core/'.$CI->config->item('subclass_prefix').'Model.php';
- foreach ($this->_ci_mvc_paths as $mod_path => $view_cascade)
- {
- if (file_exists($mod_path.$file))
- {
- require $mod_path.$file;
- break;
- }
- }
}
// Search MVC paths for model
Oops, something went wrong.

0 comments on commit 374c2d2

Please sign in to comment.