$assignedSubmissions * @property Carbon $created_at * @property string $email * @property Carbon|null $email_verified_at * @property Collection $externalprofiles * @property int $id * @property Collection $likes * @property string $name * @property string $password * @property Collection $playlists * @property string $remember_token * @property Collection $submissions * @property Collection $tokens * @property Carbon|null $two_factor_confirmed_at * @property string|null $two_factor_recovery_codes * @property string|null $two_factor_secret * @property Carbon $updated_at * * @method static UserFactory factory(...$parameters) */ #[DateFormat('Y-m-d\TH:i:s.u')] #[Hidden([ User::ATTRIBUTE_PASSWORD, User::ATTRIBUTE_REMEMBER_TOKEN, User::ATTRIBUTE_TWO_FACTOR_RECOVERY_CODES, User::ATTRIBUTE_TWO_FACTOR_SECRET, ])] #[Table(User::TABLE)] class User extends Authenticatable implements Auditable, FilamentUser, HasAvatar, HasSubtitle, MustVerifyEmail, Nameable, SoftDeletable { use HasApiTokens; use HasAudits; use HasFactory; use HasRoles; use HasSanctions; use Notifiable; use SoftDeletes; use TwoFactorAuthenticatable; final public const string TABLE = 'users'; final public const string ATTRIBUTE_EMAIL = 'email'; final public const string ATTRIBUTE_EMAIL_VERIFIED_AT = 'email_verified_at'; final public const string ATTRIBUTE_ID = 'id'; final public const string ATTRIBUTE_NAME = 'name'; final public const string ATTRIBUTE_PASSWORD = 'password'; final public const string ATTRIBUTE_REMEMBER_TOKEN = 'remember_token'; final public const string ATTRIBUTE_TWO_FACTOR_CONFIRMED_AT = 'two_factor_confirmed_at'; final public const string ATTRIBUTE_TWO_FACTOR_RECOVERY_CODES = 'two_factor_recovery_codes'; final public const string ATTRIBUTE_TWO_FACTOR_SECRET = 'two_factor_secret'; final public const string RELATION_ASSIGNED_SUBMISSIONS = 'assignedSubmissions'; final public const string RELATION_EXTERNAL_PROFILES = 'externalprofiles'; final public const string RELATION_LIKES = 'likes'; final public const string RELATION_NOTIFICATIONS = 'notifications'; final public const string RELATION_PERMISSIONS = 'permissions'; final public const string RELATION_PROHIBITIONS = 'prohibitions'; final public const string RELATION_PLAYLISTS = 'playlists'; final public const string RELATION_SANCTIONS = 'sanctions'; final public const string RELATION_SUBMISSIONS = 'submissions'; final public const string RELATION_ROLES = 'roles'; final public const string RELATION_ROLES_PERMISSIONS = 'roles.permissions'; final public const string RELATION_WATCH_HISTORY = 'watchHistory'; /** * The event map for the model. * * Allows for object-based events for native Eloquent events. * * @var array */ protected $dispatchesEvents = [ 'created' => UserCreated::class, 'deleted' => UserDeleted::class, 'restored' => UserRestored::class, 'updated' => UserUpdated::class, ]; /** * The attributes that are mass assignable. * * @var list */ protected $fillable = [ User::ATTRIBUTE_EMAIL, User::ATTRIBUTE_NAME, User::ATTRIBUTE_PASSWORD, User::ATTRIBUTE_EMAIL_VERIFIED_AT, ]; /** * Get the attributes that should be cast. * * @return array */ protected function casts(): array { return [ User::ATTRIBUTE_EMAIL => 'string', User::ATTRIBUTE_EMAIL_VERIFIED_AT => 'datetime', User::ATTRIBUTE_NAME => 'string', User::ATTRIBUTE_PASSWORD => 'hashed', User::ATTRIBUTE_REMEMBER_TOKEN => 'string', ]; } public function getName(): string { return $this->name; } public function getSubtitle(): string { return strval($this->getKey()); } /** * Determine if the user can access the filament panel. */ public function canAccessPanel(Panel $panel): bool { if ($this->hasVerifiedEmail() && $this->hasAnyPermission(SpecialPermission::VIEW_FILAMENT->value)) { return true; } return $this->hasAnyPermission(SpecialPermission::BYPASS_AUTHORIZATION->value); } public function getFilamentAvatarUrl(): string { $hash = md5(Str::lower(Str::trim($this->email))); return "https://www.gravatar.com/avatar/$hash"; } /** * @return HasMany */ public function playlists(): HasMany { return $this->hasMany(Playlist::class, Playlist::ATTRIBUTE_USER); } /** * @return HasMany */ public function externalprofiles(): HasMany { return $this->hasMany(ExternalProfile::class, ExternalProfile::ATTRIBUTE_USER); } /** * @return HasMany */ public function likes(): HasMany { return $this->hasMany(Like::class, Like::ATTRIBUTE_USER); } /** * Get the submissions that the user made. */ public function submissions(): HasMany { return $this->hasMany(Submission::class, Submission::ATTRIBUTE_USER); } /** * Get the submissions that the admin managed. */ public function assignedSubmissions(): HasMany { return $this->hasMany(Submission::class, Submission::ATTRIBUTE_ASSIGNEE); } /** * Get the activities that the user has executed. * * @return MorphMany */ public function activities(): MorphMany { return $this->morphMany(Activity::class, 'causer'); } /** * @return MorphMany */ public function notifications(): MorphMany { $notifications = $this->morphMany(Notification::class, 'notifiable')->latest(); if (Filament::isServing()) { return $notifications->where(Notification::ATTRIBUTE_TYPE, FilamentNotification::class); } return $notifications->whereNot(Notification::ATTRIBUTE_TYPE, FilamentNotification::class); } /** * @return HasMany */ public function watchHistory(): HasMany { return $this->hasMany(WatchHistory::class, WatchHistory::ATTRIBUTE_USER); } /** * Get the prunable model query. */ public function prunable(): Builder { return static::onlyTrashed()->where( self::ATTRIBUTE_DELETED_AT, ComparisonOperator::LTE->value, now()->subMonth() ); } }