├── MY_Upload.php └── README.md /MY_Upload.php: -------------------------------------------------------------------------------- 1 | set_error('upload_no_file_selected'); 16 | return FALSE; 17 | 18 | } 19 | 20 | //If not every file filled was used, clear the empties 21 | 22 | foreach( $_FILES[$field]['name'] as $k => $n ) 23 | { 24 | 25 | if( empty( $n ) ) 26 | { 27 | 28 | foreach( $_FILES[$field] as $kk => $f ) 29 | { 30 | 31 | unset( $_FILES[$field][$kk][$k] ); 32 | 33 | } 34 | 35 | } 36 | 37 | } 38 | 39 | // Is the upload path valid? 40 | if ( ! $this->validate_upload_path($field) ) 41 | { 42 | 43 | // errors will already be set by validate_upload_path() so just return FALSE 44 | return FALSE; 45 | } 46 | 47 | //Multiple file upload 48 | if( is_array( $_FILES[$field] ) ) 49 | { 50 | 51 | //$count = count($_FILES[$field]['name']); //Number of files to process 52 | 53 | foreach( $_FILES[$field]['name'] as $k => $file ) 54 | { 55 | 56 | // Was the file able to be uploaded? If not, determine the reason why. 57 | if ( ! is_uploaded_file($_FILES[$field]['tmp_name'][$k] ) ) 58 | { 59 | 60 | $error = ( ! isset($_FILES[$field]['error'][$k])) ? 4 : $_FILES[$field]['error'][$k]; 61 | 62 | switch($error) 63 | { 64 | case 1: // UPLOAD_ERR_INI_SIZE 65 | $this->set_error('upload_file_exceeds_limit'); 66 | break; 67 | case 2: // UPLOAD_ERR_FORM_SIZE 68 | $this->set_error('upload_file_exceeds_form_limit'); 69 | break; 70 | case 3: // UPLOAD_ERR_PARTIAL 71 | $this->set_error('upload_file_partial'); 72 | break; 73 | case 4: // UPLOAD_ERR_NO_FILE 74 | $this->set_error('upload_no_file_selected'); 75 | break; 76 | case 6: // UPLOAD_ERR_NO_TMP_DIR 77 | $this->set_error('upload_no_temp_directory'); 78 | break; 79 | case 7: // UPLOAD_ERR_CANT_WRITE 80 | $this->set_error('upload_unable_to_write_file'); 81 | break; 82 | case 8: // UPLOAD_ERR_EXTENSION 83 | $this->set_error('upload_stopped_by_extension'); 84 | break; 85 | default : $this->set_error('upload_no_file_selected'); 86 | break; 87 | } 88 | 89 | return FALSE; 90 | } 91 | 92 | // Set the uploaded data as class variables 93 | $this->file_temp = $_FILES[$field]['tmp_name'][$k]; 94 | $this->file_size = $_FILES[$field]['size'][$k]; 95 | $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type'][$k]); 96 | $this->file_type = strtolower(trim(stripslashes($this->file_type), '"')); 97 | 98 | if(empty($filenames)) 99 | { 100 | $this->file_name = $this->_prep_filename($_FILES[$field]['name'][$k]); 101 | } 102 | else 103 | { 104 | $this->file_name = $this->_prep_filename($filenames[$k]); 105 | } 106 | 107 | $this->file_ext = $this->get_extension($this->file_name); 108 | $this->client_name = $this->file_name; 109 | 110 | // Is the file type allowed to be uploaded? 111 | if ( ! $this->is_allowed_filetype()) 112 | { 113 | $this->set_error('upload_invalid_filetype'); 114 | return FALSE; 115 | } 116 | 117 | // if we're overriding, let's now make sure the new name and type is allowed 118 | if ($this->_file_name_override != '') 119 | { 120 | $this->file_name = $this->_prep_filename($this->_file_name_override); 121 | 122 | // If no extension was provided in the file_name config item, use the uploaded one 123 | if (strpos($this->_file_name_override, '.') === FALSE) 124 | { 125 | $this->file_name .= $this->file_ext; 126 | } 127 | 128 | // An extension was provided, lets have it! 129 | else 130 | { 131 | $this->file_ext = $this->get_extension($this->_file_name_override); 132 | } 133 | 134 | if ( ! $this->is_allowed_filetype(TRUE)) 135 | { 136 | $this->set_error('upload_invalid_filetype'); 137 | return FALSE; 138 | } 139 | } 140 | 141 | // Convert the file size to kilobytes 142 | if ($this->file_size > 0) 143 | { 144 | $this->file_size = round($this->file_size/1024, 2); 145 | } 146 | 147 | // Is the file size within the allowed maximum? 148 | if ( ! $this->is_allowed_filesize()) 149 | { 150 | $this->set_error('upload_invalid_filesize'); 151 | return FALSE; 152 | } 153 | 154 | // Are the image dimensions within the allowed size? 155 | // Note: This can fail if the server has an open_basdir restriction. 156 | if ( ! $this->is_allowed_dimensions()) 157 | { 158 | $this->set_error('upload_invalid_dimensions'); 159 | return FALSE; 160 | } 161 | 162 | // Sanitize the file name for security 163 | $this->file_name = $this->clean_file_name($this->file_name); 164 | 165 | // Truncate the file name if it's too long 166 | if ($this->max_filename > 0) 167 | { 168 | $this->file_name = $this->limit_filename_length($this->file_name, $this->max_filename); 169 | } 170 | 171 | // Remove white spaces in the name 172 | if ($this->remove_spaces == TRUE) 173 | { 174 | $this->file_name = preg_replace("/\s+/", "_", $this->file_name); 175 | } 176 | 177 | /* 178 | * Validate the file name 179 | * This function appends an number onto the end of 180 | * the file if one with the same name already exists. 181 | * If it returns false there was a problem. 182 | */ 183 | $this->orig_name = $this->file_name; 184 | 185 | if ($this->overwrite == FALSE) 186 | { 187 | $this->file_name = $this->set_filename($this->upload_path, $this->file_name); 188 | 189 | if ($this->file_name === FALSE) 190 | { 191 | return FALSE; 192 | } 193 | } 194 | 195 | /* 196 | * Run the file through the XSS hacking filter 197 | * This helps prevent malicious code from being 198 | * embedded within a file. Scripts can easily 199 | * be disguised as images or other file types. 200 | */ 201 | if ($this->xss_clean) 202 | { 203 | if ($this->do_xss_clean() === FALSE) 204 | { 205 | $this->set_error('upload_unable_to_write_file'); 206 | return FALSE; 207 | } 208 | } 209 | 210 | /* 211 | * Move the file to the final destination 212 | * To deal with different server configurations 213 | * we'll attempt to use copy() first. If that fails 214 | * we'll use move_uploaded_file(). One of the two should 215 | * reliably work in most environments 216 | */ 217 | if ( ! @copy($this->file_temp, $this->upload_path.$this->file_name)) 218 | { 219 | if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name)) 220 | { 221 | $this->set_error('upload_destination_error'); 222 | return FALSE; 223 | } 224 | } 225 | 226 | /* 227 | * Set the finalized image dimensions 228 | * This sets the image width/height (assuming the 229 | * file was an image). We use this information 230 | * in the "data" function. 231 | */ 232 | $this->set_image_properties($this->upload_path.$this->file_name); 233 | 234 | 235 | if( $return_info === TRUE ) 236 | { 237 | 238 | $return_value[$k] = $this->data(); 239 | 240 | } 241 | else 242 | { 243 | 244 | $return_value = TRUE; 245 | 246 | } 247 | 248 | 249 | } 250 | 251 | return $return_value; 252 | 253 | } 254 | else //Single file upload, rely on native CI upload class 255 | { 256 | 257 | $upload = self::do_upload(); 258 | 259 | return $upload; 260 | 261 | } 262 | 263 | 264 | } 265 | 266 | } 267 | 268 | ?> 269 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #PLEASE READ: 2 | This repo is no longer maintained. Please see @anuragrath's [fork](https://github.com/anuragrath/CodeIgniter-Multiple-File-Upload) for the latest version. 3 | 4 | #CodeIgniter Multiple Upload Library 5 | Just an extension to the existing Upload class to take advantage of multiple uploads in one form field 6 | 7 | ##v.0.2: November 7, 2011 8 | 9 | __Changes__ 10 | Added a parameter to return all the uploaded file(s) info as opposed to boolean. Set to false to return boolean instead. 11 | 12 | ##v.0.1: July 7, 2011 13 | 14 | __Description__ 15 | This version is a quick and dirty first pass for a project I'm currently working on. I haven't worked on the error reporting piece yet, so feel free to send in that contribution if you're so inclined. 16 | 17 | __Installation__ 18 | Copy MY\_Upload.php to your application/libraries directory. 19 | If you are using a prefix other than MY_ for your classes and/or alternative file paths, adjust accordingly. 20 | 21 | __Usage__ 22 | Load the Upload class as usual, in your controller call the function `do_multi_upload()`. If you are uploading a single file, it'll default to the regular `do_upload()` method. 23 | In the form, set field names to array (e.g. name="userfile[]") 24 | 25 | --------------------------------------------------------------------------------