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.
Related
I'd like some help please. I have created a form with CodeIgniter where I can write posts and what I 'd like to do is to add the functionality to upload image(s) for this post.
At the beginning I thought to add an input field in my form where I can upload files, so I can display them above the content (text) at the front end, but although this is a very quick and easy solution, may be not so flexible. So I thought to use the 'insert/edit image' button that tinymce has.
I haven’t done this before so how can I upload an image or images through tinymce so that they appear within the text at the front-end??
EDIT Here is my code.
This is my view:
<?php echo form_open_multipart(); ?>
<div>
<label for="title">Title *</label>
<?php echo form_input('title', html_escape(set_value('title', $article->title))); ?>
</div>
<div>
<label for="file">Upload image</label>
<?php echo form_upload('file'); ?>
</div>
<div>
<label for="body">Body *</label> // has TinyMce
<?php echo form_textarea('body', strip(set_value('body', $article->body))); ?>
</div>
<div>
<?php echo form_submit('save', 'Save'); ?>
</div>
<?php echo form_close(); ?>
This is my model:
public function save($id = null){
$post_data = array(
'title' => $this->input->post('title'),
'file' => $this->input->post('file'),
'body' => $this->input->post('body'),
);
return parent::save($post_data, $id);
}
This is the controller:
public function article($id = null){
....
$this->form_validation->set_rules($this->article_model->rules);
// Process the form
if ($this->form_validation->run() == TRUE) {
$this->article_model->save($id);
redirect('admin/article');
}
}
There are two approaches to this.
You either keep an upload field outside TinyMCE and use ajax/iframe file upload.
OR
Write a TinyMCE plugin with an ability to upload an image.
Please note that both of these approaches take some effort to implement.
As far as handling the file on the server side is concerned, you can go through the Codeigniter Docs to get you started.
In my opinion , I think that you should use separate field to upload images to server as this helps you control them , resize , determine file name and upload path
you can use form_open_multipart() Codeigniter function to upload files
then you can make a DB table field called image and insert the uploaded file name to it
then retrieving the post you can
<img src="<?php echo $post->image; ?>" />
<p><?php echo $post->content ?></p>
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.
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
Due-diligence done, once again I return to the experts. Please forgive my ignorance, new to all this.
I'm trying to create a form which allows users to:
Insert the values of various form fields into a mysql database table - Easy, no issues here.
Attach a file which is saved within the file structure (in a folder called 'documents').
Save the file name, size, type (pdf, txt, etc.) to the same record.
After a file is uploaded the table would contain:
id (auto incremented)
name (text field, user generated)
description (text field, user generated)
File name (e.g. text.txt, added automatically on upload)
File size (e.g. 362455[kb], added automatically on upload)
File type (e.g. pdf, added automatically on upload)
I've successfully saved files to the folder but have not been able to make my three requirements a reality... Despite hours or troubleshoot and Googling.
The database and form are correct, the php file I post to is the mystery. Any ideas?
<form method="post" id="addForm" action="includes/insert_news.php">
<table class="addForm" cellspacing="0">
<tr>
<th>Name:<span class="greenText">*</span></th>
<td><input name="name" type="text" class="textBox required" value="Friendly Document Name" maxlength="80" /></td>
</tr>
<tr>
<th>Description:<span class="greenText">*</span></th>
<td><textarea name="description" class="textBox required">Document description blah blah</textarea></td>
</tr>
<tr>
<th>File:</th>
<td><input name="file" class="textBox" /></td>
</tr>
<tr>
<th> </th>
<td><input type="image" class="button" src="images/button_submit.gif" /></td>
</tr>
</table>
I am wondering you said that
I've successfully saved files to the
folder but
but I think you are not getting anything in the $_FILES because this thing is missing in your form tag
<form enctype="multipart/form-data">
Assuming that you have already added the missing thing #shakti pointed out, and you change the <input> by adding type="file" and since you didn't give any information about your php code, try these out:
<?php
class UploadFile{
//declare some variables in corresponding to your database field here, like fields, table name and stuffs
public function attach_file($file) {
if($file['error'] != 0) {
//do something
} else {
$this->temp_path = $file['tmp_name'];
$path_parts = pathinfo($file['name']);
$this->filename = $path_parts['extension'];// to get the filename
$this->type = $file['type'];// to get the file type
$this->size = $file['size'];// to get the size
$this->name = $name;
$this->description = $description;
}
}
public function save() {
$target_path = "/some/folder";
if(move_uploaded_file($this->temp_path, $target_path)) {
if($this->create()) {
unset($this->temp_path);
return true;
}
} else {
return false;
}
}
public function create() {
//your INSERT INTO
}
?>
and in your insert_news.php :
<?php
require_once("class/location");
if($_FILES['file']) {
$news = new UploadFile();
$news->attach_file($_FILES['main_picture'], $_POST['name'], $_POST['description']);
if($pic->save()){
//do something
}
}
?>
haven't tested this, but i hope you get the point :D
How do you use the email->attach function?
I can't figure what is happen, cos when i put the code for email->attach the mesage came in blank(the mail body) and there is no attach.
If i remove that code line, everything come back to normal..
thank you
my controller (sendmail.php)
<?php
class Sendmail extends Controller {
function __construct() {
parent::Controller();
$this->load->library('email');
$this->load->helper('url');
$this->load->helper('form');
$this->load->library('validation');
}
function index() {
$info = array (
'nome' => $this->input->post('nome'),
'mail' => $this->input->post('email'),
'motivo' => $this->input->post('motivo'),
'mensagem' => $this->input->post('mensagem'),
'anexo' => $this->input->post('upload'),
);
$this->load->library('email');
$this->email->set_newline('\r\n');
$this->email->clear();
$this->email->from($info['mail'], $info['nome']);
$this->email->to('example#mai.com');
/* $this->email->cc(''); # não é preciso */
$this->email->subject($info['motivo']);
$this->email->message($info['mensagem']);
$this->email->attach($info['anexo']);
if ($this->email->send() ) {
echo 'sent';
}
else {
$this->load->view('formulario');
# show_error( $this->email->print_debugger() );
}
}
}
?>
my view (formulario.php)
<?php
echo form_open_multipart('davidslv/index.php/sendmail');
?>
<label for="nome">nome</label>
<input type="text" name="nome" id="nome" required />
<label for="email">email</label>
<input type="text" name="email" id="email" required />
<label for="assunto">assunto</label>
<select name="motivo">
<option value="motivo1">motivo1</option>
<option value="motivo2">motivo2</option>
<option value="motivo3">motivo3</option>
</select>
<p> <label for="mensagem">mensagem</label>
<textarea name="mensagem" id="mensagem" rows="8" cols="30" required></textarea>
</p>
<label for="upload">documento</label>
<input type="file" id="upload" name="upload" size="18"/>
<input type="submit" id="enviar" name="enviar" value="Enviar!" />
</form>
You can not directly attach a file from the upload field of your form to an email. You can only attach files to your email from your server, so you need to upload the file from the form with CIs upload library: $this->upload->do_upload() to your server into some directory. the upload library needs to be configured, which file types are allowed etc. if the upload was successful, the do_upload function returns extensive data about where the file is stored. you can use the 'full_path' index from the array to attach this file to the email. then send the mail. after that you may delete the file from your server. Here are some code fragments that might help.
$this->load->library('upload');
if($_FILES['upload']['size'] > 0) { // upload is the name of the file field in the form
$aConfig['upload_path'] = '/someUploadDir/';
$aConfig['allowed_types'] = 'doc|docx|pdf|jpg|png';
$aConfig['max_size'] = '3000';
$aConfig['max_width'] = '1280';
$aConfig['max_height'] = '1024';
$this->upload->initialize($aConfig);
if($this->upload->do_upload('upload'))
{
$ret = $this->upload->data();
} else {
...
}
$pathToUploadedFile = $ret['full_path'];
$this->email->attach($pathToUploadedFile);
...
$this->email->send();
...
}
...
Hope this helped...
$this->email->attach()
Enables you to send an attachment. Put
the file path/name in the first
parameter. Note: Use a file path, not
a URL. For multiple attachments use
the function multiple times. For
example:
$this->email->attach('/path/to/photo1.jpg');
$this->email->attach('/path/to/photo2.jpg');
$this->email->attach('/path/to/photo3.jpg');
$this->email->send();
Codeigniter Email Class
This is Absolutely right code Please Try
$config['upload_path'] = './uploads';
$config['allowed_types'] = 'gif|jpg|jpeg|png|txt|php|pdf';
$config['max_size'] = '9000';
$config['encrypt_name'] = true;
$image_data = $this->upload->data();
$fname=$image_data[file_name];
$fpath=$image_data[file_path].$fname;
$this->email->attach($fpath);
step 1:You can not directly attach a file from the upload field of your form to an email. You can only attach files to your email from your server, so you need to upload the file from the form with CIs upload library:
$this->upload->do_upload() to your server into some directory.
step 2:
$file=upload file;
$file_path='uploaded directory on your server(eg:uploads/career)'.$file;
step 3:just include
$this->email->attach($file_path);
$this->email->send();
This is a late update, but it might be useful.
It was said twice
"You can not directly attach a file from the upload field of your form
to an email"
. However, this works fine in Codeigniter 3.0
foreach ($_FILES as $key => $file)
{
if ($file['error'] == 0)
{
$this->email->attach($file['tmp_name'], '', $file['name']);
}
}
(Though, the email is not sent and no errors are shown, if there are two files with the same name)