/**
* Allows plugin to handle ajax file uploads.
*
* @access public
* @param object $Sender
*/
public function postController_upload_create($Sender)
{
list($FieldName) = $Sender->RequestArgs;
$Sender->deliveryMethod(DELIVERY_METHOD_JSON);
$Sender->deliveryType(DELIVERY_TYPE_VIEW);
include_once $Sender->fetchViewLocation('fileupload_functions', '', 'plugins/FileUpload');
$Sender->FieldName = $FieldName;
$Sender->ApcKey = Gdn::request()->getValueFrom(Gdn_Request::INPUT_POST, 'APC_UPLOAD_PROGRESS');
$FileData = Gdn::request()->getValueFrom(Gdn_Request::INPUT_FILES, $FieldName, false);
try {
if (!$this->CanUpload) {
throw new FileUploadPluginUploadErrorException("You do not have permission to upload files", 11, '???');
}
if (!$Sender->Form->isPostBack()) {
$PostMaxSize = ini_get('post_max_size');
throw new FileUploadPluginUploadErrorException("The post data was too big (max {$PostMaxSize})", 10, '???');
}
if (!$FileData) {
throw new FileUploadPluginUploadErrorException("No file data could be found in your post", 10, '???');
}
// Validate the file upload now.
$FileErr = $FileData['error'];
$FileType = $FileData['type'];
$FileName = $FileData['name'];
$FileTemp = $FileData['tmp_name'];
$FileSize = $FileData['size'];
$FileKey = $Sender->ApcKey ? $Sender->ApcKey : '';
if ($FileErr != UPLOAD_ERR_OK) {
$ErrorString = '';
switch ($FileErr) {
case UPLOAD_ERR_INI_SIZE:
$MaxUploadSize = ini_get('upload_max_filesize');
$ErrorString = sprintf(t('The uploaded file was too big (max %s).'), $MaxUploadSize);
break;
case UPLOAD_ERR_FORM_SIZE:
$ErrorString = 'The uploaded file was too big';
break;
case UPLOAD_ERR_PARTIAL:
$ErrorString = 'The uploaded file was only partially uploaded';
break;
case UPLOAD_ERR_NO_FILE:
$ErrorString = 'No file was uploaded';
break;
case UPLOAD_ERR_NO_TMP_DIR:
$ErrorString = 'Missing a temporary folder';
break;
case UPLOAD_ERR_CANT_WRITE:
$ErrorString = 'Failed to write file to disk';
break;
case UPLOAD_ERR_EXTENSION:
$ErrorString = 'A PHP extension stopped the file upload';
break;
}
throw new FileUploadPluginUploadErrorException($ErrorString, $FileErr, $FileName, $FileKey);
}
// Analyze file extension
$FileNameParts = pathinfo($FileName);
$Extension = strtolower($FileNameParts['extension']);
$AllowedExtensions = C('Garden.Upload.AllowedFileExtensions', array("*"));
if (!in_array($Extension, $AllowedExtensions) && !in_array('*', $AllowedExtensions)) {
throw new FileUploadPluginUploadErrorException("Uploaded file type is not allowed.", 11, $FileName, $FileKey);
}
// Check upload size
$MaxUploadSize = Gdn_Upload::unformatFileSize(c('Garden.Upload.MaxFileSize', '1G'));
if ($FileSize > $MaxUploadSize) {
$Message = sprintf(t('The uploaded file was too big (max %s).'), Gdn_Upload::formatFileSize($MaxUploadSize));
throw new FileUploadPluginUploadErrorException($Message, 11, $FileName, $FileKey);
}
// Build filename
$SaveFilename = md5(microtime()) . '.' . strtolower($Extension);
$SaveFilename = '/FileUpload/' . substr($SaveFilename, 0, 2) . '/' . substr($SaveFilename, 2);
// Get the image size before doing anything.
list($ImageWidth, $ImageHeight, $ImageType) = Gdn_UploadImage::imageSize($FileTemp, $FileName);
// Fire event for hooking save location
$this->EventArguments['Path'] = $FileTemp;
$Parsed = Gdn_Upload::parse($SaveFilename);
$this->EventArguments['Parsed'] =& $Parsed;
$this->EventArguments['OriginalFilename'] = $FileName;
$Handled = false;
$this->EventArguments['Handled'] =& $Handled;
$this->EventArguments['ImageType'] = $ImageType;
$this->fireAs('Gdn_Upload')->fireEvent('SaveAs');
if (!$Handled) {
// Build save location
$SavePath = MediaModel::pathUploads() . $SaveFilename;
if (!is_dir(dirname($SavePath))) {
@mkdir(dirname($SavePath), 0777, true);
}
if (!is_dir(dirname($SavePath))) {
throw new FileUploadPluginUploadErrorException("Internal error, could not save the file.", 9, $FileName);
}
// Move to permanent location
// Use SaveImageAs so that image is rotated if necessary
if ($ImageType !== false) {
try {
$ImgParsed = Gdn_UploadImage::saveImageAs($FileTemp, $SavePath);
$MoveSuccess = true;
// In case image got rotated
$ImageWidth = $ImgParsed['Width'];
$ImageHeight = $ImgParsed['Height'];
} catch (Exception $Ex) {
// In case it was an image, but not a supported type - still upload
$MoveSuccess = @move_uploaded_file($FileTemp, $SavePath);
}
} else {
// If not an image, just upload it
$MoveSuccess = @move_uploaded_file($FileTemp, $SavePath);
}
if (!$MoveSuccess) {
throw new FileUploadPluginUploadErrorException("Internal error, could not move the file.", 9, $FileName);
}
} else {
$SaveFilename = $Parsed['SaveName'];
}
// Save Media data
$Media = array('Name' => $FileName, 'Type' => $FileType, 'Size' => $FileSize, 'ImageWidth' => $ImageWidth, 'ImageHeight' => $ImageHeight, 'InsertUserID' => Gdn::session()->UserID, 'DateInserted' => date('Y-m-d H:i:s'), 'StorageMethod' => 'local', 'Path' => $SaveFilename);
$MediaID = $this->mediaModel()->save($Media);
$Media['MediaID'] = $MediaID;
$MediaResponse = array('Status' => 'success', 'MediaID' => $MediaID, 'Filename' => $FileName, 'Filesize' => $FileSize, 'FormatFilesize' => Gdn_Format::bytes($FileSize, 1), 'ProgressKey' => $Sender->ApcKey ? $Sender->ApcKey : '', 'Thumbnail' => base64_encode(MediaThumbnail($Media)), 'FinalImageLocation' => Url(MediaModel::url($Media)), 'Parsed' => $Parsed);
} catch (FileUploadPluginUploadErrorException $e) {
$MediaResponse = array('Status' => 'failed', 'ErrorCode' => $e->getCode(), 'Filename' => $e->getFilename(), 'StrError' => $e->getMessage());
if (!is_null($e->getApcKey())) {
$MediaResponse['ProgressKey'] = $e->getApcKey();
}
if ($e->getFilename() != '???') {
$MediaResponse['StrError'] = '(' . $e->getFilename() . ') ' . $MediaResponse['StrError'];
}
} catch (Exception $Ex) {
$MediaResponse = array('Status' => 'failed', 'ErrorCode' => $Ex->getCode(), 'StrError' => $Ex->getMessage());
}
$Sender->setJSON('MediaResponse', $MediaResponse);
// Kludge: This needs to have a content type of text/* because it's in an iframe.
ob_clean();
header('Content-Type: text/html');
echo json_encode($Sender->getJson());
die;
}