zaidysf / idn-area
Indonesian administrative area data package for Laravel (Provinces, Regencies, Districts, Villages, and Islands)
Requires
- php: ^8.0
- illuminate/contracts: ^8.0|^9.0|^10.0|^11.0|^12.0
- spatie/laravel-package-tools: ^1.9.2|^1.13.0|^1.14.0|^1.15.0|^1.16.0
Requires (Dev)
- larastan/larastan: ^1.0|^2.0|^3.0
- laravel/pint: ^1.0
- nunomaduro/collision: ^5.0|^6.0|^7.0|^8.0
- orchestra/testbench: ^6.0|^7.0|^8.0|^9.0|^10.0
- pestphp/pest: ^1.21|^2.0|^3.0
- pestphp/pest-plugin-arch: ^1.0|^2.0|^3.0
- pestphp/pest-plugin-laravel: ^1.1|^2.0|^3.0
- phpstan/extension-installer: ^1.1|^1.3
- phpstan/phpstan-deprecation-rules: ^1.0|^1.1
- phpstan/phpstan-phpunit: ^1.0|^1.3
This package is auto-updated.
Last update: 2025-06-12 09:10:38 UTC
README
A comprehensive Laravel package providing complete Indonesian administrative area data including provinces, regencies, districts, villages, and islands. Fully compatible with Laravel 8 through Laravel 12 and PHP 8.0+.
โจ Features
- ๐๏ธ Complete Administrative Hierarchy - Province โ Regency โ District โ Village
- ๐๏ธ Islands Database - Including outermost small islands and populated status
- ๐ Eloquent Models - With proper relationships and type hints
- ๐ Search Functionality - Across all area types with flexible queries
- โก Artisan Commands - Easy data seeding and management
- ๐ Laravel 8-12 Support - Full compatibility across all modern Laravel versions
- ๐ Foreign Key Constraints - Ensuring data integrity
- ๐งช Model Factories - For comprehensive testing
- โ๏ธ Configurable - Customizable through config file
- ๐ PHPStan Level 6 - Strict type safety and static analysis
๐ Compatibility Matrix
Laravel Version | PHP Version | Status |
---|---|---|
Laravel 8.x | PHP 8.0, 8.1, 8.2 | โ Fully Supported |
Laravel 9.x | PHP 8.0, 8.1, 8.2, 8.3 | โ Fully Supported |
Laravel 10.x | PHP 8.1, 8.2, 8.3, 8.4 | โ Fully Supported |
Laravel 11.x | PHP 8.2, 8.3, 8.4 | โ Fully Supported |
Laravel 12.x | PHP 8.2, 8.3, 8.4 | โ Fully Supported |
๐ Quick Start
Installation
Install the package via Composer:
composer require zaidysf/idn-area
Setup
Publish and run the migrations:
php artisan vendor:publish --tag="idn-area-migrations"
php artisan migrate
Seed Data
Populate your database with Indonesian area data:
php artisan idn-area:seed
Start Using
use zaidysf\IdnArea\Facades\IdnArea; // Get all provinces $provinces = IdnArea::provinces(); // Search for areas $results = IdnArea::search('Jakarta'); // Get statistics $stats = IdnArea::statistics();
๐ Detailed Installation
If you need more detailed setup options:
Install Package
composer require zaidysf/idn-area
Publish Migrations
php artisan vendor:publish --tag="idn-area-migrations"
php artisan migrate
Optional: Publish Config
Optionally, you can publish the config file for customization:
php artisan vendor:publish --tag="idn-area-config"
Data Seeding
Seed the Indonesian area data using the provided Artisan command:
php artisan idn-area:seed
To force reseed (clear existing data and reseed):
php artisan idn-area:seed --force
Usage
Using the Facade
use zaidysf\IdnArea\Facades\IdnArea; // Get all provinces $provinces = IdnArea::provinces(); // Get specific province $province = IdnArea::province('32'); // West Java // Get regencies by province $regencies = IdnArea::regenciesByProvince('32'); // Get districts by regency $districts = IdnArea::districtsByRegency('32.04'); // Bandung // Get villages by district $villages = IdnArea::villagesByDistrict('32.04.01'); // Sukasari // Get islands by regency $islands = IdnArea::islandsByRegency('32.04'); // Search across all area types $results = IdnArea::search('Jakarta'); // Get area statistics $stats = IdnArea::statistics();
Using Models Directly
use zaidysf\IdnArea\Models\Province; use zaidysf\IdnArea\Models\Regency; use zaidysf\IdnArea\Models\District; use zaidysf\IdnArea\Models\Village; use zaidysf\IdnArea\Models\Island; // Get province with relationships $province = Province::with(['regencies.districts.villages'])->find('32'); // Get regency with province $regency = Regency::with('province')->find('32.04'); // Search for villages $villages = Village::where('name', 'like', '%Sukamaju%')->get(); // Get populated islands only $populatedIslands = Island::populated()->get(); // Get outermost small islands $outermostIslands = Island::outermostSmall()->get();
Model Relationships
// Province relationships $province = Province::find('32'); $regencies = $province->regencies; $districts = $province->districts; // Regency relationships $regency = Regency::find('32.04'); $province = $regency->province; $districts = $regency->districts; $villages = $regency->villages; $islands = $regency->islands; // District relationships $district = District::find('32.04.01'); $regency = $district->regency; $province = $district->province(); $villages = $district->villages; // Village relationships $village = Village::find('32.04.01.2001'); $district = $village->district; $regency = $village->regency(); $province = $village->province(); // Island relationships $island = Island::find(1); $regency = $island->regency; $province = $island->province();
Using Model Factories (for Testing)
// Create test data using factories $province = Province::factory()->jakarta()->create(); $regency = Regency::factory()->forProvince('32')->create(); $district = District::factory()->forRegency('32.04')->create(); $village = Village::factory()->forDistrict('32.04.01')->create(); // Create islands with specific attributes $populatedIsland = Island::factory()->populated()->create(); $outermostIsland = Island::factory()->outermostSmall()->create();
Data Structure
Provinces
code
: 2-digit province codename
: Province name
Regencies
code
: 5-character regency code (XX.YY format)province_code
: Reference to provincename
: Regency name
Districts
code
: 8-character district code (XX.YY.ZZ format)regency_code
: Reference to regencyname
: District name
Villages
code
: 13-character village code (XX.YY.ZZ.AAAA format)district_code
: Reference to districtname
: Village name
Islands
id
: Auto-increment IDcode
: Island code (optional)coordinate
: Geographic coordinates (optional)name
: Island nameis_outermost_small
: Boolean flag for outermost small islandsis_populated
: Boolean flag for populated statusregency_code
: Reference to regency (optional)
Configuration
The config file allows you to customize various aspects:
return [ 'table_prefix' => 'idn_', 'enable_foreign_keys' => true, 'search' => [ 'village_limit' => 100, 'case_sensitive' => false, ], 'models' => [ 'province' => \zaidysf\IdnArea\Models\Province::class, 'regency' => \zaidysf\IdnArea\Models\Regency::class, 'district' => \zaidysf\IdnArea\Models\District::class, 'village' => \zaidysf\IdnArea\Models\Village::class, 'island' => \zaidysf\IdnArea\Models\Island::class, ], ];
๐ Data Overview
The package includes comprehensive Indonesian administrative data:
- ๐๏ธ 34 Provinces - All Indonesian provinces
- ๐ข 514 Regencies/Cities - Complete regency and city data
- ๐๏ธ 7,230+ Districts - All districts nationwide
- ๐ก 83,931 Villages - Complete village database
- ๐๏ธ 17,508 Islands - Including inhabited and outermost islands
Data Quality
- โ Government Sourced - Official data from Indonesian government databases
- โ Regularly Updated - Maintained for accuracy and completeness
- โ Validated Structure - Foreign key constraints ensure data integrity
- โ PHPStan Level 6 - Strict type safety and comprehensive static analysis
๐งช Testing
# Run all tests composer test # Run tests with coverage composer test-coverage # Run PHPStan analysis composer analyse # Fix code style composer format # Run specific test file vendor/bin/pest tests/IdnAreaTest.php # Run architecture tests vendor/bin/pest tests/ArchTest.php
For detailed testing instructions, see TESTING.md.
๐ API Usage Example
For complete API controller examples, see examples/IdnAreaController.php.
Route::prefix('api/idn-area')->group(function () { Route::get('provinces', [IdnAreaController::class, 'provinces']); Route::get('provinces/{provinceCode}/regencies', [IdnAreaController::class, 'regencies']); Route::get('regencies/{regencyCode}/districts', [IdnAreaController::class, 'districts']); Route::get('districts/{districtCode}/villages', [IdnAreaController::class, 'villages']); Route::get('search', [IdnAreaController::class, 'search']); Route::get('statistics', [IdnAreaController::class, 'statistics']); });
๐ Performance Tips
Optimize Queries
// Use eager loading for relationships $provinces = Province::with(['regencies.districts'])->get(); // Limit village searches for performance $villages = Village::where('name', 'like', '%Jakarta%')->limit(100)->get(); // Use specific selects for large datasets $regencies = Regency::select('code', 'name')->where('province_code', '32')->get();
Caching Recommendations
// Cache frequently accessed data $provinces = Cache::remember('idn_provinces', 3600, function () { return Province::all(); }); // Cache search results $searchResults = Cache::remember("search_{$query}", 1800, function () use ($query) { return IdnArea::search($query); });
๐ Changelog
Please see CHANGELOG for more information on what has changed recently.
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request. Here's how you can contribute:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Make your changes and add tests
- Run the test suite:
composer test
- Run static analysis:
composer analyse
- Fix code style:
composer format
- Commit your changes:
git commit -m 'Add amazing feature'
- Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
Development Setup
# Clone the repository git clone https://github.com/zaidysf/idn-area.git cd idn-area # Install dependencies composer install # Run tests composer test # Run static analysis composer analyse
๐ Security Vulnerabilities
If you discover a security vulnerability within this package, please send an e-mail to Zaid Yasyaf via zaid.ug@gmail.com. All security vulnerabilities will be promptly addressed.
Please review our security policy for more information on how to report security vulnerabilities.
๐ License
The MIT License (MIT). Please see License File for more information.
๐ Credits
- Zaid Yasyaf - Package Author
- Indonesian Area Data - Data source for Indonesian administrative areas
- All Contributors - Community contributors
Made with โค๏ธ in Indonesia