A file uploader and thumbnailer component for CakePHP 1.3 and 2.


Attachment component for CakePHP handles file uploads to the file system. If
it’s an image file, it creates thumbnail copies in
/app/webroot/attachments/photos/{required_sizes} folder; while other files
are stored in /app/webroot/attachments/files.

I’ve started it from the public copy at
to have a standard way of uploading files to CakePHP projects.

See branch cake1.3 for Cake 1.3 version; branch cake2 for CakePHP 2 version.


  1. PHP GD library installed and enabled.
  2. /app/webroot/attachments/ must be writable by the web server.


  1. Copy attachment.php to /app/controllers/components/
  2. Add component to your controller: var $components = array('Attachment');
  3. Add DB columns {prefix}_file_path, {prefix}_file_name, {prefix}_file_size
    and {prefix}_content_type to the model. The prefix is the model name, in
    lowercase, words seperated by underscores.

Model setup

We’ll asume a Model named ‘Pet’ for a sample installation. The code relies on
four columns in the Model table:

pet_file_path, pet_file_name, pet_file_size and pet_content_type

Models with multi-word names should have each word seperated by underscores.
For example, the model “GalleryPhoto” would use the table “gallery_photos” and
the following fields:

gallery_photo_file_path, gallery_photo_file_name, gallery_photo_file_size and gallery_photo_content_type

These fields are automagically updated when you call save() on the $this->data array

View setup

On forms

<?= $this->Form->create('Pet', array('type' => 'file'));
<?= $this->Form->input('pet' , array('type' => 'file')); ?>
<?= $this->Form->end('Save my pooch'); ?>

The (file) input ‘pet’ is the lower case model-name, multi-word model names
seperated by underscores.

Show files (after they are saved)

For images: <?= $this->Html->image('/attachments/files_dir/{size}/' . $data['Pet']['pet_file_path']); ?>
For files: <?= $this->Html->link('Grab file', '/attachments/files_dir/' . $data['Pet']['pet_file_path']); ?>

Controller setup

Configuration options (default values between parentheses):

  • files_dir: Where to save the files (inside /app/webroot/attachments/) (photos).
  • rm_tmp_file: Remove temporal image after resizing (false).
  • allow_non_image_files, self descriptive ;-) (true).
  • default_col: Column prefix for file related data (lowercase modelname, words seperated by underscores).
  • images_size: Array of different file sizes required by your app. Each
    element is itself an array, like: 'folder_name' => array($width, $height, $crop).
    (You may define only width or height, and the image will scale appropriately).

You can override the default configuration passing an array of options while
including the component, like:

var $components = array('Attachment' => array( 'files_dir' => 'pets', 'images_size' => array( 'avatar' => array(75, 75, 'resizeCrop') ) ));

Controller methods:


  • data: Raw data from form.

Simply call the following on the form data:


You may choose different column prefixes than the model name, as long as you
specify it on the upload method, like so:

$this->Attachment->upload($this->data['Pet'], 'dog');

thumbnail($data, $upload_dir, $maxw, $maxh, $crop = ‘resize’)

Used by the more general upload method.

  • data: image data array
  • upload_dir: where to save the file (inside attachments/files_dir)
  • maxw/maxh: maximum width/height for resizing images
  • crop: Crop image? (one of resize, resizeCrop or crop)


  • filename: file-to-delete name


You may wish to validate from the model. e.g:

var $validate = array(
'pet_file_size' => array(
'rule' => array('maxLength', 6),
'message' => 'Image size is waaaaaayyy too big. Try resizing first'

Show validation errors in the view

if(isset($this->Form->validationErrors)) {
foreach ($this->Form->validationErrors as $model => $columns) {
foreach ($columns as $err_msg) {
echo $this->Html->div('error-message', $err_msg);

Only for the file input:

if (isset($this->Form->validationErrors['Pet']['pet_file_name'])) {
echo $this->Html->div('error-message', $this->Form->validationErrors['Pet']['pet_file_name']);