Skip to content

Commit

Permalink
Fix large saved files not being preview-able (only downloaded) (#78)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
maktaa1995 authored Apr 30, 2024
1 parent 7232ba4 commit 3262ac5
Showing 1 changed file with 25 additions and 15 deletions.
40 changes: 25 additions & 15 deletions src/Http/Controllers/FilepondController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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, '');
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}

/**
Expand Down

0 comments on commit 3262ac5

Please sign in to comment.