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']); } }