Creating a Photo-sharing Application

33 min read

In this article by Rob Foster, the author of CodeIgniter Web Application Blueprints, we will create a photo-sharing application. There are quite a few image-sharing websites around at the moment. They all share roughly the same structure: the user uploads an image and that image can be shared, allowing others to view that image. Perhaps limits or constraints are placed on the viewing of an image, perhaps the image only remains viewable for a set period of time, or within set dates, but the general structure is the same. And I’m happy to announce that this project is exactly the same.

We’ll create an application allowing users to share pictures; these pictures are accessible from a unique URL. To make this app, we will create two controllers: one to process image uploading and one to process the viewing and displaying of images stored.

We’ll create a language file to store the text, allowing you to have support for multiple languages should it be needed.

We’ll create all the necessary view files and a model to interface with the database.

In this article, we will cover:

  • Design and wireframes
  • Creating the database
  • Creating the models
  • Creating the views
  • Creating the controllers
  • Putting it all together

So without further ado, let’s get on with it.

(For more resources related to this topic, see here.)

Design and wireframes

As always, before we start building, we should take a look at what we plan to build.

First, a brief description of our intent: we plan to build an app to allow the user to upload an image. That image will be stored in a folder with a unique name. A URL will also be generated containing a unique code, and the URL and code will be assigned to that image. The image can be accessed via that URL.

The idea of using a unique URL to access that image is so that we can control access to that image, such as allowing an image to be viewed only a set number of times, or for a certain period of time only.

Anyway, to get a better idea of what’s happening, let’s take a look at the following site map:

So that’s the site map. The first thing to notice is how simple the site is. There are only three main areas to this project. Let’s go over each item and get a brief idea of what they do:

  • create: Imagine this as the start point. The user will be shown a simple form allowing them to upload an image. Once the user presses the Upload button, they are directed to do_upload.
  • do_upload: The uploaded image is validated for size and file type. If it passes, then a unique eight-character string is generated. This string is then used as the name of a folder we will make. This folder is present in the main upload folder and the uploaded image is saved in it. The image details (image name, folder name, and so on) are then passed to the database model, where another unique code is generated for the image URL. This unique code, image name, and folder name are then saved to the database.

    The user is then presented with a message informing them that their image has been uploaded and that a URL has been created. The user is also presented with the image they have uploaded.

  • go: This will take a URL provided by someone typing into a browser’s address bar, or an img src tag, or some other method. The go item will look at the unique code in the URL, query the database to see if that code exists, and if so, fetch the folder name and image name and deliver the image back to the method that called it.

Now that we have a fairly good idea of the structure and form of the site, let’s take a look at the wireframes of each page.

The create item

The following screenshot shows a wireframe for the create item discussed in the previous section. The user is shown a simple form allowing them to upload an image.

Image2

The do_upload item

The following screenshot shows a wireframe from the do_upload item discussed in the previous section. The user is shown the image they have uploaded and the URL that will direct other users to that image.

The go item

The following screenshot shows a wireframe from the go item described in the previous section. The go controller takes the unique code in a URL, attempts to find it in the database table images, and if found, supplies the image associated with it. Only the image is supplied, not the actual HTML markup.

File overview

This is a relatively small project, and all in all we’re only going to create seven files, which are as follows:

  • /path/to/codeigniter/application/models/image_model.php: This provides read/write access to the images database table. This model also takes the upload information and unique folder name (which we store the uploaded image in) from the create controller and stores this to the database.
  • /path/to/codeigniter/application/views/create/create.php: This provides us with an interface to display a form allowing the user to upload a file. This also displays any error messages to the user, such as wrong file type, file size too big, and so on.
  • /path/to/codeigniter/application/views/create/result.php: This displays the image to the user after it has been successfully uploaded, as well as the URL required to view that image.
  • /path/to/codeigniter/application/views/nav/top_nav.php: This provides a navigation bar at the top of the page.
  • /path/to/codeigniter/application/controllers/create.php: This performs validation checks on the image uploaded by the user, creates a uniquely named folder to store the uploaded image, and passes this information to the model.
  • /path/to/codeigniter/application/controllers/go.php: This performs validation checks on the URL input by the user, looks for the unique code in the URL and attempts to find this record in the database. If it is found, then it will display the image stored on disk.
  • /path/to/codeigniter/application/language/english/en_admin_lang.php: This provides language support for the application.

The file structure of the preceding seven files is as follows:

application/
├── controllers/
│   ├── create.php
│   ├── go.php
├── models/
│   ├── image_model.php
├── views/create/
│   ├── create.php
│   ├── result.php
├── views/nav/
│   ├── top_nav.php
├── language/english/
│   ├── en_admin_lang.php

Creating the database

First, we’ll build the database. Copy the following MySQL code into your database:

CREATE DATABASE `imagesdb`;
USE `imagesdb`;
 
DROP TABLE IF EXISTS `images`;
CREATE TABLE `images` (
`img_id` int(11) NOT NULL AUTO_INCREMENT,
`img_url_code` varchar(10) NOT NULL,
`img_url_created_at` timestamp NOT NULL DEFAULT     CURRENT_TIMESTAMP,
`img_image_name` varchar(255) NOT NULL,
`img_dir_name` varchar(8) NOT NULL,
PRIMARY KEY (`img_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Right, let’s take a look at each item in every table and see what they mean:

Table: images

Element

Description

img_id

This is the primary key.

img_url_code

This stores the unique code that we use to identify the image in the database.

img_url_created_at

This is the MySQL timestamp for the record.

img_image_name

This is the filename provided by the CodeIgniter upload functionality.

img_dir_name

This is the name of the directory we store the image in.

We’ll also need to make amends to the config/database.php file, namely setting the database access details, username, password, and so on.

Open the config/database.php file and find the following lines:

$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'your username';
$db['default']['password'] = 'your password';
$db['default']['database'] = 'imagesdb';

Edit the values in the preceding code ensuring you substitute those values for the ones more specific to your setup and situation—so enter your username, password, and so on.

Adjusting the config.php and autoload.php files

We don’t actually need to adjust the config.php file in this project as we’re not really using sessions or anything like that. So we don’t need an encryption key or database information.

So just ensure that you are not autoloading the session in the config/autoload.php file or you will get an error, as we’ve not set any session variables in the config/config.php file.

Adjusting the routes.php file

We want to redirect the user to the create controller rather than the default CodeIgniter welcome controller. To do this, we will need to amend the default controller settings in the routes.php file to reflect this. The steps are as follows:

  1. Open the config/routes.php file for editing and find the following lines (near the bottom of the file):
    $route['default_controller'] = "welcome";
    $route['404_override'] = '';
  2. First, we need to change the default controller. Initially, in a CodeIgniter application, the default controller is set to welcome. However, we don’t need that, instead we want the default controller to be create, so find the following line:
    $route['default_controller'] = "welcome";

    Replace it with the following lines:

    $route['default_controller'] = "create";
    $route['404_override'] = '';
  3. Then we need to add some rules to govern how we handle URLs coming in and form submissions.

    Leave a few blank lines underneath the preceding two lines of code (default controller and 404 override) and add the following three lines of code:

    $route['create'] = "create/index";
    $route['(:any)'] = "go/index";
    $route['create/do_upload'] = "create/do_upload";

Creating the model

There is only one model in this project, image_model.php. It contains functions specific to creating and resetting passwords.

Create the /path/to/codeigniter/application/models/image_model.php file and add the following code to it:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
class Image_model extends CI_Model {
function __construct() {
   parent::__construct();
}
 
function save_image($data) {
   do {
      $img_url_code = random_string('alnum', 8);
 
     $this->db->where('img_url_code = ', $img_url_code);
     $this->db->from('images');
     $num = $this->db->count_all_results();
   } while ($num >= 1);
 
   $query = "INSERT INTO `images` (`img_url_code`,       `img_image_name`, `img_dir_name`) VALUES (?,?,?) ";
   $result = $this->db->query($query, array($img_url_code,       $data['image_name'], $data['img_dir_name']));
 
   if ($result) {
     return $img_url_code;
   } else {
     return flase;
   }
}
 
function fetch_image($img_url_code) {
   $query = "SELECT * FROM `images` WHERE `img_url_code` = ? ";
   $result = $this->db->query($query, array($img_url_code));
 
   if ($result) {
     return $result;
   } else {
     return false;
   }
}
}

There are two main functions in this model, which are as follows:

  • save_image(): This generates a unique code that is associated with the uploaded image and saves it, with the image name and folder name, to the database.
  • fetch_image(): This fetches an image’s details from the database according to the unique code provided.

Okay, let’s take save_image() first. The save_image() function accepts an array from the create controller containing image_name (from the upload process) and img_dir_name (this is the folder that the image is stored in).

A unique code is generated using a do…while loop as shown here:

$img_url_code = random_string('alnum', 8);

First a string is created, eight characters in length, containing alpha-numeric characters. The do…while loop checks to see if this code already exists in the database, generating a new code if it is already present. If it does not already exist, this code is used:

do {
$img_url_code = random_string('alnum', 8);
 
$this->db->where('img_url_code = ', $img_url_code);
$this->db->from('images');
$num = $this->db->count_all_results();
} while ($num >= 1);

This code and the contents of the $data array are then saved to the database using the following code:

$query = "INSERT INTO `images` (`img_url_code`, `img_image_name`,   `img_dir_name`) VALUES (?,?,?) ";
$result = $this->db->query($query, array($img_url_code,   $data['image_name'], $data['img_dir_name']));

The $img_url_code is returned if the INSERT operation was successful, and false if it failed. The code to achieve this is as follows:

if ($result) {
return $img_url_code;
} else {
return false;
}

Creating the views

There are only three views in this project, which are as follows:

  • /path/to/codeigniter/application/views/create/create.php: This displays a form to the user allowing them to upload an image.
  • /path/to/codeigniter/application/views/create/result.php: This displays a link that the user can use to forward other people to the image, as well as the image itself.
  • /path/to/codeigniter/application/views/nav/top_nav.php: This displays the top-level menu. In this project it’s very simple, containing a project name and a link to go to the create controller.

So those are our views, as I said, there are only three of them as it’s a simple project. Now, let’s create each view file.

  1. Create the /path/to/codeigniter/application/views/create/create.php file and add the following code to it:

    <div class="page-header">
    <h1><?php echo $this->lang->line('system_system_name');     ?></h1>
    </div>
     
    <p><?php echo $this->lang->line('encode_instruction_1');   ?></p>
     
    <?php echo validation_errors(); ?>
     
    <?php if (isset($success) && $success == true) : ?>
    <div class="alert alert-success">
       <strong><?php echo $this->lang->line('     common_form_elements_success_notifty'); ?></strong>    
    <?php echo $this->lang->     line('encode_encode_now_success'); ?>
    </div>
    <?php endif ; ?>
     
    <?php if (isset($fail) && $fail == true) : ?>
    <div class="alert alert-danger">
       <strong><?php echo $this->lang->line('     common_form_elements_error_notifty'); ?> </strong>     
    <?php echo $this->lang->line('encode_encode_now_error     '); ?>
       <?php echo $fail ; ?>
    </div>
    <?php endif ; ?>
     
    <?php echo form_open_multipart('create/do_upload');?>
    <input type="file" name="userfile" size="20" />
    <br />
    <input type="submit" value="upload" />
    <?php echo form_close() ; ?>
    <br />
    <?php if (isset($result) && $result == true) : ?>
    <div class="alert alert-info">
       <strong><?php echo $this->lang->line('     encode_upload_url'); ?> </strong>
       <?php echo anchor($result, $result) ; ?>
    </div>
    <?php endif ; ?>

    This view file can be thought of as the main view file; it is here that the user can upload their image. Error messages are displayed here too.

  2. Create the /path/to/codeigniter/application/views/create/result.php file and add the following code to it:
    <div class="page-header">
    <h1><?php echo $this->lang->line('system_system_name');     ?></h1>
    </div>
     
    <?php if (isset($result) && $result == true) : ?>
       <strong><?php echo $this->lang->line('     encode_encoded_url'); ?> </strong>
       <?php echo anchor($result, $result) ; ?>
       <br />
       <img src="<?php echo base_url() . 'upload/' .       $img_dir_name . '/' . $file_name ;?>" />
    <?php endif ; ?>

    This view will display the encoded image resource URL to the user (so they can copy and share it) and the actual image itself.

  3. Create the /path/to/codeigniter/application/views/nav/top_nav.php file and add the following code to it:
    <!-- Fixed navbar -->
    <div class="navbar navbar-inverse navbar-fixed-top"   role="navigation">
    <div class="container">
       <div class="navbar-header">
         <button type="button" class="navbar-toggle" data-
    toggle="collapse" data-target=".navbar-collapse">        <span class="sr-only">Toggle navigation</span>        <span class="icon-bar"></span>        <span class="icon-bar"></span>        <span class="icon-bar"></span>      </button>      <a class="navbar-brand" href="#"><?php echo $this-       >lang->line('system_system_name'); ?></a>  </div>    <div class="navbar-collapse collapse">      <ul class="nav navbar-nav">        <li class="active"><?php echo anchor('create',           'Create') ; ?></li>      </ul>    </div><!--/.nav-collapse --> </div> </div>   <div class="container theme-showcase" role="main">

    This view is quite basic but still serves an important role. It displays an option to return to the index() function of the create controller.

Creating the controllers

We’re going to create two controllers in this project, which are as follows:

  • /path/to/codeigniter/application/controllers/create.php: This handles the creation of unique folders to store images and performs the upload of a file.
  • /path/to/codeigniter/application/controllers/go.php: This fetches the unique code from the database, and returns any image associated with that code.

These are two of our controllers for this project, let’s now go ahead and create them.

Create the /path/to/codeigniter/application/controllers/create.php file and add the following code to it:

<?php if (!defined('BASEPATH')) exit('No direct script access   allowed');
 
class Create extends MY_Controller {
function __construct() {
   parent::__construct();
     $this->load->helper(array('string'));
     $this->load->library('form_validation');
     $this->load->library('image_lib');
     $this->load->model('Image_model');
     $this->form_validation->set_error_delimiters('<div         class="alert alert-danger">', '</div>');
   }
 
public function index() {
   $page_data = array('fail' => false,
                       'success' => false);
   $this->load->view('common/header');
   $this->load->view('nav/top_nav');
   $this->load->view('create/create', $page_data);
   $this->load->view('common/footer');
}
 
public function do_upload() {
   $upload_dir = '/filesystem/path/to/upload/folder/';
   do {
     // Make code
     $code = random_string('alnum', 8);
 
     // Scan upload dir for subdir with same name
     // name as the code
     $dirs = scandir($upload_dir);
 
     // Look to see if there is already a
     // directory with the name which we
     // store in $code
     if (in_array($code, $dirs)) { // Yes there is
       $img_dir_name = false; // Set to false to begin again
     } else { // No there isn't
       $img_dir_name = $code; // This is a new name
     }
 
   } while ($img_dir_name == false);
 
   if (!mkdir($upload_dir.$img_dir_name)) {
     $page_data = array('fail' => $this->lang->       line('encode_upload_mkdir_error'),
                         'success' => false);
     $this->load->view('common/header');
     $this->load->view('nav/top_nav');
     $this->load->view('create/create', $page_data);
     $this->load->view('common/footer');
   }
 
   $config['upload_path'] = $upload_dir.$img_dir_name;
   $config['allowed_types'] = 'gif|jpg|jpeg|png';
   $config['max_size'] = '10000';
   $config['max_width'] = '1024';
   $config['max_height'] = '768';
 
   $this->load->library('upload', $config);
 
   if ( ! $this->upload->do_upload()) {
     $page_data = array('fail' => $this->upload->       display_errors(),
                         'success' => false);
     $this->load->view('common/header');
     $this->load->view('nav/top_nav');
     $this->load->view('create/create', $page_data);
      $this->load->view('common/footer');
   } else {
     $image_data = $this->upload->data();
     $page_data['result'] = $this->Image_model->save_image(       array('image_name' => $image_data['file_name'],         'img_dir_name' => $img_dir_name));
   $page_data['file_name'] = $image_data['file_name'];
     $page_data['img_dir_name'] = $img_dir_name;
 
     if ($page_data['result'] == false) {
       // success - display image and link
       $page_data = array('fail' => $this->lang->         line('encode_upload_general_error'));
       $this->load->view('common/header');
       $this->load->view('nav/top_nav');
       $this->load->view('create/create', $page_data);
       $this->load->view('common/footer');
     } else {
       // success - display image and link
       $this->load->view('common/header');
       $this->load->view('nav/top_nav');
       $this->load->view('create/result', $page_data);
       $this->load->view('common/footer');
     }
   }
}
}

Let’s start with the index() function. The index() function sets the fail and success elements of the $page_data array to false. This will suppress any initial messages from being displayed to the user. The views are loaded, specifically the create/create.php view, which contains the image upload form’s HTML markup.

Once the user submits the form in create/create.php, the form will be submitted to the do_upload() function of the create controller. It is this function that will perform the task of uploading the image to the server.

First off, do_upload() defines an initial location for the upload folder. This is stored in the $upload_dir variable.

Next, we move into a do…while structure. It looks something like this:

do {
// something
} while ('…a condition is not met');

So that means do something while a condition is not being met. Now with that in mind, think about our problem—we have to save the image being uploaded in a folder. That folder must have a unique name. So what we will do is generate a random string of eight alpha-numeric characters and then look to see if a folder exists with that name. Keeping that in mind, let’s look at the code in detail:

do {
// Make code
$code = random_string('alnum', 8);
 
// Scan uplaod dir for subdir with same name
// name as the code
$dirs = scandir($upload_dir);
 
// Look to see if there is already a
// directory with the name which we
// store in $code
if (in_array($code, $dirs)) { // Yes there is
   $img_dir_name = false; // Set to false to begin again
} else { // No there isn't
   $img_dir_name = $code; // This is a new name
}
} while ($img_dir_name == false);

So we make a string of eight characters, containing only alphanumeric characters, using the following line of code:

$code = random_string('alnum', 8);

We then use the PHP function scandir() to look in $upload_dir. This will store all directory names in the $dirs variable, as follows:

$dirs = scandir($upload_dir);

We then use the PHP function in_array() to look for the value in $code in the list of directors from scandir():

If we don’t find a match, then the value in $code must not be taken, so we’ll go with that. If the value is found, then we set $img_dir_name to false, which is picked up by the final line of the do…while loop:

...
} while ($img_dir_name == false);

Anyway, now that we have our unique folder name, we’ll attempt to create it. We use the PHP function mkdir(), passing to it $upload_dir concatenated with $img_dir_name. If mkdir() returns false, the form is displayed again along with the encode_upload_mkdir_error message set in the language file, as shown here:

if (!mkdir($upload_dir.$img_dir_name)) {
$page_data = array('fail' => $this->lang->   line('encode_upload_mkdir_error'),
                     'success' => false);
$this->load->view('common/header');
$this->load->view('nav/top_nav');
$this->load->view('create/create', $page_data);
$this->load->view('common/footer');
}

Once the folder has been made, we then set the configuration variables for the upload process, as follows:

$config['upload_path'] = $upload_dir.$img_dir_name;
$config['allowed_types'] = 'gif|jpg|jpeg|png';
$config['max_size'] = '10000';
$config['max_width'] = '1024';
$config['max_height'] = '768';

Here we are specifying that we only want to upload .gif, .jpg, .jpeg, and .png files. We also specify that an image cannot be above 10,000 KB in size (although you can set this to any value you wish—remember to adjust the upload_max_filesize and post_max_size PHP settings in your php.ini file if you want to have a really big file).

We also set the minimum dimensions that an image must be. As with the file size, you can adjust this as you wish.

We then load the upload library, passing to it the configuration settings, as shown here:

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

Next we will attempt to do the upload. If unsuccessful, the CodeIgniter function $this->upload->do_upload() will return false. We will look for this and reload the upload page if it does return false. We will also pass the specific error as a reason why it failed. This error is stored in the fail item of the $page_data array. This can be done as follows:

   if ( ! $this->upload->do_upload()) {
     $page_data = array('fail' => $this->upload-       >display_errors(),
                         'success' => false);
     $this->load->view('common/header');
     $this->load->view('nav/top_nav');
     $this->load->view('create/create', $page_data);
     $this->load->view('common/footer');
   } else {
...

If, however, it did not fail, we grab the information generated by CodeIgniter from the upload. We’ll store this in the $image_data array, as follows:

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

Then we try to store a record of the upload in the database. We call the save_image function of Image_model, passing to it file_name from the $image_data array, as well as $img_dir_name, as shown here:

$page_data['result'] = $this->Image_model-> save_image(array('image_name' => $image_data['file_name'],   
'img_dir_name' => $img_dir_name));

We then test for the return value of the save_image() function; if it is successful, then Image_model will return the unique URL code generated in the model. If it is unsuccessful, then Image_model will return the Boolean false.

If false is returned, then the form is loaded with a general error. If successful, then the create/result.php view file is loaded. We pass to it the unique URL code (for the link the user needs), and the folder name and image name, necessary to display the image correctly.

Create the /path/to/codeigniter/application/controllers/go.php file and add the following code to it:

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

class Go extends MY_Controller {
function __construct() {
parent::__construct();
   $this->load->helper('string');
}

public function index() {
   if (!$this->uri->segment(1)) {
     redirect (base_url());
   } else {
     $image_code = $this->uri->segment(1);
     $this->load->model('Image_model');
     $query = $this->Image_model->fetch_image($image_code);

     if ($query->num_rows() == 1) {
       foreach ($query->result() as $row) {
         $img_image_name = $row->img_image_name;
         $img_dir_name = $row->img_dir_name;
       }          $url_address = base_url() . 'upload/' . $img_dir_name .'/' . $img_image_name;        redirect (prep_url($url_address));      } else {        redirect('create');      }    } } }

The go controller has only one main function, index(). It is called when a user clicks on a URL or a URL is called (perhaps as the src value of an HTML img tag). Here we grab the unique code generated and assigned to an image when it was uploaded in the create controller.

This code is in the first value of the URI. Usually it would occupy the third parameter—with the first and second parameters normally being used to specify the controller and controller function respectively. However, we have changed this behavior using CodeIgniter routing. This is explained fully in the Adjusting the routes.php file section of this article.

Once we have the unique code, we pass it to the fetch_image() function of Image_model:

$image_code = $this->uri->segment(1);
$this->load->model('Image_model');
$query = $this->Image_model->fetch_image($image_code);

We test for what is returned. We ask if the number of rows returned equals exactly 1. If not, we will then redirect to the create controller.

Perhaps you may not want to do this. Perhaps you may want to do nothing if the number of rows returned does not equal 1. For example, if the image requested is in an HTML img tag, then if an image is not found a redirect may send someone away from the site they’re viewing to the upload page of this project—something you might not want to happen. If you want to remove this functionality, remove the following lines in bold from the code excerpt:

....
       $img_dir_name = $row->img_dir_name;
       }
 
       $url_address = base_url() . 'upload/' . $img_dir_name .'/'           . $img_image_name;
       redirect (prep_url($url_address));
     } else {
       redirect('create');
     }
   }
}
}
....

Anyway, if the returned value is exactly 1, then we’ll loop over the returned database object and find img_image_name and img_dir_name, which we’ll need to locate the image in the upload folder on the disk. This can be done as follows:

foreach ($query->result() as $row) {
$img_image_name = $row->img_image_name;
$img_dir_name = $row->img_dir_name;
}

We then build the address of the image file and redirect the browser to it, as follows:

$url_address = base_url() . 'upload/' . $img_dir_name .'/'   . $img_image_name;
redirect (prep_url($url_address));

Creating the language file

We make use of the language file to serve text to users. In this way, you can enable multiple region/multiple language support.

Create the /path/to/codeigniter/application/language/english/en_admin_lang.php file and add the following code to it:

<?php if (!defined('BASEPATH')) exit('No direct script access   allowed');
 
// General
$lang['system_system_name'] = "Image Share";
 
// Upload
$lang['encode_instruction_1'] = "Upload your image to share it";
$lang['encode_upload_now'] = "Share Now";
$lang['encode_upload_now_success'] = "Your image was uploaded, you   can share it with this URL";
$lang['encode_upload_url'] = "Hey look at this, here's your   image:";
$lang['encode_upload_mkdir_error'] = "Cannot make temp folder";
$lang['encode_upload_general_error'] = "The Image cannot be saved   at this time";

Putting it all together

Let’s look at how the user uploads an image. The following is the sequence of events:

  1. CodeIgniter looks in the routes.php config file and finds the following line:

    $route['create'] = "create/index";

    It directs the request to the create controller’s index() function.

  2. The index() function loads the create/create.php view file that displays the upload form to the user.
  3. The user clicks on the Choose file button, navigates to the image file they wish to upload, and selects it.
  4. The user presses the Upload button and the form is submitted to the create controller’s index() function.
  5. The index() function creates a folder in the main upload directory to store the image in, then does the actual upload.
  6. On a successful upload, index() sends the details of the upload (the new folder name and image name) to the save_image() model function.
  7. The save_model() function also creates a unique code and saves it in the images table along with the folder name and image name passed to it by the create controller.
  8. The unique code generated during the database insert is then returned to the controller and passed to the result view, where it will form part of a success message to the user.

Now, let’s see how an image is viewed (or fetched). The following is the sequence of events:

      1. A URL with the syntax www.domain.com/226KgfYH comes into the application—either when someone clicks on a link or some other call (<img src=””>).

      2. CodeIgniter looks in the routes.php config file and finds the following line:
        $route['(:any)'] = "go/index";
      3. As the incoming request does not match the other two routes, the preceding route is the one CodeIgniter applies to this request.
      4. The go controller is called and the code of 226KgfYH is passed to it as the 1st segment of uri.
      5. The go controller passes this to the fetch_image() function of the Image_model.php file. The fetch_image() function will attempt to find a matching record in the database. If found, it returns the folder name marking the saved location of the image, and its filename.
      6. This is returned and the path to that image is built. CodeIgniter then redirects the user to that image, that is, supplies that image resource to the user that requested it.

Summary

So here we have a basic image sharing application. It is capable of accepting a variety of images and assigning them to records in a database and unique folders in the filesystem. This is interesting as it leaves things open to you to improve on. For example, you can do the following:

  • You can add limits on views. As the image record is stored in the database, you could adapt the database. Adding two columns called img_count and img_count_limit, you could allow a user to set a limit for the number of views per image and stop providing that image when that limit is met.
  • You can limit views by date. Similar to the preceding point, but you could limit image views to set dates.
  • You can have different URLs for different dimensions. You could add functionality to make several dimensions of image based on the initial upload, offering several different URLs for different image dimensions.
  • You can report abuse. You could add an option allowing viewers of images to report unsavory images that might be uploaded.
  • You can have terms of service. If you are planning on offering this type of application as an actual web service that members of the public could use, then I strongly recommend you add a terms of service document, perhaps even require that people agree to terms before they upload an image.

In those terms, you’ll want to mention that in order for someone to use the service, they first have to agree that they do not upload and share any images that could be considered illegal. You should also mention that you’ll cooperate with any court if information is requested of you.

You really don’t want to get into trouble for owning or running a web service that stores unpleasant images; as much as possible you want to make your limits of liability clear and emphasize that it is the uploader who has provided the images.

Resources for Article:


Further resources on this subject:


Packt

Share
Published by
Packt

Recent Posts

Harnessing Tech for Good to Drive Environmental Impact

At Packt, we are always on the lookout for innovative startups that are not only…

2 months ago

Top life hacks for prepping for your IT certification exam

I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…

3 years ago

Learn Transformers for Natural Language Processing with Denis Rothman

Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…

3 years ago

Learning Essential Linux Commands for Navigating the Shell Effectively

Once we learn how to deploy an Ubuntu server, how to manage users, and how…

3 years ago

Clean Coding in Python with Mariano Anaya

Key-takeaways:   Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…

3 years ago

Exploring Forms in Angular – types, benefits and differences   

While developing a web application, or setting dynamic pages and meta tags we need to deal with…

3 years ago