Files
nexusphp/app/Repositories/MedalRepository.php

137 lines
4.7 KiB
PHP
Raw Normal View History

2022-01-19 23:54:55 +08:00
<?php
namespace App\Repositories;
2023-01-30 14:47:02 +08:00
use App\Exceptions\NexusException;
2022-01-19 23:54:55 +08:00
use App\Models\Medal;
2023-01-30 14:47:02 +08:00
use App\Models\Setting;
2022-01-25 23:37:50 +08:00
use App\Models\User;
2022-01-19 23:54:55 +08:00
use App\Models\UserMedal;
2022-01-25 23:37:50 +08:00
use Carbon\Carbon;
2022-07-18 01:37:50 +08:00
use Illuminate\Support\Facades\Auth;
2022-01-19 23:54:55 +08:00
use Nexus\Database\NexusDB;
class MedalRepository extends BaseRepository
{
public function getList(array $params): \Illuminate\Contracts\Pagination\LengthAwarePaginator
{
$query = Medal::query();
list($sortField, $sortType) = $this->getSortFieldAndType($params);
$query->orderBy($sortField, $sortType);
return $query->paginate();
}
public function store(array $params)
{
return Medal::query()->create($params);
}
public function update(array $params, $id)
{
$medal = Medal::query()->findOrFail($id);
$medal->update($params);
return $medal;
}
public function getDetail($id)
{
return Medal::query()->findOrFail($id);
}
/**
* delete a medal, also will delete all user medal.
*
* @param $id
* @return bool
*/
public function delete($id): bool
{
$medal = Medal::query()->findOrFail($id);
NexusDB::transaction(function () use ($medal) {
do {
$deleted = UserMedal::query()->where('medal_id', $medal->id)->limit(10000)->delete();
} while ($deleted > 0);
$medal->delete();
});
return true;
}
2022-01-25 23:37:50 +08:00
public function grantToUser(int $uid, int $medalId, $duration = null)
{
$user = User::query()->findOrFail($uid, User::$commonFields);
2022-07-18 01:37:50 +08:00
if (Auth::user()->class <= $user->class) {
throw new \LogicException("No permission!");
}
2022-01-25 23:37:50 +08:00
$medal = Medal::query()->findOrFail($medalId);
$exists = $user->valid_medals()->where('medal_id', $medalId)->exists();
do_log(last_query());
if ($exists) {
throw new \LogicException("user: $uid already own this medal: $medalId.");
}
$expireAt = null;
if ($duration > 0) {
2025-05-02 21:21:37 +07:00
$expireAt = Carbon::now()->addDays(intval($duration))->toDateTimeString();
2022-01-25 23:37:50 +08:00
}
2022-08-11 19:27:50 +08:00
clear_user_cache($uid);
2022-03-19 14:55:43 +08:00
return $user->medals()->attach([$medal->id => ['expire_at' => $expireAt, 'status' => UserMedal::STATUS_NOT_WEARING]]);
}
public function toggleUserMedalStatus($id, $userId)
2022-03-19 14:55:43 +08:00
{
$userMedal = UserMedal::query()->findOrFail($id);
if ($userMedal->uid != $userId) {
throw new \LogicException("no privilege");
}
$current = $userMedal->status;
if ($current == UserMedal::STATUS_NOT_WEARING) {
2023-06-13 01:53:58 +08:00
$maxWearAllow = Setting::get('system.maximum_number_of_medals_can_be_worn');
$user = User::query()->findOrFail($userId, User::$commonFields);
$wearCount = $user->wearing_medals()->count();
if ($maxWearAllow && $wearCount >= $maxWearAllow) {
throw new NexusException(nexus_trans('medal.max_allow_wearing', ['count' => $maxWearAllow]));
}
2022-03-19 14:55:43 +08:00
$userMedal->status = UserMedal::STATUS_WEARING;
} elseif ($current == UserMedal::STATUS_WEARING) {
$userMedal->status = UserMedal::STATUS_NOT_WEARING;
}
$userMedal->save();
2022-08-21 20:00:11 +08:00
clear_user_cache($userId);
2022-03-19 14:55:43 +08:00
return $userMedal;
2022-01-25 23:37:50 +08:00
}
public function saveUserMedal(int $userId, array $userMedalData)
{
$user = User::query()->findOrFail($userId);
$validMedals = $user->valid_medals;
if ($validMedals->isEmpty()) {
return true;
}
$statusCaseWhens = $priorityCaseWhens = $idArr = [];
2023-01-30 14:47:02 +08:00
$wearCount = 0;
foreach ($validMedals as $medal) {
$id = $medal->pivot->id;
$idArr[] = $id;
if (isset($userMedalData[$id]['status'])) {
$status = UserMedal::STATUS_WEARING;
2023-01-30 14:47:02 +08:00
$wearCount++;
} else {
$status = UserMedal::STATUS_NOT_WEARING;
}
$statusCaseWhens[] = sprintf('when `id` = %s then %s', $id, $status);
$priorityCaseWhens[] = sprintf('when `id` = %s then %s', $id, $userMedalData[$id]['priority'] ?? 0);
}
2023-01-30 14:47:02 +08:00
$maxWearAllow = Setting::get('system.maximum_number_of_medals_can_be_worn');
if ($maxWearAllow && $wearCount > $maxWearAllow) {
throw new NexusException(nexus_trans('medal.max_allow_wearing', ['count' => $maxWearAllow]));
}
$sql = sprintf(
'update user_medals set `status` = case %s end, `priority` = case %s end where id in (%s)',
implode(' ', $statusCaseWhens), implode(' ', $priorityCaseWhens), implode(',', $idArr)
);
do_log("sql: $sql");
clear_user_cache($userId);
return NexusDB::statement($sql);
}
2022-01-19 23:54:55 +08:00
}