AJAX-based file upload in CodeIgniter 2 - php

I'm having some trouble with CodeIgniter 2.1.4 and uploading files via AJAX.
I currently have a form which submits perfectly, like so (views/load_form):
<!--form created to add member to database -->
<?php echo form_open_multipart('index.php/member_record/add_member'); ?>
<?php echo form_fieldset('Create Membership Record'); ?>
<div class="container">
<form id="memberform" role="form">
<?php echo form_label('First Name', 'fname'); ?>
<?php echo form_input('fname'); ?>
</div>
<!--other such fields omitted for brevity-->
<label>Upload scanned ID Card</label>
<input type="file" name="scIDFile" id="scIDFile" />
<p class="help-block">Select image as either JPEG, GIF, PNG</p>
<input id="submit" type="submit" name="submit" value="Create Record" class="btn btn-success"/>
<!--end of view-->
I have a Controller which handled this well (controllers/member_record):
public member_record extends CI_Controller{
public add_member(){
$config['upload_path'] = './files/';
$config['allowed_types'] = 'gif|jpg|png|pdf';
$config['max_size']= 1024*8;
$config['encrypt_name']=TRUE;
$config['overwrite'] =TRUE;
$this->load->library('upload',$config);
foreach($_FILES as $field => $file){
if($file['error'] == 0){
if($this->upload->do_upload($field)){
/*$image_config=array(
'source_image'=>$data['full_path'],
'new_image'=>$data['file_path'].'/thumbs',
'maintain_ratio'=>true,
'width'=>150,
'height'=>100
);
$this->load->library('image_lib',$image_config);
$this->image_lib->resize();*/
}else{
$errors = $this->upload->display_errors();
}
}
}
}
}
And this was fine. However, due to certain new functionality that I'm adding to my view: I need to convert things to AJAX and pass all these values to the back-end through AJAX. I've been able to submit all of the fields (like first-name, last-name) to the backend via POST, however I'm struggling to enable file uploads!
I've tried using jQuery File Upload plugins, but there aren't very clear directions on how one would use them for CodeIgniter 2 (especially given my current code). If anyone can shed some light on this, I would appreciate it.

Related

Codeigniter file upload from a form without ajax/jquery/javascript

Context : I am updating user_profile data after user registration using form #updateprofileform ,
i am able to process all other form fields using standard validations and insert/update using user_model.
issue is with resume field which should accept a file as input type and upload to server and store its path on server (say http://domain/uploads/$filename) to a column in database.
Expectation A logged in user , able to view his details(if already in database),update details if incomplete profile.
Question : I found methods how we can upload a file to server using CI framework or how we can upload a file in this context using jquery/ajax/java-script. But i am looking for simple solution for above problem which can do the job with out dependency on technologies.
user_profile.php (view)
<table>
<form class="row" name="updateprofile" action = "<?php echo base_url()?>user/user_profile" method="POST">
<tr>
<td><label for="email">Email ID</label></td><td><input class="form-control" name="email" placeholder="Email-ID" type="text" value="<?php if (isset($email)) echo $email;?>" /> <span style="color:red"><?php echo form_error('email'); ?></span></td>
</tr>
<tr>
<td><label for="resume">Resume</label></td>
<td>
<input name="resume" placeholder="Upload resume" type="file" value="<?php if (isset($resume)) echo $resume;?>" />
<span style="color:red"><?php echo form_error('resume'); ?>
</span>
</td>
</tr>
<tr>
<td></td>
<td><div class="col-md-6 col-lg-3"> <button type="submit" class="btn btn--primary type--uppercase" name="updateprofile" value="updateprofile" formaction = "<?php echo base_url()?>user/user_profile">Update Profile</button> </div></td>
</tr>
</form>
</table>
user_controller
class User extends CI_Controller {
public function __construct()
{
parent::__construct();
$config = array(
'upload_path' => "./uploads/",
'allowed_types' => "doc|docx|pdf",
'overwrite' => TRUE,
'max_size' => "2048000", // Can be set to particular file size , here it is 2 MB(2048 Kb)
//'max_height' => "768",
//'max_width' => "1024"
);
$this->load->library('upload', $config);
}
public function user_profile()
{
$resume = $this->input->post('resume');
if ($this->user_model->set_user_profile($id,FALSE) )
{ if($this->do_upload($resume)){
$this->session->set_flashdata('msg_success','Updation Successful!');
echo validation_errors();}
}
else
{
$this->session->set_flashdata('msg_error','Error! Please try again later.');
redirect('user/user_profile');
}
public function do_upload($resume){
if($this->upload->do_upload($resume))
{
$data = array('upload_data' => $this->upload->data($resume));
$this->load->view('user_profile',$data);
}
else
{
$error = array('error' => $this->upload->display_errors($resume));
$this->load->view('user_profile', $error);
}
}
currently always error.... Error! Please try again later . so appreciate some pointers here to upload both file and form data together and save file location in database without ajax/jquery.
Thanks
Change the form definition to the following:
<form class="row" action = "<?php echo base_url('user/user_profile'); ?>" method="post" enctype="multipart/form-data" name="updateprofile" >
Resolved !
4 important steps needed and some missing in most Q&A in all other posts to make this complete.will share samplecode in github when i get sometime.
form encryption type must be enctype="multipart/form-data" (thanks
to #Javier Larroulet and #dexter )
do_upload method by default look for file field with name=userfile
(Thanks to #Alex ! for referencing this), so, if you have your
form's file field name different than userfile, then only it is
required to mention as do_upload('filefieldname') otherwise
optional
loading of upload library configuration is tricky.. if you
autoupload the upload library , then load->library upload config will fail!, you
just =>initialize it.$this->upload->initialize($config); if you
are not using autoload for upload library, then yes, you can load it
from controller. $this->load->library('upload', $config);
when ever, you are using upload, you have to catch the form validation errors
and data errors separately (again thanks to #Alex for pointing this)
a nice documentation is given from codeigniter at this link (https://www.codeigniter.com/userguide3/libraries/file_uploading.html#the-controller ) but doesn't highlight routine mistakes.
hope this post help someone not to waste another 24 hours to debug.

Issue with uploading multiple files on a single html page using php

I am trying to build a web page where users can edit images portrayed on their public pages. There are 3 images that display on their public page and I've set up 3 HTML forms in order to handle the 3 separate files.
I only have 1 listed below because once I figure out the fix to 1 I'll be able to duplicate the fix to the other 2,
I have other upload pages on my website and they work fine, but for some reason this page is giving me trouble. I can select a file but when I want to upload it my php code doesn't read that there is anything being posted.
*I've commented out the function call (I know it works) I just need to know why my php code won't read that there is a file there.
If I had to guess it'd be something with how it's named or how it's being tossed to the php code.
The code looks like this:
<div class="academic" style="width:250px;">
<br>
<?php
if(isset($_FILES['aca']) === true)
{
echo 'please print'; //It doesn't
if(empty($_FILES['aca']['name']) === true)
{
echo 'Please choose a file! <br>';
}
else
{
$allowed = array('jpg', 'jpeg', 'gif', 'png');
$file_name = $_FILES['aca']['name'];
$file_extn = strtolower(end(explode('.', $file_name)));
$file_temp = $_FILES['aca']['tmp_name'];
echo '<br>';
echo '<br>';
print_r($_FILES['aca']['tmp_name']);
echo '<br>';
echo '<br>';
if(in_array($file_extn, $allowed) === true) {
//upload_image($file_temp,$file_extn);
echo 'You have uploaded a picture!';
echo '<b><h3>Press submit again to finish the upload</h3></b>';
//echo "<script>window.top.location='../hidden/viewPNM.php?id=$permi'</script>";
}
else
{
echo 'Incorrect File Type!! <br> Allowed: ';
echo implode(', ', $allowed);
}
}
}
?>
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="aca" id="aca">
<input type="submit" value="Upload">
</form>
</div>
</span>
Okay...here is what you can try to do:
Move the whole PHP code UNDER the form code. I remember that sometimes wierd bugs with that were happening, and the code didnt run
If that doesnt work, do following:
Change <input type="file" name="aca" id="aca"> to <input multiple="true" type="file" name="aca[]" />
Add this code above the submit button: <input type="hidden" name="sendfiles" value="Send Files" />
Replace if(isset($_FILES['aca']) === true) with if(isset($_POST['sendfiles']))
If this doesn't work, I can offer you a way to allow multiple files being uploaded from one button. (Took the code from my website I made before)

PHP-Jquery image upload not working

I'm trying to post form data through ajax
form1.php
I use request to get all URL parameter data
$_REQUEST["Ename"];
$_REQUEST["eImg"];
To upload the image,i use this code http://www.9lessons.info/2011/08/ajax-image-upload-without-refreshing.html
In the above link,you can see the source code,in the place of $_FILES['photoimg']['name'];,i use $_FILES['image']['name']; but it is not uploading the file and giving success message.
include('db.php');
session_start();
$session_id='1'; // User session id
$path = "uploads/";
I removed script that is marked with **
$valid_formats = array("jpg", "png", "gif", "bmp","jpeg");
**if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST")
{**
$name = $_FILES['image']['name'];
$size = $_FILES['image']['size'];
if(strlen($name)) {
list($txt, $ext) = explode(".", $name);
if(in_array($ext,$valid_formats)) {
if($size<(1024*1024)) { // Image size max 1 Mb
$actual_image_name = time().$session_id.".".$ext;
$tmp = $_FILES['image']['tmp_name'];
if(move_uploaded_file($tmp, $path.$actual_image_name)) {
mysql_query("UPDATE users SET profile_image='$actual_image_name' WHERE uid='$session_id'");
echo "<img src='uploads/".$actual_image_name."' class='preview'>";
} else {
echo "failed";
}
} else {
echo "Image file size max 1 MB";
}
} else {
echo "Invalid file format..";
}
} **else {
echo "Please select image..!";
exit();
}**
you simply can't upload files via $.ajax().
you'll have to use some trycky iframe-stuff or something like that to make this work. luckily, there are ready-to-go plugins for jquery to handle this for you (like $.ajaxForm() for example wich seems to be the one that's used in the tutorial you're reading).
EDIT:
the plugin also allows to add extra data thats not present in the form itself. to quote the documentation:
data
An object containing extra data that should be submitted along with the form.
data: { key1: 'value1', key2: 'value2' }
For upload image by ajax you should use an iframe and set its id to form target.
Please have a look at
http://www.coursesweb.net/ajax/upload-images
It is very simple code to upload image
That won't work!
Images are handled differently from the text data in Ajax so you would have to do more than just post it using the $.ajax({}) method.
You can however use the jquery.form.js plugin it works perfect http://jquery.malsup.com/form/#download there is a tutorial on how to use it
here
Any ways I have used it my self so let me elaborate for you.
The JavaScript code is here
$('.uploadForm').live('click', function(evt){
$('#feedback').html(' ');
$('#feedback').html('<img src="images/loader_image.gif" alt="Uploading...."/>');
$("#formID").ajaxForm({
target: '#feedback'
}).submit();
evt.preventDefault();
});
If your PHP code is fine this should work .....
Just post the rest of the form fields in the normal way way
This should work for you. If the PHP code is fine
For example if you had other form fields like firstname and lastname in form like this one
<div class="form">
<fieldset class="ui-corner-all">
<h3 class="ui-widget-header ui-corner-top" align="center">Client information</h3>
<form action="save_new_client.php" enctype="multipart/form-data" id="clientForm" method="POST">
<label>First Name</label>
<input name="firstname" type="text" id="firstname" class="required" minlength="3"/>
<label>Lastname</label>
<input name="date_added" type="text" id="date_added" class="dateEst" />
<label>Image</label>
<input name="photo" type="file" id="photo" />
<input type="submit" name="button" id="button" value="Save" class="uploadForm"/>
<input type="reset" name="reset" id="button" value="Cancel" /></td>
</form>
</fieldset>
<div id="feedback"></div>
</div>
Below it you'll just need to add a div or paragraph to hold your feedback message ....
then the rest will be just fine (like I said if your PHP code is okay)I have not looked through it alot

CodeIgniter From Post Data Not Going through

Im trying to make a file upload in CodeIgniter, how ever when I add enctype="multipart form-data" no post data will go through. At all not even the other fields. However when i dont add it, i can get the other post data, but of course no file upload. Whats going wrong here. Here is my view and controller:
View:
<h2>Add a New Album</h2>
<form enctype="multipart/form-data" method="post" action="<?php echo base_url();?>index.php/photo/newAlbum">
<table style="margin-left:5px;">
<tr>
<td> Album Name:</td>
<td><input type="text" name="name" /></td>
</tr>
<tr>
<td> Photo .zip File:</td>
<td><input type="file" name="userfile" size="20" /></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Upload Photo File" /></td>
</tr>
</table>
</form>
controller only contains:
var_dump($_POST);
Result is:
array(0) { }
You can add this form attribute:
enctype="multipart/form-data;charset=utf-8"
Instead of:
enctype="multipart/form-data"
You can see this link.
Actually, the multipart data like image/zip or some other blob data will be included in $_FILES array, not $_POST array.
I recommend you to use the upload library.
view:upload_form.php
<html>
<head>
<title>Upload Form</title>
</head>
<body>
<?php echo $error;?>
<?php echo form_open_multipart('upload/do_upload');?>
<input type="file" name="userfile" size="20" />
<br /><br />
<input type="submit" value="upload" />
</form>
</body>
</html>
view:upload_success.php
<html>
<head>
<title>Upload Form</title>
</head>
<body>
<h3>Your file was successfully uploaded!</h3>
<ul>
<?php foreach($upload_data as $item => $value):?>
<li><?php echo $item;?>: <?php echo $value;?></li>
<?php endforeach; ?>
</ul>
<p><?php echo anchor('upload', 'Upload Another File!'); ?></p>
</body>
</html>
controller:upload.php
<?php
class Upload extends CI_Controller {
function __construct()
{
parent::__construct();
$this->load->helper(array('form', 'url'));
}
function index()
{
$this->load->view('upload_form', array('error' => ' ' ));
}
function do_upload()
{
$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);
if ( ! $this->upload->do_upload())
{
$error = array('error' => $this->upload->display_errors());
$this->load->view('upload_form', $error);
}
else
{
$data = array('upload_data' => $this->upload->data());
$this->load->view('upload_success', $data);
}
}
}
?>
And that's all
You need fix your do_upload, like this..
$this->upload->do_upload('name-of-input-file-element-of-your-form')
For example, in your view code, you have:
<input type="file" name="userfile" size="20" />
So, your do_upload line, should be like this:
$this->upload->do_upload('userfile')
Saludos!
Interesting. The code you posted should work. I made a quick test script using your form, and both the $_FILES and $_POST data come through fine.
I found this previous question on SO: PHP--parsing multipart form data
It sounds like the same problem you're having. Unfortunately no real answer was reached for that problem. I would think this might be a server configuration issue - can you try the same code on another server and see if it functions?
The only other bit of information I can find was in the answer to this question, $_POST data returns empty when headers are > POST_MAX_SIZE
If you are trying to upload too large a file, apparently that can cause PHP to throw away the $_POST data as well. But if you've tried submitting your form without uploading a file (but still using "multipart/form-data"), and still don't see any $_POST data coming through, that doesn't apply.
I just had the same problem.
I solved it this way. in application/config/config.php you set the base_url
please be aware of, that this url have to be exact the same as the one you're calling
your web app. For me, I called my domain with www.sdfsd.com, but in the config file
I wrote http://sdfsd.com and so the POST of the form didn't work. So I changed this
and now everything is working!!
cheers
Check for possible wrong redirection in CI layer. It could be caused by a wrong URL request (for example, a slash '/' missing at the end of the URL). Redirections delete any POST data (I was dealing with this).
So, be sure that you are using full URLs in form action.
Check for your .htaccess and $config['uri_protocol'] consistency too.
I had this problem too. I don't agree with the above answers. I think the crucial thing is at what stage in your controller you attempt to get the post data. Perhaps you could post the relevant part of your controller. I found that both the post data and the upload data only become available after you call
this->upload->do_upload()
Obviously, you use an if statement to check for success. If successful,
$this->upload->data()
returns the standard array with info about the uploaded file and
$this->input->post('name_of_your_form_element')
is populated with what you entered in the relevant form element.
I had a similar problem - Turns out POST data is empty when you exceed max upload size / max post size.
This answer fixed my problem and allowed me to see $_POST and $_FORM data:
$_POST data returns empty when headers are > POST_MAX_SIZE

Sending Errors Back to Form: Code Igniter

I'm having trouble getting the form validation library to send my form errors back to my form in this case.
I have a controller that handles uploading images called addImage.php. This controller only handles the do_upload processing. I have a view called uploadimage.php that contains the upload form and submits to /addImage/do_upload.
The upload form is loaded on the front page of my website using a template in code igniter using
<?php $this->load->view('uploadimage'); ?>
The front page controller is contained in home.php
Right now after validation fails, I'm just redirecting to the homepage which clearly doesn't load the errors back (in addImage.php)
if($this->_submit_validate() == FALSE)
{
redirect('/', 'location');
return;
}
How can I redirect to my template_front.php while keeping those errors. Can I somehow call my home.php controller from the uploadimage.php controller to do this? I've confused myself trying to explain it! If this is totally unclear, let me know and I'll try to clarify.
Per the Documentation, you are suppose to simply re-load the view file on failure.
if ($this->form_validation->run() == FALSE)
{
$this->load->view('myform');
}
else
{
$this->load->view('formsuccess');
}
a redirect generates a new server request which flushes the validation error information.
on validation failure you should reload the form. May be you want to add a button to concel uploading.
On the view, you should add some tag to show errors (there are lots of info about validation helpares) like in:
<?=form_open_multipart("/personas/savefoto", array('class' => "form3") )?>
<h3><?=$heading?></h3>
<div class="center">
<?php echo '<strong>'.mb_convert_case($record['nombre'].' '.$record['apellido1'].' '.$record['apellido2'], MB_CASE_TITLE).'</strong><br/>';
if( file_exists("fotos/e".MATRIZ."/b".$record['id'].".jpg")){
?>
<img class="foto" src="<?php echo base_url()."fotos/e".MATRIZ."/b".$record['id']?>.jpg"/>
<br/><br/>
<?php
} ?>
</div>
<div class="form-row">
<label for="imagen">Nueva imagen <br/>(jpg, gif o png)</label>
<input type="file" name="userfile" size="20" />
<br/>
<?php if(isset($error_image)) echo '<p class="error">'.$error_image.'</p>'; ?>
</div>
<div class="form-row center">
<input type="submit" value="Aceptar" />
<input type="button" value="Cancelar" onclick="location.href='/system.php/personas/admin';">
</div>
<?=form_close();?>
look for the if(isset($error_image))
You could utilize the validation_errors() function and set them to a session variable
$this->session->set_userdata(array('form_errors', validation_errors()));
then access them on your redirect page.
echo $this->session->userdata('form_errors');
$this->session->unset_userdata('form_errors'); // prevent them from being stored past use

Categories