mirror of
https://github.com/sp-tarkov/forge.git
synced 2025-02-13 04:30:41 -05:00
Merge remote-tracking branch 'upstream/develop' into impl/mod-card-moderation-options
This commit is contained in:
commit
e2e764fce7
@ -15,6 +15,8 @@ class ModResource extends JsonResource
|
|||||||
*/
|
*/
|
||||||
public function toArray(Request $request): array
|
public function toArray(Request $request): array
|
||||||
{
|
{
|
||||||
|
$this->load(['users', 'versions', 'license']);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'type' => 'mod',
|
'type' => 'mod',
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
@ -51,11 +53,8 @@ class ModResource extends JsonResource
|
|||||||
'type' => 'version',
|
'type' => 'version',
|
||||||
'id' => $version->id,
|
'id' => $version->id,
|
||||||
],
|
],
|
||||||
|
|
||||||
// TODO: The download link to the version can be placed here, but I'd like to track the number of
|
|
||||||
// downloads that are made, so we'll need a new route/feature for that. #35
|
|
||||||
'links' => [
|
'links' => [
|
||||||
'self' => $version->link,
|
'self' => $version->downloadUrl(absolute: true),
|
||||||
],
|
],
|
||||||
|
|
||||||
])->toArray(),
|
])->toArray(),
|
||||||
|
@ -28,10 +28,7 @@ class ModVersionResource extends JsonResource
|
|||||||
// $this->description
|
// $this->description
|
||||||
//),
|
//),
|
||||||
|
|
||||||
// TODO: The download link to the version can be placed here, but I'd like to track the number of
|
'link' => $this->downloadUrl(absolute: true),
|
||||||
// downloads that are made, so we'll need a new route/feature for that. #35
|
|
||||||
'link' => $this->link,
|
|
||||||
|
|
||||||
'virus_total_link' => $this->virus_total_link,
|
'virus_total_link' => $this->virus_total_link,
|
||||||
'downloads' => $this->downloads,
|
'downloads' => $this->downloads,
|
||||||
'created_at' => $this->created_at,
|
'created_at' => $this->created_at,
|
||||||
|
@ -15,6 +15,8 @@ class UserResource extends JsonResource
|
|||||||
*/
|
*/
|
||||||
public function toArray(Request $request): array
|
public function toArray(Request $request): array
|
||||||
{
|
{
|
||||||
|
$this->load('role');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'type' => 'user',
|
'type' => 'user',
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
@ -34,7 +36,7 @@ class UserResource extends JsonResource
|
|||||||
],
|
],
|
||||||
'includes' => $this->when(
|
'includes' => $this->when(
|
||||||
ApiController::shouldInclude('user_role'),
|
ApiController::shouldInclude('user_role'),
|
||||||
new UserRoleResource($this->role)
|
new UserRoleResource($this->role),
|
||||||
),
|
),
|
||||||
'links' => [
|
'links' => [
|
||||||
'self' => $this->profileUrl(),
|
'self' => $this->profileUrl(),
|
||||||
|
@ -30,6 +30,7 @@ use Illuminate\Support\Facades\Validator;
|
|||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use League\HTMLToMarkdown\HtmlConverter;
|
use League\HTMLToMarkdown\HtmlConverter;
|
||||||
use Stevebauman\Purify\Facades\Purify;
|
use Stevebauman\Purify\Facades\Purify;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
||||||
{
|
{
|
||||||
@ -40,6 +41,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
|||||||
// Stream some data locally so that we don't have to keep accessing the Hub's database. Use MySQL temporary
|
// Stream some data locally so that we don't have to keep accessing the Hub's database. Use MySQL temporary
|
||||||
// tables to store the data to save on memory; we don't want this to be a hog.
|
// tables to store the data to save on memory; we don't want this to be a hog.
|
||||||
$this->bringUserAvatarLocal();
|
$this->bringUserAvatarLocal();
|
||||||
|
$this->bringUserOptionsLocal();
|
||||||
$this->bringFileAuthorsLocal();
|
$this->bringFileAuthorsLocal();
|
||||||
$this->bringFileOptionsLocal();
|
$this->bringFileOptionsLocal();
|
||||||
$this->bringFileContentLocal();
|
$this->bringFileContentLocal();
|
||||||
@ -98,6 +100,35 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bring the user options table from the Hub database to the local database temporary table.
|
||||||
|
*/
|
||||||
|
private function bringUserOptionsLocal(): void
|
||||||
|
{
|
||||||
|
DB::statement('DROP TEMPORARY TABLE IF EXISTS temp_user_options_values');
|
||||||
|
DB::statement('CREATE TEMPORARY TABLE temp_user_options_values (
|
||||||
|
userID INT,
|
||||||
|
about LONGTEXT
|
||||||
|
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci');
|
||||||
|
|
||||||
|
DB::connection('mysql_hub')
|
||||||
|
->table('wcf1_user_option_value')
|
||||||
|
->orderBy('userID')
|
||||||
|
->chunk(200, function ($options) {
|
||||||
|
$insertData = [];
|
||||||
|
foreach ($options as $option) {
|
||||||
|
$insertData[] = [
|
||||||
|
'userID' => (int) $option->userID,
|
||||||
|
'about' => $option->userOption1,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($insertData) {
|
||||||
|
DB::table('temp_user_options_values')->insert($insertData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bring the file authors from the Hub database to the local database temporary table.
|
* Bring the file authors from the Hub database to the local database temporary table.
|
||||||
*/
|
*/
|
||||||
@ -357,6 +388,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
|||||||
'name' => $hubUser->username,
|
'name' => $hubUser->username,
|
||||||
'email' => Str::lower($hubUser->email),
|
'email' => Str::lower($hubUser->email),
|
||||||
'password' => $this->cleanPasswordHash($hubUser->password),
|
'password' => $this->cleanPasswordHash($hubUser->password),
|
||||||
|
'about' => $this->fetchUserAbout($hubUser->userID),
|
||||||
'profile_photo_path' => $this->fetchUserAvatar($curl, $hubUser),
|
'profile_photo_path' => $this->fetchUserAvatar($curl, $hubUser),
|
||||||
'cover_photo_path' => $this->fetchUserCoverPhoto($curl, $hubUser),
|
'cover_photo_path' => $this->fetchUserCoverPhoto($curl, $hubUser),
|
||||||
'created_at' => $this->cleanRegistrationDate($hubUser->registrationDate),
|
'created_at' => $this->cleanRegistrationDate($hubUser->registrationDate),
|
||||||
@ -377,6 +409,32 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
|||||||
return str_starts_with($clean, '$2') ? $clean : '';
|
return str_starts_with($clean, '$2') ? $clean : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the user about text from the temporary table.
|
||||||
|
*/
|
||||||
|
private function fetchUserAbout(int $userID): string
|
||||||
|
{
|
||||||
|
$about = DB::table('temp_user_options_values')
|
||||||
|
->where('userID', $userID)
|
||||||
|
->limit(1)
|
||||||
|
->value('about');
|
||||||
|
|
||||||
|
return $this->cleanHubContent($about ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the mod description from WoltHub flavoured HTML to Markdown.
|
||||||
|
*/
|
||||||
|
protected function cleanHubContent(string $dirty): string
|
||||||
|
{
|
||||||
|
// Alright, hear me out... Shut up.
|
||||||
|
|
||||||
|
$converter = new HtmlConverter;
|
||||||
|
$clean = Purify::clean($dirty);
|
||||||
|
|
||||||
|
return $converter->convert($clean);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the user avatar from the Hub and store it anew.
|
* Fetch the user avatar from the Hub and store it anew.
|
||||||
*/
|
*/
|
||||||
@ -914,19 +972,6 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
|||||||
curl_close($curl);
|
curl_close($curl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the mod description from WoltHub flavoured HTML to Markdown.
|
|
||||||
*/
|
|
||||||
protected function cleanHubContent(string $dirty): string
|
|
||||||
{
|
|
||||||
// Alright, hear me out... Shut up.
|
|
||||||
|
|
||||||
$converter = new HtmlConverter;
|
|
||||||
$clean = Purify::clean($dirty);
|
|
||||||
|
|
||||||
return $converter->convert($clean);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the mod thumbnail from the Hub and store it anew.
|
* Fetch the mod thumbnail from the Hub and store it anew.
|
||||||
*/
|
*/
|
||||||
@ -1034,10 +1079,11 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue
|
|||||||
/**
|
/**
|
||||||
* The job failed to process.
|
* The job failed to process.
|
||||||
*/
|
*/
|
||||||
public function failed(Exception $exception): void
|
public function failed(Throwable $exception): void
|
||||||
{
|
{
|
||||||
// Explicitly drop the temporary tables.
|
// Explicitly drop the temporary tables.
|
||||||
DB::unprepared('DROP TEMPORARY TABLE IF EXISTS temp_user_avatar');
|
DB::unprepared('DROP TEMPORARY TABLE IF EXISTS temp_user_avatar');
|
||||||
|
DB::unprepared('DROP TEMPORARY TABLE IF EXISTS temp_user_options_values');
|
||||||
DB::unprepared('DROP TEMPORARY TABLE IF EXISTS temp_file_author');
|
DB::unprepared('DROP TEMPORARY TABLE IF EXISTS temp_file_author');
|
||||||
DB::unprepared('DROP TEMPORARY TABLE IF EXISTS temp_file_option_values');
|
DB::unprepared('DROP TEMPORARY TABLE IF EXISTS temp_file_option_values');
|
||||||
DB::unprepared('DROP TEMPORARY TABLE IF EXISTS temp_file_content');
|
DB::unprepared('DROP TEMPORARY TABLE IF EXISTS temp_file_content');
|
||||||
|
@ -75,6 +75,11 @@ class FollowCard extends Component
|
|||||||
#[Locked]
|
#[Locked]
|
||||||
public Collection $followUsers;
|
public Collection $followUsers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The events the component should listen for.
|
||||||
|
*/
|
||||||
|
protected $listeners = ['refreshComponent' => '$refresh'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of users being displayed.
|
* The number of users being displayed.
|
||||||
*/
|
*/
|
||||||
@ -148,6 +153,8 @@ class FollowCard extends Component
|
|||||||
{
|
{
|
||||||
// Update the collection of profile user's followers (or following).
|
// Update the collection of profile user's followers (or following).
|
||||||
$this->followUsers = $this->profileUser->{$this->relationship}()->get();
|
$this->followUsers = $this->profileUser->{$this->relationship}()->get();
|
||||||
|
|
||||||
|
$this->dispatch('refreshComponent');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,6 +23,16 @@ class FollowCards extends Component
|
|||||||
#[Locked]
|
#[Locked]
|
||||||
public Collection $authFollowIds;
|
public Collection $authFollowIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the component.
|
||||||
|
*/
|
||||||
|
public function render(): View
|
||||||
|
{
|
||||||
|
$this->updateAuthFollowIds();
|
||||||
|
|
||||||
|
return view('livewire.user.follow-cards');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the user follows or unfollows a user.
|
* Called when the user follows or unfollows a user.
|
||||||
*/
|
*/
|
||||||
@ -38,12 +48,4 @@ class FollowCards extends Component
|
|||||||
|
|
||||||
$this->dispatch('auth-follow-change');
|
$this->dispatch('auth-follow-change');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Render the component.
|
|
||||||
*/
|
|
||||||
public function render(): View
|
|
||||||
{
|
|
||||||
return view('livewire.user.follow-cards');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,4 +22,17 @@ class License extends Model
|
|||||||
return $this->hasMany(Mod::class)
|
return $this->hasMany(Mod::class)
|
||||||
->chaperone();
|
->chaperone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be cast to native types.
|
||||||
|
*/
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'hub_id' => 'integer',
|
||||||
|
'created_at' => 'datetime',
|
||||||
|
'updated_at' => 'datetime',
|
||||||
|
'deleted_at' => 'datetime',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,6 +243,7 @@ class Mod extends Model
|
|||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
|
'published_at' => 'datetime',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,4 +41,15 @@ class ModDependency extends Model
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(Mod::class, 'dependent_mod_id');
|
return $this->belongsTo(Mod::class, 'dependent_mod_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be cast to native types.
|
||||||
|
*/
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'created_at' => 'datetime',
|
||||||
|
'updated_at' => 'datetime',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,4 +36,15 @@ class ModResolvedDependency extends Model
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(ModVersion::class, 'resolved_mod_version_id');
|
return $this->belongsTo(ModVersion::class, 'resolved_mod_version_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be cast to native types.
|
||||||
|
*/
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'created_at' => 'datetime',
|
||||||
|
'updated_at' => 'datetime',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,4 +152,23 @@ class ModVersion extends Model
|
|||||||
|
|
||||||
return $this->downloads;
|
return $this->downloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be cast to native types.
|
||||||
|
*/
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'hub_id' => 'integer',
|
||||||
|
'version_major' => 'integer',
|
||||||
|
'version_minor' => 'integer',
|
||||||
|
'version_patch' => 'integer',
|
||||||
|
'downloads' => 'integer',
|
||||||
|
'disabled' => 'boolean',
|
||||||
|
'created_at' => 'datetime',
|
||||||
|
'updated_at' => 'datetime',
|
||||||
|
'deleted_at' => 'datetime',
|
||||||
|
'published_at' => 'datetime',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,4 +16,15 @@ class OAuthConnection extends Model
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be cast to native types.
|
||||||
|
*/
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'created_at' => 'datetime',
|
||||||
|
'updated_at' => 'datetime',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,4 +172,21 @@ class SptVersion extends Model
|
|||||||
->first();
|
->first();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be cast to native types.
|
||||||
|
*/
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'hub_id' => 'integer',
|
||||||
|
'version_major' => 'integer',
|
||||||
|
'version_minor' => 'integer',
|
||||||
|
'version_patch' => 'integer',
|
||||||
|
'mod_count' => 'integer',
|
||||||
|
'created_at' => 'datetime',
|
||||||
|
'updated_at' => 'datetime',
|
||||||
|
'deleted_at' => 'datetime',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,10 @@ class UserFactory extends Factory
|
|||||||
'email' => fake()->unique()->safeEmail(),
|
'email' => fake()->unique()->safeEmail(),
|
||||||
'email_verified_at' => now(),
|
'email_verified_at' => now(),
|
||||||
'password' => static::$password ??= Hash::make('password'),
|
'password' => static::$password ??= Hash::make('password'),
|
||||||
|
|
||||||
|
// TODO: Does Faker have a markdown plugin?
|
||||||
'about' => fake()->paragraphs(random_int(1, 10), true),
|
'about' => fake()->paragraphs(random_int(1, 10), true),
|
||||||
|
|
||||||
'two_factor_secret' => null,
|
'two_factor_secret' => null,
|
||||||
'two_factor_recovery_codes' => null,
|
'two_factor_recovery_codes' => null,
|
||||||
'remember_token' => Str::random(10),
|
'remember_token' => Str::random(10),
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
{{-- About --}}
|
{{-- About --}}
|
||||||
@if ($user->about)
|
@if ($user->about)
|
||||||
<div class="p-4 sm:p-6 bg-white dark:bg-gray-950 rounded-xl shadow-md dark:shadow-gray-950 text-gray-800 dark:text-gray-200 drop-shadow-2xl">
|
<div class="p-4 sm:p-6 bg-white dark:bg-gray-950 rounded-xl shadow-md dark:shadow-gray-950 text-gray-800 dark:text-gray-200 drop-shadow-2xl">
|
||||||
{{ $user->about }}
|
{!! Str::markdown($user->about) !!}
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user