Created
September 15, 2011 07:01
-
-
Save skunkbad/1218696 to your computer and use it in GitHub Desktop.
CodeIgniter Upload class extension for FTP or Database storage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | |
class MY_Upload extends CI_Upload { | |
public $destination_not_file_system = FALSE; | |
public function __construct($props = array()) | |
{ | |
parent::__construct(); | |
if (count($props) > 0) | |
{ | |
$this->initialize($props); | |
} | |
log_message('debug', "Upload Class Initialized"); | |
} | |
public function initialize($config = array()) | |
{ | |
$defaults = array( | |
'max_size' => 0, | |
'max_width' => 0, | |
'max_height' => 0, | |
'max_filename' => 0, | |
'allowed_types' => "", | |
'file_temp' => "", | |
'file_name' => "", | |
'orig_name' => "", | |
'file_type' => "", | |
'file_size' => "", | |
'file_ext' => "", | |
'upload_path' => "", | |
'overwrite' => FALSE, | |
'encrypt_name' => FALSE, | |
'is_image' => FALSE, | |
'image_width' => '', | |
'image_height' => '', | |
'image_type' => '', | |
'image_size_str' => '', | |
'error_msg' => array(), | |
'mimes' => array(), | |
'remove_spaces' => TRUE, | |
'xss_clean' => FALSE, | |
'temp_prefix' => "temp_file_", | |
'client_name' => '', | |
// new destination_not_file_system key | |
'destination_not_file_system' => FALSE | |
); | |
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; | |
} | |
} | |
// if a file_name was provided in the config, use it instead of the user input | |
// supplied file name for all uploads until initialized again | |
$this->_file_name_override = $this->file_name; | |
} | |
public function do_upload($field = 'userfile') | |
{ | |
// Is $_FILES[$field] set? If not, no reason to continue. | |
if ( ! isset($_FILES[$field])) | |
{ | |
$this->set_error('upload_no_file_selected'); | |
return FALSE; | |
} | |
// Is the upload path valid? (only applies if file system is final destination | |
if( $this->destination_not_file_system === FALSE ) | |
{ | |
if ( ! $this->validate_upload_path()) | |
{ | |
// errors will already be set by validate_upload_path() so just return FALSE | |
return FALSE; | |
} | |
} | |
// Was the file able to be uploaded? If not, determine the reason why. | |
if ( ! is_uploaded_file($_FILES[$field]['tmp_name'])) | |
{ | |
$error = ( ! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error']; | |
switch($error) | |
{ | |
case 1: // UPLOAD_ERR_INI_SIZE | |
$this->set_error('upload_file_exceeds_limit'); | |
break; | |
case 2: // UPLOAD_ERR_FORM_SIZE | |
$this->set_error('upload_file_exceeds_form_limit'); | |
break; | |
case 3: // UPLOAD_ERR_PARTIAL | |
$this->set_error('upload_file_partial'); | |
break; | |
case 4: // UPLOAD_ERR_NO_FILE | |
$this->set_error('upload_no_file_selected'); | |
break; | |
case 6: // UPLOAD_ERR_NO_TMP_DIR | |
$this->set_error('upload_no_temp_directory'); | |
break; | |
case 7: // UPLOAD_ERR_CANT_WRITE | |
$this->set_error('upload_unable_to_write_file'); | |
break; | |
case 8: // UPLOAD_ERR_EXTENSION | |
$this->set_error('upload_stopped_by_extension'); | |
break; | |
default : $this->set_error('upload_no_file_selected'); | |
break; | |
} | |
return FALSE; | |
} | |
// Set the uploaded data as class variables | |
$this->file_temp = $_FILES[$field]['tmp_name']; | |
$this->file_size = $_FILES[$field]['size']; | |
$this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']); | |
$this->file_type = strtolower(trim(stripslashes($this->file_type), '"')); | |
$this->file_name = $this->_prep_filename($_FILES[$field]['name']); | |
$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 is allowed | |
if ($this->_file_name_override != '') | |
{ | |
$this->file_name = $this->_prep_filename($this->_file_name_override); | |
// If no extension was provided in the file_name config item, use the uploaded one | |
if (strpos($this->_file_name_override, '.') === FALSE) | |
{ | |
$this->file_name .= $this->file_ext; | |
} | |
// An extension was provided, lets have it! | |
else | |
{ | |
$this->file_ext = $this->get_extension($this->_file_name_override); | |
} | |
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; | |
} | |
// Are the image dimensions within the allowed size? | |
// Note: This can fail if the server has an 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; | |
} | |
} | |
if( $this->destination_not_file_system === 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 two should | |
* reliably work in 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 for | |
* files saved to the file system. | |
* This sets the image width/height (assuming the | |
* file was an image). We use this information | |
* in the "data" function. | |
*/ | |
$this->set_image_properties($this->upload_path.$this->file_name); | |
return TRUE; | |
} | |
else | |
{ | |
/* | |
* Set the finalized image dimensions for | |
* files that were not saved to the file system. | |
* This sets the image width/height (assuming the | |
* file was an image). We use this information | |
* in the "data" function. | |
*/ | |
$this->set_image_properties( $this->file_temp ); | |
return TRUE; | |
} | |
} | |
} | |
/* End of file MY_Upload.php */ | |
/* Location: ./application/libraries/MY_Upload.php */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | |
class Uploads_manager extends MY_Controller { | |
public $upload_details = array(); | |
private $upload_dir; | |
private $primary_dir = FALSE; | |
private $secondary_dir = FALSE; | |
private $tertiary_dir = FALSE; | |
private $quaternary_dir = FALSE; | |
private $success_callback; | |
public function __construct() | |
{ | |
parent::__construct(); | |
$this->config->load('uploads_manager_config'); | |
$this->load->model('uploads_manager_model'); | |
} | |
/* | |
* BRIDGE DATABASE method does most of the work behind | |
* uploading a file whos destination is the database. | |
* | |
* Argument 1 - $type - used as a suffix to the upload config set. | |
* Argument 2 = $return - set to TRUE to return array instead of json. | |
* | |
* A mandatory callback function name must be supplied by post | |
* element "success_callback" | |
* | |
*/ | |
public function bridge_database( $type, $return = FALSE ) | |
{ | |
if($this->require_role('Sudo,Admin,VPM,RM,PM')) | |
{ | |
// Use CSRF protection | |
$this->load->library('csrf'); | |
// Check if a valid form submission has been made | |
if( $this->csrf->token_match ) | |
{ | |
// Get special upload config for database storage | |
$init_config = config_item( 'db_storage_configuration_' . $type ); | |
// Load and initialize file upload class | |
$this->load->library('upload', $init_config); | |
// Use upload library for file validation | |
if ( $this->upload->do_upload() ) | |
{ | |
$handle = fopen( $this->upload->file_temp, "r" ); | |
$file_string = base64_encode( fread( $handle, filesize( $this->upload->file_temp ) ) ); | |
fclose($handle); | |
// Need to have callback to handle the specific upload details | |
if( empty( $this->success_callback ) ) | |
{ | |
$this->success_callback = $this->input->post('success_callback'); | |
} | |
// Need to have callback handle the insertion to DB | |
if( ! empty( $this->success_callback ) ) | |
{ | |
if( method_exists($this, $this->success_callback) ) | |
{ | |
$callback = $this->success_callback; | |
// Pass the file string to the callback | |
if( $callback_response = $this->$callback( $file_string ) ) | |
{ | |
// Send Success Response | |
$response['status'] = 'success'; | |
$response['callback_response'] = $callback_response; | |
} | |
else | |
{ | |
// Error: Callback Failed | |
$response['status'] = 'error'; | |
$response['issue'] = 'Callback failed.'; | |
} | |
} | |
else | |
{ | |
// Error: Callback Doesn't Exist | |
$response['status'] = 'error'; | |
$response['issue'] = 'Callback does not exist.'; | |
} | |
} | |
else | |
{ | |
// Error: No Callback Specified | |
$response['status'] = 'error'; | |
$response['issue'] = 'No callback specified.'; | |
} | |
} | |
else | |
{ | |
// Error: Upload Failed | |
$response['status'] = 'error'; | |
$response['issue'] = 'Upload failed. Please try again later, or contact your supervisor.'; | |
} | |
} | |
else | |
{ | |
// Error: No Token Match | |
$response['status'] = 'error'; | |
$response['issue'] = 'No Token Match. Please reload the page.'; | |
} | |
$response['token'] = $this->csrf->token; | |
if( $return ) | |
{ | |
return $response; | |
} | |
else | |
{ | |
echo json_encode( $response ); | |
} | |
} | |
} | |
/* | |
* BRIDGE FTP method does most of the work behind | |
* uploading a file whos destination is another server. | |
* | |
* Argument 1 - $type - used as a suffix to the upload config set. | |
* Is is also the prefix of the FTP config set. | |
* Argument 2 = $return - set to TRUE to return array instead of json. | |
* | |
* A mandatory callback function name must be supplied by post | |
* element "success_callback" | |
* | |
*/ | |
public function bridge_ftp( $type, $return = FALSE ) | |
{ | |
if($this->require_role('Sudo,Admin,VPM,RM,PM')) | |
{ | |
// Use CSRF protection | |
$this->load->library('csrf'); | |
// Check if a valid form submission has been made | |
if( $this->csrf->token_match ) | |
{ | |
// Get special upload config for FTP transfer | |
$init_config = config_item( 'ftp_configuration_' . $type ); | |
// Load and initialize file upload class | |
$this->load->library('upload', $init_config); | |
// Use upload library for file validation | |
if ( $this->upload->do_upload() ) | |
{ | |
// FTP the file to the backoffice | |
$this->load->library('ftp'); | |
$this->config->load('ftp'); | |
$ftp_config = config_item( $type . '_ftp_settings' ); | |
$this->ftp->connect( $ftp_config ); | |
if( $this->ftp->upload( $this->upload->file_temp, $ftp_config['remote_directory'] . $this->upload->file_name ) ) | |
{ | |
// Need to have callback to handle the specific upload details | |
if( empty( $this->success_callback ) ) | |
{ | |
$this->success_callback = $this->input->post('success_callback'); | |
} | |
// If success callback supplied, run it | |
if( ! empty( $this->success_callback ) ) | |
{ | |
if( method_exists($this, $this->success_callback) ) | |
{ | |
$callback = $this->success_callback; | |
if( $callback_response = $this->$callback() ) | |
{ | |
// Send Success Response ( Callback Used ) | |
$response['status'] = 'success'; | |
$response['callback_response'] = $callback_response; | |
} | |
else | |
{ | |
// Error: Callback Failed | |
$response['status'] = 'error'; | |
$response['issue'] = 'Callback failed.'; | |
} | |
} | |
else | |
{ | |
// Error: Callback Doesn't Exist | |
$response['status'] = 'error'; | |
$response['issue'] = 'Callback does not exist.'; | |
} | |
} | |
else | |
{ | |
// Send Success Response ( No Callback Used ) | |
$response['status'] = 'success'; | |
} | |
} | |
else | |
{ | |
// Get FTP Errors | |
$errors = $this->ftp->error_stack; | |
$formatted_errors = ''; | |
foreach( $errors as $error ) | |
{ | |
$formatted_errors .= $error . "\n"; | |
} | |
// Send FTP Errors as Response | |
$response['status'] = 'error'; | |
$response['issue'] = $formatted_errors; | |
} | |
$this->ftp->close(); | |
} | |
else | |
{ | |
// Error: Upload Failed | |
$response['status'] = 'error'; | |
$response['issue'] = 'Upload failed. Please try again later, or contact your supervisor.'; | |
} | |
} | |
else | |
{ | |
// Error: No Token Match | |
$response['status'] = 'error'; | |
$response['issue'] = 'No Token Match. Please reload the page.'; | |
} | |
$response['token'] = $this->csrf->token; | |
if( $return ) | |
{ | |
return $response; | |
} | |
else | |
{ | |
echo json_encode( $response ); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | |
// upload_dir must be a single public root level directory | |
$config['upload_dir'] = 'site_uploads'; | |
// FILE SYSTEM --------------------------------------------- | |
$config['filesystem_configuration_documents'] = array( | |
'allowed_types' => 'doc|docx|pdf|txt|xls', | |
'max_size' => '100', | |
); | |
$config['filesystem_configuration_listing_image'] = array( | |
'allowed_types' => 'gif|jpg|jpeg|png', | |
'max_size' => '250', | |
'max_width' => '480', | |
'max_height' => '360', | |
'primary_dir' => 'region_directory', // <- post key of primary directory | |
'secondary_dir' => 'unit_id' // <- post key of secondary directory | |
); | |
// ---------------------------------------------------------- | |
// FTP ------------------------------------------------------ | |
$config['ftp_configuration_report'] = array( | |
'allowed_types' => 'pdf', | |
'max_size' => '2000', | |
'destination_not_file_system' => TRUE | |
); | |
// ---------------------------------------------------------- | |
// DATABASE ------------------------------------------------- | |
$config['db_storage_configuration_photo'] = array( | |
'allowed_types' => 'gif|jpg|jpeg|png', | |
'max_size' => '256', | |
'destination_not_file_system' => TRUE | |
); | |
// ---------------------------------------------------------- | |
/* End of file uploads_manager_config.php */ | |
/* Location: /application/config/uploads_manager_config.php */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment