CakePHP file upload validation

If you want to achieve file upload validation trough your CakePHP model, you can use the following code. For this tutorial I you have a database table with a field ‘pdf_path’ (of course, this can be anything you like).

First create a form input field using the CakePHP FormHelper class in your view file

<?php
echo $this->Form->create('Course', array( 'type' => 'file'));
echo $this->Form->input('pdf_path', array('type' => 'file','label' => 'Pdf'));
echo $this->Form->end('Upload file'); 
?>
PHP

Now set the validate array in your model.  I will put two validation rules

  1. Validate the extension of the file (if you want multiple extensions, just fill up the array)
  2. Validate against a custom validation function. The name of the function is the name you pass into the array. In this case this is ‘uploadFile’.
public $validate = array(
'pdf_path' => array(
    'extension' => array(
        'rule' => array('extension', array('pdf')),
        'message' => 'Only pdf files',
         ),
     'upload-file' => array(
        'rule' => array('uploadFile'),
        'message' => 'Error uploading file'
         )
)
);
PHP

Now you just have to write the code to validate your upload and if everything goes according to plan, you can upload your file.

public function uploadFile( $check ) {

    $uploadData = array_shift($check);

    if ( $uploadData['size'] == 0 || $uploadData['error'] !== 0) {
        return false;
    }

    $uploadFolder = 'files'. DS .'your_directory';
    $fileName = time() . '.pdf';
    $uploadPath =  $uploadFolder . DS . $fileName;

    if( !file_exists($uploadFolder) ){
        mkdir($uploadFolder);
    }

    if (move_uploaded_file($uploadData['tmp_name'], $uploadPath)) {
        $this->set('pdf_path', $fileName);
        return true;
    }

    return false;
}
PHP

First I shift the array, so we can easily access the data from our POST request. Then I do some basic checks (you can extend these to your needs if you want better validation errors, but for the sake of not making this post to long … :)).

If we don’t find any errors, I create the path (this is relative to the webroot directory) and a unique file name.  You can generate a UDID or whatever you want, but time() will do the job just fine. Then we check if the folder exists, and if it doesn’t you create it.

Now we just need to move the file from its temporary directory on the server to its final destination.  Afterwards I set the pdf_path key in my model to the correct filename, so it will be saved in the database.

Then you can return true and the validation will be ok, or return false and then the error message will be shown.

Share this post

9 Responses

  1. Great article,

    I’m beggining in php, and this article hepled me.
    Only one thing, if I use more extensions like array(‘pdf’, ‘jpg’..) then in the uploadFile function how use this part:

    $fileName = time() . ‘.pdf’;

    Thanks and sorry for my english

  2. it works like a charm but there is a issue.
    if any other field failed on validation.
    Delete the file is missing(It makes the duplication of file until the validation success)

  3. @jordi verda,

    I replaced it like this:
    $fileName = time() . ‘-‘ . basename($uploadData[‘name’]);
    This appends the original filename to the time, and you still get the extension at the end. Careful with that though.

  4. Do I have to change anything in the code? I tried to copy + paste everything but it’s not working.

  5. Hi!, nice work, this work fine for my, even in the version 3.5 with some modifications. My question is how can i set the “pdf_path” name in the 3.5v, with Tables and Entities, thanks you in advance.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts