diff --git a/.env.full b/.env.full index c90208e..556d2e9 100644 --- a/.env.full +++ b/.env.full @@ -70,7 +70,7 @@ MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS="no-reply@sp-tarkov.com" MAIL_FROM_NAME="${APP_NAME}" -OCTANE_SERVER=swoole +OCTANE_SERVER=frankenphp OCTANE_HTTPS=false SAIL_XDEBUG_MODE=develop,debug,coverage diff --git a/.gitignore b/.gitignore index 54dc261..3ccc7e5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,19 +3,20 @@ .env.backup .env.production .phpunit.result.cache -/.fleet -/.idea -/.phpunit.cache -/.vscode -/caddy -/config/psysh -/data -/node_modules -/public/build -/public/hot -/public/storage -/storage/*.key -/vendor +.fleet +.idea +.phpunit.cache +.vscode +caddy +config/psysh +config/caddy +data +node_modules +public/build +public/hot +public/storage +storage/*.key +vendor auth.json frankenphp frankenphp-worker.php diff --git a/app/Console/Commands/ImportHubCommand.php b/app/Console/Commands/ImportHubCommand.php index 5c1ed2b..b89bb91 100644 --- a/app/Console/Commands/ImportHubCommand.php +++ b/app/Console/Commands/ImportHubCommand.php @@ -9,12 +9,12 @@ class ImportHubCommand extends Command { protected $signature = 'app:import-hub'; - protected $description = 'Connects to the Hub database and imports the data into the Laravel database.'; + protected $description = 'Connects to the Hub database and imports the data into the Laravel database'; public function handle(): void { ImportHubDataJob::dispatch()->onQueue('long'); - $this->info('The import job has been added to the queue.'); + $this->info('ImportHubDataJob has been added to the queue'); } } diff --git a/app/Console/Commands/ResolveVersionsCommand.php b/app/Console/Commands/ResolveVersionsCommand.php index bf8bd88..9b2e963 100644 --- a/app/Console/Commands/ResolveVersionsCommand.php +++ b/app/Console/Commands/ResolveVersionsCommand.php @@ -10,13 +10,13 @@ class ResolveVersionsCommand extends Command { protected $signature = 'app:resolve-versions'; - protected $description = 'Resolve SPT and dependency versions for all mods.'; + protected $description = 'Resolve SPT and dependency versions for all mods'; public function handle(): void { - ResolveSptVersionsJob::dispatch()->onQueue('long'); - ResolveDependenciesJob::dispatch()->onQueue('long'); + ResolveSptVersionsJob::dispatch()->onQueue('default'); + ResolveDependenciesJob::dispatch()->onQueue('default'); - $this->info('The import job has been added to the queue.'); + $this->info('ResolveSptVersionsJob and ResolveDependenciesJob have been added to the queue'); } } diff --git a/app/Console/Commands/SearchSyncCommand.php b/app/Console/Commands/SearchSyncCommand.php index 626070f..80395ea 100644 --- a/app/Console/Commands/SearchSyncCommand.php +++ b/app/Console/Commands/SearchSyncCommand.php @@ -9,7 +9,7 @@ class SearchSyncCommand extends Command { protected $signature = 'app:search-sync'; - protected $description = 'Syncs all search settings and indexes with the database data.'; + protected $description = 'Syncs all search settings and indexes with the database data'; public function handle(): void { @@ -18,6 +18,6 @@ class SearchSyncCommand extends Command Artisan::call('scout:import', ['model' => '\App\Models\Mod']); Artisan::call('scout:import', ['model' => '\App\Models\User']); - $this->info('The search synchronisation jobs have been added to the queue.'); + $this->info('The search synchronisation jobs have been added to the queue'); } } diff --git a/app/Console/Commands/SptVersionModCountsCommand.php b/app/Console/Commands/SptVersionModCountsCommand.php new file mode 100644 index 0000000..d339a54 --- /dev/null +++ b/app/Console/Commands/SptVersionModCountsCommand.php @@ -0,0 +1,20 @@ +onQueue('default'); + + $this->info('SptVersionModCountsJob has been added to the queue'); + } +} diff --git a/app/Console/Commands/UpdateModDownloadsCommand.php b/app/Console/Commands/UpdateModDownloadsCommand.php new file mode 100644 index 0000000..a3f5eb7 --- /dev/null +++ b/app/Console/Commands/UpdateModDownloadsCommand.php @@ -0,0 +1,20 @@ +onQueue('default'); + + $this->info('UpdateModDownloadsJob added to the queue'); + } +} diff --git a/app/Http/Controllers/ModController.php b/app/Http/Controllers/ModController.php index f019ad4..939d5ae 100644 --- a/app/Http/Controllers/ModController.php +++ b/app/Http/Controllers/ModController.php @@ -27,15 +27,14 @@ class ModController extends Controller public function show(int $modId, string $slug) { - $mod = Mod::withTotalDownloads() - ->with([ - 'versions', - 'versions.latestSptVersion:id,version,color_class', - 'versions.latestResolvedDependencies', - 'versions.latestResolvedDependencies.mod:id,name,slug', - 'users:id,name', - 'license:id,name,link', - ]) + $mod = Mod::with([ + 'versions', + 'versions.latestSptVersion:id,version,color_class', + 'versions.latestResolvedDependencies', + 'versions.latestResolvedDependencies.mod:id,name,slug', + 'users:id,name', + 'license:id,name,link', + ]) ->whereHas('latestVersion') ->findOrFail($modId); diff --git a/app/Http/Filters/ModFilter.php b/app/Http/Filters/ModFilter.php index 561ef24..0fa8a39 100644 --- a/app/Http/Filters/ModFilter.php +++ b/app/Http/Filters/ModFilter.php @@ -5,6 +5,7 @@ namespace App\Http\Filters; use App\Models\Mod; use App\Models\ModVersion; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Support\Facades\DB; class ModFilter { @@ -29,14 +30,21 @@ class ModFilter */ private function baseQuery(): Builder { - return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured', 'created_at']) - ->withTotalDownloads() - ->with([ - 'users:id,name', - 'latestVersion' => function ($query) { - $query->with('latestSptVersion:id,version,color_class'); - }, - ]); + return Mod::select([ + 'mods.id', + 'mods.name', + 'mods.slug', + 'mods.teaser', + 'mods.thumbnail', + 'mods.featured', + 'mods.downloads', + 'mods.created_at', + ])->with([ + 'users:id,name', + 'latestVersion' => function ($query) { + $query->with('latestSptVersion:id,version,color_class'); + }, + ]); } /** @@ -50,6 +58,8 @@ class ModFilter } } + //dd($this->builder->toRawSql()); + return $this->builder; } @@ -60,17 +70,20 @@ class ModFilter { // We order the "recently updated" mods by the ModVersion's updated_at value. if ($type === 'updated') { - return $this->builder->orderByDesc( - ModVersion::select('updated_at') - ->whereColumn('mod_id', 'mods.id') - ->orderByDesc('updated_at') - ->take(1) - ); + return $this->builder + ->joinSub( + ModVersion::select('mod_id', DB::raw('MAX(updated_at) as latest_updated_at'))->groupBy('mod_id'), + 'latest_versions', + 'mods.id', + '=', + 'latest_versions.mod_id' + ) + ->orderByDesc('latest_versions.latest_updated_at'); } // By default, we simply order by the column on the mods table/query. $column = match ($type) { - 'downloaded' => 'total_downloads', + 'downloaded' => 'downloads', default => 'created_at', }; @@ -98,12 +111,32 @@ class ModFilter } /** - * Filter the results to a specific SPT version. + * Filter the results to specific SPT versions. */ private function sptVersions(array $versions): Builder { - return $this->builder->whereHas('latestVersion.sptVersions', function ($query) use ($versions) { - $query->whereIn('spt_versions.version', $versions); - }); + // Parse the versions into major, minor, and patch arrays + $parsedVersions = array_map(fn ($version) => [ + 'major' => (int) explode('.', $version)[0], + 'minor' => (int) (explode('.', $version)[1] ?? 0), + 'patch' => (int) (explode('.', $version)[2] ?? 0), + ], $versions); + + [$majorVersions, $minorVersions, $patchVersions] = array_map('array_unique', [ + array_column($parsedVersions, 'major'), + array_column($parsedVersions, 'minor'), + array_column($parsedVersions, 'patch'), + ]); + + return $this->builder + ->join('mod_versions as mv', 'mods.id', '=', 'mv.mod_id') + ->join('mod_version_spt_version as mvsv', 'mv.id', '=', 'mvsv.mod_version_id') + ->join('spt_versions as sv', 'mvsv.spt_version_id', '=', 'sv.id') + ->whereIn('sv.version_major', $majorVersions) + ->whereIn('sv.version_minor', $minorVersions) + ->whereIn('sv.version_patch', $patchVersions) + ->where('sv.version', '!=', '0.0.0') + ->groupBy('mods.id') + ->distinct(); } } diff --git a/app/Jobs/ImportHubDataJob.php b/app/Jobs/ImportHubDataJob.php index 2dff469..c429512 100644 --- a/app/Jobs/ImportHubDataJob.php +++ b/app/Jobs/ImportHubDataJob.php @@ -56,6 +56,8 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue Artisan::call('app:search-sync'); Artisan::call('app:resolve-versions'); + Artisan::call('app:count-mods'); + Artisan::call('app:update-downloads'); Artisan::call('cache:clear'); } diff --git a/app/Jobs/SptVersionModCountsJob.php b/app/Jobs/SptVersionModCountsJob.php new file mode 100644 index 0000000..a7b1344 --- /dev/null +++ b/app/Jobs/SptVersionModCountsJob.php @@ -0,0 +1,26 @@ +each(function (SptVersion $sptVersion) { + $sptVersion->updateModCount(); + }); + } +} diff --git a/app/Jobs/UpdateModDownloadsJob.php b/app/Jobs/UpdateModDownloadsJob.php new file mode 100644 index 0000000..57f4781 --- /dev/null +++ b/app/Jobs/UpdateModDownloadsJob.php @@ -0,0 +1,27 @@ +chunk(100, function ($mods) { + foreach ($mods as $mod) { + $mod->calculateDownloads(); + } + }); + } +} diff --git a/app/Livewire/Mod/Index.php b/app/Livewire/Mod/Index.php index 3cc2c34..5760c14 100644 --- a/app/Livewire/Mod/Index.php +++ b/app/Livewire/Mod/Index.php @@ -55,17 +55,15 @@ class Index extends Component */ public function mount(): void { - // TODO: This should ideally be updated to only pull SPT versions that have mods associated with them so that no - // empty options are shown in the listing filter. - $this->availableSptVersions = Cache::remember('availableSptVersions', 60 * 60, function () { - return SptVersion::select(['id', 'version', 'color_class'])->orderByDesc('version')->get(); + $this->availableSptVersions = $this->availableSptVersions ?? Cache::remember('available-spt-versions', 60 * 60, function () { + return SptVersion::getVersionsForLastThreeMinors(); }); $this->sptVersions = $this->sptVersions ?? $this->getLatestMinorVersions()->pluck('version')->toArray(); } /** - * Get all hotfix versions of the latest minor SPT version. + * Get all patch versions of the latest minor SPT version. */ public function getLatestMinorVersions(): Collection { @@ -88,6 +86,11 @@ class Index extends Component ]; $mods = (new ModFilter($filters))->apply()->paginate(16); + // Check if the current page is greater than the last page. Redirect if it is. + if ($mods->currentPage() > $mods->lastPage()) { + $this->redirectRoute('mods', ['page' => $mods->lastPage()]); + } + return view('livewire.mod.index', compact('mods')); } diff --git a/app/Models/Mod.php b/app/Models/Mod.php index 5261c14..030c7db 100644 --- a/app/Models/Mod.php +++ b/app/Models/Mod.php @@ -39,6 +39,15 @@ class Mod extends Model static::addGlobalScope(new PublishedScope); } + /** + * Calculate the total number of downloads for the mod. + */ + public function calculateDownloads(): void + { + $this->downloads = $this->versions->sum('downloads'); + $this->saveQuietly(); + } + /** * The relationship between a mod and its users. */ @@ -61,28 +70,17 @@ class Mod extends Model public function versions(): HasMany { return $this->hasMany(ModVersion::class) - ->whereHas('sptVersions') + ->whereHas('latestSptVersion') ->orderByDesc('version'); } - /** - * Scope a query to include the total number of downloads for a mod. - */ - public function scopeWithTotalDownloads($query) - { - return $query->addSelect([ - 'total_downloads' => ModVersion::selectRaw('SUM(downloads) AS total_downloads') - ->whereColumn('mod_id', 'mods.id'), - ]); - } - /** * The relationship between a mod and its last updated version. */ public function lastUpdatedVersion(): HasOne { return $this->hasOne(ModVersion::class) - ->whereHas('sptVersions') + ->whereHas('latestSptVersion') ->orderByDesc('updated_at'); } diff --git a/app/Models/SptVersion.php b/app/Models/SptVersion.php index 42bd18b..9d0aa0f 100644 --- a/app/Models/SptVersion.php +++ b/app/Models/SptVersion.php @@ -3,23 +3,130 @@ namespace App\Models; use App\Exceptions\InvalidVersionNumberException; -use App\Services\LatestSptVersionService; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\SoftDeletes; -use Illuminate\Support\Facades\App; +use Illuminate\Support\Facades\Cache; class SptVersion extends Model { use HasFactory, SoftDeletes; /** - * Get the version with "SPT " prepended. + * Get all versions for the last three minor versions. */ - public function getVersionFormattedAttribute(): string + public static function getVersionsForLastThreeMinors(): Collection { - return __('SPT ').$this->version; + $lastThreeMinorVersions = self::getLastThreeMinorVersions(); + + // Extract major and minor arrays. + $majorVersions = array_column($lastThreeMinorVersions, 'major'); + $minorVersions = array_column($lastThreeMinorVersions, 'minor'); + + // Fetch all versions for the last three minor versions with mod count. + return self::select(['spt_versions.id', 'spt_versions.version', 'spt_versions.color_class', 'spt_versions.mod_count']) + ->join('mod_version_spt_version', 'spt_versions.id', '=', 'mod_version_spt_version.spt_version_id') + ->join('mod_versions', 'mod_version_spt_version.mod_version_id', '=', 'mod_versions.id') + ->join('mods', 'mod_versions.mod_id', '=', 'mods.id') + ->where('spt_versions.version', '!=', '0.0.0') + ->whereIn('spt_versions.version_major', $majorVersions) + ->whereIn('spt_versions.version_minor', $minorVersions) + ->where('spt_versions.mod_count', '>', 0) + ->groupBy('spt_versions.id', 'spt_versions.version', 'spt_versions.color_class', 'spt_versions.mod_count') + ->orderBy('spt_versions.version_major', 'DESC') + ->orderBy('spt_versions.version_minor', 'DESC') + ->orderBy('spt_versions.version_patch', 'DESC') + ->orderBy('spt_versions.version_pre_release', 'ASC') + ->get(); + } + + /** + * Get the last three minor versions (major.minor format). + */ + public static function getLastThreeMinorVersions(): array + { + return self::selectRaw('CONCAT(version_major, ".", version_minor) AS minor_version, version_major, version_minor') + ->where('version', '!=', '0.0.0') + ->groupBy('version_major', 'version_minor') + ->orderByDesc('version_major') + ->orderByDesc('version_minor') + ->limit(3) + ->get() + ->map(function ($version) { + return [ + 'major' => (int) $version->version_major, + 'minor' => (int) $version->version_minor, + ]; + }) + ->toArray(); + } + + /** + * Called when the model is booted. + */ + protected static function booted(): void + { + // Callback that runs before saving the model. + static::saving(function ($model) { + // Extract the version sections from the version string. + if (! empty($model->version)) { + // Default values in case there's an exception. + $model->version_major = 0; + $model->version_minor = 0; + $model->version_patch = 0; + $model->version_pre_release = ''; + + try { + $versionSections = self::extractVersionSections($model->version); + } catch (InvalidVersionNumberException $e) { + return; + } + + $model->version_major = $versionSections['major']; + $model->version_minor = $versionSections['minor']; + $model->version_patch = $versionSections['patch']; + $model->version_pre_release = $versionSections['pre_release']; + } + }); + } + + /** + * Extract the version sections from the version string. + * + * @throws InvalidVersionNumberException + */ + public static function extractVersionSections(string $version): array + { + $matches = []; + + // Perform the regex match to capture the version sections, including the possible preRelease section. + preg_match('/^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-([a-zA-Z0-9]+))?$/', $version, $matches); + + if (! $matches) { + throw new InvalidVersionNumberException('Invalid SPT version number: '.$version); + } + + return [ + 'major' => $matches[1] ?? 0, + 'minor' => $matches[2] ?? 0, + 'patch' => $matches[3] ?? 0, + 'pre_release' => $matches[4] ?? '', + ]; + } + + /** + * Update the mod count for this SptVersion. + */ + public function updateModCount(): void + { + $modCount = $this->modVersions() + ->distinct('mod_id') + ->count('mod_id'); + + $this->mod_count = $modCount; + $this->saveQuietly(); } /** @@ -31,49 +138,39 @@ class SptVersion extends Model } /** - * Determine if the version is the latest minor version. + * Get the version with "SPT " prepended. + */ + public function getVersionFormattedAttribute(): string + { + return __('SPT ').$this->version; + } + + /** + * Determine if the version is part of the latest version's minor releases. + * For example, if the latest version is 1.2.0, this method will return true for 1.2.0, 1.2.1, 1.2.2, etc. */ public function isLatestMinor(): bool { - $latestSptVersionService = App::make(LatestSptVersionService::class); - - $latestVersion = $latestSptVersionService->getLatestVersion(); + $latestVersion = self::getLatest(); if (! $latestVersion) { return false; } - try { - [$currentMajor, $currentMinor, $currentPatch] = $this->extractVersionParts($this->version); - [$latestMajor, $latestMinor, $latestPatch] = $this->extractVersionParts($latestVersion->version); - } catch (InvalidVersionNumberException $e) { - return false; - } - - return $currentMajor == $latestMajor && $currentMinor === $latestMinor; + return $this->version_major == $latestVersion->version_major && $this->version_minor == $latestVersion->version_minor; } /** - * Extract the version components from a full version string. + * Get the latest SPT version. * - * @throws InvalidVersionNumberException + * @cached latest_spt_version 300s */ - private function extractVersionParts(string $version): array + public static function getLatest(): ?SptVersion { - // Remove everything from the version string except the numbers and dots. - $version = preg_replace('/[^0-9.]/', '', $version); - - // Validate that the version string is a valid semver. - if (! preg_match('/^\d+\.\d+\.\d+$/', $version)) { - throw new InvalidVersionNumberException; - } - - $parts = explode('.', $version); - - return [ - (int) $parts[0], - (int) $parts[1], - (int) $parts[2], - ]; + return Cache::remember('latest_spt_version', 300, function () { + return SptVersion::select(['version', 'version_major', 'version_minor', 'version_patch', 'version_pre_release']) + ->orderByDesc('version') + ->first(); + }); } } diff --git a/app/Observers/ModObserver.php b/app/Observers/ModObserver.php index 77e3947..e3b3814 100644 --- a/app/Observers/ModObserver.php +++ b/app/Observers/ModObserver.php @@ -23,5 +23,27 @@ class ModObserver foreach ($mod->versions as $modVersion) { $this->dependencyVersionService->resolve($modVersion); } + + $this->updateRelatedSptVersions($mod); + } + + /** + * Update properties on related SptVersions. + */ + protected function updateRelatedSptVersions(Mod $mod): void + { + $sptVersions = $mod->versions->flatMap->sptVersions->unique(); + + foreach ($sptVersions as $sptVersion) { + $sptVersion->updateModCount(); + } + } + + /** + * Handle the Mod "deleted" event. + */ + public function deleted(Mod $mod): void + { + $this->updateRelatedSptVersions($mod); } } diff --git a/app/Observers/ModVersionObserver.php b/app/Observers/ModVersionObserver.php index 2182f67..535a467 100644 --- a/app/Observers/ModVersionObserver.php +++ b/app/Observers/ModVersionObserver.php @@ -26,7 +26,32 @@ class ModVersionObserver public function saved(ModVersion $modVersion): void { $this->dependencyVersionService->resolve($modVersion); + $this->sptVersionService->resolve($modVersion); + + $this->updateRelatedSptVersions($modVersion); // After resolving SPT versions. + $this->updateRelatedMod($modVersion); + } + + /** + * Update properties on related SptVersions. + */ + protected function updateRelatedSptVersions(ModVersion $modVersion): void + { + $sptVersions = $modVersion->sptVersions; // These should already be resolved. + + foreach ($sptVersions as $sptVersion) { + $sptVersion->updateModCount(); + } + } + + /** + * Update properties on the related Mod. + */ + protected function updateRelatedMod(ModVersion $modVersion): void + { + $mod = $modVersion->mod; + $mod->calculateDownloads(); } /** @@ -35,5 +60,8 @@ class ModVersionObserver public function deleted(ModVersion $modVersion): void { $this->dependencyVersionService->resolve($modVersion); + + $this->updateRelatedSptVersions($modVersion); // After resolving SPT versions. + $this->updateRelatedMod($modVersion); } } diff --git a/app/Services/LatestSptVersionService.php b/app/Services/LatestSptVersionService.php deleted file mode 100644 index 29cc771..0000000 --- a/app/Services/LatestSptVersionService.php +++ /dev/null @@ -1,23 +0,0 @@ -version === null) { - $this->version = SptVersion::select('version')->orderByDesc('version')->first(); - } - - return $this->version; - } -} diff --git a/app/View/Components/ModListSection.php b/app/View/Components/ModListSection.php index 38890fb..d08350e 100644 --- a/app/View/Components/ModListSection.php +++ b/app/View/Components/ModListSection.php @@ -6,6 +6,7 @@ use App\Models\Mod; use App\Models\ModVersion; use Illuminate\Contracts\View\View; use Illuminate\Database\Eloquent\Collection; +use Illuminate\Support\Facades\DB; use Illuminate\View\Component; class ModListSection extends Component @@ -25,24 +26,22 @@ class ModListSection extends Component private function fetchFeaturedMods(): Collection { - return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured']) - ->withTotalDownloads() + return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured', 'downloads']) ->with([ 'latestVersion', 'latestVersion.latestSptVersion:id,version,color_class', 'users:id,name', 'license:id,name,link', ]) - ->where('featured', true) - ->latest() + ->whereFeatured(true) + ->inRandomOrder() ->limit(6) ->get(); } private function fetchLatestMods(): Collection { - return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured', 'created_at']) - ->withTotalDownloads() + return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured', 'created_at', 'downloads']) ->with([ 'latestVersion', 'latestVersion.latestSptVersion:id,version,color_class', @@ -56,20 +55,21 @@ class ModListSection extends Component private function fetchUpdatedMods(): Collection { - return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured']) - ->withTotalDownloads() + return Mod::select(['id', 'name', 'slug', 'teaser', 'thumbnail', 'featured', 'downloads']) ->with([ - 'latestVersion', - 'latestVersion.latestSptVersion:id,version,color_class', + 'lastUpdatedVersion', + 'lastUpdatedVersion.latestSptVersion:id,version,color_class', 'users:id,name', 'license:id,name,link', ]) - ->orderByDesc( - ModVersion::select('updated_at') - ->whereColumn('mod_id', 'mods.id') - ->orderByDesc('updated_at') - ->take(1) + ->joinSub( + ModVersion::select('mod_id', DB::raw('MAX(updated_at) as latest_updated_at'))->groupBy('mod_id'), + 'latest_versions', + 'mods.id', + '=', + 'latest_versions.mod_id' ) + ->orderByDesc('latest_versions.latest_updated_at') ->limit(6) ->get(); } @@ -85,17 +85,17 @@ class ModListSection extends Component { return [ [ - 'title' => 'Featured Mods', + 'title' => __('Featured Mods'), 'mods' => $this->modsFeatured, 'versionScope' => 'latestVersion', ], [ - 'title' => 'Newest Mods', + 'title' => __('Newest Mods'), 'mods' => $this->modsLatest, 'versionScope' => 'latestVersion', ], [ - 'title' => 'Recently Updated Mods', + 'title' => __('Recently Updated Mods'), 'mods' => $this->modsUpdated, 'versionScope' => 'lastUpdatedVersion', ], diff --git a/composer.lock b/composer.lock index a478dbd..e20bcda 100644 --- a/composer.lock +++ b/composer.lock @@ -128,16 +128,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.320.6", + "version": "3.321.2", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "73c66ce8f9d593a08409f564cd796abe6976f1b4" + "reference": "c04f8f30891cee8480c132778cd4cc486467e77a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/73c66ce8f9d593a08409f564cd796abe6976f1b4", - "reference": "73c66ce8f9d593a08409f564cd796abe6976f1b4", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c04f8f30891cee8480c132778cd4cc486467e77a", + "reference": "c04f8f30891cee8480c132778cd4cc486467e77a", "shasum": "" }, "require": { @@ -220,9 +220,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.320.6" + "source": "https://github.com/aws/aws-sdk-php/tree/3.321.2" }, - "time": "2024-08-22T18:28:28+00:00" + "time": "2024-08-30T18:14:40+00:00" }, { "name": "bacon/bacon-qr-code", @@ -1437,16 +1437,16 @@ }, { "name": "filament/actions", - "version": "v3.2.107", + "version": "v3.2.110", "source": { "type": "git", "url": "https://github.com/filamentphp/actions.git", - "reference": "de5ce76f20ee21af92b951dec2a5c533ecacbc79" + "reference": "5d6e4fe444f1ef04d373518248a445bbcc3ca272" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/actions/zipball/de5ce76f20ee21af92b951dec2a5c533ecacbc79", - "reference": "de5ce76f20ee21af92b951dec2a5c533ecacbc79", + "url": "https://api.github.com/repos/filamentphp/actions/zipball/5d6e4fe444f1ef04d373518248a445bbcc3ca272", + "reference": "5d6e4fe444f1ef04d373518248a445bbcc3ca272", "shasum": "" }, "require": { @@ -1486,20 +1486,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-08-22T12:07:53+00:00" + "time": "2024-08-26T07:22:35+00:00" }, { "name": "filament/filament", - "version": "v3.2.107", + "version": "v3.2.110", "source": { "type": "git", "url": "https://github.com/filamentphp/panels.git", - "reference": "2675472f2bdd4e765a1f3e533231bda7750a2881" + "reference": "130636e90e821154e0ce60dcbc7b358d2a1a716f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/panels/zipball/2675472f2bdd4e765a1f3e533231bda7750a2881", - "reference": "2675472f2bdd4e765a1f3e533231bda7750a2881", + "url": "https://api.github.com/repos/filamentphp/panels/zipball/130636e90e821154e0ce60dcbc7b358d2a1a716f", + "reference": "130636e90e821154e0ce60dcbc7b358d2a1a716f", "shasum": "" }, "require": { @@ -1551,20 +1551,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-08-20T08:32:50+00:00" + "time": "2024-08-30T01:52:09+00:00" }, { "name": "filament/forms", - "version": "v3.2.107", + "version": "v3.2.110", "source": { "type": "git", "url": "https://github.com/filamentphp/forms.git", - "reference": "0f80913deb90bfe9e1850ab35e80a34194cfb652" + "reference": "02fe2e211993f6291b719a093ed6f63e17125e9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/forms/zipball/0f80913deb90bfe9e1850ab35e80a34194cfb652", - "reference": "0f80913deb90bfe9e1850ab35e80a34194cfb652", + "url": "https://api.github.com/repos/filamentphp/forms/zipball/02fe2e211993f6291b719a093ed6f63e17125e9a", + "reference": "02fe2e211993f6291b719a093ed6f63e17125e9a", "shasum": "" }, "require": { @@ -1607,11 +1607,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-08-22T12:07:43+00:00" + "time": "2024-08-30T18:04:06+00:00" }, { "name": "filament/infolists", - "version": "v3.2.107", + "version": "v3.2.110", "source": { "type": "git", "url": "https://github.com/filamentphp/infolists.git", @@ -1662,7 +1662,7 @@ }, { "name": "filament/notifications", - "version": "v3.2.107", + "version": "v3.2.110", "source": { "type": "git", "url": "https://github.com/filamentphp/notifications.git", @@ -1714,16 +1714,16 @@ }, { "name": "filament/support", - "version": "v3.2.107", + "version": "v3.2.110", "source": { "type": "git", "url": "https://github.com/filamentphp/support.git", - "reference": "f00b84d43d157c85837108a7eeaceabbaf6044ab" + "reference": "78e25428c754fcbb30c321d5dda439c760de9837" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/support/zipball/f00b84d43d157c85837108a7eeaceabbaf6044ab", - "reference": "f00b84d43d157c85837108a7eeaceabbaf6044ab", + "url": "https://api.github.com/repos/filamentphp/support/zipball/78e25428c754fcbb30c321d5dda439c760de9837", + "reference": "78e25428c754fcbb30c321d5dda439c760de9837", "shasum": "" }, "require": { @@ -1769,20 +1769,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-08-22T12:08:05+00:00" + "time": "2024-08-26T07:22:57+00:00" }, { "name": "filament/tables", - "version": "v3.2.107", + "version": "v3.2.110", "source": { "type": "git", "url": "https://github.com/filamentphp/tables.git", - "reference": "5de49ef865e8788bb29d58723b88977b593a7b02" + "reference": "129943d1b4e6c1edeef53e804eb56ef78a932a6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/tables/zipball/5de49ef865e8788bb29d58723b88977b593a7b02", - "reference": "5de49ef865e8788bb29d58723b88977b593a7b02", + "url": "https://api.github.com/repos/filamentphp/tables/zipball/129943d1b4e6c1edeef53e804eb56ef78a932a6c", + "reference": "129943d1b4e6c1edeef53e804eb56ef78a932a6c", "shasum": "" }, "require": { @@ -1821,11 +1821,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-08-22T12:08:13+00:00" + "time": "2024-08-30T01:52:14+00:00" }, { "name": "filament/widgets", - "version": "v3.2.107", + "version": "v3.2.110", "source": { "type": "git", "url": "https://github.com/filamentphp/widgets.git", @@ -4464,16 +4464,16 @@ }, { "name": "mchev/banhammer", - "version": "v2.3.0", + "version": "v2.3.1", "source": { "type": "git", "url": "https://github.com/mchev/banhammer.git", - "reference": "9821abe9a2be60742b43b880091481c2a113d938" + "reference": "6193903d46294bf39869747939fad7ad7cc7ce10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mchev/banhammer/zipball/9821abe9a2be60742b43b880091481c2a113d938", - "reference": "9821abe9a2be60742b43b880091481c2a113d938", + "url": "https://api.github.com/repos/mchev/banhammer/zipball/6193903d46294bf39869747939fad7ad7cc7ce10", + "reference": "6193903d46294bf39869747939fad7ad7cc7ce10", "shasum": "" }, "require": { @@ -4520,7 +4520,7 @@ ], "support": { "issues": "https://github.com/mchev/banhammer/issues", - "source": "https://github.com/mchev/banhammer/tree/v2.3.0" + "source": "https://github.com/mchev/banhammer/tree/v2.3.1" }, "funding": [ { @@ -4528,20 +4528,20 @@ "type": "github" } ], - "time": "2024-05-24T10:09:58+00:00" + "time": "2024-08-23T16:47:51+00:00" }, { "name": "meilisearch/meilisearch-php", - "version": "v1.9.1", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/meilisearch/meilisearch-php.git", - "reference": "c4eb8ecd08799abd65d00dc74f4372b61af1fc37" + "reference": "110be455194fda42ae3a3b8b6a9243479c3a6d19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/meilisearch/meilisearch-php/zipball/c4eb8ecd08799abd65d00dc74f4372b61af1fc37", - "reference": "c4eb8ecd08799abd65d00dc74f4372b61af1fc37", + "url": "https://api.github.com/repos/meilisearch/meilisearch-php/zipball/110be455194fda42ae3a3b8b6a9243479c3a6d19", + "reference": "110be455194fda42ae3a3b8b6a9243479c3a6d19", "shasum": "" }, "require": { @@ -4593,9 +4593,9 @@ ], "support": { "issues": "https://github.com/meilisearch/meilisearch-php/issues", - "source": "https://github.com/meilisearch/meilisearch-php/tree/v1.9.1" + "source": "https://github.com/meilisearch/meilisearch-php/tree/v1.10.0" }, - "time": "2024-07-25T15:54:07+00:00" + "time": "2024-08-26T23:09:54+00:00" }, { "name": "mobiledetect/mobiledetectlib", @@ -6557,16 +6557,16 @@ }, { "name": "spatie/laravel-package-tools", - "version": "1.16.4", + "version": "1.16.5", "source": { "type": "git", "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53" + "reference": "c7413972cf22ffdff97b68499c22baa04eddb6a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53", - "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/c7413972cf22ffdff97b68499c22baa04eddb6a2", + "reference": "c7413972cf22ffdff97b68499c22baa04eddb6a2", "shasum": "" }, "require": { @@ -6605,7 +6605,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.4" + "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.5" }, "funding": [ { @@ -6613,20 +6613,20 @@ "type": "github" } ], - "time": "2024-03-20T07:29:11+00:00" + "time": "2024-08-27T18:56:10+00:00" }, { "name": "stevebauman/purify", - "version": "v6.2.0", + "version": "v6.2.1", "source": { "type": "git", "url": "https://github.com/stevebauman/purify.git", - "reference": "303d23e5756a1fd0e9b34f14459ec6aa327a8412" + "reference": "083a8bd4c956652196272ac4ece294e50df64d8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/stevebauman/purify/zipball/303d23e5756a1fd0e9b34f14459ec6aa327a8412", - "reference": "303d23e5756a1fd0e9b34f14459ec6aa327a8412", + "url": "https://api.github.com/repos/stevebauman/purify/zipball/083a8bd4c956652196272ac4ece294e50df64d8c", + "reference": "083a8bd4c956652196272ac4ece294e50df64d8c", "shasum": "" }, "require": { @@ -6677,9 +6677,9 @@ ], "support": { "issues": "https://github.com/stevebauman/purify/issues", - "source": "https://github.com/stevebauman/purify/tree/v6.2.0" + "source": "https://github.com/stevebauman/purify/tree/v6.2.1" }, - "time": "2024-03-12T15:22:59+00:00" + "time": "2024-08-26T16:21:45+00:00" }, { "name": "symfony/clock", @@ -6757,16 +6757,16 @@ }, { "name": "symfony/console", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9" + "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", - "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", + "url": "https://api.github.com/repos/symfony/console/zipball/1eed7af6961d763e7832e874d7f9b21c3ea9c111", + "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111", "shasum": "" }, "require": { @@ -6830,7 +6830,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.3" + "source": "https://github.com/symfony/console/tree/v7.1.4" }, "funding": [ { @@ -6846,7 +6846,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-08-15T22:48:53+00:00" }, { "name": "symfony/css-selector", @@ -7213,16 +7213,16 @@ }, { "name": "symfony/finder", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "717c6329886f32dc65e27461f80f2a465412fdca" + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca", - "reference": "717c6329886f32dc65e27461f80f2a465412fdca", + "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", "shasum": "" }, "require": { @@ -7257,7 +7257,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.3" + "source": "https://github.com/symfony/finder/tree/v7.1.4" }, "funding": [ { @@ -7273,7 +7273,7 @@ "type": "tidelift" } ], - "time": "2024-07-24T07:08:44+00:00" + "time": "2024-08-13T14:28:19+00:00" }, { "name": "symfony/html-sanitizer", @@ -7423,16 +7423,16 @@ }, { "name": "symfony/http-kernel", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186" + "reference": "6efcbd1b3f444f631c386504fc83eeca25963747" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/db9702f3a04cc471ec8c70e881825db26ac5f186", - "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6efcbd1b3f444f631c386504fc83eeca25963747", + "reference": "6efcbd1b3f444f631c386504fc83eeca25963747", "shasum": "" }, "require": { @@ -7517,7 +7517,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.1.3" + "source": "https://github.com/symfony/http-kernel/tree/v7.1.4" }, "funding": [ { @@ -7533,7 +7533,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T14:58:15+00:00" + "time": "2024-08-30T17:02:28+00:00" }, { "name": "symfony/mailer", @@ -7617,16 +7617,16 @@ }, { "name": "symfony/mime", - "version": "v7.1.2", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc" + "reference": "ccaa6c2503db867f472a587291e764d6a1e58758" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/26a00b85477e69a4bab63b66c5dce64f18b0cbfc", - "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc", + "url": "https://api.github.com/repos/symfony/mime/zipball/ccaa6c2503db867f472a587291e764d6a1e58758", + "reference": "ccaa6c2503db867f472a587291e764d6a1e58758", "shasum": "" }, "require": { @@ -7681,7 +7681,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.1.2" + "source": "https://github.com/symfony/mime/tree/v7.1.4" }, "funding": [ { @@ -7697,7 +7697,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T10:03:55+00:00" + "time": "2024-08-13T14:28:19+00:00" }, { "name": "symfony/polyfill-ctype", @@ -8472,16 +8472,16 @@ }, { "name": "symfony/psr-http-message-bridge", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "1365d10f5476f74a27cf9c2d1eee70c069019db0" + "reference": "405a7bcd872f1563966f64be19f1362d94ce71ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/1365d10f5476f74a27cf9c2d1eee70c069019db0", - "reference": "1365d10f5476f74a27cf9c2d1eee70c069019db0", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/405a7bcd872f1563966f64be19f1362d94ce71ab", + "reference": "405a7bcd872f1563966f64be19f1362d94ce71ab", "shasum": "" }, "require": { @@ -8535,7 +8535,7 @@ "psr-7" ], "support": { - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.1.3" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.1.4" }, "funding": [ { @@ -8551,20 +8551,20 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:10:24+00:00" + "time": "2024-08-15T22:48:53+00:00" }, { "name": "symfony/routing", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0" + "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/8a908a3f22d5a1b5d297578c2ceb41b02fa916d0", - "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0", + "url": "https://api.github.com/repos/symfony/routing/zipball/1500aee0094a3ce1c92626ed8cf3c2037e86f5a7", + "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7", "shasum": "" }, "require": { @@ -8616,7 +8616,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.1.3" + "source": "https://github.com/symfony/routing/tree/v7.1.4" }, "funding": [ { @@ -8632,7 +8632,7 @@ "type": "tidelift" } ], - "time": "2024-07-17T06:10:24+00:00" + "time": "2024-08-29T08:16:25+00:00" }, { "name": "symfony/service-contracts", @@ -8719,16 +8719,16 @@ }, { "name": "symfony/string", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "ea272a882be7f20cad58d5d78c215001617b7f07" + "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07", - "reference": "ea272a882be7f20cad58d5d78c215001617b7f07", + "url": "https://api.github.com/repos/symfony/string/zipball/6cd670a6d968eaeb1c77c2e76091c45c56bc367b", + "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b", "shasum": "" }, "require": { @@ -8786,7 +8786,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.3" + "source": "https://github.com/symfony/string/tree/v7.1.4" }, "funding": [ { @@ -8802,7 +8802,7 @@ "type": "tidelift" } ], - "time": "2024-07-22T10:25:37+00:00" + "time": "2024-08-12T09:59:40+00:00" }, { "name": "symfony/translation", @@ -8978,16 +8978,16 @@ }, { "name": "symfony/uid", - "version": "v7.1.1", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277" + "reference": "82177535395109075cdb45a70533aa3d7a521cdf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/bb59febeecc81528ff672fad5dab7f06db8c8277", - "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277", + "url": "https://api.github.com/repos/symfony/uid/zipball/82177535395109075cdb45a70533aa3d7a521cdf", + "reference": "82177535395109075cdb45a70533aa3d7a521cdf", "shasum": "" }, "require": { @@ -9032,7 +9032,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.1.1" + "source": "https://github.com/symfony/uid/tree/v7.1.4" }, "funding": [ { @@ -9048,20 +9048,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-08-12T09:59:40+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.1.3", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f" + "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/86af4617cca75a6e28598f49ae0690f3b9d4591f", - "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a5fa7481b199090964d6fd5dab6294d5a870c7aa", + "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa", "shasum": "" }, "require": { @@ -9115,7 +9115,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.1.3" + "source": "https://github.com/symfony/var-dumper/tree/v7.1.4" }, "funding": [ { @@ -9131,7 +9131,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-08-30T16:12:47+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -9647,16 +9647,16 @@ }, { "name": "fidry/cpu-core-counter", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" + "reference": "8520451a140d3f46ac33042715115e290cf5785f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", "shasum": "" }, "require": { @@ -9696,7 +9696,7 @@ ], "support": { "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" }, "funding": [ { @@ -9704,7 +9704,7 @@ "type": "github" } ], - "time": "2024-02-07T09:43:46+00:00" + "time": "2024-08-06T10:04:20+00:00" }, { "name": "filp/whoops", @@ -11044,16 +11044,16 @@ }, { "name": "phpmyadmin/sql-parser", - "version": "5.9.1", + "version": "5.10.0", "source": { "type": "git", "url": "https://github.com/phpmyadmin/sql-parser.git", - "reference": "169a9f11f1957ea36607c9b29eac1b48679f1ecc" + "reference": "91d980ab76c3f152481e367f62b921adc38af451" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/169a9f11f1957ea36607c9b29eac1b48679f1ecc", - "reference": "169a9f11f1957ea36607c9b29eac1b48679f1ecc", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/91d980ab76c3f152481e367f62b921adc38af451", + "reference": "91d980ab76c3f152481e367f62b921adc38af451", "shasum": "" }, "require": { @@ -11127,20 +11127,20 @@ "type": "other" } ], - "time": "2024-08-13T19:01:01+00:00" + "time": "2024-08-29T20:56:34+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.1", + "version": "1.30.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/5ceb0e384997db59f38774bf79c2a6134252c08f", + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f", "shasum": "" }, "require": { @@ -11172,22 +11172,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.0" }, - "time": "2024-05-31T08:52:43+00:00" + "time": "2024-08-29T09:54:52+00:00" }, { "name": "phpstan/phpstan", - "version": "1.11.11", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3" + "reference": "384af967d35b2162f69526c7276acadce534d0e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/707c2aed5d8d0075666e673a5e71440c1d01a5a3", - "reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/384af967d35b2162f69526c7276acadce534d0e1", + "reference": "384af967d35b2162f69526c7276acadce534d0e1", "shasum": "" }, "require": { @@ -11232,7 +11232,7 @@ "type": "github" } ], - "time": "2024-08-19T14:37:29+00:00" + "time": "2024-08-27T09:18:05+00:00" }, { "name": "phpunit/php-code-coverage", @@ -12954,16 +12954,16 @@ }, { "name": "symfony/yaml", - "version": "v7.1.1", + "version": "v7.1.4", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "fa34c77015aa6720469db7003567b9f772492bf2" + "reference": "92e080b851c1c655c786a2da77f188f2dccd0f4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/fa34c77015aa6720469db7003567b9f772492bf2", - "reference": "fa34c77015aa6720469db7003567b9f772492bf2", + "url": "https://api.github.com/repos/symfony/yaml/zipball/92e080b851c1c655c786a2da77f188f2dccd0f4b", + "reference": "92e080b851c1c655c786a2da77f188f2dccd0f4b", "shasum": "" }, "require": { @@ -13005,7 +13005,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.1.1" + "source": "https://github.com/symfony/yaml/tree/v7.1.4" }, "funding": [ { @@ -13021,7 +13021,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-08-12T09:59:40+00:00" }, { "name": "ta-tikoma/phpunit-architecture-test", diff --git a/config/caddy/autosave.json b/config/caddy/autosave.json deleted file mode 100644 index d5799da..0000000 --- a/config/caddy/autosave.json +++ /dev/null @@ -1 +0,0 @@ -{"admin":{"listen":"localhost:2019"},"apps":{"frankenphp":{"workers":[{"file_name":"/var/www/html/public/frankenphp-worker.php"}]},"http":{"servers":{"srv0":{"automatic_https":{"disable_redirects":true},"listen":[":443"],"logs":{"logger_names":{"localhost":["log0"]}},"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"vars","root":"/var/www/html/public"},{"encodings":{"br":{},"gzip":{},"zstd":{}},"handler":"encode","prefer":["zstd","br","gzip"]}]},{"handle":[{"handler":"static_response","headers":{"Location":["{http.request.orig_uri.path}/"]},"status_code":308}],"match":[{"file":{"try_files":["{http.request.uri.path}/frankenphp-worker.php"]},"not":[{"path":["*/"]}]}]},{"handle":[{"handler":"rewrite","uri":"{http.matchers.file.relative}"}],"match":[{"file":{"split_path":[".php"],"try_files":["{http.request.uri.path}","{http.request.uri.path}/frankenphp-worker.php","frankenphp-worker.php"]}}]},{"handle":[{"handler":"php","resolve_root_symlink":true,"split_path":[".php"]}],"match":[{"path":["*.php"]}]},{"handle":[{"handler":"file_server"}]}]}]}]}],"match":[{"host":["localhost"]}],"terminal":true}]}}}},"logging":{"logs":{"default":{"exclude":["http.log.access.log0"]},"log0":{"encoder":{"fields":{"uri":{"actions":[{"parameter":"authorization","type":"replace","value":"REDACTED"}],"filter":"query"}},"format":"filter","wrap":{"format":"json"}},"include":["http.log.access.log0"],"level":"INFO"}}}} \ No newline at end of file diff --git a/config/octane.php b/config/octane.php index c6b2ad8..0a1ca51 100644 --- a/config/octane.php +++ b/config/octane.php @@ -12,13 +12,10 @@ use Laravel\Octane\Events\WorkerErrorOccurred; use Laravel\Octane\Events\WorkerStarting; use Laravel\Octane\Events\WorkerStopping; use Laravel\Octane\Listeners\CloseMonologHandlers; -use Laravel\Octane\Listeners\CollectGarbage; -use Laravel\Octane\Listeners\DisconnectFromDatabases; use Laravel\Octane\Listeners\EnsureUploadedFilesAreValid; use Laravel\Octane\Listeners\EnsureUploadedFilesCanBeMoved; use Laravel\Octane\Listeners\FlushOnce; use Laravel\Octane\Listeners\FlushTemporaryContainerInstances; -use Laravel\Octane\Listeners\FlushUploadedFiles; use Laravel\Octane\Listeners\ReportException; use Laravel\Octane\Listeners\StopWorkerIfNecessary; use Laravel\Octane\Octane; @@ -38,7 +35,7 @@ return [ | */ - 'server' => env('OCTANE_SERVER', 'swoole'), + 'server' => env('OCTANE_SERVER', 'frankenphp'), /* |-------------------------------------------------------------------------- diff --git a/database/migrations/2024_05_15_022710_create_mods_table.php b/database/migrations/2024_05_15_022710_create_mods_table.php index 9e5c9d8..1c88974 100644 --- a/database/migrations/2024_05_15_022710_create_mods_table.php +++ b/database/migrations/2024_05_15_022710_create_mods_table.php @@ -26,6 +26,7 @@ return new class extends Migration ->constrained('licenses') ->nullOnDelete() ->cascadeOnUpdate(); + $table->unsignedBigInteger('downloads')->default(0); $table->string('source_code_link'); $table->boolean('featured')->default(false); $table->boolean('contains_ai_content')->default(false); diff --git a/database/migrations/2024_05_15_023430_create_spt_versions_table.php b/database/migrations/2024_05_15_023430_create_spt_versions_table.php index 88cb14d..1c6a0a0 100644 --- a/database/migrations/2024_05_15_023430_create_spt_versions_table.php +++ b/database/migrations/2024_05_15_023430_create_spt_versions_table.php @@ -15,12 +15,18 @@ return new class extends Migration ->default(null) ->unique(); $table->string('version'); + $table->unsignedInteger('version_major'); + $table->unsignedInteger('version_minor'); + $table->unsignedInteger('version_patch'); + $table->string('version_pre_release'); + $table->unsignedInteger('mod_count')->default(0); $table->string('link'); $table->string('color_class'); $table->softDeletes(); $table->timestamps(); - $table->index(['version', 'deleted_at'], 'spt_versions_filtering_index'); + $table->index(['version', 'deleted_at', 'id'], 'spt_versions_filtering_index'); + $table->index(['version_major', 'version_minor', 'version_patch', 'version_pre_release', 'deleted_at'], 'spt_versions_lookup_index'); }); } diff --git a/docker-compose.yml b/docker-compose.yml index 85194b7..eb4b988 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,7 +19,9 @@ services: XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}' XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}' IGNITION_LOCAL_SITES_PATH: '${PWD}' - SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=swoole --host=0.0.0.0 --port=80 --watch" + SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan octane:start --host=localhost --port=80 --admin-port=2019 --watch" + XDG_CONFIG_HOME: /var/www/html/config + XDG_DATA_HOME: /var/www/html/data volumes: - '.:/var/www/html' networks: diff --git a/package-lock.json b/package-lock.json index a1280f1..f9cb11c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,10 +1,9 @@ { - "name": "forge", + "name": "html", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "forge", "dependencies": { "@alpinejs/focus": "^3.14.1" }, @@ -557,9 +556,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.0.tgz", - "integrity": "sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", + "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", "cpu": [ "arm" ], @@ -571,9 +570,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.0.tgz", - "integrity": "sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", + "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", "cpu": [ "arm64" ], @@ -585,9 +584,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.0.tgz", - "integrity": "sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", + "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", "cpu": [ "arm64" ], @@ -599,9 +598,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.0.tgz", - "integrity": "sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", + "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", "cpu": [ "x64" ], @@ -613,9 +612,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.0.tgz", - "integrity": "sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", + "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", "cpu": [ "arm" ], @@ -627,9 +626,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.0.tgz", - "integrity": "sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", + "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", "cpu": [ "arm" ], @@ -641,9 +640,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.0.tgz", - "integrity": "sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", + "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", "cpu": [ "arm64" ], @@ -655,9 +654,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.0.tgz", - "integrity": "sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", + "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", "cpu": [ "arm64" ], @@ -669,9 +668,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.0.tgz", - "integrity": "sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", + "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", "cpu": [ "ppc64" ], @@ -683,9 +682,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.0.tgz", - "integrity": "sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", + "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", "cpu": [ "riscv64" ], @@ -697,9 +696,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.0.tgz", - "integrity": "sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", + "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", "cpu": [ "s390x" ], @@ -711,9 +710,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.0.tgz", - "integrity": "sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", + "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", "cpu": [ "x64" ], @@ -725,9 +724,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.0.tgz", - "integrity": "sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", + "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", "cpu": [ "x64" ], @@ -739,9 +738,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.0.tgz", - "integrity": "sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", + "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", "cpu": [ "arm64" ], @@ -753,9 +752,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.0.tgz", - "integrity": "sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", + "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", "cpu": [ "ia32" ], @@ -767,9 +766,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.0.tgz", - "integrity": "sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", + "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", "cpu": [ "x64" ], @@ -781,22 +780,22 @@ ] }, "node_modules/@tailwindcss/forms": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz", - "integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.8.tgz", + "integrity": "sha512-DJs7B7NPD0JH7BVvdHWNviWmunlFhuEkz7FyFxE4japOWYMLl9b1D6+Z9mivJJPWr6AEbmlPqgiFRyLwFB1SgQ==", "dev": true, "license": "MIT", "dependencies": { "mini-svg-data-uri": "^1.2.3" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20" } }, "node_modules/@tailwindcss/typography": { - "version": "0.5.14", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.14.tgz", - "integrity": "sha512-ZvOCjUbsJBjL9CxQBn+VEnFpouzuKhxh2dH8xMIWHILL+HfOYtlAkWcyoon8LlzE53d2Yo6YO6pahKKNW3q1YQ==", + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.15.tgz", + "integrity": "sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==", "dev": true, "license": "MIT", "dependencies": { @@ -806,7 +805,7 @@ "postcss-selector-parser": "6.0.10" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders" + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20" } }, "node_modules/@types/estree": { @@ -916,9 +915,9 @@ } }, "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.6.tgz", + "integrity": "sha512-Ekur6XDwhnJ5RgOCaxFnXyqlPALI3rVeukZMwOdfghW7/wGz784BYKiQq+QD8NPcr91KRo30KfHOchyijwWw7g==", "dev": true, "license": "MIT", "dependencies": { @@ -1014,9 +1013,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001651", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", - "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", + "version": "1.0.30001655", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", + "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==", "dev": true, "funding": [ { @@ -1215,9 +1214,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { @@ -1593,9 +1592,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -2177,9 +2176,9 @@ } }, "node_modules/rollup": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.0.tgz", - "integrity": "sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", + "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", "dev": true, "license": "MIT", "dependencies": { @@ -2193,22 +2192,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.21.0", - "@rollup/rollup-android-arm64": "4.21.0", - "@rollup/rollup-darwin-arm64": "4.21.0", - "@rollup/rollup-darwin-x64": "4.21.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.21.0", - "@rollup/rollup-linux-arm-musleabihf": "4.21.0", - "@rollup/rollup-linux-arm64-gnu": "4.21.0", - "@rollup/rollup-linux-arm64-musl": "4.21.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.21.0", - "@rollup/rollup-linux-riscv64-gnu": "4.21.0", - "@rollup/rollup-linux-s390x-gnu": "4.21.0", - "@rollup/rollup-linux-x64-gnu": "4.21.0", - "@rollup/rollup-linux-x64-musl": "4.21.0", - "@rollup/rollup-win32-arm64-msvc": "4.21.0", - "@rollup/rollup-win32-ia32-msvc": "4.21.0", - "@rollup/rollup-win32-x64-msvc": "4.21.0", + "@rollup/rollup-android-arm-eabi": "4.21.2", + "@rollup/rollup-android-arm64": "4.21.2", + "@rollup/rollup-darwin-arm64": "4.21.2", + "@rollup/rollup-darwin-x64": "4.21.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", + "@rollup/rollup-linux-arm-musleabihf": "4.21.2", + "@rollup/rollup-linux-arm64-gnu": "4.21.2", + "@rollup/rollup-linux-arm64-musl": "4.21.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", + "@rollup/rollup-linux-riscv64-gnu": "4.21.2", + "@rollup/rollup-linux-s390x-gnu": "4.21.2", + "@rollup/rollup-linux-x64-gnu": "4.21.2", + "@rollup/rollup-linux-x64-musl": "4.21.2", + "@rollup/rollup-win32-arm64-msvc": "4.21.2", + "@rollup/rollup-win32-ia32-msvc": "4.21.2", + "@rollup/rollup-win32-x64-msvc": "4.21.2", "fsevents": "~2.3.2" } }, diff --git a/resources/views/components/mod-list-stats.blade.php b/resources/views/components/mod-list-stats.blade.php index babb578..286fb3b 100644 --- a/resources/views/components/mod-list-stats.blade.php +++ b/resources/views/components/mod-list-stats.blade.php @@ -1,5 +1,5 @@

class(['text-slate-700 dark:text-gray-300 text-sm']) }}> - {{ Number::downloads($mod->total_downloads) }} downloads + {{ Number::downloads($mod->downloads) }} downloads @if(!is_null($mod->created_at)) — Created diff --git a/resources/views/mod/show.blade.php b/resources/views/mod/show.blade.php index e163926..9ad2f8f 100644 --- a/resources/views/mod/show.blade.php +++ b/resources/views/mod/show.blade.php @@ -38,7 +38,7 @@ {{ $user->name }}{{ $loop->last ? '' : ',' }} @endforeach

-

{{ Number::downloads($mod->total_downloads) }} {{ __('Downloads') }}

+

{{ Number::downloads($mod->downloads) }} {{ __('Downloads') }}

{{ $mod->latestVersion->latestSptVersion->first()->version_formatted }} {{ __('Compatible') }} diff --git a/routes/console.php b/routes/console.php index c11c5a6..6ab56fc 100644 --- a/routes/console.php +++ b/routes/console.php @@ -2,9 +2,13 @@ use App\Console\Commands\ImportHubCommand; use App\Console\Commands\ResolveVersionsCommand; +use App\Console\Commands\SptVersionModCountsCommand; +use App\Console\Commands\UpdateModDownloadsCommand; use Illuminate\Support\Facades\Schedule; Schedule::command(ImportHubCommand::class)->hourly(); Schedule::command(ResolveVersionsCommand::class)->hourlyAt(30); +Schedule::command(SptVersionModCountsCommand::class)->hourlyAt(40); +Schedule::command(UpdateModDownloadsCommand::class)->hourlyAt(45); Schedule::command('horizon:snapshot')->everyFiveMinutes(); diff --git a/tests/Feature/Mod/SptVersionTest.php b/tests/Feature/Mod/SptVersionTest.php new file mode 100644 index 0000000..0dc17d8 --- /dev/null +++ b/tests/Feature/Mod/SptVersionTest.php @@ -0,0 +1,32 @@ +create(['version' => '1.1.1']); + SptVersion::factory()->create(['version' => '1.2.0']); + $version = SptVersion::factory()->create(['version' => '1.3.0']); + SptVersion::factory()->create(['version' => '1.3.2']); + SptVersion::factory()->create(['version' => '1.3.3']); + + expect($version->isLatestMinor())->toBeTrue(); +}); + +it("returns false if the version is not part of the latest version's minor releases", function () { + SptVersion::factory()->create(['version' => '1.1.1']); + SptVersion::factory()->create(['version' => '1.2.0']); + $version = SptVersion::factory()->create(['version' => '1.2.1']); + SptVersion::factory()->create(['version' => '1.3.2']); + SptVersion::factory()->create(['version' => '1.3.3']); + + expect($version->isLatestMinor())->toBeFalse(); +}); + +it('returns false if there is no latest version in the database', function () { + $version = SptVersion::factory()->make(['version' => '1.0.0']); + + expect($version->isLatestMinor())->toBeFalse(); +});