Codeigniter - How to make a file upload field non mandatory? - php

I have a form which has 5 file input fields, all works fine with my CRUD methods if the file field is not empty, however the client now wants to set some of the fields to be non mandatory.
This is how I am trying to do it in my code, the problem I am encountering is declaring a null variable(to insert a blank value in the respective database field) if the file field is empty. I get an undefined variable message from codeigniter when nothing is uploaded...
This is the code that code checks if a file has been uploaded or not.
if(isset($_FILES['ticketing_summary_file']))
{
$this->upload->initialize($config);
if($this->upload->do_upload('ticketing_summary_file'))
{
$upload_data=$this->upload->data();
$ticketing_summary_file_name=$upload_data['file_name'];
$ticketing_summary_full_file_path = $path_to_uploads.'/'.$ticketing_summary_file_name;
$show['ticketing_summary_file_url'] = $ticketing_summary_full_file_path;
}
}
if(!isset($_FILES['ticketing_summary_file']))
{
$show['ticketing_summary_file_url'] = $empty_file_message;
}
Then this is how I insert the data into my database... I have tried declaring the contents of 'ticketing_summary_file' in the code below and above, but it says its empty either way
$show = array('tour_id' =>$tour,
'date' => $this->input->post('date'),
'location' => $location);
$id = $this->show_model->save($show);
Cheers for any help,
Dan

I ran into a similar problem. I ended up checking to see if the upload error matched the text in the lang file. There is probably a better way but it was a quick fix for me. I hope it helps.
<?php
//play code file field
$play_code_errors= '';
$data['play_code_file_name'] = uniqid('pc_', true) . 'csv';
$config['upload_path'] = './media/tmp/';
$config['allowed_types'] = 'csv';
$config['max_size'] = '4024';
$config['file_name'] = $data['play_code_file_name'];
$this->upload->initialize($config);
if ( ! $this->upload->do_upload('play_code_file'))
{
$play_code_errors = $this->upload->display_errors();
if($play_code_errors = $this->lang->line('upload_no_file_selected'))
{
$play_code_errors = '';
}
}

Related

CodeIgniter Error Number: 1054 Unknown column 'Array' in 'field list'. Inserting images names in a column using implode

Please, I am moving multiple images to a destination folder and I insert the images name in a single column separated by a comma. This means, all other records will be inserted into a row once and the names of the images will be inserted in a column separated by a comma. Moving of the images worked fine from the file upload but the data is not inserted into the database. It is giving this error below :
A PHP Error was encountered
Severity: Notice
Message: Array to string conversion
Filename: database/DB_driver.php
Line Number: 1465
Error Number: 1054
Unknown column 'Array' in 'field list'
INSERT INTO wzb_product (WZB_ProductCode, ProductGrade, WZB_ProductName, WZB_ProductDescription, WZB_QuantityPerUnit, WZB_UnitPrice, WZB_ProductOwner, WZB_CategoryName, WZB_VerifiedByAgent, ProductPhotoName, Addedby) VALUES ('PR02_893', 'OLD', 'Giovani Vialli Shoe', Array, NULL, '350000', 'Admin', 'Bag And Shoe', 'NO', 'main-product01.jpg,main-product02.jpg,main-product03.jpg,main-product04.jpg', '')
The fact is I do not have a column named Array. The form uses TinyMCE to allow the user type Product Description. I suspect the images file names to be the culprit, or could it be the TinyMCE column(ProducrDescription)?
This is my Controller method that does it :
$filesCount = count($_FILES['productphotos']['name']);
for($i = 0; $i < $filesCount; $i++)
{
$_FILES['file']['name'] = $_FILES['productphotos']['name'][$i];
$_FILES['file']['type'] = $_FILES['productphotos']['type'][$i];
$_FILES['file']['tmp_name'] = $_FILES['productphotos']['tmp_name'][$i];
$_FILES['file']['error'] = $_FILES['productphotos']['error'][$i];
$_FILES['file']['size'] = $_FILES['productphotos']['size'][$i];
$testprodpath = './Products/Old/BagShoes/';
//$uploadPath = './Products/';
//$uploadPath = base_url().'Products/';
$config['upload_path'] = $testprodpath;
$config['allowed_types'] = 'gif|jpg|jpeg|png';
$config['max_size'] = '5000'; // max_size in kb
$config['file_name'] = $_FILES['productphotos']['name'][$i];
$this->upload->initialize($config);
//load upload library
$this->load->library('upload', $config);
//upload the files
if($this->upload->do_upload('file'))
{
//Get data about the files
$fileData = $this->upload->data();
$name_array[] = $fileData['file_name'];
} // closes if
else
{
echo $this->upload->display_errors();
} //closes else
} //closes for loop
$content = $this->input->post('content');
$datatiny['content'] = $content;
$imagesnames= implode(',', $name_array);
//Insert file information into the database
$data2 = array(
'WZB_ProductCode'=>$this->input->post('productcode'),
'ProductGrade'=>$this->input->post('productgrade'),
'WZB_ProductName'=>$this->input->post('productname'),
'WZB_ProductDescription'=>$datatiny,
'WZB_QuantityPerUnit'=>$this->input->post('quantityperunity'),
'WZB_UnitPrice'=>$this->input->post('unitprice'),
'WZB_ProductOwner'=>$this->input->post('productowner'),
'WZB_CategoryName'=>$this->input->post('productcategory'),
'WZB_VerifiedByAgent'=>$this->input->post('verifiedbyagent'),
'ProductPhotoName'=>$imagesnames,
'Addedby'=>$this->input->post('addedby')
);
$this->db->insert('wzb_product', $data2);
$this->session->set_flashdata('Added Successfully','Record successfully added');
} //closes if for checking if file input has file is submitted and if file is uploaded
I am not using model. The point is if I insert a single image name that is not multiple images. It works fine by moving the image name and also insert records into the database with the image file name but I am getting this error when it is multiple images.
I appreciate all the efforts in advance.
Regards,
You have description in $datatiny['content'] and you are using $datatiny in initialisation. It is array and you can not use array in that. So change the line as :
$data2 = array(
'WZB_ProductCode'=>$this->input->post('productcode'),
'ProductGrade'=>$this->input->post('productgrade'),
'WZB_ProductName'=>$this->input->post('productname'),
'WZB_ProductDescription'=>$datatiny['content'],
'WZB_QuantityPerUnit'=>$this->input->post('quantityperunity'),
'WZB_UnitPrice'=>$this->input->post('unitprice'),
'WZB_ProductOwner'=>$this->input->post('productowner'),
'WZB_CategoryName'=>$this->input->post('productcategory'),
'WZB_VerifiedByAgent'=>$this->input->post('verifiedbyagent'),
'ProductPhotoName'=>$imagesnames,
'Addedby'=>$this->input->post('addedby')
);
you have some mistake in code Either change this line
$datatiny['content'] = $content;
to
$datatiny = $content;
or change this array to
$data2 = array(
'WZB_ProductCode'=>$this->input->post('productcode'),
'ProductGrade'=>$this->input->post('productgrade'),
'WZB_ProductName'=>$this->input->post('productname'),
'WZB_ProductDescription'=>$datatiny,
'WZB_QuantityPerUnit'=>$this->input->post('quantityperunity'),
'WZB_UnitPrice'=>$this->input->post('unitprice'),
'WZB_ProductOwner'=>$this->input->post('productowner'),
'WZB_CategoryName'=>$this->input->post('productcategory'),
'WZB_VerifiedByAgent'=>$this->input->post('verifiedbyagent'),
'ProductPhotoName'=>$imagesnames,
'Addedby'=>$this->input->post('addedby')
);
to
$data2 = array(
'WZB_ProductCode'=>$this->input->post('productcode'),
'ProductGrade'=>$this->input->post('productgrade'),
'WZB_ProductName'=>$this->input->post('productname'),
'WZB_ProductDescription'=>$datatiny['content'],
'WZB_QuantityPerUnit'=>$this->input->post('quantityperunity'),
'WZB_UnitPrice'=>$this->input->post('unitprice'),
'WZB_ProductOwner'=>$this->input->post('productowner'),
'WZB_CategoryName'=>$this->input->post('productcategory'),
'WZB_VerifiedByAgent'=>$this->input->post('verifiedbyagent'),
'ProductPhotoName'=>$imagesnames,
'Addedby'=>$this->input->post('addedby')
);

file name displayed same for all fields, using codeigniter's upload library

I have a view file, which includes form:
form_upload('media_image_00');
form_upload('media_image_01');
.....
form_upload('media_image_14');
And my controller(I have set the validation rules in model):
if ($this->form_validation->run() == TRUE) {
$config['upload_path'] = './my_image/';
$config['allowed_types'] = 'gif|jpg|jpeg|png';
$config['max_size'] = '10240';
$this->load->library('upload', $config);
for($i = 0;$i<=14;$i++){
$name = 'media_image_0'.$i;
if($i>9){
$name = 'media_image_'.$i;
} // end of if($i>9
if(!empty($_FILES[$name])){
$this->upload->do_upload($name);
$upload_data = $this->upload->data();
$_POST[$name] = $upload_data['file_name'];
dump($upload_data['file_name']);
}else{
// do nothing
}// end of if(!empty
} // end of for loop
I want the dump($upload_data['file_name']) to dump the filename, only where the datas are selected & uploaded. Not in every field.
The problem is when I upload data only on media_image_00 & media_image_01, it automatically dumps the name of media_image_01 to every other field after it. File is not uploaded again but the name is same for every field after media_image_01.
I don't know what the problem is. May be it is something to do with array in codeigniter.
How can I solve this?

PHP Codeigniter Uploading Class, rename files with specific schema

I am having a spot of trouble with Codeigniter and getting files to rename within the upload process from the Upload Library it has to offer. Now before anyone says it, I am not looking for "encrypted" file names.
My Problem is in uploading images you have a good handful of types you could be dealing with. So how does one change the file name using the file_name config option to a specific schema (which I already have the schema part up and working). But maintain the same file type?
Right now I am attempting
$upload_config['file_name'] = $generated_filename_from_schema
Only problem is $generated_filename_from_schema doesnt have a file extension, and leaving the file extension out of the equation CI seems to ignore it altogether and just takes the file and append_1, _2, _3 as it goes up if the files have the same name, otherwise it just leaves the name intact.
Now I have to pass the $config to CI so it will upload the file, but how can I determin what kind of file I am working with before it trys to upload so I can use my name generation schema.
*edit*
$upload_config['upload_path'] = realpath(APPPATH.'../images/');
$upload_config['allowed_types'] = 'gif|jpg|png';
$upload_config['max_size'] = 0;
$upload_config['max_width'] = 0;
$upload_config['max_height'] = 0;
$upload_config['remove_spaces'] = true;
$upload_config['file_name'] = $this->genfunc->genFileName($uid);
if($this->input->post('uploads'))
{
$this->load->library('upload');
$this->upload->initialize($upload_config);
if (!$this->upload->do_upload())
{
//echo 'error';
echo $config['upload_path'];
$this->data['errors'] = $this->upload->display_errors();
}
else
{
//echo 'uploaded';
$this->data['upload_data'] = $this->upload->data();
}
}
You can use $_FILES array to get original name of file.
Extract extension of original file.Then, append to your new file name.
Try as below
$ext = end(explode(".", $_FILES[$input_file_field_name]['name']));
$upload_config['file_name'] = $this->genfunc->genFileName($uid).'.'.$ext;
Personally, I find CodeIgniter's file uploading class to be somewhat cumbersome. If you want a vanilla PHP solution:
function submit_image(){
$f = $_FILES['image'];
$allowedTypes = array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF);
$detectedType = exif_imagetype($f['tmp_name']);
if(in_array($detectedType, $allowedTypes)){
$pi = pathinfo($f['name']);
$ext = $pi['extension'];
$target = $this->genfunc->genFileName($uid) "." . $ext;
if(move_uploaded_file($f['tmp_name'], $target)){
/*success*/
}
else {/*couldn't save the file (perhaps permission error?*/}
}
else {/*invalid file type*/}
}

data not setting in session codeigniter

//uploading product movie or image?
if($this->input->post('upload_360') == "Upload") {
$config['upload_path'] = './media/images/products/360s';
$config['allowed_types'] = 'swf';
$this->load->library('upload', $config);
$this->upload->initialize($config);
if (!$this->upload->do_upload('film')) {
$this->data['product_error'] = $this->upload->display_errors();
$this->template->build('/admin/products/create', $this->data);
} else {
$this->data['data_360'] = $this->upload->data();
$this->session->set_userdata(array('360_film' => $this->data['data_360']));
$this->template->build('/admin/products/create', $this->data);
}
$this->session->set_userdata(array('advantages' => $this->input->post('product_advantages')));
$this->data['session_advantages'] = $this->session->userdata('advantages');
}
//upload the product image, if successful the user will be
//notified if the image is too high or wide, and will be offered,
//the chance to crop the image. All cropping takes place in the media
//controller.
if($this->input->post('product_image') == "Upload") {
$config['upload_path'] = './media/images/products/';
$config['allowed_types'] = 'gif|jpg|jpeg|png';
$this->load->library('upload', $config);
$this->upload->initialize($config);
if (!$this->upload->do_upload('image_upload')) {
//die("!");
$this->data['image_error'] = $this->upload->display_errors();
$this->template->build('/admin/products/create', $this->data);
} else {
$this->data['image_data'] = $this->upload->data();
$this->session->set_userdata(array('image' => $this->data['image_data']));
$this->data['session_image'] = $this->session->userdata('image');
$this->template->build('/admin/products/create', $this->data);
}
$this->session->set_userdata(array('advantages' => $this->input->post('product_advantages')));
$this->data['session_advantages'] = $this->session->userdata('advantages');
}
if($this->input->post('screenshot_upload') == "Upload") {
$config['upload_path'] = './media/images/products/360s/screenshots/';
$config['allowed_types'] = 'gif|jpg|jpeg|png';
$this->load->library('upload', $config);
$this->upload->initialize($config);
if (!$this->upload->do_upload('screenshot')) {
//die("!");
$this->data['screenshot_error'] = $this->upload->display_errors();
$this->template->build('/admin/products/create', $this->data);
} else {
$this->data['screenshot_data'] = $this->upload->data();
$this->session->set_userdata(array('screenshot' => $this->data['screenshot_data']));
$this->data['session_screenshot'] = $this->session->userdata('screenshot');
$this->template->build('/admin/products/create', $this->data);
}
$this->session->set_userdata(array('advantages' => $this->input->post('product_advantages')));
$this->data['session_advantages'] = $this->session->userdata('advantages');
}
On my form I have the user choose a file and the click an upload button dependent on which button is clicked the file gets uploaded and the upload data gets saved in a session.
The session is then used to get data from to save to a database, the upload_360 session works, the product_image session works fine but the screenshot_upload session only has data when with the if statement (3rd one in the code) if I try and acccess it outside of the code then that portion of the session is empty?
Is there a reason for this?
Why are you storing data in a session before inserting it into the db?
Cookies can only hold 4KB of data...
but the screenshot_upload session only has data when with the if statement (3rd one in the code) if I try and acccess it outside of the code then that portion of the session is empty?
I don't understand that part of your question. Do you mean it only has data when only using the 3rd if statement? i.e. when only trying to do screenshot_upload and not product_image or 360_upload`? If so, that might speak to the cookie size limit.
Instead of
$this->session->set_userdata(array('screenshot' => $this->data['screenshot_data']));
$this->data['session_screenshot'] = $this->session->userdata('screenshot');
why don't you
$this->uploads_model->insert_screenshot_data($this->data['screenshot_data']);//send screenshot upload_data to model to be inserted into db
$this->data['screenshot_data'] = $this->data['screenshot_data'];//if you want to pass screenshot upload_data to template/view
?
It looks like you are sending output to the user before setting the session (I'm inferring this from the $this->template->build, which is custom code.)
The session, like headers, cannot be modified after anything (ANYTHING) has been sent to output. This is because the session itself is sent in the header.

Check the file name in CodeIgniter file upload function

I'm using the following CodeIgniter function to upload files which works fine:
function uploadFiles(){
$this->load->library('upload');
$error = 0;
$projectName = $_POST['projectname'];
$projectID = $_POST['maxid'];
$folderName = $this->config->item('upload_dest')."/".$projectName."_".$projectID;
if(!file_exists ($folderName)){
$aa = mkdir($folderName);
}
$config['upload_path'] = $folderName;
$config['allowed_types'] = 'xml';
//$config['allowed_types'] = '*';
$config['max_size'] = '0';
$config['overwrite'] = TRUE;
$this->upload->initialize($config);
for($i=0; $i<count($_FILES['files']['name']); $i++)
{
$_FILES['userfile']['name'] = $_FILES['files']['name'][$i];
$_FILES['userfile']['type'] = $_FILES['files']['type'][$i];
$_FILES['userfile']['tmp_name'] = $_FILES['files']['tmp_name'][$i];
$_FILES['userfile']['error'] = $_FILES['files']['error'][$i];
$_FILES['userfile']['size'] = $_FILES['files']['size'][$i];
if($this->upload->do_upload())
{
$error += 0;
}else{
$error += 1;
}
}
if($error > 0){
$this->upload->display_errors();
return FALSE;
}
else{
return TRUE;
}
}
What I need to do is - check to make sure that at least one of the files which are being uploaded is named "etl". If there's no such a file in the file list the user chosen - stop the action, don't upload anything and return a form validation error. Could anybody advise over this?
Thanks.
Firstly, from php there is no way to get the name of the file(s) before uploading, you must upload to get the properties of the file. So, the options available are:
(1) Allow the files to be uploaded, then get the names and check if any contains "etl". If non contains what you are looking for, then delete the just uploaded files, and set a custom error message yourself.
This approach have a very large overhead cost of allowing you to first upload what is not need, then deleting it. Very poor but solves the problem.
(2) On the otherhand, is the javascript solution. Give the upload fields a common class name
e.g "userfile1", "userfile2", .......
then from your javascript and using jquery, intercept the submission of the form, then use a for loop to get the values of each of the file upload field, from which you can get the full name and extension of the file and then do your "etl" comparison.
i.e
<script type="text/javascript" >
$("#formname").submit(function(){
$(".classname").each(function(){
if($(this).val().indexOf("etl") != -1 ){
return true;
}
});
/*
*whatever makes it finish executing that loop and the execution of code gets
*to this point, then the string "etl" was not found in any of the names.
*/
// write a piece of code to show an hidden error field
$("#hidden_error_div").text("Your error message").show();
return false; //makes sure the form is not submitted.
});
</script>
Hope this helps.
Oyekunmi gives a good javascript solution to intercept before it actually gets to the server. As Oyekunmi points out, once it gets there, it gets there as a package, so you could then store and process it in a temporary directory, eval each file there and process accordingly.

Categories