Skip to content

Instantly share code, notes, and snippets.

@cawecoy
Last active August 28, 2020 03:53
Show Gist options
  • Save cawecoy/b8d02dfe99c29b69e3ecdb8ed2b868d6 to your computer and use it in GitHub Desktop.
Save cawecoy/b8d02dfe99c29b69e3ecdb8ed2b868d6 to your computer and use it in GitHub Desktop.
Workaround for resumable upload with pionl/laravel-chunk-upload and blueimp/jQuery-File-Upload
// using the example from https://github.com/blueimp/jQuery-File-Upload/wiki/Chunked-file-uploads#resuming-file-uploads
// differences from the example: I added the "totalSize" parameter and changed the resumable upload URL to "resumable-upload"
$('#fileupload').fileupload({
maxChunkSize: 10000000, // 10 MB
add: function (e, data) {
var that = this;
$.getJSON('/resumable-upload', {file: data.files[0].name, totalSize: data.files[0].size}, function (result) {
var file = result.file;
data.uploadedBytes = file && file.size;
$.blueimp.fileupload.prototype
.options.add.call(that, e, data);
});
}
});
<?php
namespace App\Handler;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Pion\Laravel\ChunkUpload\Config\FileConfig;
use Pion\Laravel\ChunkUpload\Handler\ContentRangeUploadHandler;
/**
* Class JqueryFileUploadHandler.
*
* Upload receiver that accepts files on the blueimp/jQuery-File-Upload logic and resumable uploads
*
* Works with:
* - blueimp/jQuery-File-Upload (jQuery File Upload) - partial support (simple chunked and single upload)
* - pionl/laravel-chunk-upload (Laravel Chunk Upload)
*
* @see https://github.com/blueimp/jQuery-File-Upload
* @see https://github.com/pionl/laravel-chunk-upload
*/
class JqueryFileUploadHandler extends ContentRangeUploadHandler
{
/**
* ContentRangeUploadHandler constructor.
*
* @param Request $request
* @param null|UploadedFile $file
* @param null|AbstractConfig $config
*
* @throws ContentRangeValueToLargeException
*/
public function __construct(Request $request, $file, $config)
{
parent::__construct($request, $file, $config);
}
/**
* Resumable upload: if chunk file exists, then return the uploadedBytes for jQuery File Upload to resume the aborted upload.
*
* @param Request $request
* @param string $fileNameIndex
* @param string $fileSizeIndex
*
* @return array
*
* @see https://github.com/blueimp/jQuery-File-Upload/wiki/Chunked-file-uploads#resuming-file-uploads
*/
public static function resumableChunkFile(Request $request, $fileNameIndex, $fileSizeIndex)
{
$config = new FileConfig;
$disk = $config->get('storage.disk', 'local');
// ContentRangeUploadHandler's createChunkFileName method uses UploadedFile's getClientOriginalName method, which requeres a file, so we create an empty file for that
if(!Storage::disk($disk)->exists('file-upload-util.txt')){
Storage::disk($disk)->put('file-upload-util.txt', '');
}
// using the resumable file name as UploadedFile's originalName parameter
$file = new UploadedFile(storage_path().'/app/file-upload-util.txt', $request->input($fileNameIndex));
$handler = new ContentRangeUploadHandler($request, $file, $config);
// now we have the name of the possible chunk file for a previously aborted upload
$chunkFileName = $handler->createChunkFileName($request->input($fileSizeIndex));
$chunkFileFullPath = $config->get('storage.chunks', 'chunks').'/'.$chunkFileName;
// if the chunk file was found (previously uploaded and aborted), send the size for the upload to be resumed by jQuery File Upload
if(Storage::disk($disk)->exists($chunkFileFullPath)){
return [
'file' => [
'size' => Storage::disk($disk)->size($chunkFileFullPath),
],
];
}
else{
return [];
}
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Handler\JqueryFileUploadHandler;
class ResumableUploadController extends BaseController
{
/**
* Check if the file already exists to resume upload
*
* @param Request $request
*
* @return JsonResponse
*
*/
public function resumableUpload(Request $request)
{
return response()->json(JqueryFileUploadHandler::resumableChunkFile($request, 'file', 'totalSize'));
}
}
<?php
Route::get('resumable-upload', 'ResumableUploadController@resumableUpload')->name('resumable-upload');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment