Ajax Handler v1.2
The Ajax Handler is a CakePHP Component that processes and handles AJAX requests. It determines what action should be dealt as an AJAX call, applies the appropriate filters, prepares the data for a response and responds with the appropriate headers.
Recent Thoughts
- Twitter feed is currently unavailable. View my Twitter
Manual v2.x : Table of Contents
Uploader v2.5 (Log)
Uploaded: 03/06/2010
Requires: PHP 5, CakePHP 1.2
Tested On: PHP 5.3, CakePHP 1.2.5
View Manual:
Uploader
Package: Plugin
Category: CakePHP
Views: 7,265
An all around general purpose file uploader for CakePHP. Packaged as a stand alone plugin with file validation, file scanning and support for a wide range of basic mime types.
Class Features:
Class Features:
- Automatically sets all ini settings required for file uploading
- Support for a wide range of mime types: text, images, archives, audio, video, application
- Logs all internal errors that can be retrieved and displayed
- Saves a log for all uploads happening during the current request
- Automatically validates against the default mime types and internal errors
- Can scan the uploaded files for viruses using the ClamAV module
- Files can be uploaded anywhere within the webroot folder
- Convenience methods for deleting a file, moving/renaming a file and getting the file extension or dimensions
- Built in methods for resizing images and generating thumbnails
- Custom Behavior to add validation rules to your Models validation set
- Custom Behavior that allows models to attach files to automatically upload the file and save its information to a database
Top
1 - Installation
To begin using the plugin, you would download and unzip the contents into a folder called "uploader". Once that is complete, move the whole folder into the plugins directory of your CakePHP application. You would then initiate the uploader component by adding it to your controllers $components array. It's best to place the component only in the controllers that will use it, instead of the app controller.
On top this, you can add validation rules for image uploading by applying the uploader validation behavior. There are validation rules for filesize, dimensions, mime types and if the image is required or optional. Skip to the chapter dealing with Model validation.
var $components = array('Uploader.Uploader');
On top this, you can add validation rules for image uploading by applying the uploader validation behavior. There are validation rules for filesize, dimensions, mime types and if the image is required or optional. Skip to the chapter dealing with Model validation.
var $actsAs = array('Uploader.FileValidation');
Top
2 - Configuration
Like any other plugin or component, the Uploader comes packaged with some variables that can be added to a controllers beforeFilter() to customize its usage. The following variables are available.
Upload Directory
This should be the destination folder where all files should be uploaded to. When editing this variable, the path should be relative to the app/webroot/ folder, and should have a trailing slash.
Enable Uploading
If you would like to enable or disable uploading through the whole app, just set $enableUpload to boolean true or false.
Max File Size
When you set the max file size, all ini settings are automatically calculated based on the size you give. The max file size should be based on the shorthand notation which can be found here. By default, the max file size is set to 5M (5 megabytes).
Max Filename Length
You can limit the character length of a filename by setting this variable. By default the max length is 40 characters. Additionally if you set the variable to false, no length restrictions will be applied.
Scan for Viruses
If you have the ClamAV Module installed on your server, you can set this variable to true to scan the uploaded file for viruses.
Temp Upload Directory
By default the temp directory is set to your apps tmp folder, and in most cases should not be changed.
Adding Additional Mime Types
If you want to be able to upload a certain file type that isn't supported in the default list of mime types, you may use the mime() method.
Upload Directory
This should be the destination folder where all files should be uploaded to. When editing this variable, the path should be relative to the app/webroot/ folder, and should have a trailing slash.
$this->Uploader->uploadDir = 'files/uploads/';
Enable Uploading
If you would like to enable or disable uploading through the whole app, just set $enableUpload to boolean true or false.
$this->Uploader->enableUpload = false;
Max File Size
When you set the max file size, all ini settings are automatically calculated based on the size you give. The max file size should be based on the shorthand notation which can be found here. By default, the max file size is set to 5M (5 megabytes).
$this->Uploader->maxFileSize = '2M'; // 2 Megabytes
Max Filename Length
You can limit the character length of a filename by setting this variable. By default the max length is 40 characters. Additionally if you set the variable to false, no length restrictions will be applied.
$this->Uploader->maxNameLength = 25;
Scan for Viruses
If you have the ClamAV Module installed on your server, you can set this variable to true to scan the uploaded file for viruses.
$this->Uploader->scanFile = true;
Temp Upload Directory
By default the temp directory is set to your apps tmp folder, and in most cases should not be changed.
$this->Uploader->tempDir = TMP;
Adding Additional Mime Types
If you want to be able to upload a certain file type that isn't supported in the default list of mime types, you may use the mime() method.
$this->Uploader->mime('image', 'gif', 'image/gif');
Top
3 - Uploading A File
Lets begin by setting up our form and applying all the right file attributes. In our example, our upload field will be called "upload".
The next step would be to build the controller action to handle the file upload process. We will be doing a basic file upload with no options added, no behavior validation and basic error handling.
On a successful upload, the $data variable will be a populated array with the values for the uploaded files filesize, name, extension, mime group, destination path, upload time and width/height (if an image). You can use this data to output text on the frontend, or save data to a database.
Now to do a more advanced file upload, the second argument of upload() will take an array of options. The following options are available:
echo $form->create('Model', array('type' => 'file')); echo $form->input('fileName', array('type' => 'file')); echo $form->end('Upload');
The next step would be to build the controller action to handle the file upload process. We will be doing a basic file upload with no options added, no behavior validation and basic error handling.
function upload() { if (!empty($this->data)) { if ($data = $this->Uploader->upload('fileName')) { // Upload successful, do whatever } } }
On a successful upload, the $data variable will be a populated array with the values for the uploaded files filesize, name, extension, mime group, destination path, upload time and width/height (if an image). You can use this data to output text on the frontend, or save data to a database.
Now to do a more advanced file upload, the second argument of upload() will take an array of options. The following options are available:
- overwrite - If a file already exists with the filename, should we overwrite it?
- name - Give a custom name to the file once uploaded
if ($data = $this->Uploader->upload('fileName', array('overwrite' => true, 'name' => 'new_fileName'))) { debug($data); }
Top
4 - Uploading Multiple Files
In the newer versions of the Uploader, you are able to upload multiple files using the uploadAll() method. Although by using this method, you are unable to call any of the image transformation methods, so this method should only be used for batch uploading. Lets begin by setting up our example form:
Once this is done, you would call the method the same as the regular upload() method, but the first argument would be an array of fields to upload. Alternatively, if you leave the first argument blank it will upload all files.
The method will return an array of data for each successfully uploaded file and will be indexed by its field name in the form. If a file fails uploading, it will not be present in the final array. By default, all files will not overwrite files with the same name, but you can simply set the second argument to true to overwrite if necessary.
echo $form->create('Model', array('type' => 'file')); echo $form->input('fileName1', array('type' => 'file')); echo $form->input('fileName2', array('type' => 'file')); echo $form->input('fileName3', array('type' => 'file')); echo $form->end('Upload');
Once this is done, you would call the method the same as the regular upload() method, but the first argument would be an array of fields to upload. Alternatively, if you leave the first argument blank it will upload all files.
function upload() { if (!empty($this->data)) { if ($data = $this->Uploader->uploadAll()) { // Upload successful } } } // Restrict it to certain fields $this->Uploader->uploadAll(array('fileName1', 'fileName2'));
The method will return an array of data for each successfully uploaded file and will be indexed by its field name in the form. If a file fails uploading, it will not be present in the final array. By default, all files will not overwrite files with the same name, but you can simply set the second argument to true to overwrite if necessary.
$this->Uploader->uploadAll(false, true);
Top
5 - Resizing, Cropping, Flipping or Scaling an Image
The Uploader comes built in with a few image transformation functions, which are crop(), flip(), resize() and scale(). Each of these MUST be called after a file has successfully been uploaded, as it will use the last uploaded image as its template. Each of these methods will return a relative path if the successful.
Below is the correct place and usage for these transformation methods. Simply swap out resize() for the method you want to use, or place as many as you'd like.
Options Reference
Resizing
The resize() method will take its first argument as an array of options and can resize an image to any dimension you wish. The following options are available: width, height, quality, append. If you only supply the width, the height will be automatically determined to scale, and vice versa.
Cropping
The crop() method will accept the following options: width, height, quality, append, location. If no width and height is supplied, it will be cropped to the size of the smallest dimension (If the image is 500x250, the cropped will be 250x250). Both dimensions should be required for proper crop ratio. While setting the location, top/bottom should only be used where the images height is bigger then its width, and left/right should be used when the width is larger.
Flipping
To flip an image, apply a "dir" option within the array of options. Flip will accept the quality and append options. The following directions are available for flipping; any of these constants should be used.
Vertical = UploaderComponent::DIR_VERT
Horizontal = UploaderComponent::DIR_HORI
Vertical and Horizontal = UploaderComponent::DIR_BOTH
Scaling
You can scale an image to a percentage by using the scale() method. It will take an array of options as its first argument and they are: percent, quality and append. The percent should be an integer or decimal, by default its .5 (50%). For example 2 would be 200% larger, or .3 would be 33% of its original size.
Resizing in version 1.3 and below
Resizing in the older version was quite different, the options were called within the upload() method. All you need to do is set resize to true and the dimensions, like so. The resized images path will be added into the returned data array from upload().
Below is the correct place and usage for these transformation methods. Simply swap out resize() for the method you want to use, or place as many as you'd like.
function upload() { if (!empty($this->data)) { if ($data = $this->Uploader->upload('fileName')) { // Returns: /files/uploads/fileName_100xauto.jpg $resized_path = $this->Uploader->resize(array('width' => 100)); /* Or the alternatives, etc $cropped_path = $this->Uploader->crop(); */ } } }
Options Reference
- width - The width you want the image to be
- height - The height you want the image to be
- append - What you want to be appened to the end of the files name (will be generated automatically if left blank)
- quality - The quality of your images (0-100)
- location - Which part of the image you wish to grab (center, top, bottom, left, right)
- percent - What percent should the image be scaled to?
Resizing
The resize() method will take its first argument as an array of options and can resize an image to any dimension you wish. The following options are available: width, height, quality, append. If you only supply the width, the height will be automatically determined to scale, and vice versa.
$this->Uploader->resize(array('width' => 100, 'append' => 'resized', 'quality' => 50));
Cropping
The crop() method will accept the following options: width, height, quality, append, location. If no width and height is supplied, it will be cropped to the size of the smallest dimension (If the image is 500x250, the cropped will be 250x250). Both dimensions should be required for proper crop ratio. While setting the location, top/bottom should only be used where the images height is bigger then its width, and left/right should be used when the width is larger.
$this->Uploader->crop(array('width' => 100, 'height' => 75, 'append' => 'cropped', 'location' => 'center'));
Flipping
To flip an image, apply a "dir" option within the array of options. Flip will accept the quality and append options. The following directions are available for flipping; any of these constants should be used.
Vertical = UploaderComponent::DIR_VERT
Horizontal = UploaderComponent::DIR_HORI
Vertical and Horizontal = UploaderComponent::DIR_BOTH
$this->Uploader->flip(array('dir' => self::DIR_VERT, 'append' => 'flipped'));
Scaling
You can scale an image to a percentage by using the scale() method. It will take an array of options as its first argument and they are: percent, quality and append. The percent should be an integer or decimal, by default its .5 (50%). For example 2 would be 200% larger, or .3 would be 33% of its original size.
$this->Uploader->scale(array('percent' => .3, 'append' => 'scaled'));
Resizing in version 1.3 and below
Resizing in the older version was quite different, the options were called within the upload() method. All you need to do is set resize to true and the dimensions, like so. The resized images path will be added into the returned data array from upload().
$this->Uploader->upload($this->data['Model']['file'], array('resize' => true, 'width' => 100));
Top
6 - Deleting A File
If you would like to delete a file that was uploaded, you can use the delete() method. The delete() method takes a single argument which should be a relative path to the file (beginning at app/webroot/). If no argument is given, delete() will attempt to generate a path based on the last upload stored in Uploader->data.
$this->Uploader->delete('files/uploads/filename.jpg');
Top
7 - Moving or Renaming A File
You may also move or rename a file by using move() or rename() respectively (rename() is an alias of move()). The first argument would be a relative path to the source file, where as the second argument would be a relative path to the destination (must be relative to app/webroot/). Additionally, you can set the third argument to true to overwrite a file if it exists at the destination. If overwrite is set to false and a file DOES exist, it will be renamed so that it doesn't conflict.
$this->Uploader->move('files/uploads/filename.jpg', 'files/uploads/new_filename.jpg'); // Overwrite new_image.jpg if it exists $this->Uploader->move('files/uploads/image.jpg', 'files/uploads/new_image.jpg', true);
Top
8 - Convenience Methods
The Uploader comes bundled with a few convenience methods for your use. They are dimensions(), bytes() and ext().
Getting an images dimensions
You may use the dimensions() method to get the width and height of an image. It has the ability to get dimensions locally or remotely and will return an array with the height, width and mime type.
Getting a files extension
If you want to get the extension of a file, without having to do your own logic and code, you may use ext(). It will return the filenames extension without the period.
Getting a files size / bytes
You can use the bytes() method to return a formated filesize; 5242880 will return 5 MB. Additionally you can pass the first argument as a shorthand notation and the second argument a value to return different values depending on what you want (accepts byte and size, if left blank returns default value).
Getting an images dimensions
You may use the dimensions() method to get the width and height of an image. It has the ability to get dimensions locally or remotely and will return an array with the height, width and mime type.
$dimensions = $this->Uploader->dimensions('http://www.milesj.com/images/some_image.jpg');
Getting a files extension
If you want to get the extension of a file, without having to do your own logic and code, you may use ext(). It will return the filenames extension without the period.
$ext = $this->Uploader->ext('http://www.milesj.com/images/some_image.jpg'); // Returns jpg
Getting a files size / bytes
You can use the bytes() method to return a formated filesize; 5242880 will return 5 MB. Additionally you can pass the first argument as a shorthand notation and the second argument a value to return different values depending on what you want (accepts byte and size, if left blank returns default value).
$size = $this->Uploader->bytes(5242880); // Returns 5 MB $size = $this->Uploader->bytes('5M', 'byte'); // Returns M $size = $this->Uploader->bytes('5M', 'size'); // Returns 5242880
Top
9 - Validating Against A Model
Like any upload form, you want to validate the file before it is actually uploaded. We can do this by using the Uploader validation behavior and our models built in validation system. The uploader validation can validate filesizes, image dimensions, mime types and if it should be optional or required. All we need to do is set the validation rules by applying an $actsAs behavior, like so.
Here are a few examples of how to use the behavior to add form validation.
The code above would allow basic customization for validation. If you want to extend this validation even further and have custom error messages, you can do it like so. Additionally, I will show you can apply validation to more then one field.
In the examples above, the array indexes of "fileName" and "fileName2" would be the name of the input that you created with $form->input('fileName', array('type' => 'file')). Once your validation rules are set, you would trigger the validation like so, and your model checking should kick in.
Here are a few examples of how to use the behavior to add form validation.
var $actsAs = array( 'Uploader.FileValidation' => array( 'fileName' => array( 'dimension' => array('width' => 100, 'height' => 100), 'extension' => array('gif', 'jpg', 'png', 'jpeg'), 'filesize' => 5242880, 'optional' => false ) ) );
The code above would allow basic customization for validation. If you want to extend this validation even further and have custom error messages, you can do it like so. Additionally, I will show you can apply validation to more then one field.
var $actsAs = array( 'Uploader.FileValidation' => array( 'fileName' => array( 'dimension' => array( 'width' => 100, 'height' => 100, 'error' => 'Dimension incorrect' ), 'extension' => array( 'value' => array('gif', 'jpg', 'png', 'jpeg'), 'error' => 'Mimetype incorrect', ) 'filesize' => array( 'value' => 5242880, 'error' => 'Filesize incorrect' ) 'optional' => array( 'value' => false, 'error' => 'File required' ) ), 'fileName2' => array('optional' => true) ) );
In the examples above, the array indexes of "fileName" and "fileName2" would be the name of the input that you created with $form->input('fileName', array('type' => 'file')). Once your validation rules are set, you would trigger the validation like so, and your model checking should kick in.
function upload() { if (!empty($this->data)) { $this->Model->set($this->data); if ($this->Model->validates()) { if ($data = $this->Uploader->upload('fileName')) { // Upload successful } } } }
Top
10 - Attaching Files to Models (Auto Upload)
In the latest version of the Uploader Plugin (2.3) you have access to the "Attachment Behavior". This means you can define attachments within a Model, and when the Model is about to save data, the Behavior will automatically upload the file and apply its path to the Models data to be saved to the database. This gives you the power to automatically upload file paths into database columns without any manual intervention. To attach a file to a Model, you would write it similar to the example below.
The setup works in exactly the same manner as the File Validation Behavior, and works in conjunction with the Attachment Behavior as well.
The setup is pretty straight forward. You define where you want the file to be uploaded, what column in the database the image path should be saved to, what transformations should be applied, etc. Additionally, if the Uploader errors during a file upload, the data will not be saved to the database and an error will be shown in the form.
Transformations
If you are attaching images to a Model, you can apply image transformations to it. The transformations are all the available methods in the Uploader Component: crop, flip, resize, scale. To apply a transformation, you would add an array to the "transforms" index of the $actsAs array. The array index would be the method transformation you want to use, and the value would be an array of options to apply to the image (Correlates with the $options argument of the method in the Uploader Component).
However, for all transformations you need to apply a "dbColumn" value so the Behavior knows which column to apply the new path to. You may also overwrite the base dbColumn if you want to remove the original file. Here is a quick example:
Pretty awesome right? The Attachment Behavior allows you to write less code, and automatically does all the processing and manipulation for you!
Adding dynamic filenames
When attaching files, its pretty static because you are unable to use dynamic content in class properties. However, you may use the Behaviors update() method to apply dynamic settings right before a Model's save.
The setup works in exactly the same manner as the File Validation Behavior, and works in conjunction with the Attachment Behavior as well.
var $actsAs = array( 'Uploader.Attachment' => array( 'file' => array( 'uploadDir' => '/files/', // Where to upload to, relative to app webroot 'dbColumn' => 'path', // The database column name to save the path to 'maxNameLength' => 30, // Max file name length 'overwrite' => true, // Overwrite file with same name if it exists 'name' => '', // The name to give the file (should be done right before a save) 'transforms' => array() // What transformations to do on images: scale, resize, etc ) ) );
The setup is pretty straight forward. You define where you want the file to be uploaded, what column in the database the image path should be saved to, what transformations should be applied, etc. Additionally, if the Uploader errors during a file upload, the data will not be saved to the database and an error will be shown in the form.
Transformations
If you are attaching images to a Model, you can apply image transformations to it. The transformations are all the available methods in the Uploader Component: crop, flip, resize, scale. To apply a transformation, you would add an array to the "transforms" index of the $actsAs array. The array index would be the method transformation you want to use, and the value would be an array of options to apply to the image (Correlates with the $options argument of the method in the Uploader Component).
However, for all transformations you need to apply a "dbColumn" value so the Behavior knows which column to apply the new path to. You may also overwrite the base dbColumn if you want to remove the original file. Here is a quick example:
var $actsAs = array( 'Uploader.Attachment' => array( 'file' => array( // Removed settings for example 'transforms' => array( 'scale' => array('percent' => .3, 'dbColumn' => 'path_scaled'), 'resize' => array('width' => 50, 'height' => 50, 'dbColumn' => 'path') // Removes original image and uses this one instead ) ) ) );
Pretty awesome right? The Attachment Behavior allows you to write less code, and automatically does all the processing and manipulation for you!
Adding dynamic filenames
When attaching files, its pretty static because you are unable to use dynamic content in class properties. However, you may use the Behaviors update() method to apply dynamic settings right before a Model's save.
$this->Model->Behaviors->Attachment->update('Model', 'file', array('name' => 'newName')); if ($this->Model->save($this->data)) { // Filename should now be "newName" in the database }
Top
Read the whole documentation? Download the script now and try it yourself! Return to the Top
11 - Generating Thumbnails
Version Notice! This chapter only applies to Uploader version 1.3 and below, for newer versions please refer to the chapter about using resize(). The versions are not backwards compatible.
If you would like to generate a thumbnail for an image, you can call the method thumbnail() after a successful upload. The thumbnail() method takes an array of options as an argument, the options are: width, height, quality, append (what text should be appended to the filename, will be auto-generated if left blank).
If you would like to generate a thumbnail for an image, you can call the method thumbnail() after a successful upload. The thumbnail() method takes an array of options as an argument, the options are: width, height, quality, append (what text should be appended to the filename, will be auto-generated if left blank).
if ($data = $this->Uploader->upload($this->data['Model']['upload'])) { $thumb = $this->Uploader->thumbnail(array('width' => 100, 'height' => 100, 'append' => 'thumb_small')); // Now $thumb and $data both have their respective uploaded info }