/** * Append the final chunk and ready file for parent::performUpload() * @return FileRepoStatus */ public function concatenateChunks() { $chunkIndex = $this->getChunkIndex(); wfDebug(__METHOD__ . " concatenate {$this->mChunkIndex} chunks:" . $this->getOffset() . ' inx:' . $chunkIndex . "\n"); // Concatenate all the chunks to mVirtualTempPath $fileList = []; // The first chunk is stored at the mVirtualTempPath path so we start on "chunk 1" for ($i = 0; $i <= $chunkIndex; $i++) { $fileList[] = $this->getVirtualChunkLocation($i); } // Get the file extension from the last chunk $ext = FileBackend::extensionFromPath($this->mVirtualTempPath); // Get a 0-byte temp file to perform the concatenation at $tmpFile = TempFSFile::factory('chunkedupload_', $ext, wfTempDir()); $tmpPath = false; // fail in concatenate() if ($tmpFile) { // keep alive with $this $tmpPath = $tmpFile->bind($this)->getPath(); } // Concatenate the chunks at the temp file $tStart = microtime(true); $status = $this->repo->concatenate($fileList, $tmpPath, FileRepo::DELETE_SOURCE); $tAmount = microtime(true) - $tStart; if (!$status->isOK()) { return $status; } wfDebugLog('fileconcatenate', "Combined {$i} chunks in {$tAmount} seconds."); // File system path of the actual full temp file $this->setTempFile($tmpPath); $ret = $this->verifyUpload(); if ($ret['status'] !== UploadBase::OK) { wfDebugLog('fileconcatenate', "Verification failed for chunked upload"); $status->fatal($this->getVerificationErrorCode($ret['status'])); return $status; } // Update the mTempPath and mStashFile // (for FileUpload or normal Stash to take over) $tStart = microtime(true); // This is a re-implementation of UploadBase::tryStashFile(), we can't call it because we // override doStashFile() with completely different functionality in this class... $error = $this->runUploadStashFileHook($this->user); if ($error) { call_user_func_array([$status, 'fatal'], $error); return $status; } try { $this->mStashFile = parent::doStashFile($this->user); } catch (UploadStashException $e) { $status->fatal('uploadstash-exception', get_class($e), $e->getMessage()); return $status; } $tAmount = microtime(true) - $tStart; $this->mStashFile->setLocalReference($tmpFile); // reuse (e.g. for getImageInfo()) wfDebugLog('fileconcatenate', "Stashed combined file ({$i} chunks) in {$tAmount} seconds."); return $status; }
/** * Append the final chunk and ready file for parent::performUpload() * @return FileRepoStatus */ public function concatenateChunks() { $chunkIndex = $this->getChunkIndex(); wfDebug(__METHOD__ . " concatenate {$this->mChunkIndex} chunks:" . $this->getOffset() . ' inx:' . $chunkIndex . "\n"); // Concatenate all the chunks to mVirtualTempPath $fileList = array(); // The first chunk is stored at the mVirtualTempPath path so we start on "chunk 1" for ($i = 0; $i <= $chunkIndex; $i++) { $fileList[] = $this->getVirtualChunkLocation($i); } // Get the file extension from the last chunk $ext = FileBackend::extensionFromPath($this->mVirtualTempPath); // Get a 0-byte temp file to perform the concatenation at $tmpFile = TempFSFile::factory('chunkedupload_', $ext); $tmpPath = false; // fail in concatenate() if ($tmpFile) { // keep alive with $this $tmpPath = $tmpFile->bind($this)->getPath(); } // Concatenate the chunks at the temp file $tStart = microtime(true); $status = $this->repo->concatenate($fileList, $tmpPath, FileRepo::DELETE_SOURCE); $tAmount = microtime(true) - $tStart; if (!$status->isOk()) { return $status; } wfDebugLog('fileconcatenate', "Combined {$i} chunks in {$tAmount} seconds."); // File system path $this->mTempPath = $tmpPath; // Since this was set for the last chunk previously $this->mFileSize = filesize($this->mTempPath); $ret = $this->verifyUpload(); if ($ret['status'] !== UploadBase::OK) { wfDebugLog('fileconcatenate', "Verification failed for chunked upload"); $status->fatal($this->getVerificationErrorCode($ret['status'])); return $status; } // Update the mTempPath and mLocalFile // (for FileUpload or normal Stash to take over) $tStart = microtime(true); $this->mLocalFile = parent::stashFile($this->user); $tAmount = microtime(true) - $tStart; $this->mLocalFile->setLocalReference($tmpFile); // reuse (e.g. for getImageInfo()) wfDebugLog('fileconcatenate', "Stashed combined file ({$i} chunks) in {$tAmount} seconds."); return $status; }