I've got a big form that allows users to upload multiple files/filetypes to an offer/bid they are creating. Everything is working fine except one piece: the name encryption of the files before saving to the database.
I haven't found a rhyme or reason for it, but it's hit or miss. The image works fine every time. The other documents (which allow all [*] types, but primarily will consist of various business docs such as pdf, doc, xls, etc.) are the ones that are spotty.
I found threads on SO and elsewhere about general issues with the name encryption but have yet to come across one that deals with the specificity of my issue.
Here's the upload function:
//for multi uploads
function do_uploads($name, $file)
{
$status ="";
$msg = "";
$file_element_name = $name;
//go through and figure out where it goes
if($name == "QuoteDoc") {
$folder = "quotedocs";
$allowed = '*';
}
else if($name == "ProductOfferPhoto") {
$folder = "product_photos";
$allowed = 'jpeg|jpg|png|gif';
}
else if($name == "ResearchWhtPaper1" || $name == "ResearchWhtPaper2") {
$folder = "research";
$allowed = "*";
}
else if($name == "ProductLiterature1" || $name == "ProductLiterature2") {
$folder = "literature";
$allowed = "*";
}
else if ($name == "FDALink") {
$folder = "fda";
$allowed = "*";
}
$config['upload_path'] = './uploads/' . $folder;
$config['allowed_types'] = $allowed;
$config['max_size'] = 1024 * 8;
$config['encrypt_name'] = TRUE;
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload($name))
{
$status = 'error';
$msg = $this->upload->display_errors('', '');
}
else {
$data = $this->upload->data();
}
#unlink($_FILES[$file_element_name]);
//what's up?
//return $this->upload->data();
return array('status' => $status, 'msg' => $msg, 'data' => $this->upload->data(), 'allowed'=>$allowed);
}
Any help would be greatly appreciated.
You're not stating your question very clearly:
Are the names simply not being encrypted, but still uploading to the correct directories?
Are you setting these inside a loop, where perhaps the class instance is not being re-initialized? Does the first file encrypt correctly, but not the subsequent ones?
Can you track which file types are not working correctly?
I have trouble believing it is completely "random", and think there's just not enough research being done here
Solution from below:
You need to use $this->upload->initialize($config) to change the config, as the library will only be loaded once
Related
I've been trying to figure it out for a while now and can't seem to find any solution posted anywhere before. I want to allow almost all file types excluding some in codeigniter controller method. Here's my code:
function checkFileType($ext){
if(in_array($ext, array('ade','adp','bat','chm','cmd','com','cpl','dll','dmg','exe','hta','ins','isp','jar','js','jse','lib','lnk','mde','msc','msi','msp','mst','nsh','pif','scr','sct','shb','sys','vb','vbe','vbs','vxd','wsc','wsf','wsh')))
return '';
else
return $ext;
}
/* Upload files */
public function store_files(){
$data='';
$userdir = 'uploads/files/'.$this->getCategory().$this->getID();
$this->load->library('upload');
if (!file_exists($userdir)) {
mkdir($userdir, 0777, true);
}
$file = $_FILES['userfile']['name'];
$ext = substr(strrchr($file, '.'), 1);
$config = array(
'upload_path'=>$userdir,
'allowed_types'=>checkFileType($ext),
'max_width'=>0,
'max_height'=>0,
'max_size'=>0,
'encrypt_name'=>TRUE,
'file_ext_tolower'=>TRUE,
);
$this->upload->initialize($config);
if ( ! $this->upload->do_upload('userfile')) {
print_r($this->upload->display_errors());
} else {
foreach($this->upload->data() as $key=>$value){
if($value)
$data.= '<b>'.$key.'</b> : '.$value.'<br><br>';
}
echo $data;
}
}
Note:
On echoing $ext in the store_files() function, it shows the correct extension as string.
I'm trying to allow all extension types except those that match in the checkFileType() method.
If I manually specify the file extensions in the order (gif|png|pdf|pptx...) it works fine, but I can't seem to make use of '*' either because it allows all file extensions including the ones I want to block.
I would to like to implement multiple file upload. I am getting this code only single file is uploading. How to implement multiple file upload
Form Code
$docupload=new Zend_Form_Element_File('docupload',array('multiple' => 'multiple'));
$docupload->addValidator(new Zend_Validate_File_Extension('doc,docx,pdf,txt'));
$docupload->setIsArray(true);
In Controller
if(is_array($_FILES['docupload']['name']))
{
$params = $this->_form->getValues();
foreach($_FILES['docupload']['name'] as $key=>$files)
{
$file_name=$_FILES['docupload']['name'][$key];
$temp_image_path = $_FILES['docupload']['tmp_name'][$key];
$file_name=implode(",", $file_name);
$temp_image_path=implode(",", $temp_image_path);
['tmp_name'];
$path_parts = pathinfo($temp_image_path);
$tem_path = $path_parts['dirname'];
$path_parts_extension = pathinfo($file_name);
$actual_filename=$path_parts_extension['filename'];
$file_extension = $path_parts_extension['extension'];
if(APPLICATION_ENV != "development")
{
$path = '/';
}
else {
$path = '\\';
}
$filename = $tem_path.$path.$file_name;
$rename_uploadfile = $actual_filename.$random_number.".".$file_extension;
$fullFilePath = UPLOAD_USER_IMAGES.$rename_uploadfile;
// Rename uploaded file using Zend Framework
$filterFileRename = new Zend_Filter_File_Rename(array('target' => $fullFilePath));
$filterFileRename->filter($filename);
$form_data=$params;
$form_data['docupload']=$rename_uploadfile;
if($id)
{
$this->_table->updateById("id",$id, $form_data);
}
else
{
$this->_table->insert($form_data);
}
I am new to zend framework. Please help me.Thanks in advance
Rather than use the $_FILES variable, it would be better to use the applicable Zend code, considering that you're using Zend as your framework:
if (!$form->isValid()) {
print "Uh oh... validation error";
}
if (!$form->docupload->receive()) {
print "Error receiving the file(s)";
}
$files = $form->docupload->getFileName(); // result should be an array in this case
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.
I am trying to upload two files with the help of codeigniter functions.
One of the file should be mandatory and one should be optional.
I am using the code below to upload those files but I cannot figure out the way to make one optional and one mandatory. I tried few modifications to the code below, but i bumped into many errors. I am new to codeigniter.
Even the code below for handling the uploads may not be appropriate but it is working.
$config['upload_path'] = 'uploads/';
$path=$config['upload_path'];
$config['allowed_types'] = '*';
$this->load->library('upload');
$i=0;
foreach ($_FILES as $key => $value)
{
if (!empty($key['name']))
{
$this->upload->initialize($config);
if (!$this->upload->do_upload($key))
{
$errors = $this->upload->display_errors();
$this->session->set_flashdata('error', $errors);
redirect(base_url().'upload', 'refresh');
}
else
{
$data = array('upload_data' => $this->upload->data());
$p[$i] = $this->upload->data();
}
}
$i++;
} //endforeach
if(empty($errors)){
//if there are no errors, write it into the database
$data = array('user_id'=>$this->session->userdata('id'),
'name'=>$this->input->post('name'),
'screenshot'=>$p[1]['file_name'],
'model'=> $p[0]['file_name'],
'created'=>date('Y-m-d H:i:s')
);
if($this->usermodel_model->save($data)){
//success
redirect(base_url().'dashboard?success');
}else{
//failed
redirect(base_url().'upload');
}
}
Sohanmax put $i++; inside if (!empty($key['name'])){ } and after ending foreach check if($i !=0) if it's false show the error, hope it'll work.
In a larger project, have a form which uploads 2 files. I am using codeigniter as the framework. After the form upload it should send these 2 files as an email.
In order to attach it to an email, we should have a local copy of the file. Hence I move the files to a temporary folder and use the naming convention of [session-id]_my_file_1 and [session-id]_my_file_2
Finally after sending out the email I try to delete the these temporary files. But unlink is not deleting these files. I donot know the reason for this.
My guess is: It may be still being used by the mail command to upload/send. Below are the code outline I have written.
$config['upload_path'] = './tmp_holder/';
$config['allowed_types'] = 'doc|docx|pdf|rtf';
$config['max_size'] = '10240';
$config['file_name'] = $this->session->userdata('session_id').'_1';
$config['overwrite'] = TRUE;
$config2['upload_path'] = './tmp_holder/';
$config2['allowed_types'] = 'doc|docx|pdf|rtf';
$config2['max_size'] = '10240';
$config2['file_name'] = $this->session->userdata('session_id').'_2';
$config2['overwrite'] = TRUE;
$this->load->library('upload',$config);
if ($this->form_validation->run() == FALSE)
{
$this->load->view('init_app_form');
}
else
{
if($this->upload->do_upload('cvFile') === FALSE) {
$this->load->view('init_app_form');
}
else {
$file1Return = $this->upload->data();
$this->upload->initialize($config2);
if($this->upload->do_upload('researchFile') === FALSE) {
$this->load->view('init_app_form');
}
else {
//process data here
$file2Return = $this->upload->data();
$this->config->load('email');
$this->email->initialize($this->config->item('email_conf'));
$this->email->from($this->config->item('email_from'), $this->input->post('tname').' '.$this->input->post('fname').' '.$this->input->post('lname'));
$this->email->to($this->config->item('email_to'));
$this->email->subject('something');
$this->email->message('something');
$this->email->attach($file1Return['full_path']);
$this->email->attach($file2Return['full_path']);
if( $this->email->send() == false ) {
//error
echo $this->email->print_debugger(); exit;
}
$this->email->clear();
////////////////////////////////
#unlink($this->session->userdata('session_id').'_2');
////////////////////////////////
$this->load->view('init_app_success');
}
////////////////////////////////
#unlink($this->session->userdata('session_id').'_1');
////////////////////////////////
}
}
The Solution I did was to delete the files in the temp folder before I do this so that previous files are cleared. But this is not a clean approach right? This is because:
It may be trying deleting other files currently being used by other parallel instances
I want the tmp folder to be empty after I send itself.
Its better to use file_helper which is in code igniter.
$this->load->helper("file");
delete_files($this->session->userdata('session_id').'_1');
here is documentation for this