%PDF- %PDF-
Direktori : /www/loslex/production/app/Models/ |
Current File : /www/loslex/production/app/Models/User.php |
<?php namespace App\Models; use App\Models\Registration; use Carbon\CarbonImmutable; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable implements MustVerifyEmail { use HasApiTokens, HasFactory, Notifiable, SoftDeletes; /** * The attributes that are mass assignable. * * @var array<int, string> */ protected $fillable = [ 'firstname', 'lastname', 'username', 'namesuffix', 'city', 'email', 'password', 'licence_number', 'phone_number', 'lex_hash', 'last_login', 'ban_reason', 'personaltoken', ]; /** * The attributes that should be hidden for serialization. * @var array<int, string> */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast. * @var array<string, string> */ protected $casts = [ 'email_verified_at' => 'datetime', 'lex_validity' => 'date', ]; /** * Send the email verification notification. * @return void */ public function sendEmailVerificationNotification() { $this->notify(new \App\Core\Auth\VerifyEmail); Log::info("Sent verification email to {$this->username}", ['user' => $this->id]); } /** Concatenate First and Last name and NameSuffix to display on the web */ public function displayname(): Attribute { return Attribute::make( get: fn (mixed $value, array $attr) => implode(" ", array_filter([$attr['firstname'], $attr['lastname'], $attr['namesuffix']])) ); } /** Anonymization of the display name */ public function displayanonname(): Attribute { return Attribute::make( get: fn (mixed $value, array $attr) => implode(" ", array_filter([ Str::mask($attr['firstname'], '*', 1), Str::mask($attr['lastname'], '*', 1), Str::mask($attr['namesuffix'], '*', 1) ])) ); } public function phone_number_formatted() { $nospace = str_replace(' ', '', $this->phone_number); return preg_replace('/(\+\d{3})?(\d{3})(\d{3})(\d{3})/', '$1 $2 $3 $4', $nospace); } public function listedname(): Attribute { return Attribute::make( get: fn (mixed $value, array $attr) => implode(" ", array_filter([$attr['lastname'], $attr['firstname'], $attr['namesuffix']])) ); } public function organizer_groups(): BelongsToMany { return $this->belongsToMany(OrganizerGroup::class, 'organizer_group_users', 'user_id', 'organizer_group_id'); } public function registrations(): HasMany { return $this->hasMany(Registration::class); } public function dqsList($date = null, $monthsShift = 12) { $imuDate = $date === null ? new CarbonImmutable(Carbon::today()) : new CarbonImmutable($date); return $this->registrations ->where('dq', 1) ->whereBetween('contest.date', [$imuDate->subMonths($monthsShift), $imuDate] ); } public function dqs($date = null, $monthsShift = 12): int { return $this->dqsList()->count(); } /** * Verifies whether user is member of given organier group */ public function is_organizer_member($organizerid): bool { return $this->organizer_groups->pluck('id')->contains($organizerid); } /** * Checks and stores validity of LEX membership to the given (or current) date. */ public function is_valid_member(Carbon $contestdate = null): int { if (is_null($this->lex_hash)) { return -2; } // any value at all if (!preg_match("/[a-zA-Z0-9]{8}/", $this->lex_hash)) { return -1; } // correct format? if ($contestdate === null) { $contestdate = Carbon::now(); } // No date given. if (empty($this->lex_validity) || $this->lex_validity->lt($contestdate)) { // this is called only if there is no cached validity or is expired // GET user data from LEX $url = "https://k.gunlex.cz/{$this->lex_hash}?json"; $lexJSON = file_get_contents($url); $decoded = json_decode($lexJSON, false); // No member number means the hash could not be found in LEX DB if (!$decoded?->member || $decoded?->member == "NULL") { return -1; } // parse validity date and save into DB $dateval = Carbon::parse($decoded->validity); $this->lex_validity = $dateval; $this->save(); } else { $dateval = $this->lex_validity; // return cached value } return $dateval->lt($contestdate) ? 0 : 1; // membership expiresbefore contestdate : membership valid } public function is_username_guid(): bool { return preg_match("/^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$/", $this->username); } }