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. Run
  6. Output
  7. Conclusion

1. Enable CSRF

  • Open .env file.
  • Remove # from the start of the 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 in '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 file upload view.
    • page/fileUpload – It is used to upload a 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 selected file of Dropzone.

Define file validation. I set the max file size to 2 MB (2048 Kb).

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

If the file is not validated then assign 0 to $data['success'] and validation response to $data['error'].

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. Run

  • Navigate to the project using Command Prompt if you are on Windows or terminal if you are on Mac or Linux, and
  • Execute “php spark serve” command.
php spark serve
  • Run http://localhost:8080 in the web browser.

6. Output

View Output


7. 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.

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

Leave a Comment