Skip to content

Commit

Permalink
Change how paraller uploads are handled
Browse files Browse the repository at this point in the history
Related to #37
  • Loading branch information
pionl committed Jun 8, 2018
1 parent a6b6170 commit e18712e
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 83 deletions.
6 changes: 4 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ php artisan vendor:publish --provider="Pion\Laravel\ChunkUpload\Providers\ChunkU

## Usage

**simultaneous uploads are not working correctly - at this moment in experimental state.**

Setup is composed in 3 steps:

1. Integrate your controller that will handle the file upload. [How to](https://github.com/pionl/laravel-chunk-upload/wiki/controller)
Expand All @@ -51,6 +49,10 @@ Setup is composed in 3 steps:
| [simple uploader](https://github.com/simple-uploader) | :heavy_multiplication_x: | :heavy_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: | [@dyktek](https://github.com/dyktek) |
| [ng-file-upload](https://github.com/danialfarid/ng-file-upload) | [Wiki](https://github.com/pionl/laravel-chunk-upload/wiki/ng-file-upload) | :heavy_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: | [@L3o-pold](https://github.com/L3o-pold) |

**Simultaneous uploads:** The library must send last chunk as last, otherwise the merging will not work correctly.

**Custom disk:** At this moment I recommend to use the basic storage setup (not linking public folder). It is not tested (Have free time to ensure it is working? PR the changes!).

For more detailed information (tips) use the [Wiki](https://github.com/pionl/laravel-chunk-upload/wiki) or for working example continue to separate repository with [example](https://github.com/pionl/laravel-chunk-upload-example).

## Changelog
Expand Down
2 changes: 1 addition & 1 deletion src/Handler/ChunksInRequestUploadHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public function isFirstChunk()
}

/**
* Returns the chunks count
* Checks if the chunk is last
*
* @return int
*/
Expand Down
26 changes: 3 additions & 23 deletions src/Handler/DropZoneUploadHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Pion\Laravel\ChunkUpload\Config\AbstractConfig;
use Pion\Laravel\ChunkUpload\Exceptions\ChunkSaveException;
use Pion\Laravel\ChunkUpload\Save\ParallelSave;
use Pion\Laravel\ChunkUpload\Storage\ChunkStorage;
use Pion\Laravel\ChunkUpload\Handler\Traits\HandleParallelUploadTrait;

class DropZoneUploadHandler extends ChunksInRequestUploadHandler
{
use HandleParallelUploadTrait;

const CHUNK_UUID_INDEX = 'dzuuid';
const CHUNK_INDEX = 'dzchunkindex';
const CHUNK_FILE_SIZE_INDEX = 'dztotalfilesize';
Expand All @@ -33,29 +33,9 @@ class DropZoneUploadHandler extends ChunksInRequestUploadHandler
public function __construct(Request $request, $file, $config)
{
parent::__construct($request, $file, $config);

$this->fileUuid = $request->get(self::CHUNK_UUID_INDEX);
}

/**
* Returns the chunk save instance for saving
*
* @param ChunkStorage $chunkStorage the chunk storage
*
* @return ParallelSave
* @throws ChunkSaveException
* @throws ChunkSaveException
*/
public function startSaving($chunkStorage)
{
return new ParallelSave(
$this->getTotalChunksFromRequest($this->request),
$this->file,
$this,
$chunkStorage,
$this->config
);
}

/**
* Builds the chunk file name from file uuid and current chunk
Expand Down
25 changes: 3 additions & 22 deletions src/Handler/ResumableJSUploadHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Pion\Laravel\ChunkUpload\Config\AbstractConfig;
use Pion\Laravel\ChunkUpload\Exceptions\ChunkSaveException;
use Pion\Laravel\ChunkUpload\Save\ParallelSave;
use Pion\Laravel\ChunkUpload\Storage\ChunkStorage;
use Pion\Laravel\ChunkUpload\Handler\Traits\HandleParallelUploadTrait;

class ResumableJSUploadHandler extends ChunksInRequestUploadHandler
{
use HandleParallelUploadTrait;

const CHUNK_UUID_INDEX = 'resumableIdentifier';
const CHUNK_NUMBER_INDEX = 'resumableChunkNumber';
const TOTAL_CHUNKS_INDEX = 'resumableTotalChunks';
Expand All @@ -34,25 +34,6 @@ public function __construct(Request $request, $file, $config)
$this->fileUuid = $request->get(self::CHUNK_UUID_INDEX);
}

/**
* Returns the chunk save instance for saving
*
* @param ChunkStorage $chunkStorage the chunk storage
*
* @return ParallelSave
* @throws ChunkSaveException
*/
public function startSaving($chunkStorage)
{
return new ParallelSave(
$this->getTotalChunksFromRequest($this->request),
$this->file,
$this,
$chunkStorage,
$this->config
);
}

/**
* Append the resumable file - uuid and pass the current chunk index for parallel upload
* @return string
Expand Down
31 changes: 31 additions & 0 deletions src/Handler/Traits/HandleParallelUploadTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Pion\Laravel\ChunkUpload\Handler\Traits;

use Pion\Laravel\ChunkUpload\Exceptions\ChunkSaveException;
use Pion\Laravel\ChunkUpload\Save\ParallelSave;
use Pion\Laravel\ChunkUpload\Storage\ChunkStorage;

trait HandleParallelUploadTrait
{
protected $percentageDone = 0;

/**
* Returns the chunk save instance for saving
*
* @param ChunkStorage $chunkStorage the chunk storage
*
* @return ParallelSave
* @throws ChunkSaveException
*/
public function startSaving($chunkStorage)
{
// Build the parallel save
return new ParallelSave(
$this->file,
$this,
$chunkStorage,
$this->config
);
}
}
11 changes: 10 additions & 1 deletion src/Save/ChunkSave.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,21 @@ protected function handleChunk()
$this->createChunksFolderIfNeeded();
$file = $this->getChunkFilePath();

$this->handleChunkFile($file);
$this->handleChunkFile($file)
->tryToBuildFullFileFromChunks();
}

/**
* Checks if the current chunk is last
* @return $this
*/
protected function tryToBuildFullFileFromChunks()
{
// build the last file because of the last chunk
if ($this->isLastChunk) {
$this->buildFullFileFromChunks();
}
return $this;
}

/**
Expand Down
72 changes: 38 additions & 34 deletions src/Save/ParallelSave.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,16 @@
use Pion\Laravel\ChunkUpload\FileMerger;
use Pion\Laravel\ChunkUpload\Handler\AbstractHandler;
use Pion\Laravel\ChunkUpload\ChunkFile;
use Pion\Laravel\ChunkUpload\Handler\Traits\HandleParallelUploadTrait;
use Pion\Laravel\ChunkUpload\Storage\ChunkStorage;

/**
* Class ParallelSave
*
* @method HandleParallelUploadTrait|AbstractHandler handler()
*
* @package Pion\Laravel\ChunkUpload\Save
*/
class ParallelSave extends ChunkSave
{
protected $totalChunks;
Expand All @@ -23,23 +31,24 @@ class ParallelSave extends ChunkSave
/**
* ParallelSave constructor.
*
* @param int|string $totalChunks
* @param UploadedFile $file the uploaded file (chunk file)
* @param AbstractHandler $handler the handler that detected the correct save method
* @param ChunkStorage $chunkStorage the chunk storage
* @param AbstractConfig $config the config manager
* @param UploadedFile $file the uploaded file (chunk file)
* @param AbstractHandler|HandleParallelUploadTrait $handler the handler that detected the correct save method
* @param ChunkStorage $chunkStorage the chunk storage
* @param AbstractConfig $config the config manager
*
* @throws ChunkSaveException
*/
public function __construct(
$totalChunks,
UploadedFile $file,
AbstractHandler $handler,
ChunkStorage $chunkStorage,
AbstractConfig $config
) {
$this->totalChunks = intval($totalChunks);
)
{
// Get current file validation - the file instance is changed
$this->isFileValid = $file->isValid();

// Handle the file upload
parent::__construct($file, $handler, $chunkStorage, $config);
}

Expand All @@ -49,31 +58,6 @@ public function isValid()
}


/**
* Searches for all chunk files
* @return \Illuminate\Support\Collection
*/
protected function savedChunksFiles()
{
return $this->chunkStorage()->files(function ($file) {
return !preg_match("/\.[\d]+\.".ChunkStorage::CHUNK_EXTENSION."$/", $file);
});
}

/**
* Handles the chunk merging
* @throws ChunkSaveException
*/
protected function handleChunk()
{
$files = $this->savedChunksFiles();
// We need to detect if this is last chunk - get all uploaded chunks (and increase the count by 1 for this
// un-moved chunk) - it's safer due possibility of un-ordered chunks
$this->isLastChunk = ($files->count() + 1) === $this->totalChunks;

parent::handleChunk();
}

/**
* Moves the uploaded chunk file to separate chunk file for merging
*
Expand All @@ -88,13 +72,33 @@ protected function handleChunkFile($file)
return $this;
}

protected function tryToBuildFullFileFromChunks()
{
return parent::tryToBuildFullFileFromChunks();
}

/**
* Searches for all chunk files
*
* @return \Illuminate\Support\Collection
*/
protected function getSavedChunksFiles()
{
$chunkFileName = preg_replace(
"/\.[\d]+\.".ChunkStorage::CHUNK_EXTENSION."$/", '', $this->handler()->getChunkFileName()
);
return $this->chunkStorage->files(function ($file) use ($chunkFileName) {
return str_contains($file, $chunkFileName) === false;
});
}

/**
* @throws MissingChunkFilesException
* @throws ChunkSaveException
*/
protected function buildFullFileFromChunks()
{
$chunkFiles = $this->savedChunksFiles()->all();
$chunkFiles = $this->getSavedChunksFiles()->all();

if (count($chunkFiles) === 0) {
throw new MissingChunkFilesException();
Expand Down
2 changes: 2 additions & 0 deletions src/Storage/ChunkStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ public function directory()
/**
* Returns an array of files in the chunks directory
*
* @param \Closure|null $rejectClosure
*
* @return Collection
*
* @see FilesystemAdapter::files()
Expand Down

0 comments on commit e18712e

Please sign in to comment.