58 lines
2.1 KiB
PHP
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']);
|
|
}
|
|
} |