161 lines
3.9 KiB
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);
|
|
}
|
|
}
|
|
}
|