aaix/laravel-countries
Modern Laravel country-data package with zero-touch install, auto-loaded migrations, and idempotent seeders to keep tables and rows in sync on every deploy. Includes regions, countries, language translations, and native_name. Compatible with lwwcas schema/models.
Installation:
composer require aaix/laravel-countries
php artisan migrate
countries table via migrations. No additional commands or configurations are needed.First Use Case:
use Aaix\Countries\Facades\Countries;
$country = Countries::get('US'); // Returns country data for the United States
$allCountries = Countries::all(); // Returns a collection of all countries
Where to Look First:
Aaix\Countries\Facades\Countries for quick access.\Aaix\Countries\Models\Country for direct database interactions.database/migrations/[timestamp]_create_countries_table.php to inspect the schema.Basic Data Retrieval:
$countryName = Countries::get('GB')->name; // "United Kingdom"
$countryCode = Countries::get('JP')->iso2; // "JP"
Filtering Countries:
$europeanCountries = Countries::all()->where('region', 'Europe');
Integration with Forms:
iso2 or iso3 fields for dropdowns or validation:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'country' => 'required|exists:countries,iso2',
]);
Seeding Custom Data:
Country model or use the seeder directly:
use Aaix\Countries\Database\Seeders\CountriesTableSeeder;
// Manually trigger seeder (if needed)
$this->call(CountriesTableSeeder::class);
Localization:
name_en, name_es). Access them via:
$country = Countries::get('FR');
$nameInSpanish = $country->name_es; // "Francia"
Zero-Touch Setup:
Idempotent Seeders:
API-Driven Development:
$countries = \Aaix\Countries\Models\Country::where('region', 'Asia')->get();
Testing:
$this->assertEquals('Canada', Countries::get('CA')->name);
Laravel Scout:
countries table for search functionality:
use Laravel\Scout\Searchable;
class Country extends \Aaix\Countries\Models\Country
{
use Searchable;
}
API Responses:
return response()->json([
'country' => Countries::get($request->country)->toArray(),
]);
Blade Templates:
@foreach (Countries::all() as $country)
<option value="{{ $country->iso2 }}">{{ $country->name }}</option>
@endforeach
Caching:
$countries = Cache::remember('all-countries', now()->addDays(7), function () {
return Countries::all();
});
Migration Conflicts:
countries table, drop it before running migrations to avoid conflicts. The package’s migration is idempotent but assumes a fresh table.Locale Fallbacks:
name_es) is missing, the package defaults to name_en. Handle missing locales explicitly if needed:
$name = $country->{'name_' . $locale} ?? $country->name_en;
Performance with Large Queries:
$countries = Countries::all()->paginate(20);
Overwriting Default Data:
Country model or create a custom seeder that updates specific fields.Missing Data:
countries table exists and is populated:
php artisan migrate:fresh --seed
storage/logs/laravel.log if seeding fails.Facade Not Found:
config/app.php:
'providers' => [
// ...
Aaix\Countries\CountriesServiceProvider::class,
],
Locale-Specific Issues:
en, es). Refer to the supported locales.Custom Fields:
countries table via a new migration:
Schema::table('countries', function (Blueprint $table) {
$table->string('custom_field')->nullable();
});
Partial Updates:
updateOrCreate method to patch country data:
\Aaix\Countries\Models\Country::updateOrCreate(
['iso2' => 'US'],
['custom_field' => 'value']
);
Testing Seeders:
public function setUp(): void
{
parent::setUp();
Artisan::call('migrate:fresh', ['--seed' => true]);
}
Extending the Facade:
namespace App\Facades;
use Aaix\Countries\Facades\Countries as BaseCountries;
use Illuminate\Support\Facades\Facade;
class Countries extends Facade
{
protected static function getFacadeAccessor()
{
return 'countries';
}
public static function getByRegion($region)
{
return BaseCountries::all()->where('region', $region);
}
}
AppServiceProvider.Performance Optimization:
Schema::table('countries', function (Blueprint $table) {
$table->index('iso2');
$table->index('iso3');
$table->index('region');
});
Fallback to Original Package:
How can I help you explore Laravel packages today?