This commit is contained in:
2026-03-20 21:17:26 +01:00
parent 1a62fcb81d
commit 29c3ff8572
229 changed files with 13147 additions and 2577 deletions

View File

@@ -0,0 +1,100 @@
<?php
declare(strict_types=1);
namespace App\Services\Countries;
use App\Models\Country;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Schema;
final class CountryCatalogService
{
public const ACTIVE_ALL_CACHE_KEY = 'countries.active.all';
public const PROFILE_SELECT_CACHE_KEY = 'countries.profile.select';
/**
* @return Collection<int, Country>
*/
public function activeCountries(): Collection
{
if (! Schema::hasTable('countries')) {
return collect();
}
/** @var Collection<int, Country> $countries */
$countries = Cache::remember(
self::ACTIVE_ALL_CACHE_KEY,
max(60, (int) config('skinbase-countries.cache_ttl', 86400)),
fn (): Collection => Country::query()->active()->ordered()->get(),
);
return $countries;
}
/**
* @return array<int, array<string, mixed>>
*/
public function profileSelectOptions(): array
{
return Cache::remember(
self::PROFILE_SELECT_CACHE_KEY,
max(60, (int) config('skinbase-countries.cache_ttl', 86400)),
fn (): array => $this->activeCountries()
->map(fn (Country $country): array => [
'id' => $country->id,
'iso2' => $country->iso2,
'name' => $country->name_common,
'flag_emoji' => $country->flag_emoji,
'flag_css_class' => $country->flag_css_class,
'is_featured' => $country->is_featured,
'flag_path' => $country->local_flag_path,
])
->values()
->all(),
);
}
public function findById(?int $countryId): ?Country
{
if ($countryId === null || $countryId <= 0 || ! Schema::hasTable('countries')) {
return null;
}
return Country::query()->find($countryId);
}
public function findByIso2(?string $iso2): ?Country
{
$normalized = strtoupper(trim((string) $iso2));
if ($normalized === '' || ! preg_match('/^[A-Z]{2}$/', $normalized) || ! Schema::hasTable('countries')) {
return null;
}
return Country::query()->where('iso2', $normalized)->first();
}
public function resolveUserCountry(User $user): ?Country
{
if ($user->relationLoaded('country') && $user->country instanceof Country) {
return $user->country;
}
if (! empty($user->country_id)) {
return $this->findById((int) $user->country_id);
}
$countryCode = strtoupper((string) ($user->profile?->country_code ?? ''));
return $countryCode !== '' ? $this->findByIso2($countryCode) : null;
}
public function flushCache(): void
{
Cache::forget(self::ACTIVE_ALL_CACHE_KEY);
Cache::forget(self::PROFILE_SELECT_CACHE_KEY);
}
}