Files
SkinbaseNova/app/Services/NovaCards/NovaCardVersionService.php
2026-03-28 19:15:39 +01:00

58 lines
2.1 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\NovaCards;
use App\Models\NovaCard;
use App\Models\NovaCardVersion;
use App\Models\User;
class NovaCardVersionService
{
public function __construct(
private readonly NovaCardProjectNormalizer $normalizer,
) {
}
public function snapshot(NovaCard $card, ?User $actor = null, ?string $label = null, bool $force = false): NovaCardVersion
{
$project = $this->normalizer->normalizeForCard($card->fresh(['template']));
$hash = hash('sha256', json_encode($project, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
$latest = $card->versions()->latest('version_number')->first();
if (! $force && $latest && $latest->snapshot_hash === $hash) {
return $latest;
}
return $card->versions()->create([
'user_id' => $actor?->id,
'version_number' => (int) ($latest?->version_number ?? 0) + 1,
'label' => $label,
'snapshot_hash' => $hash,
'snapshot_json' => $project,
]);
}
public function restore(NovaCard $card, NovaCardVersion $version, ?User $actor = null): NovaCard
{
$project = $this->normalizer->normalize($version->snapshot_json, $card->template, [], $card);
$topLevel = $this->normalizer->syncTopLevelAttributes($project);
$card->forceFill([
'project_json' => $project,
'schema_version' => $topLevel['schema_version'],
'title' => $topLevel['title'],
'quote_text' => $topLevel['quote_text'],
'quote_author' => $topLevel['quote_author'],
'quote_source' => $topLevel['quote_source'],
'background_type' => $topLevel['background_type'],
'background_image_id' => $topLevel['background_image_id'],
'render_version' => (int) $card->render_version + 1,
])->save();
$this->snapshot($card->refresh(['template']), $actor, 'Restored from version ' . $version->version_number, true);
return $card->refresh()->load(['category', 'template', 'tags', 'backgroundImage', 'versions']);
}
}