Files
Investidor-V2/app/Services/CountryCatalogue.php
T
nala 6ddafc95ba
tests / ci (push) Canceled after 0s
oportunidades 4
2026-10-10 07:03:59 +02:00

57 lines
2.0 KiB
PHP

<?php
namespace App\Services;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
/** Shared ISO identifiers; independent of administrative territories and IP data. */
final class CountryCatalogue
{
/** @return list<array{code: string, name: string, name_en: string}> */
public function all(): array
{
$countries = [];
$lines = file(resource_path('data/iso3166.tab'), FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if ($lines === false) {
throw new \RuntimeException('Catálogo ISO local indisponível.');
}
foreach ($lines as $line) {
if (str_starts_with($line, '#')) {
continue;
}
[$code, $english] = explode("\t", $line, 2);
$name = class_exists(\Locale::class) ? \Locale::getDisplayRegion('und_'.$code, 'pt') : $english;
$countries[] = ['code' => $code, 'name' => is_string($name) && $name !== '' ? $name : $english, 'name_en' => $english];
}
usort($countries, fn ($a, $b) => strnatcasecmp($a['name'], $b['name']));
return $countries;
}
public function rule(): In
{
return Rule::in(array_column($this->all(), 'code'));
}
/** Accept existing free-text integrations; validate ISO-shaped values without rewriting them. */
public function legacyCountryRule(): \Closure
{
$codes = array_column($this->all(), 'code');
return static function (string $attribute, mixed $value, \Closure $fail) use ($codes): void {
if (is_string($value) && preg_match('/^[a-zA-Z]{2}$/D', $value) && ! in_array($value, $codes, true)) {
$fail('Seleccione um código ISO de país válido.');
}
};
}
/** @return array{code:string|null,name:string} */
public function describe(?string $code): array
{
$names = array_column($this->all(), 'name', 'code');
return isset($names[$code ?? '']) ? ['code' => $code, 'name' => $names[$code]] : ['code' => null, 'name' => 'Não informado'];
}
}