Add editable project template flow
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Projects;
|
||||
|
||||
use App\Models\ProjectTemplate;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class UpdateProjectTemplate
|
||||
{
|
||||
public function __construct(
|
||||
private readonly DuplicateProjectConfiguration $duplicateProjectConfiguration,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @param array{name: string, copy_areas?: array<int, string>} $attributes
|
||||
*/
|
||||
public function handle(ProjectTemplate $projectTemplate, array $attributes): ProjectTemplate
|
||||
{
|
||||
$projectTemplate->loadMissing('sourceProject', 'linkedProjects.projectTemplate');
|
||||
|
||||
$sourceProject = $projectTemplate->sourceProject;
|
||||
abort_if($sourceProject === null, 422, 'This template cannot be edited because the source project is missing.');
|
||||
|
||||
$copyAreas = array_values(Arr::get($attributes, 'copy_areas', []));
|
||||
$normalizedCopyAreas = $this->duplicateProjectConfiguration->normalizeCopyAreas($copyAreas);
|
||||
$previousConfiguration = $projectTemplate->configuration_snapshot ?? [];
|
||||
$nextConfiguration = $this->duplicateProjectConfiguration->export($sourceProject, $normalizedCopyAreas);
|
||||
$affectedAreas = array_values(array_unique([
|
||||
...array_keys($previousConfiguration),
|
||||
...array_keys($nextConfiguration),
|
||||
]));
|
||||
|
||||
DB::transaction(function () use ($projectTemplate, $attributes, $normalizedCopyAreas, $nextConfiguration, $previousConfiguration, $affectedAreas): void {
|
||||
$projectTemplate->forceFill([
|
||||
'name' => $attributes['name'],
|
||||
'copy_areas' => $normalizedCopyAreas,
|
||||
'configuration_snapshot' => $nextConfiguration,
|
||||
])->save();
|
||||
|
||||
foreach ($projectTemplate->linkedProjects as $linkedProject) {
|
||||
$currentConfiguration = $this->duplicateProjectConfiguration->export($linkedProject->fresh(), $affectedAreas);
|
||||
$replacementConfiguration = [];
|
||||
|
||||
foreach ($nextConfiguration as $area => $configuration) {
|
||||
$isNewTemplateArea = ! array_key_exists($area, $previousConfiguration);
|
||||
$matchesPreviousTemplate = array_key_exists($area, $previousConfiguration)
|
||||
&& array_key_exists($area, $currentConfiguration)
|
||||
&& $currentConfiguration[$area] === $previousConfiguration[$area];
|
||||
|
||||
if ($isNewTemplateArea || $matchesPreviousTemplate) {
|
||||
$replacementConfiguration[$area] = $configuration;
|
||||
}
|
||||
}
|
||||
|
||||
if ($replacementConfiguration === []) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->duplicateProjectConfiguration->apply($linkedProject->fresh(), $replacementConfiguration);
|
||||
}
|
||||
});
|
||||
|
||||
return $projectTemplate->fresh(['sourceProject'])->loadCount('linkedProjects');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user