Create user permission by URI in Codeigniter 3

Hello. No I want to share how to about to create user role/permission by access URI. Oke now the first you must download new CodeIgniter 3 in this site https://www.codeigniter.com/download.
After that we must open CodeIgniter framework on your editor. Example I use sublime text.
Oke lest go code, the first we must change config/autoload.php and add auto load library ‘session’ and helper ‘url’.

/*
| -------------------------------------------------------------------
|  Auto-load Libraries
| -------------------------------------------------------------------
| These are the classes located in system/libraries/ or your
| application/libraries/ directory, with the addition of the
| 'database' library, which is somewhat of a special case.
|
| Prototype:
|
|	$autoload['libraries'] = array('database', 'email', 'session');
|
| You can also supply an alternative library name to be assigned
| in the controller:
|
|	$autoload['libraries'] = array('user_agent' => 'ua');
*/
$autoload['libraries'] = array('session');

/*
| -------------------------------------------------------------------
|  Auto-load Drivers
| -------------------------------------------------------------------
| These classes are located in system/libraries/ or in your
| application/libraries/ directory, but are also placed inside their
| own subdirectory and they extend the CI_Driver_Library class. They
| offer multiple interchangeable driver options.
|
| Prototype:
|
|	$autoload['drivers'] = array('cache');
*/
$autoload['drivers'] = array();

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

Then change config/database.php with your database config.

$active_group = 'default';
$query_builder = TRUE;

$db['default'] = array(
	'dsn'	=> 'mysql:host=localhost;dbname=yourdbname',
	'hostname' => 'localhost',
	'username' => 'yourusername',
	'password' => 'yourpassword',
	'database' => 'yourdbname',
	'dbdriver' => 'pdo',
	'dbprefix' => '',
	'pconnect' => FALSE,
	'db_debug' => (ENVIRONMENT !== 'production'),
	'cache_on' => FALSE,
	'cachedir' => '',
	'char_set' => 'utf8',
	'dbcollat' => 'utf8_general_ci',
	'swap_pre' => '',
	'encrypt' => FALSE,
	'compress' => FALSE,
	'stricton' => FALSE,
	'failover' => array(),
	'save_queries' => TRUE
);

And import this sql command, this is the default database structure for this tutorial.

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

--
-- Database: `learn_ci`
--

-- --------------------------------------------------------

--
-- Table structure for table `permissions`
--

DROP TABLE IF EXISTS `permissions`;
CREATE TABLE `permissions` (
  `id` int(10) UNSIGNED NOT NULL,
  `uri` varchar(255) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- --------------------------------------------------------

--
-- Table structure for table `permission_user`
--

DROP TABLE IF EXISTS `permission_user`;
CREATE TABLE `permission_user` (
  `id` int(10) UNSIGNED NOT NULL,
  `user_id` int(10) UNSIGNED NOT NULL,
  `permission_id` int(10) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- --------------------------------------------------------

--
-- Table structure for table `users`
--

DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` int(10) UNSIGNED NOT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Truncate table before insert `users`
--

TRUNCATE TABLE `users`;
--
-- Dumping data for table `users`
--

INSERT INTO `users` (`id`, `name`, `email`, `password`) VALUES
(1, 'admin', 'admin@mail.com', '5f4dcc3b5aa765d61d8327deb882cf99'),
(2, 'User', 'user@mail.com', '5f4dcc3b5aa765d61d8327deb882cf99');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `permissions`
--
ALTER TABLE `permissions`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `permission_user`
--
ALTER TABLE `permission_user`
  ADD PRIMARY KEY (`id`),
  ADD KEY `permission_user_user_id_foreign` (`user_id`),
  ADD KEY `permission_user_permission_id_foreign` (`permission_id`);

--
-- Indexes for table `users`
--
ALTER TABLE `users`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `users_email_unique` (`email`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `permissions`
--
ALTER TABLE `permissions`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=21;
--
-- AUTO_INCREMENT for table `permission_user`
--
ALTER TABLE `permission_user`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=34;
--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
--
-- Constraints for dumped tables
--

--
-- Constraints for table `permission_user`
--
ALTER TABLE `permission_user`
  ADD CONSTRAINT `permission_user_permission_id_foreign` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE CASCADE,
  ADD CONSTRAINT `permission_user_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE;

Now after that we must create login method, this function is used for access role by user_id. So this is login code:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Login extends CI_Controller {

    public function __construct()
    {
        parent::__construct();
        $this->load->model('login_model');
    }

	public function index()
	{
        if(isset($_SESSION['user_id'])) {
            return redirect('home');
        }
        if($_POST) {
            $data = [
                'email' => $this->input->post('email'),
                'password' => md5($this->input->post('password')),
            ];
            $result = $this->login_model->login($data);
            
            if(!empty($result)) {
                $this->session->set_userdata([
                    'user_id' => $result->id,
                    'email' => $result->email,
                    'name' => $result->name
                ]);
                redirect('home');
            } else {
                $this->session->set_flashdata('err', 'Wrong username or password.');
                redirect('login');
            }
        }
		$this->load->view('login');
	}
	
	public function logout() {
        session_destroy();
        redirect('login');
    }
}

This is the login model:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Login_model extends CI_Model
{
    private $_mongoDb;

    function __construct() {
        parent::__construct();
        $this->load->database();
    }

    public function login($data) {
        $email = $data['email'];
        $password = $data['password'];

        $query = $this->db->get_where('users', array('email' => $email, 'password' => $password))->row();
        return $query;
    }

    public function __destruct() {
        $this->db->close();
    }
}

And this is for the view:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Login</title>
</head>
<body>
	<h1>Login</h1>
	<?php if(isset($_SESSION['err'])): ?>
		<strong>Warning!</strong> <?= $this->session->userdata('err'); ?>
	<?php endif ?>
	<form action="<?= base_url('login') ?>" method="POST">
		<label>Email</label>
		<input type="email" name="email" placeholder="Email" required="required" />
		<br />
		<label>Password</label>
		<input type="password" name="password" placeholder="Password" required="required" />
		<br />
		<button type="submit">Save</button>
	</form>
</body>
</html>

And don’t forget to add controller and view after a successful login (example redirect to home).
This is home controller:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Home extends CI_Controller {

	function __construct()
	{
		parent::__construct();

		if(!isset($_SESSION['user_id'])) {
            $this->session->set_flashdata('flash_data', 'You don\'t have access!');
            return redirect('login');
        }
	}

	public function index()
	{
		$data['page'] = 'home';
		$this->load->view('layout', $data);
	}

	
}

This is home view:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Permission</title>
</head>
<body>
	<header>
	</header>

	<?php $this->load->view($page); ?>
</body>
</html>
<h1>Dashboard</h1>
<?php if(isset($_SESSION['err'])): ?>
	<strong>Warning!</strong> <?= $this->session->userdata('err'); ?>
<?php endif ?>

For more information about create login information, you can read on my latest post https://imron02.wordpress.com/2013/06/01/simple-login-using-codeigniter-database
Now run this code, and you can get result like this:
Login page
And this is after login is successful
Dashboard page
Oke now we must create menu crud for user and permission. For crud implementation using codeigniter, you can search example crud using codeigniter in here http://google.com
First we must change home controller like this:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Home extends CI_Controller {

	function __construct()
	{
		parent::__construct();

		if(!isset($_SESSION['user_id'])) {
            $this->session->set_flashdata('flash_data', 'You don\'t have access!');
            return redirect('login');
        }

		$this->load->model('data_model');
	}

	public function index()
	{
		$data['page'] = 'home';
		$this->load->view('layout', $data);
	}

	public function users()
	{
		$data['users'] = $this->data_model->users();
		$data['page'] = 'user';
		$this->load->view('layout', $data);
	}

	public function user_crud($id = 0)
	{
		if ($_POST) {
			$data = [
				'name' => $this->input->post('name'),
				'email' => $this->input->post('email'),
				'password' => md5($this->input->post('password')),
				'id' => $this->input->post('id'),
			];
			$this->data_model->user_crud($data);
			return redirect('home/users');
		}
		$data['page'] = 'user_form';
		if($id) {
			$data['user'] = $this->data_model->users($id);
		}
		$this->load->view('layout', $data);
	}

	public function user_delete($id)
	{
		$this->data_model->user_delete($id);
		return redirect('home/users');
	}

	public function permissions()
	{
		$data['permissions'] = $this->data_model->permissions();
		$data['page'] = 'permission';
		$this->load->view('layout', $data);
	}

	public function permission_crud($id = 0)
	{
		if ($_POST) {
			$data = [
				'uri' => $this->input->post('uri'),
				'pu_id' => $this->input->post('pu_id'),
				'permission_id' => $this->input->post('permission_id'),
				'user_id' => $this->input->post('user_id'),
			];
			$this->data_model->permission_crud($data);
			return redirect('home/permissions');
		}
		$data['page'] = 'permission_form';
		if($id) {
			$data['permission'] = $this->data_model->permissions($id);
		}
		$data['users'] = $this->data_model->users();
		$this->load->view('layout', $data);
	}

	public function permission_delete($id)
	{
		$this->data_model->permission_delete($id);
		return redirect('home/permissions');
	}
}

Explanation:

  1. Line 15. We create the code for interaction with database (we call model), so for crud in this tutorial, we must create file data_model.php
  2. Another highlight code is function for crud user and permission

So this is the data_model.php code:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Data_model extends CI_Model {

	public function __construct()
	{
		parent::__construct();
		$this->load->database();
	}

	public function users($id = 0)
	{
		if ($id) {
			$this->db->where('id', $id);
			$query = $this->db->get('users')->row();
			return $query;
		}
		$query = $this->db->get('users')->result();
		return $query;
	}

	public function user_crud($data)
	{
		if($data['id']) {
			$this->db->where('id', $data['id']);
			$this->db->update('users', $data);
			return;
		}
		$this->db->insert('users', $data);
	}

	public function user_delete($id)
	{
		$this->db->where('id', $id);
		$this->db->delete('users');
	}

	public function permissions($id = 0)
	{
		if ($id) {
			$this->db->select('pu.*, p.*, u.*, pu.id as pu_id, p.id as permission_id, u.id as user_id');
			$this->db->join('permissions p', 'p.id = pu.permission_id');
			$this->db->join('users u', 'u.id = pu.user_id');
			$this->db->where('pu.id', $id);
			$query = $this->db->get('permission_user pu')->row();
			return $query;
		}
		$this->db->select('pu.*, p.*, u.*, pu.id as pu_id, p.id as permission_id, u.id as user_id');
		$this->db->join('permissions p', 'p.id = pu.permission_id');
		$this->db->join('users u', 'u.id = pu.user_id');
		$query = $this->db->get('permission_user pu')->result();
		return $query;
	}

	public function permission_crud($data)
	{
		$permission_data = [
			'uri' => $data['uri']
		];

		$pu_data = [
			'permission_id' => $data['permission_id'],
			'user_id' => $data['user_id']
		];

		if($data['permission_id']) {
			// update permissions table
			$this->db->where('id', $data['permission_id']);
			$this->db->update('permissions', $permission_data);

			// update permission_user table
			$this->db->where('id', $data['pu_id']);
			$this->db->update('permission_user', $pu_data);
			return;
		}

		// Insert into permission table
		$this->db->insert('permissions', $permission_data);
		$permission_id = $this->db->insert_id();

		// Insert into table permission_user
		$pu_data['permission_id'] = $permission_id;
		$this->db->insert('permission_user', $pu_data);
	}

	public function permission_delete($id)
	{
		$this->db->where('id', $id);
		$this->db->delete('permissions');
	}

	public function __destruct()
	{
		$this->db->close();
	}
}

Okay now we must add library for validate user by uri. If the user authenticates and have permission, so URI accessible, but if not, the user can not access. And now we must create file Permission.php on application/libraries

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Permission
{
	private static $_CI;

	public function __construct()
	{
		self::$_CI =& get_instance();
		self::$_CI->load->database();
	}

	public static function grant($uri)
	{
		$match = false;
		$user_id = $_SESSION['user_id'];
    	$permissions = self::$_CI->db->join('permission_user', 'permissions.id = permission_user.permission_id')
                      ->join('users', 'users.id = permission_user.user_id')
                      ->where('permission_user.user_id', $user_id)
                      ->get('permissions')
                      ->result();

        foreach($permissions as $permission) {
            if($permission->uri != "*") {
                $re_uri = preg_replace('/\\\\\*/','*', preg_quote($permission->uri, '/'));
                $match = preg_match("/{$re_uri}/", $uri);
            }

            if($permission->uri == "*" || $uri == 'home') {
                return;
            } else {
                $match = (!$match) ? $match : true;
            }

            // if found true
            if($match) {
                return;
            }
        }

        // if all false
        if(!$match) {
        	self::$_CI->session->set_flashdata('err', 'You don\'t have permission.');
            return redirect('home');
        }
	}

	public function __destruct()
	{
		self::$_CI->db->close();
	}
}

Explanation:

  1. Line 8-12 is used to instance all of CI object and load the database
  2. Line 14-41 is used to validate URI. So if the user can access (match), the page will be redirect and if not, the user will get the message “You don’t have permission.”

And this for crud view:

<h1>Listing User</h1>
<table border="1" cellpadding="5">
	<caption><a href="<?= base_url('home/user_crud') ?>">Add User</a></caption>
	<thead>
		<tr>
			<th>No</th>
			<th>Name</th>
			<th>Email</th>
			<th>Action</th>
		</tr>
	</thead>
	<tbody>
		<?php $i=1; foreach($users as $user): ?>
			<tr>
				<td><?= $i++ ?></td>
				<td><?= $user->name ?></td>
				<td><?= $user->email ?></td>
				<td>
					<a href="<?= base_url('home/user_crud/'.$user->id) ?>">Edit</a> |
					<a href="<?= base_url('home/user_delete/'.$user->id) ?>">Delete</a>
				</td>
			</tr>
		<?php endforeach; ?>
	</tbody>
</table>
<h1>Form User</h1>
<form action="<?= base_url('home/user_crud') ?>" method="POST">
	<label>Name</label>
	<input type="text" name="name" placeholder="Name" value="<?= (isset($user)) ? $user->name : "" ?>" />
	<input type="hidden" name="id" value="<?= (isset($user)) ? $user->id : "" ?>" />
	<br />
	<label>Email</label>
	<input type="email" name="email" placeholder="Email" value="<?= (isset($user)) ? $user->email : "" ?>" />
	<br />
	<label>Password</label>
	<input type="password" name="password" placeholder="Password" />
	<br />
	<button type="submit">Save</button>
</form>
<h1>Listing Permission</h1>
<table border="1" cellpadding="5">
	<caption><a href="<?= base_url('home/permission_crud') ?>">Add Permission</a></caption>
	<thead>
		<tr>
			<th>No</th>
			<th>Uri</th>
			<th>User</th>
			<th>Action</th>
		</tr>
	</thead>
	<tbody>
		<?php $i=1; foreach($permissions as $permission): ?>
			<tr>
				<td><?= $i++ ?></td>
				<td><?= $permission->uri ?></td>
				<td><?= $permission->name ?></td>
				<td>
					<a href="<?= base_url('home/permission_crud/'.$permission->pu_id) ?>">Edit</a> |
					<a href="<?= base_url('home/permission_delete/'.$permission->permission_id) ?>">Delete</a>
				</td>
			</tr>
		<?php endforeach; ?>
	</tbody>
</table>
<h1>Form User</h1>
<form action="<?= base_url('home/permission_crud') ?>" method="POST">
	<label>Uri</label>
	<input type="text" name="uri" placeholder="Uri" value="<?= (isset($permission)) ? $permission->uri : "" ?>" />
	<input type="hidden" name="pu_id" value="<?= (isset($permission)) ? $permission->pu_id : "" ?>" />
	<input type="hidden" name="permission_id" value="<?= (isset($permission)) ? $permission->permission_id : "" ?>" />
	<br />
	<label>User</label>
	<select name="user_id">
		<option value="">Select</option>
		<?php foreach($users as $user): ?>
			<option value="<?= $user->id ?>" <?= (isset($permission) && $user->id == $permission->user_id) ? "selected='selected'" : "" ?> ><?= $user->name ?></option>
		<?php endforeach; ?>
	</select>
	<br />
	<button type="submit">Save</button>
</form>

Oke the last is add function grant from Permission library for checking user permission. So we must edit controllers/Home.php.

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Home extends CI_Controller {

	function __construct()
	{
		parent::__construct();

		if(!isset($_SESSION['user_id'])) {
            $this->session->set_flashdata('flash_data', 'You don\'t have access!');
            return redirect('login');
        }

		$this->load->model('data_model');
		$this->load->library('permission');
	}

	public function index()
	{
		$data['page'] = 'home';
		$this->load->view('layout', $data);
	}

	public function users()
	{
		Permission::grant(uri_string());
		$data['users'] = $this->data_model->users();
		$data['page'] = 'user';
		$this->load->view('layout', $data);
	}

	public function user_crud($id = 0)
	{
		Permission::grant(uri_string());
		if ($_POST) {
			$data = [
				'name' => $this->input->post('name'),
				'email' => $this->input->post('email'),
				'password' => md5($this->input->post('password')),
				'id' => $this->input->post('id'),
			];
			$this->data_model->user_crud($data);
			return redirect('home/users');
		}
		$data['page'] = 'user_form';
		if($id) {
			$data['user'] = $this->data_model->users($id);
		}
		$this->load->view('layout', $data);
	}

	public function user_delete($id)
	{
		Permission::grant(uri_string());
		$this->data_model->user_delete($id);
		return redirect('home/users');
	}

	public function permissions()
	{
		Permission::grant(uri_string());
		$data['permissions'] = $this->data_model->permissions();
		$data['page'] = 'permission';
		$this->load->view('layout', $data);
	}

	public function permission_crud($id = 0)
	{
		Permission::grant(uri_string());
		if ($_POST) {
			$data = [
				'uri' => $this->input->post('uri'),
				'pu_id' => $this->input->post('pu_id'),
				'permission_id' => $this->input->post('permission_id'),
				'user_id' => $this->input->post('user_id'),
			];
			$this->data_model->permission_crud($data);
			return redirect('home/permissions');
		}
		$data['page'] = 'permission_form';
		if($id) {
			$data['permission'] = $this->data_model->permissions($id);
		}
		$data['users'] = $this->data_model->users();
		$this->load->view('layout', $data);
	}

	public function permission_delete($id)
	{
		Permission::grant(uri_string());
		$this->data_model->permission_delete($id);
		return redirect('home/permissions');
	}
}

Explanation:

  1. Line 16 is used for load permission library
  2. Line 27, 35, 55, 62, 70, and 91 is used for call funtion grant from library and checking this user can access or not

Now run apps and tadaaaaaaaaa, your apps with permission role is running. 😀
Source code: https://www.mediafire.com/?9ovymq9n0c6o2fc

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s