diff --git a/Controller/AbstractChunkedController.php b/Controller/AbstractChunkedController.php index de094cbc..e3438075 100644 --- a/Controller/AbstractChunkedController.php +++ b/Controller/AbstractChunkedController.php @@ -4,7 +4,11 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\File\UploadedFile; + +use Oneup\UploaderBundle\UploadEvents; +use Oneup\UploaderBundle\Uploader\Response\ResponseInterface; use Oneup\UploaderBundle\Controller\AbstractController; +use Oneup\UploaderBundle\Event\PostChunkUploadEvent; abstract class AbstractChunkedController extends AbstractController { @@ -35,7 +39,7 @@ abstract protected function parseChunkedRequest(Request $request); * * @param file The uploaded chunk. */ - protected function handleChunkedUpload(UploadedFile $file) + protected function handleChunkedUpload(UploadedFile $file, ResponseInterface $response, Request $request) { // get basic container stuff $request = $this->container->get('request'); @@ -47,12 +51,13 @@ protected function handleChunkedUpload(UploadedFile $file) // get information about this chunked request list($last, $uuid, $index, $orig) = $this->parseChunkedRequest($request); - $uploaded = $chunkManager->addChunk($uuid, $index, $file, $orig); + $chunk = $chunkManager->addChunk($uuid, $index, $file, $orig); + + $this->dispatchChunkEvents($chunk, $response, $request, $last); // if all chunks collected and stored, proceed // with reassembling the parts - if($last) - { + if ($last) { // we'll take the first chunk and append the others to it // this way we don't need another file in temporary space for assembling $chunks = $chunkManager->getChunks($uuid); @@ -66,11 +71,22 @@ protected function handleChunkedUpload(UploadedFile $file) // validate this entity and upload on success $this->validate($uploadedFile); - $uploaded = $this->handleUpload($uploadedFile); + $uploaded = $this->handleUpload($uploadedFile, $response, $request); $chunkManager->cleanup($path); } + } + + /** + * This function is a helper function which dispatches post chunk upload event. + */ + protected function dispatchChunkEvents($uploaded, ResponseInterface $response, Request $request, $isLast) + { + $dispatcher = $this->container->get('event_dispatcher'); - return $uploaded; + // dispatch post upload event (both the specific and the general) + $postUploadEvent = new PostChunkUploadEvent($uploaded, $response, $request, $isLast, $this->type, $this->config); + $dispatcher->dispatch(UploadEvents::POST_CHUNK_UPLOAD, $postUploadEvent); + $dispatcher->dispatch(sprintf('%s.%s', UploadEvents::POST_CHUNK_UPLOAD, $this->type), $postUploadEvent); } } \ No newline at end of file diff --git a/Controller/AbstractController.php b/Controller/AbstractController.php index 49bce30a..bcbe7639 100644 --- a/Controller/AbstractController.php +++ b/Controller/AbstractController.php @@ -44,7 +44,7 @@ abstract public function upload(); * @param UploadedFile The file to upload * @return File the actual file */ - protected function handleUpload(UploadedFile $file) + protected function handleUpload(UploadedFile $file, ResponseInterface $response, Request $request) { $this->validate($file); @@ -55,7 +55,7 @@ protected function handleUpload(UploadedFile $file) // perform the real upload $uploaded = $this->storage->upload($file, $name); - return $uploaded; + $this->dispatchEvents($uploaded, $response, $request); } /** @@ -71,8 +71,7 @@ protected function dispatchEvents($uploaded, ResponseInterface $response, Reques $dispatcher->dispatch(UploadEvents::POST_UPLOAD, $postUploadEvent); $dispatcher->dispatch(sprintf('%s.%s', UploadEvents::POST_UPLOAD, $this->type), $postUploadEvent); - if(!$this->config['use_orphanage']) - { + if (!$this->config['use_orphanage']) { // dispatch post persist event (both the specific and the general) $postPersistEvent = new PostPersistEvent($uploaded, $response, $request, $this->type, $this->config); $dispatcher->dispatch(UploadEvents::POST_PERSIST, $postPersistEvent); diff --git a/Controller/BlueimpController.php b/Controller/BlueimpController.php index 981a4a4e..e62ed31f 100644 --- a/Controller/BlueimpController.php +++ b/Controller/BlueimpController.php @@ -23,15 +23,12 @@ public function upload() { $file = $file[0]; - try - { - $uploaded = $chunked ? $this->handleChunkedUpload($file) : $this->handleUpload($file); - - // dispatch POST_PERSIST AND POST_UPLOAD events - $this->dispatchEvents($uploaded, $response, $request); - } - catch(UploadException $e) - { + try { + $chunked ? + $this->handleChunkedUpload($file, $response, $request) : + $this->handleUpload($file, $response, $request) + ; + } catch(UploadException $e) { // return nothing return new JsonResponse(array()); } diff --git a/Controller/FancyUploadController.php b/Controller/FancyUploadController.php index c2e32bd0..30a58a88 100644 --- a/Controller/FancyUploadController.php +++ b/Controller/FancyUploadController.php @@ -20,7 +20,7 @@ public function upload() { try { - $uploaded = $this->handleUpload($file); + $uploaded = $this->handleUpload($file, $response, $request); // dispatch POST_PERSIST AND POST_UPLOAD events $this->dispatchEvents($uploaded, $response, $request); diff --git a/Controller/FineUploaderController.php b/Controller/FineUploaderController.php index 37aa0b4a..c2952344 100644 --- a/Controller/FineUploaderController.php +++ b/Controller/FineUploaderController.php @@ -25,10 +25,10 @@ public function upload() { try { - $uploaded = $chunked ? $this->handleChunkedUpload($file) : $this->handleUpload($file); - - // dispatch POST_PERSIST AND POST_UPLOAD events - $this->dispatchEvents($uploaded, $response, $request); + $chunked ? + $this->handleChunkedUpload($file, $response, $request) : + $this->handleUpload($file, $response, $request) + ; } catch(UploadException $e) { diff --git a/Controller/MooUploadController.php b/Controller/MooUploadController.php index 1b06878d..1b2ec9b5 100644 --- a/Controller/MooUploadController.php +++ b/Controller/MooUploadController.php @@ -33,8 +33,6 @@ public function upload() try { - $uploaded = $chunked ? $this->handleChunkedUpload($file) : $this->handleUpload($file); - // fill response object $response = $this->response; @@ -42,9 +40,11 @@ public function upload() $response->setSize($headers->get('content-length')); $response->setName($headers->get('x-file-name')); $response->setUploadedName($uploadFileName); - - // dispatch POST_PERSIST AND POST_UPLOAD events - $this->dispatchEvents($uploaded, $response, $request); + + $chunked ? + $this->handleChunkedUpload($file, $response, $request) : + $this->handleUpload($file, $response, $request) + ; } catch(UploadException $e) { diff --git a/Controller/PluploadController.php b/Controller/PluploadController.php index c4451748..60501e98 100644 --- a/Controller/PluploadController.php +++ b/Controller/PluploadController.php @@ -23,10 +23,10 @@ public function upload() { try { - $uploaded = $chunked ? $this->handleChunkedUpload($file) : $this->handleUpload($file); - - // dispatch POST_PERSIST AND POST_UPLOAD events - $this->dispatchEvents($uploaded, $response, $request); + $chunked ? + $this->handleChunkedUpload($file, $response, $request) : + $this->handleUpload($file, $response, $request) + ; } catch(UploadException $e) { diff --git a/Controller/UploadifyController.php b/Controller/UploadifyController.php index ea18f524..88038a26 100644 --- a/Controller/UploadifyController.php +++ b/Controller/UploadifyController.php @@ -20,7 +20,7 @@ public function upload() { try { - $uploaded = $this->handleUpload($file); + $uploaded = $this->handleUpload($file, $response, $request); // dispatch POST_PERSIST AND POST_UPLOAD events $this->dispatchEvents($uploaded, $response, $request); diff --git a/Controller/YUI3Controller.php b/Controller/YUI3Controller.php index b063e92d..44759477 100644 --- a/Controller/YUI3Controller.php +++ b/Controller/YUI3Controller.php @@ -20,7 +20,7 @@ public function upload() { try { - $uploaded = $this->handleUpload($file); + $uploaded = $this->handleUpload($file, $response, $request); // dispatch POST_PERSIST AND POST_UPLOAD events $this->dispatchEvents($uploaded, $response, $request); diff --git a/Event/PostChunkUploadEvent.php b/Event/PostChunkUploadEvent.php new file mode 100644 index 00000000..7d5aacde --- /dev/null +++ b/Event/PostChunkUploadEvent.php @@ -0,0 +1,62 @@ +chunk = $chunk; + $this->request = $request; + $this->response = $response; + $this->isLast = $isLast; + $this->type = $type; + $this->config = $config; + } + + public function getChunk() + { + return $this->chunk; + } + + public function getRequest() + { + return $this->request; + } + + public function getType() + { + return $this->type; + } + + public function getResponse() + { + return $this->response; + } + + public function getConfig() + { + return $this->config; + } + + public function getIsLast() + { + return $this->isLast; + } + + public function isLast() + { + return $this->isLast; + } +} diff --git a/Resources/doc/events.md b/Resources/doc/events.md index 4edba13d..a7a5ff5d 100644 --- a/Resources/doc/events.md +++ b/Resources/doc/events.md @@ -6,6 +6,10 @@ For a list of general Events, you can always have a look at the `UploadEvents.ph * `oneup_uploader.post_upload` Will be dispatched after a file has been uploaded and moved. * `oneup_uploader.post_persist` The same as `oneup_uploader.post_upload` but will only be dispatched if no `Orphanage` is used. +In case you are using chunked uploads on your frontend, you can listen to: + +* `oneup_uploader.post_chunk_upload` Will be dispatched after a chunk has been uploaded (including the last and assembled one) + Moreover this bundles also dispatches some special kind of generic events you can listen to. * `oneup_uploader.post_upload.{mapping}` diff --git a/Tests/Controller/AbstractChunkedUploadTest.php b/Tests/Controller/AbstractChunkedUploadTest.php index a5dfc2ea..dd434c6c 100644 --- a/Tests/Controller/AbstractChunkedUploadTest.php +++ b/Tests/Controller/AbstractChunkedUploadTest.php @@ -2,7 +2,10 @@ namespace Oneup\UploaderBundle\Tests\Controller; +use Symfony\Component\EventDispatcher\Event; use Oneup\UploaderBundle\Tests\Controller\AbstractUploadTest; +use Oneup\UploaderBundle\UploadEvents; +use Oneup\UploaderBundle\Event\PostChunkUploadEvent; abstract class AbstractChunkedUploadTest extends AbstractUploadTest { @@ -31,4 +34,38 @@ public function testChunkedUpload() $this->assertEquals(120, $file->getSize()); } } + + public function testEvents() + { + $endpoint = $this->helper->endpoint($this->getConfigKey()); + + // prepare listener data + $me = $this; + $chunkCount = 0; + $uploadCount = 0; + $chunkSize = $this->getNextFile(0)->getSize(); + + for($i = 0; $i < $this->total; $i ++) { + // each time create a new client otherwise the events won't get dispatched + $client = static::createClient(); + $dispatcher = $client->getContainer()->get('event_dispatcher'); + + $dispatcher->addListener(UploadEvents::POST_CHUNK_UPLOAD, function(PostChunkUploadEvent $event) use (&$chunkCount, $chunkSize, &$me) { + ++ $chunkCount; + + $chunk = $event->getChunk(); + + $me->assertEquals($chunkSize, $chunk->getSize()); + }); + + $dispatcher->addListener(UploadEvents::POST_UPLOAD, function(Event $event) use (&$uploadCount) { + ++ $uploadCount; + }); + + $client->request('POST', $endpoint, $this->getNextRequestParameters($i), array($this->getNextFile($i))); + } + + $this->assertEquals($this->total, $chunkCount); + $this->assertEquals(1, $uploadCount); + } } diff --git a/UploadEvents.php b/UploadEvents.php index b4e6aebf..73f5c937 100644 --- a/UploadEvents.php +++ b/UploadEvents.php @@ -4,7 +4,8 @@ final class UploadEvents { - const POST_PERSIST = 'oneup_uploader.post_persist'; - const POST_UPLOAD = 'oneup_uploader.post_upload'; - const VALIDATION = 'oneup_uploader.validation'; + const POST_PERSIST = 'oneup_uploader.post_persist'; + const POST_UPLOAD = 'oneup_uploader.post_upload'; + const POST_CHUNK_UPLOAD = 'oneup_uploader.post_chunk_upload'; + const VALIDATION = 'oneup_uploader.validation'; } \ No newline at end of file