90 lines
2.7 KiB
PHP
90 lines
2.7 KiB
PHP
<?php declare(strict_types=1);
|
|
|
|
namespace AeonDumpManager\Service;
|
|
|
|
use Doctrine\DBAL\Connection;
|
|
use Shopware\Core\Framework\Uuid\Uuid;
|
|
|
|
/**
|
|
* Owns the aeon_dump_manager_job table. Shopware core has no generic
|
|
* async-job-status framework to hook into (confirmed against core's own
|
|
* Import/Export source) — this mirrors that pattern with a small dedicated table.
|
|
*/
|
|
class DumpJobStatusService
|
|
{
|
|
public function __construct(private readonly Connection $connection)
|
|
{
|
|
}
|
|
|
|
public function createPending(): string
|
|
{
|
|
$id = Uuid::randomBytes();
|
|
|
|
$this->connection->insert('aeon_dump_manager_job', [
|
|
'id' => $id,
|
|
'status' => 'pending',
|
|
'created_at' => (new \DateTimeImmutable())->format('Y-m-d H:i:s.v'),
|
|
]);
|
|
|
|
return Uuid::fromBytesToHex($id);
|
|
}
|
|
|
|
public function markRunning(string $jobId): void
|
|
{
|
|
$this->update($jobId, ['status' => 'running']);
|
|
}
|
|
|
|
public function updateProgress(string $jobId, int $percent): void
|
|
{
|
|
$this->update($jobId, ['percent' => min(99, max(0, $percent))]);
|
|
}
|
|
|
|
public function markDone(string $jobId, string $filename): void
|
|
{
|
|
$this->update($jobId, ['status' => 'done', 'percent' => 100, 'filename' => $filename]);
|
|
}
|
|
|
|
public function markFailed(string $jobId, string $errorMessage): void
|
|
{
|
|
$this->update($jobId, ['status' => 'failed', 'error_message' => $errorMessage]);
|
|
}
|
|
|
|
/**
|
|
* @return array{id: string, status: string, percent: ?int, filename: ?string, errorMessage: ?string}|null
|
|
*/
|
|
public function find(string $jobId): ?array
|
|
{
|
|
$row = $this->connection->fetchAssociative(
|
|
'SELECT LOWER(HEX(id)) AS id, status, percent, filename, error_message FROM aeon_dump_manager_job WHERE id = :id',
|
|
['id' => Uuid::fromHexToBytes($jobId)]
|
|
);
|
|
|
|
if ($row === false) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
'id' => $row['id'],
|
|
'status' => $row['status'],
|
|
'percent' => $row['percent'] !== null ? (int) $row['percent'] : null,
|
|
'filename' => $row['filename'],
|
|
'errorMessage' => $row['error_message'],
|
|
];
|
|
}
|
|
|
|
public function purgeOlderThan(\DateTimeImmutable $threshold): void
|
|
{
|
|
$this->connection->executeStatement(
|
|
'DELETE FROM aeon_dump_manager_job WHERE created_at < :threshold',
|
|
['threshold' => $threshold->format('Y-m-d H:i:s.v')]
|
|
);
|
|
}
|
|
|
|
private function update(string $jobId, array $data): void
|
|
{
|
|
$data['updated_at'] = (new \DateTimeImmutable())->format('Y-m-d H:i:s.v');
|
|
|
|
$this->connection->update('aeon_dump_manager_job', $data, ['id' => Uuid::fromHexToBytes($jobId)]);
|
|
}
|
|
}
|