Write your own Codeigniter4 File Upload Class.

Codeigniter3 provides a File Uploading class functionality to upload and validate files with ease.

$config['upload_path'] = './uploads/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size']     = '100';
$config['max_width'] = '1024';
$config['max_height'] = '768';

$this->load->library('upload', $config);


This does not exist under Codeignter4.
This posed a problem when migrating my project from CI3 to CI4.
So I had to write my own Upload Model that imitates the similar functions.

Below is the sample Upload model with a few functions that was needed for my use case.

<?php namespace App\Models;

use CodeIgniter\Model;
use CodeIgniter\Files\File;

class UploadModel extends Model{
    protected $config = array();
    function __construct($config) {
        $this->validationRules = array();
        $this->data = array(); //uploaded file info
        $this->errors = array();
	$this->config = $config;
        $this->filedata = array();
        $this->request = \Config\Services::request();	
    }

    function setValidation($rules){
        $this->validationRules = $rules;
    }

    function do_upload($fileField = "userfile"){
        $file = $this->request->getFile($fileField);
        if (!$file->hasMoved()) {
            if ($file->isValid() && empty($this->errors)) {

                $newName = $file->getName();
                $filepath = FCPATH . $this->config['upload_path'];  //You can give any writable path here
                $file->move($filepath);

                $fullpath = $filepath."/".$newName;
                $this->setData($file,$fullpath);
                return true;
            }
        }else{
            $this->errors['error'] = "File already moved. Please reupload.";
            return false;
        }
        return false;
    }

    //get all upload errors.
    function display_errors(){
        foreach($this->errors as $k=>$v){
            echo "\n $v";
        }
    }

    function setData($file,$fullpath){
        $this->data = array();
        $pathInfo = pathinfo($fullpath);
        
        $this->data['file_name'] = $pathInfo['basename'];
        //$this->data['file_type'] = $file->getMimeType();

        $this->data['file_path'] = $pathInfo['dirname']; 

        $this->data['full_path'] = $fullpath; 
        $this->data['raw_name'] = $file->getBasename();

        $this->data['orig_name'] = $file->getBasename();
        $this->data['client_name'] = $file->getClientName(); 
        $this->data['file_ext'] = $file->getClientExtension();
        $this->data['file_size'] = $file->getSize();
        
    }

    function data(){
        return $this->data;
    }
}

The method data() returns only some fields unlike Codeigniter3 which has extra fields like is_image, image_width, image_height, image_type, image_size_str.
The display_errors() method also returns the validation errors for the uploaded file.

For CI4, the upload file rules and config can be used as below in your controller.

//initialize the upload Model Object with a configuration
$config['upload_path'] = './images/user'; //give the directory path
$upload = new UploadModel($config);

//set validation rules
$rules = [
	'uploaded[file]',
	'is_image[file]',
	'mime_in[file,image/jpg,image/jpeg,image/gif,image/png,image/webp]',
	'max_size[file,10000000]',
];

$upload->setValidation($rules);
$this->runValidation($upload);

if(count($upload->errors) == 0){
   if ( ! $upload->do_upload('file')){ //file parameter is the upload field name from form UI
	$errors = array();
	$errors['file']=$upload->display_errors();
   }
}

In your same Controller you can define the runValidation method as below:

/*for upload file validations */
function runValidation($uploadObj){
    if (!$this->validate($uploadObj->validationRules)) {
        $uploadObj->errors = $this->validator->getErrors();
    }
}

$upload->display_errors() will print all the error messages if the validations failed.

Leave a Reply