/** * Process the upload. * @param string $uploadDirectory Target directory. * @param string $name Overwrites the name of the file. */ public function handleUpload($uploadDirectory, $name = null) { // Make the chunks and upload directories if they don't exist $chunks_folder = !is_dir($this->chunksFolder) ? @mkdir($this->chunksFolder, 0775, true) : true; $upload_folder = !is_dir($uploadDirectory) ? @mkdir($uploadDirectory, 0775, true) : true; if (is_writable($this->chunksFolder) && 1 == mt_rand(1, 1 / $this->chunksCleanupProbability)) { // Run garbage collection $this->cleanupChunks(); } // Check that the max upload size specified in class configuration does not // exceed size allowed by server config if ($this->toBytes(ini_get('post_max_size')) < $this->sizeLimit || $this->toBytes(ini_get('upload_max_filesize')) < $this->sizeLimit) { $size = max(1, $this->sizeLimit / 1024 / 1024) . 'M'; return array('error' => "Server error. Increase post_max_size and upload_max_filesize to " . $size); } if (!is_writable($uploadDirectory)) { return array('error' => "Server error. Uploads directory isn't writable or executable."); } if (!isset($_SERVER['CONTENT_TYPE'])) { return array('error' => "No files were uploaded."); } else { if (strpos(strtolower($_SERVER['CONTENT_TYPE']), 'multipart/') !== 0) { return array('error' => "Server error. Not a multipart request. Please set forceMultipart to default value (true)."); } } // Get size and name $file = $_FILES[$this->inputName]; $size = $file['size']; if ($name === null) { $name = $this->originalName = $this->getName(); } // Validate name if ($name === null || $name === '') { return array('error' => 'File name empty.'); } // Validate file size if ($size == 0) { return array('error' => 'File is empty.'); } if ($size > $this->sizeLimit) { return array('error' => 'File is too large.'); } // Validate file extension $pathinfo = pathinfo($name); $ext = isset($pathinfo['extension']) ? $pathinfo['extension'] : ''; if ($this->allowedExtensions && !in_array(strtolower($ext), array_map("strtolower", $this->allowedExtensions))) { $these = implode(', ', $this->allowedExtensions); return array('error' => 'File has an invalid extension, it should be one of ' . $these . '.'); } // Save a chunk $totalParts = isset($_REQUEST['qqtotalparts']) ? (int) $_REQUEST['qqtotalparts'] : 1; if ($totalParts > 1) { $chunksFolder = $this->chunksFolder; $partIndex = (int) $_REQUEST['qqpartindex']; $uuid = $_REQUEST['qquuid']; if (!is_writable($chunksFolder) || !is_executable($uploadDirectory)) { return array('error' => "Server error. Chunks directory isn't writable or executable."); } $targetFolder = $this->chunksFolder . DIRECTORY_SEPARATOR . $uuid; if (!file_exists($targetFolder)) { mkdir($targetFolder); } $target = $targetFolder . '/' . $partIndex; $success = move_uploaded_file($_FILES[$this->inputName]['tmp_name'], $target); // Last chunk saved successfully if ($success and $totalParts - 1 == $partIndex) { $target = \CMF::getUniqueFilePath($uploadDirectory, $name); $this->uploadName = basename($target); $target = fopen($target, 'w'); for ($i = 0; $i < $totalParts; $i++) { $chunk = fopen($targetFolder . '/' . $i, "rb"); stream_copy_to_stream($chunk, $target); fclose($chunk); } // Success fclose($target); for ($i = 0; $i < $totalParts; $i++) { $chunk = fopen($targetFolder . '/' . $i, "r"); unlink($targetFolder . '/' . $i); } rmdir($targetFolder); return array("success" => true); } return array("success" => true); } else { $target = $this->target = \CMF::getUniqueFilePath($uploadDirectory, $name); if ($target) { $this->uploadName = basename($target); if (move_uploaded_file($file['tmp_name'], $target)) { return array('success' => true); } } return array('error' => 'Could not save uploaded file.' . 'The upload was cancelled, or server error encountered'); } }