%PDF- %PDF-
| Direktori : /www/loslex/test/app/Livewire/ |
| Current File : /www/loslex/test/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
}
}