0

I am working on a Social Network application with Codeigniter 3, Ion-Auth and Bootstrap 4. You can see the Github repo HERE.

Update

I now have:

if ($this->form_validation->run() === TRUE)
    {
        //more code here

        $config['upload_path'] = './assets/img/avatars';
        $config['file_ext_tolower']     = TRUE;
        $config['allowed_types']        = 'gif|jpg|jpeg|png';
        $config['max_size']             = 1024;
        $config['max_width']            = 1024;
        $config['max_height']           = 1024;
        $config['encrypt_name']         = TRUE;
        $this->load->library('upload', $config);

        if (!$this->upload->do_upload('userfile')){
            $error = array('error' => $this->upload->display_errors());
            $file_name = null;
        } else {
            $file_name = $this->upload->data('file_name');
        }

        $additional_data = [
            'first_name' => $this->input->post('first_name'),
            'last_name' => $this->input->post('last_name'),
            'avatar' =>  $file_name,
            'company' => $this->input->post('company'),
            'phone' => $this->input->post('phone'),
        ];
}

The code above correctly hashes the filename before inserting it in the avatarcolumn, but the upload itself never happens.

Original code

I am uploading a user image (avatar) with the code below:

if ($this->form_validation->run() === TRUE)
    {
        //more code here

        $config['upload_path'] = './assets/img/avatars';
        $config['file_ext_tolower']     = TRUE;
        $config['allowed_types']        = 'gif|jpg|jpeg|png';
        $config['max_size']             = 1024;
        $config['max_width']            = 1024;
        $config['max_height']           = 1024;
        $this->load->library('upload', $config);

        if (!$this->upload->do_upload('userfile')){
            $error = array('error' => $this->upload->display_errors());
            $file_name = null;
        } else {
            // get filename with extension
            $file_name = $_FILES['userfile']['name'];
            // get filename without extension
            $file_name_clean = explode('.', $file_name)[0];
            // get filename extension   
            $file_ext = explode('.', $file_name)[1];
            //Add timestamp to filename and hash it
            $file_name = md5($file_name.date('m-d-Y_H:i:s'));
            // add extension
            $file_name = $file_name_clean . '.' . $file_ext;
        }

        $additional_data = [
            'first_name' => $this->input->post('first_name'),
            'last_name' => $this->input->post('last_name'),
            'avatar' =>  $file_name,
            'company' => $this->input->post('company'),
            'phone' => $this->input->post('phone'),
        ];
}

As you can see in the else block, I am changing the original filename by adding it the current timestamp and hashing.

The problem is that the image file itself is not renamed accordingly before the upload. It is uploaded with the original name (the image is not stored in /assets/img/avatars/).

Why does that happen?

Razvan Zamfir
  • 4,209
  • 6
  • 38
  • 252
  • 1
    What happens in the posted code is this: The server gets a request with the file contents. The file contents gets stored in a temp folder (PHP automatically does this for you). This code is then executed, where you run `$this->upload->do_upload('userfile')`, which basically checks the file and moves it from the temp folder to the configured `upload_path`-folder. If the file was successfully moved (the upload is done), you generate a new filename in a new variable which you only put in an array. Why would you expect that to change the actual file name? – M. Eriksson Sep 02 '20 at 13:25
  • it happens because the actual file is uploaded as soon as you run `$this->upload->do_upload('userfile')`. What you're doing afterwards with the `$file_name` variable is just transforming the filename for use with that variable, you are not actually renaming the file. To actually rename the file, I recommend you look into PHP's `rename()` function which is described [HERE](https://www.php.net/manual/en/function.rename.php) – Javier Larroulet Sep 02 '20 at 13:27
  • If you want it to save the file with a custom name, you should generate the file name _before_ you run `->do_upload()` and then set the new name in the config array: `$config['file_name'] = $your_new_name;`. [Here's the manual](https://codeigniter.com/userguide3/libraries/file_uploading.html#preferences) about what you can configure for the upload. – M. Eriksson Sep 02 '20 at 13:29
  • @MagnusEriksson Yes, that makes sense. – Razvan Zamfir Sep 02 '20 at 13:47
  • check this https://stackoverflow.com/questions/18705639/how-to-rename-uploaded-file-before-saving-it-into-a-directory – Ashok Sep 02 '20 at 14:20
  • @Ashok I added this line to the configuration: `$config['encrypt_name'] = TRUE`. Now the file name is hashed, but the original filename is inserted in the **users** table. – Razvan Zamfir Sep 02 '20 at 14:37

3 Answers3

2

if Use UPLOAD library

$config['encrypt_name']         = TRUE;

Don't use $_FILES

Change

$file_name = $_FILES['userfile']['name'];

To

$file_name = $this->upload->data('file_name');

And config.php Add directly your path

$config['base_url'] = "http://localhost/yourname/";
Ashok
  • 346
  • 1
  • 8
1

Try this,

$config['upload_path'] = './assets/img/avatars';
$config['file_ext_tolower']     = TRUE;
$config['allowed_types']        = 'gif|jpg|jpeg|png';
$config['max_size']             = 1024;
$config['max_width']            = 1024;
$config['max_height']           = 1024;
$config['file_name']           = "Your Encrypted Name.ext";//add this to your code and try
$this->load->library('upload', $config);
M.Hemant
  • 2,345
  • 1
  • 9
  • 14
1

Here is how the final version looks:

At the top of the Auth class I added the $file_name variable:

//upload file
public $file_name = null;

I created a reusable upload method:

public function upload_avatar(){
    $config['upload_path'] = './assets/img/avatars';
    $config['file_ext_tolower']     = TRUE;
    $config['allowed_types']        = 'gif|jpg|jpeg|png';
    $config['max_size']             = 1024;
    $config['max_width']            = 1024;
    $config['max_height']           = 1024;
    $config['encrypt_name']         = TRUE;
    $this->upload->initialize($config); 

    if (!$this->upload->do_upload('userfile')){
        $error = array('error' => $this->upload->display_errors());
    } else {
        $this->file_name = $this->upload->data('file_name');
    }
}

I use this method inside the create_user() and edit_user($id) methods:

$this->upload_avatar();

Then I add the avatar in the $additional_data and $data arrays, of the two methods:

$additional_data = [
    //more code
    'avatar' =>  $this->file_name,
    //more code
];

and

$data = [
    //more code
    'avatar' =>  $this->file_name,
    //more code
]

See the GitHub commit HERE.

Many thanks to all those who helped.

Razvan Zamfir
  • 4,209
  • 6
  • 38
  • 252