laravel-addresses/src/Models/Address.php

169 lines
5.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Blax\Addresses\Models;
use Blax\Workkit\Traits\HasMeta;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Represents a physical address — from a rural GPS coordinate to a specific
* room inside a high-rise building.
*
* Coordinate system:
* latitude / longitude → WGS-84 decimal degrees
* altitude → metres Above Mean Sea Level (AMSL)
*
* @property int $id
* @property string|null $street Primary street line (name + number)
* @property string|null $street_extra Secondary line (c/o, suite, P.O. box …)
* @property string|null $building Building / complex name
* @property string|null $floor Floor / level (string: "GF", "B2", "Mezzanine")
* @property string|null $room Room, suite or unit identifier
* @property string|null $postal_code Postal / ZIP code
* @property string|null $city City, town, village or locality
* @property string|null $state State, province, canton …
* @property string|null $county County, district …
* @property string|null $country_code ISO 3166-1 alpha-2 ("AT", "US", "JP")
* @property float|null $latitude Decimal degrees (90 … +90)
* @property float|null $longitude Decimal degrees (180 … +180)
* @property float|null $altitude Metres AMSL (positive = above, negative = below)
* @property bool $has_elevator Whether the building has an elevator
* @property string|null $notes Free-form notes / delivery instructions
* @property object|null $meta Arbitrary JSON data
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property \Carbon\Carbon|null $deleted_at
*/
class Address extends Model
{
use HasMeta;
use SoftDeletes;
/**
* Mass-assignable attributes.
*
* Every column is intentionally nullable so that an address record can be
* as sparse as a single coordinate pair or as detailed as a full postal
* address with indoor precision.
*/
protected $fillable = [
'street',
'street_extra',
'building',
'floor',
'room',
'postal_code',
'city',
'state',
'county',
'country_code',
'latitude',
'longitude',
'altitude',
'has_elevator',
'notes',
'meta',
];
/**
* Attribute casting.
*/
protected $casts = [
'latitude' => 'float',
'longitude' => 'float',
'altitude' => 'float',
'has_elevator' => 'boolean',
'meta' => 'object',
];
/*
|--------------------------------------------------------------------------
| Constructor — configurable table name
|--------------------------------------------------------------------------
*/
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->table = config('addresses.table_names.addresses') ?: parent::getTable();
}
/*
|--------------------------------------------------------------------------
| Relationships
|--------------------------------------------------------------------------
*/
/**
* All links that reference this address (polymorphic pivot rows).
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function links()
{
return $this->hasMany(
config('addresses.models.address_link', AddressLink::class),
'address_id'
);
}
/*
|--------------------------------------------------------------------------
| Helpers
|--------------------------------------------------------------------------
*/
/**
* Whether the address has geographic coordinates set.
*/
public function hasCoordinates(): bool
{
return $this->latitude !== null && $this->longitude !== null;
}
/**
* Whether the address has altitude (AMSL) set.
*/
public function hasAltitude(): bool
{
return $this->altitude !== null;
}
/**
* Build a single-line formatted representation of the address.
*
* Useful for display purposes — joins non-empty components with ", ".
*/
public function getFormattedAttribute(): string
{
return collect([
$this->street,
$this->street_extra,
$this->building ? "({$this->building})" : null,
$this->floor ? "Floor {$this->floor}" : null,
$this->room ? "Room {$this->room}" : null,
$this->postal_code,
$this->city,
$this->state,
$this->county,
$this->country_code,
])->filter()->implode(', ');
}
/**
* Return coordinates as an associative array.
*
* @return array{latitude: float|null, longitude: float|null, altitude: float|null}
*/
public function toCoordinates(): array
{
return [
'latitude' => $this->latitude,
'longitude' => $this->longitude,
'altitude' => $this->altitude,
];
}
}