101 lines
2.9 KiB
PHP
101 lines
2.9 KiB
PHP
<?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);
|
|
}
|
|
}
|