paginated list

This commit is contained in:
Flo 2024-02-24 20:16:24 +01:00
parent 3f97413c4e
commit 0201c5c559
11 changed files with 141 additions and 32 deletions

View File

@ -15,19 +15,22 @@ $apiName = $argv[3];
$cqrsType = strtolower($argv[4]) === 'true' ? 'Command' : 'Query';
$cqrsNamespace = $argv[5];
$apiDirectoryPath = $projectSourceDirectory . 'ApiDomain/' . $apiType . '/' . $apiNamespace . '/';
$cqrsDirectoryPath = $projectSourceDirectory . 'HandlingDomain/' . $cqrsNamespace . '/';
# API Handler
$apiHandlerName = $apiName . 'Handler';
$apiHandlerNamespace = $projectNamespace . '\\API\\' . $apiType . '\\' . $apiNamespace . '\\Handler';
$apiHandlerFilePath = $projectSourceDirectory . 'ApiDomain/' . $apiType . '/' . $apiNamespace . '/src/Handler/' . $apiHandlerName . '.php';
$apiHandlerFilePath = $apiDirectoryPath . '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';
$apiResponseFormatterFilePath = $apiDirectoryPath . 'src/ResponseFormatter/' . $apiResponseFormatterName . '.php';
# CQRS
$cqrsFilePath = $projectSourceDirectory . 'HandlingDomain/' . $cqrsNamespace . '/src/Handler/' . $cqrsType . '/' . $apiName . '/';
$cqrsFilePath = $cqrsDirectoryPath . 'src/Handler/' . $cqrsType . '/' . $apiName . '/';
$cqrsName = $apiName . $cqrsType;
$cqrsVariableName = lcfirst($cqrsName);
$cqrsNamespace = $projectNamespace . '\\Handling\\' . $cqrsNamespace . '\\Handler\\' . $cqrsType . '\\' . $apiName;
@ -70,6 +73,11 @@ function writeToFile($path, $content) {
file_put_contents($path, $content);
}
if (!file_exists($apiDirectoryPath)) {
$routesFilePath = $apiDirectoryPath . 'config/routes.php';
$serviceManagerFilePath = $apiDirectoryPath . 'config/service_manager.php';
}
$apiHandlerFileContent = "<?php
declare(strict_types=1);

View File

@ -3,6 +3,7 @@
declare(strict_types=1);
use MyTube\Infrastructure\Exception\Middleware\MyTubeExceptionHandlerMiddleware;
use MyTube\Infrastructure\Request\Middleware\AnalyzeBodyMiddleware;
use MyTube\Infrastructure\Request\Middleware\AnalyzeHeaderMiddleware;
use MyTube\Infrastructure\Session\Middleware\SessionMiddleware;
use Laminas\Stratigility\Middleware\ErrorHandler;
@ -69,6 +70,7 @@ return function (Application $app, MiddlewareFactory $factory, ContainerInterfac
//// Pre MyTube Space
$app->pipe(MyTubeExceptionHandlerMiddleware::class);
$app->pipe(AnalyzeHeaderMiddleware::class);
$app->pipe(AnalyzeBodyMiddleware::class);
//// MyTube Space
$app->pipe(SessionMiddleware::class);

View File

@ -1,4 +1,5 @@
file_uploads = On
max_file_uploads = 1000
memory_limit = 10000M
upload_max_filesize = 10000M
post_max_size = 10000M

View File

@ -7,6 +7,7 @@ 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\Request\Middleware\AnalyzeBodyMiddleware;
use MyTube\Infrastructure\Response\SuccessResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@ -23,13 +24,12 @@ class ReadListHandler implements RequestHandlerInterface
public function handle(ServerRequestInterface $request): ResponseInterface
{
$data = json_decode(
$request->getBody()->getContents(),
true
);
$data = $request->getAttribute(AnalyzeBodyMiddleware::JSON_DATA);
$readListQuery = $this->readListQueryBuilder->build(
$data
$data['query'] ?? null,
$data['page'],
$data['perPage'],
);
$result = $this->readListQueryHandler->execute($readListQuery);

View File

@ -6,12 +6,16 @@ namespace MyTube\API\External\VideoList\ResponseFormatter;
use MyTube\Data\Business\Entity\Tag;
use MyTube\Data\Business\Entity\Video;
use MyTube\Handling\VideoList\Handler\Query\ReadList\ReadListQueryResult;
class ReadListResponseFormatter
{
public function format(array $videos): array
public function format(ReadListQueryResult $queryResult): array
{
$result = [];
$paginator = $queryResult->getPaginator();
$videos = $paginator->getIterator();
$items = [];
/** @var Video $video */
foreach ($videos as $video) {
@ -22,13 +26,16 @@ class ReadListResponseFormatter
$tags[] = $tag->getDescription();
}
$result[] = [
$items[] = [
'title' => $video->getTitle(),
'id' => $video->getId()->toString(),
'tags' => $tags
];
}
return $result;
return [
'total' => $paginator->count(),
'items' => $items,
];
}
}

View File

@ -8,21 +8,24 @@ use Doctrine\ORM\EntityRepository;
class VideoRepository extends EntityRepository {
public function findByFilter(
string $identifier
?string $query,
int $page,
int $perPage,
): Paginator
{
$queryBuilder = $this->createQueryBuilder('r');
$queryBuilder->where(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->eq('r.username', ':identifier'),
$queryBuilder->expr()->eq('r.mail', ':identifier')
)
)
->setParameter('identifier', $identifier);
$query = $queryBuilder->getQuery();
$queryBuilder = $this->createQueryBuilder('v');
/** @var ?Registration $registration */
$registration = $query->execute()[0] ?? null;
return $registration;
if ($query !== null) {
$query = '%'.$query.'%';
$queryBuilder
->where('v.title like :query')
->setParameter('query', $query);
}
$queryBuilder->setFirstResult($perPage * ($page - 1));
$queryBuilder->setMaxResults($perPage);
return new Paginator($queryBuilder->getQuery());
}
}

View File

@ -7,9 +7,24 @@ namespace MyTube\Handling\VideoList\Handler\Query\ReadList;
class ReadListQuery
{
public function __construct(
#TODO
private readonly ?string $query,
private readonly int $page,
private readonly int $perPage,
) {
}
#TODO
public function getQuery(): ?string
{
return $this->query;
}
public function getPage(): int
{
return $this->page;
}
public function getPerPage(): int
{
return $this->perPage;
}
}

View File

@ -7,10 +7,14 @@ namespace MyTube\Handling\VideoList\Handler\Query\ReadList;
class ReadListQueryBuilder
{
public function build(
#TODO
?string $query,
int $page,
int $perPage,
): ReadListQuery {
return new ReadListQuery(
#TODO
$query,
$page,
$perPage,
);
}
}

View File

@ -20,8 +20,14 @@ class ReadListQueryHandler
) {
}
public function execute(ReadListQuery $readListQuery): array
public function execute(ReadListQuery $readListQuery): ReadListQueryResult
{
return $this->videoRepository->findAll();
return new ReadListQueryResult(
$this->videoRepository->findByFilter(
$readListQuery->getQuery(),
$readListQuery->getPage(),
$readListQuery->getPerPage()
)
);
}
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace MyTube\Handling\VideoList\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;
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace MyTube\Infrastructure\Request\Middleware;
use MyTube\Data\Business\Entity\Permission;
use MyTube\Data\Business\Entity\User;
use MyTube\Infrastructure\Response\ForbiddenResponse;
use MyTube\Infrastructure\Session\Middleware\LoggedInUserMiddleware;
use Laminas\Config\Config;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Reinfi\DependencyInjection\Annotation\InjectConfig;
class AnalyzeBodyMiddleware implements MiddlewareInterface
{
const JSON_DATA = 'json_data_attribute';
private const CONTENT_TYPE_HEADER = 'Content-Type';
private const CONTENT_TYPE_APPLICATION_JSON = 'application/json';
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface
{
$jsonData = [];
$contentType = $request->getHeaderLine(self::CONTENT_TYPE_HEADER);
if (str_contains($contentType, self::CONTENT_TYPE_APPLICATION_JSON)) {
$jsonData = json_decode(
$request->getBody()->getContents(),
true
);
}
return $handler->handle($request->withAttribute(
self::JSON_DATA,
$jsonData
));
}
}