Skip to content

Instantly share code, notes, and snippets.

@hengkiardo
Forked from og-shawn-crigger/controller.php
Created September 4, 2012 11:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hengkiardo/3620389 to your computer and use it in GitHub Desktop.
Save hengkiardo/3620389 to your computer and use it in GitHub Desktop.
Valums AJAX File Uploader for CodeIgniter
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Ajax_uploader extends CI_Controller {
// ------------------------------------------------------------------------
/**
* Array of allowed file extensions to upload.
*
* @var array
*/
protected $_extensions = array('png', 'jpeg', 'jpg', 'gif', 'bmp'); // Acceptable file extensions
/**
* Directory files get uploaded to.
*
* @var string
*/
protected $_directory = 'media';
/**
* Max Upload Size limit in bytes.
*
* @var integer
*/
protected $_size_limit = 10485760;
/**
* Place holder for error message.
*
* @var string
*/
public $error;
// ------------------------------------------------------------------------
public function index()
{
echo 'test';
}
public function __construct()
{
parent::__construct();
// Everything that happens here gets told in JSON format!
$this->output->set_content_type('application/json');
if ($this->input->get_post('sizeLimit'))
{
logit('Ajax_uploader - Setting sizeLimit via script to - ' . $this->input->post('sizeLimit'));
$this->_size_limit = (int) $this->input->post('sizeLimit');
}
// Check directory exists, is writable, etc.
$this->_directory = $this->check_directory();
$this->_directory = rtrim($this->_directory, '/') . '/';
// Check the server post/upload size against the size_limit.
//$this->check_server_settings();
$this->load->helper('security');
$this->load->library('security');
logit('Ajax_uploader class inited');
}
// ------------------------------------------------------------------------
/**
* The main method, handles uploading files via Valums Ajax File script.
*
* @return void
*/
public function upload_files()
{
$json = array('error' => 'Something really really bad happened, and well I donnu what :(.');
$file = NULL;
if ($this->input->get('qqfile'))
{
$file = $this->input->get('qqfile');
}
elseif (isset($_FILES) && array_key_exists('qqfile', $_FILES))
{
$file = $_FILES['qqfile']['tmp_name'];
}
if (isset($file) && $file !== NULL) //$this->security->xss_clean($file)
{
$ext = pathinfo($file, PATHINFO_EXTENSION);
if (in_array($ext, $this->_extensions))
{
$directory = $this->_directory;
$this->load->helper('url');
$filename = str_replace('.'.$ext, '', $file);
$filename = strtolower(url_title($filename));
$filename .= '.' . $ext;
if ($this->input->get('qqfile'))
{
$input = fopen('php://input', 'r');
$temp = tmpfile();
if ($temp === FALSE)
{
$this->error_report('Failed to create upload file.');
}
$real_size = stream_copy_to_stream($input, $temp);
fclose($input);
/*
if ($real_size != $this->get_size())
{
$this->error_report('File did not completely upload. Try again.');
}
*/
$target = fopen($directory . $filename, 'w');
fseek($temp, 0, SEEK_SET);
stream_copy_to_stream($temp, $target);
fclose($target);
}
elseif ($_FILES['qqfile'])
{
move_uploaded_file($_FILES['qqfile']['tmp_name'], $directory . $filename.'.' .$ext);
}
$json = array('success' => 'true', 'filename' => $file);
}
else
{
$this->error_report('File type not supported.');
}
}
$this->output->set_output(json_encode($json));
}
// ------------------------------------------------------------------------
// PRIVATE METHODS!
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
/**
* Gets File Size by Content Length Server Setting. Isn't Ajax File Uploading Fun!
*
* @return int
*/
private function get_size()
{
if ($this->input->server('CONTENT_LENGTH'))
{
return (int)$this->input->server('CONTENT_LENGTH');
} else {
logit('Ajax_Uploader Failed - Getting content length is not supported.', 'error');
throw new Exception('Getting content length is not supported.');
}
}
// ------------------------------------------------------------------------
/**
* Handles Error reports, logs them, and sends a json response back to the script.
*
* @access private
*
* @param string $message Error message to display
*
* @return void
*/
private function error_report($message = '')
{
$this->error = $message;
logit('Ajax_Uploader failed - '.$this->error, 'error');
$this->output->set_output(json_encode(array('error', $message)));
die;
}
// ------------------------------------------------------------------------
/**
* Checks Server Max Upload and Post Sizes against the Size limit to verify your not nuts.
*
* @access private
*
* @return void
*/
private function check_server_settings()
{
$post_size = $this->to_bytes(ini_get('post_max_size'));
$upload_size = $this->to_bytes(ini_get('upload_max_filesize'));
if ($post_size < $this->_size_limit || $upload_size < $this->_size_limit)
{
$size = max(1, $this->_size_limit / 1024 / 1024) . 'M';
$this->error_report('Increase post_max_size and upload_max_filesize to ' . $size);
return FALSE;
}
}
// ------------------------------------------------------------------------
/**
* Converts Filesize into Kilobytes.
*
* @access private
*
* @param string $str Filesize to be converted
*
* @return int
*/
private function to_bytes($str)
{
$val = trim($str);
$last = strtolower($str[strlen($str)-1]);
switch($last)
{
case 'g': $val *= 1024;
case 'm': $val *= 1024;
case 'k': $val *= 1024;
}
return $val;
}
// ------------------------------------------------------------------------
/**
* Checks upload directory to make sure it exists, if not trys to create one or fails with status message.
*
* @access private
*
* @return string
*/
private function check_directory()
{
$directory = realpath(FCPATH . $this->_directory);
if ( ! is_dir($directory))
{
$status = mkdir($directory, DIR_WRITE_MODE);
if ( ! $status)
{
$this->error_report('Directory does not exist and could not be created.');
}
}
if ( ! is_writable($directory))
{
$status = chmod($directory, DIR_WRITE_MODE);
if ( ! $status)
{
$this->error_report('Server error. Upload directory isn\'t writable.');
}
}
return $directory;
}
}
/* End of file ajax_uploader.php */
/* Location: ./application/controllers/ajax_uploader.php */
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="<?php echo base_url(); ?>assets/css/file-uploader.css" rel="stylesheet" type="text/css">
<link href="<?php echo base_url(); ?>assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<style>
body {font-size:13px; font-family:arial, sans-serif; width:700px; margin:100px auto;}
</style>
</head>
<body>
<p>To upload a file, click on the button below. Drag-and-drop is supported in FF, Chrome.</p>
<p>Progress-bar is supported in FF3.6+, Chrome6+, Safari4+</p>
<?php
/*
<div class="progress progress-striped active">
<div class="bar" style="display:none;"></div>
</div>
*/
?>
<div class="well">
Drag and Drop files here to upload.
<div class="qq-upload-extra-drop-area"></div>
</div>
<div id="image-uploader"></div>
<!-- Assets::add_js(); -->
<script src="<?php echo base_url('/assets/js/file-uploader.js'); ?>" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
function createUploader(){
var ajaxuploader = new qq.FileUploader({
element: document.getElementById('image-uploader'),
action: "<?php echo site_url();?>ajax_uploader/upload_files",
debug: true,
extraDropzones: [qq.getByClass(document, 'qq-upload-extra-drop-area')[0]],
template: '<div class="qq-uploader">' +
'<div class="qq-upload-drop-area"><span>{dragText}</span></div>' +
'<div class="qq-upload-button btn btn-primary btn-large">{uploadButtonText}</div>' +
'<ul class="qq-upload-list"></ul>' +
'</div>',
// template for one item in file list
fileTemplate: '<li>' +
'<span class="qq-progress-bar"></span>' +
'<span class="qq-upload-spinner"></span>' +
'<span class="qq-upload-finished"></span>' +
'<span class="qq-upload-file"></span>' +
'<span class="qq-upload-size"></span>' +
'<a class="qq-upload-cancel btn btn-danger" href="#">{cancelButtonText}</a>' +
'<span class="qq-upload-failed-text alert alert-danger">{failUploadtext}</span>' +
'</li>',
classes: {
// used to get elements from templates
button: 'qq-upload-button',
drop: 'qq-upload-drop-area',
dropActive: 'qq-upload-drop-area-active',
dropDisabled: 'qq-upload-drop-area-disabled',
list: 'qq-upload-list',
progressBar: 'qq-progress-bar',
file: 'qq-upload-file',
spinner: 'qq-upload-spinner',
finished: 'qq-upload-finished',
size: 'qq-upload-size',
cancel: 'qq-upload-cancel',
// added to list item <li> when upload completes
// used in css to hide progress spinner
success: 'qq-upload-success',
fail: 'qq-upload-fail',
successIcon: null,
failIcon: null,
},
showMessage: function(message){
alert(message);
},
<?php
/*
onProgress: function(id, fileName, loaded, total) {
var progress = Math.round((loaded/total)*100);
$('.progress .bar').css({
'width': progress,
});
},
*/
?>
});
}
$(document).ready(function() {
createUploader();
});
// Wrap in doc Ready
// don't wait for the window to load
//window.onload = createUploader;
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment