%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /mnt/tnb2/git/loslex/app/Models/
Upload File :
Create Path :
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);
    }
}

Zerion Mini Shell 1.0