'datetime', 'password' => 'hashed', 'password_change_required' => 'boolean', 'disattivato_at' => 'datetime', 'proclamatore_id' => 'integer', ]; } /** Il proclamatore di cui è l'utenza (sorvegliante di gruppo). */ public function proclamatore() { return $this->belongsTo(Proclamatore::class, 'proclamatore_id')->withTrashed(); } /** * Sorvegliante di gruppo: vede solo il proprio gruppo e il proprio * profilo (middleware LimitaSorvegliante). */ public function isSorvegliante(): bool { return $this->hasRole('sorvegliante'); } /** Il gruppo (attivo) di cui è sorvegliante, se c'è. */ public function gruppoSorvegliato(): ?GruppoServizio { return $this->proclamatore_id ? GruppoServizio::attivi()->where('sorvegliante_id', $this->proclamatore_id)->first() : null; } /** Utenza disattivata (gruppo sciolto): non può più entrare. */ public function isDisattivato(): bool { return $this->disattivato_at !== null; } /** * Il sorvegliante non conferma l'email (scelta dell'utente, 19 ottobre * 2026): l'utenza la crea l'amministratore con una password temporanea. * Per tutti gli altri resta obbligatoria. */ public function hasVerifiedEmail(): bool { return ! is_null($this->email_verified_at) || $this->isSorvegliante(); } public function getActivitylogOptions(): LogOptions { return LogOptions::defaults() ->logOnly(['name', 'email']) ->logOnlyDirty() ->dontSubmitEmptyLogs(); } protected static function booted(): void { // Un indirizzo nuovo va confermato di nuovo, chiunque lo cambi. static::updating(function (self $utente) { if ($utente->isDirty('email') && ! $utente->isDirty('email_verified_at')) { $utente->email_verified_at = null; } }); } /** * Manda l'email di conferma; false se il server di posta non risponde o * rifiuta. Chi chiama decide cosa dire: l'utente è comunque salvato, e * l'email si può richiedere di nuovo. */ public function inviaConfermaEmail(): bool { if ($this->isSorvegliante()) { return true; } try { $this->sendEmailVerificationNotification(); } catch (\Throwable $e) { report($e); return false; } return true; } }