%PDF- %PDF-
Direktori : /mnt/tnb2/git/loslex/app/Models/ |
Current File : //mnt/tnb2/git/loslex/app/Models/Contest.php |
<?php namespace App\Models; use App\Models\User; use App\Models\Range; use App\Models\ContestLevel; use App\Models\Registration; use Illuminate\Http\Request; use App\Models\OrganizerGroup; use Illuminate\Support\Carbon; use App\Models\ContestCategory; use App\Models\ContestDivision; use Illuminate\Support\Facades\App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasManyThrough; class Contest extends Model { use HasFactory; protected $fillable = [ 'published', 'contestname', 'range_id', 'organizer_group_id', 'date', 'contest_category_id', 'contest_level_id', 'registration_start', 'registration_end', 'director_id', 'rangemaster_id', 'instructions', // 'settings', ]; protected $casts = [ 'settings' => 'array', 'date' => 'date', 'registration_start' => 'datetime', 'registration_end' => 'datetime' ]; /* fill values into JSON Settings field */ public function fillSettings(Request $request) { $fields = array( "presentation_start", "presentation_end", "contest_start", "contest_end", "stages", "squads", "capacity", "feebasic", "feelex", "calibrationwpn", "secretstages", "flashlight", "restrictions", "restrictionstext", "squadshootstyle", ); $trimfields = array("presentation_start", "presentation_end", "contest_start", "contest_end"); $data = array(); foreach ($fields as $key) { switch($key) { case "restrictions": $data[$key] = $request->input($key) ?? 0; break; case "restrictionstext": if (!empty($request->input("restrictions"))) $data[$key] = $this->normalizeInstructions($request->input($key)); break; default: $data[$key] = $request->input($key); break; } } // if squad shoots together no need to store separate times. // OTOH we need to store the null for [0] field to avoid array shifting when reading to use in contest if ($request->squadshootstyle == 'together') { foreach ($trimfields as $key) { $data[$key] = array_splice($data[$key], 0, 1); } } $this->settings = $data; } protected function normalizeInstructions(String $instructions) : String { $result = trim($instructions); // trim starting and ending shitespaces $result = str_replace(array("\r\n", "\r", "\n"), "\n", $result); // replace all wariants to single \n $result = preg_replace("/\n{3,}/", "\n\n", $result); // avoid extra whitespacing of the of the content return $result; } public function instructions(): Attribute { return Attribute::make( get: fn ($value) => $value, set: fn ($value) => $this->normalizeInstructions($value), ); } /* ========== ========== Custom settings attributes ========== ========== */ public function squadShootStyle(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['squadshootstyle'] : null); } public function presentationStart(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['presentation_start'] : null); } public function presentationEnd(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['presentation_end'] : null); } public function contestStart(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['contest_start'] : null); } public function contestEnd(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['contest_end'] : null); } public function capacity(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['capacity'] : 0); } public function squads(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['squads'] : 0); } public function stages(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['stages'] : 0); } public function calibrationwpn(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['calibrationwpn'] : null); } public function secretstages(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['secretstages'] : 0); } public function flashlight(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['flashlight'] : 0); } public function restrictions(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['restrictions'] : 0); } public function restrictionstext(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) && $this->restrictions ? $this->settings['restrictionstext'] : null); } public function feebasic(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['feebasic'] : 0); } public function feelex(): Attribute { return Attribute::make(get: fn ($value) => !is_null($this->settings) ? $this->settings['feelex'] : null); } public function offisiteregurl(): Attribute { return Attribute::make(get: fn ($value) => $this->settings['offsiteregurl'] ?? ""); } /* ========== ========== Other helpers ========== ========== */ public function isRegActive(): Attribute { $locale = App::currentLocale(); $now = Carbon::now()->locale($locale); $result = $now->gte($this->registration_start) && $now->lte($this->registration_end); return Attribute::make( get: fn() => $result, ); } public function isBeforeReg(): Attribute { $locale = App::currentLocale(); $now = Carbon::now()->locale($locale); $regStart = Carbon::parse($this->registration_start)->locale($locale); return Attribute::make( get: fn () => $now->lt($regStart), ); } public function isAfterReg(): Attribute { $locale = App::currentLocale(); $now = Carbon::now()->locale($locale); $regEnd = Carbon::parse($this->registration_end)->locale($locale); return Attribute::make( get: fn () => $now->gt($regEnd), ); } // /* Get the localized date formats */ public function dateDay(): Attribute { $this->date->settings(['formatFunction' => 'translatedFormat']); return Attribute::make(get: fn () => $this->date->format('d')); } public function dateMth(): Attribute { $locale = App::currentLocale(); $dateval = Carbon::parse($this->date)->locale($locale); $dateval->settings(['formatFunction' => 'translatedFormat']); return Attribute::make(get: fn () => $dateval->format('M')); } public function dateDow(): Attribute { $locale = App::currentLocale(); $dateval = Carbon::parse($this->date)->locale($locale); $dateval->settings(['formatFunction' => 'translatedFormat']); return Attribute::make(get: fn () => $dateval->format('l')); } public function squadSize(): Attribute { return Attribute::make( get: function() { $base = intdiv($this->capacity, $this->squads); $arr = array_fill(1, $this->squads, $base); $reduction = array_reduce($arr, function($res, $a) { return $res + $a; }, 0); if ($reduction == $this->capacity) return $arr; for ($i = 1; $i < $this->squads; $i++) { $arr[$i]++; $reduction = array_reduce($arr, function($res, $a) { return $res + $a; }, 0); if ($reduction == $this->capacity) return $arr; } } ); } public function divisionCounts(): Attribute { return Attribute::make( get: function() { return $this->registrations->groupBy(function(Registration $item, int $key) { return $item->division->bgdivision; })->map->count(); } ); } /* ========== ========== Foreign keys ========== ========== */ /* Get the level of contest/event is placed */ /* @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function contest_level(): BelongsTo { return $this->belongsTo(ContestLevel::class); } /* Get the category of contest */ /* @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function contest_category(): BelongsTo { return $this->belongsTo(ContestCategory::class); } // /* Get the category of contest */ // /* @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ // public function contest_division(): BelongsTo // { // return $this->belongsTo(ContestDivision::class); // } /* Get the range where contest is placed */ /* @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function range(): BelongsTo { return $this->belongsTo(Range::class); } /* Get the organizer that owns the Contest */ /* @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function organizer_group(): BelongsTo { return $this->belongsTo(OrganizerGroup::class); } /* Get the organizer that owns the Contest */ /* @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function organizer(): BelongsTo { return $this->belongsTo(OrganizerGroup::class); } /* Get the director of the Contest */ /* @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function director(): BelongsTo { return $this->belongsTo(User::class); } /* Get the range master of the Contest */ /* @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function rangemaster(): BelongsTo { return $this->belongsTo(User::class); } /* Registrations for given contest */ /* @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function registrations() : HasMany { return $this->hasMany(Registration::class); } }