Welcome Guest, Not a member yet? Register   Sign In
Custom 404 Without file_get_contents or Curl
#1

[eluser]Unknown[/eluser]
Lately I've needed my 404 pages to function as controllers and I wanted to avoid using file_get_contents or curl, so I've done the following to serve a custom 404 controller if a requested controller of function is not found.

1) Create a new router library to overwrite the _validate_request functionality
2) Add a line in the config file to define a 404 controller


Step 1
-----------------------------

First, create the file
Code:
./system/application/libraries/MY_Router.php
and copy and paste the following code into it:

Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class MY_Router extends CI_Router {
    
    function Custom_Router()
    {
        parent::CI_Router();
    }

    function _validate_request($segments,$error = false,$page='')
    {    
        // Does the requested controller exist in the root folder?
        if (file_exists(APPPATH.'controllers/'.$segments[0].EXT))
        {
            return $segments;
        }

        // Is the controller in a sub-folder?
        if (is_dir(APPPATH.'controllers/'.$segments[0]))
        {        
            // Set the directory and remove it from the segment array
            $this->set_directory($segments[0]);
            $segments = array_slice($segments, 1);
            
            if (count($segments) > 0)
            {
                // Does the requested controller exist in the sub-folder?
                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT))
                {
                    if(!$error)
                    {
                        return $this->show_404($this->fetch_directory().$segments[0]);
                    }
                    else
                    {
                        show_404($page);
                    }
                }
            }
            else
            {
                $this->set_class($this->default_controller);
                $this->set_method('index');
            
                // Does the default controller exist in the sub-folder?
                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))
                {
                    $this->directory = '';
                    return array();
                }
            
            }

            return $segments;
        }

        // Can't find the requested controller...
        
        if(!$error)
        {
            return $this->show_404($segments[0]);
        }
        else
        {
            show_404($page);
        }
    }
    
    function show_404($page){
        
        if(isset($this->config->config['error_controller']) && isset($this->config->config['error_controller']) != '')
        {    
            $error_controller = explode('/',$this->config->config['error_controller']);
            $error_controller = $this->_validate_request($error_controller,true,$page);
            
            log_message('error', '404 Page Not Found --> '.$page);
            header("HTTP/1.0 404 Not Found");
            
            return $error_controller;
        }
        else
        {
            show_404($page);
            return false;
        }
    }
}


Step 2
-----------------------------

Then, open your
Code:
./system/application/config/config.php
file and add the following section to it, changing the $config['error_controller'] variable to match the location of the controller you'd like to use for your 404 pages.

Code:
/*
|--------------------------------------------------------------------------
| 404 Controller
|--------------------------------------------------------------------------
|
| Your 404 error controller including containing folder (if applicable).
|
|    errors/error404
|
*/

$config['error_controller'] = "errors/error404";


Description
-----------------------------

Essentially what this does is intercepts the call to the default 404 function in CodeIgniter and checks to see if you've defined a 404 controller. If the 404 controller has been defined, it runs the path specified in the config file through the request validator to verify that the controller actually exists. If the controller does exist, it is served. If it does not exist, the default 404 function is invoked instead.


Notes
-----------------------------
- If you've changed the class extension prefix in your config.php file, you'll need to name the file I've called MY_Router.php to match your selected prefix.
- This does not modify the behavior of the show_404 function. You'll have to get creative in your controllers when requested data is not returned.

I haven't found it to be too troublesome not using show_404 as I often try to create 404 pages that are relevant the the area of the site the user is having trouble in (articles, news, registration, etc.), where a static or generic 404 wouldn't be extremely useful anyway.


Messages In This Thread
Custom 404 Without file_get_contents or Curl - by El Forum - 06-20-2010, 10:56 PM



Theme © iAndrew 2016 - Forum software by © MyBB