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

Geoname Bundle Laravel Package

brawcks/geoname-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require bordeux/geoname-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Bordeux\GeonameBundle\BordeuxGeonameBundle::class => ['all' => true],
    ];
    
  2. Configuration Create a config/packages/bordeux_geoname.yaml:

    bordeux_geoname:
        api_key: 'your_geonames_api_key'  # Get from https://www.geonames.org/login
        cache_dir: '%kernel.cache_dir%/geoname'
        import:
            countries: true
            states: true
            cities: true
    
  3. First Use Case Fetch a country by ISO code:

    use Bordeux\GeonameBundle\Entity\Country;
    
    $country = $this->getDoctrine()
        ->getRepository(Country::class)
        ->findOneBy(['isoCode' => 'US']);
    

Implementation Patterns

Data Import Workflow

  1. One-Time Setup Use the CLI command to import data (run once):

    php bin/console bordeux:geoname:import
    
    • Supports incremental updates via --update flag.
  2. Lazy Loading For large datasets, configure Doctrine to lazy-load:

    # config/packages/doctrine.yaml
    orm:
        dql:
            string_functions:
                GEONAME_DISTANCE: Bordeux\GeonameBundle\DQL\GeonameDistance
    
  3. Integration with Forms Use the bundle’s entities in Symfony forms:

    use Bordeux\GeonameBundle\Form\Type\CountryType;
    
    $builder->add('country', CountryType::class, [
        'label' => 'Select Country',
        'required' => true,
    ]);
    

Common Use Cases

  • Geocoding: Resolve city/state/country from coordinates.
    $geonameService = $this->get('bordeux_geoname.service');
    $location = $geonameService->findNearbyPlace(52.5200, 13.4050, 10); // Berlin, radius=10km
    
  • Validation: Ensure user input matches GeoNames data.
    $validator = $this->get('validator');
    $errors = $validator->validate($userInput, [
        new \Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity(['entityClass' => City::class, 'fields' => ['name', 'geonameId']]),
    ]);
    

Caching Strategy

  • Cache API Responses: Configure cache_dir to persist API calls.
  • TTL Management: Extend the service to clear stale cache:
    $this->get('bordeux_geoname.cache')->clear();
    

Gotchas and Tips

Pitfalls

  1. API Rate Limits

    • GeoNames API has strict usage policies.
    • Fix: Cache responses aggressively or use the bundled import command for offline access.
  2. Doctrine Mismatches

    • The bundle assumes specific entity structures (e.g., geonameId as primary key).
    • Fix: Override entities or use custom repositories if your schema differs.
  3. Symfony 5+ Compatibility

    • Original bundle was forked for Symfony 5. Test thoroughly with newer versions.
    • Tip: Check composer.json for symfony/* version constraints.

Debugging

  • Missing Data: Verify import command ran successfully:
    php bin/console bordeux:geoname:import --update
    
  • API Errors: Log the api_key and validate it on GeoNames.
  • Performance: Use Doctrine’s DISTINCT or IN clauses for large queries:
    $qb->select('DISTINCT c')
       ->from(Country::class, 'c')
       ->where('c.name LIKE :name')
       ->setParameter('name', '%USA%');
    

Extension Points

  1. Custom Data Imports Extend the importer to fetch additional GeoNames datasets (e.g., airports):

    // src/Command/CustomGeonameImportCommand.php
    use Bordeux\GeonameBundle\Command\AbstractGeonameImportCommand;
    
    class CustomGeonameImportCommand extends AbstractGeonameImportCommand {
        protected function configure() {
            $this->setName('app:geoname:import:airports');
        }
        protected function getDataUrl() { return 'http://download.geonames.org/export/dump/airport.txt'; }
    }
    
  2. Event Listeners Hook into entity lifecycle events (e.g., validate geoname IDs):

    // src/EventListener/GeonameValidationListener.php
    use Bordeux\GeonameBundle\Entity\City;
    use Doctrine\Common\EventSubscriber;
    
    class GeonameValidationListener implements EventSubscriber {
        public function prePersist($entity) {
            if ($entity instanceof City && empty($entity->getGeonameId())) {
                throw new \RuntimeException('Geoname ID required for City entity.');
            }
        }
        // ...
    }
    
  3. Custom DQL Functions Add distance calculations between locations:

    // src/DQL/Haversine.php
    use Doctrine\ORM\Query\AST\Functions\FunctionNode;
    
    class Haversine extends FunctionNode {
        public function parse(\Doctrine\ORM\Query\Parser $parser) { /* ... */ }
        public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { /* ... */ }
    }
    

    Register in doctrine.yaml:

    dql:
        string_functions:
            HAVERSINE: App\DQL\Haversine
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
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