Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Algereography Laravel Package

thehocinesaad/laravel-algereography

Laravel package that ships Algeria's administrative geography out of the box: wilayas, dairas, and communes with ready-made migrations, Eloquent models, seeders, and relationships, so you can add reliable location data to your app quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish

composer require thehocinesaad/laravel-algereography
php artisan vendor:publish --provider="Thehocinesaad\AlgeriaGeography\AlgeriaGeographyServiceProvider"

The provider publishes up to three asset groups — migrations, seeders, and (usually) a config file. Publish selectively so you can inspect before running:

php artisan vendor:publish --tag=algereography-migrations
php artisan vendor:publish --tag=algereography-seeders

Check vendor/thehocinesaad/laravel-algereography/src/ for the actual tag names and namespace before wiring anything — this package is small enough that reading the source is faster than guessing.

First run

php artisan migrate
php artisan db:seed --class=WilayaSeeder
php artisan db:seed --class=DairaSeeder

Order matters: Dairas carry a wilaya_id foreign key, so WilayaSeeder must run first.

First use case

A two-level address form. On a registration or checkout page, render a Wilaya <select> from Wilaya::orderBy('code')->get(), then load Dairas for the chosen Wilaya via a small JSON endpoint. That's 90% of what this package is used for in real projects — the package is a data seed, not a UI library, so the form logic is yours.

Verify the install before building anything: Wilaya::count() should return 58, not 48. Algeria reorganized from 48 to 58 wilayas in 2019; anything returning 48 is stale data and you should stop and check the seeder contents.

Implementation Patterns

Adding the FK to your own tables

Match the package's column type exactly. If the package uses unsignedTinyInteger for wilaya_id, your FK column must be unsignedTinyInteger too — a mismatch produces a cryptic errno: 150 on migrate.

Schema::create('addresses', function (Blueprint $table) {
    $table->id();
    $table->unsignedTinyInteger('wilaya_id');
    $table->unsignedSmallInteger('daira_id')->nullable();
    $table->string('street');
    $table->timestamps();

    $table->foreign('wilaya_id')->references('id')->on('wilayas');
    $table->foreign('daira_id')->references('id')->on('dairas');
});

Use restrictOnDelete() on the wilaya FK. Cascading a user address because someone re-ran a geography seeder is a bad day.

Cascading dropdown endpoint

Route::get('/wilayas/{wilaya}/dairas', fn (Wilaya $wilaya) =>
    Daira::where('wilaya_id', $wilaya->id)->orderBy('name')->get(['id', 'name'])
);

Wrap the response in a JsonResource if you already have an API layer; the payload is tiny and rarely changes, so also consider caching per-wilaya with Cache::rememberForever("dairas.{$wilaya->id}", ...).

Validation

'daira_id' => [
    'required',
    Rule::exists('dairas', 'id')->where('wilaya_id', $request->wilaya_id),
],

The where clause is the important part — it prevents a client from submitting a Daira from a different Wilaya, which is a real bug class in these forms.

Seeding in deploy pipelines

Geography data is reference data, not user data. Do not put it in DatabaseSeeder where migrate:fresh --seed will run it locally every time and slow down your test suite. Instead:

  • Create a dedicated GeographySeeder that is idempotent (updateOrCreate keyed on code, or guard with if (Wilaya::count() > 0) return;).
  • Run it once post-deploy: php artisan db:seed --class=GeographySeeder --force.
  • Commit the published migrations and seeders into your repo so deploys don't depend on the vendor directory layout staying stable.

Testing

RefreshDatabase plus the full seeder in every test is slow (58 + ~550 rows). Seed once per test suite using a setUpTraits hook or a Pest beforeAll, or stub a handful of rows in the test that actually needs them.

Reporting / filtering

Joining users to wilayas for a dashboard is fine but note the table is small — a with('wilaya') eager load is cheaper than a join for list views. For aggregate reports, join and group by wilayas.code, and remember wilaya code (the official 1–58 numbering) is the stable identifier for external reporting, not the autoincrement id.

Extending the models

If you need HasMany relations from your User model, don't modify vendor code. Either add the relations on your side ($user->addresses()->with('wilaya')) or extend the package model in app/Models/Wilaya.php and bind your subclass via the config file if it exposes a model mapping.

Gotchas and Tips

  • Verify 58, not 48. The 2019 reorganization created 10 new wilayas. If the seeder ships 48, the data predates the current administrative map and you need a patch or a fork. Check Wilaya::count() immediately after install.
  • Dairas ≠ communes (baladiyas). Algeria has ~1,541 communes. This package provides Wilayas and Dairas only. If your form needs commune-level granularity, this package covers one of the three levels and you'll need the commune list elsewhere.
  • Code drift after 2019. New wilayas and boundary changes mean some open-source Algerian geography datasets disagree on Daira counts (~548 vs ~553). Pin the package version in composer.json and don't assume counts match whatever source your business team quotes.
  • Seeder duplication. Many small geography packages use raw insert() in their seeders. Running the seeder twice creates duplicate rows or fails on unique constraints. Confirm whether it uses truncate(), updateOrCreate, or nothing, and wrap it in your own idempotent wrapper before running in production.
  • Migration auto-loading. If the provider calls loadMigrationsFrom(), publishing the migrations first and then running migrate can create duplicate or conflicting schema definitions. Read the provider. If migrations auto-load, do not publish them.
  • FK type mismatch. The package's wilaya_id may be unsignedTinyInteger (58 values fit in 1 byte) while your own tables default to unsignedBigInteger. Mismatched FK types are the #1 cause of errno: 150 with this kind of package.
  • Truncating breaks references. Never migrate:fresh or truncate geography tables in production once user data references them. If wilaya IDs are autoincrement and not derived from code, a reseed can renumber everything and silently corrupt addresses.
  • id vs code. Use code for anything external (reports, exports, third-party APIs). Use id only internally. They may coincidentally be equal on a fresh seed but that's an implementation detail, not a contract.
  • Arabic names and charset. If name columns store Arabic, confirm the table and connection use utf8mb4 / utf8mb4_unicode_ci. Default utf8 will mangle some characters.
  • No localization layer. The package ships names as stored — likely a mix of Arabic and French transliteration. There's no name_en, no translation files. Add an accessor or a small lookup table keyed on code if you need consistent English display.
  • Cache invalidation. If you cache the wilaya list with rememberForever, remember to Cache::forget() it after any deploy that reseeds geography, or stale lists will linger past the data change.
  • Stale package, newer Laravel. Last release was Feb 2023. On Laravel 11/12 you may hit an illuminate/support constraint conflict. Try composer require thehocinesaad/laravel-algereography --with-all-dependencies; if it still fails, either fork and bump the constraint in composer.json or copy the migrations and seeder files directly into your project and drop the dependency — for a package that is fundamentally a data seed, vendoring the files is a legitimate and often preferable exit strategy.
  • Namespace discovery. Package model classes are likely namespaced Thehocinesaad\AlgeriaGeography\Models\... — but verify in the source rather than trusting the README. A wrong use statement produces a confusing "class not found" that looks like an install failure.
  • Table name collisions. If you already have a wilayas or dairas table in your schema, the published migration will fail. Check the config for table-name overrides or rename your existing tables before installing.
  • No factories, no policies, no routes. This package is a schema + seed delivery vehicle. Everything above the data layer — controllers, resources, validation, UI — is yours to write, and the assessment should budget for that.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings