'datetime', 'last_seen' => 'datetime', 'credits' => 'float', 'server_limit' => 'float', 'email_verified_reward' => 'boolean' ]; public static function boot() { parent::boot(); static::created(function (User $user) { $user->notify(new WelcomeMessage($user)); }); static::deleting(function (User $user) { // delete every server the user owns without using chunks $user->servers()->each(function ($server) { $server->delete(); }); $user->payments()->delete(); $user->tickets()->delete(); $user->ticketBlackList()->delete(); $user->vouchers()->detach(); $user->discordUser()->delete(); Pterodactyl::client()->delete("/application/users/{$user->pterodactyl_id}"); }); } /** * @return HasMany */ public function servers() { return $this->hasMany(Server::class); } /** * @return HasMany */ public function payments() { return $this->hasMany(Payment::class); } /** * @return HasMany */ public function tickets() { return $this->hasMany(Ticket::class); } /** * @return HasMany */ public function ticketBlackList() { return $this->hasMany(TicketBlacklist::class); } /** * @return BelongsToMany */ public function vouchers() { return $this->belongsToMany(Voucher::class); } /** * @return HasOne */ public function discordUser() { return $this->hasOne(DiscordUser::class); } public function sendEmailVerificationNotification() { $this->notify(new QueuedVerifyEmail); } /** * @return string */ public function credits() { return number_format($this->credits, 2, '.', ''); } /** * @return bool */ public function isSuspended() { return $this->suspended; } /** * @throws Exception */ public function suspend() { foreach ($this->servers as $server) { $server->suspend(); } $this->update([ 'suspended' => true, ]); return $this; } /** * @throws Exception */ public function unSuspend() { foreach ($this->getServersWithProduct() as $server) { if ($this->credits >= $server->product->getHourlyPrice()) { $server->unSuspend(); } } $this->update([ 'suspended' => false, ]); return $this; } private function getServersWithProduct() { return $this->servers() ->with('product') ->get(); } /** * @return string */ public function getAvatar() { //TODO loading the images to confirm they exist is causing to much load time. alternative has to be found :) maybe onerror tag on the // if ($this->discordUser()->exists()) { // if(@getimagesize($this->discordUser->getAvatar())) { // $avatar = $this->discordUser->getAvatar(); // } else { // $avatar = "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email))); // } // } else { // $avatar = "https://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email))); // } return 'https://www.gravatar.com/avatar/' . md5(strtolower(trim($this->email))); } /** * @return string */ public function creditUsage() { $usage = 0; foreach ($this->getServersWithProduct() as $server) { $usage += $server->product->price; } return number_format($usage, 2, '.', ''); } /** * @return array|string|string[] */ public function getVerifiedStatus() { $status = ''; if ($this->hasVerifiedEmail()) { $status .= 'email '; } if ($this->discordUser()->exists()) { $status .= 'discord'; } $status = str_replace(' ', '/', $status); return $status; } public function verifyEmail() { $this->forceFill([ 'email_verified_at' => now(), ])->save(); } public function reVerifyEmail() { $this->forceFill([ 'email_verified_at' => null ])->save(); } public function getActivitylogOptions(): LogOptions { return LogOptions::defaults() ->logOnly(['role', 'name', 'server_limit', 'pterodactyl_id', 'email']) ->logOnlyDirty() ->dontSubmitEmptyLogs(); } }