Uploading a file to a custom path in codeigniter - php

I'm trying to upload a file but I keep getting a "The upload path does not appear to be valid." error. The problem is the path I'm trying to upload to is in the directory just outside the current one. The current folder structure is as follows:
application
assets
- uploads
- profile_pictures
Admin
- application
- assets
I am attempting to upload a picture from the admin application into the 'assets/uploads/profile_pictures' folder which is in the main application root directory. The only issue is correcting the path.
Here's the code from the Controller:
public function update_image(){
$user_id= $this->input->post('user_id');
//$user_id=$this->input->post('user_id');
$query5 = $this->db->get_where('user_details', array('user_id' => $user_id));
$name_user = $query5->row()->name;
$name='profile_image_edit';
$user_img=$this->function->upload_profile_images(array($name), $name_user);
var_dump($user_img);
$this->db->set("image_path",$user_img);
$this->db->where("user_id",$user_id);
$update = $this->db->update("users");
if($update)
{
echo 'Profile Image Updated.';
}
else
{
echo 'Profile Image Update Failed.';
}
}
And here's the code from the Model:
public function upload_profile_images($names, $username)
{
$config['upload_path']='./assets/uploads/profile_pictures';
$config['allowed_types']='jpeg|jpg|png';
$path = $_FILES[$names[0]]['name'];
var_dump($names[0]);
var_dump($path);
$ste_d =date('YmdHis') . gettimeofday()['usec'];
$newName = str_replace("",'',str_replace("",'',"$ste_d.str_replace(" ",'_',str_replace(".","",pathinfo($path, PATHINFO_FILENAME)))."_muddy.")).pathinfo($path, PATHINFO_EXTENSION);
$config['file_name'] = $username ."_". $newName;
$this->upload->initialize($config);
$this->load->library('upload', $config['upload_path']);
$check = true;
for($i = 0; $i < count($names) && $check; $i++)
{
if ( ! $this->upload->do_upload($names[$i]))
{
$path='./assets/uploads/profile_pictures';
$this->load->helper("file");
$error = array('error' => $this->upload->display_errors());
var_dump($error);
// delete_files($path, true);
$check = false;
return false;
}
else
{
$data = array('upload_data' => $this->upload->data());
$check = true;
return 'assets/uploads/profile_pictures'.'/'.$data['upload_data']['file_name'];
}
}
}
How do I set a custom path so the file is always saved in the desired directory of assets/uploads/profile_pictures from the Admin application. Thanks for any help!

Related

How to set 755 permissions in php after creating folder in the existing folder

I have a following code in the Codeigniter controller to upload some files to "upload" folder in the remote ubuntu server. In this case there is created a new folder named as officer_id in the upload folder when upload files and should be applied 755 permissions to it. Otherwise rejected to upload the files.
public function addFiles()
{
$this->checkPermissions('add', 'officer');
$bc = array(array('link' => '#', 'page' => 'Attachments'));
$meta = array('page_title' => 'Officers - Files', 'bc' => $bc);
$this->data['officer'] = $this->Officer_model->getOfficer();
$this->form_validation->set_rules('officer', "Officer", 'required');
if ($this->form_validation->run() == true) {
$files = $this->multi_upload($_FILES['file'], './uploads/' . $this->input->post('officer'));
if (!empty($files)) {
foreach ($files as $fname) {
$fdata[] = array(
'officer' => $this->input->post('officer'),
'file_name' => $fname,
'status' => 1,
);
}
if ($this->db->insert_batch('tbl_officer_files', $fdata)) {
$this->session->set_flashdata('message', 'Officer Attachments Updated Successfully ..!!');
redirect('officer/addFiles');
} else {
$this->session->set_flashdata('message', 'Officer Attachments Updation Failed ..!!');
redirect('officer/addFiles');
}
}
}
$this->render('officer/addFiles', $meta, $this->data);
}
public function saveUpload()
{
$this->multi_upload($_FILES['file']);
if ($this->upload->do_upload('file')) {
$data = array('upload_data' => $this->upload->data());
$inputFileName = './uploads/' . $data['upload_data']['file_name'];
echo json_encode(array('success' => 'Files have been uploaded successfuly ..!!'));
} else {
$error = array('error' => $this->upload->display_errors());
echo json_encode($error);//array('error' => 'You are not allowed to upload such a file.',
}
}
How can I modified my code to enable this (Like chmod ......) ? Can anyone help ?
You can use chmod("test.txt",0755); to update the permission on file after uploading.
You can do this step by step as follow.
//this function returns uploaded file path
$uploadedd_file = file_upload_function(...);
if(!file_exists($uploadedd_file)){
die('Error in uploading file');
}
// Setting file permission
$set_permission = chmod($uploadedd_file,0755);
if(!$set_permission){
// delete file if permission is not set
unlink($uploadedd_file);
}
// optional step to validate
$new_permission = substr(sprintf('%o', fileperms($uploadedd_file)), -4);
echo "all good goes here, file uploaded and permission is set to " . $new_permission;
Read more about chmod: https://www.w3schools.com/php/func_filesystem_chmod.asp
https://www.php.net/manual/en/function.chmod.php
I hope this works, let me know.

How to delete old file from the folder while updating?

I want to delete the old file from the folder ie, if I update an image the old one remains as it is in the folder and a new one is get uploaded.
Here updating is done fine but after frequent updating number of files is increasing .
This is the code for selecting the content from the database and also for updating
public function select_testimonials($id)
{
$this->session->set_userdata('id',$id );
$query = $this->cl_testimonials_model->select($id);
$data1['selectdata'] = $query->result();
// $this->index();
$query = $this->db->get("cl_testimonials");
$data1['records'] = $query->result();
$this->load->view('admin/testimonials/testimonials_edit',$data1);
}
public function update_testimonials()
{
$id = $this->input->post("id");
if ($this->input->post('submit')=="update")
{
if(!empty($_FILES['picture']['name']))
{
$config['upload_path'] = 'uploads/images/testimonials';
$config['allowed_types'] = 'jpg|jpeg|png|gif';
$config['file_name'] = $_FILES['picture']['name'];
//Load upload library and initialize configuration
$this->load->library('upload',$config);
$this->upload->initialize($config);
if($this->upload->do_upload('picture'))
{
$uploadData = $this->upload->data();
$picture = $uploadData['file_name'];
}
}
//Prepare array of user data
$data = array('name' => $this->input->post('name'),'content' => $this->input->post('content'),'picture' => $picture);
//Pass user data to model
$insertUserData = $this->cl_testimonials_model->update($id,$data);
}
//Storing insertion status message.
if(isset($insertUserData))
{
$data['message']="* testimonials updated successfully.";
}
else
{
$data['message']="* Some problems occured, please try again.";
}
$query = $this->db->get("cl_testimonials");
$data['records'] = $query->result();
$this->load->view('admin/testimonials/testimonials_listing',$data);
}
Fetch Existing testimonial picture path by id, update, then use unlink('old file path')
More here : Here
Use the unlink(); function in php. it is applicable also in Codeigniter.
unlink("target path/".$file name);

Is there a better way of multipart/form-data validation

I have a multipart/form-data with an image upload and some personal data, so I want to include file upload in form validation, I can successfully do this.
However, I now find that there is an issue, ie even if my other form fields have errors and upload file field with no error, then image uploads to folder, how to prevent this, I mean, in my case, If name, email, file fields validation is ok then only file should upload, if name filed validation fails and file field validation ok then file should not upload
here is the code I use:
In Controller:
<?php
public $_rules = array(
'name'=>array('field'=>'name', 'label'=>'Name', 'rules'=>'trim|required'),
'email'=>array('field'=>'email', 'label'=>'Email', 'rules'=>'trim|required|valid_email'),
'profile_img'=>array('field'=>'profile_img', 'label'=>'Design', 'rules'=>'callback__profile_upload')
);
public function profile()
{
$this->load->library('upload');
$rules = $this->_rules;
$this->form_validation->set_rules($rules);
if($this->form_validation->run()==TRUE){
die('success');
}else {
$this->data['content'] = 'frontend/pages/place_order';
$this->load->view('frontend/_layout_main', $this->data);
}
}
function _profile_upload(){
if($_FILES['profile_img']['size'] != 0 && !empty($_FILES['profile_img']) ){
$upload_dir = './profile_pics/';
if (!is_dir($upload_dir)) {
mkdir($upload_dir);
}
$config['upload_path'] = $upload_dir;
$config['allowed_types'] = 'gif|jpg|png|jpeg';
$config['file_name'] = 'profile_img_'.substr(md5(rand()),0,7);
$config['overwrite'] = false;
$config['max_size'] = '5120';
$this->upload->initialize($config);
if (!$this->upload->do_upload('profile_img')){
$this->form_validation->set_message('_profile_upload', $this->upload->display_errors());
return false;
}
else{
$this->upload_data['file'] = $this->upload->data();
return true;
}
}
else{
$this->form_validation->set_message('_profile_upload', "No file selected");
return false;
}
}
IN VIEW:
<?php echo form_open_multipart();?>
<?php $name_err = (!empty(form_error('name'))) ? 'err' : ' ';
echo form_input('name',set_value('name'), array('placeholder'=>'Name','class'=>" {$name_err } "));
?>
<?php $email_err = (!empty(form_error('email'))) ? 'err' : ' ';
echo form_input('email',set_value('email'), array('placeholder'=>'EMail','class'=>" {$email_err } "));
?>
<?php
echo form_error('profile_img');
echo form_upload(array('name' =>'profile_img', 'class' => 'inputfile inputfile-4', 'id' => 'profile_img'));
?>
<li><input type="submit" class="special" value="Submit" /></li>
Try once like this.I think for images not need to set rules like other fields.
public $_rules = array(
'name'=>array('field'=>'name', 'label'=>'Name', 'rules'=>'trim|required'),
'email'=>array('field'=>'email', 'label'=>'Email', 'rules'=>'trim|required|valid_email'),
);
And
public function profile()
{
$this->load->library('upload');
$rules = $this->_rules;
$this->form_validation->set_rules($rules);
if($this->form_validation->run()==TRUE){
die('success');
}else {
if ($this->_profile_upload()) { //return true if file uploaded successfully otherwise error
$this->data['content'] = 'frontend/pages/place_order';
$this->load->view('frontend/_layout_main', $this->data);
}
}
}
yes that is very obvious that your file get uploads even any other fields' validation failed. You have to initiate image uploading only after form validation success.
For that simply validate file specific requirement in that callback, and do actual uploads after successful form validation.
I have got a solution from codexWorld, I have asked same question over there, and they replied with a tutorial, If anybody still looking for a solution here is the link
http://www.codexworld.com/codeigniter-file-upload-validation/
in the validation call back, we just want to do the file type check
public function _profile_upload($str){
$allowed_mime_type_arr = array('image/jpeg','image/pjpeg','image/png','image/x-png');
$mime = get_mime_by_extension($_FILES['file']['name']);
if(isset($_FILES['file']['name']) && $_FILES['file']['name']!=""){
if(in_array($mime, $allowed_mime_type_arr)){
return true;
}else{
$this->form_validation->set_message('_profile_upload', 'Please select only pdf/gif/jpg/png file.');
return false;
}
}else{
$this->form_validation->set_message('_profile_upload', 'Please choose a file to upload.');
return false;
}
}
and in the main function we just want to do the same as normal, using do_upload and specifying the upload config items, anyhow there will be a second file type check when the function executes, I think that doesn't matter. The code will look like this::
public function profile()
{
$rules = $this->_rules;
$this->form_validation->set_rules($rules);
if($this->form_validation->run()==TRUE){
$config['upload_path'] = 'uploads/files/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 1024;
$this->load->library('upload', $config);
//upload file to directory
if($this->upload->do_upload('file')){
$uploadData = $this->upload->data();
$uploadedFile = $uploadData['file_name'];
/*
*insert file information into the database
*.......
*/
}else{
$data['error_msg'] = $this->upload->display_errors();
}
}else {
$this->data['content'] = 'frontend/pages/place_order';
$this->load->view('frontend/_layout_main', $this->data);
}
}

how can i check the value of a variable from a controller in codeigniter

I am doing an upload image file in CodeIgniter. I want to trace out the image in my code and update my database path with it. I want to print the $image_path variable in the code below where it was located in my controller.
How can I print the $image_path variable to display or check its value inside the controller or maybe echo it out ?
Here it is:
<?php
public function upload_file()
{
$status = "";
$msg = "";
$file_element_name = 'userfile';
if ($status != "error") {
$config['upload_path'] = './assets/upimages/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 1024 * 8;
$config['encrypt_name'] = FALSE;
$this->load->library('upload', $config);
if (!$this->upload->do_upload($file_element_name))
{
$status = 'error';
$msg = $this->upload->display_errors('', '');
}
else
{
$data = $this->upload->data();
$image_path = $data['full_path'];
if(file_exists($image_path))
{
$status = "success";
$msg = "File successfully uploaded";
}
else
{
$status = "error";
$msg = "Something went wrong when saving the file, please try again.";
}
}
#unlink($_FILES[$file_element_name]);
}
echo json_encode(array('status' => $status, 'msg' => $msg));
}
?>
If I understand the question your asking then you want to view the contents of the $image_path variable.
If all you want is to check this then you could pass it back to the view with the json array ('image_path' => $image_path).
The other option is to var_dump($image_path) however to view this you would need to inspect the post data response on the browser and it may also stop the json from working while you are using the var_dump().
Blinky
try echo $image_path; or print_r($image_path)

Codeigniter, uploading multiple files with same name

I have an upload form that allows me to add as many files as needed. However when I start trying to upload the files I get an error.
Controller
$this->load->library('upload');
$error = "";
$file = "";
$this->total_count_of_files = count($_FILES['user_certificates']['name']);
print_r($_FILES['user_certificates']['name']);
for($i=0; $i<$this->total_count_of_files; $i++)
{
$_FILES['user_certificates']['name'] = $_FILES['user_certificates']['name'][$i];
$_FILES['user_certificates']['type'] = $_FILES['user_certificates']['type'][$i];
$_FILES['user_certificates']['tmp_name'] = $_FILES['user_certificates']['tmp_name'][$i];
$_FILES['user_certificates']['error'] = $_FILES['user_certificates']['error'][$i];
$_FILES['user_certificates']['size'] = $_FILES['user_certificates']['size'][$i];
$config['encrypt_name'] = TRUE;
$config['file_name'] = $_FILES['user_certificates']['name'];
$config['upload_path'] = './certificate_files/';
$config['allowed_types'] = 'txt|pdf|doc|docx';
$config['max_size'] = 0;
$this->upload->initialize($config);
if (!$this->upload->do_upload())
{
$status = 'error';
$msg = $this->upload->display_errors();
}
else
{
$data = $this->upload->data();
$file = $data['raw_name'] . $data['file_ext'];
}
if($file)
{
$status = "success";
$msg = "Image successfully uploaded";
}
else
{
$status = "error";
$msg = "Something went wrong when saving the image, please try again.";
}
}
echo json_encode(array('status' => $status, 'msg' => $msg));
exit();
The print_r($_FILES['user_certificates']['name'])) shows me the files I have added:
Array ( [0] => license.txt [1] => license.txt )
I am totally stuck on how to get the upload to work. Any ideas?
Cheers in advance!
EDIT
If I change this:
if (!$this->upload->do_upload())
to this:
if (!$this->upload->do_upload('user_certificates'))
it works, but only for one file, it doesn't seem to loop round again for some reason
Your loops seems to be incorrect.
...
$_FILES['user_certificates']['name'] = $_FILES['user_certificates']['name'][$i];
...
these lines overwrite the original $_FILES array, so after completion of first loop, it will not find anything else in the loop because it got overwritten.
Instead you may first store the $_FILES array to a local variable and loop through it to upload one by one.

Categories