44
55namespace Enjoys \Upload ;
66
7+ use Enjoys \Upload \Event \AfterUploadEvent ;
8+ use Enjoys \Upload \Event \BeforeUploadEvent ;
9+ use Enjoys \Upload \Event \BeforeValidationEvent ;
10+ use Enjoys \Upload \Event \UploadErrorEvent ;
11+ use Enjoys \Upload \Exception \RuleException ;
712use League \Flysystem \Filesystem ;
813use League \Flysystem \FilesystemException ;
14+ use Psr \EventDispatcher \EventDispatcherInterface ;
915use Psr \Http \Message \UploadedFileInterface ;
16+ use Throwable ;
1017
1118final class UploadProcessing
1219{
1320 /**
14- * @var string|null Final storage path (null until file is uploaded)
21+ * @var string|null Final storage path (null until a file is uploaded)
1522 */
1623 private ?string $ targetPath = null ;
1724
@@ -29,10 +36,12 @@ final class UploadProcessing
2936 * @param UploadedFileInterface $uploadedFile The PSR-7 uploaded file to process
3037 * @param Filesystem $filesystem Flysystem instance that provides filesystem abstraction
3138 * (supports local, FTP, S3, and other storage systems)
39+ * @param EventDispatcherInterface|null $dispatcher Optional event dispatcher for handling upload-related events
3240 */
3341 public function __construct (
3442 private readonly UploadedFileInterface $ uploadedFile ,
3543 private readonly Filesystem $ filesystem ,
44+ private readonly ?EventDispatcherInterface $ dispatcher = null
3645 ) {
3746 $ this ->fileInfo = new FileInfo ($ uploadedFile );
3847 }
@@ -42,16 +51,24 @@ public function __construct(
4251 *
4352 * @param string $targetPath The target directory path (defaults to '/')
4453 * @throws FilesystemException If there's an error during file system operations
54+ * @throws RuleException Thrown when validation fails
55+ * @throws Throwable
4556 */
4657 public function upload (string $ targetPath = '/ ' ): void
4758 {
59+ $ this ->dispatcher ?->dispatch(new BeforeValidationEvent ($ this ));
4860 $ this ->validate ();
4961
62+ $ this ->dispatcher ?->dispatch(new BeforeUploadEvent ($ this ));
5063 $ this ->targetPath = rtrim ($ targetPath , '/ ' ) . '/ ' . $ this ->fileInfo ->getFilename ();
5164
5265 $ resource = $ this ->uploadedFile ->getStream ()->detach ();
5366 try {
5467 $ this ->filesystem ->writeStream ($ this ->targetPath , $ resource );
68+ $ this ->dispatcher ?->dispatch(new AfterUploadEvent ($ this ));
69+ } catch (Throwable $ e ) {
70+ $ this ->dispatcher ?->dispatch(new UploadErrorEvent ($ this , $ e ));
71+ throw $ e ;
5572 } finally {
5673 if (is_resource ($ resource )) {
5774 fclose ($ resource );
@@ -61,6 +78,8 @@ public function upload(string $targetPath = '/'): void
6178
6279 /**
6380 * Validates the uploaded file against all registered rules
81+ *
82+ * @throws RuleException Thrown when validation fails
6483 */
6584 private function validate (): void
6685 {
@@ -149,6 +168,4 @@ public function getRules(): array
149168 {
150169 return $ this ->rules ;
151170 }
152-
153-
154171}
0 commit comments