Esempio n. 1
0
 /**
  * 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');
     }
 }