Files
imail/app/Models/Domain.php
idevakk 7dc89880a7 feat(mailbox): Implement cinematic UX and user tiers
- Added Spatie roles (free, pro, enterprise, admin) and access scopes
- Implemented delayed, cinematic mailbox provisioning animation
- Fixed GSAP and SVG collision issues on creation overlay
- Improved component sync with livewire refresh
- Added feature tests for tier systems and fixed RegistrationTest
2026-03-06 00:22:27 +05:30

69 lines
1.9 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Domain extends Model
{
/** @use HasFactory<\Database\Factories\DomainFactory> */
use HasFactory, SoftDeletes;
protected $fillable = [
'domain_hash',
'name',
'allowed_types',
'is_active',
'is_archived',
];
protected function casts(): array
{
return [
'allowed_types' => 'array',
'is_active' => 'boolean',
'is_archived' => 'boolean',
];
}
protected static function booted(): void
{
static::creating(function (Domain $domain) {
if (empty($domain->domain_hash)) {
$domain->domain_hash = bin2hex(random_bytes(32));
}
});
}
public function mailboxes()
{
return $this->hasMany(Mailbox::class, 'domain_hash', 'domain_hash');
}
/**
* Scope to domains accessible by the given user tier.
* For guests (null user), only 'public' domains are returned.
*
* Uses MySQL's JSON_CONTAINS to check if the domain's `allowed_types`
* array includes ANY of the user's allowed types.
*
* Usage:
* Domain::accessibleBy(auth()->user())->get(); // logged-in
* Domain::accessibleBy(null)->get(); // guest
* Domain::accessibleBy($user)->where('is_active', true)->get();
*/
public function scopeAccessibleBy(Builder $query, ?User $user = null): Builder
{
$types = $user ? $user->allowedDomainTypes() : User::guestDomainTypes();
return $query->where(function (Builder $q) use ($types) {
foreach ($types as $type) {
$q->orWhereJsonContains('allowed_types', $type);
}
});
}
}