Part of the EllisLab Network
   
1 of 2
1
Multiple file uploads
Posted: 18 September 2008 07:28 PM   [ Ignore ]  
Grad Student
Rank
Total Posts:  40
Joined  04-24-2008

Hi there,

I have a form like so:

<form action="upload" enctype="multipart/form-data" method="post">
    <
input type="file" name="featured_image[0]">
    <
input type="file" name="featured_image[1]">
    <
input type="file" name="featured_image[2]">
    <
input type="file" name="featured_image[3]">
    <
input type="submit" value="Upload Images">
</
form

How can I use the upload library with the above form?

I get an error when I try to upload (You did not select a file to Upload.)

Profile
 
 
Posted: 18 September 2008 09:05 PM   [ Ignore ]   [ # 1 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2770
Joined  07-27-2006

You either need to give each file input a unique name (featured_image_0, featured_image_1) etc, and process each one in a loop, or overload the Uploader class to handle file upload arrays.

Copying this from an earlier post I made:

So, yeah, I was failing to pass $config from my constructor to CI_Upload’s constructor…

I also updated it so the API remains the same, just call $this->upload->do_upload(), not ->do_multi_upload()

<?php

class MY_Upload extends CI_Upload {
   
   
function MY_Upload($props = array())
   
{
      parent
::CI_Upload($props);
   
}
   
   
function do_upload($field 'userfile')
   
{
      $success 
FALSE;
      if (isset(
$_FILES[$field]) and is_array($_FILES[$field]['error']))
      
{
         
// Create a pseudo file field for each file in our array
         
for ($i 0$i count($_FILES[$field]['error']); $i++)
         
{
            
// Give it a name not likely to already exist!
            
$pseudo_field_name '_psuedo_'$field .'_'$i;
            
// Mimick the file
            
$_FILES[$pseudo_field_name] = array(
               
'name' => $_FILES[$field]['name'][$i],
               
'size' => $_FILES[$field]['size'][$i],
               
'type' => $_FILES[$field]['type'][$i],
               
'tmp_name' => $_FILES[$field]['tmp_name'][$i],
               
'error' => $_FILES[$field]['error'][$i]
            
);
            
// Let do_upload work it's magic on our pseudo file field
            
$success parent::do_upload($pseudo_field_name);
         
}
      }
      
else
      
// Works just like do_upload since it's not an array of files
      
{
         $success 
parent::do_upload($field);
      
}
      
return $success;
   
}
   

A few caveats that should be addressed: The $this->upload->data() method will only return data of the last file to be uploaded, not all files uploaded. If one of the fields errors, there is no way to know which individual one was erroneous. Not impossible problems to solve, but the code above has yet to address either of them. I’ll work on rounding it out if I get some time, or need to do it myself.

For now, it might be good to just have unique names for x number of upload fields, then process each one individually.

Here’s my controller:

<?php

class Upload extends Controller {
   
   
function Upload()
   
{
      parent
::Controller();
   
}
   
   
function index()
   
{
      $data 
= array(
         
'error' => array(),
         
'upload_data' => array(),
      );
      
      
$this->load->helper('form');
      
      
$config['upload_path''uploads';
      
$config['allowed_types''gif|jpg|png';
      
$config['max_size''2048';
      
$config['max_width''1024';
      
$config['max_height''768';
      
$this->load->library('upload'$config);
      
      if ( ! 
$this->upload->do_upload())
      
{
         $data[
'error'= array('error' => $this->upload->display_errors());
      
}  
      
else
      
{
         $data[
'upload_data'$this->upload->data();
      
}
      
      $this
->load->view('sandbox/upload'$data);
      
   
}
   

And my view:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
>
<
html >
<
head>
   <
title>Multi Upload Test</title>
   <
meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</
head>
<
body>
   
   
<? foreach ($error as $msg) : ?>
   
<div style="color: red; display: block; margin: 12px 0"><?$msg ?></div>
   
<? endforeach; ?>
   
   <? 
if (count($upload_data)) : ?>
      
<ul>
      
<?php foreach($upload_data as $item => $value):?>
         
<li><?php echo $item;?><?php echo $value;?></li>
      
<?php endforeach; ?>
      
</ul>
   
<? endif; ?>
   
   
<h1>Single File Upload</h1>
   
   
<?form_open_multipart('sandbox/upload'?>
      
<div><?form_upload('userfile'?></div>
      <
div><button type="submit">Upload!</button></div>
   </
form>
   
   <
h1>Multiple File Upload</h1>
   
   
<?form_open_multipart('sandbox/upload'?>
      
<div><?form_upload('userfile[]'?></div>
      <
div><?form_upload('userfile[]'?></div>
      <
div><?form_upload('userfile[]'?></div>
      <
div><button type="submit">Upload!</button></div>
   </
form>
   
</
body>
</
html
 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

Profile
 
 
Posted: 18 September 2008 09:16 PM   [ Ignore ]   [ # 2 ]  
Grad Student
Rank
Total Posts:  40
Joined  04-24-2008

I never thought about that, but now I am doing using a completely separate field for each file…it is working perfectly!

Here’s my code:

public function upload()
        
{
            
// setup the config
            
$config['upload_path']   "/Projects/{$this->config->item('common_path')}/assets/images/series/featured/";
            
$config['allowed_types''gif|jpg|png';
            
$config['overwrite']     TRUE;
            
$config['remove_spaces'TRUE;
            
$this->load->library('upload'$config);
            
            
$image_types = array("image/jpeg""image/gif""image/x-png""image/png");
            
            
$images      = array();
            
// $imagesarray = array();
            
$series $this->input->post('featured_series');
            
// we are saving the featured series...
            
for($i =0$i <= count($_FILES); $i++)
            
{
                
if(in_array(strtolower($_FILES['featured_image_'.$i]['type']), $image_types))
                
{
                    
// get the extension
                    
$extension split("[/\\.]"strtolower($_FILES['featured_image_'.$i]['name']));
                    
$extension $extension[(count($extension)) - 1];
                    
                    
// get the new filename...
                    
$category $this->category_model->getCatbyID($series[$i]);
                    
$_FILES['featured_image_'.$i]['name'url_title(strtolower($category['name']), 'dash') . '.' $extension;
                    if(!
$this->upload->do_upload("featured_image_{$i}"))
                    
{
                        $error 
$this->upload->display_errors();
                        
dump($error);
                    
else {
                        $data 
$this->upload->data();
                        
dump($data);                    
                    
}
                }
            }
        } 

Obviously I am going to need to edit the $config stuff (gonna chuck that in config/upload.php)

Profile
 
 
Posted: 18 September 2008 09:19 PM   [ Ignore ]   [ # 3 ]  
Grad Student
Rank
Total Posts:  40
Joined  04-24-2008

I forgot to mention, but there are some custom things in there..

This is basically a system to let my users select a ‘series’ to show on the front page of my website.

I am renaming the image file for normalization reasons (I never need to store that info in the database, since the system will know exactly what the image name is based on the category).

Profile
 
 
Posted: 18 September 2008 11:34 PM   [ Ignore ]   [ # 4 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2770
Joined  07-27-2006

That is definitely the route to go in order to work nicely with the standard Upload class.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

Profile
 
 
Posted: 19 September 2008 08:06 AM   [ Ignore ]   [ # 5 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  547
Joined  07-28-2008

I see that you are on the right track, and one thing I would like to point out is that when naming your files, dont give them a position in the array.

IE

<form action="upload" enctype="multipart/form-data" method="post">
    <
input type="file" name="featured_image[]">
    <
input type="file" name="featured_image[]">
    <
input type="file" name="featured_image[]">
    <
input type="file" name="featured_image[]">
    <
input type="submit" value="Upload Images">
</
form

That way, if a user adds an image to the second one and maybe 4th, it will end up generating an array on the server side of simply 1 & 2.

Just personal preference I guess, but I have always seen it done this way.

 Signature 

~ 4 All the Right Reasons ~

Profile
 
 
Posted: 19 September 2008 03:44 PM   [ Ignore ]   [ # 6 ]  
Grad Student
Rank
Total Posts:  40
Joined  04-24-2008

Actually, if I use an array, it makes it hell to use the standard upload class (because it is not expecting a multi-dimensional array for the fields)...so instead, I am using _1, _2, _3, etc

Profile
 
 
Posted: 24 December 2008 04:16 PM   [ Ignore ]   [ # 7 ]  
Summer Student
Total Posts:  27
Joined  10-06-2008

I’m using the code from Colin Williams and it works great.
But how do I incorporate the image_lib class to upload multiple images and then resize them?

Profile
 
 
Posted: 24 December 2008 10:32 PM   [ Ignore ]   [ # 8 ]  
Grad Student
Rank
Total Posts:  46
Joined  09-21-2008

Another option is to use the library I published at

http://www.mitesdesign.com/blog/open-source/multi-upload-jquery-code-igniter

uses a JQuery dialog to upload multiple files from a single input, though the process beyond that is much the same as what’s been posted, though I don’t know if they’ve tested their code yet,

gotta love the community here

Profile
 
 
Posted: 27 December 2008 12:04 AM   [ Ignore ]   [ # 9 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2770
Joined  07-27-2006

My offering is more of the start of a solution, not a complete one. Seems better to just name your fields uniquely and upload them in a loop.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

Profile
 
 
Posted: 27 December 2008 08:52 AM   [ Ignore ]   [ # 10 ]  
Grad Student
Rank
Total Posts:  46
Joined  09-21-2008

the advantage of my release is the integration of the JQuery multi-upload plugin

thus 1 upload button = (name your limit) # of files

suppose plugging it into the WIKI might be a good idea

Happy Holidays

Profile
 
 
Posted: 07 February 2009 04:30 PM   [ Ignore ]   [ # 11 ]  
Grad Student
Rank
Total Posts:  82
Joined  05-31-2008

does CI 1.7 has any new solution for this or is this still the best solution?

 Signature 

http://www.MIMAteam.com

Profile
 
 
Posted: 07 February 2009 07:35 PM   [ Ignore ]   [ # 12 ]  
Grad Student
Rank
Total Posts:  46
Joined  09-21-2008

this is the best solution that I’m aware of, short of building your own which isn’t particularly difficult,

if you are looking for something more customized then feel free to play with it and make it your own

Profile
 
 
Posted: 13 February 2009 03:02 PM   [ Ignore ]   [ # 13 ]  
Grad Student
Avatar
Rank
Total Posts:  55
Joined  12-19-2007
amites - 24 December 2008 10:32 PM

Another option is to use the library I published at

http://www.mitesdesign.com/blog/open-source/multi-upload-jquery-code-igniter

uses a JQuery dialog to upload multiple files from a single input, though the process beyond that is much the same as what’s been posted, though I don’t know if they’ve tested their code

I was already using the jquery multifile upload plugin but ran into the issue everyone else is having here. Was glad to find your CI library, but I’m having some trouble with it. Mainly, it’s not uploading the files, and not reporting any errors back to me.

INPUT:

<input type="file" name="userfile[]" id="claimfile" class="multi" maxlength="5" accept="pdf|doc|docx|xls|gif|jpg|zip"/> 

CONTROLLER:

$config['upload_path''/files/';
$config['allowed_types''pdf|doc|docx|xls|gif|jpg|zip';
$config['max_size']    '0';
$config['encrypt_name'TRUE;
$this->load->library('upload'$config);
$this->load->library('Multi_upload'); 

Now, I should note that I’m passing along other form data that I’m running through CI’s standard validation routines. If there are no other form validation errors, then I check on my files. This is almost a verbatum copy/paste from your sample code:

$files $this->multi_upload->go_upload();
                
if ( ! 
$files {
    $x[
'error'= array('error' => $this->upload->display_errors());
    
$this->load->view('/admin/jobs_add_v'$x);
else {
    $x[
'data'= array('upload_data' => $files);
    
$job_id $this->Sql->insertJob($_POST); # from form data
    
$this->load->view('/admin/jobs_add_v',$x);

$error is echo’d out on the view page, and contains nothing; neither does $data. And the files are not uploaded. My logs also don’t indicate any errors.

Any ideas?

thanks,
Bob

 Signature 

Bob Sawyer
Head Chef, Web Design & Development
Pixels and Code, LLC
http://www.pixelsandcode.net

Profile
 
 
Posted: 13 February 2009 04:41 PM   [ Ignore ]   [ # 14 ]  
Grad Student
Avatar
Rank
Total Posts:  55
Joined  12-19-2007

Disregard… I had made some modifications to the jquery.MultiFile.js file that were causing problems.

 Signature 

Bob Sawyer
Head Chef, Web Design & Development
Pixels and Code, LLC
http://www.pixelsandcode.net

Profile
 
 
Posted: 14 February 2009 01:57 PM   [ Ignore ]   [ # 15 ]  
Summer Student
Total Posts:  15
Joined  10-19-2008
Bob Sawyer - 13 February 2009 04:41 PM

Disregard… I had made some modifications to the jquery.MultiFile.js file that were causing problems.

Can you post/tell the modifications you did?
I’m having the same problem and can’t figure it out :S

Profile
 
 
   
1 of 2
1
 
Post Marker Legend
New Topic New posts Hot Topic Hot Topic with new posts New Poll New Poll Moved Topic Moved Topic Sticky Topic Sticky topic
Old Topic No new posts Hot Old Topic Hot Topic with no new posts Old Poll Old Poll Closed Topic Closed Topic Announcement Announcements
Theme
Change Theme
Visitor Statistics
The most visitors ever was 819, on March 11, 2010 11:15 AM
Total Registered Members: 149967 Total Logged-in Users: 42
Total Topics: 103610 Total Anonymous Users: 4
Total Replies: 518110 Total Guests: 428
Total Posts: 621720    
Members ( View Memberlist )