Files
AeonDumpManager/src/Controller/DumpController.php
T

125 lines
4.4 KiB
PHP

<?php declare(strict_types=1);
namespace AeonDumpManager\Controller;
use AeonDumpManager\MessageQueue\Message\CreateDumpMessage;
use AeonDumpManager\Service\DumpJobStatusService;
use AeonDumpManager\Service\DumpLister;
use AeonDumpManager\Service\DumpService;
use AeonDumpManager\Service\Exception\DumpNotFoundException;
use Shopware\Core\Framework\Routing\ApiRouteScope;
use Shopware\Core\PlatformRequest;
use Symfony\Component\HttpFoundation\HeaderUtils;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Annotation\Route;
/**
* Client-side acl.can() in the admin UI only hides buttons — real
* enforcement is the PlatformRequest::ATTRIBUTE_ACL route default below,
* checked server-side by AclAnnotationValidator against Context::isAllowed().
*/
#[Route(defaults: [PlatformRequest::ATTRIBUTE_ROUTE_SCOPE => [ApiRouteScope::ID]])]
class DumpController
{
public function __construct(
private readonly DumpLister $dumpLister,
private readonly DumpService $dumpService,
private readonly DumpJobStatusService $jobStatus,
private readonly MessageBusInterface $bus,
) {
}
#[Route(
path: '/api/_action/aeon-dump-manager/dumps',
name: 'api.action.aeon_dump_manager.dumps.list',
defaults: [PlatformRequest::ATTRIBUTE_ACL => ['aeon_dump_manager.viewer']],
methods: ['GET']
)]
public function list(): JsonResponse
{
$dumps = array_map(
static fn ($dumpFile) => $dumpFile->jsonSerialize(),
$this->dumpLister->list()
);
return new JsonResponse(['dumps' => $dumps]);
}
#[Route(
path: '/api/_action/aeon-dump-manager/dumps',
name: 'api.action.aeon_dump_manager.dumps.create',
defaults: [PlatformRequest::ATTRIBUTE_ACL => ['aeon_dump_manager.creator']],
methods: ['POST']
)]
public function create(): JsonResponse
{
$jobId = $this->jobStatus->createPending();
$this->bus->dispatch(new CreateDumpMessage($jobId));
return new JsonResponse(['jobId' => $jobId], Response::HTTP_ACCEPTED);
}
#[Route(
path: '/api/_action/aeon-dump-manager/dumps/{filename}',
name: 'api.action.aeon_dump_manager.dumps.delete',
defaults: [PlatformRequest::ATTRIBUTE_ACL => ['aeon_dump_manager.deleter']],
methods: ['DELETE']
)]
public function delete(string $filename): JsonResponse
{
try {
$this->dumpService->delete($filename);
} catch (DumpNotFoundException $exception) {
return new JsonResponse(['message' => $exception->getMessage()], Response::HTTP_NOT_FOUND);
}
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
}
#[Route(
path: '/api/_action/aeon-dump-manager/dumps/{filename}/download',
name: 'api.action.aeon_dump_manager.dumps.download',
defaults: [PlatformRequest::ATTRIBUTE_ACL => ['aeon_dump_manager.viewer']],
methods: ['GET']
)]
public function download(string $filename): StreamedResponse
{
try {
$stream = $this->dumpService->readStream($filename);
} catch (DumpNotFoundException $exception) {
throw new NotFoundHttpException($exception->getMessage());
}
$response = new StreamedResponse(static function () use ($stream): void {
fpassthru($stream);
});
$response->headers->set('Content-Type', 'application/gzip');
$response->headers->set(
'Content-Disposition',
HeaderUtils::makeDisposition(HeaderUtils::DISPOSITION_ATTACHMENT, $filename)
);
return $response;
}
#[Route(
path: '/api/_action/aeon-dump-manager/dumps/jobs/{jobId}',
name: 'api.action.aeon_dump_manager.dumps.jobs.status',
defaults: [PlatformRequest::ATTRIBUTE_ACL => ['aeon_dump_manager.viewer']],
methods: ['GET']
)]
public function jobStatus(string $jobId): JsonResponse
{
$job = $this->jobStatus->find($jobId);
if ($job === null) {
return new JsonResponse(['message' => 'Job not found'], Response::HTTP_NOT_FOUND);
}
return new JsonResponse($job);
}
}