99 lines
2.3 KiB
PHP
99 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class UserAddress extends Model
|
|
{
|
|
// table name
|
|
protected $table = 'user_addresses';
|
|
|
|
// mass-assignable columns
|
|
protected $fillable = [
|
|
'user_id',
|
|
'label',
|
|
'kind',
|
|
'line1',
|
|
'line2',
|
|
'city',
|
|
'state',
|
|
'postal',
|
|
'country',
|
|
'phone',
|
|
'location_id',
|
|
'is_primary',
|
|
];
|
|
|
|
// simple casts
|
|
protected $casts = [
|
|
'is_primary' => 'boolean',
|
|
'is_billing' => 'boolean',
|
|
'created_at' => 'datetime',
|
|
'updated_at' => 'datetime',
|
|
];
|
|
|
|
/* relationships */
|
|
|
|
// belongs to a user (users.id is char(26))
|
|
public function user(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'user_id', 'id');
|
|
}
|
|
|
|
// optional normalized/geocoded location row
|
|
public function location(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Location::class, 'location_id');
|
|
}
|
|
|
|
/* query scopes */
|
|
|
|
// filter by kind (e.g., 'billing', 'shipping', 'home', 'work')
|
|
public function scopeKind($query, string $kind)
|
|
{
|
|
return $query->where('kind', $kind);
|
|
}
|
|
|
|
// filter to primary rows
|
|
public function scopePrimary($query)
|
|
{
|
|
return $query->where('is_primary', 1);
|
|
}
|
|
|
|
/* helpers */
|
|
|
|
// set this address as the single primary of its kind for the user
|
|
public function setAsPrimary(): void
|
|
{
|
|
DB::transaction(function () {
|
|
// clear any existing primary for this user+kind (null is allowed by the unique index)
|
|
static::where('user_id', $this->user_id)
|
|
->where('kind', $this->kind)
|
|
->update(['is_primary' => null]);
|
|
|
|
// mark this one as primary
|
|
$this->is_primary = 1;
|
|
$this->save();
|
|
});
|
|
}
|
|
|
|
// quick one-line label useful for dropdowns and summaries
|
|
public function getOneLineAttribute(): string
|
|
{
|
|
$parts = array_filter([
|
|
$this->label,
|
|
$this->line1,
|
|
$this->line2,
|
|
$this->city,
|
|
$this->state,
|
|
$this->postal,
|
|
$this->country,
|
|
]);
|
|
|
|
return trim(collect($parts)->join(', '));
|
|
}
|
|
}
|