yipikai/geolocation-bundle
A PHP geolocation bundle that adds location-aware services and configuration to your application, providing a reusable way to integrate geographic data handling into Symfony-style projects.
Architecture fit — poor as a dependency, good as a pattern. The naming is the first red flag: this is a Symfony bundle, not a Laravel package. Symfony bundles register through a Bundle subclass and a DI container (XML/YAML/PHP config); Laravel has no equivalent extension mechanism, so composer require yipikai/geolocation-bundle will install code that Laravel's container never boots. The usable surface is almost certainly one small service that does GET https://api-adresse.data.gouv.fr/search/?q={address} and reads features[0].geometry.coordinates. We would be pulling in Symfony DI/HttpClient machinery to obtain what is realistically 50–150 lines of logic.
Integration feasibility — moderate, via porting rather than installing. Two paths: (a) wrap the bundle's service behind a Laravel service provider and bind it manually, which drags symfony/dependency-injection and symfony/http-client into a stack that already pins Symfony components via laravel/framework; or (b) vendor the logic into an app-owned BanGeocoder class using Laravel's Http facade, Cache, and config(). Path (b) is lower risk and cheaper. Because the package is MIT, forking is legally clean.
Technical risk — high concentration, low blast radius. Single maintainer, zero stars, zero dependents, one release (2024-07-24). There is no evidence of CI, a version-support matrix, security policy, or test coverage. The underlying data source is strong — the Base Adresse Nationale is the French government's authoritative address registry, free and open — but the package is a thin, unmaintained shim over it. Risk is not "this breaks production"; it is "we inherit an orphan and must own it from day one." Note the coverage boundary: BAN geocodes France only. Any international address silently fails or returns a wrong-confidence match.
Key questions:
api-adresse.data.gouv.fr (BAN) or the newer adresse.gouv.fr routing? Is the API version pinned, and what is the deprecation posture?score, type (housenumber/street/municipality), and citycode, or does it discard them and return bare lat/long? Without score/type we cannot set a confidence threshold or distinguish a rooftop hit from a commune centroid.null, exception, or silently wrong coordinates?composer.json constraints on php and symfony/*? Will they conflict with the Symfony components already locked by laravel/framework?geocoder-php with a BAN provider) that removes the Symfony coupling?Stack fit. Treat the package as a reference implementation, not a dependency. Target: Laravel 10/11, PHP 8.2+, an app-owned Geocoder contract with a BanGeocoder implementation using Http::timeout(2)->retry(2, 200), Cache::remember keyed on a normalized address hash, and a queued job for bulk backfills.
Migration path. Extract, don't adopt. Read the bundle's source, port the request/response handling, and discard the Symfony wiring. Keep the public contract narrow — geocode(string $address): ?Coordinates — so swapping to Mapbox, Google, or Nominatim later is a config change rather than a refactor. Add score/type to the returned value object from the start; retrofitting confidence data after the fact is painful.
Compatibility. If we do evaluate a direct install first, resolve composer why symfony/http-client and run composer update --dry-run in a scratch branch. Laravel already depends transitively on symfony/http-foundation, console, process, var-dumper, and error-handler; a bundle pinning older minor versions will either block the install or force unrelated upgrades. Budget half a day for this spike and expect it to fail.
Sequencing.
Geocoder contract + Coordinates value object (with score, type, label).BanGeocoder with HTTP, timeout, retry, and cache.type != housenumber results for manual review.Data-protection note, in our favour. Routing addresses to a French public-sector API is materially simpler under GDPR than sending them to Google or Mapbox — no DPA, no third-country transfer, no per-request billing. That is the strongest argument for BAN, and it survives the package being abandoned.
Maintenance. Assume full ownership. Zero stars and zero dependents means no community patch flow; if the maintainer disappears, we are the maintainer. If we fork, name it internally, assign a single owner, and pin the BAN API contract in a test that fails loudly if the response shape changes. Review cadence: quarterly is sufficient for a frozen, single-endpoint integration.
Support. No commercial support, no documentation beyond a README, no issue-tracker history to mine. The compensating factor is that the upstream documentation (BAN / adresse.data.gouv.fr) is genuinely good, in French, and stable. Our on-call runbook should point at the government API status page, not at the package.
Scaling. Geocoding is idempotent — an address resolves to the same point essentially forever. Cache aggressively (30–90 day TTL, address-hash key) and the external call volume collapses to near zero after warm-up. For bulk backfills, queue with a concurrency cap; BAN enforces fair-use rate limiting and will return 429 under load. A 100k-address backfill at a conservative 10 req/s is roughly three hours — plan it as a background job, not a request-path operation.
Failure modes.
null; the write path must degrade gracefully (store the address, leave coordinates pending, retry on a job) rather than blocking checkout or signup.score. Taking features[0] unconditionally, as thin wrappers typically do, silently maps "12 Rue de la Paix" to a street centroid instead of a rooftop. Enforce a score threshold and persist type.Ramp-up. Low for any PHP developer — a day to understand, an afternoon to port. The real learning curve is domain-side, not code-side: understanding BAN score, type, and citycode, and deciding what confidence level is acceptable for the business use case (billing address vs. delivery routing vs. analytics have very different tolerances).
Verdict. Do not take a runtime dependency on this package — the Symfony/Laravel impedance mismatch and the orphan-project risk both point the same direction. Do take the idea: a small, cached, contract-isolated client over the French national address API, owned in-house, with a paid fallback for non-French addresses. That is roughly two days of work and removes the only real liability here.
How can I help you explore Laravel packages today?