tagList first version

This commit is contained in:
Flo 2024-02-24 21:03:10 +01:00
parent 24192495cf
commit c8a2513b87
17 changed files with 343 additions and 12 deletions

View File

@ -103,7 +103,7 @@ declare(strict_types=1);
use {$apiHandlerUsingNamespace};
use {$apiResponseFormatterUsingNamespace};
use Reinfi\DependencyInjection\Factory\AutoWiringFactory;
use Reinfi\\DependencyInjection\\Factory\\AutoWiringFactory;
return [
'factories' => [
@ -122,7 +122,7 @@ return [
declare(strict_types=1);
namespace MyTube\API\{$apiType}\{$apiNamespace};
namespace MyTube\\API\\{$apiType}\\{$apiNamespace};
class ConfigProvider
{
@ -146,8 +146,8 @@ declare(strict_types=1);
use {$cqrsHandlerUsingNamespace};
use {$cqrsBuilderUsingNamespace};
use Reinfi\DependencyInjection\Factory\AutoWiringFactory;
use Reinfi\DependencyInjection\Factory\InjectionFactory;
use Reinfi\\DependencyInjection\\Factory\\AutoWiringFactory;
use Reinfi\\DependencyInjection\\Factory\\InjectionFactory;
return [
'factories' => [
@ -165,7 +165,7 @@ return [
declare(strict_types=1);
namespace MyTube\Handling\{$originalCqrsNamespace};
namespace MyTube\\Handling\\{$originalCqrsNamespace};
class ConfigProvider
{
@ -191,10 +191,11 @@ namespace {$apiHandlerNamespace};
use {$cqrsHandlerUsingNamespace};
use {$cqrsBuilderUsingNamespace};
use {$apiResponseFormatterUsingNamespace};
use {$projectNamespace}\\Infrastructure\\Request\\Middleware\\AnalyzeBodyMiddleware;
use {$projectNamespace}\\Infrastructure\\Response\\SuccessResponse;
use Psr\\Http\\Message\\ResponseInterface;
use Psr\\Http\\Message\\ServerRequestInterface;
use Psr\\Http\\Server\\RequestHandlerInterface;
use {$projectNamespace}\\Infrastructure\\Response\\SuccessResponse;
class {$apiHandlerName} implements RequestHandlerInterface
{
@ -207,10 +208,7 @@ class {$apiHandlerName} implements RequestHandlerInterface
public function handle(ServerRequestInterface \$request): ResponseInterface
{
\$data = json_decode(
\$request->getBody()->getContents(),
true
);
\$data = \$request->getAttribute(AnalyzeBodyMiddleware::JSON_DATA);
\${$cqrsVariableName} = \$this->{$cqrsBuilderVariableName}->build(
\$data

View File

@ -16,7 +16,8 @@ $stepNames = array_slice($argv, 3);
# Pipeline
$pipelineClassName = $pipelineName . 'Pipeline';
$pipelineVariableName = lcfirst($pipelineClassName);
$pipelineFilePath = $projectSourceDirectory . 'HandlingDomain/' . $pipelineNamespace . '/src/Pipeline/' . $pipelineName . '/' . $pipelineClassName . '.php';
$pipelineDirectoryPath = $projectSourceDirectory . 'HandlingDomain/' . $pipelineNamespace . '/';
$pipelineFilePath = $pipelineDirectoryPath . 'src/Pipeline/' . $pipelineName . '/' . $pipelineClassName . '.php';
$pipelineFullNamespace = $projectNamespace . '\\Handling\\' . $pipelineNamespace . '\\Pipeline\\' . $pipelineName;
$pipelineUsingNamespace = $pipelineFullNamespace . '\\' . $pipelineClassName;
@ -57,8 +58,11 @@ function writeToFile($path, $content) {
file_put_contents($path, $content);
}
$createNamespaceFiles = !file_exists($pipelineDirectoryPath);
$stepsUsingNamespaces = [];
$stepsDeclarations = [];
$stepsAutoWirings = [];
$stepsReferences = [];
foreach ($steps as $step) {
@ -69,6 +73,7 @@ foreach ($steps as $step) {
$stepsUsingNamespaces[] = $stepUsingNamespace . ';';
$stepsDeclarations[] = 'private readonly ' . $stepClassName . ' $' . $stepVariableName . ',';
$stepsAutoWirings[] = $stepClassName . '::class => AutoWiringFactory::class,';
$stepsReferences[] = '$this->' . $stepVariableName . ',';
$stepFileContent = "<?php
@ -106,6 +111,7 @@ class {$stepClassName} implements TaskInterface
$stepsUsingNamespace = implode(PHP_EOL, $stepsUsingNamespaces);
$stepsDeclaration = implode(PHP_EOL . ' ', $stepsDeclarations);
$stepsAutoWiring = implode(PHP_EOL . ' ', $stepsAutoWirings);
$stepsReference = implode(PHP_EOL . ' ', $stepsReferences);
@ -147,3 +153,48 @@ class {$payloadClassName}
}
";
writeToFile($payloadFilePath, $payloadFileContent);
if ($createNamespaceFiles) {
$serviceManagerFileContent = "<?php
declare(strict_types=1);
use {$pipelineUsingNamespace};
{$stepsUsingNamespace}
use Reinfi\\DependencyInjection\\Factory\\AutoWiringFactory;
use Reinfi\\DependencyInjection\\Factory\\InjectionFactory;
return [
'factories' => [
/// Pipeline
// {$pipelineName}
{$pipelineName}::class => AutoWiringFactory::class,
{$stepsAutoWirings}
],
];
";
$serviceManagerFilePath = $createNamespaceFiles . 'config/service_manager.php';
writeToFile($serviceManagerFilePath, $serviceManagerFileContent);
$configProviderFileContent = "<?php
declare(strict_types=1);
namespace MyTube\\Handling\\{$pipelineNamespace};
class ConfigProvider
{
public function __invoke(): array
{
return [
'dependencies' => require __DIR__ . './../config/service_manager.php',
];
}
}
";
$configProviderFilePath = $createNamespaceFiles . 'src/ConfigProvider.php';
writeToFile($configProviderFilePath, $configProviderFileContent);
}

View File

@ -28,6 +28,7 @@
"MyTube\\API\\External\\Authentication\\": "src\/ApiDomain\/External\/Authentication\/src",
"MyTube\\API\\External\\Health\\": "src\/ApiDomain\/External\/Health\/src",
"MyTube\\API\\External\\Tag\\": "src\/ApiDomain\/External\/Tag\/src",
"MyTube\\API\\External\\TagList\\": "src\/ApiDomain\/External\/TagList\/src",
"MyTube\\API\\External\\User\\": "src\/ApiDomain\/External\/User\/src",
"MyTube\\API\\External\\Video\\": "src\/ApiDomain\/External\/Video\/src",
"MyTube\\API\\External\\VideoList\\": "src\/ApiDomain\/External\/VideoList\/src",
@ -36,6 +37,7 @@
"MyTube\\Handling\\Registration\\": "src\/HandlingDomain\/Registration\/src",
"MyTube\\Handling\\Role\\": "src\/HandlingDomain\/Role\/src",
"MyTube\\Handling\\Tag\\": "src\/HandlingDomain\/Tag\/src",
"MyTube\\Handling\\TagList\\": "src\/HandlingDomain\/TagList\/src",
"MyTube\\Handling\\User\\": "src\/HandlingDomain\/User\/src",
"MyTube\\Handling\\UserSession\\": "src\/HandlingDomain\/UserSession\/src",
"MyTube\\Handling\\Video\\": "src\/HandlingDomain\/Video\/src",
@ -98,6 +100,7 @@
"MyTube\\API\\External\\Authentication\\": "src\/ApiDomain\/External\/Authentication\/src",
"MyTube\\API\\External\\Health\\": "src\/ApiDomain\/External\/Health\/src",
"MyTube\\API\\External\\Tag\\": "src\/ApiDomain\/External\/Tag\/src",
"MyTube\\API\\External\\TagList\\": "src\/ApiDomain\/External\/TagList\/src",
"MyTube\\API\\External\\User\\": "src\/ApiDomain\/External\/User\/src",
"MyTube\\API\\External\\Video\\": "src\/ApiDomain\/External\/Video\/src",
"MyTube\\API\\External\\VideoList\\": "src\/ApiDomain\/External\/VideoList\/src",
@ -106,6 +109,7 @@
"MyTube\\Handling\\Registration\\": "src\/HandlingDomain\/Registration\/src",
"MyTube\\Handling\\Role\\": "src\/HandlingDomain\/Role\/src",
"MyTube\\Handling\\Tag\\": "src\/HandlingDomain\/Tag\/src",
"MyTube\\Handling\\TagList\\": "src\/HandlingDomain\/TagList\/src",
"MyTube\\Handling\\User\\": "src\/HandlingDomain\/User\/src",
"MyTube\\Handling\\UserSession\\": "src\/HandlingDomain\/UserSession\/src",
"MyTube\\Handling\\Video\\": "src\/HandlingDomain\/Video\/src",

View File

@ -60,6 +60,7 @@ $aggregator = new ConfigAggregator([
\MyTube\Handling\Video\ConfigProvider::class,
\MyTube\Handling\VideoList\ConfigProvider::class,
\MyTube\Handling\Tag\ConfigProvider::class,
\MyTube\Handling\TagList\ConfigProvider::class,
// API
/// Command
@ -72,6 +73,7 @@ $aggregator = new ConfigAggregator([
\MyTube\API\External\Video\ConfigProvider::class,
\MyTube\API\External\VideoList\ConfigProvider::class,
\MyTube\API\External\Tag\ConfigProvider::class,
\MyTube\API\External\TagList\ConfigProvider::class,
/// Internal

View File

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
use MyTube\API\External\TagList\Handler\ReadListHandler;
return [
[
'name' => 'tag-list.read-list',
'path' => '/api/tag-list/read-list[/]',
'allowed_methods' => ['POST'],
'middleware' => [
ReadListHandler::class,
],
],
];

View File

@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
use MyTube\API\External\TagList\Handler\ReadListHandler;
use MyTube\API\External\TagList\ResponseFormatter\ReadListResponseFormatter;
use Reinfi\DependencyInjection\Factory\AutoWiringFactory;
return [
'factories' => [
// Handler
ReadListHandler::class => AutoWiringFactory::class,
// Response Formatter
ReadListResponseFormatter::class => AutoWiringFactory::class,
],
];

View File

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace MyTube\API\External\TagList;
class ConfigProvider
{
public function __invoke(): array
{
return [
'dependencies' => require __DIR__ . './../config/service_manager.php',
'routes' => require __DIR__ . '/./../config/routes.php',
];
}
}

View File

@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace MyTube\API\External\TagList\Handler;
use MyTube\Handling\TagList\Handler\Query\ReadList\ReadListQueryHandler;
use MyTube\Handling\TagList\Handler\Query\ReadList\ReadListQueryBuilder;
use MyTube\API\External\TagList\ResponseFormatter\ReadListResponseFormatter;
use MyTube\Infrastructure\Request\Middleware\AnalyzeBodyMiddleware;
use MyTube\Infrastructure\Response\SuccessResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class ReadListHandler implements RequestHandlerInterface
{
public function __construct(
private readonly ReadListQueryHandler $readListQueryHandler,
private readonly ReadListQueryBuilder $readListQueryBuilder,
private readonly ReadListResponseFormatter $responseFormatter,
) {
}
public function handle(ServerRequestInterface $request): ResponseInterface
{
$data = $request->getAttribute(AnalyzeBodyMiddleware::JSON_DATA);
$readListQuery = $this->readListQueryBuilder->build(
$data['query'] ?? null,
$data['page'],
$data['perPage'],
);
$result = $this->readListQueryHandler->execute($readListQuery);
return new SuccessResponse($this->responseFormatter->format($result));
}
}

View File

@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace MyTube\API\External\TagList\ResponseFormatter;
use MyTube\Data\Business\Entity\Tag;
use MyTube\Handling\TagList\Handler\Query\ReadList\ReadListQueryResult;
class ReadListResponseFormatter
{
public function format(ReadListQueryResult $readListQueryResult): array
{
$paginator = $readListQueryResult->getPaginator();
$tags = $paginator->getIterator();
$items = [];
/** @var Tag $tag */
foreach ($tags as $tag) {
$items[] = [
'id' => $tag->getId()->toString(),
'description' => $tag->getDescription(),
];
}
return [
'total' => $paginator->count(),
'items' => $items,
];
}
}

View File

@ -5,8 +5,8 @@ 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\Handling\VideoList\Handler\Query\ReadList\ReadListQueryHandler;
use MyTube\Infrastructure\Request\Middleware\AnalyzeBodyMiddleware;
use MyTube\Infrastructure\Response\SuccessResponse;
use Psr\Http\Message\ResponseInterface;

View File

@ -3,6 +3,28 @@
namespace MyTube\Data\Business\Repository;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Tools\Pagination\Paginator;
class TagRepository extends EntityRepository {
public function findByFilter(
?string $query,
int $page,
int $perPage,
): Paginator
{
$queryBuilder = $this->createQueryBuilder('t');
if ($query !== null) {
$query = '%'.$query.'%';
$queryBuilder
->where('t.description like :query')
->setParameter('query', $query);
}
$queryBuilder->setFirstResult($perPage * ($page - 1));
$queryBuilder->setMaxResults($perPage);
return new Paginator($queryBuilder->getQuery());
}
}

View File

@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
use MyTube\Handling\TagList\Handler\Query\ReadList\ReadListQueryHandler;
use MyTube\Handling\TagList\Handler\Query\ReadList\ReadListQueryBuilder;
use Reinfi\DependencyInjection\Factory\AutoWiringFactory;
use Reinfi\DependencyInjection\Factory\InjectionFactory;
return [
'factories' => [
/// CQRS
// ReadList
ReadListQueryBuilder::class => AutoWiringFactory::class,
ReadListQueryHandler::class => AutoWiringFactory::class,
],
];

View File

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace MyTube\Handling\TagList;
class ConfigProvider
{
public function __invoke(): array
{
return [
'dependencies' => require __DIR__ . './../config/service_manager.php',
];
}
}

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace MyTube\Handling\TagList\Handler\Query\ReadList;
class ReadListQuery
{
public function __construct(
private readonly ?string $query,
private readonly int $page,
private readonly int $perPage,
) {
}
public function getQuery(): ?string
{
return $this->query;
}
public function getPage(): int
{
return $this->page;
}
public function getPerPage(): int
{
return $this->perPage;
}
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace MyTube\Handling\TagList\Handler\Query\ReadList;
class ReadListQueryBuilder
{
public function build(
?string $query,
int $page,
int $perPage,
): ReadListQuery {
return new ReadListQuery(
$query,
$page,
$perPage,
);
}
}

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace MyTube\Handling\TagList\Handler\Query\ReadList;
use MyTube\Data\Business\Repository\TagRepository;
use Reinfi\DependencyInjection\Annotation\InjectDoctrineRepository;
class ReadListQueryHandler
{
/**
* @InjectDoctrineRepository(
* entityManager="MyTube\Data\Business\Manager\MyTubeEntityManager",
* entity="MyTube\Data\Business\Entity\Tag"
* )
*/
public function __construct(
private readonly TagRepository $tagRepository
) {
}
public function execute(ReadListQuery $readListQuery): ReadListQueryResult
{
return new ReadListQueryResult(
$this->tagRepository->findByFilter(
$readListQuery->getQuery(),
$readListQuery->getPage(),
$readListQuery->getPerPage()
)
);
}
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace MyTube\Handling\TagList\Handler\Query\ReadList;
use Doctrine\ORM\Tools\Pagination\Paginator;
class ReadListQueryResult
{
public function __construct(
private readonly Paginator $paginator
) {
}
public function getPaginator(): Paginator
{
return $this->paginator;
}
}