From 3262ac5271cf79187c9b9d8c2165a870c639c1dd Mon Sep 17 00:00:00 2001 From: Mohammad aktaa <134686831+maktaa1995@users.noreply.github.com> Date: Tue, 30 Apr 2024 13:09:11 +0300 Subject: [PATCH] Fix large saved files not being preview-able (only downloaded) (#78) * Fix large saved files not being preview-able (only downloaded) * PR feedback * PR feedback * PR feedback * fix Cannot access offset of type string on string error --- src/Http/Controllers/FilepondController.php | 40 +++++++++++++-------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/Http/Controllers/FilepondController.php b/src/Http/Controllers/FilepondController.php index f48e9bf..8468dee 100755 --- a/src/Http/Controllers/FilepondController.php +++ b/src/Http/Controllers/FilepondController.php @@ -37,7 +37,7 @@ public function upload(Request $request) $input = $request->file(config('filepond.input_name')); if ($input === null) { - return $this->handleChunkInitialization(); + return $this->handleChunkInitialization($request); } $file = is_array($input) ? $input[0] : $input; @@ -62,13 +62,19 @@ public function upload(Request $request) * @param Request $request * @return \Illuminate\Http\Response */ - private function handleChunkInitialization() + private function handleChunkInitialization(Request $request) { $randomId = Str::random(); $path = config('filepond.temporary_files_path', 'filepond'); $disk = config('filepond.temporary_files_disk', 'local'); - $fileLocation = $path . DIRECTORY_SEPARATOR . $randomId; + $baseName = $randomId; + if ($request->header('Upload-Name')) { + $fileName = pathinfo($request->header('Upload-Name'), PATHINFO_FILENAME); + $ext = pathinfo($request->header('Upload-Name'), PATHINFO_EXTENSION); + $baseName = $fileName.'-'.$randomId.'.'.$ext; + } + $fileLocation = $path . DIRECTORY_SEPARATOR . $baseName; $fileCreated = Storage::disk($disk) ->put($fileLocation, ''); @@ -125,7 +131,7 @@ public function chunk(Request $request) ->put($basePath . DIRECTORY_SEPARATOR . 'patch.' . $offset, $request->getContent(), ['mimetype' => 'application/octet-stream']); $this->persistFileIfDone($disk, $basePath, $length, $finalFilePath); - + return Response::make('', 204); } @@ -164,20 +170,24 @@ private function persistFileIfDone($disk, $basePath, $length, $finalFilePath) $chunks = $chunks->sortKeys(); // Append each chunk to the final file - $data = ''; + $tmpFile = tmpfile(); + $tmpFileName = stream_get_meta_data($tmpFile)['uri']; + // Append each chunk to the final file foreach ($chunks as $chunk) { // Get chunk contents - $chunkContents = $storage - ->get($chunk); - - // Laravel's local disk implementation is quite inefficient for appending data to existing files - // To be at least a bit more efficient, we build the final content ourselves, but the most efficient - // Way to do this would be to append using the driver's capabilities - $data .= $chunkContents; - unset($chunkContents); + $chunkContents = $storage->readStream($chunk); + + // Stream data from chunk to tmp file + stream_copy_to_stream($chunkContents, $tmpFile); + } + // We can also pass ['mimetype' => $storage->mimeType($finalFilePath)] since the + // $finalFilePath now contains the extension of the file + $storage->put($finalFilePath, $tmpFile); + $storage->deleteDirectory($basePath); + + if (file_exists($tmpFileName)) { + unlink($tmpFileName); } - Storage::disk($disk)->put($finalFilePath, $data, ['mimetype' => 'application/octet-stream']); - Storage::disk($disk)->deleteDirectory($basePath); } /**