kithkin/app/Models/User.php

161 lines
3.9 KiB
PHP

<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Models\UserSetting;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Str;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, Notifiable;
use HasUlids; // generates ULIDs automatically
protected $keyType = 'string';
public $incrementing = false;
/**
* The attributes that are mass assignable.
*
* @var list<string>
*/
protected $fillable = [
'firstname',
'lastname',
'displayname',
'email',
'timezone',
'phone',
];
/**
* The attributes that should be hidden for serialization.
*
* @var list<string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
/**
* user can own many calendars
*/
public function calendars(): HasMany
{
return $this->hasMany(Calendar::class);
}
/**
* get the current user's principal uri
*/
public function getPrincipalUriAttribute(): string
{
return 'principals/' . $this->email;
}
/**
* get all user addresses
*/
public function addresses()
{
return $this->hasMany(\App\Models\UserAddress::class, 'user_id', 'id');
}
/**
* get the user's billing address
*/
public function billingAddress()
{
return $this->addresses()
->where('kind', 'billing')
->where('is_primary', 1)
->first();
}
/**
* user can have many settings
*/
public function userSettings(): HasMany
{
return $this->hasMany(UserSetting::class, 'user_id');
}
/**
* get a user setting by key
*/
public function getSetting(string $key, mixed $default = null): mixed
{
// avoid repeated queries if the relationship is already eager loaded
if ($this->relationLoaded('userSettings')) {
$match = $this->userSettings->firstWhere('key', $key);
return $match?->value ?? $default;
}
$value = $this->userSettings()
->where('key', $key)
->value('value');
return $value ?? $default;
}
/**
* set a user setting by key
*/
public function setSetting(string $key, mixed $value): void
{
// store everything as a string in the value column
$stringValue = is_null($value) ? null : (string) $value;
$this->userSettings()->updateOrCreate(
['key' => $key],
['value' => $stringValue],
);
// keep in-memory relation in sync if it was loaded
if ($this->relationLoaded('userSettings')) {
$existing = $this->userSettings->firstWhere('key', $key);
if ($existing) {
$existing->value = $stringValue;
} else {
$this->userSettings->push(new UserSetting([
'user_id' => $this->getKey(),
'key' => $key,
'value' => $stringValue,
]));
}
}
}
/**
* convenience: set many settings at once
*/
public function setSettings(array $pairs): void
{
foreach ($pairs as $key => $value) {
$this->setSetting($key, $value);
}
}
}