From 7c6bd31a6ca1768c118031a3beff734acca7fbd7 Mon Sep 17 00:00:00 2001 From: Flo Date: Fri, 23 Feb 2024 14:06:49 +0100 Subject: [PATCH] first nice version --- bin/createApi.php | 57 +++++++++++++++++-- config/config.php | 2 + .../myTube/Version20240214194156.php | 2 +- .../myTube/Version20240223130626.php | 31 ++++++++++ docker/nginx/config/nginx.conf | 2 + docker/php/config/uploads.ini | 5 ++ docker/php/dockerfile | 3 + .../External/Video/config/routes.php | 23 +++++++- .../External/Video/config/service_manager.php | 11 +++- .../Video/src/Handler/ReadDetailsHandler.php | 43 ++++++++++++++ .../Video/src/Handler/StreamHandler.php | 30 ++++++---- .../Video/src/Handler/ThumbnailHandler.php | 47 +++++++++++++++ .../Video/src/Handler/UploadHandler.php | 41 +++++++++++++ .../ReadDetailsResponseFormatter.php | 20 +++++++ .../ThumbnailResponseFormatter.php | 15 +++++ .../External/VideoList/config/routes.php | 14 +++++ .../VideoList/config/service_manager.php | 15 +++++ .../External/VideoList/src/ConfigProvider.php | 16 ++++++ .../VideoList/src/Handler/ReadListHandler.php | 6 +- .../ReadListResponseFormatter.php | 25 ++++++++ src/DataDomain/Business/src/Entity/Video.php | 13 +++-- .../Video/config/service_manager.php | 25 ++++++++ .../Video/src/Builder/VideoBuilder.php | 20 +++++++ .../Video/src/Builder/VideoImageBuilder.php | 38 +++++++++++++ .../Exception/VideoNotFoundByIdException.php | 25 ++++++++ .../Handler/Command/Upload/UploadCommand.php | 20 +++++++ .../Command/Upload/UploadCommandBuilder.php | 18 ++++++ .../Command/Upload/UploadCommandHandler.php | 45 +++++++++++++++ .../Query/ReadDetails/ReadDetailsQuery.php | 20 +++++++ .../ReadDetails/ReadDetailsQueryBuilder.php | 18 ++++++ .../ReadDetails/ReadDetailsQueryHandler.php | 43 ++++++++++++++ .../ReadDetails/ReadDetailsQueryResult.php | 20 +++++++ .../src/Handler/Query/Stream/StreamQuery.php | 11 +++- .../Query/Stream/StreamQueryBuilder.php | 6 +- .../Query/Stream/StreamQueryHandler.php | 24 +++++++- .../Query/Thumbnail/ThumbnailQuery.php | 20 +++++++ .../Query/Thumbnail/ThumbnailQueryBuilder.php | 18 ++++++ .../Query/Thumbnail/ThumbnailQueryHandler.php | 38 +++++++++++++ .../Query/Thumbnail/ThumbnailQueryResult.php | 20 +++++++ .../Video/src/Uploader/VideoUploader.php | 40 +++++++++++++ .../VideoList/config/service_manager.php | 21 +++++++ .../VideoList/src/ConfigProvider.php | 15 +++++ .../Query/ReadList/ReadListQueryHandler.php | 14 ++++- .../Exception/src/ErrorDomain.php | 1 + 44 files changed, 903 insertions(+), 38 deletions(-) create mode 100644 data/migrations/myTube/Version20240223130626.php create mode 100644 docker/php/config/uploads.ini create mode 100644 src/ApiDomain/External/Video/src/Handler/ReadDetailsHandler.php create mode 100644 src/ApiDomain/External/Video/src/Handler/ThumbnailHandler.php create mode 100644 src/ApiDomain/External/Video/src/Handler/UploadHandler.php create mode 100644 src/ApiDomain/External/Video/src/ResponseFormatter/ReadDetailsResponseFormatter.php create mode 100644 src/ApiDomain/External/Video/src/ResponseFormatter/ThumbnailResponseFormatter.php create mode 100644 src/ApiDomain/External/VideoList/config/routes.php create mode 100644 src/ApiDomain/External/VideoList/config/service_manager.php create mode 100644 src/ApiDomain/External/VideoList/src/ConfigProvider.php create mode 100644 src/ApiDomain/External/VideoList/src/ResponseFormatter/ReadListResponseFormatter.php create mode 100644 src/HandlingDomain/Video/src/Builder/VideoBuilder.php create mode 100644 src/HandlingDomain/Video/src/Builder/VideoImageBuilder.php create mode 100644 src/HandlingDomain/Video/src/Exception/VideoNotFoundByIdException.php create mode 100644 src/HandlingDomain/Video/src/Handler/Command/Upload/UploadCommand.php create mode 100644 src/HandlingDomain/Video/src/Handler/Command/Upload/UploadCommandBuilder.php create mode 100644 src/HandlingDomain/Video/src/Handler/Command/Upload/UploadCommandHandler.php create mode 100644 src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQuery.php create mode 100644 src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQueryBuilder.php create mode 100644 src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQueryHandler.php create mode 100644 src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQueryResult.php create mode 100644 src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQuery.php create mode 100644 src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQueryBuilder.php create mode 100644 src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQueryHandler.php create mode 100644 src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQueryResult.php create mode 100644 src/HandlingDomain/Video/src/Uploader/VideoUploader.php create mode 100644 src/HandlingDomain/VideoList/config/service_manager.php create mode 100644 src/HandlingDomain/VideoList/src/ConfigProvider.php diff --git a/bin/createApi.php b/bin/createApi.php index 96622f6..cd8d703 100644 --- a/bin/createApi.php +++ b/bin/createApi.php @@ -20,6 +20,12 @@ $apiHandlerName = $apiName . 'Handler'; $apiHandlerNamespace = $projectNamespace . '\\API\\' . $apiType . '\\' . $apiNamespace . '\\Handler'; $apiHandlerFilePath = $projectSourceDirectory . 'ApiDomain/' . $apiType . '/' . $apiNamespace . '/src/Handler/' . $apiHandlerName . '.php'; +# Response Formatter +$apiResponseFormatterName = $apiName . 'ResponseFormatter'; +$apiResponseFormatterNamespace = $projectNamespace . '\\API\\' . $apiType . '\\' . $apiNamespace . '\\ResponseFormatter'; +$apiResponseFormatterUsingNamespace = $apiResponseFormatterNamespace . '\\' . $apiResponseFormatterName; +$apiResponseFormatterFilePath = $projectSourceDirectory . 'ApiDomain/' . $apiType . '/' . $apiNamespace . '/src/ResponseFormatter/' . $apiResponseFormatterName . '.php'; + # CQRS $cqrsFilePath = $projectSourceDirectory . 'HandlingDomain/' . $cqrsNamespace . '/src/Handler/' . $cqrsType . '/' . $apiName . '/'; $cqrsName = $apiName . $cqrsType; @@ -30,6 +36,12 @@ $cqrsNamespace = $projectNamespace . '\\Handling\\' . $cqrsNamespace . '\\Handle $cqrsPath = $cqrsFilePath . $cqrsName . '.php'; $cqrsUsingNamespace = $cqrsNamespace . '\\' . $cqrsName; +# Result +$cqrsResultName = $cqrsName . 'Result'; +$cqrsResultVariableName = lcfirst($cqrsResultName); +$cqrsResultPath = $cqrsFilePath . $cqrsResultName . '.php'; +$cqrsResultUsingNamespace = $cqrsNamespace . '\\' . $cqrsResultName; + # Handler $cqrsHandlerName = $cqrsName . 'Handler'; $cqrsHandlerVariableName = lcfirst($cqrsHandlerName); @@ -66,16 +78,18 @@ namespace {$apiHandlerNamespace}; use {$cqrsHandlerUsingNamespace}; use {$cqrsBuilderUsingNamespace}; +use {$apiResponseFormatterUsingNamespace}; use Psr\\Http\\Message\\ResponseInterface; use Psr\\Http\\Message\\ServerRequestInterface; use Psr\\Http\\Server\\RequestHandlerInterface; -use Bee\\Infrastructure\\Response\\SuccessResponse; +use {$projectNamespace}\\Infrastructure\\Response\\SuccessResponse; class {$apiHandlerName} implements RequestHandlerInterface { public function __construct( private readonly {$cqrsHandlerName} \${$cqrsHandlerVariableName}, private readonly {$cqrsBuilderName} \${$cqrsBuilderVariableName}, + private readonly {$apiResponseFormatterName} \$responseFormatter, ) { } @@ -91,12 +105,30 @@ class {$apiHandlerName} implements RequestHandlerInterface ); \$result = \$this->{$cqrsHandlerVariableName}->execute(\${$cqrsVariableName}); - return new SuccessResponse('OK'); + return new SuccessResponse(\$this->responseFormatter->format(\$result)); } } "; writeToFile($apiHandlerFilePath, $apiHandlerFileContent); +$apiResponseFormatterFileContent = " 'video.stream', - 'path' => '/api/video/stream[/]', + 'path' => '/api/video/stream/:videoUuid[/]', 'allowed_methods' => ['GET'], 'middleware' => [ StreamHandler::class ], ], + [ + 'name' => 'video.thumbnail', + 'path' => '/api/video/thumbnail/:videoUuid[/]', + 'allowed_methods' => ['GET'], + 'middleware' => [ + ThumbnailHandler::class + ], + ], [ 'name' => 'video.upload', 'path' => '/api/video/upload[/]', 'allowed_methods' => ['POST'], 'middleware' => [ - StreamHandler::class + UploadHandler::class + ], + ], + [ + 'name' => 'video.read-details', + 'path' => '/api/video/read-details[/]', + 'allowed_methods' => ['POST'], + 'middleware' => [ + ReadDetailsHandler::class ], ], ]; diff --git a/src/ApiDomain/External/Video/config/service_manager.php b/src/ApiDomain/External/Video/config/service_manager.php index e0182e0..b560f48 100644 --- a/src/ApiDomain/External/Video/config/service_manager.php +++ b/src/ApiDomain/External/Video/config/service_manager.php @@ -1,10 +1,19 @@ [ - StreamHandler::class => AutoWiringFactory::class + ThumbnailHandler::class => AutoWiringFactory::class, + StreamHandler::class => AutoWiringFactory::class, + UploadHandler::class => AutoWiringFactory::class, + ReadDetailsHandler::class => AutoWiringFactory::class, + + ReadDetailsResponseFormatter::class => AutoWiringFactory::class, ], ]; diff --git a/src/ApiDomain/External/Video/src/Handler/ReadDetailsHandler.php b/src/ApiDomain/External/Video/src/Handler/ReadDetailsHandler.php new file mode 100644 index 0000000..5e70b95 --- /dev/null +++ b/src/ApiDomain/External/Video/src/Handler/ReadDetailsHandler.php @@ -0,0 +1,43 @@ +getBody()->getContents(), + true + ); + + $readDetailsQuery = $this->readDetailsQueryBuilder->build( + Uuid::fromString($data['videoId']) + ); + $result = $this->readDetailsQueryHandler->execute($readDetailsQuery); + + return new SuccessResponse($this->responseFormatter->format($result)); + } +} diff --git a/src/ApiDomain/External/Video/src/Handler/StreamHandler.php b/src/ApiDomain/External/Video/src/Handler/StreamHandler.php index bfaaee0..0d6c473 100644 --- a/src/ApiDomain/External/Video/src/Handler/StreamHandler.php +++ b/src/ApiDomain/External/Video/src/Handler/StreamHandler.php @@ -12,6 +12,7 @@ use MyTube\Handling\Video\Handler\Query\Stream\StreamQueryHandler; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; +use Ramsey\Uuid\Uuid; class StreamHandler implements RequestHandlerInterface { @@ -23,19 +24,24 @@ class StreamHandler implements RequestHandlerInterface public function handle(ServerRequestInterface $request): ResponseInterface { - $videoPath = APP_ROOT . '/var/filestore/video.mp4'; + $videoUuid = $request->getAttribute('videoUuid') ?? null; - if (file_exists($videoPath)) { - $stream = new VideoStream(); - return $stream->streamVideo( - $videoPath, - [ - 'is_localPath' => true, - 'content_type' => 'video/mp4' - ] - ); - } else { - return new JsonResponse("Video not found", Response::STATUS_CODE_404); + if ($videoUuid === null) { + return new JsonResponse('No videoId provided'); } + + $streamQuery = $this->streamQueryBuilder->build( + Uuid::fromString($videoUuid) + ); + $video = $this->streamQueryHandler->execute($streamQuery); + + $stream = new VideoStream(); + return $stream->streamVideo( + $video->getDirectoryPath() . 'video.mp4', + [ + 'is_localPath' => true, + 'content_type' => 'video/mp4' + ] + ); } } diff --git a/src/ApiDomain/External/Video/src/Handler/ThumbnailHandler.php b/src/ApiDomain/External/Video/src/Handler/ThumbnailHandler.php new file mode 100644 index 0000000..f44bbcc --- /dev/null +++ b/src/ApiDomain/External/Video/src/Handler/ThumbnailHandler.php @@ -0,0 +1,47 @@ +getAttribute('videoUuid') ?? null; + + if ($videoUuid === null) { + return new JsonResponse('No videoId provided'); + } + + $thumbnailQuery = $this->thumbnailQueryBuilder->build( + Uuid::fromString($videoUuid) + ); + $result = $this->thumbnailQueryHandler->execute($thumbnailQuery); + + $filePath = $result->getVideo()->getDirectoryPath() . 'thumbnail.png'; + + if (!file_exists($filePath)) { + return new JsonResponse('Not Found', 404); + } + + $fileContent = file_get_contents($filePath); + $response = new TextResponse($fileContent); + return $response->withHeader('Content-Type', 'image/png'); + } +} diff --git a/src/ApiDomain/External/Video/src/Handler/UploadHandler.php b/src/ApiDomain/External/Video/src/Handler/UploadHandler.php new file mode 100644 index 0000000..e613840 --- /dev/null +++ b/src/ApiDomain/External/Video/src/Handler/UploadHandler.php @@ -0,0 +1,41 @@ +getUploadedFiles(); + + if (count($uploadedFiles) !== 1) { + return new JsonResponse('Uploaded more than one file', Response::STATUS_CODE_400); + } + + $uploadCommand = $this->uploadCommandBuilder->build( + $request->getUploadedFiles()['file'] + ); + $result = $this->uploadCommandHandler->execute($uploadCommand); + + return new SuccessResponse([ + 'id' => $result->getId()->toString() + ]); + } +} diff --git a/src/ApiDomain/External/Video/src/ResponseFormatter/ReadDetailsResponseFormatter.php b/src/ApiDomain/External/Video/src/ResponseFormatter/ReadDetailsResponseFormatter.php new file mode 100644 index 0000000..c3e11af --- /dev/null +++ b/src/ApiDomain/External/Video/src/ResponseFormatter/ReadDetailsResponseFormatter.php @@ -0,0 +1,20 @@ +getVideo(); + + return [ + 'id' => $video->getId(), + 'title' => $video->getTitle() + ]; + } +} diff --git a/src/ApiDomain/External/Video/src/ResponseFormatter/ThumbnailResponseFormatter.php b/src/ApiDomain/External/Video/src/ResponseFormatter/ThumbnailResponseFormatter.php new file mode 100644 index 0000000..b05504c --- /dev/null +++ b/src/ApiDomain/External/Video/src/ResponseFormatter/ThumbnailResponseFormatter.php @@ -0,0 +1,15 @@ + 'video-list.read-list', + 'path' => '/api/video-list/read-list[/]', + 'allowed_methods' => ['POST'], + 'middleware' => [ + ReadListHandler::class + ], + ], +]; diff --git a/src/ApiDomain/External/VideoList/config/service_manager.php b/src/ApiDomain/External/VideoList/config/service_manager.php new file mode 100644 index 0000000..c1b5eff --- /dev/null +++ b/src/ApiDomain/External/VideoList/config/service_manager.php @@ -0,0 +1,15 @@ + [ + ReadListHandler::class => AutoWiringFactory::class, + + ReadListResponseFormatter::class => AutoWiringFactory::class, + ], +]; diff --git a/src/ApiDomain/External/VideoList/src/ConfigProvider.php b/src/ApiDomain/External/VideoList/src/ConfigProvider.php new file mode 100644 index 0000000..15b7656 --- /dev/null +++ b/src/ApiDomain/External/VideoList/src/ConfigProvider.php @@ -0,0 +1,16 @@ + require __DIR__ . './../config/service_manager.php', + 'routes' => require __DIR__ . '/./../config/routes.php', + ]; + } +} diff --git a/src/ApiDomain/External/VideoList/src/Handler/ReadListHandler.php b/src/ApiDomain/External/VideoList/src/Handler/ReadListHandler.php index 0fab5c1..16eef1a 100644 --- a/src/ApiDomain/External/VideoList/src/Handler/ReadListHandler.php +++ b/src/ApiDomain/External/VideoList/src/Handler/ReadListHandler.php @@ -4,18 +4,20 @@ declare(strict_types=1); namespace MyTube\API\External\VideoList\Handler; +use MyTube\API\External\VideoList\ResponseFormatter\ReadListResponseFormatter; use MyTube\Handling\VideoList\Handler\Query\ReadList\ReadListQueryHandler; use MyTube\Handling\VideoList\Handler\Query\ReadList\ReadListQueryBuilder; +use MyTube\Infrastructure\Response\SuccessResponse; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; -use Bee\Infrastructure\Response\SuccessResponse; class ReadListHandler implements RequestHandlerInterface { public function __construct( private readonly ReadListQueryHandler $readListQueryHandler, private readonly ReadListQueryBuilder $readListQueryBuilder, + private readonly ReadListResponseFormatter $readListResponseFormatter, ) { } @@ -31,6 +33,6 @@ class ReadListHandler implements RequestHandlerInterface ); $result = $this->readListQueryHandler->execute($readListQuery); - return new SuccessResponse('OK'); + return new SuccessResponse($this->readListResponseFormatter->format($result)); } } diff --git a/src/ApiDomain/External/VideoList/src/ResponseFormatter/ReadListResponseFormatter.php b/src/ApiDomain/External/VideoList/src/ResponseFormatter/ReadListResponseFormatter.php new file mode 100644 index 0000000..6d1a415 --- /dev/null +++ b/src/ApiDomain/External/VideoList/src/ResponseFormatter/ReadListResponseFormatter.php @@ -0,0 +1,25 @@ + $video->getTitle(), + 'id' => $video->getId()->toString(), + ]; + } + + return $result; + } +} diff --git a/src/DataDomain/Business/src/Entity/Video.php b/src/DataDomain/Business/src/Entity/Video.php index 301d1fc..dd6cd04 100644 --- a/src/DataDomain/Business/src/Entity/Video.php +++ b/src/DataDomain/Business/src/Entity/Video.php @@ -21,8 +21,8 @@ class Video { /** @ORM\Column(name="title", type="string") */ private string $title; - /** @ORM\Column(name="file_path", type="string") */ - private string $filePath; + /** @ORM\Column(name="directory_path", type="string") */ + private ?string $directoryPath; /** @ORM\Column(name="created_at", type="datetime") */ private DateTime $createdAt; @@ -36,6 +36,7 @@ class Video { $now = new DateTime(); $this->setCreatedAt($now); + $this->setUpdatedAt($now); } @@ -51,12 +52,12 @@ class Video { $this->title = $title; } - public function getFilePath(): ?string { - return $this->filePath; + public function getDirectoryPath(): ?string { + return $this->directoryPath; } - public function setFilePath(?string $filePath): void { - $this->filePath = $filePath; + public function setDirectoryPath(?string $directoryPath): void { + $this->directoryPath = $directoryPath; } public function getCreatedAt(): DateTime { diff --git a/src/HandlingDomain/Video/config/service_manager.php b/src/HandlingDomain/Video/config/service_manager.php index 7440492..f94b3f9 100644 --- a/src/HandlingDomain/Video/config/service_manager.php +++ b/src/HandlingDomain/Video/config/service_manager.php @@ -1,16 +1,41 @@ [ + /// Uploader + VideoUploader::class => AutoWiringFactory::class, + + /// Builder + VideoBuilder::class => AutoWiringFactory::class, + VideoImageBuilder::class => AutoWiringFactory::class, + /// CQRS // Stream Query StreamQueryHandler::class => InjectionFactory::class, StreamQueryBuilder::class => AutoWiringFactory::class, + // Thumbnail Query + ThumbnailQueryHandler::class => InjectionFactory::class, + ThumbnailQueryBuilder::class => AutoWiringFactory::class, + // Upload Command + UploadCommandHandler::class => AutoWiringFactory::class, + UploadCommandBuilder::class => AutoWiringFactory::class, + // Read Details + ReadDetailsQueryHandler::class => InjectionFactory::class, + ReadDetailsQueryBuilder::class => AutoWiringFactory::class, ], ]; diff --git a/src/HandlingDomain/Video/src/Builder/VideoBuilder.php b/src/HandlingDomain/Video/src/Builder/VideoBuilder.php new file mode 100644 index 0000000..24f9258 --- /dev/null +++ b/src/HandlingDomain/Video/src/Builder/VideoBuilder.php @@ -0,0 +1,20 @@ +setTitle($title); + $video->setDirectoryPath($directoryPath); + + return $video; + } +} diff --git a/src/HandlingDomain/Video/src/Builder/VideoImageBuilder.php b/src/HandlingDomain/Video/src/Builder/VideoImageBuilder.php new file mode 100644 index 0000000..f3d06b8 --- /dev/null +++ b/src/HandlingDomain/Video/src/Builder/VideoImageBuilder.php @@ -0,0 +1,38 @@ +getId()->toString(); + + $targetPath = sprintf( + '%s/%s/%s/%s', + APP_ROOT, + 'var/filestore', + $videoId, + self::FILE_NAME + ); + + if (file_exists($targetPath)) { + return null; + } + + $command = "cd /var/www/html/var/filestore/" . $videoId . "/" . + " && " . + "ffmpeg -i video.mp4 -ss " . $timestamp . " -vframes 1 " . self::FILE_NAME; + + $output = shell_exec($command); + + return $targetPath; + } +} diff --git a/src/HandlingDomain/Video/src/Exception/VideoNotFoundByIdException.php b/src/HandlingDomain/Video/src/Exception/VideoNotFoundByIdException.php new file mode 100644 index 0000000..0585f04 --- /dev/null +++ b/src/HandlingDomain/Video/src/Exception/VideoNotFoundByIdException.php @@ -0,0 +1,25 @@ +toString() + ), + ErrorDomain::Video, + ErrorCode::NotFound + ); + } +} diff --git a/src/HandlingDomain/Video/src/Handler/Command/Upload/UploadCommand.php b/src/HandlingDomain/Video/src/Handler/Command/Upload/UploadCommand.php new file mode 100644 index 0000000..f7b99d6 --- /dev/null +++ b/src/HandlingDomain/Video/src/Handler/Command/Upload/UploadCommand.php @@ -0,0 +1,20 @@ +uploadedFile; + } +} diff --git a/src/HandlingDomain/Video/src/Handler/Command/Upload/UploadCommandBuilder.php b/src/HandlingDomain/Video/src/Handler/Command/Upload/UploadCommandBuilder.php new file mode 100644 index 0000000..5615cf5 --- /dev/null +++ b/src/HandlingDomain/Video/src/Handler/Command/Upload/UploadCommandBuilder.php @@ -0,0 +1,18 @@ +getUploadedFile(); + + $video = $this->videoBuilder->build( + $uploadedFile->getClientFilename() + ); + + $this->uploader->upload( + $uploadedFile, + $video + ); + + $this->entityManager->persist($video); + $this->entityManager->flush(); + + return $video; + } +} diff --git a/src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQuery.php b/src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQuery.php new file mode 100644 index 0000000..b54d559 --- /dev/null +++ b/src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQuery.php @@ -0,0 +1,20 @@ +videoId; + } +} diff --git a/src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQueryBuilder.php b/src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQueryBuilder.php new file mode 100644 index 0000000..96b9f49 --- /dev/null +++ b/src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQueryBuilder.php @@ -0,0 +1,18 @@ +getVideoId(); + + /** @var Video $video */ + $video = $this->videoRepository->findOneBy(['id' => $videoId]); + + if ($video === null) { + throw new VideoNotFoundByIdException($videoId); + } + + return new ReadDetailsQueryResult($video); + } +} diff --git a/src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQueryResult.php b/src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQueryResult.php new file mode 100644 index 0000000..e060b3c --- /dev/null +++ b/src/HandlingDomain/Video/src/Handler/Query/ReadDetails/ReadDetailsQueryResult.php @@ -0,0 +1,20 @@ +video; + } +} diff --git a/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQuery.php b/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQuery.php index a0b9167..b9682f5 100644 --- a/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQuery.php +++ b/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQuery.php @@ -4,12 +4,17 @@ declare(strict_types=1); namespace MyTube\Handling\Video\Handler\Query\Stream; +use Ramsey\Uuid\UuidInterface; + class StreamQuery { public function __construct( - #TODO + private readonly UuidInterface $videoUuid, ) { } - - #TODO + + public function getVideoUuid(): UuidInterface + { + return $this->videoUuid; + } } diff --git a/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQueryBuilder.php b/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQueryBuilder.php index ad4d3cd..460cd51 100644 --- a/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQueryBuilder.php +++ b/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQueryBuilder.php @@ -4,13 +4,15 @@ declare(strict_types=1); namespace MyTube\Handling\Video\Handler\Query\Stream; +use Ramsey\Uuid\UuidInterface; + class StreamQueryBuilder { public function build( - #TODO + UuidInterface $videoUuid, ): StreamQuery { return new StreamQuery( - #TODO + $videoUuid, ); } } diff --git a/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQueryHandler.php b/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQueryHandler.php index 18417d7..e5e8393 100644 --- a/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQueryHandler.php +++ b/src/HandlingDomain/Video/src/Handler/Query/Stream/StreamQueryHandler.php @@ -4,14 +4,34 @@ declare(strict_types=1); namespace MyTube\Handling\Video\Handler\Query\Stream; +use Exception; +use MyTube\Data\Business\Entity\Video; +use MyTube\Data\Business\Repository\VideoRepository; +use Reinfi\DependencyInjection\Annotation\InjectDoctrineRepository; + class StreamQueryHandler { + /** + * @InjectDoctrineRepository( + * entityManager="MyTube\Data\Business\Manager\MyTubeEntityManager", + * entity="MyTube\Data\Business\Entity\Video" + * ) + */ public function __construct( - #TODO + private readonly VideoRepository $videoRepository, ) { } - public function execute(StreamQuery $streamQuery): void + public function execute(StreamQuery $streamQuery): Video { + $video = $this->videoRepository->findOneBy([ + 'id' => $streamQuery->getVideoUuid() + ]); + + if ($video === null) { + throw new Exception('Video not found'); + } + + return $video; } } diff --git a/src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQuery.php b/src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQuery.php new file mode 100644 index 0000000..0806e40 --- /dev/null +++ b/src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQuery.php @@ -0,0 +1,20 @@ +videoUuid; + } +} diff --git a/src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQueryBuilder.php b/src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQueryBuilder.php new file mode 100644 index 0000000..30d1174 --- /dev/null +++ b/src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQueryBuilder.php @@ -0,0 +1,18 @@ +videoRepository->findOneBy([ + 'id' => $streamQuery->getVideoUuid() + ]); + + if ($video === null) { + throw new Exception('Video not found'); + } + + return new ThumbnailQueryResult($video); + } +} diff --git a/src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQueryResult.php b/src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQueryResult.php new file mode 100644 index 0000000..e0e45f7 --- /dev/null +++ b/src/HandlingDomain/Video/src/Handler/Query/Thumbnail/ThumbnailQueryResult.php @@ -0,0 +1,20 @@ +video; + } +} diff --git a/src/HandlingDomain/Video/src/Uploader/VideoUploader.php b/src/HandlingDomain/Video/src/Uploader/VideoUploader.php new file mode 100644 index 0000000..a7b55c6 --- /dev/null +++ b/src/HandlingDomain/Video/src/Uploader/VideoUploader.php @@ -0,0 +1,40 @@ +getId()->toString(), + ); + + if (file_exists($targetPath)) { + throw new Exception('File already exists'); + } + + mkdir($targetPath, 0777, true); + $video->setDirectoryPath($targetPath); + + $targetPath = $targetPath . 'video.' . substr(strrchr($file->getClientFilename(),'.'),1); + $file->moveTo($targetPath); + + $this->imageBuilder->build($video); + } +} diff --git a/src/HandlingDomain/VideoList/config/service_manager.php b/src/HandlingDomain/VideoList/config/service_manager.php new file mode 100644 index 0000000..414fba4 --- /dev/null +++ b/src/HandlingDomain/VideoList/config/service_manager.php @@ -0,0 +1,21 @@ + [ + /// CQRS + // Read List + ReadListQueryHandler::class => InjectionFactory::class, + ReadListQueryBuilder::class => AutoWiringFactory::class, + ], +]; diff --git a/src/HandlingDomain/VideoList/src/ConfigProvider.php b/src/HandlingDomain/VideoList/src/ConfigProvider.php new file mode 100644 index 0000000..5f92887 --- /dev/null +++ b/src/HandlingDomain/VideoList/src/ConfigProvider.php @@ -0,0 +1,15 @@ + require __DIR__ . '/./../config/service_manager.php', + ]; + } +} diff --git a/src/HandlingDomain/VideoList/src/Handler/Query/ReadList/ReadListQueryHandler.php b/src/HandlingDomain/VideoList/src/Handler/Query/ReadList/ReadListQueryHandler.php index e66c8c0..c3be531 100644 --- a/src/HandlingDomain/VideoList/src/Handler/Query/ReadList/ReadListQueryHandler.php +++ b/src/HandlingDomain/VideoList/src/Handler/Query/ReadList/ReadListQueryHandler.php @@ -4,14 +4,24 @@ declare(strict_types=1); namespace MyTube\Handling\VideoList\Handler\Query\ReadList; +use MyTube\Data\Business\Repository\VideoRepository; +use Reinfi\DependencyInjection\Annotation\InjectDoctrineRepository; + class ReadListQueryHandler { + /** + * @InjectDoctrineRepository( + * entityManager="MyTube\Data\Business\Manager\MyTubeEntityManager", + * entity="MyTube\Data\Business\Entity\Video" + * ) + */ public function __construct( - #TODO + private readonly VideoRepository $videoRepository ) { } - public function execute(ReadListQuery $readListQuery): void + public function execute(ReadListQuery $readListQuery): array { + return $this->videoRepository->findAll(); } } diff --git a/src/Infrastructure/Exception/src/ErrorDomain.php b/src/Infrastructure/Exception/src/ErrorDomain.php index e6a3b7b..ac45722 100644 --- a/src/Infrastructure/Exception/src/ErrorDomain.php +++ b/src/Infrastructure/Exception/src/ErrorDomain.php @@ -10,4 +10,5 @@ enum ErrorDomain : string { case UserPassword = 'UserPassword'; case Registration = 'Registration'; case Product = 'Product'; + case Video = 'Video'; } \ No newline at end of file