Separating Front-end and Back-end in Codeigniter

Introduction

This tutorial will show you an example on how to separate front-end and back-end in Codeigniter 3. 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.

Prerequisites

Codeigniter 3.1.10 – 3.1.11, PHP 7.0.15 – 7.4.22, Apache 2.4 (optional)

Recommended reading: Setup HMVC with Codeigniter 3 tutorials for getting an idea for better understanding of the following implementation.

Project Directory

It’s assumed that you have setup Apache (Optional), PHP and Codeigniter in Windows system.

Now I will create a project root directory called codeigniter-seperate-frontend-backend the Apache server’s htdocs folder.

Now move all the directories and files from CodeIgniter framework into  codeigniter-seperate-frontend-backend directory.

I may not mention the project root directory in subsequent sections and I will assume that I am talking with respect to the project root directory.

Autoload Configuration

You need some configurations, such as, auto-loading for helpers to avoid loading every time we need to use.

Modify application/config/autoload.php file for auto-loading libraries and helper functions.

This one time auto-loading gives flexibility to uniformly use the helpers and libraries anywhere throughout the application without loading repeatedly.

$autoload['libraries'] = array('session', 'template', 'userauth');
$autoload['helper'] = array('url', 'form');
$autoload['config'] = array('app_config');

Application Config

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.roytuts.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.

$autoload['libraries'] = array('session', 'template', 'userauth');
$autoload['helper'] = array('url', 'form');
$autoload['config'] = array('app_config');

I have loaded built-in library – session along with our custom libraries – template and userauth. You will also see how to create these custom libraries.

I have also loaded helper functions – url and form.

I have loaded our custom config file app_config, which I created in previous step.

Route Configuration

Step 3. Check default controller is home in <project root>/application/config/routes.php. I will create this controller later.

$route['default_controller'] = 'home';

Template File

Step 4. I will use two different templates for front-end and back-end. So, I need to create template configuration file <project root>/application/config/template.php.

//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 */

Input Form Validation

Step 5. I need to create form validation library to make codeigniter validation work correctly. Create below validation class 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 */

LIbrary – User Authentication

Step 6. I loaded userauth library in autoload.php file above. Now create userauth library to authenticate users 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.

Step 7. I loaded template library in autoload.php file above. Now create template library to load views at <project root>/application/libraries/template.php.

<?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 ($email == 'admin@roytuts.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@roytuts.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() {
        // 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 */

Controllers

Step 8. Now I 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 9. 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 10. Create Admin_Controller at <project root>/application/core/Admin_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 */

Now for all other files you need to download the source code from the below link given at the bottom.

Testing – Separate Frontend and Backend in Codeigniter

When your home page is displayed by accessing the URL http://localhost in the browser:

separating front end and back end in codeigniter

Clicking on the Signin link will redirect you to the signin page:

separating front end and back end in codeigniter

For admin login, use admin@roytuts.com/admin as a credential for username/password fields.

separating front end and back end in codeigniter

On successful login you will find three links – account, control panel, signout – on the left top header and signin link will disappear:

separating front end and back end in codeigniter

Clicking on the control panel link will take you to the following dashboard. As the separate dashboard is required for admin users, so you will be redirected to the separate page.

separating front end and back end in codeigniter

Once you logout from the above admin dashboard, you will no longer get the signin page which was shown from the home page and for admin users, the signin or login page will look like:

separating front end and back end in codeigniter

Now if you login using admin user credential then you will go to the admin dashboard directly. So public home page will not appear, but logout or login will work from both places.

If you click on the Visit Site link from admin dashboard you will be redirected to the public home page in separate tab with Account, Control panel and Signout links on the top left header. Therefore, login and logout functionalities are in sync from both places.

Hope you understood how to separate frontend and backend interfaces in Codeigniter 3.

Source Code

Download

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

  1. Hi… nice tutorial, but i get an error:

    Message: Call to undefined method MY_Loader::_ci_load_class()
    Filename: C:\wamp64\www\code10split\application\third_party\MX\Loader.php
    Line Number: 165

    Line 165 reads: $this->_ci_load_class($library, $params, $object_name);

    As you did not cover the nature of these files in the tutorial, i’m not sure how to go about correcting the error. Any help would be greatly appreciated.

  2. 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.