This tutorial will show you an example on how to we can separate front-end and back-end in Codeigniter. Front-end which is mainly used by public users who navigate through the site and sometimes register themselves to get updates on the site activities, new posts, update on a particular post etc. Back-end which is mainly used by site author, administrator, editor etc. to manage the site. So back-end will be restricted to some people with given roles.

Here I can use different URL, i.e., http://www.example.com/admin, for accessing directly admin login page or I can also use the URL http://www.example.com where login link is present on front-end header to navigate to the admin section.

First you need to go through https://www.roytuts.com/how-to-remove-index-php-from-url-in-codeigniter/, https://www.roytuts.com/setup-hmvc-with-codeigniter-2-1-4/ and https://www.roytuts.com/using-template-in-codeigniter/ tutorials for getting an idea for better understanding of the following implementation.

Step 1. Create a config file app_config.php with the following source code and put it under <project root>/application/config/

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/*
  |--------------------------------------------------------------------------
  | Website Name
  |--------------------------------------------------------------------------
  |
  |Name of the Website
  |
 */

$config['site_name'] = 'www.example.com';

/*
  |--------------------------------------------------------------------------
  | Message key
  |--------------------------------------------------------------------------
  |
  | Message key where message will be kept for future use
 */
$config['msg_key'] = 'msg_key';

/* End of file app_config.php */
/* Location: ./application/config/app_config.php */

Step 2. Verify <project root>/application/config/autoload.php with the following content

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');
/*
  | -------------------------------------------------------------------
  | AUTO-LOADER
  | -------------------------------------------------------------------
  | This file specifies which systems should be loaded by default.
  |
  | In order to keep the framework as light-weight as possible only the
  | absolute minimal resources are loaded by default. For example,
  | the database is not connected to automatically since no assumption
  | is made regarding whether you intend to use it.  This file lets
  | you globally define which systems you would like loaded with every
  | request.
  |
  | -------------------------------------------------------------------
  | Instructions
  | -------------------------------------------------------------------
  |
  | These are the things you can load automatically:
  |
  | 1. Packages
  | 2. Libraries
  | 3. Helper files
  | 4. Custom config files
  | 5. Language files
  | 6. Models
  |
 */

/*
  | -------------------------------------------------------------------
  |  Auto-load Packges
  | -------------------------------------------------------------------
  | Prototype:
  |
  |  $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared');
  |
 */

$autoload['packages'] = array();


/*
  | -------------------------------------------------------------------
  |  Auto-load Libraries
  | -------------------------------------------------------------------
  | These are the classes located in the system/libraries folder
  | or in your application/libraries folder.
  |
  | Prototype:
  |
  |	$autoload['libraries'] = array('database', 'session', 'xmlrpc');
 */

$autoload['libraries'] = array('session', 'template', 'userauth');


/*
  | -------------------------------------------------------------------
  |  Auto-load Helper Files
  | -------------------------------------------------------------------
  | Prototype:
  |
  |	$autoload['helper'] = array('url', 'file');
 */

$autoload['helper'] = array('url', 'file', 'text', 'form');


/*
  | -------------------------------------------------------------------
  |  Auto-load Config files
  | -------------------------------------------------------------------
  | Prototype:
  |
  |	$autoload['config'] = array('config1', 'config2');
  |
  | NOTE: This item is intended for use ONLY if you have created custom
  | config files.  Otherwise, leave it blank.
  |
 */

$autoload['config'] = array('app_config');


/*
  | -------------------------------------------------------------------
  |  Auto-load Language files
  | -------------------------------------------------------------------
  | Prototype:
  |
  |	$autoload['language'] = array('lang1', 'lang2');
  |
  | NOTE: Do not include the "_lang" part of your file.  For example
  | "codeigniter_lang.php" would be referenced as array('codeigniter');
  |
 */

$autoload['language'] = array();


/*
  | -------------------------------------------------------------------
  |  Auto-load Models
  | -------------------------------------------------------------------
  | Prototype:
  |
  |	$autoload['model'] = array('model1', 'model2');
  |
 */

$autoload['model'] = array();


/* End of file autoload.php */
/* Location: ./application/config/autoload.php */

Step 3. Check default controller is home in <project root>/application/config/routes.php 

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');
/*
  | -------------------------------------------------------------------------
  | URI ROUTING
  | -------------------------------------------------------------------------
  | This file lets you re-map URI requests to specific controller functions.
  |
  | Typically there is a one-to-one relationship between a URL string
  | and its corresponding controller class/method. The segments in a
  | URL normally follow this pattern:
  |
  |	example.com/class/method/id/
  |
  | In some instances, however, you may want to remap this relationship
  | so that a different class/function is called than the one
  | corresponding to the URL.
  |
  | Please see the user guide for complete details:
  |
  |	http://codeigniter.com/user_guide/general/routing.html
  |
  | -------------------------------------------------------------------------
  | RESERVED ROUTES
  | -------------------------------------------------------------------------
  |
  | There area two reserved routes:
  |
  |	$route['default_controller'] = 'welcome';
  |
  | This route indicates which controller class should be loaded if the
  | URI contains no data. In the above example, the "welcome" class
  | would be loaded.
  |
  |	$route['404_override'] = 'errors/page_missing';
  |
  | This route will tell the Router what URI segments to use if those provided
  | in the URL cannot be matched to a valid route.
  |
 */

$route['default_controller'] = "home";
$route['404_override'] = '';


/* End of file routes.php */
/* Location: ./application/config/routes.php */

Step 4. We will use two different templates for front-end and back-end. So check <project root>/application/config/template.php 

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');
/*
  |--------------------------------------------------------------------------
  | Active template
  |--------------------------------------------------------------------------
  |
  | The $template['active_template'] setting lets you choose which template
  | group to make active.  By default there is only one group (the
  | "default" group).
  |
 */
$template['active_template'] = 'public';

/*
  |--------------------------------------------------------------------------
  | Explaination of template group variables
  |--------------------------------------------------------------------------
  |
  | ['template'] The filename of your master template file in the Views folder.
  |   Typically this file will contain a full XHTML skeleton that outputs your
  |   full template or region per region. Include the file extension if other
  |   than ".php"
  | ['regions'] Places within the template where your content may land.
  |   You may also include default markup, wrappers and attributes here
  |   (though not recommended). Region keys must be translatable into variables
  |   (no spaces or dashes, etc)
  | ['parser'] The parser class/library to use for the parse_view() method
  |   NOTE: See http://codeigniter.com/forums/viewthread/60050/P0/ for a good
  |   Smarty Parser that works perfectly with Template
  | ['parse_template'] FALSE (default) to treat master template as a View. TRUE
  |   to user parser (see above) on the master template
  |
  | Region information can be extended by setting the following variables:
  | ['content'] Must be an array! Use to set default region content
  | ['name'] A string to identify the region beyond what it is defined by its key.
  | ['wrapper'] An HTML element to wrap the region contents in. (We
  |   recommend doing this in your template file.)
  | ['attributes'] Multidimensional array defining HTML attributes of the
  |   wrapper. (We recommend doing this in your template file.)
  |
  | Example:
  | $template['default']['regions'] = array(
  |    'header' => array(
  |       'content' => array('<h1>Welcome</h1>','<p>Hello World</p>'),
  |       'name' => 'Page Header',
  |       'wrapper' => '<div>',
  |       'attributes' => array('id' => 'header', 'class' => 'clearfix')
  |    )
  | );
  |
 */

/*
  |--------------------------------------------------------------------------
  | Default Template Configuration (adjust this or create your own)
  |--------------------------------------------------------------------------
 */
//public template
$template['public']['template'] = 'templates/public/template';
$template['public']['regions'] = array(
    'title',
    'content'
);
$template['public']['parser'] = 'parser';
$template['public']['parser_method'] = 'parse';
$template['public']['parse_template'] = TRUE;

//admin template
$template['admin']['template'] = 'templates/admin/template';
$template['admin']['regions'] = array(
    'title',
    'content'
);
$template['admin']['parser'] = 'parser';
$template['admin']['parser_method'] = 'parse';
$template['admin']['parse_template'] = TRUE;

/* End of file template.php */
/* Location: ./config/template.php */

Step 5. We need to create form validation library to make codeigniter validation work correctly. Create below file at <project root>/application/libraries/my_form_validation.php

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

class MY_Form_Validation extends CI_Form_validation {

    function run($module = '', $group = '') {
        (is_object($module)) AND $this->CI = &$module;
        return parent::run($group);
    }

}

/* End of file my_form_validation.php */
/* Location: ./application/libraries/my_form_validation.php */

Step 6. Create one userauth library related to user authentication functionalities at <project root>/application/libraries/userauth.php. Note that all hardcoded values used here for demo purpose only and those values should come from database or any other external system as per your need.

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

define('STATUS_ACTIVATED', '1');
define('STATUS_NOT_ACTIVATED', '0');

/**
 * Description of UserAuth
 *
 * @author Admin
 */
class UserAuth {

    private $ci;
    private $msg;

    function __construct() {
        $this->ci = & get_instance();
        $this->ci->lang->load('msg');
    }

    /*
     * get message
     */

    private function get_msg($msg) {
        $this->msg .= $msg . "\r\n";
    }

    /*
     * display message
     */

    function display_msg() {
        return $this->msg;
    }

    /**
     * Login user on the site. Return TRUE if login is successful
     * (user exists and activated, password is correct), otherwise FALSE.
     *
     * @param	string	(email)
     * @param	string  (password)
     */
    function login($email, $password) {
        if ((strlen($email) > 0) AND (strlen($password) > 0)) {
            if (!is_null($email == 'admin@example.com')) { // email ok --should be checked against database
                if ($password == 'admin') {  // password ok //should be checked against database
                        $this->ci->session->set_userdata(array(
                            'user_id' => 1, //should come from database
                            'user_email' => 'admin@example.com', //should come from database
                            'last_login' => '2015-05-05 12:00:25', //should come from database
                            'user_role' => 'admin', //should come from database
                            'user_status' => STATUS_ACTIVATED //should be checked against database
                        ));
                    return TRUE;
                } else {              // fail - wrong password
                    $this->get_msg($this->ci->lang->line('incorrect_password'));
                }
            } else {               // fail - wrong email
                $this->get_msg($this->ci->lang->line('incorrect_email'));
            }
        }
        return FALSE;
    }

    /**
     * Logout user from the site
     *
     * @return	void
     */
    function logout() {
        $this->delete_autologin();
        // See http://codeigniter.com/forums/viewreply/662369/ as the reason for the next line
        $this->ci->session->set_userdata(array('user_id' => '', 'user_email' => '', 'last_login' => '',
            'user_role' => '', 'user_status' => ''));
        $this->ci->session->sess_destroy();
    }

    /**
     * Get user role_id
     *
     * @param int
     * @return int
     */
    function get_role_id($user_id == 1) {
        return 1; //should come from database
    }

    /**
     * Check if user logged in. Also test if user is activated or not.
     *
     * @param	bool
     * @return	bool
     */
    function is_logged_in($activated = TRUE) {
        return $this->ci->session->userdata('user_status') === ($activated ? STATUS_ACTIVATED : STATUS_NOT_ACTIVATED);
    }

    /**
     * Get role name from role_id
     *
     * @param	string
     * @param	integer
     */
    function get_role_name($role_id == 1) {
        if ($role_id > 0) {
            return 'admin'; //should come from database
        }
        return '';
    }

    /**
     * Get user_id
     *
     * @return	string
     */
    function get_user_id() {
        if ($this->ci->session->userdata('user_id')) {
            return $this->ci->session->userdata('user_id');
        }
        return -1;
    }

    /**
     * Get username
     *
     * @return	string
     */
    function get_user_email() {
        if ($this->ci->session->userdata('user_email')) {
            return $this->ci->session->userdata('user_email');
        }
        return '';
    }

    /**
     * check logged in user is admin
     *
     * @param	string
     * @return	bool
     */
    function is_admin() {
        if ($this->ci->session->userdata('user_role')) {
            if (strtolower(trim($this->ci->session->userdata('user_role'))) === 'admin') {
                return TRUE;
            }
        }
        return FALSE;
    }

    /**
     * Get error message.
     * Can be invoked after any failed operation such as login or register.
     *
     * @return	string
     */
    function get_error_message() {
        return $this->msg;
    }

}

/* End of file userAuth.php */
/* Location: ./application/libraries/userAuth.php */

Step 7. Now we will create MY_Controller at <project root>/application/core/MY_Controller.php which will be extended by Public_Controller for front-end and Admin_Controller for back-end to meet extended functionality performed by those two different templates.

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/* load the MX_Router class */
require APPPATH . "third_party/MX/Controller.php";

/**
 * Description of my_controller
 *
 * @author Administrator
 */
class MY_Controller extends MX_Controller {

    function __construct() {
        parent::__construct();
        if (version_compare(CI_VERSION, '2.1.0', '<')) {
            $this->load->library('security');
        }
        //no title for public and admin template
        $this->template->write('title', '', TRUE);
        $this->template->write('content', '', TRUE);
    }

}

/* End of file MY_Controller.php */
/* Location: ./application/core/MY_Controller.php */

Step 8. Create Public_Controller at <project root>/application/core/Public_Controller.php for front-end related view.

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

class Public_Controller extends MY_Controller {

    function __construct() {
        parent::__construct();
        // logic for template
    }

}

/* End of file Public_Controller.php */
/* Location: ./application/core/Public_Controller.php */

Step 9. Create Public_Controller at <project root>/application/core/MY_Controller.php for back-end related view.

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

class Admin_Controller extends MY_Controller {

    function __construct() {
        parent::__construct();
        // logic for template
        $this->template->set_template('admin');
    }

}

/* End of file Admin_Controller.php */
/* Location: ./application/core/Admin_Controller.php */

Step 10. For other files like public/admin templates, css, js, images, HMVC modules etc. please download from the below link and put them accordingly.

download

Step 11. Run the application.

That’s all. Thank you for your reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on JEE Tutorials | TwitterFacebook Google PlusLinkedin | Reddit | Email Me

2 thoughts on “Separating Front-end and Back-end in Codeigniter

  1. When i try this code i found this error

    Use of undefined constant VIEWPATH – assumed ‘VIEWPATH’ in /opt/lampp/htdocs/front_admin/system/core/Exceptions.php on line 242

Leave a Reply

Your email address will not be published. Required fields are marked *