File Upload and Validation in CodeIgniter

In this article, we are going to discuss about How to do the file upload and validation in CodeIgniter. I would like to explain how to upload files to server in CodeIgniter and to validate it with Form Validation library.

  1. How to upload files to server
  2. How to Validate file before uploading
  3. How to upload files to server

Step 1 :

Create a view that contains form fields and a field with input type file (Register.php) and add the below code in that file.

<?php echo form_open_multipart('welcome/register/'); ?>

form_open_multipart is used to upload files. It supports the input type file. Next we have to add other form fields and fiel field.

<?php echo validation_errors('<p class="form_error">','</p>'); ?>
<?php echo form_open_multipart('welcome/register/'); ?>
<input type="text" name="firstname" placeholder="Enter your Firstname"/>
<input type="text" name="city" placeholder="Enter your City"/>
<input type="file" name="userimage">
<button type="submit">Create Account</button>
</form>

Step 2:

Now, the form is submitted to the Register method in Welcome controller. Our Register method in Welcome contoller looks like this Welcome.php

public function register(){
     $this->load->library('form_validation');
     $this->form_validation->set_rules('firstname', 'First Name', 'required|trim|xss_clean');
     $this->form_validation->set_rules('city', 'City', 'required|trim|xss_clean');
     $this->form_validation->set_rules('userimage', 'Profile Image', 'callback_image_upload');
     if($this->form_validation->run() == TRUE){
         echo "Account Created Successfully";
     }
     $this->load->view('register');
}

Step 3:

Create a callback function for uploading image and validation. Method image_upload looks like the following.

function image_upload(){
      if($_FILES['userimage']['size'] != 0){
        $upload_dir = './images/';
        if (!is_dir($upload_dir)) {
             mkdir($upload_dir);
        }  
        $config['upload_path']   = $upload_dir;
        $config['allowed_types'] = 'gif|jpg|png|jpeg';
        $config['file_name']     = 'userimage_'.substr(md5(rand()),0,7);
        $config['overwrite']     = false;
        $config['max_size']  = '5120';
        $this->load->library('upload', $config);
        if (!$this->upload->do_upload('userimage')){
            $this->form_validation->set_message('image_upload', $this->upload->display_errors());
            return false;
        }  
        else{
            $this->upload_data['file'] =  $this->upload->data();
            return true;
        }  
    }  
    else{
        $this->form_validation->set_message('image_upload', "No file selected");
        return false;
    }
}

Explaining the callback function.

Steps Involved are

  • First we are checking if the file is submitted with the form. If the file is empty, we are setting the form validation error message as "No file selected".
  • We are creating a directory if the directory does not exist.
  • We have to configure the directory path, allowed upload files, filename, maximum file size, maximum width, maximum height etc.,
  • Then we are uploading the file. If upload fails, error message is set to the form validation.


Hope this is helpful.

Export data as CSV from database in CodeIgniter

In this article, we are going to discuss about How to export the data as CSV from database in CodeIgniter. In CodeIgniter we can export data easily from database as CSV using a library called dbutil. We can pass the query result directly into the dbutil function and we can download the data as CSV.

In your model, write down a function called exportCSV as mentioned below.

function ExportCSV()
{
$this->load->dbutil();
    $this->load->helper('file');
    $this->load->helper('download');
    $delimiter = ",";
    $newline = "\r\n";
    $filename = "filename_you_wish.csv";
    $query = "SELECT * FROM table_name WHERE 1";
    $result = $this->db->query($query);
    $data = $this->dbutil->csv_from_result($result, $delimiter, $newline);
    force_download($filename, $data);
}

You can change the filename and the database query as per your needs. Call this function from your controller.

PDF Generator Library for CodeIgniter

In this article, we are going to discuss about How to install PDF generator library for CodeIgniter and How to use PDF generator library in CodeIgniter. CodeIgniter is an open source rapid development web application framework, for use in building dynamic web sites with PHP.

CodeIgniter is loosely based on the popular Model-View-Controller development pattern. While controller classes are a necessary part of development under CodeIgniter, models and views are optional.

Installation

  1. Drop the pdf.php library into your libraries directory.
  2. Download domPDF from http://code.google.com/p/dompdf/downloads/list
  3. Drop the dompdf directory into your libraries directory alongside the pdf.php file.

Usage

You can convert a view into a PDF by using the following code.

$this->load->library('pdf');
$this->pdf->load_view('welcome');
$this->pdf->render();
$this->pdf->stream("welcome.pdf");

You can also pass in data to the function just as you would using $this->load->view('welcome', $data); by using

$this->pdf->load_view('welcome', $data);

Authentication Library for CodeIgniter PHP framework

In this article, we are going to discuss about the various authentication library for the CodeIgniter PHP Framework. Codeigniter still does not has a native authentication library. Many people try to build thier own authentication library. Now we can find few good Codeigniter authentication library, they are free as well.

I would like to suggest some of Codeigniter authentication library.

Tank Auth

Tank Auth is an authentication library for PHP-framework CodeIgniter. It's based on DX Auth, although the code was seriously reworked.

Features

  1. Basic auth options (login, logout, register, unregister).
  2. Very compact (less than 20 files and 4 DB-tables).
  3. Username is optional, only email is obligatory.
  4. Using phpass library for password hashing (instead of unsafe md5).
  5. Counting login attempt for bruteforce preventing (optional). Failed login attempts determined by IP and by username.
  6. Logging last login IP-address and time (optional).
  7. CAPTCHA for registration and repetitive login attempt (optional).
  8. Unactivated accounts and forgotten password requests auto-expire.
  9. Strict MVC model: controller for controlling, views for representation and library as model interface.
  10. Language file support.
  11. View files contain only necessary HTML code without redundant decoration.
  12. Most of the features are optional and can be tuned or switched-off in well-documented config file.
  13. Login using username, email address or both (depending on config settings).
  14. Registration is instant or after activation by email (optional).
  15. "Remember me" option.
  16. Forgot password (letting users pick a new password upon reactivation).
  17. Change password or email for registered users.
  18. Email or password can be changed even before account is activated.
  19. Ban user (optional).
  20. User Profile (optional).
  21. CAPTCHA support (CI-native and reCAPTCHA are available).
  22. HTML or plain-text emails.

DX Auth

DX Auth is an authentication library for Code Igniter. It's goal to enable you to easily include secure and easy to use authentication library to your project, while giving you the flexibility to choose from simple authentication system to full fledged authentication system.

DX Auth is also build with internationalization in mind, so every string is available in language file. (Except the examples because that is your code, not the library).

It's based on CL Auth 0.2.5 beta developed by Jason Ashdown.

Features

  1. Basic auth (Login, logout, register, change password).
  2. Remember me.
  3. Login using username or email address or both (depend on config settings).
  4. Forgot password.
  5. Ban user.
  6. Last login IP address and time (optional).
  7. Email activation (optional).
  8. User Profile (optional).
  9. Role based (admin, user, moderator, etc). Inheritance also supported (optional)
  10. Restrict page based on URI and role (optional).
  11. Custom permission for each role (optional).
  12. Login attempt (optional). You can use this to display catpcha after specified try to login to prevent bot.
  13. Event feature (For example: You can put your own code like PM welcome message after user activated, etc).
  14. Captcha (optional, native and reCAPTCHA is available).
  15. Simple admin panel (So you can customize it, include it into your own admin panel, or delete if you don't need it).
  16. Most of the feature is optional, means you can turn it off in config file, delete it, or just don't use it.

DX Auth is tested in CI 1.7.0, but should be working for above version.

CodeIgniter-Ion-Auth 

Redux Auth 2 had a lot of potential. It's lightweight, simple, and clean, but had a ton of bugs and was missing some key features. So we refactored the code and added new features.

Community Auth

Community Auth is a user authentication application for CodeIgniter. It is completely unique, and not based on anyone's previous work. If you've come here looking for a CodeIgniter authentication library, then please keep in mind that Community Auth is more than just a library. Community Auth is distributed with example controllers, models, views, and should be considered a project foundation.

Features

  1. User Authentication (User Login)
  2. Access Granted by Level / Role
  3. Access Granted by Role Group
  4. Content Switching in Views
  5. Limits Failed Login Attempts
  6. Limits Login to a Single Device (Default)
  7. Deny Access by IP (Requires Local Apache Configuration File)
  8. Persistent Login (Remember Me) (Turned Off by Default)
  9. Forgotten Password and Username Recovery
  10. New User Registration
    • Off by Default
    • Instant Registration Mode
    • Registration by Email Verification Mode
    • Registration by Admin Approval Mode
  11. User Account Update
    • Self Update
    • Update by Superior Role

Codeigniter - Run Multiple Sites from single install

In this article, we are going to discuss about How to run multiple websites from a single CodeIgniter (CI) install. CodeIgniter is a powerful PHP framework with a very small footprint, built for PHP coders who need a simple and elegant toolkit to create full-featured web applications. If you're a developer who lives in the real world of shared hosting accounts and clients with deadlines, and if you're tired of ponderously large and thoroughly undocumented frameworks

Each CodeIgniter website have a different "application" folder. But all are using the same "System" folder.

Take the application folder out from the system folder and make an additional copies based on the number of sites your need to create. For example, if you want to create 3 sites then, create the application folder names like "application_site1, application_site2, application_site3".

Now copy the index.php file to the root of each website folder, and edit it as follows:

At line 26, put the full path to the system folder:

$system_folder = dirname(__FILE__) . '../codeigniter/system';

At line 43, put the full path to the application folder:

$application_folder = dirname(__FILE__) . '../application_site1';

Now you can have independent websites using separate application folders, but sharing the same system folder.

There is a similar implementation in the CodeIgniter User Guide you can read also.

Steps to Install CodeIgniter On LinuxMint and Ubuntu

In this article, we are going to discuss about How to install CodeIgniter (CI) on LinuxMint and Ubuntu. CodeIgniter is a powerful PHP framework with a very small footprint, built for PHP coders who need a simple and elegant toolkit to create full-featured web applications. If you're a developer who lives in the real world of shared hosting accounts and clients with deadlines, and if you're tired of ponderously large and thoroughly undocumented frameworks

Step 1:

Download the latest version of CodeIgniter (CI) by Clicking Here

Step 2:

Unzip the downloaded zip file by executing the below command

sudo unzip CodeIgniter_2.2.0.zip 

Step 3:

Rename the unzipped folder by executing the below command.

mv CodeIgniter_2.2.0  codeigniter

Step 4:

Move the unzipped renamed folder the www directory.

sudo mv codeigniter /var/www

Step 5:

Run the below URL and check the site is working.

http://localhost/codeigniter

CodeIgniter – Add Captcha to your website

In this article, we are going to discuss about How to add captcha to your website in CodeIgniter (CI). In CodeIgniter (CI), we have an in-built helper to add captcha named "Captcha Helper".  Using Captcha helper, we can easily integrate Captcha into our application. To use this helper we have to load it.
At first we have to create a table for Captcha in our database. It contains four fields.

id => INT, word => TEXT, ip => TEXT, time=>TEXT

Then use the following code.

$this->load->helper('url');
$this->load->helper('string');
$this->load->helper('captcha');

Then declare an array with the following values. This array contains the values needed to create Captcha.

$rand = random_string('numeric', 8);
$vals = array(
'word'     => $rand,
'img_path'   => './captcha/',
'img_url'    => './captcha/',
'img_width'  => '150',
'img_height' => 60,
'expiration' => 7200
);
$cap = create_captcha($vals);  // Generates Capthca

I would like to explain the values mentioned in this array. First 'word' mentions the random value to be displayed. I generated a random number of length 8 and assigned it to the Captcha word. Next is 'img_path'. This decides the path to the file where generated Captcha image is to be stored. 'img_url' defines the path to be used when displaying the image. As name specifies 'img_width','img_height','expiration' denotes the image width, height and expiration time of Captcha.

Next we have to insert the generated Captcha value into table.

$this->load->model('common_model');
$this->common_model->insert_captcha($cap);
$data['cap'] = $cap;
$this->load->view('welcome_message',$data);

Add the following in your View file.

<p><h3>Enter the following Number</h3></p>
<form action="<?php echo base_url().'index.php/welcome/check' ?>" method="post">
<?php echo $cap['image']; ?><br>
<input type="text" name="captcha" placeholder="Type here.."/>
<br><br>
<input type="submit" value="submit">
</form>

Captcha values are inserted into the table and View is called.

Then on form submission, use the following code.

$expiration = time()-7200; // Two hour limit
$ip = $_SERVER['REMOTE_ADDR'];
$this->load->database();
$this->db->query("DELETE FROM captcha WHERE time < ".$expiration);

// Then see if a captcha exists:
$sql = "SELECT COUNT(*) AS count FROM captcha WHERE word = ? AND ip = ? AND time > ?";
$binds = array($_POST['captcha'], $ip, $expiration);
$query = $this->db->query($sql, $binds);
$row = $query->row();

if ($row->count == 0)
{
echo "You must submit the word that appears in the image";
}
else{
echo "Matches";
}

CodeIgniter - Change the URL and Email as Hyperlink automatically

In this article, we are going to discuss about How to change the URL and Email as Hyperlink in CodeIgniter. We might have seen plain text get converted to hypertext when we type it. For example, In gtalk when we type www.phpcmsframework.com it automatically changes as a hyperlink and point to http://www.phpcmsframework.com, Same way, when we type an email address it is automatically converted to mailto:phpcmsframework@gmail.com.

These kind of conversion can be made using PHP string replace function. We have to check the whole string where it has the url or email address, then we have to replace the url with anchor tag.

In CodeIgniter the easiest way to do it is to use the URL helper. First step is to load the URL helper.

$this->load->helper('url');

Then the next thing to do is to use a function

auto_link();

This function makes our life easier. We have to pass the string that we need to find for url and email.

$string = "This is a sample text and its url is www.phpcmsframework.com";
echo auto_link($string);

The output of the above code is Today I visited a useful blog about web development and its url is www.phpcmsframework.com

The same way email id is also auto linked. We can also restrict the automation only to url or email. This can be done by

echo auto_link($string,'email');
echo auto_link($string,'url');

In case if we want the link to open in a new tab, we can do it by adding a third parameter which can be either TRUE or FALSE.

echo auto_link($string, 'both', TRUE);

Here second parameter 'both' indicates that both 'email' and 'url' has to be automatically converted to hypertext.

Steps to implement calendar in CodeIgniter

In this tutorial, we are going to discuss about How implement the calendar in CodeIgniter (CI). We use dates in many parts of our application. Consider an example where you have to display "Thoughts of the Day" in calendar format. When you click on a date, it takes you to a page where it display a thought. To do this using CodeIgniter is very simple. As I mentioned about libraries and the advantages of using them in my earlier posts, today I would like to explain about "Calendar" library.

Lets see how to use it. In order to use the library we have to first load it. The code to load the library is

$this->load->library('calendar');

And displaying the calendar is pretty simple. Just add the following line

echo $this->calendar->generate();

This two lines will display a calendar of the current year and month. If you want to display for a specific year and month, lets say 2010 march, we can do that by passing year and month as parameters to the generate method.

echo $this->calendar->generate(2010,3);

If in case, you wish to change the start day to Monday we can do that as well. We can customize it as we want. To make Monday as the first day make the following changes.

$prefs = array (
               'start_day'    => 'monday',
               'month_type'   => 'long',
               'day_type'     => 'short'
             );
$this->load->library('calendar', $prefs);
echo $this->calendar->generate();

If you wish to add next and previous link to the calendar, we can do that by

$prefs = array (
               'show_next_prev'  => TRUE,
               'next_prev_url'   => 'http://www.geeks.gallery/calendar/'
             );
$this->load->library('calendar', $prefs);
echo $this->calendar->generate($this->uri->segment(2), $this->uri->segment(3));

Coming to the important section, linking the dates to separate page, the code is

$data = array(
       3  => 'http://www.geeks.gallery/wordpress-theme-installation/',
       7  => 'http://www.geeks.gallery/how-to-remove-index-php-from-codeigniter-url/',
       13 => 'http://www.geeks.gallery/tabactivity-in-android/',
       26 => 'http://www.geeks.gallery/change-the-favicon-in-your-website/'
     );
echo $this->calendar->generate(date('Y'),date('m'),$data);

Codeigniter Trick to shorten input form to database table

In this article, we are going to discuss about the simple trick to shorten the input form to database table in CodeIgniter (CI). I found this trick when I have to insert data that have many data fields for example I have 5 table each table have about 20 fields. In CodeIgniter (CI) we have active record class to make it easy when inserting to database.

Basic codeigniter active record is

$data = array(
   'title' => 'My title' ,
   'name' => 'My Name' ,
   'date' => 'My date'
);

$this->db->insert('mytable', $data);

Form code

In the form field name I use the same name on the input fields so I can pass the input fields as array.

<form method="post" action="">
<label>Fields 1</label>
<input type="text" name="fields[fields1]"/>
<label>Fields 2</label>
<input type="text" name="fields[fields2]"/>
<label>Fields 3</label>
<input type="text" name="fields[fields3]"/>
<!-- other field (text, select, textarea, etc) -->
<label>Fields 19</label>
<input type="text" name="fields[fields19]"/>
<label>Fields 20</label>
<input type="text" name="fields[fields20]"/>
<input type="submit" value="submit" />
</form>

Controller

In the controller code, after the form being submitted, I have used input class for fetching input data form, or you can use original $_POST variable.

$this->fields = $this->input->post('fields');

// check fields
if (strlen($this->fields['fields1']) == 0) {
$this->error['fields1'] = 'fields1 cannot be empty';
}
// other validation ....

$this->db->insert('some_table_name', $this->fields);

As you can see above when inserting data to table, when using active record insert feature, we don't have to define one by one to array data field like the original example and this might save you some time. When dealing with many form fields just make the input form name as array.

Steps to create Image Gallery in CodeIgniter

In this article, we are going to discuss about How to create an image gallery in CodeIgniter. CodeIgniter is quite mature framework to creating web application, the built in libraries and helper very helpful to creating most feature in web application. This article is describes about How to create a very basic image gallery using CodeIgniter, the built in libraries that I used are File Uploading, Image Manipulation and Pagination, whereas the used helper is URL Helper.

Step 1:

Open the "config.php" file which is in the folder "system/application/config/" and set the CodeIgniter base_url

$config['base_url'] = "http://localhost/ci_gallery/";

Step 2:

Load the URL Helper in "autoload.php" file which is in the same folder as above file

$autoload['helper'] = array('url');

Step 3:

Create an image controller in file "image.php" which is in the folder "system/application/controller" and add the below attribute inside the image class

private $data = array(
    'dir' => array(
        'original' => 'assets/uploads/original/',
        'thumb' => 'assets/uploads/thumbs/'
    ),
    'total' => 0,
    'images' => array(),
    'error' => ''
);

Step 4:

The variable which is created in the above file is to store the default directory path, total images inside the folder, and error message while uploading the image, the value of those variables will set in the next function.

Add the function index inside the Image class

public function index($start = 0)
{
    if ($this->input->post('btn_upload')) {
        $this->upload();
    }

    $this->load->library('pagination');

    $c_paginate['base_url'] = site_url('image/index');
    $c_paginate['per_page'] = '9';
    $finish = $start + $c_paginate['per_page'];

    if (is_dir($this->data['dir']['thumb']))
    {
        $i = 0;
        if ($dh = opendir($this->data['dir']['thumb'])) {
            while (($file = readdir($dh)) !== false) {
                // get file extension
                $ext = strrev(strstr(strrev($file), ".", TRUE));
                if ($ext == 'jpg' || $ext == 'jpeg' || $ext == 'png') {
                    if ($start <= $this->data['total'] && $this->data['total'] < $finish) {
                        $this->data['images'][$i]['thumb'] = $file;
                        $this->data['images'][$i]['original'] = str_replace('thumb_', '', $file);
                        $i++;
                    }
                    $this->data['total']++;
                }
            }
            closedir($dh);
        }
    }

    $c_paginate['total_rows'] = $this->data['total'];

    $this->pagination->initialize($c_paginate);

    $this->load->view('images/index', $this->data);
}

Inside the index function it will call the upload function when the upload button is clicked by the user, and the pagination class is configured, the script is looping through the folder find whether the file is image or not, and now the upload function.

private function upload()
{
    $c_upload['upload_path']    = $this->data['dir']['original'];
    $c_upload['allowed_types']  = 'gif|jpg|png|jpeg|x-png';
    $c_upload['max_size']       = '500';
    $c_upload['max_width']      = '1600';
    $c_upload['max_height']     = '1200';
    $c_upload['remove_spaces']  = TRUE;

    $this->load->library('upload', $c_upload);

    if ($this->upload->do_upload()) {

        $img = $this->upload->data();

        // create thumbnail
        $new_image = $this->data['dir']['thumb'].'thumb_'.$img['file_name'];

        $c_img_lib = array(
            'image_library'     => 'gd2',
            'source_image'      => $img['full_path'],
            'maintain_ratio'    => TRUE,
            'width'             => 100,
            'height'            => 100,
            'new_image'         => $new_image
        );

        $this->load->library('image_lib', $c_img_lib);
        $this->image_lib->resize();
    } else {
        $this->data['error'] = $this->upload->display_errors();
    }
}

You can see on the code above, thumbnail is created every time image is uploaded to maximum size 100 x 100 pixels, and putted in the different folder , the last function is delete image

public function delete($ori_img)
{
    unlink($this->data['dir']['original'].$ori_img);
    unlink($this->data['dir']['thumb'].'thumb_'.$ori_img);
    redirect('/');
}

The function getting the parameter as image name and deleted the orginal and thumbnail image, and now the view file "index.php" which is in the folder "system/application/views/images/"

<!-- the javascript code to load clicked image and changing the class-->
<script type="text/javascript">
    function changepic(img_src, obj) {
        document["img_tag"].src = img_src;
        var thumbs = document.getElementsByName("thumb");
        for (var i = 0; i < thumbs.length; i++) {
            var tmp_id = "thumb_" + i;
            document.getElementById(tmp_id).setAttribute("class", "thumb");
        }
        document.getElementById(obj).setAttribute("class", "thumbclick");
        var ori_img = img_src.replace("thumb_", "");
        document.getElementById("detimglink").setAttribute("href", ori_img);
    }
</script>

<!-- the view file -->
<div id="container">
    <div id="imgshow">
        <?php if (isset($images[0])) { ?>
        <a href="<?php echo base_url().$dir['original'].$images[0]['original']; ?>" target="_blank" id="detimglink">
            <img class="imgdet" name="img_tag" src="<?php echo base_url().$dir['original'].$images[0]['original']; ?>" width="500"/>
        </a>
        <?php } ?>
    </div>

    <div id="imglist">
        <form enctype="multipart/form-data" id="fupload" method="post" action="<?php echo site_url('image/'); ?>">
            <input name="userfile" type="file" size="20"/>
            <input type="submit" name="btn_upload" value="Upload &uarr;" class="btnupload"/>
            <?php if (isset ($error)) { ?>
            <div class="error"><?php echo $error; ?></div>
            <?php } ?>
        </form>

        <div class="clear"></div>

        <div class="imgfor">
        <!-- Looping Array Image -->
        <?php foreach($images as $key => $img) { ?>
        <div class="imgbox">
            <div>
                <a href="javascript:" onclick="changepic('<?php echo base_url().$dir['original'].$img['original']; ?>', 'thumb_<?php echo $key; ?>');">
                <img class="thumb" name="thumb" id="thumb_<?php echo $key; ?>" src="<?php echo base_url().$dir['thumb'].$img['thumb']; ?>"/>
                </a>
            </div>
            <div class="dadel">
            <a class="adel" href="<?php echo site_url('image/delete/'.$img['original']); ?>">
                delete
            </a>
            </div>
        </div>
        <?php } ?>
        <div class="clear"></div>
        </div>
        <div class="clear"></div>

        <div class="bottom">
            <?php echo $total; ?> Image(s)
        </div>

        <div class="bottom">
            <?php echo $this->pagination->create_links(); ?>
        </div>
    </div>

    <div class="clear"></div>

</div> <!-- end div container -->

CIBB - Basic Forum With Codeigniter and Twitter Bootstrap

In this article, we are going to discuss about How to create basic forum CIBB (CodeIgniter Bulletin Board) with CodeIgniter and Twitter Bootstrap.

For learning more about using twitter bootstrap I made this and completely using a basic bootstrap style, I have created only a very basic forum software. So do not expect to much features from it, but you can download and use it for any kind of purpose.

Features

  1. User roles management
  2. Rich text editor using jWysiwyg
  3. Threaded category
  4. Basic forum (create thread, post reply)

Installation

I have not created the web installer yet. So you have to manually export the sql file (cibb.sql) to your mysql administrator, and on the web change the $config['base_url'] in config.php and change databse value in database.php, like in official codeigniter user guide.

Sample Screen

thread index

thread talk
list of roles

To download the source files Click Here

Steps to develop a Web Installer for a Codeigniter Application

In this article, we are going to discuss about How to develop a web installer for a CodeIgniter (CI) application. When you installing a CMS on your server, usually you need to find a form for setting up your database settings, admin user credentials, SMTP details..etc. This option can be found on popular open source CMS by default. This article might help after you finish create your own custom web project and don't want to make confuse your client with manual install by editing php file.

This script will change some of default CodeIgniter (CI) setting, they are

  1. - index.php
  2. - application/config/config.php
  3. - application/config/database.php

Just make sure they are writable (I'm using windows, no permission needs to be changed)

Step 1 : Create MY_Install library (MY_Install.php)

Create a file named "MY_Install.php" on your codeigniter application library, I assume we have a default codeigniter database setting, so this script will check if database name are blank we can continue on installation, by redirecting the page to install folder.

<?php
class MY_Install {
    public function __construct() {
        $CI =& get_instance();
        $CI->load->database();
        if ($CI->db->database == "") {
            header('location:install/');
        } else {
            if (is_dir('install')) {
                echo '<i>Plese delete or rename <b>Install</b> folder</i>';
                exit;
            }
        }
    }
}

Step 2 : Include the library on autoload.php

$autoload['libraries'] = array('database', 'MY_Install');

Step 3 : Create an install folder


After an install folder is created, create an index file which consists of form script for database setting and php script for replacing the default codeigniter settings.

Form script

<?php
$error = 0;
if (isset($_POST['btn-install'])) {
    
    // validation
    if ($_POST['inputDBhost'] == '' || $_POST['inputDBusername'] == '' || 
            $_POST['inputDBname'] == '' ||
            $_POST['inputSiteurl'] == '' || $_POST['inputAppfolder'] == '' || 
            $_POST['inputSystemfolder'] == '' || 
            ($_POST['inputAppfolder'] == $_POST['inputSystemfolder'])) {
        $error = 1;
    } else {
        
        @$con = mysql_connect($_POST['inputDBhost'], $_POST['inputDBusername'], $_POST['inputDBpassword']);
        @$db_selected = mysql_select_db($_POST['inputDBname'], $con);

        if (!$con) {
            $error = 1;
        } else if (!$db_selected) {  
            $error = 1;
        } else {
            // setting site url
            $file_config = "../application/config/config.php";
            $content_config = file_get_contents($file_config);
            $content_config .= "\n\$config['base_url'] = '".$_POST['inputSiteurl']."';";
            file_put_contents($file_config, $content_config);

            // setting database
            $file_db = "../application/config/database.php";
            $content_db = file_get_contents($file_db);
            $content_db .= "\n\$db['default']['hostname'] = '".$_POST['inputDBhost']."';";
            $content_db .= "\n\$db['default']['username'] = '".$_POST['inputDBusername']."';";
            $content_db .= "\n\$db['default']['password'] = '".$_POST['inputDBpassword']."';";
            $content_db .= "\n\$db['default']['database'] = '".$_POST['inputDBname']."';";
            file_put_contents($file_db, $content_db);

            // setting folder name
            $file_index = "../index.php";
            $content_index = str_replace("\$system_path = 'system';", "\$system_path = '".$_POST['inputSystemfolder']."';", file_get_contents($file_index));
            file_put_contents($file_index, $content_index);
            $content_index = str_replace("\$application_folder = 'application';", "\$application_folder = '".$_POST['inputAppfolder']."';", file_get_contents($file_index));
            file_put_contents($file_index, $content_index);

            // rename app folder
            $index = str_replace('install', '', dirname(__FILE__));
            rename($index.'application', $index.$_POST['inputAppfolder']);
            rename($index.'system',      $index.$_POST['inputSystemfolder']);
            header('location:../');
        }
    }
}

?>

PHP Script

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="bootstrap.css"/>
</head>
<body>
<div class="container">
    <div class="row-fluid">
    <h4>Install Your Codeigniter App</h4>
    <form class="form-horizontal" action="" method="post" style="margin-top:30px;">

        <?php if ($error == 1): ?>
        <div class="alert alert-error" style="font-size:11px;">               
            <b>Opps error ... </b> please check: 
            <br/> - <i>Each fields cannot be blank</i>
            <br/> - <i>App Folder and System Folder cannot the same</i>
            <br/> - <i>Database name must exist on your MySQL</i>
        </div>
        <?php endif; ?>
        <legend>Database Settings</legend>
        <div class="control-group">
            <label class="control-label">DB Host</label>
            <div class="controls">
                <input type="text" name="inputDBhost">
            </div>
        </div>
        <div class="control-group">
            <label class="control-label">DB Name</label>
            <div class="controls">
                <input type="text" name="inputDBname">
            </div>
        </div>
        <div class="control-group">
            <label class="control-label">DB Username</label>
            <div class="controls">
                <input type="text" name="inputDBusername">
            </div>
        </div>
        <div class="control-group">
            <label class="control-label">DB Password</label>
            <div class="controls">
                <input type="password" name="inputDBpassword">
            </div>
        </div>

        <legend>App Settings</legend>
        <div class="control-group">
            <label class="control-label">Site URL</label>
            <div class="controls">
                <input type="text" name="inputSiteurl">
            </div>
        </div>
        <div class="control-group">
            <label class="control-label">App Folder</label>
            <div class="controls">
                <input type="text" name="inputAppfolder">
            </div>
        </div>
        <div class="control-group">
            <label class="control-label">System Folder</label>
            <div class="controls">
                <input type="text" name="inputSystemfolder">
            </div>
        </div>
        <div class="control-group">
            <div class="controls">
                <input type="reset" class="btn" name="btn" value="Reset"/>
                <input type="submit" class="btn btn-primary" name="btn-install" value="Install"/>
            </div>
        </div>
    </form>
    </div>
</div>
</body>
</html>

That's all after the installation finish it will redirect to index page again and ask you to rename or remove install folder, you can add more validation by yourself or even other settings for common web application, below are the example screenshot.

Drag and Drop Shopping Cart Using CodeIgniter Cart and ExtJS

In this article, we are going to discuss about How to create the Drag and Drop shopping cart application using CodeIgniter Cart and ExtJS. We are using MYSQL for storing the product data. Here I am going to explain in step by step detail to create the Drag and Drop shopping cart app using CI cart and ExtJS.

Step 1 : Database Preparation

Create a database named "ci_extjs_cart" or with other name that you desired then create the table.

CREATE TABLE IF NOT EXISTS `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) DEFAULT NULL,
  `price` varchar(32) DEFAULT NULL,
  `image` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

And these are the sample datas (I already included the sample image on the code that you can download)

INSERT INTO `products` (`id`, `name`, `price`, `image`) VALUES
(1, 'HP - 20 Inch Widescreen Flat-Panel LCD Monitor', '169', 'hp.jpg'),
(2, 'Gateway - 20 Inch Widescreen Flat-Panel LCD Monitor', '159', 'gateway.jpg'),
(3, 'Apple - 30 Flat-Panel TFT-LCD Monitor', '1799', 'apple.jpg'),
(4, 'Acer - 24 Inch Flat-Panel LED-LCD Monitor', '299', 'acer.jpg'),
(5, 'Asus - 24 Inch Widescreen Flat-Panel LCD Monitor', '249', 'asus.jpg');

Step 2 : CodeIgniter Configuration

First time to get hand dirty with a framework is to set all the config file (in folder: "application/config/"). The four files that we have to configure are:

config.php

$config['base_url'] = "http://localhost/ci_extjs_cart/";

database.php

$db['default']['hostname'] = "localhost";
$db['default']['username'] = "root";
$db['default']['password'] = "admin";
$db['default']['database'] = "ci_extjs_cart";
$db['default']['dbdriver'] = "mysql";

routes.php

$route['default_controller'] = "product";

The default controller is set to product controller, in this step we have not create the controller yet.

autoload.php

$autoload['libraries'] = array('database', 'session');
$autoload['helper'] = array('url');

Step 3 : ExtJS configuration on CodeIgniter

Like always, include the ExtJS file on separate folder from Codeigniter (CI).

Step 4 : Controller and View creation

The Controller, create a file product.php inside the controllers folder, the very usual method on the controller is the contrustion and the index method, in the construction method the codeigniter cart class loaded.

<?php

class Product extends Controller {

    public function  __construct()
    {
        parent::Controller();
        $this->load->library('cart');
    }

    public function index()
    {
        $this->load->view('product/index');
    }
}

The View, create the view file inside views folder "index.php", the first step to preparing the view is to preparing the HTML layout, include the ExtJS file, and create a basic layout style in CSS.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>assets/js/ext/resources/css/ext-all.css"/>
    <script type="text/javascript" src="<?php echo base_url(); ?>assets/js/ext/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="<?php echo base_url(); ?>assets/js/ext/ext-all.js"></script>
    <!-- product data view style -->
    <link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>assets/js/ext/ux/data-view.css"/>

    <script type="text/javascript">
    var BASE_URL = '<?php echo site_url(); ?>/';

    Ext.onReady(function() {
    });
    </script>
    <title>Extjs Image Gallery Using DataView</title>
    <style type="text/css">
        body {
            padding: 20px;
            margin: 0 auto;
        }
        #container {
            padding: 10px;
            background: #e3e3e3;
            border: 1px solid #d3d3d3;
            margin: 0 auto;
            text-align: left;
            width: 630px;
        }
        #top {

        }
        #bottom {
            margin-top: 10px;
        }
    </style>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
      <div id="container">
          <div id="top"></div>
          <div id="bottom"></div>
      </div>
  </body>
</html>

The Ext.ready function is still empty, inside this function all the ExtJS component will be placed, and I always using BASE_URL value that have value of site_url(); function, to make it easier when accessing a url.

Step 5 : Get Product List

The Controller, this is the method the get all the product data, and sending the data as json format.

public function ext_get_all()
{
    $query = $this->db->get('products');
    $product_arr = array();
    foreach($query->result() as $key => $data)
    {
        $product_arr[] = array(
            'id'    => $data->id,
            'name'  => $data->name,
            'price' => $data->price,
            'image' => $data->image
        );
    }
    echo json_encode(array('products' => $product_arr));
}

The View, this is the code for creating the product list in dataview, and a function to make the dataview draggable.

var proxyProduct = new Ext.data.HttpProxy({
    url: BASE_URL + 'product/ext_get_all', method: 'POST'
});

var strProduct = new Ext.data.JsonStore({
    proxy: proxyProduct,
    root: 'products',
    fields: [
        'id', 'name', 'price', 'image'
    ]
});

strProduct.load();

var tplProduct = new Ext.XTemplate(
    '<tpl for=".">',
        '<div class="thumb-wrap" id="{name}">',
        '<div class="thumb"><img src="http://localhost/ci_extjs_cart/assets/img/{image}" title="{name}"></div>',
        '<span class="name">{name}</span>',
        '<div class="price">$ {price}</div></div>',
    '</tpl>',
    '<div class="x-clear"></div>'
);

var dvProduct = new Ext.DataView({
    autoScroll: true, store: strProduct, tpl: tplProduct,
    autoHeight: false, height: 200, multiSelect: false,
    overClass: 'x-view-over', itemSelector: 'div.thumb-wrap',
    emptyText: 'No product to display',
    style: 'border:1px solid #99BBE8;',
    listeners: {
        render: initializeItemDragZone
    }
});

function initializeItemDragZone(v) {
    v.dragZone = new Ext.dd.DragZone(v.getEl(), {
        getDragData: function(e) {
            var sourceEl = e.getTarget(v.itemSelector, 10);
            if (sourceEl) {
                d = sourceEl.cloneNode(true);
                d.id = Ext.id();
                return v.dragData = {
                    sourceEl: sourceEl,
                    repairXY: Ext.fly(sourceEl).getXY(),
                    ddel: d,
                    itemData: v.getRecord(sourceEl).data
                }
            }
        },

        getRepairXY: function() {
            return this.dragData.repairXY;
        }
    });
}

var panelProduct = new Ext.Panel({
    id: 'images-view',
    frame: true,
    width: 620,
    autoHeight: true,
    title: 'Product DataView',
    style: 'margin:0 auto;',
    items: [dvProduct]
});

panelProduct.render('top');

Step 6 : Create The Cart (Using EditorGridPanel)

The Controller, we will create some basic function to manipulating the cart I try to explain them in the separate way, but still in the same controller

6.1 Get All Cart

public function ext_get_cart()
{
    if ($this->cart->total_items() != 0)
    {
        foreach($this->cart->contents() as $product)
        {
            $cart_arr[] = array(
                'rowid' => $product['rowid'],
                'id'    => $product['id'],
                'qty'   => $product['qty'],
                'name'  => $product['name'],
                'price' => $product['price'],
                'subtotal' => $product['subtotal']
            );
        }
        $cart_arr[] = array(
            'rowid' => '',
            'id'    => '',
            'qty'   => '',
            'name'  => '',
            'price' => '<b>Total:</b>',
            'subtotal' => '<b>'.$this->cart->total().'</b>'
        );
        echo json_encode(array('cart' => $cart_arr));
    }
    else
    {
        $cart_arr[] = array();
        echo json_encode(array('cart' => $cart_arr));
    }
}

This function is to getting all the available product in the cart in the session, if the cart is not empty then just loop through the cart function "$this->cart->contents()" and put this to array. I add another array to showing the total value from the cart, this will be treated different in the ExtJS grid, and send it as json format

6.2 Add a Product to Cart

public function ext_add_cart()
{
    if ($_POST['rowid'] == '')
    {
        $data = array(
            'id'    => $_POST['id'],
            'qty'   => 1,
            'price' => $_POST['price'],
            'name'  => $_POST['name']
        );
        $this->cart->insert($data);
    }
    else
    {
        $data = array(
          'rowid'   => $_POST['rowid'],
          'qty'     => intval($_POST['qty']) + 1
        );
        $this->cart->update($data);
    }
    echo '{success:true, total: "'.$this->cart->total().'"}';
}

You must be can see in the add cart function there are conditional statement that updating the cart instead insert a new data to cart, well this is to handle if a user adding the product that already available on the cart, so the cart must be updating only the quantity.

6.3 Update a Product Quantity

public function ext_update_cart()
{
    $data = array(
      'rowid'   => $_POST['rowid'],
      'qty'     => $_POST['qty']
    );
    $this->cart->update($data);
    echo '{success:true}';
}

This function is to updating a product quantity on the cart, I make the quantity editable on the grid so the user can easy put the number of a product that he desired, and to deleting a product from cart the user have to put zero value on the quantity editable grid.

6.4 Clear Cart

public function ext_clear_cart()
{
    $this->cart->destroy();
    echo '{success:true}';
}

Well nothing really hard in this function, using "$this->cart->destroy()" all the cart clear.

6.5 The Cart

var strCart = new Ext.data.JsonStore({
    root: 'cart',
    fields: [
        'rowid', 'id', 'qty', 'name', 'price', 'subtotal'
    ],
    proxy: new Ext.data.HttpProxy({
        url: BASE_URL + 'product/ext_get_cart', method: 'POST'
    })
});
strCart.load();

var cb_select = new Ext.grid.CheckboxSelectionModel();

function showDollar(val) {
    if (val == '' || val == '<b>Total:</b>') {
        return val;
    }
    else {
        return '$ ' + val;
    }
}

var panelCart = new Ext.grid.EditorGridPanel({
    frame: true, border: true, stripeRows: true,
    store: strCart, loadMask: true, title: 'Your Cart (Drag Here)',
    style: 'margin:0 auto;font-size:13px;',
    height: 220, width: 500, sm: cb_select,
    columns: [{
        header: 'rowid',
        dataIndex: 'rowid',
        hidden: true,
        hideable: false
    }, {
        header: 'id',
        dataIndex: 'id',
        hidden: true,
        hideable: false
    }, {
        header: "Product Name",
        dataIndex: 'name',
        sortable: true,
        width: 280
    }, {
        header: "Qty",
        align: 'center',
        width: 40,
        dataIndex: 'qty',
        menuDisabled: true,
        editor: new Ext.form.TextField({
            allowBlank: false,
            vtype: 'alphanum',
            id: 'qtyField'
        })
    }, {
        header: "Price",
        dataIndex: 'price',
        sortable: true,
        align: 'right',
        renderer: showDollar,
        width: 80
    }, {
        header: "Subtotal",
        sortable: true,
        align: 'right',
        width: 80,
        renderer: showDollar
    }],
    listeners: {
        'afteredit': function() {
            var sm = panelCart.getSelectionModel().getSelections();
            panelCart.getSelectionModel().clearSelections();
            Ext.Ajax.request({
                method: 'POST',
                url: BASE_URL + 'product/ext_update_cart',
                params: {
                    rowid: sm[0].get('rowid'),
                    qty: Ext.getCmp('qtyField').getValue()
                },
                success: function() {
                    strCart.load();
                }
            });
        }
    },
    buttons: [{
        text: 'Clear Cart',
        handler: function() {
            Ext.Ajax.request({
                url: BASE_URL + 'product/ext_clear_cart',
                method: 'POST',
                success: function() {
                    strCart.load();
                }
            });
        }
    }, {
        text: 'Check Out',
        handler: function() {

        }
    }]
});

panelCart.render('bottom');

var formPanelDropTargetEl =  panelCart.getView().scroller.dom;

var formPanelDropTarget = new Ext.dd.DropTarget(formPanelDropTargetEl, {
    notifyDrop  : function(ddSource, e, data){
        panelCart.getSelectionModel().selectAll();
        var sm = panelCart.getSelectionModel().getSelections();
        panelCart.getSelectionModel().clearSelections();

        data.itemData.rowid = '';
        for (i=0; i<=sm.length-1; i++) {
            if (sm[i].get('id') == data.itemData.id) {
                data.itemData.rowid = sm[i].get('rowid');
                data.itemData.qty = sm[i].get('qty');
                // so can out from loop
                i = sm.length;
            }
        }

        Ext.Ajax.request({
            url: BASE_URL + 'product/ext_add_cart',
            method: 'POST',
            params: {
                'id': data.itemData.id,
                'price': data.itemData.price,
                'name': data.itemData.name,
                'rowid': data.itemData.rowid,
                'qty': data.itemData.qty
            },
            success: function() {
                strCart.load();
            }
        });
        return(true);
    }
});

That's all for the Cart features, there is CheckboxSelectionModel component, this component is to check whether the product is already on the cart, you can see it used on notifyDrop inside the dropTarget you have to add, the expected result is something like this.



To download full source of this application Click Here