189 lines
4.6 KiB
Markdown
189 lines
4.6 KiB
Markdown
|
|
# Customization
|
||
|
|
|
||
|
|
## Custom Model Classes
|
||
|
|
|
||
|
|
You can extend any of the three package models with your own. This is useful for adding custom methods, relationships, accessors or validation logic.
|
||
|
|
|
||
|
|
### 1. Create your custom model
|
||
|
|
|
||
|
|
```php
|
||
|
|
// app/Models/CustomAddress.php
|
||
|
|
|
||
|
|
namespace App\Models;
|
||
|
|
|
||
|
|
use Blax\Addresses\Models\Address as BaseAddress;
|
||
|
|
|
||
|
|
class CustomAddress extends BaseAddress
|
||
|
|
{
|
||
|
|
public function getFullAddressAttribute(): string
|
||
|
|
{
|
||
|
|
return "{$this->street}, {$this->postal_code} {$this->city}, {$this->country_code}";
|
||
|
|
}
|
||
|
|
|
||
|
|
public function geocode(): self
|
||
|
|
{
|
||
|
|
// your geocoding logic
|
||
|
|
return $this;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Update the config
|
||
|
|
|
||
|
|
```php
|
||
|
|
// config/addresses.php
|
||
|
|
|
||
|
|
'models' => [
|
||
|
|
'address' => \App\Models\CustomAddress::class,
|
||
|
|
'address_link' => \Blax\Addresses\Models\AddressLink::class,
|
||
|
|
'address_assignment' => \Blax\Addresses\Models\AddressAssignment::class,
|
||
|
|
],
|
||
|
|
```
|
||
|
|
|
||
|
|
The package resolves all model classes through `config('addresses.models.…')`, so your custom class will be used everywhere — in relationships, service methods, and traits.
|
||
|
|
|
||
|
|
### Example: Custom AddressLink
|
||
|
|
|
||
|
|
```php
|
||
|
|
namespace App\Models;
|
||
|
|
|
||
|
|
use Blax\Addresses\Models\AddressLink as BaseAddressLink;
|
||
|
|
|
||
|
|
class CustomAddressLink extends BaseAddressLink
|
||
|
|
{
|
||
|
|
protected static function booted()
|
||
|
|
{
|
||
|
|
static::creating(function (self $link) {
|
||
|
|
// Auto-set label from type if not provided
|
||
|
|
if (! $link->label) {
|
||
|
|
$link->label = $link->type->label();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
```php
|
||
|
|
'models' => [
|
||
|
|
'address_link' => \App\Models\CustomAddressLink::class,
|
||
|
|
],
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Custom Table Names
|
||
|
|
|
||
|
|
Change the table names if they collide with existing tables in your application:
|
||
|
|
|
||
|
|
```php
|
||
|
|
// config/addresses.php
|
||
|
|
|
||
|
|
'table_names' => [
|
||
|
|
'addresses' => 'company_addresses',
|
||
|
|
'address_links' => 'company_address_links',
|
||
|
|
'address_assignments' => 'company_address_assignments',
|
||
|
|
],
|
||
|
|
```
|
||
|
|
|
||
|
|
**Important:** Update the published migration to match these names before running `php artisan migrate`. The migration stub reads from the config, so if you publish the config first and then the migration, the table names will be picked up automatically.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Custom Default Link Type
|
||
|
|
|
||
|
|
Change the default `AddressLinkType` applied when adding an address without specifying a type:
|
||
|
|
|
||
|
|
```php
|
||
|
|
// config/addresses.php
|
||
|
|
|
||
|
|
'default_link_type' => \Blax\Addresses\Enums\AddressLinkType::Home,
|
||
|
|
```
|
||
|
|
|
||
|
|
Now `$user->addAddress(['city' => 'Vienna'])` will use `Home` instead of `Other`.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Using the Meta Column
|
||
|
|
|
||
|
|
All three models (`Address`, `AddressLink`, `AddressAssignment`) include a `meta` JSON column for storing arbitrary data. The column is cast to `object`.
|
||
|
|
|
||
|
|
```php
|
||
|
|
// On addresses — store extra data
|
||
|
|
$link = $user->addAddress([
|
||
|
|
'street' => 'Main Street 1',
|
||
|
|
'city' => 'Vienna',
|
||
|
|
'meta' => [
|
||
|
|
'plus_code' => '8FWR4HCJ+XX',
|
||
|
|
'what3words' => 'index.home.raft',
|
||
|
|
'timezone' => 'Europe/Vienna',
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
|
||
|
|
// On address links — store context about the relationship
|
||
|
|
$link = $user->addAddress(['city' => 'Vienna'], AddressLinkType::Office, [
|
||
|
|
'meta' => [
|
||
|
|
'department' => 'Engineering',
|
||
|
|
'access_code' => '4521',
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
|
||
|
|
// On address assignments — store context about the assignment
|
||
|
|
$job->assignAddressLink($link, 'delivery', [
|
||
|
|
'meta' => [
|
||
|
|
'time_window' => '09:00-12:00',
|
||
|
|
'priority' => 'express',
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
|
||
|
|
// Reading meta
|
||
|
|
$address->meta->plus_code; // "8FWR4HCJ+XX"
|
||
|
|
$link->meta->department; // "Engineering"
|
||
|
|
$assignment->meta->time_window; // "09:00-12:00"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Model Bindings
|
||
|
|
|
||
|
|
The service provider registers model bindings so that resolving a package model through the container returns the configured (possibly customised) class:
|
||
|
|
|
||
|
|
```php
|
||
|
|
// Always resolves to your custom class if configured
|
||
|
|
$address = app(\Blax\Addresses\Models\Address::class);
|
||
|
|
```
|
||
|
|
|
||
|
|
This means type-hinting the base class in dependency injection will automatically resolve to your custom model.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Extending the AddressService
|
||
|
|
|
||
|
|
The `AddressService` is registered as a singleton. To add custom methods, extend it and rebind:
|
||
|
|
|
||
|
|
```php
|
||
|
|
namespace App\Services;
|
||
|
|
|
||
|
|
use Blax\Addresses\Services\AddressService;
|
||
|
|
use Blax\Addresses\Models\Address;
|
||
|
|
|
||
|
|
class CustomAddressService extends AddressService
|
||
|
|
{
|
||
|
|
public function geocode(Address $address): Address
|
||
|
|
{
|
||
|
|
// your geocoding implementation
|
||
|
|
return $address;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
In a service provider:
|
||
|
|
|
||
|
|
```php
|
||
|
|
$this->app->singleton(
|
||
|
|
\Blax\Addresses\Services\AddressService::class,
|
||
|
|
\App\Services\CustomAddressService::class
|
||
|
|
);
|
||
|
|
```
|
||
|
|
|
||
|
|
The `address()` helper and all DI injection will now resolve your custom service.
|