public static function realMultipleUpload($frontEnd = 0)
{
$paramsC = ComponentHelper::getParams('com_phocagallery');
$chunkMethod = $paramsC->get('multiple_upload_chunk', 0);
$uploadMethod = $paramsC->get('multiple_upload_method', 4);
$app = Factory::getApplication();
$app->allowCache(false);
// Chunk Files
header('Content-type: text/plain; charset=UTF-8');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
// Invalid Token
Session::checkToken('request') or jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 100, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_INVALID_TOKEN'))));
// Set FTP credentials, if given
$ftp = ClientHelper::setCredentialsFromRequest('ftp');
$path = PhocaGalleryPath::getPath();
$file = Factory::getApplication()->input->files->get('file', null);
$chunk = Factory::getApplication()->input->get('chunk', 0, '', 'int');
$chunks = Factory::getApplication()->input->get('chunks', 0, '', 'int');
$folder = Factory::getApplication()->input->get('folder', '', '', 'path');
// Make the filename safe
if (isset($file['name'])) {
$file['name'] = File::makeSafe($file['name']);
}
if (isset($folder) && $folder != '') {
$folder = $folder . '/';
}
$chunkEnabled = 0;
// Chunk only if is enabled and only if flash is enabled
if ($chunkMethod == 1 && $uploadMethod == 1 || $frontEnd == 0 && $chunkMethod == 0 && $uploadMethod == 1) {
$chunkEnabled = 1;
}
if (isset($file['name'])) {
// - - - - - - - - - -
// Chunk Method
// - - - - - - - - - -
// $chunkMethod = 1, for frontend and backend
// $chunkMethod = 0, only for backend
if ($chunkEnabled == 1) {
// If chunk files are used, we need to upload parts to temp directory
// and then we can run e.g. the condition to recognize if the file already exists
// We must upload the parts to temp, in other case we get everytime the info
// that the file exists (because the part has the same name as the file)
// so after first part is uploaded, in fact the file already exists
// Example: NOT USING CHUNK
// If we upload abc.jpg file to server and there is the same file
// we compare it and can recognize, there is one, don't upload it again.
// Example: USING CHUNK
// If we upload abc.jpg file to server and there is the same file
// the part of current file will overwrite the same file
// and then (after all parts will be uploaded) we can make the condition to compare the file
// and we recognize there is one - ok don't upload it BUT the file will be damaged by
// parts uploaded by the new file - so this is why we are using temp file in Chunk method
$stream = JFactory::getStream();
// Chunk Files
$tempFolder = 'pgpluploadtmpfolder/';
$filepathImgFinal = Path::clean($path->image_abs . $folder . strtolower($file['name']));
$filepathImgTemp = Path::clean($path->image_abs . $folder . $tempFolder . strtolower($file['name']));
$filepathFolderFinal = Path::clean($path->image_abs . $folder);
$filepathFolderTemp = Path::clean($path->image_abs . $folder . $tempFolder);
$maxFileAge = 60 * 60;
// Temp file age in seconds
$lastChunk = $chunk + 1;
$realSize = 0;
// Get the real size - if chunk is uploaded, it is only a part size, so we must compute all size
// If there is last chunk we can computhe the whole size
if ($lastChunk == $chunks) {
if (File::exists($filepathImgTemp) && File::exists($file['tmp_name'])) {
$realSize = filesize($filepathImgTemp) + filesize($file['tmp_name']);
}
}
// 5 minutes execution time
@set_time_limit(5 * 60);
// usleep(5000);
// If the file already exists on the server:
// - don't copy the temp file to final
// - remove all parts in temp file
// Because some parts are uploaded before we can run the condition
// to recognize if the file already exists.
if (File::exists($filepathImgFinal)) {
if ($lastChunk == $chunks) {
@Folder::delete($filepathFolderTemp);
}
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 108, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_FILE_ALREADY_EXISTS'))));
}
if (!PhocaGalleryFileUpload::canUpload($file, $errUploadMsg, $frontEnd, $chunkEnabled, $realSize)) {
// If there is some error, remove the temp folder with temp files
if ($lastChunk == $chunks) {
@Folder::delete($filepathFolderTemp);
}
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 104, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_($errUploadMsg))));
}
// Ok create temp folder and add chunks
if (!Folder::exists($filepathFolderTemp)) {
@Folder::create($filepathFolderTemp);
}
// Remove old temp files
if (Folder::exists($filepathFolderTemp)) {
$dirFiles = Folder::files($filepathFolderTemp);
if (!empty($dirFiles)) {
foreach ($dirFiles as $fileS) {
$filePathImgS = $filepathFolderTemp . $fileS;
// Remove temp files if they are older than the max age
if (preg_match('/\\.tmp$/', $fileS) && filemtime($filepathImgTemp) < time() - $maxFileAge) {
@File::delete($filePathImgS);
}
}
}
} else {
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 100, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_ERROR_FOLDER_UPLOAD_NOT_EXISTS'))));
}
// Look for the content type header
if (isset($_SERVER["HTTP_CONTENT_TYPE"])) {
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
}
if (isset($_SERVER["CONTENT_TYPE"])) {
$contentType = $_SERVER["CONTENT_TYPE"];
}
if (strpos($contentType, "multipart") !== false) {
if (isset($file['tmp_name']) && is_uploaded_file($file['tmp_name'])) {
// Open temp file
$out = $stream->open($filepathImgTemp, $chunk == 0 ? "wb" : "ab");
//$out = fopen($filepathImgTemp, $chunk == 0 ? "wb" : "ab");
if ($out) {
// Read binary input stream and append it to temp file
$in = fopen($file['tmp_name'], "rb");
if ($in) {
while ($buff = fread($in, 4096)) {
$stream->write($buff);
//fwrite($out, $buff);
}
} else {
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 101, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_ERROR_OPEN_INPUT_STREAM'))));
}
$stream->close();
//fclose($out);
@File::delete($file['tmp_name']);
} else {
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 102, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_ERROR_OPEN_OUTPUT_STREAM'))));
}
} else {
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 103, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_ERROR_MOVE_UPLOADED_FILE'))));
}
} else {
// Open temp file
$out = $stream->open($filepathImgTemp, $chunk == 0 ? "wb" : "ab");
//$out = JFile::read($filepathImg);
if ($out) {
// Read binary input stream and append it to temp file
$in = fopen("php://input", "rb");
if ($in) {
while ($buff = fread($in, 4096)) {
$stream->write($buff);
}
} else {
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 101, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_ERROR_OPEN_INPUT_STREAM'))));
}
$stream->close();
//fclose($out);
} else {
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 102, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_ERROR_OPEN_OUTPUT_STREAM'))));
}
}
// Rename the Temp File to Final File
if ($lastChunk == $chunks) {
if (($imginfo = getimagesize($filepathImgTemp)) === FALSE) {
Folder::delete($filepathFolderTemp);
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 110, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_WARNING_INVALIDIMG'))));
}
if (!File::move($filepathImgTemp, $filepathImgFinal)) {
Folder::delete($filepathFolderTemp);
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 109, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_ERROR_UNABLE_TO_MOVE_FILE') . '<br />' . Text::_('COM_PHOCAGALLERY_CHECK_PERMISSIONS_OWNERSHIP'))));
}
Folder::delete($filepathFolderTemp);
}
if ((int) $frontEnd > 0) {
return $file['name'];
}
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'OK', 'code' => 200, 'message' => Text::_('COM_PHOCAGALLERY_SUCCESS') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_IMAGES_UPLOADED'))));
} else {
// No Chunk Method
$filepathImgFinal = Path::clean($path->image_abs . $folder . strtolower($file['name']));
$filepathFolderFinal = Path::clean($path->image_abs . $folder);
if (!PhocaGalleryFileUpload::canUpload($file, $errUploadMsg, $frontEnd, $chunkMethod, 0)) {
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 104, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_($errUploadMsg))));
}
if (File::exists($filepathImgFinal)) {
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 108, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_FILE_ALREADY_EXISTS'))));
}
if (!File::upload($file['tmp_name'], $filepathImgFinal, false, true)) {
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 109, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_ERROR_UNABLE_TO_UPLOAD_FILE') . '<br />' . Text::_('COM_PHOCAGALLERY_CHECK_PERMISSIONS_OWNERSHIP'))));
}
if ((int) $frontEnd > 0) {
return $file['name'];
}
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'OK', 'code' => 200, 'message' => Text::_('COM_PHOCAGALLERY_SUCCESS') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_IMAGES_UPLOADED'))));
}
} else {
// No isset $file['name']
jexit(json_encode(array('jsonrpc' => '2.0', 'result' => 'error', 'code' => 104, 'message' => Text::_('COM_PHOCAGALLERY_ERROR') . ': ', 'details' => Text::_('COM_PHOCAGALLERY_ERROR_UNABLE_TO_UPLOAD_FILE'))));
}
}