How to output uploading errors as flashdata - CodeIgniter - codeigniter

I'm wanting to display any errors produced while uploading a file by redirecting the user back to the same page they used to upload the file. The thing is that I pre-populate some inputs on that page, so I can't use redirect(controller/method_to_load_page) as that wouldn't carry out the data population.
Using $this->load->view('add_page',$error); won't work either (the way that I'm using it), because although that will show the errors, it won't show the input fields with the pre-populated data.
This is the method in my controller which loads the form to upload a file and other fields:
public function add_products_page()
{
//get each categories subcategory and place them in their own variable
$data['categories1'] = $this->admin_model->getSubcategories('1');
$data['error'] = '';
$this->load->view('add_page',$data);
}
And from that page, the user can fill in the form and choose an image. The form will then be submitted to this method in the same controller:
public function add_book()
{
$id = $this->admin_model->add_book();
$config['file_name'] = $id;
$config['upload_path'] = './images/';
$config['allowed_types'] = 'jpg';
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload())
{
$error = array('error' => $this->upload->display_errors());
$this->load->view('add_page', $error);
}
else
{
redirect('admin/add_products_page', 'refresh');
}
}
If there are no errors, the redirect to add_products_page() method is okay, however when there's an error, the view 'add_page' is loaded and the errors are shown, but my pre-populated field isn't populated anymore because the method to do that isn't being called.
So I really would like to know how I can both load my view by calling the method add_products_page to populate my input fields, and also show errors when they occur. Please if someone could help I would appreciate it greatly.

Why post to a different method and then redirect? You can handle it all in the same method.
public function add_products_page()
{
if ($this->input->server('REQUEST_METHOD') == 'POST')
{
$result = $this->_add_book();
if ($result['is_error'])
{
// TODO: whatever it takes to show an error message
$data['error'] = $result['message'];
}
else
{
// TODO: whatever it takes to show a success message
$data['error'] = '';
}
}
//get each categories subcategory and place them in their own variable
$data['categories1'] = $this->admin_model->getSubcategories('1');
$this->load->view('add_page',$data);
}
public function _add_book() // add underscore so it's not directly accessible
{
$result = array(
'is_error' => TRUE,
'message' => '',
);
$id = $this->admin_model->add_book();
$config['file_name'] = $id;
$config['upload_path'] = './images/';
$config['allowed_types'] = 'jpg';
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload())
{
$error = array('error' => $this->upload->display_errors());
// set an error message
$result['message'] = $error;
}
else
{
// set a success message
$result['is_error'] = FALSE;
$result['message'] = 'SOME SUCCESS MSG';
}
return $result;
}

Related

Error while uploading Image and image name in database, codeigniter

There is an error while uploading an image in Codeigniter. The file name noimage is saved in the database.
// Upload Image Controller
$config['upload_path'] = './assets/Images/profilepictures';
$config['allowed_types'] = 'gif|jpg|png|jpeg';
$config['max_size'] = '2048';
$config['max_width'] = '2000';
$config['max_height'] = '2000';
$this->load->library('upload', $config);
if(!$this->upload->do_upload()){
$errors = array('error' => $this->upload->display_errors());
$post_image = 'noimage.jpg';
} else {
$data = array('upload_data' => $this->upload->data());
$post_image = $_FILES['userfile']['name'];
}
$this->m_user->profilepicture($post_image);
if($data['user']->profile_pic==null)
{
redirect(base_url().'user/profilepicture/');
}
Model
public function profilepicture($post_image){
$userID = $this->session->userdata("user_id");
$data = array(
'profile_pic' => $post_image,
);
$this->db->where('user_id', $userID);
$this->db->update('users', $data);
}
Your Image Name is not inserting in the database, because in your update query, you have not passed the $userID value.
Changes in Model =>
public function profilepicture($userID,$post_image) //Pass $userID here from Controller.
{
$data = array(
'profile_pic' => $post_image,
);
$this->db->where('user_id', $userID);
$this->db->update('users', $data);
}
Changes in Controller =>
$userID = $data['user']->user_id; //Add this line.
$this->m_user->profilepicture($userID,$post_image); //Update here
Your page is redirected because profile_pic is always null as it isn't updated in database. So after you successfully insert profile_pic in your database, your page will not redirected to redirect(base_url().'user/profilepicture/');.
When the image is not uploading try to redirect back to the form and don't add noimage.jpg to database
if(!$this->upload->do_upload()){
$errors = array('error' => $this->upload->display_errors());
//Redirect to form with error message
} else {
//Get image name like this
$data = $this->upload->data();
$post_image = $data['file_name'];
//Call model function only when image successfully uploaded
$this->m_user->profilepicture($post_image);
}
Call model function only when image successfully uploaded
So, remove this condition if($data['user']->profile_pic==null)

Saving multiple images for one product using one to many in codeigniter

I am new in code igniter.
Here is what I am trying to do. I have lists of products stored in database table name products. For each products i need to insert multiple images. I have created two tables, products and productimage. I have made the product_id of table productimage the foreign key, referencing the product_id of table products. Now i want to save the datas from form. Here is what i did previously Saving images in a single row by imploding
But it became quite difficult for me to manage CRUD(like editing and deleting pictures).
So i am trying to do the above mentioned way. I am not finding the way to start. Can anyone please instruct me, how can I start?
Okay now I have done some coding here. This is my controller:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Products extends CI_Controller{
public function __construct()
{
parent::__construct();
$this->load->model('product_model');
$this->load->helper(array('form','url'));
//Codeigniter : Write Less Do More
}
public function index()
{
$data['products']=$this->product_model->get_product();
$this->load->view('/landing_page',$data);
}
public function create()
{
#code
$this->load->helper('form');
$this->load->library('form_validation');
$this->form_validation->set_rules('product_name','Product_Name','required');
if($this->form_validation->run()=== FALSE)
{
$this->load->view('products/create');
}
else {
$this->product_model->set_product();
$data['products']=$this->product_model->get_product();
redirect('/');
}
}
}
This is my model:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Product_model extends CI_Model{
public function __construct()
{
$this->load->database();
parent::__construct();
//Codeigniter : Write Less Do More
}
public function get_product()
{
#code
$query=$this->db->get('products');
return $query->result_array();
}
public function set_product($id=0)
{
#code
// if($this->input->post('userSubmit')){
$picture=array();
$count=count($_FILES['picture']['name']);
//Check whether user upload picture
if(!empty($_FILES['picture']['name'])){
foreach($_FILES as $value)
{
for($s=0; $s<=$count-1; $s++)
{
$_FILES['picture']['name']=$value['name'][$s];
$_FILES['picture']['type'] = $value['type'][$s];
$_FILES['picture']['tmp_name'] = $value['tmp_name'][$s];
$_FILES['picture']['error'] = $value['error'][$s];
$_FILES['picture']['size'] = $value['size'][$s];
$config['upload_path'] = 'uploads/images/';
$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);
// print_r($value['name'][$s]);exit;
if($this->upload->do_upload('picture')){
$uploadData = $this->upload->data();
$picture[] = $uploadData['file_name'];
}
else{
$picture = '';
}
}
}
}//end of first if
else{
$picture = '';
}
$data=array(
'product_name'=>$this->input->post('product_name')
);
$picture=array(
'product_id'=>$this->db->get('products',$id),
'picture_image'=>$picture
);
if ($id==0)
{
return $this->db->insert('products',$data);
return $this->db->insert('images',$picture);
}
else {
$this->db->where('id',$id);
return $this->db->update('products',$data);
return $this->db->update('images',$picture);
}
}
}
Noe the case is when my form opens i am being able to fill product name and upload image files. When i submit it doesn't throws any errors too. But only product name is stored in products table and nothing happens to images table. No any images are inserted. Neither any error is thrown by browser. Simply images
table is empty. What's the problem here?
Let me help you with the Controller .. You need to check for all the uploaded files. They are $_FILES. Loop through the array, upload them on the server and than call a model function to add them in your product Images table
If CI Upload is too tricky for you. Use the following Controller function
public function upload_images()
{
// following IF statement only checks if the user is logged in or not
if($this->session->userdata['id'] && $this->session->userdata['type']=='user')
{
if($_FILES)
{
// check whether there are files uploaded / posted
if(isset($_FILES['files'])){
$data['errors']= array();
$extensions = array("jpeg","jpg","png");
//Loop through the uploaded files
foreach($_FILES['files']['tmp_name'] as $key => $tmp_name ){
$file_name = $key.$_FILES['files']['name'][$key];
$file_size =$_FILES['files']['size'][$key];
$file_tmp =$_FILES['files']['tmp_name'][$key];
$i=1;
if($file_size > 2097152){
$data['errors'][$i]='File '.$i.' size must be less than 2 MB';
$i++;
}
// Set upload destination directory
$desired_dir="uploads";
if(empty($data['errors'])==true){
if(is_dir($desired_dir)==false){
mkdir("$desired_dir", 0700); // Create directory if it does not exist
}
if(is_dir("$desired_dir/".$file_name)==false){
// Upload the file.
move_uploaded_file($file_tmp,"uploads/".$file_name);
// Call a function from model to save the name of the image in images table along with entity id
$this->post_model->addImage('property_images',$file_name,$this->uri->segment(3));
}else{ //rename the file if another one exist
$new_dir="uploads/".$file_name.time();
rename($file_tmp,$new_dir) ;
}
}else{
$data['contact']=$this->admin_model->getContactDetails();
$data['images']=$this->post_model->getPropertyImages($this->uri->segment(3));
//load views
}
}
if(empty($data['errors']))
{
redirect(base_url().'dashboard');
}
else
{
$data['contact']=$this->admin_model->getContactDetails();
$data['images']=$this->post_model->getPropertyImages($this->uri->segment(3));
//load views
}
}
}
else
{
//Load view
}
}
else
{
redirect(base_url().'user/login');
}
}
Incase anyone is having the same problem then here is the solution. Just do this in your upload function.(code by my friend Amani Ben azzouz)
public function set_product($id=0){
$picture=array();
$count=count($_FILES['picture']['name']);
//Check whether user upload picture
if(!empty($_FILES['picture']['name'])){
foreach($_FILES as $value){
for($s=0; $s<=$count-1; $s++){
$_FILES['picture']['name']=$value['name'][$s];
$_FILES['picture']['type'] = $value['type'][$s];
$_FILES['picture']['tmp_name'] = $value['tmp_name'][$s];
$_FILES['picture']['error'] = $value['error'][$s];
$_FILES['picture']['size'] = $value['size'][$s];
$config['upload_path'] = 'uploads/images/';
$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);
// print_r($value['name'][$s]);exit;
if($this->upload->do_upload('picture')){
$uploadData = $this->upload->data();
$picture[] = $uploadData['file_name'];
}
}
}
}//end of first if
$data=array('product_name'=>$this->input->post('product_name'));
if ($id==0){
$this->db->insert('products',$data);
$last_id = $this->db->insert_id();
if(!empty($picture)){
foreach($picture as $p_index=>$p_value) {
$this->db->insert('images', array('product_id'=>$last_id,'images'=>$p_value));
}
}
}
else {
$this->db->where('id',$id);
$this->db->update('products',$data);
if(!empty($picture)){
foreach($picture as $p_index=>$p_value) {
$this->db->update('images', array('product_id'=>$last_id,'images'=>$p_value) ); // --> this one?
}
}
}
}
This is for inserting and updating too. If you simply want do insert just delete the parameter passed as 'id' and cut that if and else part write a plain code of inside 'if'.
function contract_upload(){ // function to call from your view.
$data = array();
// If file upload form submitted
if(!empty($_FILES['files']['name']) AND !empty('user_id')){
$filesCount = count($_FILES['files']['name']);
for($i = 0; $i < $filesCount; $i++){
$_FILES['file']['name'] = $_FILES['files']['name'][$i];
$_FILES['file']['type'] = $_FILES['files']['type'][$i];
$_FILES['file']['tmp_name'] = $_FILES['files']['tmp_name'][$i];
$_FILES['file']['error'] = $_FILES['files']['error'][$i];
$_FILES['file']['size'] = $_FILES['files']['size'][$i];
// File upload configuration
$uploadPath = './uploads/contract/';
$config['upload_path'] = $uploadPath;
$config['allowed_types'] = 'jpg|jpeg|png|gif';
$config['encrypt_name'] = TRUE;
// Load and initialize upload library
$this->load->library('upload', $config);
$this->upload->initialize($config);
// Upload file to server
if($this->upload->do_upload('file')){
// Uploaded file data
$fileData = $this->upload->data();
$uploadData[$i]['file_name'] = $fileData['file_name'];
$uploadData[$i]['emp_id'] = $this->input->post('user_id');
}
}
if(!empty($uploadData)){
// Insert files data into the database
$insert = $this->Contract_model->insert($uploadData);
// Upload status message
$statusMsg = $insert?'Files uploaded successfully.':'Some problem occurred, please try again.';
$this->session->set_flashdata('messageactive', $statusMsg);
}
}
redirect('contract'); // redirect link, where do you want to redirect after successful uploading of the file.
}
// Model Function
public function insert($data = array()){
$insert = $this->db->insert_batch('employee_contract_files', $data); // table name and the data you want to insert into database.
return $insert?true:false;
}
Remember one thing, you should write your HTML as below:
<input type="file" name="files[]" multiple />

codeigniter uploading image from form

I have a field of my form (which is uploading personal picture). So the user selects image from pc and submit the form. I am later on handling all posted data via:
$this->input->post()
My method for insertion into database is:
public function add_user()
{
$data = array(
'membership'=>$this->input->post('membership_type'),
'fullname'=>$this->input->post('fullname'),
'username'=>$this->input->post('username'),
'password'=>md5($this->input->post('password')),
'email'=>$this->input->post('email'),
'city'=>$this->input->post('city'));
'profilepic'=>$this->input->post('profilepic'));
$this->db->insert('members',$data);
}
Now what I want to insert in the profilepic field is the path to the image on the server. I know am doing it wrong above because this way am inserting the picture posted to profilepic. I need some correction please. Is there a function that can perform upload and return the path? but again how can I associate the upload of picture with upload of user data?
Regards,
EDIT: Tried the code provided below and got this:
A PHP Error was encountered
Severity: Notice
Message: Use of undefined constant full_path - assumed 'full_path'
Filename: models/membership_model.php
Line Number: 29
A PHP Error was encountered
Severity: Warning
Message: Cannot modify header information - headers already sent by
(output started at
/home2/xsysdeve/public_html/system/core/Exceptions.php:185)
Filename: core/Common.php
Line Number: 438
Please try this one:
public function add_user()
{
$config['upload_path'] = '/file_path/';
$config['allowed_types'] = 'gif|jpg|png|jpeg';
$this->load->library('upload', $config);
$this->upload->do_upload('profilepic');
$data_upload_files = $this->upload->data();
$image = $data_upload_files[full_path];
$data = array(
'membership'=>$this->input->post('membership_type'),
'fullname'=>$this->input->post('fullname'),
'username'=>$this->input->post('username'),
'password'=>md5($this->input->post('password')),
'email'=>$this->input->post('email'),
'city'=>$this->input->post('city'));
'profilepic'=>$image;
$this->db->insert('members',$data);
}
For more information visit this link: http://ellislab.com/codeigniter/user-guide/libraries/file_uploading.html
You can also try using 2 CI functions and check for the POST of the textual data as well as the image validation:
class SomeForm extends CI_Controller{
function add_user() //this function is your form
{
$this->load->view('templates/header');
$this->load->view('new_form_entry', array('error' => ' ' ));
$this->load->view('templates/footer');
}
function add_user_status() //this function is your form processing
{
$config['upload_path'] = './assets/images';
$config['allowed_types'] = 'gif|jpg|png';
//$config['max_size'] = '2000';
//$config['max_width'] = '340';
//$config['max_height'] = '190';
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload())
{
//check for errors with the upload
$error = array('error' => $this->upload->display_errors());
$this->load->view('templates/header');
$this->load->view('new_form_entry', $error);
$this->load->view('templates/footer');
}
else
{
//upload the new image
$upload_data = $this->upload->data();
$image_name = $upload_data['file_name'];
if($_POST){
$data = array(
'author'=>$_POST['author'],
'name'=>$_POST['name'],
'image_thumb'=>'../assets/images/'.$image_name,
'video'=>$_POST['video'],
'title'=>$_POST['title'],
'body'=>$_POST['body'],
'created' => date('Y-m-d H:i:s')
);
//insert the new post
$this->your_database_model_name->insert_entry($data);
}
redirect(base_url().'SomeForm/index');
}
}
}

Codeigniter - form validation doesn't work for files

i need to set a input file as required into my Codeigniter Controller.
This is my form_validation:
$this->form_validation->set_rules('copertina','Foto principale','required|xss_clean');
and this is the form:
<?php echo form_open_multipart('admin/canile/nuovo'); ?>
<li class="even">
<label for="copertina">Foto principale <span>*</span></label>
<div class="input"><input type="file" name="copertina" value="<?php echo set_value('copertina'); ?>" id="copertina" /></div>
</li>
<?php echo form_close(); ?>
But after the submit the form say that the file is not set, so the required clausole fails...how can i fix it?
File upload data is not stored in the $_POST array, so cannot be validated using CodeIgniter's form_validation library. File uploads are available to PHP using the $_FILES array.
It maybe possible to directly manipulate the $_POST array using data from the $_FILES array, before running form validation, but I haven't tested this. It's probably best to just check the upload library process for errors.
In addition, it is not possible, for security reasons, to (re-)set the value on page reload.
To make validation to work for files you have to check whether is it empty.
like,
if (empty($_FILES['photo']['name']))
{
$this->form_validation->set_rules('userfile', 'Document', 'required');
}
you can solve it by overriding the Run function of CI_Form_Validation
copy this function in a class which extends CI_Form_Validation .
This function will override the parent class function . Here i added only a extra check which can handle file also
/**
* Run the Validator
*
* This function does all the work.
*
* #access public
* #return bool
*/
function run($group = '') {
// Do we even have any data to process? Mm?
if (count($_POST) == 0) {
return FALSE;
}
// Does the _field_data array containing the validation rules exist?
// If not, we look to see if they were assigned via a config file
if (count($this->_field_data) == 0) {
// No validation rules? We're done...
if (count($this->_config_rules) == 0) {
return FALSE;
}
// Is there a validation rule for the particular URI being accessed?
$uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group;
if ($uri != '' AND isset($this->_config_rules[$uri])) {
$this->set_rules($this->_config_rules[$uri]);
} else {
$this->set_rules($this->_config_rules);
}
// We're we able to set the rules correctly?
if (count($this->_field_data) == 0) {
log_message('debug', "Unable to find validation rules");
return FALSE;
}
}
// Load the language file containing error messages
$this->CI->lang->load('form_validation');
// Cycle through the rules for each field, match the
// corresponding $_POST or $_FILES item and test for errors
foreach ($this->_field_data as $field => $row) {
// Fetch the data from the corresponding $_POST or $_FILES array and cache it in the _field_data array.
// Depending on whether the field name is an array or a string will determine where we get it from.
if ($row['is_array'] == TRUE) {
if (isset($_FILES[$field])) {
$this->_field_data[$field]['postdata'] = $this->_reduce_array($_FILES, $row['keys']);
} else {
$this->_field_data[$field]['postdata'] = $this->_reduce_array($_POST, $row['keys']);
}
} else {
if (isset($_POST[$field]) AND $_POST[$field] != "") {
$this->_field_data[$field]['postdata'] = $_POST[$field];
} else if (isset($_FILES[$field]) AND $_FILES[$field] != "") {
$this->_field_data[$field]['postdata'] = $_FILES[$field];
}
}
$this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']);
}
// Did we end up with any errors?
$total_errors = count($this->_error_array);
if ($total_errors > 0) {
$this->_safe_form_data = TRUE;
}
// Now we need to re-set the POST data with the new, processed data
$this->_reset_post_array();
// No errors, validation passes!
if ($total_errors == 0) {
return TRUE;
}
// Validation fails
return FALSE;
}
Have you looked at this ->
http://codeigniter.com/user_guide/libraries/file_uploading.html
<?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);
}
}
}
?>
Update as per comment:
You can check using plain php if you like ...
$errors_file = array(
0=>'Success!',
1=>'The uploaded file exceeds the upload_max_filesize directive in php.ini',
2=>'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
3=>'The uploaded file was only partially uploaded',
4=>'No file was uploaded',
6=>'Missing a temporary folder',
7=>'Cannot write file to disk'
);
if($_FILES['form_input_file_name']['error'] == 4) {
echo 'No file uploaded';
}
if($_FILES['form_input_file_name']['error'] == 0) {
echo 'File uploaded... no errors';
}

Codeigniter FILE upload validation failure

My app uses Codeigniter validation successfully in multiple controller for various input fields. But when it comes to uploading and validating an uploaded image the validation complains.
I have the following form:
require_once('head.php');
echo 'Update Avatar';
if(validation_errors())
echo ''.validation_errors().'';
if($info)
echo '<div class="info">'.$info.'</div>';
$attributes = array('class' => 'updateavatarform', 'id' => 'updateavatarform');
echo form_open_multipart('user/avatar', $attributes);
echo '<div>Select Image</div>';
$data = array(
'name' => 'avatar',
'id' => 'avatar',
'value' => '',
'maxlength' => '',
'size' => '48',
);
echo form_upload($data);
echo '<br/><br/>';
echo form_submit('submit', 'Submit');
echo form_close();
require_once('footer.php');
The controller looks like:
function avatar()
{
$data['user'] = $this->authorize->isLoggedIn();
if(!$data['user'])
$this->authorize->protectUser();
$data['title'] = 'Evcenter User Update Avatar';
$data['keywords'] = 'alternative fuel';
$data['description'] = 'evcenter.org';
$data['info'] = FALSE;
if($_POST)
{
$this->load->model('User_model', '', TRUE);
$this->load->library('form_validation');
$input['avatar'] = trim($this->input->post('avatar', TRUE));
$this->form_validation->set_rules('avatar', 'Avatar', 'trim|required|xss_clean');
if($this->form_validation->run() == FALSE)
{
$this->load->view('avatar', $data);
}
else
{
$avatar = $this->User_model->getAvatar($data['user']['user_id']);
$old_avatar = $this->config->item('avatarpath').$avatar['avatar'];
unset($old_avatar);
$input['avatar'] = $this->uploadAvatar();
$input['id'] = $data['user']['user_id'];
$this->User_model->updateAvatar($input);
$data['info'] = 'Your avatar has been updated';
$this->load->view('avatar', $data);
}
}
else
{
$this->load->view('avatar', $data);
}
}
The validation throws the following error with or w/o an uploaded image "The Avatar field is required." Needless to say $this->uploadAvatar(); works when called from the register controller.
Can anyone see what's wrong?
Do FILE uploads need to be validated differently than text input?
Correct, files need to be validated differently than text inputs - as they are, not text inputs !
From the docs:
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);
}
}
note the call to $this->upload->do_upload() and $this->upload->display_errors()
Uploading in CI with text fields can be annoying (imo), I would upload the file first in your controller, then if it is successful do the rest of the POST data and update your database.
That way if there's a problem with the upload later on, you won't have invalid records.
*Assuming you already happen to have a MY_Form_Validation library that extends the built in CodeIgniter stuff.*
First
I added some functions to validate portions of the $_FILE upload based on this:
http://devbro.com/testing/ci_form_validation/
I just copied the functions, not the entire file. I don't need the custom run or execute methods. Just the validation methods. (I already have a customization that allows me to mix the form_validation config file AND the controller rules together.)
/**
* tests to see if a required file is uploaded
*
* #param mixed $file
*/
function file_required($file)
{
if($file['size']===0)
{
$this->CI->form_validation->set_message('file_required','Uploading a file for %s is required.');
return FALSE;
}
return TRUE;
}
/**
* tests the file extension for valid file types
*
* #param mixed $file
* #param mixed $type
*/
function file_allowed_type($file,$type)
{
//is type of format a,b,c,d? -> convert to array
$exts = explode(',',$type);
//is $type array? run self recursively
if(count($exts)>1)
{
foreach($exts as $v)
{
$rc = $this->file_allowed_type($file,$v);
if($rc===TRUE)
{
return TRUE;
}
}
}
//is type a group type? image, application, word_document, code, zip .... -> load proper array
$ext_groups = array();
$ext_groups['image'] = array('jpg','jpeg','gif','png');
$ext_groups['application'] = array('exe','dll','so','cgi');
$ext_groups['php_code'] = array('php','php4','php5','inc','phtml');
$ext_groups['word_document'] = array('rtf','doc','docx');
$ext_groups['compressed'] = array('zip','gzip','tar','gz');
$ext_groups['pdf'] = array('pdf');
if(array_key_exists($exts[0],$ext_groups))
{
$exts = $ext_groups[$exts[0]];
}
//get file ext
$file_ext = strtolower(strrchr($file['name'],'.'));
$file_ext = substr($file_ext,1);
if(!in_array($file_ext,$exts))
{
$this->CI->form_validation->set_message('file_allowed_type',"%s should be $type.");
return false;
}
else
{
return TRUE;
}
}
etc, etc.
Then
I added the rules I wanted to my form_validation.php config file, but I treat my FILE input as if were included in the $_POST. Of course it isn't, but I will fix that in a moment. DON'T use the other types of validations built into CodeIgniter, only use your FILE validations!
$config = array(
'form/index' => array(
array( 'field'=>'my_upload_file', 'label'=>'File To Upload', 'rules'=>'file_required|file_allowed_type[pdf]'),
...
Finally
In my controller, add the $_FILE['my_upload_file'] to the $_POST array
if ( isset($_FILES['my_upload_file']) )
{
$_POST['my_upload_file'] = $_FILES['my_upload_file'];
}
I think the big caveat is if you use the $_POST to populate your models or other actions. My code projects specifically grabs elements out of input->post() and I don't use mass assignment for much of anything. If you do use mass assignment, I would assume you messed up your assumptions.

Resources