ferdirn/laravel-id-countries
Laravel package to create and seed a countries table with global country data: name, ISO code, capital, currency, and calling code. Includes artisan commands to generate migrations and a seeder for quick setup in your app.
Installation:
composer require ferdirn/laravel-id-countries
Add the service provider and facade to config/app.php:
'providers' => [
Ferdirn\Countries\CountriesServiceProvider::class,
],
'aliases' => [
'Countries' => Ferdirn\Countries\CountriesFacade::class,
],
Publish Config (Optional):
php artisan vendor:publish --provider="Ferdirn\Countries\CountriesServiceProvider"
(Only if you need to customize the default countries table name.)
Run Migrations:
php artisan migrate
The package creates a countries table with columns: id, name, iso_code, capital, currency, calling_code.
First Use Case: Fetch all countries in a controller or blade view:
use Countries;
$countries = Countries::all();
return view('countries.index', compact('countries'));
Fetching Countries:
$countries = Countries::all(); // Collection of Country models
$country = Countries::where('iso_code', 'US')->first();
$countries = Countries::where('name', 'like', '%United%')->get();
Integration with Eloquent Models:
Use polymorphic relationships or foreign keys to link countries to other models (e.g., users table):
// In User model
public function country()
{
return $this->belongsTo(Country::class);
}
Query users by country:
$usersInUs = User::whereHas('country', function($query) {
$query->where('iso_code', 'US');
})->get();
Blade Views: Render a dropdown of countries:
<select name="country_id">
@foreach(Countries::all() as $country)
<option value="{{ $country->id }}">{{ $country->name }} ({{ $country->iso_code }})</option>
@endforeach
</select>
API Responses: Return countries as JSON in a controller:
return Countries::select('id', 'name', 'iso_code')->get();
Caching:
Cache the countries list to reduce database queries (e.g., in AppServiceProvider):
public function boot()
{
Cache::remember('countries', now()->addHours(1), function() {
return Countries::all();
});
}
Table Name Assumption:
countries table. If you rename it via config, ensure migrations and queries reflect this change.config/countries.php (if published) or check the migration file.Missing Facade Alias:
'Countries' => 'Ferdirn\Countries\CountriesFacade') will throw Class not found errors.config/app.php after installation.Case Sensitivity in ISO Codes:
US, us) are case-sensitive in queries. Use strtoupper() for consistency:
$country = Countries::where('iso_code', strtoupper('us'))->first();
Migration Conflicts:
countries table already exists, the migration may fail. The package does not handle this gracefully.php artisan migrate.Data Updates:
spatie/laravel-data-import to manually update records.Check Published Config:
If the package behaves unexpectedly, verify config/countries.php exists and matches your expectations:
php artisan config:clear
Query Logging: Enable Laravel's query log to debug slow or failing queries:
DB::enableQueryLog();
$countries = Countries::all();
dd(DB::getQueryLog());
Model Binding Issues:
If Countries::find($id) returns null, ensure:
id column is auto-incrementing and primary in the countries table.Country model is properly namespaced (e.g., Ferdirn\Countries\Models\Country).Custom Fields:
Extend the Country model to add custom fields (e.g., region, population):
// In Country model
protected $fillable = ['name', 'iso_code', 'capital', 'currency', 'calling_code', 'region'];
Update the migration and seeder accordingly.
Localization: Add translated country names using Laravel's localization features:
// In Country model
public function getNameAttribute($value)
{
return trans('countries.' . $this->iso_code);
}
Define translations in resources/lang/{locale}/countries.php.
API Integration: Sync country data with an external API (e.g., REST Countries):
// Example seeder
public function run()
{
$response = Http::get('https://restcountries.com/v3.1/all');
foreach ($response->json() as $country) {
Country::updateOrCreate(
['iso_code' => $country['cca2']],
[
'name' => $country['name']['common'],
'capital' => $country['capital'][0] ?? null,
'currency' => $country['currencies'][0]['name'] ?? null,
'calling_code' => $country['idd']['root'] . $country['idd']['suffixes'][0] ?? null,
]
);
}
}
Validation Rules: Create custom validation rules for country-related fields:
use Illuminate\Validation\Rule;
$validated = request()->validate([
'country_iso_code' => [
'required',
Rule::exists('countries', 'iso_code'),
],
]);
Scopes:
Add reusable query scopes to the Country model:
// In Country model
public function scopeByRegion($query, $region)
{
return $query->where('region', $region);
}
Usage:
$europeanCountries = Countries::byRegion('Europe')->get();
How can I help you explore Laravel packages today?