CI Framework
Copy the Code code as follows:
/**
* Multi-upload
*
* Extends Codeigniters Native Upload class to add support for multiple
* Uploads.
*
* @package CodeIgniter
* @subpackage Libraries
* @category Uploads
*/
Class My_upload extends Ci_upload {
/**
* Properties
*/
Protected $_multi_upload_data = Array ();
protected $_multi_file_name_override = "";
/**
* Initialize Preferences
*
* @access public
* @param array
* @return void
*/
Publi C function Initialize ($config = Array ()) {
//upload default settings.
$defaults = Array (
"max_size" + 0,
"Max_width" = 0,
"max_height" = 0,
"max_filename" = 0,
"allowed_types" + ","
"File_temp" = = "",
"file_name" = "",
"orig_name" + "",
"File_type" and "",
"file_size" + "",
"fi Le_ext "=" ",
" upload_path "=" ",
" overwrite "and" = False,
"encrypt_name" = False,
"Is_image" = = FALSE,
"image_width" = "",
"image_height" = "",
"Image_type" and "",
"Image_size_str" => ; "",
"error_msg" = Array (),
"mimes" = = Array (),
"remove_spaces" = TRUE,
"Xss_clean" = FALSE,
"Temp_prefix" = "Temp_file_",
"Client_name" and "
";
Set each configuration.
foreach ($defaults as $key = = $val) {
if (Isset ($config [$key])) {
$method = "set_{$key}";
if (Method_exists ($this, $method)) {
$this-$method ($config [$key]);
} else {
$this $key = $config [$key];
}
} else {
$this $key = $val;
}
}
Check if file_name was provided.
if (!empty ($this->file_name)) {
Multiple file upload.
if (Is_array ($this->file_name)) {
Clear file name override.
$this->_file_name_override = "";
Set multiple file name override.
$this->_multi_file_name_override = $this->file_name;
Single File upload.
} else {
Set file name override.
$this->_file_name_override = $this->file_name;
Clear multiple file name override.
$this->_multi_file_name_override = "";
}
}
}
/**
* File MIME Type
*
* Detects the (actual) MIME type of the uploaded file, if possible.
* The input array is expected to be $_files[$field].
*
* In the case of multiple uploads, a optional second argument
* passed specifying which array element of the $_files[$field] Array
* Elements should be referenced (name, type, tmp_name, etc).
*
* @access protected
* @param $file Array
* @param $count int
* @return void
*/
protected function _file_mime_type ($file, $count =0) {
mutliple file?
if (Is_array ($file ["name"])) {
$tmp _name = $file ["Tmp_name"] [$count];
$type = $file ["type"] [$count];
Single file.
} else {
$tmp _name = $file ["Tmp_name"];
$type = $file ["type"];
}
We ' ll need this to validate the MIME info string (e.g. text/plain; charset=us-ascii).
$regexp = "/^ ([a-z\-]+\/[a-z0-9\-\.\+]+) (; \s.+) $/";
/* Fileinfo extension-most Reliable method.
*
* Unfortunately, prior to PHP 5.3-it's only available as a PECL extension and the
* More convenient Fileinfo_mime_type flag doesn ' t exist.
*/
if (function_exists ("Finfo_file")) {
$finfo = Finfo_open (fileinfo_mime);
if (Is_resource ($finfo)) {
$mime = @finfo_file ($finfo, $tmp _name);
Finfo_close ($finfo);
/* According to the comments section of the PHP manual page,
* It is possible the This function returns a empty string
* For some files (e.g. if they don ' t exist in the Magic MIME database).
*/
if (is_string ($mime) && preg_match ($regexp, $mime, $matches)) {
$this->file_type = $matches [1];
Return
}
}
}
/* This is an ugly hack, but Unix-type systems provide a "native" the "from" to detect the file type,
* which is still mo Re secure than depending on the value of $_files[$field [' type '], and as it
* is reported in issue #750 (Https://gith ub.com/ellislab/codeigniter/issues/750)-it ' s better
* than Mime_content_type () as well, hence the attempts to try Ca Lling the command line with
* three different functions.
*
* Notes:
*-The Directory_separator comparison Ensures that we ' re isn't on a Windows system
*-Many system admins would disable the exec (), shell_exec (), Popen () and Similar functions
* Due to security concerns, hence the function_exists () checks
*/
if (directory_separator! = = "\ \") {
$cmd = "File--brief--mime". Escapeshellarg ($tmp _name). " 2>&1 ";
If (function_exists ("exec")) {
/* This might look confusing, as $mime are being populated with all of the output when Set in the second parameter.
* However, we only neeed the last line, which is the actual return value of exec (), and as such-it overwrites
* Anything that could already is set for $mime previously. This effectively makes the second parameter a dummy
* value, which are only put into allow us to get the return status Co De.
*/
$mime = @exec ($cmd, $mime, $return _status),
if ($return _status = = = 0 && is_string ($mime) && Preg_match ($regexp, $mime, $matches)) {
$this->file_type = $matches [1];
return;
}
}
}
if (bool) @ini_get ("safe_mode") = = = FALSE && function_exists ("Shell_exec")) {
$mime = @shell_exec ($cmd);
if (strlen ($mime) > 0) {
$mime = explode ("\ n", Trim ($mime));
if (Preg_match ($regexp, $mime [(Count ($mime)-1)], $matches)) {
$this->file_type = $matches [1];
Return
}
}
}
if (function_exists ("Popen")) {
$proc = @popen ($cmd, "R");
if (Is_resource ($proc)) {
$mime = @fread ($proc, 512);
@pclose ($PROC);
if ($mime!== FALSE) {
$mime = explode ("\ n", Trim ($mime));
if (Preg_match ($regexp, $mime [(Count ($mime)-1)], $matches)) {
$this->file_type = $matches [1];
Return
}
}
}
}
Fall back to the deprecated mime_content_type (), if available (still better than $_files[$field ["type"])
if (function_exists ("Mime_content_type")) {
$this->file_type = @mime_content_type ($tmp _name);
It ' s possible that Mime_content_type () returns FALSE or an empty string.
if (strlen ($this->file_type) > 0) {
Return
}
}
If all else fails, use $_files default MIME type.
$this->file_type = $type;
}
/**
* Set multiple Upload Data
*
* @access protected
* @return void
*/
Protected function Set_multi_upload_data () {
$this->_multi_upload_data[] = Array (
"file_name" and "= $this->file_name,
" File_type "= $this->file_type,
" File_path "and" = $this->upload_path,
"Full_path" and $this- Upload_path. $this->file_name,
"raw_name" = Str_replace ($this->file_ext, "", $this->file_name),
"Orig_name" = $this->orig_name,
"client_name" and "= $this->client_name,
" File_ext "and $this- File_ext,
"file_size" + $this->file_size,
"is_image" and "= $this->is_image (),
" image_width "= > $this->image_width,
"image_height" + $this->image_height,
"image_type" + = $this->image_ Type,
"image_size_str" = $this->image_size_str
);
}
/**
* Get multiple Upload Data
*
* @access Public
* @return Array
*/
Public Function Get_multi_upload_data () {
return $this->_multi_upload_data;
}
/**
* Multile File Upload
*
* @access Public
* @param string
* @return Mixed
*/
Public Function Do_multi_upload ($field) {
is $_files[$field] set? If not, no reason to continue.
if (!isset ($_files[$field])) {return false;}
Is this really a multi upload?
if (!is_array ($_files[$field ["name"])) {
Fallback to Do_upload method.
return $this->do_upload ($field);
}
is the upload path valid?
if (! $this->validate_upload_path ()) {
Errors'll already be set by Validate_upload_path () so just return FALSE
return FALSE;
}
//every file'll has a separate entry in each of the $_files associative array elements (name, type, etc).
//loop through $_files[$field ["name"] as representative of total number of FILES. Use count as key in
//corresponding elements of the $_files[$field] elements.
for ($i =0; $i //was the file able to be uploaded? If not, determine the reason why.
if (!is_uploaded_file ($_files[$field] ["Tmp_name"] [$i]) {
//determine error number.
$error = (!isset ($_files[$field ["Error"] [$i]))? 4: $_files[$field] [ERROR] [$i];
Set error.
Switch ($error) {
Upload_err_ini_size
Case 1:
$this->set_error ("Upload_file_exceeds_limit");
Break
Upload_err_form_size
Case 2:
$this->set_error ("Upload_file_exceeds_form_limit");
Break
Upload_err_partial
Case 3:
$this->set_error ("upload_file_partial");
Break
Upload_err_no_file
Case 4:
$this->set_error ("upload_no_file_selected");
Break
Upload_err_no_tmp_dir
Case 6:
$this->set_error ("Upload_no_temp_directory");
Break
Upload_err_cant_write
Case 7:
$this->set_error ("Upload_unable_to_write_file");
Break
Upload_err_extension
Case 8:
$this->set_error ("upload_stopped_by_extension");
Break
Default
$this->set_error ("upload_no_file_selected");
Break
}
Return failed upload.
return FALSE;
}
Set current file data as class variables.
$this->file_temp = $_files[$field] ["Tmp_name"] [$i];
$this->file_size = $_files[$field ["Size"] [$i];
$this->_file_mime_type ($_files[$field], $i);
$this->file_type = Preg_replace ("/^ (. +?);. *$/"," \\1 ", $this->file_type);
$this->file_type = Strtolower (Trim (stripslashes ($this->file_type), ' "');
$this->file_name = $this->_prep_filename ($_files[$field ["name"] [$i]);
$this->file_ext = $this->get_extension ($this->file_name);
$this->client_name = $this->file_name;
Is the file type allowed to be uploaded?
if (! $this->is_allowed_filetype ()) {
$this->set_error ("Upload_invalid_filetype");
return FALSE;
}
If we ' re overriding, let's now make sure the new name and type are allowed.
Check if a filename is supplied for the current file. Otherwise, use it ' s given name.
if (!empty ($this->_multi_file_name_override[$i])) {
$this->file_name = $this->_prep_filename ($this->_multi_file_name_override[$i]);
If no extension is provided in the File_name Config item, use the uploaded one.
if (Strpos ($this->_multi_file_name_override[$i], ".") = = = = FALSE) {
$this->file_name. = $this->file_ext;
An extension is provided, lets has it!
} else {
$this->file_ext = $this->get_extension ($this->_multi_file_name_override[$i]);
}
if (! $this->is_allowed_filetype (TRUE)) {
$this->set_error ("Upload_invalid_filetype");
return FALSE;
}
}
Convert the file size to kilobytes.
if ($this->file_size > 0) {
$this->file_size = round ($this->file_size/1024, 2);
}
is the file size within the allowed maximum?
if (! $this->is_allowed_filesize ()) {
$this->set_error ("upload_invalid_filesize");
return FALSE;
}
is the image dimensions within the allowed size?
Note:this can fail if the server has a open_basdir restriction.
if (! $this->is_allowed_dimensions ()) {
$this->set_error ("upload_invalid_dimensions");
return FALSE;
}
Sanitize the file name for security.
$this->file_name = $this->clean_file_name ($this->file_name);
Truncate the file name if it ' s too long
if ($this->max_filename > 0) {
$this->file_name = $this->limit_filename_length ($this->file_name, $this->max_filename);
}
Remove white spaces in the name
if ($this->remove_spaces = = TRUE) {
$this->file_name = preg_replace ("/\s+/", "_", $this->file_name);
}
/* Validate the file name
* This function appends an number onto the end of
* The file if one with the same name already exists.
* IF It returns false there was a problem.
*/
$this->orig_name = $this->file_name;
if ($this->overwrite = = FALSE) {
$this->file_name = $this->set_filename ($this->upload_path, $this->file_name);
if ($this->file_name = = = FALSE) {
return FALSE;
}
}
/* Run the file through the XSS hacking filter
* This helps prevent malicious code from being
* Embedded within a file. Scripts can easily
* Be disguised as images, or other file types.
*/
if ($this->xss_clean) {
if ($this->do_xss_clean () = = = FALSE) {
$this->set_error ("Upload_unable_to_write_file");
return FALSE;
}
}
/* Move the file to the final destination
* To deal with different server configurations
* We ll attempt to use copy () first. If that fails
* We ll use Move_uploaded_file (). One of the should
* Reliably work on most environments
*/
if (! @copy ($this->file_temp, $this->upload_path. $this->file_name)) {
if (! @move_uploaded_file ($this->file_temp, $this->upload_path. $this->file_name)) {
$this->set_error ("Upload_destination_error");
return FALSE;
}
}
/* Set the finalized image dimensions
* This sets the image width/height (assuming the
* file is an image). We Use this information
* In the "data" function.
*/
$this->set_image_properties ($this->upload_path. $this->file_name);
Set current file data to Multi_file_upload_data.
$this->set_multi_upload_data ();
}
Return all file upload data.
return TRUE;
}
}