Drag and Drop file upload with Dropzone in CodeIgniter 4

Dropzone makes file upload implementation easier. It allows uploading files by directly drag and drop on the Dropzone container.

Displays a preview after the image file upload.

In this tutorial, I show how you can create drag and drop file upload using Dropzone.js in CodeIgniter 4.

Drag and Drop file upload with Dropzone in CodeIgniter 4


Contents

  1. Enable CSRF
  2. Route
  3. Controller
  4. View
  5. Output
  6. Conclusion

1. Enable CSRF

  • Open .env file.
  • Remove # from the start of security.tokenName, security.headerName, security.cookieName, security.expires, and security.regenerate.
  • Using security.tokenName read CSRF hash. You can update it with any other value.
# security.csrfProtection = 'cookie'
# security.tokenRandomize = false
security.tokenName = 'csrf_token_name'
security.headerName = 'X-CSRF-TOKEN'
security.cookieName = 'csrf_cookie_name'
security.expires = 7200
security.regenerate = true
# security.redirect = true
# security.samesite = 'Lax'
  • Open app/Config/Filters.php file.
  • Uncomment 'csrf' in 'before' if commented.
public $globals = [
    'before' => [
        // 'honeypot',
        'csrf',
        // 'invalidchars',
     ],
     'after' => [
        'toolbar',
        // 'honeypot',
        // 'secureheaders',
     ],
];

2. Route

  • Open app/Config/Routes.php file.
  • Define 2 routes –
    • / – Display dropzone file upload view.
    • page/fileUpload – It is used to upload dropzone selected file.

Completed Code

$routes->get('/', 'PageController::index');
$routes->post('page/fileUpload', 'PageController::fileUpload');

3. Controller

  • Create PageController Controller –
php spark make:controller PageController
  • Open app/Controllers/PageController.php file.
  • Create 2 methods –
    • index() – Load index view.
    • fileUpload() – This method is used to upload the dropzone selected file.

Define file validation. I set the max file size to 2 MB (2048 Kb) and valid file extensions – jpeg,jpg,png,pdf.

NOTE – File validation is same as defined while initializing Dropzone.

Assign 0 to $data['success'] and validation response to $data['error'] if the file is not validated.

If file is validated successfully then upload the file to "uploads" location. Assign 1 to $data['success'] and assign Uploaded Successfully! to $data['message'].

Return $data Array in JSON format.

Completed Code

<?php 
namespace App\Controllers;
use App\Controllers\BaseController;

class PageController extends BaseController{

   public function index(){
      return view('index');
   }

   public function fileUpload(){

      $data = array();

      // Read new token and assign to $data['token']
      $data['token'] = csrf_hash();

      ## Validation
      $validation = \Config\Services::validation();

      $input = $validation->setRules([
         'file' => 'uploaded[file]|max_size[file,2048]|ext_in[file,jpeg,jpg,png,pdf],'
      ]);

      if ($validation->withRequest($this->request)->run() == FALSE){

          $data['success'] = 0;
          $data['error'] = $validation->getError('file');// Error response

      }else{

          if($file = $this->request->getFile('file')) {
             if ($file->isValid() && ! $file->hasMoved()) {
                // Get file name and extension
                $name = $file->getName();
                $ext = $file->getClientExtension();

                // Get random file name
                $newName = $file->getRandomName();

                // Store file in public/uploads/ folder
                $file->move('../public/uploads', $newName);

                // Response
                $data['success'] = 1;
                $data['message'] = 'Uploaded Successfully!';

             }else{
                // Response
                $data['success'] = 2;
                $data['message'] = 'File not uploaded.'; 
             }
          }else{
             // Response
             $data['success'] = 2;
             $data['message'] = 'File not uploaded.';
          }
      }
      return $this->response->setJSON($data);

   }

}

4. View

Create index.php file in app/Views/.

Include Dropzone and jQuery library.

You can download Dropzone from here or you can use CDN –

<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/min/dropzone.min.css" type="text/css" />
<script src="https://unpkg.com/[email protected]/dist/min/dropzone.min.js"></script>

Create a hidden element to store CSRF token name specified in .env file in the name attribute and store CSRF hash in the value attribute.

<input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />

Create <form action="<?=site_url('page/fileUpload')?>", class='dropzone' ></form> to initialize Dropzone.

Script

  • Disable dropzone autoDiscover – Dropzone.autoDiscover = false and initialize Dropzone on class="dropzone".
  • Set max upload filesize to 2 MB and valid file extensions – “.jpeg,.jpg,.png,.pdf”.
  • With Dropzone sending event send CSRF token – formData.append(csrfName, csrfHash);.
  • Using success event update token hash and check return response.
  • If response.status == 0 means there is an error and if response.status == 2 means file is not uploaded. Display error message using alert().

Completed Code

<!doctype html>
<html>
<head>
   <title>Drag and Drop file upload with Dropzone in CodeIgniter 4</title>

   <!-- CSS -->
   <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/min/dropzone.min.css" type="text/css" />

   <!-- Script -->
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
   <script src="https://unpkg.com/[email protected]/dist/min/dropzone.min.js"></script>

</head>
<body>

   <!-- CSRF token --> 
   <input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />

   <div class='content'>
      <!-- Dropzone -->
      <form action="<?=site_url('page/fileUpload')?>", class='dropzone' ></form> 
   </div>

   <!-- Script -->
   <script>

   Dropzone.autoDiscover = false;
   var myDropzone = new Dropzone(".dropzone",{ 
      maxFilesize: 2, // 2 mb
      acceptedFiles: ".jpeg,.jpg,.png,.pdf",
   });
   myDropzone.on("sending", function(file, xhr, formData) {
      // CSRF Hash
      var csrfName = $('.txt_csrfname').attr('name'); // CSRF Token name
      var csrfHash = $('.txt_csrfname').val(); // CSRF hash

      formData.append(csrfName, csrfHash);
   }); 
   myDropzone.on("success", function(file, response) {
      $('.txt_csrfname').val(response.token);
      if(response.success == 0){ // Error
         alert(response.error);
      }
      if(response.success == 2){
         alert(response.message);
      }

   });
   </script>

</body>
</html>

5. Output

View Output


6. Conclusion

It is always better to again validate before uploading the file. Update Dropzone validation according to your requirement.

Remove CSRF token steps if CSRF is disabled on your project.

View this tutorial to know how you can display uploaded files after page reload in Dropzone.

If you found this tutorial helpful then don't forget to share.

Leave a Comment