• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
HTML5 Multiple File Upload

#1
[eluser]RMinor[/eluser]
I am trying to upload multiple files using a single HTML5 file input field. When I try to upload I get the following error " Illegal offset type in isset or empty" and "You did not select a file to upload." How would I go about fixing this issue? Thanks!

CONTROLLER
Code:
/**
  * Method to add photos
  * @param integer $gallery_id
  */
public function add_photos($gallery_id)
{
  // Retrieve page information
  $data['page_info'] = $this->Global_model->pageInfo($this->_page);
  // Retrieve gallery information
  $data['gallery_info'] = $this->Person_model->getGallery($gallery_id);
  
  $this->load->helper('form');
  if ($this->input->post('upload')) {
   $this->load->library('form_validation');
   $this->form_validation->set_rules('gallery_id', 'Gallery ID', 'trim|required');
   if ($this->form_validation->run() == FALSE) {} else {
    $uploaded = array();
    $failed = array();
    foreach($_FILES['photo'] as $file) {
     if ($this->_uploadPhoto($file)) {
      $uploaded[] = $file;
     } else {
      $failed[] = $file;
     }
    }
   }
  }
  
  // Load required view and data
  $this->load->view('profile/add-photos_view', $data);
}

/**
  * Method to upload a photo
  * @param string $source
  * @return boolean
  */
protected function _uploadPhoto($source)
{
  $this->load->library('upload');
  $config['upload_path']  = './uploads/photo/';
  $config['allowed_types'] = 'gif|jpg|jpeg|png';
  $config['max_size']   = '5120'; // 5Mb
  $config['remove_spaces'] = TRUE;
  $this->upload->initialize($config);
  if (!$this->upload->do_upload($source)) {
   echo $this->upload->display_errors();
   return;
   $this->_photo_error['upload'] = array('error' => $this->upload->display_errors());
   return FALSE;
  } else {
   $photo_info = $this->upload->data();
   $this->load->library('image_lib');
   $config['source_image'] = $photo_info['full_path'];
   $config['maintain_ratio'] = TRUE;
   $config['new_image'] = './uploads/photo/' . $photo_info['file_name'];  
   if ($photo_info['image_width'] < 600) {
    $config['width'] = $photo_info['image_width'];
   } else {
    $config['width'] = 600;
   }
   if ($photo_info['image_height'] < 600) {
    $config['height'] = $photo_info['image_height'];
   } else {
    $config['height'] = 600;
   }
   $this->image_lib->initialize($config);
   if (!$this->image_lib->resize()) {
    $this->_photo_error['resize'] = array('error' => $this->image_lib->display_errors());
    // Since we have an error let's delete the photo that was already uploaded
    $path = $photo_info['full_path'];
    unlink($path);
    return FALSE;
   } else {
    $this->_photo_array['resized'] = $photo_info['file_name'];
    $this->image_lib->clear();
    // Create thumbnail version
    $config['source_image'] = $photo_info['full_path'];
    $config['maintain_ratio'] = TRUE;
    $config['new_image'] = './uploads/photo/' . $photo_info['raw_name'] . '_200' . $photo_info['file_ext'];
    if ($photo_info['image_width'] > $photo_info['image_height']) {
     $config['height'] = $thumb_height = 200;
     $ratio = $config['height'] / $photo_info['image_height'];
     $config['width'] = $thumb_width = $ratio * $photo_info['image_width'];
    } else {
     $config['width'] = $thumb_width = 200;
     $ratio = $config['width'] / $photo_info['image_width'];
     $config['height'] = $thumb_height = $ratio * $photo_info['image_height'];
    }
    $this->image_lib->initialize($config);
    if (!$this->image_lib->resize()) {
     $this->_photo_error['resize_'] = array('error' => $this->image_lib->display_errors());
     // Since we have an error let's delete the photo that was already uploaded
     $path = $photo_info['full_path'];
     unlink($path);
     return FALSE;
    } else {
     $config['source_image'] = './uploads/photo/' . $photo_info['raw_name'] . '_200' . $photo_info['file_ext'];
     $config['maintain_ratio'] = FALSE;
     $config['new_image'] = './uploads/photo/thumb/' . $photo_info['raw_name'] . '_thumb' . $photo_info['file_ext'];
     $config['width'] = 200;
     $config['height'] = 200;
     if ($photo_info['image_width'] > $photo_info['image_height']) {
      $config['x_axis'] = (($thumb_width / 2) - ($config['width']) / 2);
      $config['y_axis'] = 0;
     } else {
      $config['x_axis'] = 0;
      $config['y_axis'] = (($thumb_height / 2) - ($config['height']) / 2);
     }
     $this->image_lib->initialize($config);
     if (!$this->image_lib->crop()) {
      $data['upload_errors'] = array('error' => $this->image_lib->display_errors());
      // Since we have an error let's delete the photos that were already uploaded
      $path = './uploads/photo/' . $photo_info['raw_name'] . '_200' . $photo_info['file_ext'];
      unlink($path);
      $path = $photo_info['full_path'];
      unlink($path);
      return FALSE;
     } else {
      $this->_photo_array['thumb'] = $photo_info['raw_name'] . '_thumb' . $photo_info['file_ext'];
      // Delete what we don't need
      $path = './uploads/photo/' . $photo_info['raw_name'] . '_200' . $photo_info['file_ext'];
      unlink($path);
      
      return TRUE;
     }
    }
   }

  }
}

VIEW
Code:
&lt;form name="form" id="contact-form" method="post" acti enctype="multipart/form-data"&gt;
     <fieldset>
      <div>
       <label for="gallery_photo">Select Photo(s) To Upload:</label>
       &lt;input type="file" id="photo" name="photo[]" multiple&gt;
       &lt;input type="hidden" name="gallery_id" value="&lt;?php echo $gallery_info['gallery_id']; ?&gt;"&gt;
      </div>
     </fieldset>
     &lt;input type="submit" name="upload" value="Add Photos"&gt;
    &lt;/form&gt;

#2
[eluser]TheFuzzy0ne[/eluser]
By default, CodeIgniter expects your file field to be called "userfile", or that you pass the field name of the file to the do_upload() method. You are passing an array.

I'm not sure that the upload library supports an array of uploaded files. You might have to extend the library and add support for that yourself, but I'm not certain.

#3
[eluser]RMinor[/eluser]
I think this thread, http://stackoverflow.com/questions/99036...es-at-once, might be the answer I need. I will give it a go in a couple hours and post my finished working code.

#4
[eluser]RMinor[/eluser]
Here is my working code. It uploads any number of photos, re-sizes them, and crops a 200x200 thumbnail. It also displays each successful upload and if needed any failed uploads along with their respective errors. Hopefully this can help someone else out as well. I omitted the model, but it's pretty self-explanatory.

CONTROLLER (Will be in two pieces due to character limit)
Code:
/**
  * Method to add photos
  * @param integer $gallery_id
  */
public function add_photos($gallery_id)
{
  // Retrieve page information
  $data['page_info'] = $this->Global_model->pageInfo($this->_page);
  // Retrieve gallery information
  $data['gallery_info'] = $this->Person_model->getGallery($gallery_id);
  
  $this->load->helper('form');
  if ($this->input->post('upload')) {
   $this->load->library('form_validation');
   $this->form_validation->set_rules('gallery_id', 'Gallery ID', 'trim|required');
   if ($this->form_validation->run() == FALSE) {} else {
    
    $arr_files = @$_FILES['photo'];
    $_FILES = array();
    foreach (array_keys($arr_files['name']) as $h) {
     $_FILES["file_{$h}"] = array(
      'name' => $arr_files['name'][$h],
      'type' => $arr_files['type'][$h],
      'tmp_name' => $arr_files['tmp_name'][$h],
      'error' => $arr_files['error'][$h],
      'size' => $arr_files['size'][$h]
     );
    }
    
    foreach(array_keys($_FILES) as $h) {
     $this->_uploadPhoto($h, $gallery_id);
    }
    
    $data['uploaded'] = $this->_uploaded;
    $data['failed'] = $this->_failed;
   }
  }
  
  // Load required view and data
  $this->load->view('profile/add-photos_view', $data);
}

#5
[eluser]RMinor[/eluser]
...continued

CONTROLLER
Code:
/**
  * Method to upload a photo
  * @param string $source
  * @return boolean
  */
protected function _uploadPhoto($source, $gallery_id)
{
  $this->load->library('upload');
  $config['upload_path']  = './uploads/photo/';
  $config['allowed_types'] = 'gif|jpg|jpeg|png';
  $config['max_size']   = '5120'; // 5Mb
  $config['remove_spaces'] = TRUE;
  $this->upload->initialize($config);
  if (!$this->upload->do_upload($source)) {
   // Add the photo name to the failed array
   $this->_failed[] = array(
    'name' => $source['name'],
    'error' => $this->upload->display_errors(),
   );
   // $this->_photo_error['upload'] = array('error' => $this->upload->display_errors());
   return FALSE;
  } else {
   $photo_info = $this->upload->data();
   $this->load->library('image_lib');
   $config['source_image'] = $photo_info['full_path'];
   $config['maintain_ratio'] = TRUE;
   $config['new_image'] = './uploads/photo/' . $photo_info['file_name'];  
   if ($photo_info['image_width'] < 600) {
    $config['width'] = $photo_info['image_width'];
   } else {
    $config['width'] = 600;
   }
   if ($photo_info['image_height'] < 600) {
    $config['height'] = $photo_info['image_height'];
   } else {
    $config['height'] = 600;
   }
   $this->image_lib->initialize($config);
   if (!$this->image_lib->resize()) {
    // Add the photo name to the failed array
    $this->_failed[] = array(
     'name' => $photo_info['file_name'],
     'error' => $this->image_lib->display_errors(),
    );
    // $this->_photo_error['resize'] = array('error' => $this->image_lib->display_errors());
    // Since we have an error let's delete the photo that was already uploaded
    $path = $photo_info['full_path'];
    unlink($path);
    return FALSE;
   } else {
    $photo = $photo_info['file_name'];
    $this->image_lib->clear();
    // Create thumbnail version
    $config['source_image'] = $photo_info['full_path'];
    $config['maintain_ratio'] = TRUE;
    $config['new_image'] = './uploads/photo/' . $photo_info['raw_name'] . '_200' . $photo_info['file_ext'];
    if ($photo_info['image_width'] > $photo_info['image_height']) {
     $config['height'] = $thumb_height = 200;
     $ratio = $config['height'] / $photo_info['image_height'];
     $config['width'] = $thumb_width = $ratio * $photo_info['image_width'];
    } else {
     $config['width'] = $thumb_width = 200;
     $ratio = $config['width'] / $photo_info['image_width'];
     $config['height'] = $thumb_height = $ratio * $photo_info['image_height'];
    }
    $this->image_lib->initialize($config);
    if (!$this->image_lib->resize()) {
     // Add the photo name to the failed array
     $this->_failed[] = array(
      'name' => $photo_info['file_name'],
      'error' => $this->image_lib->display_errors(),
     );
     // $this->_photo_error['resize_'] = array('error' => $this->image_lib->display_errors());
     // Since we have an error let's delete the photo that was already uploaded
     $path = $photo_info['full_path'];
     unlink($path);
     return FALSE;
    } else {
     $config['source_image'] = './uploads/photo/' . $photo_info['raw_name'] . '_200' . $photo_info['file_ext'];
     $config['maintain_ratio'] = FALSE;
     $config['new_image'] = './uploads/photo/thumb/' . $photo_info['raw_name'] . '_thumb' . $photo_info['file_ext'];
     $config['width'] = 200;
     $config['height'] = 200;
     if ($photo_info['image_width'] > $photo_info['image_height']) {
      $config['x_axis'] = (($thumb_width / 2) - ($config['width']) / 2);
      $config['y_axis'] = 0;
     } else {
      $config['x_axis'] = 0;
      $config['y_axis'] = (($thumb_height / 2) - ($config['height']) / 2);
     }
     $this->image_lib->initialize($config);
     if (!$this->image_lib->crop()) {
      // Add the photo name to the failed array
      $this->_failed[] = array(
       'name' => $photo_info['file_name'],
       'error' => $this->image_lib->display_errors(),
      );
      // $data['upload_errors'] = array('error' => $this->image_lib->display_errors());
      // Since we have an error let's delete the photos that were already uploaded
      $path = './uploads/photo/' . $photo_info['raw_name'] . '_200' . $photo_info['file_ext'];
      unlink($path);
      $path = $photo_info['full_path'];
      unlink($path);
      return FALSE;
     } else {
      $thumb = $photo_info['raw_name'] . '_thumb' . $photo_info['file_ext'];
      $this->_uploaded[] = $photo_info['file_name'];
      // Delete what we don't need
      $path = './uploads/photo/' . $photo_info['raw_name'] . '_200' . $photo_info['file_ext'];
      unlink($path);
      $this->Person_model->savePhotoAndThumb($photo, $thumb, $gallery_id);
      return TRUE;
     }
    }
   }

  }
}

View to come in next post...

#6
[eluser]RMinor[/eluser]
...continued, here is the view

VIEW
Code:
<!DOCTYPE html>
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;title&gt;&lt;?php echo $page_info['site_name']; ?&gt; | &lt;?php echo $page_info['page_title']; ?&gt;&lt;/title&gt;
&lt;meta name="description" c echo $page_info['meta_description']; ?&gt;"&gt;
&lt;meta name="author" c echo $page_info['author']; ?&gt;"&gt;
&lt;meta name="keywords" c echo $page_info['meta_keywords']; ?&gt;"&gt;
&lt;meta name="copyright" c echo $page_info['copyright']; ?&gt;" /&gt;
&lt;meta name="viewport" c&gt;
&lt;link rel="shortcut icon" href="&lt;?php echo base_url(); ?&gt;favicon.ico" /&gt;
&lt;link rel="stylesheet" href="&lt;?php echo asset_url(); ?&gt;css/base.css"/&gt;
&lt;!--[if lt IE 9]>[removed][removed]<![endif]--&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?php $this->load->view('header_view'); ?&gt;
<div role="main" id="main-container">
  <h1>Add Photos</h1>
  <section class="group contact">
   <div class="section-description centered italic separate-bottom">
    &lt;?php echo validation_errors(); ?&gt;
   </div>
   <div class="form">
    &lt;form name="form" id="contact-form" method="post" acti enctype="multipart/form-data"&gt;
     <fieldset>
      <div>
       <label for="gallery_photo">Select Photo(s) To Upload:</label>
       &lt;input type="file" id="photo" name="photo[]" multiple&gt;
       &lt;input type="hidden" name="gallery_id" value="&lt;?php echo $gallery_info['gallery_id']; ?&gt;"&gt;
      </div>
     </fieldset>
     &lt;input type="submit" name="upload" value="Add Photos"&gt;
    &lt;/form&gt;
   </div>
   <section class="contact-info" >
    &lt;?php if (!empty($uploaded)) { ?&gt;
     Uploaded Photos<br />
     &lt;?php foreach ($uploaded as $upload) { ?&gt;
      <p>&lt;?php echo $upload; ?&gt;</p>
     &lt;?php }
    }
    if (!empty($failed)) { ?&gt;
     Failed Uploads<br />
     &lt;?php print_r($failed); ?&gt;
    &lt;?php } ?&gt;
    <p><strong>Gallery Title:</strong> &lt;?php echo $gallery_info['gallery_title']; ?&gt;</p>
    <p>Click the Browse button to select photo(s) to upload to this gallery. If your browser supports multiple file
    uploads you will be able to upload as many photos as you want at a time.</p>
    
   </section>
  </section>
</div>
&lt;?php $this->load->view('footer_view'); ?&gt;
[removed][removed]
[removed][removed]
&lt;/body&gt;
&lt;/html&gt;

#7
[eluser]TheFuzzy0ne[/eluser]
Wow, that's a lot of code! But well done, and thanks for posting back your solution. Smile

#8
[eluser]RMinor[/eluser]
No problem at all and you're welcome. I know it's a lot of code. I intend to move most of it into the model and call it from the controller.


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.