mirror of
https://github.com/sp-tarkov/forge.git
synced 2025-02-12 12:10:41 -05:00
Resolves Remaining Larastan Issues
This commit is contained in:
parent
bbb8fab1a1
commit
d9b7d6fcc8
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Jobs\ImportHubDataJob;
|
||||
use App\Jobs\Import\ImportHubDataJob;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class ImportHubCommand extends Command
|
||||
|
@ -2,9 +2,13 @@
|
||||
|
||||
namespace App\Http\Filters\V1;
|
||||
|
||||
use App\Models\Mod;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @extends QueryFilter<Mod>
|
||||
*/
|
||||
class ModFilter extends QueryFilter
|
||||
{
|
||||
protected array $sortable = [
|
||||
@ -23,6 +27,11 @@ class ModFilter extends QueryFilter
|
||||
// TODO: Many of these are repeated across UserFilter and ModFilter. Consider refactoring into a shared trait.
|
||||
// Also, consider using common filter types and making the field names dynamic.
|
||||
|
||||
/**
|
||||
* Filter by ID.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function id(string $value): Builder
|
||||
{
|
||||
$ids = array_map('trim', explode(',', $value));
|
||||
@ -30,6 +39,11 @@ class ModFilter extends QueryFilter
|
||||
return $this->builder->whereIn('id', $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by hub ID.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function hub_id(string $value): Builder
|
||||
{
|
||||
$ids = array_map('trim', explode(',', $value));
|
||||
@ -37,6 +51,11 @@ class ModFilter extends QueryFilter
|
||||
return $this->builder->whereIn('hub_id', $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by name.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function name(string $value): Builder
|
||||
{
|
||||
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
|
||||
@ -45,6 +64,11 @@ class ModFilter extends QueryFilter
|
||||
return $this->builder->where('name', 'like', $like);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by slug.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function slug(string $value): Builder
|
||||
{
|
||||
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
|
||||
@ -53,6 +77,11 @@ class ModFilter extends QueryFilter
|
||||
return $this->builder->where('slug', 'like', $like);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by teaser.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function teaser(string $value): Builder
|
||||
{
|
||||
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
|
||||
@ -61,6 +90,11 @@ class ModFilter extends QueryFilter
|
||||
return $this->builder->where('teaser', 'like', $like);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by source code link.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function source_code_link(string $value): Builder
|
||||
{
|
||||
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
|
||||
@ -69,6 +103,11 @@ class ModFilter extends QueryFilter
|
||||
return $this->builder->where('source_code_link', 'like', $like);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by created at date.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function created_at(string $value): Builder
|
||||
{
|
||||
// The API allows for a range of dates to be passed as a comma-separated list.
|
||||
@ -80,6 +119,11 @@ class ModFilter extends QueryFilter
|
||||
return $this->builder->whereDate('created_at', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by updated at date.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function updated_at(string $value): Builder
|
||||
{
|
||||
// The API allows for a range of dates to be passed as a comma-separated list.
|
||||
@ -91,6 +135,11 @@ class ModFilter extends QueryFilter
|
||||
return $this->builder->whereDate('updated_at', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by published at date.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function published_at(string $value): Builder
|
||||
{
|
||||
// The API allows for a range of dates to be passed as a comma-separated list.
|
||||
@ -102,6 +151,11 @@ class ModFilter extends QueryFilter
|
||||
return $this->builder->whereDate('published_at', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by featured.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function featured(string $value): Builder
|
||||
{
|
||||
// We need to convert the string user input to a boolean, or null if it's not a valid "truthy/falsy" value.
|
||||
@ -115,6 +169,11 @@ class ModFilter extends QueryFilter
|
||||
return $this->builder->where('featured', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by contains ads.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function contains_ads(string $value): Builder
|
||||
{
|
||||
// We need to convert the string user input to a boolean, or null if it's not a valid "truthy/falsy" value.
|
||||
@ -128,6 +187,11 @@ class ModFilter extends QueryFilter
|
||||
return $this->builder->where('contains_ads', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by contains AI content.
|
||||
*
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function contains_ai_content(string $value): Builder
|
||||
{
|
||||
// We need to convert the string user input to a boolean, or null if it's not a valid "truthy/falsy" value.
|
||||
|
@ -3,15 +3,25 @@
|
||||
namespace App\Http\Filters\V1;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @template TModelClass of Model
|
||||
*/
|
||||
abstract class QueryFilter
|
||||
{
|
||||
/**
|
||||
* The query builder instance.
|
||||
*
|
||||
* @var Builder<TModelClass>
|
||||
*/
|
||||
protected Builder $builder;
|
||||
|
||||
protected Request $request;
|
||||
|
||||
/** @var array<string> */
|
||||
protected array $sortable = [];
|
||||
|
||||
public function __construct(Request $request)
|
||||
@ -19,6 +29,12 @@ abstract class QueryFilter
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the filter to the query builder.
|
||||
*
|
||||
* @param Builder<TModelClass> $builder
|
||||
* @return Builder<TModelClass>
|
||||
*/
|
||||
public function apply(Builder $builder): Builder
|
||||
{
|
||||
$this->builder = $builder;
|
||||
@ -32,17 +48,11 @@ abstract class QueryFilter
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
protected function filter(array $filters): Builder
|
||||
{
|
||||
foreach ($filters as $attribute => $value) {
|
||||
if (method_exists($this, $attribute)) {
|
||||
$this->$attribute($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the sort type to the query.
|
||||
*
|
||||
* @return Builder<TModelClass>
|
||||
*/
|
||||
protected function sort(string $values): Builder
|
||||
{
|
||||
$sortables = array_map('trim', explode(',', $values));
|
||||
|
@ -2,11 +2,20 @@
|
||||
|
||||
namespace App\Http\Filters\V1;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @extends QueryFilter<User>
|
||||
*/
|
||||
class UserFilter extends QueryFilter
|
||||
{
|
||||
/**
|
||||
* The sortable fields.
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
protected array $sortable = [
|
||||
'name',
|
||||
'created_at',
|
||||
@ -16,6 +25,11 @@ class UserFilter extends QueryFilter
|
||||
// TODO: Many of these are repeated across UserFilter and ModFilter. Consider refactoring into a shared trait.
|
||||
// Also, consider using common filter types and making the field names dynamic.
|
||||
|
||||
/**
|
||||
* Filter by ID.
|
||||
*
|
||||
* @return Builder<User>
|
||||
*/
|
||||
public function id(string $value): Builder
|
||||
{
|
||||
$ids = array_map('trim', explode(',', $value));
|
||||
@ -23,6 +37,11 @@ class UserFilter extends QueryFilter
|
||||
return $this->builder->whereIn('id', $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by name.
|
||||
*
|
||||
* @return Builder<User>
|
||||
*/
|
||||
public function name(string $value): Builder
|
||||
{
|
||||
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
|
||||
@ -31,6 +50,11 @@ class UserFilter extends QueryFilter
|
||||
return $this->builder->where('name', 'like', $like);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by created at date.
|
||||
*
|
||||
* @return Builder<User>
|
||||
*/
|
||||
public function created_at(string $value): Builder
|
||||
{
|
||||
// The API allows for a range of dates to be passed as a comma-separated list.
|
||||
@ -42,6 +66,11 @@ class UserFilter extends QueryFilter
|
||||
return $this->builder->whereDate('created_at', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by updated at date.
|
||||
*
|
||||
* @return Builder<User>
|
||||
*/
|
||||
public function updated_at(string $value): Builder
|
||||
{
|
||||
// The API allows for a range of dates to be passed as a comma-separated list.
|
||||
|
@ -16,6 +16,8 @@ class LoginUserRequest extends FormRequest
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
@ -16,11 +16,11 @@ class StoreModRequest extends FormRequest
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@ -16,11 +16,11 @@ class StoreUserRequest extends FormRequest
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@ -16,11 +16,11 @@ class UpdateModRequest extends FormRequest
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@ -16,11 +16,11 @@ class UpdateUserRequest extends FormRequest
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,11 @@ use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ModRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
@ -18,6 +23,9 @@ class ModRequest extends FormRequest
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
|
@ -9,6 +9,11 @@ use Illuminate\Http\Resources\Json\JsonResource;
|
||||
/** @mixin License */
|
||||
class LicenseResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
|
@ -12,6 +12,8 @@ class ModResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
|
@ -11,6 +11,8 @@ class ModVersionResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
@ -32,7 +34,6 @@ class ModVersionResource extends JsonResource
|
||||
// downloads that are made, so we'll need a new route/feature for that. #35
|
||||
'link' => $this->link,
|
||||
|
||||
'spt_version_id' => $this->spt_version_id,
|
||||
'virus_total_link' => $this->virus_total_link,
|
||||
'downloads' => $this->downloads,
|
||||
'created_at' => $this->created_at,
|
||||
@ -44,7 +45,6 @@ class ModVersionResource extends JsonResource
|
||||
[
|
||||
'data' => [
|
||||
'type' => 'spt_version',
|
||||
'id' => $this->spt_version_id,
|
||||
],
|
||||
],
|
||||
],
|
||||
|
@ -10,6 +10,11 @@ use Illuminate\Http\Resources\Json\JsonResource;
|
||||
/** @mixin User */
|
||||
class UserResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
|
@ -9,6 +9,11 @@ use Illuminate\Http\Resources\Json\JsonResource;
|
||||
/** @mixin UserRole */
|
||||
class UserRoleResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
|
@ -2,12 +2,18 @@
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\License;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/** @mixin \App\Models\License */
|
||||
/** @mixin License */
|
||||
class LicenseResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
|
@ -2,12 +2,18 @@
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\Mod;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/** @mixin \App\Models\Mod */
|
||||
/** @mixin Mod */
|
||||
class ModResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
|
@ -2,12 +2,18 @@
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\ModVersion;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/** @mixin \App\Models\ModVersion */
|
||||
/** @mixin ModVersion */
|
||||
class ModVersionResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
@ -19,10 +25,7 @@ class ModVersionResource extends JsonResource
|
||||
'description' => $this->description,
|
||||
'virus_total_link' => $this->virus_total_link,
|
||||
'downloads' => $this->downloads,
|
||||
|
||||
'mod_id' => $this->mod_id,
|
||||
'spt_version_id' => $this->spt_version_id,
|
||||
|
||||
'mod' => new ModResource($this->whenLoaded('mod')),
|
||||
'sptVersion' => new SptVersionResource($this->whenLoaded('sptVersion')),
|
||||
];
|
||||
|
@ -2,12 +2,18 @@
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\SptVersion;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
/** @mixin \App\Models\SptVersion */
|
||||
/** @mixin SptVersion */
|
||||
class SptVersionResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
|
23
app/Jobs/Import/DataTransferObjects/HubUser.php
Normal file
23
app/Jobs/Import/DataTransferObjects/HubUser.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Import\DataTransferObjects;
|
||||
|
||||
class HubUser
|
||||
{
|
||||
public function __construct(
|
||||
public int $userID,
|
||||
public string $username,
|
||||
public string $email,
|
||||
public string $password,
|
||||
public string $registrationDate,
|
||||
public ?bool $banned,
|
||||
public ?string $banReason,
|
||||
public ?string $banExpires,
|
||||
public ?string $coverPhotoHash,
|
||||
public ?string $coverPhotoExtension,
|
||||
public ?int $rankID,
|
||||
public ?string $rankTitle,
|
||||
) {
|
||||
//
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
namespace App\Jobs\Import;
|
||||
|
||||
use App\Jobs\Import\DataTransferObjects\HubUser;
|
||||
use App\Models\License;
|
||||
use App\Models\Mod;
|
||||
use App\Models\ModVersion;
|
||||
@ -306,14 +307,29 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||
$userData = $bannedUsers = $userRanks = [];
|
||||
|
||||
foreach ($users as $user) {
|
||||
$userData[] = $this->collectUserData($curl, $user);
|
||||
$hubUser = new HubUser(
|
||||
$user->userID,
|
||||
$user->username,
|
||||
$user->email,
|
||||
$user->password,
|
||||
$user->registrationDate,
|
||||
$user->banned,
|
||||
$user->banReason,
|
||||
$user->banExpires,
|
||||
$user->coverPhotoHash,
|
||||
$user->coverPhotoExtension,
|
||||
$user->rankID,
|
||||
$user->rankTitle
|
||||
);
|
||||
|
||||
$bannedUserData = $this->collectBannedUserData($user);
|
||||
$userData[] = $this->collectUserData($curl, $hubUser);
|
||||
|
||||
$bannedUserData = $this->collectBannedUserData($hubUser);
|
||||
if ($bannedUserData) {
|
||||
$bannedUsers[] = $bannedUserData;
|
||||
}
|
||||
|
||||
$userRankData = $this->collectUserRankData($user);
|
||||
$userRankData = $this->collectUserRankData($hubUser);
|
||||
if ($userRankData) {
|
||||
$userRanks[] = $userRankData;
|
||||
}
|
||||
@ -328,16 +344,21 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||
curl_close($curl);
|
||||
}
|
||||
|
||||
protected function collectUserData(CurlHandle $curl, object $user): array
|
||||
/**
|
||||
* Build an array of user data ready to be inserted into the local database.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
protected function collectUserData(CurlHandle $curl, HubUser $hubUser): array
|
||||
{
|
||||
return [
|
||||
'hub_id' => (int) $user->userID,
|
||||
'name' => $user->username,
|
||||
'email' => Str::lower($user->email),
|
||||
'password' => $this->cleanPasswordHash($user->password),
|
||||
'profile_photo_path' => $this->fetchUserAvatar($curl, $user),
|
||||
'cover_photo_path' => $this->fetchUserCoverPhoto($curl, $user),
|
||||
'created_at' => $this->cleanRegistrationDate($user->registrationDate),
|
||||
'hub_id' => (int) $hubUser->userID,
|
||||
'name' => $hubUser->username,
|
||||
'email' => Str::lower($hubUser->email),
|
||||
'password' => $this->cleanPasswordHash($hubUser->password),
|
||||
'profile_photo_path' => $this->fetchUserAvatar($curl, $hubUser),
|
||||
'cover_photo_path' => $this->fetchUserCoverPhoto($curl, $hubUser),
|
||||
'created_at' => $this->cleanRegistrationDate($hubUser->registrationDate),
|
||||
'updated_at' => now('UTC')->toDateTimeString(),
|
||||
];
|
||||
}
|
||||
@ -358,10 +379,10 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||
/**
|
||||
* Fetch the user avatar from the Hub and store it anew.
|
||||
*/
|
||||
protected function fetchUserAvatar(CurlHandle $curl, object $user): string
|
||||
protected function fetchUserAvatar(CurlHandle $curl, HubUser $hubUser): string
|
||||
{
|
||||
// Fetch the user's avatar data from the temporary table.
|
||||
$avatar = DB::table('temp_user_avatar')->where('userID', $user->userID)->first();
|
||||
$avatar = DB::table('temp_user_avatar')->where('userID', $hubUser->userID)->first();
|
||||
|
||||
if (! $avatar) {
|
||||
return '';
|
||||
@ -410,15 +431,15 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||
/**
|
||||
* Fetch the user avatar from the Hub and store it anew.
|
||||
*/
|
||||
protected function fetchUserCoverPhoto(CurlHandle $curl, object $user): string
|
||||
protected function fetchUserCoverPhoto(CurlHandle $curl, HubUser $hubUser): string
|
||||
{
|
||||
if (empty($user->coverPhotoHash) || empty($user->coverPhotoExtension)) {
|
||||
if (empty($hubUser->coverPhotoHash) || empty($hubUser->coverPhotoExtension)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$hashShort = substr($user->coverPhotoHash, 0, 2);
|
||||
$fileName = $user->coverPhotoHash.'.'.$user->coverPhotoExtension;
|
||||
$hubUrl = 'https://hub.sp-tarkov.com/images/coverPhotos/'.$hashShort.'/'.$user->userID.'-'.$fileName;
|
||||
$hashShort = substr($hubUser->coverPhotoHash, 0, 2);
|
||||
$fileName = $hubUser->coverPhotoHash.'.'.$hubUser->coverPhotoExtension;
|
||||
$hubUrl = 'https://hub.sp-tarkov.com/images/coverPhotos/'.$hashShort.'/'.$hubUser->userID.'-'.$fileName;
|
||||
$relativePath = 'user-covers/'.$fileName;
|
||||
|
||||
return $this->fetchAndStoreImage($curl, $hubUrl, $relativePath);
|
||||
@ -441,14 +462,16 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||
|
||||
/**
|
||||
* Build an array of banned user data ready to be inserted into the local database.
|
||||
*
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
protected function collectBannedUserData($user): ?array
|
||||
protected function collectBannedUserData(HubUser $hubUser): ?array
|
||||
{
|
||||
if ($user->banned) {
|
||||
if ($hubUser->banned) {
|
||||
return [
|
||||
'hub_id' => (int) $user->userID,
|
||||
'comment' => $user->banReason ?? '',
|
||||
'expired_at' => $this->cleanUnbannedAtDate($user->banExpires),
|
||||
'hub_id' => (int) $hubUser->userID,
|
||||
'comment' => $hubUser->banReason ?? '',
|
||||
'expired_at' => $this->cleanUnbannedAtDate($hubUser->banExpires),
|
||||
];
|
||||
}
|
||||
|
||||
@ -495,12 +518,17 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||
}
|
||||
}
|
||||
|
||||
protected function collectUserRankData($user): ?array
|
||||
/**
|
||||
* Build an array of user rank data ready to be inserted into the local database.
|
||||
*
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
protected function collectUserRankData(HubUser $hubUser): ?array
|
||||
{
|
||||
if ($user->rankID && $user->rankTitle) {
|
||||
if ($hubUser->rankID && $hubUser->rankTitle) {
|
||||
return [
|
||||
'hub_id' => (int) $user->userID,
|
||||
'title' => $user->rankTitle,
|
||||
'hub_id' => (int) $hubUser->userID,
|
||||
'title' => $hubUser->rankTitle,
|
||||
];
|
||||
}
|
||||
|
||||
@ -509,8 +537,10 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||
|
||||
/**
|
||||
* Insert or update the users in the local database.
|
||||
*
|
||||
* @param array<array<string, mixed>> $usersData
|
||||
*/
|
||||
protected function upsertUsers($usersData): void
|
||||
protected function upsertUsers(array $usersData): void
|
||||
{
|
||||
if (! empty($usersData)) {
|
||||
DB::table('users')->upsert($usersData, ['hub_id'], [
|
||||
@ -525,8 +555,10 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||
|
||||
/**
|
||||
* Fetch the hub-banned users from the local database and ban them locally.
|
||||
*
|
||||
* @param array<array<string, mixed>> $bannedUsers
|
||||
*/
|
||||
protected function handleBannedUsers($bannedUsers): void
|
||||
protected function handleBannedUsers(array $bannedUsers): void
|
||||
{
|
||||
foreach ($bannedUsers as $bannedUser) {
|
||||
$user = User::whereHubId($bannedUser['hub_id'])->first();
|
||||
@ -539,8 +571,10 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||
|
||||
/**
|
||||
* Fetch or create the user ranks in the local database and assign them to the users.
|
||||
*
|
||||
* @param array<array<string, mixed>> $userRanks
|
||||
*/
|
||||
protected function handleUserRoles($userRanks): void
|
||||
protected function handleUserRoles(array $userRanks): void
|
||||
{
|
||||
foreach ($userRanks as $userRank) {
|
||||
$roleName = Str::ucfirst(Str::afterLast($userRank['title'], '.'));
|
||||
@ -555,6 +589,8 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||
|
||||
/**
|
||||
* Build the user role data based on the role name.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function buildUserRoleData(string $name): array
|
||||
{
|
||||
@ -672,6 +708,8 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||
|
||||
/**
|
||||
* Get the latest current version from the response data.
|
||||
*
|
||||
* @param array<string, array<string, string>> $versions
|
||||
*/
|
||||
protected function getLatestVersion(array $versions): string
|
||||
{
|
@ -4,6 +4,7 @@ namespace App\Livewire;
|
||||
|
||||
use App\Models\Mod;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\View;
|
||||
use Livewire\Component;
|
||||
@ -34,16 +35,18 @@ class GlobalSearch extends Component
|
||||
|
||||
/**
|
||||
* Execute the search against each of the searchable models.
|
||||
*
|
||||
* @return array<string, array<array<string, mixed>>>
|
||||
*/
|
||||
protected function executeSearch(string $query): array
|
||||
{
|
||||
$query = Str::trim($query);
|
||||
$results = ['data' => [], 'total' => 0];
|
||||
|
||||
if (Str::length($query)) {
|
||||
if (Str::length($query) > 0) {
|
||||
$results['data'] = [
|
||||
'user' => collect(User::search($query)->raw()['hits']),
|
||||
'mod' => collect(Mod::search($query)->raw()['hits']),
|
||||
'user' => $this->fetchUserResults($query),
|
||||
'mod' => $this->fetchModResults($query),
|
||||
];
|
||||
$results['total'] = $this->countTotalResults($results['data']);
|
||||
}
|
||||
@ -55,11 +58,39 @@ class GlobalSearch extends Component
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the total number of results across all models.
|
||||
* Fetch the user search results.
|
||||
*
|
||||
* @return Collection<int, array<string, mixed>>
|
||||
*/
|
||||
protected function countTotalResults($results): int
|
||||
protected function fetchUserResults(string $query): Collection
|
||||
{
|
||||
return collect($results)->reduce(function ($carry, $result) {
|
||||
/** @var array<int, array<string, mixed>> $userHits */
|
||||
$userHits = User::search($query)->raw()['hits'];
|
||||
|
||||
return collect($userHits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the mod search results.
|
||||
*
|
||||
* @return Collection<int, array<string, mixed>>
|
||||
*/
|
||||
protected function fetchModResults(string $query): Collection
|
||||
{
|
||||
/** @var array<int, array<string, mixed>> $modHits */
|
||||
$modHits = Mod::search($query)->raw()['hits'];
|
||||
|
||||
return collect($modHits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the total number of results across all models.
|
||||
*
|
||||
* @param array<string, Collection<int, array<string, mixed>>> $results
|
||||
*/
|
||||
protected function countTotalResults(array $results): int
|
||||
{
|
||||
return collect($results)->reduce(function (int $carry, Collection $result) {
|
||||
return $carry + $result->count();
|
||||
}, 0);
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ class Index extends Component
|
||||
|
||||
/**
|
||||
* The SPT versions filter value.
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
#[Url]
|
||||
public array $sptVersions = [];
|
||||
@ -42,6 +44,8 @@ class Index extends Component
|
||||
|
||||
/**
|
||||
* The available SPT versions.
|
||||
*
|
||||
* @var Collection<int, SptVersion>
|
||||
*/
|
||||
public Collection $activeSptVersions;
|
||||
|
||||
@ -59,6 +63,8 @@ class Index extends Component
|
||||
|
||||
/**
|
||||
* Get all patch versions of the latest minor SPT version.
|
||||
*
|
||||
* @return Collection<int, SptVersion>
|
||||
*/
|
||||
public function getLatestMinorVersions(): Collection
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Database\Factories\LicenseFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -9,10 +10,15 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class License extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
/** @use HasFactory<LicenseFactory> */
|
||||
use HasFactory;
|
||||
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* The relationship between a license and mod.
|
||||
*
|
||||
* @return HasMany<Mod>
|
||||
*/
|
||||
public function mods(): HasMany
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ namespace App\Models;
|
||||
use App\Http\Filters\V1\QueryFilter;
|
||||
use App\Models\Scopes\DisabledScope;
|
||||
use App\Models\Scopes\PublishedScope;
|
||||
use Database\Factories\ModFactory;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
@ -19,24 +20,20 @@ use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Scout\Searchable;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $name
|
||||
* @property string $slug
|
||||
*/
|
||||
class Mod extends Model
|
||||
{
|
||||
use HasFactory, Searchable, SoftDeletes;
|
||||
/** @use HasFactory<ModFactory> */
|
||||
use HasFactory;
|
||||
|
||||
use Searchable;
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* Post boot method to configure the model.
|
||||
*/
|
||||
protected static function booted(): void
|
||||
{
|
||||
// Apply the global scope to exclude disabled mods.
|
||||
static::addGlobalScope(new DisabledScope);
|
||||
|
||||
// Apply the global scope to exclude non-published mods.
|
||||
static::addGlobalScope(new PublishedScope);
|
||||
}
|
||||
|
||||
@ -51,6 +48,8 @@ class Mod extends Model
|
||||
|
||||
/**
|
||||
* The relationship between a mod and its users.
|
||||
*
|
||||
* @return BelongsToMany<User>
|
||||
*/
|
||||
public function users(): BelongsToMany
|
||||
{
|
||||
@ -59,6 +58,8 @@ class Mod extends Model
|
||||
|
||||
/**
|
||||
* The relationship between a mod and its license.
|
||||
*
|
||||
* @return BelongsTo<License, Mod>
|
||||
*/
|
||||
public function license(): BelongsTo
|
||||
{
|
||||
@ -67,6 +68,8 @@ class Mod extends Model
|
||||
|
||||
/**
|
||||
* The relationship between a mod and its versions.
|
||||
*
|
||||
* @return HasMany<ModVersion>
|
||||
*/
|
||||
public function versions(): HasMany
|
||||
{
|
||||
@ -78,6 +81,8 @@ class Mod extends Model
|
||||
|
||||
/**
|
||||
* The relationship between a mod and its last updated version.
|
||||
*
|
||||
* @return HasOne<ModVersion>
|
||||
*/
|
||||
public function lastUpdatedVersion(): HasOne
|
||||
{
|
||||
@ -89,6 +94,8 @@ class Mod extends Model
|
||||
|
||||
/**
|
||||
* The data that is searchable by Scout.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toSearchableArray(): array
|
||||
{
|
||||
@ -102,13 +109,15 @@ class Mod extends Model
|
||||
'created_at' => strtotime($this->created_at),
|
||||
'updated_at' => strtotime($this->updated_at),
|
||||
'published_at' => strtotime($this->published_at),
|
||||
'latestVersion' => $this->latestVersion()?->first()?->latestSptVersion()?->first()?->version_formatted,
|
||||
'latestVersionColorClass' => $this->latestVersion()?->first()?->latestSptVersion()?->first()?->color_class,
|
||||
'latestVersion' => $this->latestVersion()->first()->latestSptVersion()->first()->version_formatted,
|
||||
'latestVersionColorClass' => $this->latestVersion()->first()->latestSptVersion()->first()->color_class,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The relationship to the latest mod version, dictated by the mod version number.
|
||||
*
|
||||
* @return HasOne<ModVersion>
|
||||
*/
|
||||
public function latestVersion(): HasOne
|
||||
{
|
||||
@ -136,7 +145,7 @@ class Mod extends Model
|
||||
}
|
||||
|
||||
// Fetch the latest version instance.
|
||||
$latestVersion = $this->latestVersion()?->first();
|
||||
$latestVersion = $this->latestVersion()->first();
|
||||
|
||||
// Ensure the mod has a latest version.
|
||||
if (is_null($latestVersion)) {
|
||||
@ -162,6 +171,8 @@ class Mod extends Model
|
||||
|
||||
/**
|
||||
* Build the URL to the mod's thumbnail.
|
||||
*
|
||||
* @return Attribute<string, never>
|
||||
*/
|
||||
public function thumbnailUrl(): Attribute
|
||||
{
|
||||
@ -185,6 +196,10 @@ class Mod extends Model
|
||||
|
||||
/**
|
||||
* Scope a query by applying QueryFilter filters.
|
||||
*
|
||||
* @param Builder<Mod> $builder
|
||||
* @param QueryFilter<Mod> $filters
|
||||
* @return Builder<Mod>
|
||||
*/
|
||||
public function scopeFilter(Builder $builder, QueryFilter $filters): Builder
|
||||
{
|
||||
@ -201,6 +216,8 @@ class Mod extends Model
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
@ -214,6 +231,8 @@ class Mod extends Model
|
||||
|
||||
/**
|
||||
* Mutate the slug attribute to always be lower case on get and slugified on set.
|
||||
*
|
||||
* @return Attribute<string, string>
|
||||
*/
|
||||
protected function slug(): Attribute
|
||||
{
|
||||
|
@ -2,24 +2,21 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Database\Factories\ModDependencyFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int $mod_version_id
|
||||
* @property int $dependency_mod_id
|
||||
* @property string $constraint
|
||||
* @property int|null $resolved_version_id
|
||||
*/
|
||||
class ModDependency extends Model
|
||||
{
|
||||
/** @use HasFactory<ModDependencyFactory> */
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The relationship between the mod dependency and the mod version.
|
||||
*
|
||||
* @return BelongsTo<ModVersion, ModDependency>
|
||||
*/
|
||||
public function modVersion(): BelongsTo
|
||||
{
|
||||
@ -28,6 +25,8 @@ class ModDependency extends Model
|
||||
|
||||
/**
|
||||
* The relationship between the mod dependency and the resolved dependency.
|
||||
*
|
||||
* @return HasMany<ModResolvedDependency>
|
||||
*/
|
||||
public function resolvedDependencies(): HasMany
|
||||
{
|
||||
@ -37,6 +36,8 @@ class ModDependency extends Model
|
||||
|
||||
/**
|
||||
* The relationship between the mod dependency and the dependent mod.
|
||||
*
|
||||
* @return BelongsTo<Mod, ModDependency>
|
||||
*/
|
||||
public function dependentMod(): BelongsTo
|
||||
{
|
||||
|
@ -9,6 +9,8 @@ class ModResolvedDependency extends Model
|
||||
{
|
||||
/**
|
||||
* The relationship between the resolved dependency and the mod version.
|
||||
*
|
||||
* @return BelongsTo<ModVersion, ModResolvedDependency>
|
||||
*/
|
||||
public function modVersion(): BelongsTo
|
||||
{
|
||||
@ -17,6 +19,8 @@ class ModResolvedDependency extends Model
|
||||
|
||||
/**
|
||||
* The relationship between the resolved dependency and the dependency.
|
||||
*
|
||||
* @return BelongsTo<ModDependency, ModResolvedDependency>
|
||||
*/
|
||||
public function dependency(): BelongsTo
|
||||
{
|
||||
@ -25,6 +29,8 @@ class ModResolvedDependency extends Model
|
||||
|
||||
/**
|
||||
* The relationship between the resolved dependency and the resolved mod version.
|
||||
*
|
||||
* @return BelongsTo<ModVersion, ModResolvedDependency>
|
||||
*/
|
||||
public function resolvedModVersion(): BelongsTo
|
||||
{
|
||||
|
@ -4,6 +4,7 @@ namespace App\Models;
|
||||
|
||||
use App\Models\Scopes\DisabledScope;
|
||||
use App\Models\Scopes\PublishedScope;
|
||||
use Database\Factories\ModFactory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
@ -11,14 +12,12 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int $mod_id
|
||||
* @property string $version
|
||||
*/
|
||||
class ModVersion extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
/** @use HasFactory<ModFactory> */
|
||||
use HasFactory;
|
||||
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* Post boot method to configure the model.
|
||||
@ -31,6 +30,8 @@ class ModVersion extends Model
|
||||
|
||||
/**
|
||||
* The relationship between a mod version and mod.
|
||||
*
|
||||
* @return BelongsTo<Mod, ModVersion>
|
||||
*/
|
||||
public function mod(): BelongsTo
|
||||
{
|
||||
@ -39,6 +40,8 @@ class ModVersion extends Model
|
||||
|
||||
/**
|
||||
* The relationship between a mod version and its dependencies.
|
||||
*
|
||||
* @return HasMany<ModDependency>
|
||||
*/
|
||||
public function dependencies(): HasMany
|
||||
{
|
||||
@ -48,6 +51,8 @@ class ModVersion extends Model
|
||||
|
||||
/**
|
||||
* The relationship between a mod version and its resolved dependencies.
|
||||
*
|
||||
* @return BelongsToMany<ModVersion>
|
||||
*/
|
||||
public function resolvedDependencies(): BelongsToMany
|
||||
{
|
||||
@ -58,6 +63,8 @@ class ModVersion extends Model
|
||||
|
||||
/**
|
||||
* The relationship between a mod version and its each of it's resolved dependencies' latest versions.
|
||||
*
|
||||
* @return BelongsToMany<ModVersion>
|
||||
*/
|
||||
public function latestResolvedDependencies(): BelongsToMany
|
||||
{
|
||||
@ -74,6 +81,8 @@ class ModVersion extends Model
|
||||
/**
|
||||
* The relationship between a mod version and each of its SPT versions' latest version.
|
||||
* Hint: Be sure to call `->first()` on this to get the actual instance.
|
||||
*
|
||||
* @return BelongsToMany<SptVersion>
|
||||
*/
|
||||
public function latestSptVersion(): BelongsToMany
|
||||
{
|
||||
@ -84,6 +93,8 @@ class ModVersion extends Model
|
||||
|
||||
/**
|
||||
* The relationship between a mod version and its SPT versions.
|
||||
*
|
||||
* @return BelongsToMany<SptVersion>
|
||||
*/
|
||||
public function sptVersions(): BelongsToMany
|
||||
{
|
||||
|
@ -6,10 +6,15 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Scope;
|
||||
|
||||
/**
|
||||
* @template TModelClass of Model
|
||||
*/
|
||||
class DisabledScope implements Scope
|
||||
{
|
||||
/**
|
||||
* Apply the scope to a given Eloquent query builder.
|
||||
*
|
||||
* @param Builder<TModelClass> $builder
|
||||
*/
|
||||
public function apply(Builder $builder, Model $model): void
|
||||
{
|
||||
|
@ -6,10 +6,15 @@ use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Scope;
|
||||
|
||||
/**
|
||||
* @template TModelClass of Model
|
||||
*/
|
||||
class PublishedScope implements Scope
|
||||
{
|
||||
/**
|
||||
* Apply the scope to a given Eloquent query builder.
|
||||
*
|
||||
* @param Builder<TModelClass> $builder
|
||||
*/
|
||||
public function apply(Builder $builder, Model $model): void
|
||||
{
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Exceptions\InvalidVersionNumberException;
|
||||
use Database\Factories\SptVersionFactory;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@ -12,10 +13,15 @@ use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class SptVersion extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
/** @use HasFactory<SptVersionFactory> */
|
||||
use HasFactory;
|
||||
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* Get all versions for the last three minor versions.
|
||||
*
|
||||
* @return Collection<int, SptVersion>
|
||||
*/
|
||||
public static function getVersionsForLastThreeMinors(): Collection
|
||||
{
|
||||
@ -44,6 +50,8 @@ class SptVersion extends Model
|
||||
|
||||
/**
|
||||
* Get the last three minor versions (major.minor format).
|
||||
*
|
||||
* @return array<int, array{major: int, minor: int}>
|
||||
*/
|
||||
public static function getLastThreeMinorVersions(): array
|
||||
{
|
||||
@ -54,7 +62,7 @@ class SptVersion extends Model
|
||||
->orderByDesc('version_minor')
|
||||
->limit(3)
|
||||
->get()
|
||||
->map(function ($version) {
|
||||
->map(function (SptVersion $version) {
|
||||
return [
|
||||
'major' => (int) $version->version_major,
|
||||
'minor' => (int) $version->version_minor,
|
||||
@ -69,7 +77,7 @@ class SptVersion extends Model
|
||||
protected static function booted(): void
|
||||
{
|
||||
// Callback that runs before saving the model.
|
||||
static::saving(function ($model) {
|
||||
static::saving(function (SptVersion $model) {
|
||||
// Extract the version sections from the version string.
|
||||
if (! empty($model->version)) {
|
||||
// Default values in case there's an exception.
|
||||
@ -95,6 +103,8 @@ class SptVersion extends Model
|
||||
/**
|
||||
* Extract the version sections from the version string.
|
||||
*
|
||||
* @return array{major: int, minor: int, patch: int, pre_release: string}
|
||||
*
|
||||
* @throws InvalidVersionNumberException
|
||||
*/
|
||||
public static function extractVersionSections(string $version): array
|
||||
@ -131,6 +141,8 @@ class SptVersion extends Model
|
||||
|
||||
/**
|
||||
* The relationship between an SPT version and mod version.
|
||||
*
|
||||
* @return BelongsToMany<ModVersion>
|
||||
*/
|
||||
public function modVersions(): BelongsToMany
|
||||
{
|
||||
|
@ -6,6 +6,7 @@ use App\Http\Filters\V1\QueryFilter;
|
||||
use App\Notifications\ResetPassword;
|
||||
use App\Notifications\VerifyEmail;
|
||||
use App\Traits\HasCoverPhoto;
|
||||
use Database\Factories\UserFactory;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
@ -25,7 +26,10 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
use Bannable;
|
||||
use HasApiTokens;
|
||||
use HasCoverPhoto;
|
||||
|
||||
/** @use HasFactory<UserFactory> */
|
||||
use HasFactory;
|
||||
|
||||
use HasProfilePhoto;
|
||||
use Notifiable;
|
||||
use Searchable;
|
||||
@ -44,6 +48,8 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
|
||||
/**
|
||||
* The relationship between a user and their mods.
|
||||
*
|
||||
* @return BelongsToMany<Mod>
|
||||
*/
|
||||
public function mods(): BelongsToMany
|
||||
{
|
||||
@ -52,6 +58,8 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
|
||||
/**
|
||||
* The data that is searchable by Scout.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toSearchableArray(): array
|
||||
{
|
||||
@ -132,6 +140,8 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
|
||||
/**
|
||||
* The relationship between a user and their role.
|
||||
*
|
||||
* @return BelongsTo<UserRole, User>
|
||||
*/
|
||||
public function role(): BelongsTo
|
||||
{
|
||||
@ -140,6 +150,10 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
|
||||
/**
|
||||
* Scope a query by applying QueryFilter filters.
|
||||
*
|
||||
* @param Builder<User> $builder
|
||||
* @param QueryFilter<User> $filters
|
||||
* @return Builder<User>
|
||||
*/
|
||||
public function scopeFilter(Builder $builder, QueryFilter $filters): Builder
|
||||
{
|
||||
@ -156,6 +170,8 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user