116 lines
3.7 KiB
PHP
116 lines
3.7 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Http\Controllers\V5\Concerns;
|
||
|
|
|
||
|
|
use App\Models\Environment;
|
||
|
|
use App\Models\Project;
|
||
|
|
use App\Models\Team;
|
||
|
|
use Illuminate\Database\Eloquent\Builder;
|
||
|
|
use Illuminate\Http\Request;
|
||
|
|
|
||
|
|
trait ResolvesProjectSelection
|
||
|
|
{
|
||
|
|
protected const SELECTED_PROJECT_SESSION_KEY = 'v5.selectedProjectUuid';
|
||
|
|
|
||
|
|
protected const SELECTED_ENVIRONMENT_SESSION_KEY = 'v5.selectedEnvironmentUuid';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @return array{id: int}|null
|
||
|
|
*/
|
||
|
|
protected function serializeCurrentTeam(mixed $currentTeam): ?array
|
||
|
|
{
|
||
|
|
if (! $currentTeam instanceof Team) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
return [
|
||
|
|
'id' => $currentTeam->id,
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param array<int, array{uuid: string, name: string, environments: array<int, array{uuid: string, name: string}>}> $projects
|
||
|
|
* @return array{0: array{uuid: string, name: string, environments: array<int, array{uuid: string, name: string}>}|null, 1: array{uuid: string, name: string}|null}
|
||
|
|
*/
|
||
|
|
protected function selectedProjectAndEnvironment(Request $request, array $projects): array
|
||
|
|
{
|
||
|
|
$selectedProjectUuid = $request->session()->get(self::SELECTED_PROJECT_SESSION_KEY);
|
||
|
|
$selectedEnvironmentUuid = $request->session()->get(self::SELECTED_ENVIRONMENT_SESSION_KEY);
|
||
|
|
$selectedProject = null;
|
||
|
|
|
||
|
|
foreach ($projects as $project) {
|
||
|
|
if ($project['uuid'] === $selectedProjectUuid) {
|
||
|
|
$selectedProject = $project;
|
||
|
|
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$selectedProject ??= $projects[0] ?? null;
|
||
|
|
$selectedEnvironment = null;
|
||
|
|
|
||
|
|
foreach ($selectedProject['environments'] ?? [] as $environment) {
|
||
|
|
if ($environment['uuid'] === $selectedEnvironmentUuid) {
|
||
|
|
$selectedEnvironment = $environment;
|
||
|
|
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$selectedEnvironment ??= $selectedProject['environments'][0] ?? null;
|
||
|
|
|
||
|
|
return [$selectedProject, $selectedEnvironment];
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function selectedEnvironment(Project $project, ?string $environmentUuid): ?Environment
|
||
|
|
{
|
||
|
|
if ($environmentUuid === null) {
|
||
|
|
return $project->environments->first();
|
||
|
|
}
|
||
|
|
|
||
|
|
$environment = $project->environments->firstWhere('uuid', $environmentUuid);
|
||
|
|
|
||
|
|
if (! $environment instanceof Environment) {
|
||
|
|
abort(422, 'The selected environment is not available for the selected project.');
|
||
|
|
}
|
||
|
|
|
||
|
|
return $environment;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @return array<int, array{uuid: string, name: string, environments: array<int, array{uuid: string, name: string}>}>
|
||
|
|
*/
|
||
|
|
protected function projects(mixed $currentTeam): array
|
||
|
|
{
|
||
|
|
if (! $currentTeam instanceof Team) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
|
||
|
|
return $this->projectQuery($currentTeam)
|
||
|
|
->get()
|
||
|
|
->map(fn (Project $project) => [
|
||
|
|
'uuid' => $project->uuid,
|
||
|
|
'name' => $project->name,
|
||
|
|
'environments' => $project->environments
|
||
|
|
->map(fn ($environment) => [
|
||
|
|
'uuid' => $environment->uuid,
|
||
|
|
'name' => $environment->name,
|
||
|
|
])
|
||
|
|
->all(),
|
||
|
|
])
|
||
|
|
->all();
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function projectQuery(Team $currentTeam): Builder
|
||
|
|
{
|
||
|
|
return Project::query()
|
||
|
|
->select(['id', 'uuid', 'name', 'team_id'])
|
||
|
|
->where('team_id', $currentTeam->id)
|
||
|
|
->with(['environments' => fn ($query) => $query
|
||
|
|
->select(['id', 'uuid', 'name', 'project_id'])
|
||
|
|
->orderByRaw("CASE WHEN LOWER(name) = 'production' THEN 0 ELSE 1 END")
|
||
|
|
->orderByRaw('LOWER(name)')])
|
||
|
|
->orderByRaw('LOWER(name)');
|
||
|
|
}
|
||
|
|
}
|