Files
Atomcms-edit/app/Models/User.php
T

421 lines
13 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace App\Models;
use App\Models\Articles\WebsiteArticle;
use App\Models\Articles\WebsiteArticleComment;
use App\Models\Community\Staff\WebsiteStaffApplications;
use App\Models\Community\Staff\WebsiteTeam;
use App\Models\Game\Furniture\Item;
use App\Models\Game\Guild\GuildMember;
use App\Models\Game\Permission;
use App\Models\Game\Player\MessengerFriendship;
use App\Models\Game\Player\UserBadge;
use App\Models\Game\Player\UserCurrency;
use App\Models\Game\Player\UserSetting;
use App\Models\Game\Player\UserSubscription;
use App\Models\Game\Room;
use App\Models\Help\WebsiteHelpCenterTicket;
use App\Models\Miscellaneous\CameraWeb;
use App\Models\Miscellaneous\WebsiteBetaCode;
use App\Models\Shop\WebsitePaypalTransaction;
use App\Models\Shop\WebsiteUsedShopVoucher;
use App\Models\User\Ban;
use App\Models\User\ClaimedReferralLog;
use App\Models\User\Referral;
use App\Models\User\UserReferral;
use App\Models\User\WebsiteUserGuestbook;
use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasName;
use Filament\Panel;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Fortify\TwoFactorAuthenticationProvider;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Activitylog\Models\Concerns\LogsActivity;
use Spatie\Activitylog\Support\LogOptions;
/**
* @method static \Illuminate\Database\Eloquent\Builder|User query()
* @method static \Illuminate\Database\Eloquent\Builder|User where($column, $operator = null, $value = null)
* @method static \Illuminate\Database\Eloquent\Builder|User orWhere($column, $operator = null, $value = null)
* @method static \Illuminate\Database\Eloquent\Builder|User find($id, $columns = ['*'])
* @method static \Illuminate\Database\Eloquent\Builder|User first($columns = ['*'])
* @method static \Illuminate\Database\Eloquent\Builder|User create(array $attributes)
* @method static \Illuminate\Database\Eloquent\Builder|User updateOrCreate(array $attributes, array $values = [])
* @method static \Illuminate\Database\Eloquent\Builder|User select($columns = ['*'])
* @method static \Illuminate\Database\Eloquent\Builder|User count($columns = '*')
* @method static \Illuminate\Database\Eloquent\Builder|User get($columns = ['*'])
*
* @property int $id
* @property string $username
* @property string $mail
* @property string $password
* @property string $account_created
* @property string|null $last_login
* @property string|null $last_online
* @property string|null $motto
* @property string $look
* @property int $credits
* @property int $rank
* @property bool $online
* @property string $auth_ticket
* @property string $ip_register
* @property string $ip_current
* @property int $home_room
* @property string|null $referral_code
* @property string|null $two_factor_secret
* @property string|null $two_factor_recovery_codes
* @property string|null $two_factor_confirmed_at
* @property bool|null $hidden_staff
* @property int|null $team_id
* @property int|null $website_balance
* @property int $radio_points
* @property array|null $preferences
* @property-read UserSetting|null $settings
* @property-read Collection<int, UserCurrency> $currencies
* @property-read Ban|null $ban
* @property-read Permission $permission
* @property-read UserReferral|null $referrals
* @property-read Collection<int, Referral> $userReferrals
* @property-read Collection<int, ClaimedReferralLog> $claimedReferralLog
* @property-read Collection<int, UserBadge> $badges
* @property-read Collection<int, Room> $rooms
* @property-read Collection<int, MessengerFriendship> $friends
* @property-read Ban|null $banRelation
* @property-read WebsiteBetaCode|null $betaCode
* @property-read WebsiteTeam|null $team
* @property-read Collection<int, WebsiteStaffApplications> $applications
* @property-read UserSubscription|null $hcSubscription
* @property-read Collection<int, WebsiteArticleComment> $articleComments
* @property-read Collection<int, WebsitePaypalTransaction> $transactions
* @property-read Collection<int, WebsiteUsedShopVoucher> $usedShopVouchers
* @property-read Collection<int, Item> $items
* @property-read Collection<int, WebsiteHelpCenterTicket> $tickets
* @property-read Collection<int, CameraWeb> $photos
* @property-read Collection<int, WebsiteUserGuestbook> $profileGuestbook
* @property-read Collection<int, WebsiteUserGuestbook> $guestbook
* @property-read Collection<int, ChatlogRoom> $chatLogs
* @property-read Collection<int, ChatlogPrivate> $chatLogsPrivate
* @property-read Collection<int, WebsiteArticle> $articles
* @property-read Collection<int, Session> $sessions
*
* @extends Factory<User>
*/
class User extends Authenticatable implements FilamentUser, HasName
{
use HasApiTokens;
use HasFactory;
use LogsActivity;
use Notifiable;
use TwoFactorAuthenticatable;
#[\Override]
public $timestamps = false;
#[\Override]
protected $fillable = ['username', 'mail', 'password', 'account_created', 'last_login', 'motto', 'look', 'credits', 'auth_ticket', 'home_room', 'ip_register', 'ip_current', 'referral_code', 'preferences', 'team_id', 'avatar_background', 'home_background', 'pincode', 'secret_key', 'extra_rank', 'is_hidden', 'background_id', 'background_stand_id', 'background_overlay_id', 'radio_points', 'pixels', 'points', 'online', 'gender', 'rank', 'mail_verified', 'two_factor_secret', 'two_factor_recovery_codes', 'two_factor_confirmed_at'];
#[\Override]
protected $hidden = ['id', 'password', 'remember_token'];
/**
* @return array<string, string>
*/
#[\Override]
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
'hidden_staff' => 'boolean',
'online' => 'boolean',
'preferences' => 'array',
];
}
public function currencies(): HasMany
{
return $this->hasMany(UserCurrency::class, 'user_id');
}
public function sessions(): HasMany
{
return $this->hasMany(Session::class);
}
public function currency(string $currency): int
{
if (! $this->relationLoaded('currencies')) {
$this->load('currencies');
}
$type = match ($currency) {
'duckets' => 0,
'diamonds' => 5,
'points' => 101,
default => 0,
};
return $this->currencies->where('type', $type)->first()->amount ?? 0;
}
public function permission(): HasOne
{
return $this->hasOne(Permission::class, 'id', 'rank');
}
public function articles(): HasMany
{
return $this->hasMany(WebsiteArticle::class);
}
public function referrals(): HasOne
{
return $this->hasOne(UserReferral::class);
}
public function userReferrals(): HasMany
{
return $this->hasMany(Referral::class);
}
public function claimedReferralLog(): HasMany
{
return $this->hasMany(ClaimedReferralLog::class);
}
public function badges(): HasMany
{
return $this->hasMany(UserBadge::class);
}
public function rooms(): HasMany
{
return $this->hasMany(Room::class, 'owner_id');
}
public function friends(): HasMany
{
return $this->hasMany(MessengerFriendship::class, 'user_one_id');
}
public function referralsNeeded(): int
{
$referrals = $this->referrals?->referrals_total ?? 0;
return (int) setting('referrals_needed') - (int) $referrals;
}
public function ban(): HasOne
{
return $this->hasOne(Ban::class, 'user_id')
->where('ban_expire', '>', time())
->whereIn('type', ['account', 'super'])
->withoutGlobalScopes();
}
public function settings(): HasOne
{
return $this->hasOne(UserSetting::class);
}
public function ssoTicket(): string
{
$hotelName = Str::replace(' ', '', (string) setting('hotel_name'));
$sso = sprintf('%s-%s', $hotelName, Str::uuid()->toString());
$this->update([
'auth_ticket' => $sso,
'ip_current' => request()->ip(),
]);
return $sso;
}
public function betaCode(): HasOne
{
return $this->hasOne(WebsiteBetaCode::class);
}
public function team(): BelongsTo
{
return $this->belongsTo(WebsiteTeam::class, 'team_id');
}
public function applications(): HasMany
{
return $this->hasMany(WebsiteStaffApplications::class, 'user_id');
}
public function hcSubscription(): HasOne
{
return $this->hasOne(UserSubscription::class);
}
public function articleComments(): HasMany
{
return $this->hasMany(WebsiteArticleComment::class);
}
public function transactions(): HasMany
{
return $this->hasMany(WebsitePaypalTransaction::class);
}
public function usedShopVouchers(): HasMany
{
return $this->hasMany(WebsiteUsedShopVoucher::class);
}
public function items(): HasMany
{
return $this->hasMany(Item::class, 'user_id');
}
public function tickets(): HasMany
{
return $this->hasMany(WebsiteHelpCenterTicket::class);
}
public function photos(): HasMany
{
return $this->hasMany(CameraWeb::class);
}
public function guilds(): HasMany
{
return $this->hasMany(GuildMember::class, 'user_id');
}
public function profileGuestbook(): HasMany
{
return $this->hasMany(WebsiteUserGuestbook::class, 'profile_id');
}
public function guestbook(): HasMany
{
return $this->hasMany(WebsiteUserGuestbook::class, 'user_id');
}
public function chatLogs(): HasMany
{
return $this->hasMany(ChatlogRoom::class, 'user_from_id');
}
public function chatLogsPrivate(): HasMany
{
return $this->hasMany(ChatlogPrivate::class, 'user_from_id');
}
public function socialAccounts(): HasMany
{
return $this->hasMany(SocialAccount::class);
}
public function hasSocialAccount(string $provider): bool
{
return $this->socialAccounts()->where('provider', $provider)->exists();
}
public function getOnlineFriends(int $total = 10): Collection
{
return $this->friends()
->select(['user_two_id', 'users.id', 'users.username', 'users.look', 'users.motto', 'users.last_online'])
->join('users', 'users.id', '=', 'user_two_id')
->where('users.online', '1')
->inRandomOrder()
->limit($total)
->get()
->map(fn ($item) => (new User)->forceFill([
'id' => $item->id,
'username' => $item->username,
'look' => $item->look,
'motto' => $item->motto,
'last_online' => $item->last_online,
]));
}
public function confirmTwoFactorAuthentication(string $code): bool
{
$secret = $this->two_factor_secret;
if ($secret === null) {
return false;
}
$codeIsValid = app(TwoFactorAuthenticationProvider::class)
->verify(decrypt((string) $secret), $code);
if (! $codeIsValid) {
return false;
}
$this->update(['two_factor_confirmed' => true]);
return true;
}
public function hasAppliedForPosition(int $rankId): bool
{
return $this->applications()->where('rank_id', $rankId)->exists();
}
public function changePassword(string $newPassword): void
{
$this->password = Hash::make($newPassword);
$this->save();
}
public function getFilamentName(): string
{
return $this->username ?? 'Guest';
}
public function canAccessPanel(Panel $panel): bool
{
return hasHousekeepingPermission('can_access_housekeeping');
}
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()
->logOnly(['id', 'username', 'motto', 'rank', 'credits'])
->logOnlyDirty();
}
/**
* @param array<string, mixed> $options
*/
#[\Override]
public function save(array $options = []): bool
{
if (! $this->isDirty()) {
return false;
}
return parent::save($options);
}
public function hasAppliedForTeam(int $teamId): bool
{
if ($teamId === 0) {
return false;
}
return $this->applications()
->where('team_id', $teamId)
->exists();
}
}