dillingham/locality

Automatic Address Normalization in Laravel

Downloads

8

Stars

2

Version

0.0.8

Locality

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads


A Laravel package that automatically normalizes address data. Instead of storing city state & zipcodes repeatedly, create tables and reference the foreign key. This package accepts the string representation, checks if it exists or creates it and adds the relationship. This package also provides accessors to make it feel as though you aren't even normalizing.


Installation

You can install the package via composer:

composer require dillingham/locality

You can publish the config file with:

php artisan vendor:publish --provider="Dillingham\Locality\LocalityServiceProvider" --tag="locality-config"

Add the following columns to your model's migration:

$table->addAddress();

Which is just a shorthand for adding these columns:

column nullable indexed description
address_1 yes no street and building number
address_2 yes no optional unit number
admin_level_3_id yes yes the neighborhood political region
admin_level_2_id no yes the city political region
admin_level_1_id no yes the state political region
postal_code_id no yes the postal foreign key
country_id yes no the country foreign key
formatted_address no no static address without queries

The 5 tables will be migrated:

php artisan migrate

Then add the HasAddress trait:

<?php

namespace App\Models;

use Dillingham\Locality\HasAddress;

class Profile extends Model
{
  use HasAddress;
}

Usage

Profile::create([
    'address_1' => '104 India St',
    'address_2' => 'Apt #3L',
    'admin_level_2' => 'Brookyln',    
    'admin_level_1' => 'NY',
    'postal_code' => '11222',
]);

Automatically the trait will use firstOrCreate when storing Profile

'admin_level_2' => 'Brookyln'

becomes the foreign id of Brooklyn in the admin_level_2 table

'admin_level_2_id' => 332

Access Values

Access the string values of the relationships via accessors:

$profile->admin_level_2 == 'Brooklyn'
$profile->admin_level_1 == 'NY'

These accessors call relationships behind the scenes, eager load in collections

Note: the full address formatting is statically stored while saving:

$profile->formatted_address == '104 India St, #3l Brooklyn, NY 11222`

Bonus

The following are opt in loosely related features;

Dependent Filters

Here are some api routes for filtering models by localtion info

Route::localityDepenentOptions();

The following assumes routes/api.php and prefixed from RouteServiceProvider.php

GET /api/locality/countries
{
    "data": [
        {
            "value": 1,
            "display": "US"
        }
    ]
}
GET /api/locality/admin_level_2?country_id=1
{
    "data": [
        {
            "value": 1,
            "display": "NY"
        }
    ]
}
GET /api/locality/admin_level_1?admin_level_2_id=1
{
    "data": [
        {
            "value": 1,
            "display": "Brooklyn"
        }
    ]
}
GET /api/locality/postal_code?admin_level_1_id=1
{
    "data": [
        {
            "value": 1,
            "display": "11222"
        }
    ]
}

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

dillingham

Author

dillingham