PHP code example of byte5 / addressable

1. Go to this page and download the library: Download byte5/addressable library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

byte5 / addressable example snippets


return [
    'models' => [
        'address' => \Byte5\Addressable\App\Models\Address::class,
    ],
    'table_names' => [
        'addresses' => 'addresses',
    ],
    'column_names' => [
        'model_morph_key' => 'addressable_id',
    ],
    'type_enum' => \Byte5\Addressable\App\Enums\AddressType::class, // or '' to disable
];

namespace App\Models;

use Byte5\Addressable\App\Models\Address as BaseAddress;
use Illuminate\Database\Eloquent\Concerns\HasUuids;

class Address extends BaseAddress
{
    use HasUuids;
}

// config/byte5-addressable.php
'models' => [
    'address' => \App\Models\Address::class,
],

  // database/migrations/..._create_addresses_table.php
  // $table->unsignedBigInteger($morphKey)->nullable();
  $table->uuid($morphKey)->nullable();   // or ->ulid($morphKey)
  

  // config/byte5-addressable.php
  'type_enum' => \App\Enums\MyAddressType::class,
  

  'type_enum' => '',
  

use Byte5\Addressable\App\Concerns\HasAddresses;
use Byte5\Addressable\App\Contracts\Addressable;

class User extends Model implements Addressable
{
    use HasAddresses;
}

// All addresses (morphMany)
$user->addresses;
$user->addresses()->create([
    'street' => 'Main 10',
    'postal' => '10115',
    'city' => 'Berlin',
    'region' => 'Berlin',
    'country' => 'DE',
    'type' => 'billing', // optional role/label
]);

// The most recently attached address (morphOne)
$user->latestAddress;

// The owning model from an address (morphTo)
$address->addressable;

use Byte5\Addressable\App\Data\AddressData;
use Byte5\Addressable\App\Enums\AddressType;

// From a typed DTO
$user->addAddress(new AddressData(
    street: 'Pariser Platz 1',
    postal: '10117',
    city:   'Berlin',
    country: 'DE',
), AddressType::Billing);

// From a loose array — internally calls AddressData::fromArray()
$user->addAddress([
    'street'  => 'Pariser Platz 1',
    'postal'  => '10117',
    'city'    => 'Berlin',
    'country' => 'DE',
    'type'    => 'billing',
]);

// From a resolved Google Place
$details = AddressLookup::details($placeId);   // PlaceDetails
$data    = $details->toAddressData(AddressType::Shipping);

// From a schema.org PostalAddress DTO
$postal = $address->toSchemaOrg();             // PostalAddress
$data   = $postal->toAddressData(AddressType::Billing);

use Byte5\Addressable\App\Contracts\CreatesAddresses;

$this->app->bind(CreatesAddresses::class, MyDedupingAddressCreator::class);

$address->toSchemaOrg()->toArray();
// [
//     '@type' => 'PostalAddress',
//     'streetAddress' => 'Pariser Platz 1',
//     'postalCode' => '10117',
//     'addressLocality' => 'Berlin',
//     'addressCountry' => 'DE',
//     // null fields omitted; no '@context'
// ]

$address->toSchemaOrg()->toJsonLd();
// {"@context":"https://schema.org","@type":"PostalAddress","streetAddress":"Pariser Platz 1",…}

use Byte5\Addressable\App\Rules\AddressExists;
use Byte5\Addressable\App\Rules\Country;
use Byte5\Addressable\App\Rules\PostalFormat;

public function rules(): array
{
    return [
        'country' => ['untry inputs and makes a single
        // (billable) provider call per validation run.
        'street'  => ['

use Byte5\Addressable\App\Facades\AddressRules;

AddressRules::country();           // new Country()
AddressRules::postalFormat('DE');  // new PostalFormat('DE')
AddressRules::exists();            // new AddressExists()

new AddressExists(['postal' => 'zip_code', 'country' => 'address.country']);

use Byte5\Addressable\App\Facades\Countries;

Countries::list();      // ['DE' => 'Germany', 'FR' => 'France', …] in the app locale
Countries::list('de');  // ['DE' => 'Deutschland', 'FR' => 'Frankreich', …]

// config/byte5-addressable.php
// Autocomplete + geocoding (AddressLookup::suggest/details)
'lookup' => [
    'provider' => env('ADDRESSABLE_LOOKUP_PROVIDER', 'google'),
    'providers' => [
        'google' => [
            'key' => env('ADDRESSABLE_LOOKUP_GOOGLE_KEY'),
            'language' => env('ADDRESSABLE_LOOKUP_GOOGLE_LANGUAGE'), // Places languageCode; falls back to app locale
            'region' => env('ADDRESSABLE_LOOKUP_GOOGLE_REGION'),     // region bias (regionCode)
            'country' => env('ADDRESSABLE_LOOKUP_GOOGLE_COUNTRY'),   // single ISO 3166-1 alpha-2 code (set an array in the published config for multiple)
        ],
    ],
],

// Address validation (AddressValidator::validate + the AddressExists rule) — separate provider + key
'validation' => [
    'provider' => env('ADDRESSABLE_VALIDATION_PROVIDER', 'google'),

    // How the AddressExists rule reacts when the provider is unreachable:
    // false (default) surfaces the error; true lets the address through.
    'pass_on_outage' => env('ADDRESSABLE_VALIDATION_PASS_ON_OUTAGE', false),

    'providers' => [
        'google' => [
            'key' => env('ADDRESSABLE_VALIDATION_GOOGLE_KEY'),
        ],
    ],
],

use Byte5\Addressable\App\Facades\AddressLookup;

// 1. Suggestions as the user types
$suggestions = AddressLookup::suggest('Branden');
// => Byte5\Addressable\App\Data\Suggestion[] { placeId, description, mainText, secondaryText }

// 2. Resolve the chosen suggestion into a structured address
$details = AddressLookup::details($suggestions[0]->placeId);
// => Byte5\Addressable\App\Data\PlaceDetails (or null if not found)

// 3. Persist it — toArray() matches the Address columns
$user->addresses()->create($details->toArray());

AddressLookup::suggest('Haupt', ['country' => 'DE', 'language' => 'de']);

use Byte5\Addressable\App\Data\AddressInput;
use Byte5\Addressable\App\Facades\AddressValidator;

$validation = AddressValidator::validate(new AddressInput(
    street: 'Pariser Platz 1',
    postal: '10117',
    city: 'Berlin',
    country: 'DE', // ISO 3166-1 alpha-2 (regionCode)
));

$validation->valid;             // normalised: deliverable / exists (every provider)
$validation->provider;          // 'google'
$validation->formattedAddress;  // standardised address
$validation->raw;               // full provider payload

// Typed Google specifics — narrow to the provider's result:
use Byte5\Addressable\App\Data\GoogleAddressValidation;

if ($validation instanceof GoogleAddressValidation) {
    $validation->granularity;              // PREMISE | SUB_PREMISE | ROUTE | LOCALITY | OTHER | ...
    $validation->complete;                 // Google addressComplete
    $validation->hasUnconfirmedComponents;
    $validation->hasInferredComponents;
    $validation->hasReplacedComponents;
}

use Byte5\Addressable\App\Events\AddressResolved;
use Illuminate\Support\Facades\Event;

Event::listen(function (AddressResolved $event) {
    logger()->info("Resolved {$event->placeId} via {$event->provider}", $event->details->toArray());
});

use Byte5\Addressable\App\Facades\AddressLookup;
use Livewire\Component;

class AddressForm extends Component
{
    public string $query = '';

    /** @var array<int, array{placeId: string, description: string}> */
    public array $suggestions = [];

    // Bound form fields — filled from the chosen address.
    public ?string $street = null;
    public ?string $postal = null;
    public ?string $city = null;
    public ?string $region = null;
    public ?string $country = null;

    public function updatedQuery(): void
    {
        // Map to plain arrays — Livewire only serialises primitive/array props,
        // not the Suggestion DTO.
        $this->suggestions = strlen($this->query) >= 3
            ? array_map(
                fn ($s) => ['placeId' => $s->placeId, 'description' => $s->description],
                AddressLookup::suggest($this->query),
            )
            : [];
    }

    public function select(string $placeId): void
    {
        if ($details = AddressLookup::details($placeId)) {
            $this->street  = $details->street;
            $this->postal  = $details->postal;
            $this->city    = $details->city;
            $this->region  = $details->region;
            $this->country = $details->country;
        }

        $this->suggestions = [];
    }

    public function render()
    {
        return view('livewire.address-form');
    }
}

use Byte5\Addressable\App\Facades\AddressLookup;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::middleware(['auth', 'throttle:30,1'])->group(function () {
    Route::get('/address/suggest', fn (Request $r) => AddressLookup::suggest($r->string('q')));
    Route::get('/address/details/{placeId}', fn (string $placeId) => AddressLookup::details($placeId));
});
bash
php artisan vendor:publish --tag=byte5-addressable/migrations
php artisan migrate
bash
php artisan vendor:publish --tag=byte5-addressable/config
bash
php artisan vendor:publish --tag=byte5-addressable/config