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

Address Bundle Laravel Package

padam87/address-bundle

Symfony bundle for managing postal addresses: address entities, forms, and country/region data with Doctrine integration, letting you store, validate, and reuse addresses across your app instead of rebuilding the same model each time.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is a small Symfony 2/3-era package: it ships an Address entity, a form type, and a geocoding hook that fills latitude/longitude from a text address. Treat it as a reference implementation rather than a maintained dependency — it has not been touched since 2016, so pin your Symfony version deliberately.

  1. Install with an explicit constraint. The default composer require padam87/address-bundle will resolve to the last tag (2016). Because there is no symfony/* upper bound you can trust, add it alongside your existing framework constraints and run composer why-not padam87/address-bundle if resolution fails. On Symfony 4+ you will likely need composer.json extra.symfony tweaks or a fork; on Symfony 2.8/3.x it installs cleanly.

  2. Register the bundle in app/AppKernel.php:

    new Padam87\AddressBundle\Padam87AddressBundle(),
    
  3. Configure the geocoder. The bundle's raison d'être is turning a postal address into coordinates. Look for a config block under padam87_address: in config.yml (or config/packages/padam87_address.yaml) for an API key / HTTP client service. If the shipped config expects a provider you no longer use (e.g. the old Google Maps v2 endpoint), override the geocoder service ID with your own implementation.

  4. Where to look first. Open the bundle's Entity/Address.php and Resources/config/services.yml. Those two files tell you everything: which fields exist (typically name, line1, line2, city, state, postalCode, country, latitude, longitude) and which service performs the geocode call.

  5. First use case. Add an Address to a User or Order via a OneToOne/ManyToOne relation, render the AddressType in your form, and call the geocoder on prePersist. A good smoke test: create an address, save it, and confirm latitude/longitude are populated. If they are not, the geocoder service is misconfigured — not the entity.

Implementation Patterns

  • Composition over inheritance. Attach addresses to your domain objects as a related entity ($order->setShippingAddress(new Address())) rather than extending the bundle's entity. This keeps your schema stable if you later swap the package out.

  • Doctrine embeddables. If you only need one address per entity, consider mapping Address as an @Embeddable and embedding it (@Embedded(class="...Address")). The bundle's entity is a plain POPO with no IDs, so this works — but you gain flat columns (shipping_city, shipping_lat, …) at the cost of nullability caveats (see Gotchas).

  • Form wiring. Inject Padam87\AddressBundle\Form\Type\AddressType (or whatever the bundle registers) into your parent form with ->add('address', AddressType::class). If you need to customize country choices, copy the type into your app rather than fighting its configureOptions; the bundle was not written with OptionsResolver extensibility in mind.

  • Geocode on a lifecycle event, not in the controller. Register a Doctrine prePersist/preUpdate listener that calls the geocoder only when the address text fields changed and coordinates are empty. This avoids paying for an API call on every write.

    public function prePersist(LifecycleEventArgs $args) {
        $entity = $args->getEntity();
        if ($entity instanceof Address && !$entity->getLatitude()) {
            $this->geocoder->geocode($entity);
        }
    }
    
  • Formatting for display. The entity's __toString() (or a small formatter service) joins the non-empty parts with commas. Add a Twig filter of your own (e.g. {{ order.shippingAddress|address_format }}) instead of relying on implicit casting, because blank lines leave awkward , , artifacts. A simple array_filter over getFormattedParts() and implode(', ') is usually cleaner than the shipped template.

  • Distance / proximity queries. With latitude/longitude populated, you can do a bounding-box or Haversine query directly in DQL:

    SELECT a, (6371 * ACOS(COS(RADIANS(:lat)) * COS(RADIANS(a.latitude))
         * COS(RADIANS(a.longitude) - RADIANS(:lng))
         + SIN(RADIANS(:lat)) * SIN(RADIANS(a.latitude)))) AS distance
    FROM AddressBundle:Address a
    HAVING distance < :radius
    ORDER BY distance
    

    This is where the bundle actually earns its keep — the coordinates are the value, not the entity.

  • Integration tips. Wrap the geocoder in your own GeocoderInterface adapter so tests can return fixed coordinates. The shipped service is almost certainly bound to a concrete HTTP client from 2016; a thin adapter layer is cheaper than patching the bundle.

Gotchas and Tips

  • It is unmaintained. Last release November 2016, 10 stars, zero known dependents. Do not assume Symfony 4/5/6 compatibility. Expect to fork ("repositories": [{"type": "vcs", "url": "..."}]) and replace the HTTP/geocoder layer. Budget an afternoon for this or pick a maintained alternative (e.g. willdurand/geocoder + your own entity).

  • Geocoder API drift. Google's Geocoding API has changed response shapes and key requirements since 2016. The bundle's parser may read keys that no longer exist. Verify in a REPL: $geocoder->geocode($address); dump($address->getLatitude()); before trusting production flows. Handle ZERO_RESULTS and OVER_QUERY_LIMIT explicitly — the shipped code tends to silently leave coordinates null.

  • Fail soft on geocoding. Never block a form submit because geocoding failed. Store null coordinates and let a background job retry. Add a geocodedAt timestamp column so you can find un-geocoded rows: WHERE a.latitude IS NULL AND a.geocodedAt IS NULL.

  • Doctrine embeddable nullability. If you embed the address, an entity with no address yields null columns, and Doctrine will hydrate a partially-initialized embeddable. Use nullable=true on every column and guard with a hasAddress() helper rather than null !== $entity->getAddress().

  • Country data is stale. Any country list baked into a 2016 bundle predates later ISO reassignments and naming changes. Replace it with symfony/intl's Countries::getNames() or a maintained list; keep the bundle's storage format (ISO 3166-1 alpha-2 is typical) so existing rows still resolve.

  • Debugging the geocoder. Set the HTTP client's logger to debug and log the raw response. Most failures are (a) billing not enabled on the API key, (b) an address the provider can't parse (PO boxes, new builds), or (c) a proxy intercepting the 2016-era endpoint URL. Log the request URL too — old endpoints are a frequent culprit.

  • Extension points are thin. The bundle exposes little via DI tags. Rather than decorating internal services (names are not part of any API contract), copy the 3–4 useful classes (Address, AddressType, the listener skeleton) into App\ and own them. At 10 stars and no releases in years, this is the pragmatic path — you keep the semantics without the abandoned dependency.

  • Testing. Never hit a live geocoder in tests. Bind a stub implementation returning fixed coordinates and assert that prePersist fills lat/lng only when appropriate. Test the formatting logic with addresses that have empty second lines and missing states — this is where the shipped __toString() breaks.

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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings