This article shows how to create a simple CodeIgniter CRUD (Create, Read, Update, Delete) application with Login and Registration feature. CodeIgniter (CI) is a PHP framework that helps building a full-fledged web application.
This article is a continuation of my past article Simple CodeIgniter CRUD Application tutorial. The tutorial has add, edit, delete, and view feature but it didn’t contain login and registration feature.
– This article/tutorial uses session for login and registration of users.
– You have to register and then login in order to add news/article.
– You can view/edit/delete only those articles that are added by you.
Create Database and Table
First of all, we create database and table. For this article example, we will be creating database named test</strong>
. We will be creating a table named <strong>news</strong>
inside the database <strong>test
.
--
-- Create database `test`
--
CREATE DATABASE `test`;
use `test`;
--
-- Table structure for table `news`
--
CREATE TABLE IF NOT EXISTS `news` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(128) NOT NULL,
`slug` varchar(128) NOT NULL,
`text` text NOT NULL,
`user_id` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `slug` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
--
-- Dumping data for table `news`
--
INSERT INTO `news` (`id`, `title`, `slug`, `text`, `user_id`) VALUES
(1, 'Test', 'test', 'Hello World !!', 1),
(2, 'What is Lorem Ipsum?', 'what-is-lorem-ipsum', 'Lorem Ipsum is simply dummy text.', 1),
(3, 'My test', 'my-test', 'hello there', 2);
--
-- Table structure for table `user`
--
CREATE TABLE `user` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`firstname` varchar(255) NOT NULL,
`lastname` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`updated_at`varchar(255) NULL DEFAULT NULL,
PRIMARY_KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
--
-- Indexes for table `user`
--
ALTER TABLE `user`
ADD UNIQUE KEY `user_email_unique` (`email`);
I will present below the full code of controller, model, and views files. We will be adding, updating, deleting news item to our database table. News item just contains title and text content.
Database Config Settings
After you create your database, you need to specify your database host, database name, database username & database password in a database config file in codeigniter. The file is located at application/config/database.php
.
My database host is localhost</strong>
, database name is <strong>test</strong>
(as created by above sql query), database username is <strong>root</strong>
and database password is <strong>root
.
Here is the config settings for this example:
File: application/config/database.php
$db['default'] = array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'root',
'password' => 'root',
'database' => 'test',
'dbdriver' => 'mysqli',
'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
);
==========================================================
Here’s the full code of controller, model, and views files. In this example, we will be having two controller class. One will be for User and the other will be for News. Similarly, there will be two model classes (User_model and News_model).
Let’s first create User controller and model class for user login and registration.
User Controller
(application/controllers/User.php)
Controller processes the input request from user, communicates with Model and then loads appropriate Views file.
In the below Controller class, we have different functions (actions) for different tasks. Like, the login() function is used for logging users, register() function is used to register users in the application.
<?php
class User extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('user_model');
$this->load->helper(array('form', 'url'));
$this->load->library(array('session', 'form_validation'));
}
public function index()
{
$this->register();
}
public function register()
{
$this->form_validation->set_rules('firstname', 'First Name', 'trim|required|alpha|min_length[3]|max_length[50]');
$this->form_validation->set_rules('lastname', 'Last Name', 'trim|required|alpha|min_length[3]|max_length[50]');
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email|is_unique[user.email]');
$this->form_validation->set_rules('password', 'Password', 'trim|required|matches[cpassword]|md5');
$this->form_validation->set_rules('cpassword', 'Confirm Password', 'trim|required');
$data['title'] = 'Register';
if ($this->form_validation->run() === FALSE)
{
$this->load->view('templates/header', $data);
$this->load->view('user/register');
$this->load->view('templates/footer');
}
else
{
if ($this->user_model->set_user())
{
$this->session->set_flashdata('msg_success','Registration Successful!');
redirect('user/register');
}
else
{
$this->session->set_flashdata('msg_error','Error! Please try again later.');
redirect('user/register');
}
}
}
public function login()
{
$email = $this->input->post('email');
$password = $this->input->post('password');
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'trim|required|md5');
$data['title'] = 'Login';
if ($this->form_validation->run() === FALSE)
{
$this->load->view('templates/header', $data);
$this->load->view('user/login');
$this->load->view('templates/footer');
}
else
{
if ($user = $this->user_model->get_user_login($email, $password))
{
/*$user_data = array(
'email' => $email,
'is_logged_in' => true
);
$this->session->set_userdata($user_data);*/
$this->session->set_userdata('email', $email);
$this->session->set_userdata('user_id', $user['id']);
$this->session->set_userdata('is_logged_in', true);
$this->session->set_flashdata('msg_success','Login Successful!');
redirect('news');
}
else
{
$this->session->set_flashdata('msg_error','Login credentials does not match!');
$currentClass = $this->router->fetch_class(); // class = controller
$currentAction = $this->router->fetch_method(); // action = function
redirect("$currentClass/$currentAction");
//redirect('user/login');
}
}
}
public function logout()
{
if ($this->session->userdata('is_logged_in')) {
//$this->session->unset_userdata(array('email' => '', 'is_logged_in' => ''));
$this->session->unset_userdata('email');
$this->session->unset_userdata('is_logged_in');
$this->session->unset_userdata('user_id');
}
redirect('news');
}
}
User Model
(application/models/User_model.php)
Model class communicates with the database. The main database logic is written here. This class is responsible for interacting with database for data select, insert, update and delete purposes.
In the below Model class, get_user() function fetches/selects users by $id. get_user_login() function fetches user by checking username and password. set_user() function either edit or add user. delete_user() function deletes any particular user.
<?php
class User_model extends CI_Model {
public function __construct()
{
$this->load->database();
}
public function get_user($id = 0)
{
if ($id === 0)
{
$query = $this->db->get('user');
return $query->result_array();
}
$query = $this->db->get_where('user', array('id' => $id));
return $query->row_array();
}
public function get_user_login($email, $password)
{
$query = $this->db->get_where('user', array('email' => $email, 'password' => md5($password)));
//return $query->num_rows();
return $query->row_array();
}
public function set_user($id = 0)
{
$data = array(
'firstname' => $this->input->post('firstname'),
'lastname' => $this->input->post('lastname'),
'email' => $this->input->post('email'),
'password' => $this->input->post('password'),
'updated_at' => date('Y-m-d H:i:s')
);
if ($id == 0) {
return $this->db->insert('user', $data);
} else {
$this->db->where('id', $id);
return $this->db->update('user', $data);
}
}
public function delete_user($id)
{
$this->db->where('id', $id);
return $this->db->delete('user');
}
}
User Registration View
(application/views/user/register.php)
<?php echo $this->session->flashdata('verify_msg'); ?>
<h4>User Registration Form</h4>
<?php $attributes = array("name" => "registrationform");
echo form_open("user/register", $attributes);?>
<table>
<tr>
<td><label for="name">First Name</label></td>
<td><input name="firstname" placeholder="First Name" type="text" value="<?php echo set_value('fname'); ?>" /> <span style="color:red"><?php echo form_error('firstname'); ?></span></td>
</tr>
<tr>
<td><label for="name">Last Name</label></td><td><input name="lastname" placeholder="Last Name" type="text" value="<?php echo set_value('lname'); ?>" /> <span style="color:red"><?php echo form_error('lastname'); ?></span></td>
</tr>
<tr>
<td><label for="email">Email ID</label></td><td><input class="form-control" name="email" placeholder="Email-ID" type="text" value="<?php echo set_value('email'); ?>" /> <span style="color:red"><?php echo form_error('email'); ?></span></td>
</tr>
<tr>
<td><label for="subject">Password</label></td><td><input class="form-control" name="password" placeholder="Password" type="password" /> <span style="color:red"><?php echo form_error('password'); ?></span></td>
</tr>
<tr>
<td><label for="subject">Confirm Password</label></td><td><input class="form-control" name="cpassword" placeholder="Confirm Password" type="password" /> <span style="color:red"><?php echo form_error('cpassword'); ?></span></td>
</tr>
<tr>
<td></td>
<td><button name="submit" type="submit">Signup</button></td>
</tr>
</table>
<?php echo form_close(); ?>
<p style="color:green; font-style:bold"><?php echo $this->session->flashdata('msg_success'); ?></p>
<p style="color:red; font-style:bold"><?php echo $this->session->flashdata('msg_error'); ?></p>
User Login View
(application/views/user/login.php)
<?php echo $this->session->flashdata('verify_msg'); ?>
<h4>User Login Form</h4>
<?php $attributes = array("name" => "loginform");
echo form_open("user/login", $attributes);?>
<table>
<tr>
<td><label for="email">Email</label></td><td><input class="form-control" name="email" placeholder="Email-ID" type="text" /> <span style="color:red"><?php echo form_error('email'); ?></span></td>
</tr>
<tr>
<td><label for="subject">Password</label></td><td><input class="form-control" name="password" placeholder="Password" type="password" /> <span style="color:red"><?php echo form_error('password'); ?></span></td>
</tr>
<tr>
<td></td>
<td><button name="submit" type="submit">Login</button></td>
</tr>
</table>
<?php echo form_close(); ?>
<p style="color:green; font-style:bold"><?php echo $this->session->flashdata('msg_success'); ?></p>
<p style="color:red; font-style:bold"><?php echo $this->session->flashdata('msg_error'); ?></p>
News Controller
(application/controllers/News.php)
In the below Controller class the index() function is used for listing all news items, create() function is used to add a new news item, edit() function is used to edit the news item, and delete() function is used to delete the news item.
While creating and editing news items, first of all, we check if the user is logged in or not. If not logged in, the user is redirected to login page.
if (!$this->session->userdata('is_logged_in')) {
redirect(site_url('user/login'));
} else {
$data['user_id'] = $this->session->userdata('user_id');
}
Similarly, we also check if the logged in user is actually trying to edit/delete his/her own article (article added by him/her) or trying to edit/delete others’ article. If trying to edit others’ article then the user is redirected to news index page.
if ($data['news_item']['user_id'] != $this->session->userdata('user_id')) {
$currentClass = $this->router->fetch_class(); // class = controller
redirect(site_url($currentClass));
}
Here’s the full source code for News Controller.
<?php
class News extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('news_model');
$this->load->helper('url_helper');
$this->load->library('session');
$this->load->library('pagination');
}
public function index()
{
$data['news'] = $this->news_model->get_news();
$data['title'] = 'News archive';
$this->load->view('templates/header', $data);
$this->load->view('news/index', $data);
$this->load->view('templates/footer');
}
public function view($slug = NULL)
{
$data['news_item'] = $this->news_model->get_news($slug);
if (empty($data['news_item'])) {
show_404();
}
$data['title'] = $data['news_item']['title'];
$this->load->view('templates/header', $data);
$this->load->view('news/view', $data);
$this->load->view('templates/footer');
}
public function create()
{
if (!$this->session->userdata('is_logged_in')) {
redirect(site_url('user/login'));
} else {
$data['user_id'] = $this->session->userdata('user_id');
}
$this->load->helper('form');
$this->load->library('form_validation');
$data['title'] = 'Create a news item';
$this->form_validation->set_rules('title', 'Title', 'required');
$this->form_validation->set_rules('text', 'Text', 'required');
if ($this->form_validation->run() === FALSE) {
$this->load->view('templates/header', $data);
$this->load->view('news/create');
$this->load->view('templates/footer');
} else {
$this->news_model->set_news();
$this->load->view('templates/header', $data);
$this->load->view('news/success');
$this->load->view('templates/footer');
}
}
public function edit()
{
if (!$this->session->userdata('is_logged_in')) {
redirect(site_url('user/login'));
} else {
$data['user_id'] = $this->session->userdata('user_id');
}
$id = $this->uri->segment(3);
//$id = $this->input->post('id');
if (empty($id)) {
show_404();
}
$this->load->helper('form');
$this->load->library('form_validation');
$data['title'] = 'Edit a news item';
$data['news_item'] = $this->news_model->get_news_by_id($id);
if ($data['news_item']['user_id'] != $this->session->userdata('user_id')) {
$currentClass = $this->router->fetch_class(); // class = controller
redirect(site_url($currentClass));
}
$this->form_validation->set_rules('title', 'Title', 'required');
$this->form_validation->set_rules('text', 'Text', 'required');
if ($this->form_validation->run() === FALSE) {
$this->load->view('templates/header', $data);
$this->load->view('news/edit', $data);
$this->load->view('templates/footer');
} else {
$this->news_model->set_news($id);
//$this->load->view('news/success');
redirect( site_url('news') );
}
}
public function delete()
{
if (!$this->session->userdata('is_logged_in')) {
redirect(site_url('user/login'));
}
$id = $this->uri->segment(3);
if (empty($id)) {
show_404();
}
$news_item = $this->news_model->get_news_by_id($id);
if ($news_item['user_id'] != $this->session->userdata('user_id')) {
$currentClass = $this->router->fetch_class(); // class = controller
redirect(site_url($currentClass));
}
$this->news_model->delete_news($id);
redirect( base_url() . 'index.php/news');
}
}
News Model
(application/models/News_model.php)
In the below Model class, get_news() function fetches/selects news items by $slug name and user id. get_news_by_id() function fetches news by it’s ID. set_news() function either edit or add news item. delete_news() function delets any particular news item.
<?php
class News_model extends CI_Model {
public function __construct()
{
$this->load->database();
}
public function record_count()
{
return $this->db->count_all('news');
}
public function get_news($slug = FALSE)
{
if ($slug === FALSE)
{
$query = $this->db->get_where('news', array('user_id' => $this->session->userdata('user_id')));
return $query->result_array(); // $query->result(); // returns object
}
$query = $this->db->get_where('news', array('slug' => $slug, 'user_id' => $this->session->userdata('user_id')));
return $query->row_array(); // $query->row(); // returns object
// $query->num_rows(); // returns number of rows selected, similar to counting rows
// $query->num_fields(); // returns number of fields selected
}
public function get_news_by_id($id = 0)
{
if ($id === 0)
{
$query = $this->db->get('news');
return $query->result_array();
}
$query = $this->db->get_where('news', array('id' => $id));
return $query->row_array();
}
public function set_news($id = 0)
{
$this->load->helper('url');
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$data = array(
'title' => $this->input->post('title'), // $this->db->escape($this->input->post('title'))
'slug' => $slug,
'text' => $this->input->post('text'),
'user_id' => $this->input->post('user_id'),
);
if ($id == 0) {
//$this->db->query('YOUR QUERY HERE');
return $this->db->insert('news', $data);
} else {
$this->db->where('id', $id);
return $this->db->update('news', $data);
}
}
public function delete_news($id)
{
$this->db->where('id', $id);
return $this->db->delete('news'); // $this->db->delete('news', array('id' => $id));
// error() method will return an array containing its code and message
// $this->db->error();
}
}
Template Header
(application/views/templates/header.php)
This is a template file common for all pages. We call header in all pages. User email is displayed if the user is logged in.
<html>
<head>
<title>CodeIgniter Tutorial</title>
</head>
<body>
<h1>Simple CRUD</h1>
<a href="<?php echo site_url('news'); ?>">Home</a> |
<a href="<?php echo site_url('news/create'); ?>">Add News</a> |
<?php if ($this->session->userdata('is_logged_in')) {
echo '<b>Logged in as:</b> ' . $this->session->userdata('email');
echo ' | ' . "<a href=" . site_url('user/logout') . ">Logout</a>";
} else {
?>
<a href="<?php echo site_url('user/register'); ?>">Register</a> |
<a href="<?php echo site_url('user/login'); ?>">Login</a>
<?php } ?>
Template Footer
(application/views/templates/footer.php)
This is a template file common for all pages. We call footer in all pages.
<em>Copyright © 2016</em>
</body>
</html>
Index View
(application/views/news/index.php)
This view file is called by index() function of our Controller class. It lists out all the news item. The Edit and Delete link are only displayed for logged in users.
<h2><?php echo $title; ?></h2>
<table border='1' cellpadding='4'>
<tr>
<td><strong>Title</strong></td>
<td><strong>Content</strong></td>
<td><strong>Action</strong></td>
</tr>
<?php foreach ($news as $news_item): ?>
<tr>
<td><?php echo $news_item['title']; ?></td>
<td><?php echo $news_item['text']; ?></td>
<td>
<a href="<?php echo site_url('news/'.$news_item['slug']); ?>">View</a>
<?php if ($this->session->userdata('is_logged_in')) { ?>
|
<a href="<?php echo site_url('news/edit/'.$news_item['id']); ?>">Edit</a> |
<a href="<?php echo site_url('news/delete/'.$news_item['id']); ?>" onClick="return confirm('Are you sure you want to delete?')">Delete</a>
<?php } // end if ?>
</td>
</tr>
<?php endforeach; ?>
</table>
Detail View
(application/views/news/view.php)
This view file is called by view() function of our Controller class. It prints a particular news item.
<?php
echo '<h2>'.$news_item['title'].'</h2>';
echo $news_item['text'];
Add View
(application/views/news/create.php)
This view file is called by create() function of our Controller class. It prints a form to add news item.
<h2><?php echo $title; ?></h2>
<?php echo validation_errors(); ?>
<?php echo form_open_multipart('news/create'); ?>
<table>
<tr>
<td><label for="title">Title</label></td>
<td><input type="input" name="title" size="50" /></td>
</tr>
<tr>
<td><label for="text">Text</label></td>
<td><textarea name="text" rows="10" cols="40"></textarea></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="submit" value="Create news item" /></td>
</tr>
</table>
<input type="hidden" name="user_id" value="<?php echo $user_id; ?>" />
</form>
Edit View
(application/views/news/edit.php)
This view file is called by edit() function of our Controller class. It prints a form to edit news item.
<h2><?php echo $title; ?></h2>
<?php echo validation_errors(); ?>
<?php echo form_open('news/edit/'.$news_item['id']); ?>
<table>
<tr>
<td><label for="title">Title</label></td>
<td><input type="input" name="title" size="50" value="<?php echo $news_item['title'] ?>" /></td>
</tr>
<tr>
<td><label for="text">Text</label></td>
<td><textarea name="text" rows="10" cols="40"><?php echo $news_item['text'] ?></textarea></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="submit" value="Edit news item" /></td>
</tr>
</table>
<input type="hidden" name="user_id" value="<?php echo $user_id; ?>" />
</form>
Add Success View
(application/views/news/success.php)
This view file is called after a new news item is added to database. This file is called in create() function of our Controller class.
News added successfully!
Config Routes
(application/config/routes.php)
Routing rules are defined here. Routes can either be specified using wildcards or Regular Expressions.
$route['user'] = 'user';
$route['user/register'] = 'user/register';
$route['news'] = 'news';
$route['news/create'] = 'news/create';
$route['news/edit/(:any)'] = 'news/edit/$1';
$route['news/view/(:any)'] = 'news/view/$1';
$route['news/(:any)'] = 'news/view/$1';
Now, you can access your news application as http://your-website.com/news</strong>
. User login page will be found at <strong>http://your-website.com/user/login</strong>
& user registration page will be at <strong>http://your-website.com/user/register
.
Here is an example page of logged in user with some news added:
Download Source Code from GitHub
Hope this helps. Thanks.