66 lines
2.8 KiB
PHP
66 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Projects;
|
|
|
|
use App\Models\Project;
|
|
use App\Models\ProjectTemplate;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class CreateProjectTemplate
|
|
{
|
|
public function __construct(
|
|
private readonly DuplicateProjectConfiguration $duplicateProjectConfiguration,
|
|
private readonly ProjectConfigurationIdentity $projectConfigurationIdentity,
|
|
) {}
|
|
|
|
/** @param array<string, mixed> $attributes */
|
|
public function empty(array $attributes): ProjectTemplate
|
|
{
|
|
$areas = $this->duplicateProjectConfiguration->normalizeCopyAreas(Arr::get($attributes, 'copy_areas', []));
|
|
|
|
return ProjectTemplate::query()->create([
|
|
'name' => Arr::get($attributes, 'name'),
|
|
'slug' => Arr::get($attributes, 'slug'),
|
|
'is_published' => true,
|
|
'copy_areas' => $areas,
|
|
'configuration_snapshot' => collect($this->duplicateProjectConfiguration->normalizeConfiguration(
|
|
Arr::get($attributes, 'configuration_snapshot', $this->projectConfigurationIdentity->defaults()),
|
|
))->only($areas)->all(),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @param array{name: string, slug: string, copy_areas?: array<int, string>} $attributes
|
|
*/
|
|
public function handle(Project $sourceProject, array $attributes): ProjectTemplate
|
|
{
|
|
return DB::transaction(function () use ($sourceProject, $attributes): ProjectTemplate {
|
|
$sourceProject = Project::query()->whereKey($sourceProject->id)->lockForUpdate()->firstOrFail();
|
|
$copyAreas = $this->duplicateProjectConfiguration->normalizeCopyAreas(Arr::get($attributes, 'copy_areas', []));
|
|
$template = $sourceProject->projectTemplate;
|
|
if ($template === null || $template->is_published || $template->project_id !== $sourceProject->id) {
|
|
$template = new ProjectTemplate;
|
|
$template->slug = Arr::get($attributes, 'slug');
|
|
}
|
|
$template->forceFill([
|
|
'project_id' => null,
|
|
'source_project_id' => $sourceProject->id,
|
|
'name' => Arr::get($attributes, 'name'),
|
|
'is_published' => true,
|
|
'copy_areas' => $copyAreas,
|
|
'configuration_snapshot' => $this->duplicateProjectConfiguration->export($sourceProject, $copyAreas),
|
|
])->save();
|
|
$sourceProject->forceFill([
|
|
'project_template_id' => $template->id,
|
|
'template_overrides' => array_values(array_diff(DuplicateProjectConfiguration::copyableAreas(), $copyAreas)),
|
|
])->saveQuietly();
|
|
foreach ($sourceProject->configurationRelations() as $relation) {
|
|
$sourceProject->{$relation}()->update(['project_template_id' => $template->id]);
|
|
}
|
|
|
|
return $template;
|
|
}, 3);
|
|
}
|
|
}
|