$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} $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); } }