ogcore/src/State/Provider/GitRepositoryProvider.php

136 lines
5.4 KiB
PHP

<?php
namespace App\State\Provider;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Put;
use ApiPlatform\State\Pagination\TraversablePaginator;
use ApiPlatform\State\ProviderInterface;
use App\Dto\Input\GitRepositoryInput;
use App\Dto\Output\GitRepositoryOutput;
use App\Service\ExternalGitRepositoryService;
use App\Repository\ImageRepositoryRepository;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\RequestStack;
readonly class GitRepositoryProvider implements ProviderInterface
{
public function __construct(
private ExternalGitRepositoryService $externalService,
private ImageRepositoryRepository $imageRepositoryRepository,
private RequestStack $requestStack
)
{
}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
switch ($operation){
case $operation instanceof GetCollection:
return $this->provideCollection($operation, $uriVariables, $context);
case $operation instanceof Patch:
case $operation instanceof Put:
return $this->provideInput($operation, $uriVariables, $context);
case $operation instanceof Get:
return $this->provideItem($operation, $uriVariables, $context);
}
}
private function provideCollection(Operation $operation, array $uriVariables = [], array $context = []): object
{
// Obtener el ImageRepository desde los parámetros de la request
$request = $this->requestStack->getCurrentRequest();
$repositoryId = $request->query->get('repository');
if (!$repositoryId) {
throw new \InvalidArgumentException('El parámetro "repository" es requerido');
}
$imageRepository = $this->imageRepositoryRepository->find($repositoryId);
if (!$imageRepository) {
throw new NotFoundHttpException('ImageRepository no encontrado');
}
// Obtener repositorios de la API externa
$externalRepositories = $this->externalService->getRepositories($imageRepository);
$items = new \ArrayObject();
foreach ($externalRepositories as $externalData) {
$gitRepository = $this->externalService->createEntityFromExternalData($externalData, $imageRepository);
$items[] = new GitRepositoryOutput($gitRepository, $context);
}
// Simular paginación básica
$page = $request->query->getInt('page', 1);
$limit = $request->query->getInt('limit', 10);
$offset = ($page - 1) * $limit;
$paginatedItems = array_slice($items->getArrayCopy(), $offset, $limit);
return new TraversablePaginator(
new \ArrayObject($paginatedItems),
$page,
$limit,
count($items)
);
}
public function provideItem(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
// Obtener el nombre del repositorio desde los parámetros
$request = $this->requestStack->getCurrentRequest();
$repositoryId = $request->query->get('repository');
$name = $uriVariables['name'] ?? $request->query->get('name');
if (!$repositoryId || !$name) {
throw new \InvalidArgumentException('Los parámetros "repository" y "name" son requeridos');
}
$imageRepository = $this->imageRepositoryRepository->find($repositoryId);
if (!$imageRepository) {
throw new NotFoundHttpException('ImageRepository no encontrado');
}
// Obtener repositorio específico de la API externa
$externalData = $this->externalService->getRepository($name, $imageRepository);
if (!$externalData) {
throw new NotFoundHttpException('GitRepository no encontrado');
}
$gitRepository = $this->externalService->createEntityFromExternalData($externalData, $imageRepository);
return new GitRepositoryOutput($gitRepository);
}
public function provideInput(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
if (isset($uriVariables['name'])) {
// Para operaciones de actualización, necesitamos obtener el repositorio existente
$request = $this->requestStack->getCurrentRequest();
$repositoryId = $request->query->get('repository');
$name = $uriVariables['name'];
if (!$repositoryId) {
throw new \InvalidArgumentException('El parámetro "repository" es requerido');
}
$imageRepository = $this->imageRepositoryRepository->find($repositoryId);
if (!$imageRepository) {
throw new NotFoundHttpException('ImageRepository no encontrado');
}
$externalData = $this->externalService->getRepository($name, $imageRepository);
if (!$externalData) {
throw new NotFoundHttpException('GitRepository no encontrado');
}
$gitRepository = $this->externalService->createEntityFromExternalData($externalData, $imageRepository);
return new GitRepositoryInput($gitRepository);
}
return new GitRepositoryInput();
}
}