Uploading Multiple Files in CakePHP


THIS WORKS WITH CAKE 2.x

There are many plugins available in the internet for attaching files.

This custom made script will give you idea on how to attach multiple files. In this script we have a model Attachment and Document. Attachment model saves all information of the file while Document is just an add-on if you have model related to your attachment. If none, then just omit it and it should still run well.

First in the Attachments view "index.ctp" we will create a form that will look for files. 

<?php

echo $this->Form->create('Attachment',array('type'=>'file'));

echo $this->Form->input('filename.', array('type'=>'file','multiple'));

echo $this->Form->end('Attach');

?>

In the same view we create our table that will display all attached files.



<table>

    <tr>

        <th>Filename</th><br />

    </tr>

    <!-- Here is where we loop through our $posts array, printing out post info -->

    <?php foreach ($attachments as $attachment): ?>

        <tr>

            <td>

                <?php echo $attachment['Attachment']['filename']; ?>

                <?php //echo $document['Document']['control'];  ?>

            </td>

        </tr>

    <?php endforeach; ?>

    <?php unset($attachment); ?>

</table>

Next in our AttachmentsController we need to add the File and Folder classes. You might as well create the index function as well.

App::uses('Folder', 'Utility');

App::uses('File', 'Utility');


 class AttachmentsController extends AppController{

        public $helpers = array('Html', 'Form', 'Session');

        public $components = array('Session');



        public function index($id = null){



        }

}

The purpose of the parameter is that I want to get additional information in my Document model such as ID and save it to my Attachment's table so that I can identify which attachments belongs to a certain document. Inside the index function add the following code. Just follow along the comments to further understand in.



$this->loadModel("Document");
$control = $this->Document->findById($id);
$this->Session->write('link',$id);

$dir = new Folder();

//check if directory where file be uploaded exist, if not will create it. the folder will be created inside the APP/uploads

$folder_path = APP.DS.'uploads';

if(!is_dir($folder_path)){
    $dir->create(APP.DS.'uploads' );
}

//instantiate the folder
$dir = new Folder(APP.DS.'uploads');

if(isset($this->request->data['Attachment'])){
    $attachment = $this->request->data['Attachment'];
    //count number of files in the directory
    $files = $dir->findRecursive($control['Document']['control'].'.*', true);
    $file_count = count($files);
    //We loop through files and individually save it to the database.
    for($x=0;$x<count($attachment['filename']);$x++){
         $file_count = $file_count+1;
         //getting temp name
         $filename = $attachment['filename'][$x]['tmp_name'];
         //getting extension
         $extension = pathinfo($attachment['filename'][$x]['name'],PATHINFO_EXTENSION);
         //setting new name
         $attachment['filename'][$x]['name'] = $control['Document']['control'].'-'.$file_count."-".$attachment['filename'][$x]['name'];
         //store path
         $filePath = APP . 'uploads' .DS.$attachment['filename'][$x]['name'];
         if (move_uploaded_file($filename, $filePath))
         {
         //SAVE it to the database
              if (!$id) {
                  throw new NotFoundException(__('Invalid post'));
              }
              if ($this->request->is('post')) {
                   $this->request->data['Attachment']['filename'] = $attachment['filename'][$x]['name'];
                   $this->request->data['Attachment']['document_id'] = $id;
                   $this->request->data['Attachment']['user_id'] = $this->Auth->user('id');
                   $this->Attachment->create();
                   if ($this->Attachment->save($this->request->data)) {
                        // $this->Session->setFlash(__('Your post has been saved.'));
                   } else {
                         $this->Session->setFlash(__('Unable to add your post.'));
                   }
         }
         $this->Session->setFlash('Uploaded file has been moved SUCCESSFULLY.');
         }else{
             $this->Session->setFlash('Uploaded file has been DENIED.');
         }
     }
      $this->redirect($this->referer());
}
//SHOW in TABLE
$data = $this->Attachment->find('all',array('conditions'=>array('document_id'=>$id)));
$this->set('attachments',$data);
That's it, if you follow along, you should be able to run it well.

For downloading of the uploaded files click here: Downloading Files in CakePHP

Labels: , , ,