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 Algeria Laravel Package

djouamaah/laravel-algeria

Laravel package for Algeria: ships wilayas and communes data with models, migrations, seeders, and helpers so you can add Algerian regions, postal codes, and location dropdowns to your app quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require djouamaah/laravel-algeria
php artisan vendor:publish --tag="algeria-config"   # optional but recommended
php artisan migrate
php artisan algeria:seed

The package ships migrations for wilayas and communes tables (1,541 communes), a seeder command, an Algeria facade/helper, and an Commune Eloquent model. Look first at:

  1. config/algeria.php — table names, route prefix, and any toggles for the API route.
  2. Djouemaaah\LaravelAlgeria\Models\Commune — your primary relationship target (wilaya(), latitude, longitude, plus the new distanceTo()).
  3. routes/ inside the package — the new GET /api/algeria/communes/nearest endpoint.

First use case: an address/delivery form. Seed once, then populate a wilaya → commune cascade from the DB, and store commune_id on your addresses/orders table. You now have coordinates for free, which means distance-based delivery pricing without a geocoding bill:

$commune = Commune::where('name', 'Bab Ezzouar')->firstOrFail();
$km = $commune->distanceTo($order->latitude, $order->longitude);

Implementation Patterns

Cascade selects (the 80% use case). Don't hardcode wilaya/commune lists in Blade. Query Wilaya::with('communes')->get() once, cache it, and drive a dependent <select> from that payload. If you need it on every page, cache the whole tree (Cache::remember('algeria.tree', now()->addDay(), ...)) — it's ~1.5k rows and changes only when the package is updated.

Find-my-commune from coordinates. The new Algeria::nearest($lat, $lng, $limit) returns the closest communes; use it to reverse-resolve a GPS pin to a commune. Two flavours:

  • Server-side: after a browser geolocation POST, call Algeria::nearest() and preselect the commune in the form.
  • Client-side/JS: proxy the package route /api/algeria/communes/nearest?lat=&lng=&limit= (respect its configured prefix) rather than exposing your own controller.

Distance for pricing/validation. Keep it inside your domain service, not your controllers:

$distance = Algeria::distance($originLat, $originLng, $destLat, $destLng); // km
$fee = $this->bracket($distance);

For "is this deliverable?" checks, prefer Commune::distanceTo() on the stored commune over re-geocoding the address text — the package's coordinates are curated and cross-checked, your geocoder's aren't.

Guard against nullable coordinates. Coordinates arrive via the seeder, not the migration. Wrap reverse-geocoding in a fallback: if the commune has no latitude/longitude, degrade to the wilaya centre or skip the distance calculation entirely. Never assume the columns are populated.

Store the FK, not the string. Even with coordinates available, persist commune_id and resolve names via the model. Labels change; IDs are stable across seed runs. Keep a commune_name snapshot column if you need historical invoices to read correctly.

Integration tip: keep the package's tables read-only. Treat wilayas/communes as reference data. Put user-editable addresses in your own table with a commune_id FK; this makes php artisan algeria:seed a safe, idempotent operation you can run in CI and on deploy.

Gotchas and Tips

migrate alone is not enough. v1.2.0's migration only adds latitude/longitude. The values come from php artisan algeria:seed. If you pull the release, migrate, and skip the seed, every coordinate is null and nearest() returns nothing useful — a confusing "the feature doesn't work" bug rather than an error.

Upgrade order matters. composer update → php artisan migrate → php artisan algeria:seed, exactly as documented. Running the seeder before the migration fails on the missing columns. In production pipelines, gate the seed behind the same deploy step as the migration, and make sure the seeder is idempotent/upsert-based before re-running it against live data (verify against a staging copy the first time).

Seeding can be slow. 1,541 rows with a full dataset is a batch job, not a request-cycle operation. Use --quiet in deploy scripts, and if you're on a constrained host consider wrapping the seed in a transaction or chunking it. Avoid running it in a per-test setUp() — seed once into a test fixture instead.

Existing rows survive, but check foreign keys. Re-seeding typically truncates/upserts communes; if you wired your own FKs to communes.id and IDs shift, your references break. Prefer matching on a stable natural key (code/postal code if exposed) when you link your tables, or confirm the seeder preserves primary keys before running it on data you care about. Test this explicitly — it's the highest-risk part of the upgrade.

Route registration. The new /api/algeria/communes/nearest route is registered by the package's service provider. If you use shouldRenderJsonWhen/route caching (php artisan route:cache), re-run the cache clear after upgrading or the route won't appear. Also check whether the route needs to be explicitly enabled in config/algeria.php, and whether it's web or api middleware — if it inherits web, add CSRF/RateLimiter consideration before hitting it from JS.

No auth on the package route. It's a public read endpoint; add throttling at the proxy/edge if you don't want anonymous clients hammering nearest-neighbour queries.

Precision expectations. nearest() is a distance sort over point coordinates — it's not a polygon/routing lookup, so a pin near a commune boundary may resolve to the "wrong" commune (the centroid is closer). Don't present it as authoritative for legal jurisdiction; treat it as a helpful default the user can override.

Debugging tips. If distances look absurd, check for swapped lat/lng (Algeria is roughly lat 19–37, lng −8–12) and for degrees-vs-kilometres confusion in distance(). Verify units in a Tinker session against a known pair (e.g. Algiers ↔ Oran ≈ 400 km) before shipping pricing logic. Use DB::listen() or dd(Algeria::nearest(...)) to see exactly what a failed lookup returns ([] vs null vs an empty Collection) and code your fallback against the actual return type.

Extension points. Publish the config to move the API prefix or disable the route; bind your own service around Algeria::distance() if you later swap in a routing provider. Keep the third-party provenance in THIRD-PARTY-NOTICES.md intact if you redistribute the dataset (it aggregates Wikidata, kossa/algerian-cities, and geoalgeria) — worth a line in your own legal/attribution docs, since data-licence obligations flow through to you.

Pin your version. Because correctness of the dataset improves release-to-release (manual corrections in this one), pin the package in composer.json and treat upgrades as data migrations with a review step rather than silent patch bumps.

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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib