KEINE used_bytes / message_count hier, die cachen wir separat ]; protected $hidden = ['password_hash']; protected $casts = [ 'is_system' => 'boolean', 'is_active' => 'boolean', 'can_login' => 'boolean', 'quota_mb' => 'integer', 'rate_limit_per_hour' => 'integer', 'last_login_at' => 'datetime', 'stats_refreshed_at' => 'datetime', 'created_at' => 'datetime', 'updated_at' => 'datetime', ]; /* |-------------------------------------------------------------------------- | Beziehungen |-------------------------------------------------------------------------- */ public function domain(): BelongsTo { return $this->belongsTo(Domain::class); } /* |-------------------------------------------------------------------------- | Accessors / Helper |-------------------------------------------------------------------------- */ /** * Bevorzugt den DB-Wert aus 'email'. * Fehlt dieser, wird aus localpart + domain.domain gebaut. * Gibt niemals "@" zurück, sondern null, wenn unbestimmbar. */ public function getEmailAttribute($value): ?string { if (!empty($value)) { return $value; // DB-Wert hat Vorrang } $local = (string)($this->attributes['localpart'] ?? ''); // Domainname – wenn Relation geladen, daraus; sonst nichts (kein teurer Query hier). $dom = $this->relationLoaded('domain') ? (string)($this->domain->domain ?? '') : (string)($this->attributes['domain'] ?? ''); // nur falls bei Joins alias 'domain' selektiert wäre if ($local !== '' && $dom !== '') { return "{$local}@{$dom}"; } return null; } /** * „Adresse“ als bequemer Fallback (identisch zu email(), fällt aber am Ende auf '@dom' NICHT zurück). */ public function getAddressAttribute(): string { return (string)($this->getRawOriginal('email') ?: ($this->email ?? '')); } /** * Optionaler Setter für Passwort über virtuelles Attribut "password". */ public function setPasswordAttribute(string $plain): void { $this->attributes['password_hash'] = password_hash($plain, PASSWORD_BCRYPT); } /* |-------------------------------------------------------------------------- | Scopes |-------------------------------------------------------------------------- */ public function scopeActive($q) { return $q->where('is_active', true); } public function scopeSystem($q) { return $q->where('is_system', true); } public function scopeByEmail($q, string $email) { return $q->where('email', $email); } } //class MailUser extends Model //{ // protected $fillable = [ // 'domain_id', 'localpart', 'email', 'display_name', 'password_hash', // 'is_active', 'quota_mb', 'is_system' // ]; // // protected $hidden = ['password_hash']; // // protected $casts = [ // 'is_active' => 'bool', // 'is_system' => 'bool', // 'quota_mb' => 'int', // 'last_login_at' => 'datetime', // ]; // // public function domain(): BelongsTo // { // return $this->belongsTo(Domain::class); // } // // // optional: virtueller Setter // public function setPasswordAttribute(string $plain): void // { // $this->attributes['password_hash'] = password_hash($plain, PASSWORD_BCRYPT); // } // // /** // * KORREKT: DB-Wert hat Vorrang; falls leer → Fallback localpart@domain.domain // */ // public function getEmailAttribute($value): ?string // { // if (!empty($value)) { // return $value; // } // $local = (string)($this->attributes['localpart'] ?? $this->localpart ?? ''); // $dom = $this->relationLoaded('domain') // ? (string)($this->domain->domain ?? '') // : (string)($this->attributes['domain'] ?? ''); // // if ($local !== '' && $dom !== '') { // return "{$local}@{$dom}"; // } // // nichts zusammenfummeln → nicht "@" // return null; // } // // /** // * Adresse ohne Accessor/DB-Fallback erzwingen (z.B. in Queries vor-joined) // */ // public function getAddressAttribute(): string // { // $raw = (string)($this->attributes['email'] ?? ''); // if ($raw !== '') return $raw; // // $local = (string)($this->attributes['localpart'] ?? $this->localpart ?? ''); // $dom = $this->relationLoaded('domain') // ? (string)($this->domain->domain ?? '') // : (string)($this->attributes['domain'] ?? ''); // // return ($local !== '' && $dom !== '') ? "{$local}@{$dom}" : ''; // } // // // Scopes // public function scopeActive($q) // { // return $q->where('is_active', true); // } // // public function scopeSystem($q) // { // return $q->where('is_system', true); // } // // public function scopeByEmail($q, string $email) // { // return $q->where('email', $email); // } //} //class MailUser extends Model //{ //// protected $table = 'mail_users'; // // protected $fillable = [ // 'domain_id','localpart','email','display_name','password_hash', // 'is_active','quota_mb','is_system' // ]; // // protected $hidden = ['password_hash']; // protected $casts = [ // 'is_active'=>'bool', // 'is_system' => 'boolean', // 'quota_mb'=>'int', // 'last_login_at'=>'datetime', // ]; // // public function domain(): BelongsTo { // return $this->belongsTo(Domain::class); // } // // public function setPasswordAttribute(string $plain): void { // // optional: allow 'password' virtual attribute // $this->attributes['password_hash'] = password_hash($plain, PASSWORD_BCRYPT); // } // // // Ausgabe: vollständige Adresse // public function getEmailAttribute(): string { // return "{$this->local_part}@{$this->domain->name}"; // } // // public function getAddressAttribute(): string // { // $local = (string)($this->attributes['localpart'] ?? $this->localpart ?? ''); // // bevorzugt den in Queries selektierten Alias `dom`, sonst Relation, sonst Roh-Attribut // $dom = (string)( // $this->attributes['dom'] // ?? ($this->relationLoaded('domain') ? ($this->domain->domain ?? '') : '') // ?? ($this->attributes['domain'] ?? '') // ); // // if ($local !== '' && $dom !== '') return "{$local}@{$dom}"; // if (($this->attributes['email'] ?? null) !== null) return (string)$this->attributes['email']; // return $dom !== '' ? "@{$dom}" : ''; // } // // // Scopes // public function scopeActive($q) { return $q->where('is_active', true); } // // public function scopeSystem($q) { return $q->where('is_system', true); } // // public function scopeByEmail($q, string $email) { return $q->where('email', $email); } // //}