$externalprofiles * @property int $id * @property Collection $managedsubmissions * @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) */ class User extends Authenticatable implements FilamentUser, HasAvatar, HasSubtitle, MustVerifyEmail, Nameable, SoftDeletable { use HasApiTokens; use HasFactory; use HasRoles; 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_EXTERNAL_PROFILES = 'externalprofiles'; final public const string RELATION_MANAGED_SUBMISSIONS = 'managedsubmissions'; final public const string RELATION_NOTIFICATIONS = 'notifications'; final public const string RELATION_PERMISSIONS = 'permissions'; final public const string RELATION_PLAYLISTS = 'playlists'; final public const string RELATION_SUBMISSIONS = 'submissions'; final public const string RELATION_ROLES = 'roles'; final public const string RELATION_ROLES_PERMISSIONS = 'roles.permissions'; /** * The table associated with the model. * * @var string */ protected $table = User::TABLE; /** * 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, ]; /** * The attributes that should be hidden for serialization. * * @var list */ protected $hidden = [ User::ATTRIBUTE_PASSWORD, User::ATTRIBUTE_REMEMBER_TOKEN, User::ATTRIBUTE_TWO_FACTOR_RECOVERY_CODES, User::ATTRIBUTE_TWO_FACTOR_SECRET, ]; /** * The storage format of the model's date columns. * * @var string */ protected $dateFormat = 'Y-m-d\TH:i:s.u'; /** * Get the attributes that should be cast. * * @return array */ protected function casts(): array { return [ User::ATTRIBUTE_EMAIL_VERIFIED_AT => 'datetime', User::ATTRIBUTE_PASSWORD => 'hashed', ]; } 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 ($panel->getId() === 'submission') { return $this->hasAnyPermission(SpecialPermission::MAKE_SUBMISSION->value); } 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); } /** * Get the liked entries of the user. * * @return BelongsToMany */ public function likedentries(): BelongsToMany { return $this->belongsToMany( AnimeThemeEntry::class, Like::TABLE, Like::ATTRIBUTE_USER, Like::ATTRIBUTE_LIKEABLE_ID, null, AnimeThemeEntry::ATTRIBUTE_ID ) ->wherePivot(Like::ATTRIBUTE_LIKEABLE_TYPE, Relation::getMorphAlias(AnimeThemeEntry::class)) ->withTimestamps(); } /** * Get the liked playlists of the user. * * @return BelongsToMany */ public function likedplaylists(): BelongsToMany { return $this->belongsToMany( Playlist::class, Like::TABLE, Like::ATTRIBUTE_USER, Like::ATTRIBUTE_LIKEABLE_ID, null, Playlist::ATTRIBUTE_ID ) ->wherePivot(Like::ATTRIBUTE_LIKEABLE_TYPE, Relation::getMorphAlias(Playlist::class)) ->withTimestamps(); } /** * 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 managedsubmissions(): HasMany { return $this->hasMany(Submission::class, Submission::ATTRIBUTE_MODERATOR); } /** * Get the action logs that the user has executed. * * @return HasMany */ public function actionlogs(): HasMany { return $this->hasMany(ActionLog::class, ActionLog::ATTRIBUTE_USER); } /** * @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); } /** * Get the prunable model query. */ public function prunable(): Builder { return static::onlyTrashed()->where( self::ATTRIBUTE_DELETED_AT, ComparisonOperator::LTE->value, now()->subMonth() ); } }