Trongate Website Homepage

The Submit Upload Method

Brace yourself! You're about to be presented with some very complicated looking code. The code is a method that is designed to process image upload requests. At first glance, it will look extremely complicated, but there's no need to worry because:

Okay. Are you ready for the slightly miserable looking code? Here it comes!


    function submit_upload_picture($update_id) {

 $this->module("trongate_security");
 $this->trongate_security->_make_sure_allowed();

 $submit = post("submit");

 if ($submit == "Upload") {
  $picture_settings = $this->_init_picture_settings();
  extract($picture_settings);

  $validation_str = "allowed_types[gif,jpg,jpeg,png]|max_size[".$max_file_size."]|max_width[".$max_width."]|max_height[".$max_height."]";
  $this->validation_helper->set_rules("picture", "item picture", $validation_str);

  $result = $this->validation_helper->run();

  if ($result == true) {

   $config["destination"] = $destination."/".$update_id;
   $config["max_width"] = $resized_max_width;
   $config["max_height"] = $resized_max_height;

   if ($thumbnail_dir !== "") {
    $config["thumbnail_dir"] = $thumbnail_dir."/".$update_id;
    $config["thumbnail_max_width"] = $thumbnail_max_width;
    $config["thumbnail_max_height"] = $thumbnail_max_height;
   }

   //upload the picture
   $this->upload_picture($config);

   //update the database
   $data["picture"] = $_FILES["picture"]["name"];
   $this->model->update($update_id, $data);

   $flash_msg = "The picture was successfully uploaded";
   set_flashdata($flash_msg);
   redirect($_SERVER["HTTP_REFERER"]);

  } else {
   redirect($_SERVER["HTTP_REFERER"]);
  }
 }
}

Told you it was miserable!

So, let's explore what this code does and how it works.

General Goals

The method, which is called 'submit_upload_picture' is designed to:

Basic Method Structure

Our method is going to read an 'id' from the third segment of the URL. This 'id' will correspond with the 'id' of the record that is to be associated with a picture. In Trongate modules, the first argument that gets passed into a public method is assumed to have a value equal to the third URL segment. For example:


function whatever($id) {
 //this method will assign the value of the third URL segment to $id
}

We'll start our method off by assigning the third segment of the URL to a variable named $update_id. We'll then add a couple of lines of security code, to make sure only administrators have access to this method.


function submit_upload_picture($update_id) {

 $this->module("trongate_security");
 $this->trongate_security->_make_sure_allowed();
}

When you upload files, using PHP, your uploaded files immediately become part of a special kind of array called the $_FILES superglobal. The $_FILES superglobal is an array containing information about files that have been submitted. You can view full details about what is contained within your $_FILES superglobal by calling Trongate's json method. For example,

json($_FILES, true);

Now we're going to protect our method with an IF statement. The idea here is to make sure a form was submitted. In this instance, we'll test for a posted form field with a name of 'submit' and a value of 'Upload'. Of course, if the user has clicked the 'Upload' button (as defined on the previous page) then it means that the requirements of the IF statement would be met:


$submit = post("submit");

if ($submit == "Upload") {
  // showtime!
}

Now, we're into the business part of the code. Let's start by reading the uploader settings for this particular controller file.

$picture_settings = $this->_init_picture_settings();

The uploader settings is going to be an array. We can turn the (picture_settings) array into individual variables by invoking PHP's extract method.

extract($picture_settings);

The extract() method takes an array and breaks it down into individual variables. For example, let's assume you have an array of data that represents a user:


$data["first_name"] = "John";
$data["last_name"] = "Smith";
$data["age"] = 21;

The code above produces an array named $data. With just our $data array declared, and nothing more, the following code would produce an error:
echo $age;

An error would be produced because there is no age variable - only an age property ($data['age']).

If order to produce an $age variable, we'd call the extract() method. For example:


$data["first_name"] = "John";
$data["last_name"] = "Smith";
$data["age"] = 21;
extract($data);
echo $age; //would display "21"

Using extract() can often produce code that that is incredibly confusing. If you're not careful, you can end up with all sorts of variables everywhere and have no clue as to where they came from! So, it's generally a good idea to avoid using extract(), unless there's a genuine benefit to be gained.

Moving on...

We're now going to run our submitted form variables through some form validation tests. However, let's pause for a moment and recap on how our method looks so far...


function submit_upload_picture($update_id) {
 $this->module("trongate_security");
 $this->trongate_security->_make_sure_allowed();

 $submit = post("submit");

 if ($submit == "Upload") {
  $picture_settings = $this->_init_picture_settings();
  extract($picture_settings);

  //let"s do some form validation!

 }
}

In this instance, we'll be running our submitted values through the following form validation tests:

Our allowed file types will be; gif, jpg, jpeg and png. The other values will be taken from our picture settings (method). To make our code a little bit more readable, we'll produce a validation string and then pass our validation string into our 'set_rules' declaration. For example,


$validation_str = "allowed_types[gif,jpg,jpeg,png]|max_size[".$max_file_size."]|max_width[".$max_width."]|max_height[".$max_height."]";
$this->validation_helper->set_rules("picture", "item picture", $validation_str);

With our validation rules declared, we can now go into an ordinary form validation protocol:


  $result = $this->validation_helper->run();

  if ($result == true) {

   //upload ahoy!

  } else {
   redirect($_SERVER["HTTP_REFERER"]);
  }

If there is a form validation error then we are sending the user back to the previous page by calling Trongate's redirect() method. The $_SERVER['HTTP_REFERER'] value is equal to whatever the previous URL is. If you want, you can achieve the same outcome with:

redirect(previous_url());

Uploading The Picture

If our form submission passes validation then it's time to upload our submitted picture. In Trongate, you can upload pictures by creating an array of configuration data and passing it into Trongate's upload_picture() method.

Before we begin the actual upload, let's clarify where the file is to be sent to:

$config["destination"] = $destination."/".$update_id;

We may also wish to reduce the size of uploaded images to save space and improve page load speed, later on. This is optional. However, if it's something you'd like to do then you can achieve this with:


   $config["max_width"] = $resized_max_width;
   $config["max_height"] = $resized_max_height;

The two lines of code above ensure that our uploaded image will be resized - if necessary - to ensure the stored picture does not exceed the dimensions declared. If the uploaded image is smaller than the dimensions declared then no resizing will occur.

Then, we move onto the business of thumbnails.

Thumbnails are optional. However, if you'd like to have thumbnail settings declared, Trongate will generate thumbnails for you - at the point of upload - in accordance with your settings.

Strictly speaking, the IF statement shown below is not essential. However, it has been added to make our code a little more reusable.


   if ($thumbnail_dir !== "") {
    $config["thumbnail_dir"] = $thumbnail_dir."/".$update_id;
    $config["thumbnail_max_width"] = $thumbnail_max_width;
    $config["thumbnail_max_height"] = $thumbnail_max_height;
   }

As you can see, here we have declared a thumbnail directory as well as a thumbnail maximum width (in pixels) and a thumbnail maximum height (also in pixels).

Upload Ahoy!

Finally, here's the bit that you came here for. Uploading the picture. In Trongate, uploading can be activated with:

$this->upload_picture($config);

Loose Ends

All that remains, thereafter, is a simple database update that adds the picture name onto the 'picture' value for the affected record:


//update the database
$data["picture"] = $_FILES["picture"]["name"];
$this->model->update($update_id, $data);

...followed by a nice flash message (to let the user know what just happened) and sending the user back to the previous page.


$flash_msg = "The picture was successfully uploaded";
set_flashdata($flash_msg);
redirect($_SERVER["HTTP_REFERER"]);

The code that gets produced by the Trongate Desktop App is constantly being tweaked and improved. Don't worry if your generated picture uploader code looks at little bit different to the example shown on this page. That's normal and you can rest assured that there are no plans to fundamentally change how picture uploading works with Trongate.