125 lines
4.4 KiB
PHP
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);
|
|
}
|
|
}
|