update
This commit is contained in:
100
app/Services/Countries/CountryCatalogService.php
Normal file
100
app/Services/Countries/CountryCatalogService.php
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user