Weave Code
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

Addressable Bundle Laravel Package

daa/addressable-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require daa/addressable-bundle
    

    Register it in config/bundles.php (Symfony 5/6):

    Addressable\Bundle\AddressableBundle::class => ['all' => true],
    

    For Symfony 2/3, add it to AppKernel.php.

  2. Configure Twig Include the form theme in config/packages/twig.yml (Symfony 5/6):

    twig:
        form_themes:
            - '@Addressable/Form/fields.html.twig'
    

    For Symfony 2/3, add it to config.yml under twig.form_themes.

  3. First Use Case: Making an Entity Addressable Annotate your entity with Addressable\Bundle\AddressableBundle\Annotation\Addressable:

    use Addressable\Bundle\AddressableBundle\Annotation\Addressable;
    
    /**
     * @Addressable
     */
    class Restaurant
    {
        // ...
    }
    

    Add latitude and longitude fields to your entity:

    /**
     * @ORM\Column(type="decimal", scale=10, precision=13)
     */
    private $latitude;
    
    /**
     * @ORM\Column(type="decimal", scale=10, precision=13)
     */
    private $longitude;
    
  4. Generate Addressable Fields Run the bundle’s command to scaffold the address fields:

    php bin/console addressable:generate
    

    This creates a Address entity (or uses an existing one) and updates your entity with address-related fields.


Implementation Patterns

Common Workflows

1. Address Form Integration

Use the Google Maps form type to let users search for addresses interactively:

{{ form_row(form.address) }}

This renders a searchable Google Maps input. The bundle handles conversion between addresses and lat/lng.

2. Geo-Spatial Queries

Leverage the GeoSpatialService to filter/sort entities by distance or location:

use Addressable\Bundle\AddressableBundle\Service\GeoSpatialService;

class RestaurantController
{
    public function __construct(private GeoSpatialService $geoSpatial)
    {
    }

    public function nearbyRestaurants(Request $request)
    {
        $latitude = $request->query->get('lat');
        $longitude = $request->query->get('lng');
        $radius = $request->query->get('radius', 10); // km

        $restaurants = $this->geoSpatial->findNearby(
            Restaurant::class,
            $latitude,
            $longitude,
            $radius
        );

        return $this->render('restaurants/index.html.twig', [
            'restaurants' => $restaurants,
        ]);
    }
}

3. Distance Calculations

Calculate distances between two addressable entities:

$distance = $this->geoSpatial->distance(
    $entity1,
    $entity2
); // Returns distance in kilometers

4. Sorting by Proximity

Sort a collection of entities by their distance to a given point:

$sortedRestaurants = $this->geoSpatial->sortByDistance(
    $restaurants,
    $latitude,
    $longitude
);

Integration Tips

Entity Configuration

  • Custom Address Entity: If you don’t want to use the default Address entity, configure a custom one in config/packages/addressable.yml:
    addressable:
        address_entity: App\Entity\CustomAddress
    
  • Field Mapping: Override default field names (e.g., lat/lng) in your entity annotations:
    /**
     * @Addressable(latitudeField="custom_lat", longitudeField="custom_lng")
     */
    class Event {}
    

Form Customization

  • Extend the Google Maps form theme (@Addressable/Form/fields.html.twig) to add custom behavior (e.g., default markers, API keys).
  • Pass options to the form type:
    $form = $this->createFormBuilder($entity)
        ->add('address', AddressType::class, [
            'google_maps_api_key' => 'YOUR_API_KEY',
            'default_lat' => 40.7128,
            'default_lng' => -74.0060,
        ])
        ->getForm();
    

Doctrine Integration

  • Ensure your latitude/longitude fields are indexed for performance:
    /**
     * @ORM\Column(type="decimal", scale=10, precision=13)
     * @ORM\Index(columns={"latitude", "longitude"})
     */
     private $latitude;
    

Gotchas and Tips

Pitfalls

  1. Outdated Dependencies

    • The bundle was last updated in 2018 and targets Symfony 2/3/5/6. Test thoroughly in newer Symfony versions (e.g., Doctrine 2.10+ may require adjustments).
    • Workaround: Fork the repo and update dependencies (e.g., symfony/form, doctrine/orm) if needed.
  2. Google Maps API Key

    • The Google Maps form type requires an API key. Without it, the form will fail silently or show errors.
    • Fix: Configure the key in the form type options or set it globally in config/packages/addressable.yml:
      addressable:
          google_maps_api_key: 'YOUR_KEY'
      
  3. Precision Issues

    • Latitude/longitude fields are stored as decimal(13,10). Ensure your database supports this precision (e.g., MySQL’s DECIMAL type).
    • Tip: Use scale=10 and precision=13 to avoid rounding errors during calculations.
  4. Doctrine DQL Limitations

    • The GeoSpatialService uses raw SQL for distance calculations (e.g., Haversine formula). Complex queries may hit performance limits.
    • Tip: Cache frequent queries or use a dedicated spatial database (e.g., PostgreSQL with PostGIS) for large datasets.
  5. Entity Generation Overwrite

    • Running addressable:generate again may overwrite your entity’s address fields. Backup or use --dry-run to preview changes.

Debugging

  1. Form Not Rendering

    • Check if form_themes is correctly configured in Twig. Clear the cache if needed:
      php bin/console cache:clear
      
    • Verify the Google Maps API key is valid and not restricted.
  2. Distance Calculations Returning null

    • Ensure latitude/longitude fields are populated and valid (e.g., -90 <= lat <= 90, -180 <= lng <= 180).
    • Debug the raw SQL generated by the GeoSpatialService:
      $query = $this->geoSpatial->createNearbyQuery(...);
      dump($query->getSQL());
      
  3. Performance Issues

    • Add indexes to latitude/longitude fields if queries are slow.
    • For large datasets, consider denormalizing distances or using a spatial index (e.g., PostgreSQL’s GIS functions).

Tips

  1. Extend the Address Entity Add custom fields to the Address entity (e.g., formattedAddress, country) to store additional data from the Google Maps API:

    /**
     * @ORM\Column(type="text", nullable=true)
     */
    private $formattedAddress;
    
  2. Custom Distance Units Modify the GeoSpatialService to return distances in miles instead of kilometers by overriding the distance method or creating a decorator.

  3. Validation Add validation constraints to latitude/longitude:

    use Symfony\Component\Validator\Constraints as Assert;
    
    /**
     * @Assert\Type("numeric")
     * @Assert\GreaterThanOrEqual(-90)
     * @Assert\LessThanOrEqual(90)
     */
    private $latitude;
    
  4. Testing Mock the GeoSpatialService in tests to avoid external dependencies:

    $geoSpatial = $this->createMock(GeoSpatialService::class);
    $geoSpatial->method('distance')->willReturn(1.5);
    $this->entityManager->getRepository(Restaurant::class)->setGeoSpatial($geoSpatial);
    
  5. Fallback for Offline Use Provide a fallback mechanism (e.g., static lat/lng) when the Google Maps API is unavailable:

    {% if form.address.vars.data.google_maps_error %}
        <p>Google Maps unavailable. Using default location.</p>
    {% endif %}
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky