From fdce543b9935fcda9a3c74c76813eabf80cb9f68 Mon Sep 17 00:00:00 2001 From: BitPyrate <155480328+BitPyrate@users.noreply.github.com> Date: Tue, 2 Apr 2024 18:58:01 -0500 Subject: [PATCH 01/61] Update two-factor-auth-form.blade.php Changed 2fa wording to be less exclusive to google --- resources/views/livewire/two-factor-auth-form.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/two-factor-auth-form.blade.php b/resources/views/livewire/two-factor-auth-form.blade.php index ebb758b8eb..6758afee55 100644 --- a/resources/views/livewire/two-factor-auth-form.blade.php +++ b/resources/views/livewire/two-factor-auth-form.blade.php @@ -21,7 +21,7 @@
- {{ __('When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone\'s Google Authenticator application.') }} + {{ __('When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from a syncronized 2fa app (Google Authenticator, Authy, BitWarden, etc.) }}
From 3152cc554f6462dd5c326f324c90832ec6434d5d Mon Sep 17 00:00:00 2001 From: LostRager Date: Wed, 3 Apr 2024 04:39:28 +0200 Subject: [PATCH 02/61] (Fix) Call to a member function pluck() on array --- app/Http/Resources/TorrentResource.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Resources/TorrentResource.php b/app/Http/Resources/TorrentResource.php index 223c7e413f..f8a4a634f0 100644 --- a/app/Http/Resources/TorrentResource.php +++ b/app/Http/Resources/TorrentResource.php @@ -31,7 +31,7 @@ public function toArray($request): array 'attributes' => [ 'meta' => [ 'poster' => isset($this->meta->poster) ? tmdb_image('poster_small', $this->meta->poster) : 'https://via.placeholder.com/90x135', - 'genres' => isset($this->meta->genres) ? $this->meta->genres->pluck('name')->implode(', ') : '', + 'genres' => isset($this->meta->genres) ? collect($this->meta->genres)->pluck('name')->implode(', ') : '', ], 'name' => $this->name, 'release_year' => $this->release_year, From bcfbb35e64a1206aeb6f7823c58e3eca4e8d7b24 Mon Sep 17 00:00:00 2001 From: Jay Sizzla Date: Thu, 4 Apr 2024 12:13:03 +0200 Subject: [PATCH 03/61] Add invite priv to group requirements page --- .../views/stats/groups/groups-requirements.blade.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/resources/views/stats/groups/groups-requirements.blade.php b/resources/views/stats/groups/groups-requirements.blade.php index 5930413302..7e0ae94540 100644 --- a/resources/views/stats/groups/groups-requirements.blade.php +++ b/resources/views/stats/groups/groups-requirements.blade.php @@ -175,6 +175,7 @@ class="{{ config('other.font-awesome') }} fa-arrow-down-short-wide text-blue" DL Slots: {{ $group->download_slots ?? '∞' }} + @if ($group->can_upload) @@ -187,6 +188,17 @@ class="{{ config('other.font-awesome') }} fa-upload text-success" @endif + @if (\in_array($group->name, config('other.invite_groups'), true)) + + + + {{ __('user.send-invite') }} + + + @endif + @if ($group->is_freeleech) From b628252b5a5376b9b12948a3e16ee7380730603c Mon Sep 17 00:00:00 2001 From: Jay Sizzla Date: Thu, 4 Apr 2024 12:21:12 +0200 Subject: [PATCH 04/61] Requirements & Perks columns should be equal in width --- resources/sass/pages/_stats.scss | 6 ++++++ resources/views/stats/groups/groups-requirements.blade.php | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/resources/sass/pages/_stats.scss b/resources/sass/pages/_stats.scss index a2a26e67ae..8474bf000d 100644 --- a/resources/sass/pages/_stats.scss +++ b/resources/sass/pages/_stats.scss @@ -9,3 +9,9 @@ display: table; table-layout: fixed; } + +.perks-table tr { + width: 100%; + display: table; + table-layout: fixed; +} diff --git a/resources/views/stats/groups/groups-requirements.blade.php b/resources/views/stats/groups/groups-requirements.blade.php index 7e0ae94540..6797706185 100644 --- a/resources/views/stats/groups/groups-requirements.blade.php +++ b/resources/views/stats/groups/groups-requirements.blade.php @@ -165,7 +165,7 @@ class="{{ config('other.font-awesome') }} fa-x text-red" @endif - +
@endif - @if (\in_array($group->name, config('other.invite_groups'), true)) + @if (!config('other.invites_restriced') || (config('other.invites_restriced') && \in_array($group->name, config('other.invite_groups'), true))) @endif - @if (!config('other.invites_restriced') || (config('other.invites_restriced') && \in_array($group->name, config('other.invite_groups'), true))) + @if (! config('other.invites_restriced') || (config('other.invites_restriced') && \in_array($group->name, config('other.invite_groups'), true)))
From f01beb9f1f470d2e270f793e4ba606e6040f8b2a Mon Sep 17 00:00:00 2001 From: Jay Sizzla Date: Thu, 4 Apr 2024 13:15:09 +0200 Subject: [PATCH 05/61] Add mobile layout --- resources/sass/pages/_stats.scss | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/resources/sass/pages/_stats.scss b/resources/sass/pages/_stats.scss index 8474bf000d..d47effb948 100644 --- a/resources/sass/pages/_stats.scss +++ b/resources/sass/pages/_stats.scss @@ -15,3 +15,21 @@ display: table; table-layout: fixed; } + +@media only screen and (max-width: 806px) { + .data-table > thead { + display: none; + } + + .data-table:not(.requirements-table):not(.perks-table) > tbody > tr { + width: 100%; + display: grid; + grid-template-columns: 1fr; + grid-template-rows: auto; + margin-bottom: 20px; + } + + .data-table > tbody > tr > td { + text-align: center; + } +} From 2825e1e4b1945de5fd6583f06d7d0f10cf36a1e0 Mon Sep 17 00:00:00 2001 From: Jay Sizzla Date: Thu, 4 Apr 2024 20:17:42 +0200 Subject: [PATCH 06/61] Take global invite restriction into account --- resources/views/stats/groups/groups-requirements.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/stats/groups/groups-requirements.blade.php b/resources/views/stats/groups/groups-requirements.blade.php index 6797706185..ae21f751a0 100644 --- a/resources/views/stats/groups/groups-requirements.blade.php +++ b/resources/views/stats/groups/groups-requirements.blade.php @@ -188,7 +188,7 @@ class="{{ config('other.font-awesome') }} fa-upload text-success"
Date: Thu, 4 Apr 2024 18:18:42 +0000 Subject: [PATCH 07/61] Blade Style Change (Prettier Blade CI) --- resources/views/stats/groups/groups-requirements.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/stats/groups/groups-requirements.blade.php b/resources/views/stats/groups/groups-requirements.blade.php index ae21f751a0..c8b8773e81 100644 --- a/resources/views/stats/groups/groups-requirements.blade.php +++ b/resources/views/stats/groups/groups-requirements.blade.php @@ -188,7 +188,7 @@ class="{{ config('other.font-awesome') }} fa-upload text-success"
Date: Sat, 6 Apr 2024 12:45:34 +0200 Subject: [PATCH 08/61] Improve desktop and mobile layout --- resources/sass/pages/_stats.scss | 27 +++++++++++++++---- .../groups/groups-requirements.blade.php | 6 ++--- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/resources/sass/pages/_stats.scss b/resources/sass/pages/_stats.scss index d47effb948..5dcf79e697 100644 --- a/resources/sass/pages/_stats.scss +++ b/resources/sass/pages/_stats.scss @@ -4,24 +4,41 @@ gap: 1rem; } -.requirements-table tr { +.stats__requirements-table tr { width: 100%; display: table; table-layout: fixed; } -.perks-table tr { +.stats__perks-table tr { width: 100%; display: table; table-layout: fixed; } +.stats__requirements-table tr:nth-child(even) > td, +.stats__perks-table tr:nth-child(even) > td { + background-color: inherit; +} + +.stats__requirements-table tr:nth-child(odd) > td, +.stats__perks-table tr:nth-child(odd) > td { + background-color: inherit; +} + +.stats__requirements-table > tr:not(:last-child) > td, +.stats__requirements-table > thead > tr:not(:last-child) > td, +.stats__requirements-table > tbody > tr:not(:last-child) > td, +.stats__requirements-table > tfoot > tr:not(:last-child) > td { + border-bottom: var(--data-table-tr-border); +} + @media only screen and (max-width: 806px) { - .data-table > thead { + .stats__groups-table > thead { display: none; } - .data-table:not(.requirements-table):not(.perks-table) > tbody > tr { + .stats__groups-table > tbody > tr { width: 100%; display: grid; grid-template-columns: 1fr; @@ -29,7 +46,7 @@ margin-bottom: 20px; } - .data-table > tbody > tr > td { + .stats__groups-table > tbody > tr > td { text-align: center; } } diff --git a/resources/views/stats/groups/groups-requirements.blade.php b/resources/views/stats/groups/groups-requirements.blade.php index c8b8773e81..50d7285794 100644 --- a/resources/views/stats/groups/groups-requirements.blade.php +++ b/resources/views/stats/groups/groups-requirements.blade.php @@ -28,7 +28,7 @@

{{ __('stat.groups') }}

- +
@@ -53,7 +53,7 @@
{{ __('common.group') }} @if ($group->autogroup) - +
@@ -165,7 +165,7 @@ class="{{ config('other.font-awesome') }} fa-x text-red" @endif
- +
From 14652fa8b882fbb0ce30963cf71ed1b3fda576a9 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Sat, 6 Apr 2024 21:02:18 -0400 Subject: [PATCH 09/61] fix: broken syntax --- resources/views/livewire/two-factor-auth-form.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/two-factor-auth-form.blade.php b/resources/views/livewire/two-factor-auth-form.blade.php index 6758afee55..00e06dcbc3 100644 --- a/resources/views/livewire/two-factor-auth-form.blade.php +++ b/resources/views/livewire/two-factor-auth-form.blade.php @@ -21,7 +21,7 @@
- {{ __('When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from a syncronized 2fa app (Google Authenticator, Authy, BitWarden, etc.) }} + {{ __('When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from a syncronized 2fa app such as Google Authenticator, Authy, BitWarden, etc.') }}
From 3f1e4971d92f6eba00fe327602471d1d00ca6aef Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Sat, 6 Apr 2024 21:05:23 -0400 Subject: [PATCH 10/61] chore: larastan --- phpstan-baseline.neon | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1d1f0cdfed..906a2a40ca 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1275,6 +1275,16 @@ parameters: count: 1 path: app/Http/Resources/TorrentResource.php + - + message: "#^Unable to resolve the template type TKey in call to function collect$#" + count: 1 + path: app/Http/Resources/TorrentResource.php + + - + message: "#^Unable to resolve the template type TValue in call to function collect$#" + count: 1 + path: app/Http/Resources/TorrentResource.php + - message: "#^Method App\\\\Http\\\\Resources\\\\TorrentsResource\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 From 5da57295fc12b1d78b75c06797b0fe10e680c928 Mon Sep 17 00:00:00 2001 From: crKtv <36048892+crKtv@users.noreply.github.com> Date: Sun, 7 Apr 2024 17:18:20 +0100 Subject: [PATCH 11/61] Update row.blade.php --- resources/views/components/torrent/row.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/components/torrent/row.blade.php b/resources/views/components/torrent/row.blade.php index b075e2c057..a34c295d64 100644 --- a/resources/views/components/torrent/row.blade.php +++ b/resources/views/components/torrent/row.blade.php @@ -18,7 +18,7 @@ data-mal-id="{{ $torrent->mal }}" data-category-id="{{ $torrent->category_id }}" data-type-id="{{ $torrent->type_id }}" - data-type-id="{{ $torrent->resolution_id }}" + data-resolution-id="{{ $torrent->resolution_id }}" > @if (auth()->user()->show_poster == 1)
From 65ced2cf75566fe8ec0ead81031715fd92c81ca3 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Sun, 7 Apr 2024 20:29:49 -0400 Subject: [PATCH 12/61] fix: #3729 - closes #3729 --- app/Http/Livewire/InviteLogSearch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Livewire/InviteLogSearch.php b/app/Http/Livewire/InviteLogSearch.php index 2575dab80a..61bb84dbc3 100644 --- a/app/Http/Livewire/InviteLogSearch.php +++ b/app/Http/Livewire/InviteLogSearch.php @@ -85,7 +85,7 @@ final public function invites(): \Illuminate\Contracts\Pagination\LengthAwarePag ->when($this->sender, fn ($query) => $query->whereRelation('sender', 'username', '=', $this->sender)) ->when($this->email, fn ($query) => $query->where('email', 'LIKE', '%'.$this->email.'%')) ->when($this->code, fn ($query) => $query->where('code', 'LIKE', '%'.$this->code.'%')) - ->when($this->receiver, fn ($query) => $query->whereRelation('sender', 'username', '=', $this->receiver)) + ->when($this->receiver, fn ($query) => $query->whereRelation('receiver', 'username', '=', $this->receiver)) ->when($this->custom, fn ($query) => $query->where('custom', 'LIKE', '%'.$this->custom.'%')) ->when( $this->groupBy === 'user_id', From c5d7859dd83730857cd00010da0349c5f54c322b Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Sun, 7 Apr 2024 21:03:50 -0400 Subject: [PATCH 13/61] fix: #3724 - closes #3724 --- app/Http/Controllers/API/TorrentController.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/API/TorrentController.php b/app/Http/Controllers/API/TorrentController.php index e840a54b7a..be5ed885af 100644 --- a/app/Http/Controllers/API/TorrentController.php +++ b/app/Http/Controllers/API/TorrentController.php @@ -79,10 +79,12 @@ public function index(): TorrentsResource ) ->latest('sticky') ->latest('bumped_at') - ->paginate(25); + ->cursorPaginate(25); // See app/Traits/TorrentMeta.php - return $this->scopeMeta($torrents); + $this->scopeMeta($torrents); + + return $torrents; }); return new TorrentsResource($torrents); @@ -499,7 +501,7 @@ public function filter(Request $request): TorrentsResource|\Illuminate\Http\Json $cacheKey = $url.'?'.$queryString; $torrents = cache()->remember($cacheKey, 300, function () use ($request, $isRegex) { - $torrents = Torrent::with(['user:id,username', 'category', 'type', 'resolution', 'distributor', 'region']) + $torrents = Torrent::with(['user:id,username', 'category', 'type', 'resolution', 'distributor', 'region', 'files']) ->select('*') ->selectRaw(" CASE @@ -546,10 +548,12 @@ public function filter(Request $request): TorrentsResource|\Illuminate\Http\Json ->when($request->filled('episodeNumber'), fn ($query) => $query->ofEpisode((int) $request->episodeNumber)) ->latest('sticky') ->orderBy($request->input('sortField') ?? $this->sortField, $request->input('sortDirection') ?? $this->sortDirection) - ->paginate(min($request->input('perPage') ?? $this->perPage, 100)); + ->cursorPaginate(min($request->input('perPage') ?? $this->perPage, 100)); // See app/Traits/TorrentMeta.php - return $this->scopeMeta($torrents); + $this->scopeMeta($torrents); + + return $torrents; }); if ($torrents !== null) { From b308debf51aec8594a2f49af84d5f97a4d9b4fa9 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Mon, 8 Apr 2024 11:57:26 -0400 Subject: [PATCH 14/61] update: dependencies --- composer.json | 7 +- composer.lock | 316 ++++++---- docker-compose.yml | 21 + public/vendor/livewire/livewire.js | 851 ++++++++++++++++----------- public/vendor/livewire/manifest.json | 2 +- 5 files changed, 711 insertions(+), 486 deletions(-) diff --git a/composer.json b/composer.json index 6933145117..6d6d2f4957 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "laravel/fortify": "1.20.0", "laravel/framework": "^10.48.4", "laravel/tinker": "^2.9.0", - "livewire/livewire": "^v3.4.9", + "livewire/livewire": "^v3.4.10", "marcreichel/igdb-laravel": "^3.8.1", "paragonie/constant_time_encoding": "^2.6.3", "spatie/laravel-backup": "^8.6.0", @@ -45,7 +45,7 @@ "fakerphp/faker": "^1.23.1", "jasonmccreary/laravel-test-assertions": "^2.4", "larastan/larastan": "^2.9.2", - "laravel/pint": "^1.15.0", + "laravel/pint": "^1.15.1", "laravel/sail": "^1.29.1", "mockery/mockery": "^1.6.11", "nunomaduro/collision": "v7.10.0", @@ -54,7 +54,8 @@ "pestphp/pest-plugin-laravel": "^v2.2.0", "pestphp/pest-plugin-livewire": "^2.1", "phpunit/phpunit": "10.5.9", - "spatie/laravel-ignition": "^2.4.2" + "ryoluo/sail-ssl": "^1.3.2", + "spatie/laravel-ignition": "^2.5.1" }, "config": { "preferred-install": "dist", diff --git a/composer.lock b/composer.lock index 127bde0595..2dbbbec3b9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5543f09b65f9fa46d16125107cfa64ae", + "content-hash": "755663ed237060ffa943aab3c6bc96a8", "packages": [ { "name": "assada/laravel-achievements", @@ -2753,16 +2753,16 @@ }, { "name": "league/flysystem", - "version": "3.26.0", + "version": "3.27.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "072735c56cc0da00e10716dd90d5a7f7b40b36be" + "reference": "4729745b1ab737908c7d055148c9a6b3e959832f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/072735c56cc0da00e10716dd90d5a7f7b40b36be", - "reference": "072735c56cc0da00e10716dd90d5a7f7b40b36be", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/4729745b1ab737908c7d055148c9a6b3e959832f", + "reference": "4729745b1ab737908c7d055148c9a6b3e959832f", "shasum": "" }, "require": { @@ -2827,7 +2827,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.26.0" + "source": "https://github.com/thephpleague/flysystem/tree/3.27.0" }, "funding": [ { @@ -2839,7 +2839,7 @@ "type": "github" } ], - "time": "2024-03-25T11:49:53+00:00" + "time": "2024-04-07T19:17:50+00:00" }, { "name": "league/flysystem-local", @@ -2958,16 +2958,16 @@ }, { "name": "livewire/livewire", - "version": "v3.4.9", + "version": "v3.4.10", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0" + "reference": "6f90e2d7f8e80a97a7406c22a0fbc61ca1256ed9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0", - "reference": "c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0", + "url": "https://api.github.com/repos/livewire/livewire/zipball/6f90e2d7f8e80a97a7406c22a0fbc61ca1256ed9", + "reference": "6f90e2d7f8e80a97a7406c22a0fbc61ca1256ed9", "shasum": "" }, "require": { @@ -2977,6 +2977,7 @@ "illuminate/validation": "^10.0|^11.0", "league/mime-type-detection": "^1.9", "php": "^8.1", + "symfony/console": "^6.0|^7.0", "symfony/http-kernel": "^6.2|^7.0" }, "require-dev": { @@ -2984,8 +2985,8 @@ "laravel/framework": "^10.0|^11.0", "laravel/prompts": "^0.1.6", "mockery/mockery": "^1.3.1", - "orchestra/testbench": "8.20.0|^9.0", - "orchestra/testbench-dusk": "8.20.0|^9.0", + "orchestra/testbench": "^8.21.0|^9.0", + "orchestra/testbench-dusk": "^8.24|^9.1", "phpunit/phpunit": "^10.4", "psy/psysh": "^0.11.22|^0.12" }, @@ -3021,7 +3022,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v3.4.9" + "source": "https://github.com/livewire/livewire/tree/v3.4.10" }, "funding": [ { @@ -3029,7 +3030,7 @@ "type": "github" } ], - "time": "2024-03-14T14:03:32+00:00" + "time": "2024-04-02T14:22:50+00:00" }, { "name": "marcreichel/igdb-laravel", @@ -3105,16 +3106,16 @@ }, { "name": "masterminds/html5", - "version": "2.8.1", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", - "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", "shasum": "" }, "require": { @@ -3122,7 +3123,7 @@ "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9" }, "type": "library", "extra": { @@ -3166,9 +3167,9 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" + "source": "https://github.com/Masterminds/html5-php/tree/2.9.0" }, - "time": "2023-05-10T11:58:31+00:00" + "time": "2024-03-31T07:05:07+00:00" }, { "name": "monolog/monolog", @@ -4325,16 +4326,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.2", + "version": "v0.12.3", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "9185c66c2165bbf4d71de78a69dccf4974f9538d" + "reference": "b6b6cce7d3ee8fbf31843edce5e8f5a72eff4a73" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/9185c66c2165bbf4d71de78a69dccf4974f9538d", - "reference": "9185c66c2165bbf4d71de78a69dccf4974f9538d", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/b6b6cce7d3ee8fbf31843edce5e8f5a72eff4a73", + "reference": "b6b6cce7d3ee8fbf31843edce5e8f5a72eff4a73", "shasum": "" }, "require": { @@ -4398,9 +4399,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.2" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.3" }, - "time": "2024-03-17T01:53:00+00:00" + "time": "2024-04-02T15:57:53+00:00" }, { "name": "ralouphie/getallheaders", @@ -4629,16 +4630,16 @@ }, { "name": "spatie/db-dumper", - "version": "3.4.2", + "version": "3.5.0", "source": { "type": "git", "url": "https://github.com/spatie/db-dumper.git", - "reference": "59beef7ad612ca7463dfddb64de6e038eb59e0d7" + "reference": "d6519cd43cb8dacec448e97fb713240f9467d147" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/db-dumper/zipball/59beef7ad612ca7463dfddb64de6e038eb59e0d7", - "reference": "59beef7ad612ca7463dfddb64de6e038eb59e0d7", + "url": "https://api.github.com/repos/spatie/db-dumper/zipball/d6519cd43cb8dacec448e97fb713240f9467d147", + "reference": "d6519cd43cb8dacec448e97fb713240f9467d147", "shasum": "" }, "require": { @@ -4676,7 +4677,7 @@ "spatie" ], "support": { - "source": "https://github.com/spatie/db-dumper/tree/3.4.2" + "source": "https://github.com/spatie/db-dumper/tree/3.5.0" }, "funding": [ { @@ -4688,7 +4689,7 @@ "type": "github" } ], - "time": "2023-12-25T11:42:15+00:00" + "time": "2024-04-08T07:24:04+00:00" }, { "name": "spatie/image-optimizer", @@ -5305,16 +5306,16 @@ }, { "name": "symfony/console", - "version": "v6.4.4", + "version": "v6.4.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0d9e4eb5ad413075624378f474c4167ea202de78" + "reference": "a2708a5da5c87d1d0d52937bdeac625df659e11f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0d9e4eb5ad413075624378f474c4167ea202de78", - "reference": "0d9e4eb5ad413075624378f474c4167ea202de78", + "url": "https://api.github.com/repos/symfony/console/zipball/a2708a5da5c87d1d0d52937bdeac625df659e11f", + "reference": "a2708a5da5c87d1d0d52937bdeac625df659e11f", "shasum": "" }, "require": { @@ -5379,7 +5380,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.4" + "source": "https://github.com/symfony/console/tree/v6.4.6" }, "funding": [ { @@ -5395,7 +5396,7 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:10+00:00" + "time": "2024-03-29T19:07:53+00:00" }, { "name": "symfony/css-selector", @@ -5598,16 +5599,16 @@ }, { "name": "symfony/error-handler", - "version": "v6.4.4", + "version": "v6.4.6", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "c725219bdf2afc59423c32793d5019d2a904e13a" + "reference": "64db1c1802e3a4557e37ba33031ac39f452ac5d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/c725219bdf2afc59423c32793d5019d2a904e13a", - "reference": "c725219bdf2afc59423c32793d5019d2a904e13a", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/64db1c1802e3a4557e37ba33031ac39f452ac5d4", + "reference": "64db1c1802e3a4557e37ba33031ac39f452ac5d4", "shasum": "" }, "require": { @@ -5653,7 +5654,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.4.4" + "source": "https://github.com/symfony/error-handler/tree/v6.4.6" }, "funding": [ { @@ -5669,7 +5670,7 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:10+00:00" + "time": "2024-03-19T11:56:30+00:00" }, { "name": "symfony/event-dispatcher", @@ -5753,16 +5754,16 @@ }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.4.0", + "version": "v3.4.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + "reference": "4e64b49bf370ade88e567de29465762e316e4224" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/4e64b49bf370ade88e567de29465762e316e4224", + "reference": "4e64b49bf370ade88e567de29465762e316e4224", "shasum": "" }, "require": { @@ -5809,7 +5810,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.2" }, "funding": [ { @@ -5825,7 +5826,7 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-01-23T14:51:35+00:00" }, { "name": "symfony/finder", @@ -5970,16 +5971,16 @@ }, { "name": "symfony/http-kernel", - "version": "v6.4.5", + "version": "v6.4.6", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "f6947cb939d8efee137797382cb4db1af653ef75" + "reference": "060038863743fd0cd982be06acecccf246d35653" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f6947cb939d8efee137797382cb4db1af653ef75", - "reference": "f6947cb939d8efee137797382cb4db1af653ef75", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/060038863743fd0cd982be06acecccf246d35653", + "reference": "060038863743fd0cd982be06acecccf246d35653", "shasum": "" }, "require": { @@ -6063,7 +6064,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/v6.4.5" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.6" }, "funding": [ { @@ -6079,20 +6080,20 @@ "type": "tidelift" } ], - "time": "2024-03-04T21:00:47+00:00" + "time": "2024-04-03T06:09:15+00:00" }, { "name": "symfony/mailer", - "version": "v6.4.4", + "version": "v6.4.6", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "791c5d31a8204cf3db0c66faab70282307f4376b" + "reference": "677f34a6f4b4559e08acf73ae0aec460479e5859" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/791c5d31a8204cf3db0c66faab70282307f4376b", - "reference": "791c5d31a8204cf3db0c66faab70282307f4376b", + "url": "https://api.github.com/repos/symfony/mailer/zipball/677f34a6f4b4559e08acf73ae0aec460479e5859", + "reference": "677f34a6f4b4559e08acf73ae0aec460479e5859", "shasum": "" }, "require": { @@ -6143,7 +6144,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.4" + "source": "https://github.com/symfony/mailer/tree/v6.4.6" }, "funding": [ { @@ -6159,20 +6160,20 @@ "type": "tidelift" } ], - "time": "2024-02-03T21:33:47+00:00" + "time": "2024-03-27T21:14:17+00:00" }, { "name": "symfony/mime", - "version": "v6.4.3", + "version": "v6.4.6", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "5017e0a9398c77090b7694be46f20eb796262a34" + "reference": "14762b86918823cb42e3558cdcca62e58b5227fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/5017e0a9398c77090b7694be46f20eb796262a34", - "reference": "5017e0a9398c77090b7694be46f20eb796262a34", + "url": "https://api.github.com/repos/symfony/mime/zipball/14762b86918823cb42e3558cdcca62e58b5227fe", + "reference": "14762b86918823cb42e3558cdcca62e58b5227fe", "shasum": "" }, "require": { @@ -6193,6 +6194,7 @@ "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.4|^7.0", "symfony/property-access": "^5.4|^6.0|^7.0", "symfony/property-info": "^5.4|^6.0|^7.0", "symfony/serializer": "^6.3.2|^7.0" @@ -6227,7 +6229,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.4.3" + "source": "https://github.com/symfony/mime/tree/v6.4.6" }, "funding": [ { @@ -6243,7 +6245,7 @@ "type": "tidelift" } ], - "time": "2024-01-30T08:32:12+00:00" + "time": "2024-03-21T19:36:20+00:00" }, { "name": "symfony/polyfill-ctype", @@ -7099,16 +7101,16 @@ }, { "name": "symfony/routing", - "version": "v6.4.5", + "version": "v6.4.6", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "7fe30068e207d9c31c0138501ab40358eb2d49a4" + "reference": "f2591fd1f8c6e3734656b5d6b3829e8bf81f507c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/7fe30068e207d9c31c0138501ab40358eb2d49a4", - "reference": "7fe30068e207d9c31c0138501ab40358eb2d49a4", + "url": "https://api.github.com/repos/symfony/routing/zipball/f2591fd1f8c6e3734656b5d6b3829e8bf81f507c", + "reference": "f2591fd1f8c6e3734656b5d6b3829e8bf81f507c", "shasum": "" }, "require": { @@ -7162,7 +7164,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.5" + "source": "https://github.com/symfony/routing/tree/v6.4.6" }, "funding": [ { @@ -7178,20 +7180,20 @@ "type": "tidelift" } ], - "time": "2024-02-27T12:33:30+00:00" + "time": "2024-03-28T13:28:49+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.4.1", + "version": "v3.4.2", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + "reference": "11bbf19a0fb7b36345861e85c5768844c552906e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/11bbf19a0fb7b36345861e85c5768844c552906e", + "reference": "11bbf19a0fb7b36345861e85c5768844c552906e", "shasum": "" }, "require": { @@ -7244,7 +7246,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.4.2" }, "funding": [ { @@ -7260,7 +7262,7 @@ "type": "tidelift" } ], - "time": "2023-12-26T14:02:43+00:00" + "time": "2023-12-19T21:51:00+00:00" }, { "name": "symfony/string", @@ -7445,16 +7447,16 @@ }, { "name": "symfony/translation-contracts", - "version": "v3.4.1", + "version": "v3.4.2", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "06450585bf65e978026bda220cdebca3f867fde7" + "reference": "43810bdb2ddb5400e5c5e778e27b210a0ca83b6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/06450585bf65e978026bda220cdebca3f867fde7", - "reference": "06450585bf65e978026bda220cdebca3f867fde7", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/43810bdb2ddb5400e5c5e778e27b210a0ca83b6b", + "reference": "43810bdb2ddb5400e5c5e778e27b210a0ca83b6b", "shasum": "" }, "require": { @@ -7503,7 +7505,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.4.1" + "source": "https://github.com/symfony/translation-contracts/tree/v3.4.2" }, "funding": [ { @@ -7519,7 +7521,7 @@ "type": "tidelift" } ], - "time": "2023-12-26T14:02:43+00:00" + "time": "2024-01-23T14:51:35+00:00" }, { "name": "symfony/uid", @@ -7597,16 +7599,16 @@ }, { "name": "symfony/var-dumper", - "version": "v6.4.4", + "version": "v6.4.6", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "b439823f04c98b84d4366c79507e9da6230944b1" + "reference": "95bd2706a97fb875185b51ecaa6112ec184233d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b439823f04c98b84d4366c79507e9da6230944b1", - "reference": "b439823f04c98b84d4366c79507e9da6230944b1", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/95bd2706a97fb875185b51ecaa6112ec184233d4", + "reference": "95bd2706a97fb875185b51ecaa6112ec184233d4", "shasum": "" }, "require": { @@ -7662,7 +7664,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.4" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.6" }, "funding": [ { @@ -7678,7 +7680,7 @@ "type": "tidelift" } ], - "time": "2024-02-15T11:23:52+00:00" + "time": "2024-03-19T11:56:30+00:00" }, { "name": "theodorejb/polycast", @@ -8858,16 +8860,16 @@ }, { "name": "laravel/pint", - "version": "v1.15.0", + "version": "v1.15.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "c52de679b3ac01207016c179d7ce173e4be128c4" + "reference": "5f288b5e79938cc72f5c298d384e639de87507c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/c52de679b3ac01207016c179d7ce173e4be128c4", - "reference": "c52de679b3ac01207016c179d7ce173e4be128c4", + "url": "https://api.github.com/repos/laravel/pint/zipball/5f288b5e79938cc72f5c298d384e639de87507c6", + "reference": "5f288b5e79938cc72f5c298d384e639de87507c6", "shasum": "" }, "require": { @@ -8878,13 +8880,13 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.49.0", - "illuminate/view": "^10.43.0", - "larastan/larastan": "^2.8.1", + "friendsofphp/php-cs-fixer": "^3.52.1", + "illuminate/view": "^10.48.4", + "larastan/larastan": "^2.9.2", "laravel-zero/framework": "^10.3.0", - "mockery/mockery": "^1.6.7", + "mockery/mockery": "^1.6.11", "nunomaduro/termwind": "^1.15.1", - "pestphp/pest": "^2.33.6" + "pestphp/pest": "^2.34.5" }, "bin": [ "builds/pint" @@ -8920,7 +8922,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-03-26T16:40:24+00:00" + "time": "2024-04-02T14:28:47+00:00" }, { "name": "laravel/sail", @@ -10053,16 +10055,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.27.0", + "version": "1.28.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "86e4d5a4b036f8f0be1464522f4c6b584c452757" + "reference": "cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/86e4d5a4b036f8f0be1464522f4c6b584c452757", - "reference": "86e4d5a4b036f8f0be1464522f4c6b584c452757", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb", + "reference": "cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb", "shasum": "" }, "require": { @@ -10094,22 +10096,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.27.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.28.0" }, - "time": "2024-03-21T13:14:53+00:00" + "time": "2024-04-03T18:51:33+00:00" }, { "name": "phpstan/phpstan", - "version": "1.10.65", + "version": "1.10.66", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "3c657d057a0b7ecae19cb12db446bbc99d8839c6" + "reference": "94779c987e4ebd620025d9e5fdd23323903950bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3c657d057a0b7ecae19cb12db446bbc99d8839c6", - "reference": "3c657d057a0b7ecae19cb12db446bbc99d8839c6", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/94779c987e4ebd620025d9e5fdd23323903950bd", + "reference": "94779c987e4ebd620025d9e5fdd23323903950bd", "shasum": "" }, "require": { @@ -10158,7 +10160,7 @@ "type": "tidelift" } ], - "time": "2024-03-23T10:30:26+00:00" + "time": "2024-03-28T16:17:31+00:00" }, { "name": "phpunit/php-code-coverage", @@ -10582,6 +10584,68 @@ ], "time": "2024-01-22T14:35:40+00:00" }, + { + "name": "ryoluo/sail-ssl", + "version": "v1.3.2", + "source": { + "type": "git", + "url": "https://github.com/ryoluo/sail-ssl.git", + "reference": "afc8cbdbc27a41bbb32a835df02e38a9f937f2bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ryoluo/sail-ssl/zipball/afc8cbdbc27a41bbb32a835df02e38a9f937f2bc", + "reference": "afc8cbdbc27a41bbb32a835df02e38a9f937f2bc", + "shasum": "" + }, + "require": { + "illuminate/console": "^8.0|^9.0|^10.0|^11.0", + "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0", + "illuminate/support": "^8.0|^9.0|^10.0|^11.0", + "php": "^7.3|^8.0|^8.1|^8.2|^8.3" + }, + "require-dev": { + "laravel/sail": "^1.14", + "orchestra/testbench": "^6.0|^7.0|^8.0|^9.0", + "phpunit/phpunit": "^9.5|^10.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Ryoluo\\SailSsl\\SailSslServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Ryoluo\\SailSsl\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ryo Kobayashi", + "email": "ryoluo@lotus-base.com" + } + ], + "description": "Laravel Sail plugin to enable SSL (HTTPS) connection with Nginx.", + "keywords": [ + "docker", + "laravel", + "nginx", + "sail", + "ssl" + ], + "support": { + "issues": "https://github.com/ryoluo/sail-ssl/issues", + "source": "https://github.com/ryoluo/sail-ssl" + }, + "time": "2024-03-15T18:32:51+00:00" + }, { "name": "sebastian/cli-parser", "version": "2.0.1", @@ -11631,16 +11695,16 @@ }, { "name": "spatie/ignition", - "version": "1.12.0", + "version": "1.13.1", "source": { "type": "git", "url": "https://github.com/spatie/ignition.git", - "reference": "5b6f801c605a593106b623e45ca41496a6e7d56d" + "reference": "889bf1dfa59e161590f677728b47bf4a6893983b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/ignition/zipball/5b6f801c605a593106b623e45ca41496a6e7d56d", - "reference": "5b6f801c605a593106b623e45ca41496a6e7d56d", + "url": "https://api.github.com/repos/spatie/ignition/zipball/889bf1dfa59e161590f677728b47bf4a6893983b", + "reference": "889bf1dfa59e161590f677728b47bf4a6893983b", "shasum": "" }, "require": { @@ -11710,20 +11774,20 @@ "type": "github" } ], - "time": "2024-01-03T15:49:39+00:00" + "time": "2024-03-29T14:03:47+00:00" }, { "name": "spatie/laravel-ignition", - "version": "2.4.2", + "version": "2.5.1", "source": { "type": "git", "url": "https://github.com/spatie/laravel-ignition.git", - "reference": "351504f4570e32908839fc5a2dc53bf77d02f85e" + "reference": "0c864b3cbd66ce67a2096c5f743e07ce8f1d6ab9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/351504f4570e32908839fc5a2dc53bf77d02f85e", - "reference": "351504f4570e32908839fc5a2dc53bf77d02f85e", + "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/0c864b3cbd66ce67a2096c5f743e07ce8f1d6ab9", + "reference": "0c864b3cbd66ce67a2096c5f743e07ce8f1d6ab9", "shasum": "" }, "require": { @@ -11733,7 +11797,7 @@ "illuminate/support": "^10.0|^11.0", "php": "^8.1", "spatie/flare-client-php": "^1.3.5", - "spatie/ignition": "^1.9", + "spatie/ignition": "^1.13", "symfony/console": "^6.2.3|^7.0", "symfony/var-dumper": "^6.2.3|^7.0" }, @@ -11802,7 +11866,7 @@ "type": "github" } ], - "time": "2024-02-09T16:08:40+00:00" + "time": "2024-04-02T06:30:22+00:00" }, { "name": "symfony/yaml", diff --git a/docker-compose.yml b/docker-compose.yml index 23e5942123..281e1a8208 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,24 @@ version: '3' services: + nginx: + image: 'nginx:latest' + ports: + - '${HTTP_PORT:-8000}:80' + - '${SSL_PORT:-443}:443' + environment: + - SSL_PORT=${SSL_PORT:-443} + - APP_SERVICE=${APP_SERVICE:-laravel.test} + - SERVER_NAME=${SERVER_NAME:-localhost} + - SSL_DOMAIN=${SSL_DOMAIN:-localhost} + - SSL_ALT_NAME=${SSL_ALT_NAME:-DNS:localhost} + volumes: + - 'sail-nginx:/etc/nginx/certs' + - './vendor/ryoluo/sail-ssl/nginx/templates:/etc/nginx/templates' + - './vendor/ryoluo/sail-ssl/nginx/generate-ssl-cert.sh:/docker-entrypoint.d/99-generate-ssl-cert.sh' + depends_on: + - ${APP_SERVICE:-laravel.test} + networks: + - sail laravel.test: build: context: ./vendor/laravel/sail/runtimes/8.3 @@ -75,6 +94,8 @@ networks: sail: driver: bridge volumes: + sail-nginx: + driver: local sail-mysql: driver: local sail-redis: diff --git a/public/vendor/livewire/livewire.js b/public/vendor/livewire/livewire.js index 3d80e5c09e..f237ace4bc 100644 --- a/public/vendor/livewire/livewire.js +++ b/public/vendor/livewire/livewire.js @@ -312,14 +312,18 @@ return this.get(key).forEach(callback); } }; - function dispatch(el, name, detail = {}, bubbles = true) { - el.dispatchEvent(new CustomEvent(name, { + function dispatch(target, name, detail = {}, bubbles = true) { + target.dispatchEvent(new CustomEvent(name, { detail, bubbles, composed: true, cancelable: true })); } + function listen(target, name, handler4) { + target.addEventListener(name, handler4); + return () => target.removeEventListener(name, handler4); + } function isObjecty(subject) { return typeof subject === "object" && subject !== null; } @@ -465,6 +469,13 @@ } }; el.addEventListener("change", eventHandler); + component.$wire.$watch(property, (value) => { + if (!el.isConnected) + return; + if (value === null || value === "") { + el.value = ""; + } + }); let clearFileInputValue = () => { el.value = null; }; @@ -2014,7 +2025,6 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); "checked", "required", "readonly", - "hidden", "open", "selected", "autofocus", @@ -2222,7 +2232,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); get raw() { return raw; }, - version: "3.13.7", + version: "3.13.8", flushAndStopDeferringMutations, dontAutoEvaluateFunctions, disableEffectScheduling, @@ -3295,7 +3305,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); }); if (modifiers.includes("fill")) { if ([void 0, null, ""].includes(getValue()) || el.type === "checkbox" && Array.isArray(getValue())) { - el.dispatchEvent(new Event(event, {})); + setValue(getInputValue(el, modifiers, { target: el }, getValue())); } } if (!el._x_removeModelListeners) @@ -3364,12 +3374,25 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); return option.value || option.text; }); } else { + let newValue; + if (el.type === "radio") { + if (event.target.checked) { + newValue = event.target.value; + } else { + newValue = currentValue; + } + } else { + newValue = event.target.value; + } if (modifiers.includes("number")) { - return safeParseNumber(event.target.value); + return safeParseNumber(newValue); } else if (modifiers.includes("boolean")) { - return safeParseBoolean(event.target.value); + return safeParseBoolean(newValue); + } else if (modifiers.includes("trim")) { + return newValue.trim(); + } else { + return newValue; } - return modifiers.includes("trim") ? event.target.value.trim() : event.target.value; } }); } @@ -3418,7 +3441,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); }); }); mapAttributes(startingWith(":", into(prefix("bind:")))); - var handler2 = (el, { value, modifiers, expression, original }, { effect: effect3 }) => { + var handler2 = (el, { value, modifiers, expression, original }, { effect: effect3, cleanup: cleanup22 }) => { if (!value) { let bindingProviders = {}; injectBindingProviders(bindingProviders); @@ -3440,6 +3463,10 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } mutateDom(() => bind(el, value, result, modifiers)); })); + cleanup22(() => { + el._x_undoAddedClasses && el._x_undoAddedClasses(); + el._x_undoAddedStyles && el._x_undoAddedStyles(); + }); }; handler2.inline = (el, { value, modifiers, expression }) => { if (!value) @@ -4349,25 +4376,15 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); return component.$wire.set(name, !component.$wire.get(name), live); }); wireProperty("$watch", (component) => (path, callback) => { - let firstTime = true; - let oldValue = void 0; - module_default.effect(() => { - let value = dataGet(component.reactive, path); - JSON.stringify(value); - if (!firstTime) { - queueMicrotask(() => { - callback(value, oldValue); - oldValue = value; - }); - } else { - oldValue = value; - } - firstTime = false; - }); + let getter = () => { + return dataGet(component.reactive, path); + }; + let unwatch = module_default.watch(getter, callback); + component.addCleanup(unwatch); }); wireProperty("$refresh", (component) => component.$wire.$commit); wireProperty("$commit", (component) => async () => await requestCommit(component)); - wireProperty("$on", (component) => (...params) => listen(component, ...params)); + wireProperty("$on", (component) => (...params) => listen2(component, ...params)); wireProperty("$dispatch", (component) => (...params) => dispatch3(component, ...params)); wireProperty("$dispatchSelf", (component) => (...params) => dispatchSelf(component, ...params)); wireProperty("$dispatchTo", () => (...params) => dispatchTo(...params)); @@ -4574,7 +4591,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); dispatchEvent(target.el, name, params, false); }); } - function listen(component, name, callback) { + function listen2(component, name, callback) { component.el.addEventListener(name, (e) => { callback(e.detail); }); @@ -5770,7 +5787,10 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); return storage.getItem(key) !== null; } function storageGet(key, storage) { - return JSON.parse(storage.getItem(key, storage)); + let value = storage.getItem(key, storage); + if (value === void 0) + return; + return JSON.parse(value); } function storageSet(key, value, storage) { storage.setItem(key, JSON.stringify(value)); @@ -7067,18 +7087,72 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); var module_default6 = src_default6; // js/plugins/navigate/history.js + var Snapshot = class { + constructor(url, html) { + this.url = url; + this.html = html; + } + }; + var snapshotCache = { + currentKey: null, + currentUrl: null, + keys: [], + lookup: {}, + limit: 10, + has(location) { + return this.lookup[location] !== void 0; + }, + retrieve(location) { + let snapshot = this.lookup[location]; + if (snapshot === void 0) + throw "No back button cache found for current location: " + location; + return snapshot; + }, + replace(key, snapshot) { + if (this.has(key)) { + this.lookup[key] = snapshot; + } else { + this.push(key, snapshot); + } + }, + push(key, snapshot) { + this.lookup[key] = snapshot; + let index = this.keys.indexOf(key); + if (index > -1) + this.keys.splice(index, 1); + this.keys.unshift(key); + this.trim(); + }, + trim() { + for (let key of this.keys.splice(this.limit)) { + delete this.lookup[key]; + } + } + }; function updateCurrentPageHtmlInHistoryStateForLaterBackButtonClicks() { let url = new URL(window.location.href, document.baseURI); replaceUrl(url, document.documentElement.outerHTML); } - function whenTheBackOrForwardButtonIsClicked(callback) { + function updateCurrentPageHtmlInSnapshotCacheForLaterBackButtonClicks(key, url) { + let html = document.documentElement.outerHTML; + snapshotCache.replace(key, new Snapshot(url, html)); + } + function whenTheBackOrForwardButtonIsClicked(registerFallback, handleHtml) { + let fallback2; + registerFallback((i) => fallback2 = i); window.addEventListener("popstate", (e) => { let state = e.state || {}; let alpine = state.alpine || {}; - if (!alpine._html) + if (Object.keys(state).length === 0) return; - let html = fromSessionStorage(alpine._html); - callback(html); + if (!alpine.snapshotIdx) + return; + if (snapshotCache.has(alpine.snapshotIdx)) { + let snapshot = snapshotCache.retrieve(alpine.snapshotIdx); + handleHtml(snapshot.html, snapshot.url, snapshotCache.currentUrl, snapshotCache.currentKey); + } else { + fallback2(alpine.url); + } }); } function updateUrlAndStoreLatestHtmlForFutureBackButtons(html, destination) { @@ -7091,14 +7165,17 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); updateUrl("replaceState", url, html); } function updateUrl(method, url, html) { - let key = new Date().getTime(); - tryToStoreInSession(key, html); + let key = url.toString() + "-" + Math.random(); + method === "pushState" ? snapshotCache.push(key, new Snapshot(url, html)) : snapshotCache.replace(key = snapshotCache.currentKey ?? key, new Snapshot(url, html)); let state = history.state || {}; if (!state.alpine) state.alpine = {}; - state.alpine._html = key; + state.alpine.snapshotIdx = key; + state.alpine.url = url.toString(); try { - history[method](state, document.title, url); + history[method](state, JSON.stringify(document.title), url); + snapshotCache.currentKey = key; + snapshotCache.currentUrl = url; } catch (error2) { if (error2 instanceof DOMException && error2.name === "SecurityError") { console.error("Livewire: You can't use wire:navigate with a link to a different root domain: " + url); @@ -7106,23 +7183,6 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); console.error(error2); } } - function fromSessionStorage(timestamp) { - let state = JSON.parse(sessionStorage.getItem("alpine:" + timestamp)); - return state; - } - function tryToStoreInSession(timestamp, value) { - try { - sessionStorage.setItem("alpine:" + timestamp, JSON.stringify(value)); - } catch (error2) { - if (![22, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14].includes(error2.code)) - return; - let oldestTimestamp = Object.keys(sessionStorage).map((key) => Number(key.replace("alpine:", ""))).sort().shift(); - if (!oldestTimestamp) - return; - sessionStorage.removeItem("alpine:" + oldestTimestamp); - tryToStoreInSession(timestamp, value); - } - } // js/plugins/navigate/links.js function whenThisLinkIsPressed(el, callback) { @@ -7177,10 +7237,13 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); function createUrlObjectFromString(urlString) { return new URL(urlString, document.baseURI); } + function getUriStringFromUrlObject(urlObject) { + return urlObject.pathname + urlObject.search + urlObject.hash; + } // js/plugins/navigate/fetch.js function fetchHtml(destination, callback) { - let uri = destination.pathname + destination.search; + let uri = getUriStringFromUrlObject(destination); performFetch(uri, (html, finalDestination) => { callback(html, finalDestination); }); @@ -7197,7 +7260,11 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); }); let finalDestination; fetch(uri, options).then((response) => { + let destination = createUrlObjectFromString(uri); finalDestination = createUrlObjectFromString(response.url); + if (destination.pathname + destination.search === finalDestination.pathname + finalDestination.search) { + finalDestination.hash = destination.hash; + } return response.text(); }).then((html) => { callback(html, finalDestination); @@ -7207,24 +7274,24 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); // js/plugins/navigate/prefetch.js var prefetches = {}; function prefetchHtml(destination, callback) { - let path = destination.pathname; - if (prefetches[path]) + let uri = getUriStringFromUrlObject(destination); + if (prefetches[uri]) return; - prefetches[path] = { finished: false, html: null, whenFinished: () => { + prefetches[uri] = { finished: false, html: null, whenFinished: () => { } }; - performFetch(path, (html, routedUri) => { + performFetch(uri, (html, routedUri) => { callback(html, routedUri); }); } function storeThePrefetchedHtmlForWhenALinkIsClicked(html, destination, finalDestination) { - let state = prefetches[destination.pathname]; + let state = prefetches[getUriStringFromUrlObject(destination)]; state.html = html; state.finished = true; state.finalDestination = finalDestination; state.whenFinished(); } function getPretchedHtmlOr(destination, receive, ifNoPrefetchExists) { - let uri = destination.pathname + destination.search; + let uri = getUriStringFromUrlObject(destination); if (!prefetches[uri]) return ifNoPrefetchExists(); if (prefetches[uri].finished) { @@ -7573,7 +7640,15 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); var autofocus = false; function navigate_default(Alpine3) { Alpine3.navigate = (url) => { - navigateTo(createUrlObjectFromString(url)); + let destination = createUrlObjectFromString(url); + let prevented = fireEventForOtherLibariesToHookInto("alpine:navigate", { + url: destination, + history: false, + cached: false + }); + if (prevented) + return; + navigateTo(destination); }; Alpine3.navigate.disableProgressBar = () => { showProgressBar = false; @@ -7593,11 +7668,18 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); storeThePrefetchedHtmlForWhenALinkIsClicked(html, destination, finalDestination); }); whenItIsReleased(() => { + let prevented = fireEventForOtherLibariesToHookInto("alpine:navigate", { + url: destination, + history: false, + cached: false + }); + if (prevented) + return; navigateTo(destination); }); }); }); - function navigateTo(destination) { + function navigateTo(destination, shouldPushToHistoryState = true) { showProgressBar && showAndStartProgressBar(); fetchHtmlOrUsePrefetchedHtml(destination, (html, finalDestination) => { fireEventForOtherLibariesToHookInto("alpine:navigating"); @@ -7609,28 +7691,55 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); enablePersist && storePersistantElementsForLater((persistedEl) => { packUpPersistedTeleports(persistedEl); }); + if (shouldPushToHistoryState) { + updateUrlAndStoreLatestHtmlForFutureBackButtons(html, finalDestination); + } else { + replaceUrl(finalDestination, html); + } swapCurrentPageWithNewHtml(html, (afterNewScriptsAreDoneLoading) => { removeAnyLeftOverStaleTeleportTargets(document.body); enablePersist && putPersistantElementsBack((persistedEl, newStub) => { unPackPersistedTeleports(persistedEl); }); restoreScrollPositionOrScrollToTop(); - updateUrlAndStoreLatestHtmlForFutureBackButtons(html, finalDestination); - fireEventForOtherLibariesToHookInto("alpine:navigated"); afterNewScriptsAreDoneLoading(() => { andAfterAllThis(() => { setTimeout(() => { autofocus && autofocusElementsWithTheAutofocusAttribute(); }); nowInitializeAlpineOnTheNewPage(Alpine3); + fireEventForOtherLibariesToHookInto("alpine:navigated"); }); }); }); }); }); } - whenTheBackOrForwardButtonIsClicked((html) => { + whenTheBackOrForwardButtonIsClicked((ifThePageBeingVisitedHasntBeenCached) => { + ifThePageBeingVisitedHasntBeenCached((url) => { + let destination = createUrlObjectFromString(url); + let prevented = fireEventForOtherLibariesToHookInto("alpine:navigate", { + url: destination, + history: true, + cached: false + }); + if (prevented) + return; + let shouldPushToHistoryState = false; + navigateTo(destination, shouldPushToHistoryState); + }); + }, (html, url, currentPageUrl, currentPageKey) => { + let destination = createUrlObjectFromString(url); + let prevented = fireEventForOtherLibariesToHookInto("alpine:navigate", { + url: destination, + history: true, + cached: true + }); + if (prevented) + return; storeScrollInformationInHtmlBeforeNavigatingAway(); + fireEventForOtherLibariesToHookInto("alpine:navigating"); + updateCurrentPageHtmlInSnapshotCacheForLaterBackButtonClicks(currentPageUrl, currentPageKey); preventAlpineFromPickingUpDomChanges(Alpine3, (andAfterAllThis) => { enablePersist && storePersistantElementsForLater((persistedEl) => { packUpPersistedTeleports(persistedEl); @@ -7641,10 +7750,10 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); unPackPersistedTeleports(persistedEl); }); restoreScrollPositionOrScrollToTop(); - fireEventForOtherLibariesToHookInto("alpine:navigated"); andAfterAllThis(() => { autofocus && autofocusElementsWithTheAutofocusAttribute(); nowInitializeAlpineOnTheNewPage(Alpine3); + fireEventForOtherLibariesToHookInto("alpine:navigated"); }); }); }); @@ -7667,8 +7776,14 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); }); }); } - function fireEventForOtherLibariesToHookInto(eventName) { - document.dispatchEvent(new CustomEvent(eventName, { bubbles: true })); + function fireEventForOtherLibariesToHookInto(name, detail) { + let event = new CustomEvent(name, { + cancelable: true, + bubbles: true, + detail + }); + document.dispatchEvent(event); + return event.defaultPrevented; } function nowInitializeAlpineOnTheNewPage(Alpine3) { Alpine3.initTree(document.body, void 0, (el, skip) => { @@ -7878,6 +7993,8 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); let entries = search.split("&").map((i) => i.split("=")); let data2 = /* @__PURE__ */ Object.create(null); entries.forEach(([key, value]) => { + if (typeof value == "undefined") + return; value = decodeURIComponent(value.replaceAll("+", "%20")); if (!key.includes("[")) { data2[key] = value; @@ -8454,110 +8571,29 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } } - // js/features/supportDisablingFormsDuringRequest.js - var cleanupStackByComponentId = {}; - on2("element.init", ({ el, component }) => setTimeout(() => { - let directives2 = getDirectives(el); - if (directives2.missing("submit")) - return; - el.addEventListener("submit", () => { - cleanupStackByComponentId[component.id] = []; - module_default.walk(component.el, (node, skip) => { - if (!el.contains(node)) - return; - if (node.hasAttribute("wire:ignore")) - return skip(); - if (node.tagName.toLowerCase() === "button" && node.type === "submit" || node.tagName.toLowerCase() === "select" || node.tagName.toLowerCase() === "input" && (node.type === "checkbox" || node.type === "radio")) { - if (!node.disabled) - cleanupStackByComponentId[component.id].push(() => node.disabled = false); - node.disabled = true; - } else if (node.tagName.toLowerCase() === "input" || node.tagName.toLowerCase() === "textarea") { - if (!node.readOnly) - cleanupStackByComponentId[component.id].push(() => node.readOnly = false); - node.readOnly = true; - } - }); - }); - })); - on2("commit", ({ component, respond }) => { - respond(() => { - cleanup2(component); - }); - }); - function cleanup2(component) { - if (!cleanupStackByComponentId[component.id]) - return; - while (cleanupStackByComponentId[component.id].length > 0) { - cleanupStackByComponentId[component.id].shift()(); - } - } - - // js/features/supportPropsAndModelables.js - on2("commit.pooling", ({ commits }) => { - commits.forEach((commit) => { - let component = commit.component; - getDeepChildrenWithBindings(component, (child) => { - child.$wire.$commit(); - }); - }); - }); - on2("commit.pooled", ({ pools }) => { - let commits = getPooledCommits(pools); - commits.forEach((commit) => { - let component = commit.component; - getDeepChildrenWithBindings(component, (child) => { - colocateCommitsByComponent(pools, component, child); - }); - }); + // js/features/supportListeners.js + on2("effect", ({ component, effects }) => { + registerListeners(component, effects.listeners || []); }); - function getPooledCommits(pools) { - let commits = []; - pools.forEach((pool) => { - pool.commits.forEach((commit) => { - commits.push(commit); + function registerListeners(component, listeners2) { + listeners2.forEach((name) => { + let handler4 = (e) => { + if (e.__livewire) + e.__livewire.receivedBy.push(component); + component.$wire.call("__dispatch", name, e.detail || {}); + }; + window.addEventListener(name, handler4); + component.addCleanup(() => window.removeEventListener(name, handler4)); + component.el.addEventListener(name, (e) => { + if (!e.__livewire) + return; + if (e.bubbles) + return; + if (e.__livewire) + e.__livewire.receivedBy.push(component.id); + component.$wire.call("__dispatch", name, e.detail || {}); }); }); - return commits; - } - function colocateCommitsByComponent(pools, component, foreignComponent) { - let pool = findPoolWithComponent(pools, component); - let foreignPool = findPoolWithComponent(pools, foreignComponent); - let foreignCommit = foreignPool.findCommitByComponent(foreignComponent); - foreignPool.delete(foreignCommit); - pool.add(foreignCommit); - pools.forEach((pool2) => { - if (pool2.empty()) - pools.delete(pool2); - }); - } - function findPoolWithComponent(pools, component) { - for (let [idx, pool] of pools.entries()) { - if (pool.hasCommitFor(component)) - return pool; - } - } - function getDeepChildrenWithBindings(component, callback) { - getDeepChildren(component, (child) => { - if (hasReactiveProps(child) || hasWireModelableBindings(child)) { - callback(child); - } - }); - } - function hasReactiveProps(component) { - let meta = component.snapshot.memo; - let props = meta.props; - return !!props; - } - function hasWireModelableBindings(component) { - let meta = component.snapshot.memo; - let bindings = meta.bindings; - return !!bindings; - } - function getDeepChildren(component, callback) { - component.children.forEach((child) => { - callback(child); - getDeepChildren(child, callback); - }); } // js/features/supportScriptsAndAssets.js @@ -8660,42 +8696,6 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); return script; } - // js/features/supportFileDownloads.js - on2("commit", ({ succeed }) => { - succeed(({ effects }) => { - let download = effects.download; - if (!download) - return; - let urlObject = window.webkitURL || window.URL; - let url = urlObject.createObjectURL(base64toBlob(download.content, download.contentType)); - let invisibleLink = document.createElement("a"); - invisibleLink.style.display = "none"; - invisibleLink.href = url; - invisibleLink.download = download.name; - document.body.appendChild(invisibleLink); - invisibleLink.click(); - setTimeout(function() { - urlObject.revokeObjectURL(url); - }, 0); - }); - }); - function base64toBlob(b64Data, contentType = "", sliceSize = 512) { - const byteCharacters = atob(b64Data); - const byteArrays = []; - if (contentType === null) - contentType = ""; - for (let offset2 = 0; offset2 < byteCharacters.length; offset2 += sliceSize) { - let slice = byteCharacters.slice(offset2, offset2 + sliceSize); - let byteNumbers = new Array(slice.length); - for (let i = 0; i < slice.length; i++) { - byteNumbers[i] = slice.charCodeAt(i); - } - let byteArray = new Uint8Array(byteNumbers); - byteArrays.push(byteArray); - } - return new Blob(byteArrays, { type: contentType }); - } - // js/features/supportJsEvaluation.js on2("effect", ({ component, effects }) => { let js = effects.js; @@ -8714,28 +8714,264 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } }); - // js/features/supportLazyLoading.js - var componentsThatWantToBeBundled = /* @__PURE__ */ new WeakSet(); - var componentsThatAreLazy = /* @__PURE__ */ new WeakSet(); - on2("component.init", ({ component }) => { - let memo = component.snapshot.memo; - if (memo.lazyLoaded === void 0) - return; - componentsThatAreLazy.add(component); - if (memo.lazyIsolated !== void 0 && memo.lazyIsolated === false) { - componentsThatWantToBeBundled.add(component); + // js/morph.js + function morph2(component, el, html) { + let wrapperTag = el.parentElement ? el.parentElement.tagName.toLowerCase() : "div"; + let wrapper = document.createElement(wrapperTag); + wrapper.innerHTML = html; + let parentComponent; + try { + parentComponent = closestComponent(el.parentElement); + } catch (e) { } - }); - on2("commit.pooling", ({ commits }) => { - commits.forEach((commit) => { - if (!componentsThatAreLazy.has(commit.component)) - return; - if (componentsThatWantToBeBundled.has(commit.component)) { - commit.isolate = false; - componentsThatWantToBeBundled.delete(commit.component); - } else { - commit.isolate = true; - } + parentComponent && (wrapper.__livewire = parentComponent); + let to = wrapper.firstElementChild; + to.__livewire = component; + trigger2("morph", { el, toEl: to, component }); + module_default.morph(el, to, { + updating: (el2, toEl, childrenOnly, skip) => { + if (isntElement(el2)) + return; + trigger2("morph.updating", { el: el2, toEl, component, skip, childrenOnly }); + if (el2.__livewire_ignore === true) + return skip(); + if (el2.__livewire_ignore_self === true) + childrenOnly(); + if (isComponentRootEl(el2) && el2.getAttribute("wire:id") !== component.id) + return skip(); + if (isComponentRootEl(el2)) + toEl.__livewire = component; + }, + updated: (el2) => { + if (isntElement(el2)) + return; + trigger2("morph.updated", { el: el2, component }); + }, + removing: (el2, skip) => { + if (isntElement(el2)) + return; + trigger2("morph.removing", { el: el2, component, skip }); + }, + removed: (el2) => { + if (isntElement(el2)) + return; + trigger2("morph.removed", { el: el2, component }); + }, + adding: (el2) => { + trigger2("morph.adding", { el: el2, component }); + }, + added: (el2) => { + if (isntElement(el2)) + return; + const closestComponentId = closestComponent(el2).id; + trigger2("morph.added", { el: el2 }); + }, + key: (el2) => { + if (isntElement(el2)) + return; + return el2.hasAttribute(`wire:key`) ? el2.getAttribute(`wire:key`) : el2.hasAttribute(`wire:id`) ? el2.getAttribute(`wire:id`) : el2.id; + }, + lookahead: false + }); + } + function isntElement(el) { + return typeof el.hasAttribute !== "function"; + } + function isComponentRootEl(el) { + return el.hasAttribute("wire:id"); + } + + // js/features/supportMorphDom.js + on2("effect", ({ component, effects }) => { + let html = effects.html; + if (!html) + return; + queueMicrotask(() => { + queueMicrotask(() => { + morph2(component, component.el, html); + }); + }); + }); + + // js/features/supportDispatches.js + on2("effect", ({ component, effects }) => { + dispatchEvents(component, effects.dispatches || []); + }); + function dispatchEvents(component, dispatches) { + dispatches.forEach(({ name, params = {}, self = false, to }) => { + if (self) + dispatchSelf(component, name, params); + else if (to) + dispatchTo(to, name, params); + else + dispatch3(component, name, params); + }); + } + + // js/features/supportDisablingFormsDuringRequest.js + var cleanupStackByComponentId = {}; + on2("element.init", ({ el, component }) => setTimeout(() => { + let directives2 = getDirectives(el); + if (directives2.missing("submit")) + return; + el.addEventListener("submit", () => { + cleanupStackByComponentId[component.id] = []; + module_default.walk(component.el, (node, skip) => { + if (!el.contains(node)) + return; + if (node.hasAttribute("wire:ignore")) + return skip(); + if (node.tagName.toLowerCase() === "button" && node.type === "submit" || node.tagName.toLowerCase() === "select" || node.tagName.toLowerCase() === "input" && (node.type === "checkbox" || node.type === "radio")) { + if (!node.disabled) + cleanupStackByComponentId[component.id].push(() => node.disabled = false); + node.disabled = true; + } else if (node.tagName.toLowerCase() === "input" || node.tagName.toLowerCase() === "textarea") { + if (!node.readOnly) + cleanupStackByComponentId[component.id].push(() => node.readOnly = false); + node.readOnly = true; + } + }); + }); + })); + on2("commit", ({ component, respond }) => { + respond(() => { + cleanup2(component); + }); + }); + function cleanup2(component) { + if (!cleanupStackByComponentId[component.id]) + return; + while (cleanupStackByComponentId[component.id].length > 0) { + cleanupStackByComponentId[component.id].shift()(); + } + } + + // js/features/supportPropsAndModelables.js + on2("commit.pooling", ({ commits }) => { + commits.forEach((commit) => { + let component = commit.component; + getDeepChildrenWithBindings(component, (child) => { + child.$wire.$commit(); + }); + }); + }); + on2("commit.pooled", ({ pools }) => { + let commits = getPooledCommits(pools); + commits.forEach((commit) => { + let component = commit.component; + getDeepChildrenWithBindings(component, (child) => { + colocateCommitsByComponent(pools, component, child); + }); + }); + }); + function getPooledCommits(pools) { + let commits = []; + pools.forEach((pool) => { + pool.commits.forEach((commit) => { + commits.push(commit); + }); + }); + return commits; + } + function colocateCommitsByComponent(pools, component, foreignComponent) { + let pool = findPoolWithComponent(pools, component); + let foreignPool = findPoolWithComponent(pools, foreignComponent); + let foreignCommit = foreignPool.findCommitByComponent(foreignComponent); + foreignPool.delete(foreignCommit); + pool.add(foreignCommit); + pools.forEach((pool2) => { + if (pool2.empty()) + pools.delete(pool2); + }); + } + function findPoolWithComponent(pools, component) { + for (let [idx, pool] of pools.entries()) { + if (pool.hasCommitFor(component)) + return pool; + } + } + function getDeepChildrenWithBindings(component, callback) { + getDeepChildren(component, (child) => { + if (hasReactiveProps(child) || hasWireModelableBindings(child)) { + callback(child); + } + }); + } + function hasReactiveProps(component) { + let meta = component.snapshot.memo; + let props = meta.props; + return !!props; + } + function hasWireModelableBindings(component) { + let meta = component.snapshot.memo; + let bindings = meta.bindings; + return !!bindings; + } + function getDeepChildren(component, callback) { + component.children.forEach((child) => { + callback(child); + getDeepChildren(child, callback); + }); + } + + // js/features/supportFileDownloads.js + on2("commit", ({ succeed }) => { + succeed(({ effects }) => { + let download = effects.download; + if (!download) + return; + let urlObject = window.webkitURL || window.URL; + let url = urlObject.createObjectURL(base64toBlob(download.content, download.contentType)); + let invisibleLink = document.createElement("a"); + invisibleLink.style.display = "none"; + invisibleLink.href = url; + invisibleLink.download = download.name; + document.body.appendChild(invisibleLink); + invisibleLink.click(); + setTimeout(function() { + urlObject.revokeObjectURL(url); + }, 0); + }); + }); + function base64toBlob(b64Data, contentType = "", sliceSize = 512) { + const byteCharacters = atob(b64Data); + const byteArrays = []; + if (contentType === null) + contentType = ""; + for (let offset2 = 0; offset2 < byteCharacters.length; offset2 += sliceSize) { + let slice = byteCharacters.slice(offset2, offset2 + sliceSize); + let byteNumbers = new Array(slice.length); + for (let i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + let byteArray = new Uint8Array(byteNumbers); + byteArrays.push(byteArray); + } + return new Blob(byteArrays, { type: contentType }); + } + + // js/features/supportLazyLoading.js + var componentsThatWantToBeBundled = /* @__PURE__ */ new WeakSet(); + var componentsThatAreLazy = /* @__PURE__ */ new WeakSet(); + on2("component.init", ({ component }) => { + let memo = component.snapshot.memo; + if (memo.lazyLoaded === void 0) + return; + componentsThatAreLazy.add(component); + if (memo.lazyIsolated !== void 0 && memo.lazyIsolated === false) { + componentsThatWantToBeBundled.add(component); + } + }); + on2("commit.pooling", ({ commits }) => { + commits.forEach((commit) => { + if (!componentsThatAreLazy.has(commit.component)) + return; + if (componentsThatWantToBeBundled.has(commit.component)) { + commit.isolate = false; + componentsThatWantToBeBundled.delete(commit.component); + } else { + commit.isolate = true; + } componentsThatAreLazy.delete(commit.component); }); }); @@ -8868,12 +9104,16 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); // js/features/supportNavigate.js shouldHideProgressBar() && Alpine.navigate.disableProgressBar(); - document.addEventListener("alpine:navigated", (e) => { - document.dispatchEvent(new CustomEvent("livewire:navigated", { bubbles: true })); - }); - document.addEventListener("alpine:navigating", (e) => { - document.dispatchEvent(new CustomEvent("livewire:navigating", { bubbles: true })); - }); + document.addEventListener("alpine:navigate", (e) => forwardEvent("livewire:navigate", e)); + document.addEventListener("alpine:navigating", (e) => forwardEvent("livewire:navigating", e)); + document.addEventListener("alpine:navigated", (e) => forwardEvent("livewire:navigated", e)); + function forwardEvent(name, original) { + let event = new CustomEvent(name, { cancelable: true, bubbles: true, detail: original.detail }); + document.dispatchEvent(event); + if (event.defaultPrevented) { + original.preventDefault(); + } + } function shouldRedirectUsingNavigateOr(effects, url, or) { let forceNavigate = effects.redirectUsingNavigate; if (forceNavigate) { @@ -8900,121 +9140,6 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); }); }); - // js/morph.js - function morph2(component, el, html) { - let wrapperTag = el.parentElement ? el.parentElement.tagName.toLowerCase() : "div"; - let wrapper = document.createElement(wrapperTag); - wrapper.innerHTML = html; - let parentComponent; - try { - parentComponent = closestComponent(el.parentElement); - } catch (e) { - } - parentComponent && (wrapper.__livewire = parentComponent); - let to = wrapper.firstElementChild; - to.__livewire = component; - trigger2("morph", { el, toEl: to, component }); - module_default.morph(el, to, { - updating: (el2, toEl, childrenOnly, skip) => { - if (isntElement(el2)) - return; - trigger2("morph.updating", { el: el2, toEl, component, skip, childrenOnly }); - if (el2.__livewire_ignore === true) - return skip(); - if (el2.__livewire_ignore_self === true) - childrenOnly(); - if (isComponentRootEl(el2) && el2.getAttribute("wire:id") !== component.id) - return skip(); - if (isComponentRootEl(el2)) - toEl.__livewire = component; - }, - updated: (el2) => { - if (isntElement(el2)) - return; - trigger2("morph.updated", { el: el2, component }); - }, - removing: (el2, skip) => { - if (isntElement(el2)) - return; - trigger2("morph.removing", { el: el2, component, skip }); - }, - removed: (el2) => { - if (isntElement(el2)) - return; - trigger2("morph.removed", { el: el2, component }); - }, - adding: (el2) => { - trigger2("morph.adding", { el: el2, component }); - }, - added: (el2) => { - if (isntElement(el2)) - return; - const closestComponentId = closestComponent(el2).id; - trigger2("morph.added", { el: el2 }); - }, - key: (el2) => { - if (isntElement(el2)) - return; - return el2.hasAttribute(`wire:key`) ? el2.getAttribute(`wire:key`) : el2.hasAttribute(`wire:id`) ? el2.getAttribute(`wire:id`) : el2.id; - }, - lookahead: false - }); - } - function isntElement(el) { - return typeof el.hasAttribute !== "function"; - } - function isComponentRootEl(el) { - return el.hasAttribute("wire:id"); - } - - // js/features/supportMorphDom.js - on2("effect", ({ component, effects }) => { - let html = effects.html; - if (!html) - return; - queueMicrotask(() => { - queueMicrotask(() => { - morph2(component, component.el, html); - }); - }); - }); - - // js/features/supportEvents.js - on2("effect", ({ component, effects }) => { - registerListeners(component, effects.listeners || []); - dispatchEvents(component, effects.dispatches || []); - }); - function registerListeners(component, listeners2) { - listeners2.forEach((name) => { - let handler4 = (e) => { - if (e.__livewire) - e.__livewire.receivedBy.push(component); - component.$wire.call("__dispatch", name, e.detail || {}); - }; - window.addEventListener(name, handler4); - component.addCleanup(() => window.removeEventListener(name, handler4)); - component.el.addEventListener(name, (e) => { - if (!e.__livewire) - return; - if (e.bubbles) - return; - if (e.__livewire) - e.__livewire.receivedBy.push(component.id); - component.$wire.call("__dispatch", name, e.detail || {}); - }); - }); - } - function dispatchEvents(component, dispatches) { - dispatches.forEach(({ name, params = {}, self = false, to }) => { - if (self) - dispatchSelf(component, name, params); - else if (to) - dispatchTo(to, name, params); - else - dispatch3(component, name, params); - }); - } - // js/directives/wire-transition.js on2("morph.added", ({ el }) => { el.__addedByMorph = true; @@ -9149,7 +9274,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } else { let cache = cachedDisplay ?? window.getComputedStyle(el, null).getPropertyValue("display"); let display = ["inline", "block", "table", "flex", "grid", "inline-flex"].filter((i) => directive3.modifiers.includes(i))[0] || "inline-block"; - display = directive3.modifiers.includes("remove") ? cache : display; + display = directive3.modifiers.includes("remove") && !isTruthy ? cache : display; el.style.display = isTruthy ? display : "none"; } } @@ -9171,17 +9296,21 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); }); // js/directives/wire-loading.js - directive2("loading", ({ el, directive: directive3, component }) => { + directive2("loading", ({ el, directive: directive3, component, cleanup: cleanup3 }) => { let { targets, inverted } = getTargets(el); let [delay3, abortDelay] = applyDelay(directive3); - whenTargetsArePartOfRequest(component, targets, inverted, [ + let cleanupA = whenTargetsArePartOfRequest(component, targets, inverted, [ () => delay3(() => toggleBooleanStateDirective(el, directive3, true)), () => abortDelay(() => toggleBooleanStateDirective(el, directive3, false)) ]); - whenTargetsArePartOfFileUpload(component, targets, [ + let cleanupB = whenTargetsArePartOfFileUpload(component, targets, [ () => delay3(() => toggleBooleanStateDirective(el, directive3, true)), () => abortDelay(() => toggleBooleanStateDirective(el, directive3, false)) ]); + cleanup3(() => { + cleanupA(); + cleanupB(); + }); }); function applyDelay(directive3) { if (!directive3.modifiers.includes("delay") || directive3.modifiers.includes("none")) @@ -9222,7 +9351,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); ]; } function whenTargetsArePartOfRequest(component, targets, inverted, [startLoading, endLoading]) { - on2("commit", ({ component: iComponent, commit: payload, respond }) => { + return on2("commit", ({ component: iComponent, commit: payload, respond }) => { if (iComponent !== component) return; if (targets.length > 0 && containsTargets(payload, targets) === inverted) @@ -9242,21 +9371,26 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); return true; return false; }; - window.addEventListener("livewire-upload-start", (e) => { + let cleanupA = listen(window, "livewire-upload-start", (e) => { if (eventMismatch(e)) return; startLoading(); }); - window.addEventListener("livewire-upload-finish", (e) => { + let cleanupB = listen(window, "livewire-upload-finish", (e) => { if (eventMismatch(e)) return; endLoading(); }); - window.addEventListener("livewire-upload-error", (e) => { + let cleanupC = listen(window, "livewire-upload-error", (e) => { if (eventMismatch(e)) return; endLoading(); }); + return () => { + cleanupA(); + cleanupB(); + cleanupC(); + }; } function containsTargets(payload, targets) { let { updates, calls } = payload; @@ -9629,14 +9763,19 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); return module_default.navigate; } }; + var warnAboutMultipleInstancesOf = (entity) => console.warn(`Detected multiple instances of ${entity} running`); if (window.Livewire) - console.warn("Detected multiple instances of Livewire running"); + warnAboutMultipleInstancesOf("Livewire"); if (window.Alpine) - console.warn("Detected multiple instances of Alpine running"); + warnAboutMultipleInstancesOf("Alpine"); window.Livewire = Livewire2; window.Alpine = module_default; if (window.livewireScriptConfig === void 0) { + window.Alpine.__fromLivewire = true; document.addEventListener("DOMContentLoaded", () => { + if (window.Alpine.__fromLivewire === void 0) { + warnAboutMultipleInstancesOf("Alpine"); + } Livewire2.start(); }); } diff --git a/public/vendor/livewire/manifest.json b/public/vendor/livewire/manifest.json index 154963a2de..c0a72e976b 100644 --- a/public/vendor/livewire/manifest.json +++ b/public/vendor/livewire/manifest.json @@ -1,2 +1,2 @@ -{"/livewire.js":"5d8beb2e"} +{"/livewire.js":"239a5c52"} From 4d5d701069e3613c967dac94738ced3d643b5c73 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Mon, 8 Apr 2024 12:00:44 -0400 Subject: [PATCH 15/61] fix: middleware alias --- routes/web.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/web.php b/routes/web.php index cf9850e5b7..ace40accce 100644 --- a/routes/web.php +++ b/routes/web.php @@ -306,7 +306,7 @@ Route::get('/create', [App\Http\Controllers\TicketController::class, 'create'])->name('create'); Route::post('/', [App\Http\Controllers\TicketController::class, 'store'])->name('store'); Route::get('/{ticket}', [App\Http\Controllers\TicketController::class, 'show'])->name('show'); - Route::delete('/{ticket}', [App\Http\Controllers\TicketController::class, 'destroy'])->name('destroy')->middleware('is_modo'); + Route::delete('/{ticket}', [App\Http\Controllers\TicketController::class, 'destroy'])->name('destroy')->middleware('modo'); Route::post('/{ticket}/note', [App\Http\Controllers\TicketNoteController::class, 'store'])->name('note.store'); Route::delete('/{ticket}/note', [App\Http\Controllers\TicketNoteController::class, 'destroy'])->name('note.destroy'); Route::post('/{ticket}/assignee', [App\Http\Controllers\TicketAssigneeController::class, 'store'])->name('assignee.store'); From 2685606fbe2850abb1c045c3d84b197ffca07af2 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Mon, 8 Apr 2024 18:53:09 -0400 Subject: [PATCH 16/61] add: request #3676 - closes #3676 - replaces top_uploaders block with new top_users block which covers old stats plus more --- app/Http/Controllers/HomeController.php | 134 +++++- resources/sass/pages/_home.scss | 17 + .../views/blocks/top_uploaders.blade.php | 77 ---- resources/views/blocks/top_users.blade.php | 385 ++++++++++++++++++ resources/views/home/index.blade.php | 2 +- 5 files changed, 520 insertions(+), 95 deletions(-) delete mode 100644 resources/views/blocks/top_uploaders.blade.php create mode 100644 resources/views/blocks/top_users.blade.php diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 99ca38f50b..87abf81549 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -15,11 +15,15 @@ use App\Models\Article; use App\Models\Bookmark; +use App\Models\Comment; use App\Models\FeaturedTorrent; use App\Models\FreeleechToken; use App\Models\Group; +use App\Models\History; +use App\Models\Peer; use App\Models\Poll; use App\Models\Post; +use App\Models\Thank; use App\Models\Topic; use App\Models\Torrent; use App\Models\User; @@ -41,7 +45,7 @@ class HomeController extends Controller public function index(Request $request): \Illuminate\Contracts\View\Factory|\Illuminate\View\View { // For Cache - $expiresAt = now()->addMinutes(1); + $expiresAt = now()->addMinutes(5); // Authorized User $user = $request->user(); @@ -65,7 +69,7 @@ public function index(Request $request): \Illuminate\Contracts\View\Factory|\Ill $query->whereNotNull('torrent')->where('active', '1'); }, ]) - ->where('last_action', '>', now()->subMinutes(5)) + ->where('last_action', '>', now()->subMinutes(60)) ->orderByRaw('(select position from `groups` where `groups`.id = users.group_id), group_id, username') ->get() ->sortBy(fn ($user) => $user->hidden || !$user->isVisible($user, 'other', 'show_online')) @@ -119,21 +123,117 @@ public function index(Request $request): \Illuminate\Contracts\View\Factory|\Ill ])->get() ), 'poll' => cache()->remember('latest_poll', $expiresAt, fn () => Poll::latest()->first()), - 'uploaders' => cache()->remember('top_uploaders', $expiresAt, fn () => Torrent::with(['user.group']) - ->select(DB::raw('user_id, count(*) as value')) - ->where('anon', '=', false) - ->groupBy('user_id') - ->latest('value') - ->take(10) - ->get()), - 'past_uploaders' => cache()->remember('month_uploaders', $expiresAt, fn () => Torrent::with(['user.group']) - ->where('created_at', '>', now()->subDays(30)->toDateTimeString()) - ->select(DB::raw('user_id, count(*) as value')) - ->where('anon', '=', false) - ->groupBy('user_id') - ->latest('value') - ->take(10) - ->get()), + 'uploaders' => cache()->remember( + 'top-users:uploaders', + 3_600, + fn () => Torrent::with(['user' , 'user.group']) + ->select(DB::raw('user_id, COUNT(user_id) as value')) + ->where('user_id', '!=', User::SYSTEM_USER_ID) + ->where('anon', '=', false) + ->groupBy('user_id') + ->orderByDesc('value') + ->take(8) + ->get() + ), + 'downloaders' => cache()->remember( + 'top-users:downloaders', + 3_600, + fn () => History::with(['user' , 'user.group']) + ->select(DB::raw('user_id, count(distinct torrent_id) as value')) + ->whereNotNull('completed_at') + ->where('user_id', '!=', User::SYSTEM_USER_ID) + ->groupBy('user_id') + ->orderByDesc('value') + ->take(8) + ->get() + ), + 'uploaded' => cache()->remember( + 'top-users:uploaded', + 3_600, + fn () => User::select(['id', 'group_id', 'username', 'uploaded', 'image', 'private_profile']) + ->where('id', '!=', User::SYSTEM_USER_ID) + ->whereNotIn('group_id', Group::select('id')->whereIn('slug', ['banned', 'validating', 'disabled', 'pruned'])) + ->orderByDesc('uploaded') + ->take(8) + ->get(), + ), + 'downloaded' => cache()->remember( + 'top-users:downloaded', + 3_600, + fn () => User::select(['id', 'group_id', 'username', 'downloaded', 'image', 'private_profile']) + ->where('id', '!=', User::SYSTEM_USER_ID) + ->whereNotIn('group_id', Group::select('id')->whereIn('slug', ['banned', 'validating', 'disabled', 'pruned'])) + ->orderByDesc('downloaded') + ->take(8) + ->get(), + ), + 'seeders' => cache()->remember( + 'top-users:seeders', + 3_600, + fn () => Peer::with(['user' , 'user.group']) + ->select(DB::raw('user_id, count(distinct torrent_id) as value')) + ->where('user_id', '!=', User::SYSTEM_USER_ID) + ->where('seeder', '=', 1) + ->where('active', '=', 1) + ->groupBy('user_id') + ->orderByDesc('value') + ->take(8) + ->get(), + ), + 'seedtimes' => cache()->remember( + 'top-users:seedtimes', + 3_600, + fn () => User::withSum('history as seedtime', 'seedtime') + ->where('id', '!=', User::SYSTEM_USER_ID) + ->whereNotIn('group_id', Group::select('id')->whereIn('slug', ['banned', 'validating', 'disabled', 'pruned'])) + ->orderByDesc('seedtime') + ->take(8) + ->get(), + ), + 'served' => cache()->remember( + 'top-users:served', + 3_600, + fn () => User::withCount('uploadSnatches') + ->where('id', '!=', User::SYSTEM_USER_ID) + ->whereNotIn('group_id', Group::select('id')->whereIn('slug', ['banned', 'validating', 'disabled', 'pruned'])) + ->orderByDesc('upload_snatches_count') + ->take(8) + ->get(), + ), + 'commenters' => cache()->remember( + 'top-users:commenters', + 3_600, + fn () => Comment::with(['user' , 'user.group']) + ->select(DB::raw('user_id, COUNT(user_id) as value')) + ->where('user_id', '!=', User::SYSTEM_USER_ID) + ->where('anon', '=', false) + ->groupBy('user_id') + ->orderByRaw('COALESCE(value, 0) DESC') + ->take(8) + ->get() + ), + 'posters' => cache()->remember( + 'top-users:posters', + 3_600, + fn () => Post::with(['user' , 'user.group']) + ->select(DB::raw('user_id, COUNT(user_id) as value')) + ->where('user_id', '!=', User::SYSTEM_USER_ID) + ->groupBy('user_id') + ->orderByRaw('COALESCE(value, 0) DESC') + ->take(8) + ->get() + ), + 'thankers' => cache()->remember( + 'top-users:thankers', + 3_600, + fn () => Thank::with(['user' , 'user.group']) + ->select(DB::raw('user_id, COUNT(user_id) as value')) + ->where('user_id', '!=', User::SYSTEM_USER_ID) + ->groupBy('user_id') + ->orderByRaw('COALESCE(value, 0) DESC') + ->take(8) + ->get() + ), 'freeleech_tokens' => FreeleechToken::where('user_id', $user->id)->get(), 'bookmarks' => Bookmark::where('user_id', $user->id)->get(), ]); diff --git a/resources/sass/pages/_home.scss b/resources/sass/pages/_home.scss index fa0255b4e7..847606bfd7 100644 --- a/resources/sass/pages/_home.scss +++ b/resources/sass/pages/_home.scss @@ -13,3 +13,20 @@ // margin: 0 calc(-1 * max(0px, 45vw - 800px)); /* Inverses the magic numbers used in the main layout styles */ // } // } + +.top-users__place { + border-radius: 50%; + background: #212125; + border: 2px solid #934042; + height: 30px; + line-height: 27px; + width: 30px; + box-shadow: + 0 8px 10px 1px #00000024, + 0 3px 14px 2px #0000001f, + 0 5px 5px -3px #0003; + font-size: 11px; + text-align: center; + float: right; + display: inline-block; +} diff --git a/resources/views/blocks/top_uploaders.blade.php b/resources/views/blocks/top_uploaders.blade.php deleted file mode 100644 index fb23007957..0000000000 --- a/resources/views/blocks/top_uploaders.blade.php +++ /dev/null @@ -1,77 +0,0 @@ -
-

Top Uploaders

- - - - -
- - - - - - - - - - @foreach ($uploaders as $uploader) - - - - - - @endforeach - -
{{ __('common.user') }}{{ __('user.total-uploads') }}{{ __('stat.place') }}
- - {{ $uploader->value }} - {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} - {{ __('stat.place') }} -
-
-
- - - - - - - - - - @foreach ($past_uploaders as $uploader) - - - - - - @endforeach - -
{{ __('common.user') }}{{ __('user.total-uploads') }}{{ __('stat.place') }}
- - {{ $uploader->value }} - {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} - {{ __('stat.place') }} -
-
-
diff --git a/resources/views/blocks/top_users.blade.php b/resources/views/blocks/top_users.blade.php new file mode 100644 index 0000000000..8ed09eb2db --- /dev/null +++ b/resources/views/blocks/top_users.blade.php @@ -0,0 +1,385 @@ +
+

Top Users

+ + + + + + + + + + + + +
+
+ @foreach ($uploaders as $uploader) +
+

+ +
+ {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} +
+

+

{{ $uploader->value }} Uploads

+ + @if ($uploader->user->private_profile) + avatar + @else + avatar + @endif +
+ @endforeach +
+
+ @foreach ($downloaders as $downloader) +
+

+ +
+ {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} +
+

+

{{ $downloader->value }} Downloads

+ + @if ($downloader->user->private_profile) + avatar + @else + avatar + @endif +
+ @endforeach +
+
+ @foreach ($uploaded as $upload) +
+

+ +
+ {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} +
+

+

+ {{ App\Helpers\StringHelper::formatBytes($upload->uploaded, 2) }} Uploaded +

+ + @if ($upload->private_profile) + avatar + @else + avatar + @endif +
+ @endforeach +
+
+ @foreach ($downloaded as $download) +
+

+ +
+ {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} +
+

+

+ {{ App\Helpers\StringHelper::formatBytes($download->downloaded, 2) }} + Downloaded +

+ + @if ($download->private_profile) + avatar + @else + avatar + @endif +
+ @endforeach +
+
+ @foreach ($seeders as $seeder) +
+

+ +
+ {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} +
+

+

{{ $seeder->value }} Seeds

+ + @if ($seeder->user->private_profile) + avatar + @else + avatar + @endif +
+ @endforeach +
+
+ @foreach ($seedtimes as $seedtime) +
+

+ +
+ {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} +
+

+

+ {{ App\Helpers\StringHelper::timeElapsed($seedtime->seedtime ?? 0) }} + Seedtime Average +

+ + @if ($seedtime->private_profile) + avatar + @else + avatar + @endif +
+ @endforeach +
+
+ @foreach ($served as $serve) +
+

+ +
+ {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} +
+

+

+ {{ $serve->upload_snatches_count }} Users Served +

+ + @if ($serve->private_profile) + avatar + @else + avatar + @endif +
+ @endforeach +
+
+ @foreach ($commenters as $commenter) +
+

+ +
+ {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} +
+

+

{{ $commenter->value }} Comments Made

+ + @if ($commenter->user->private_profile) + avatar + @else + avatar + @endif +
+ @endforeach +
+
+ @foreach ($posters as $poster) +
+

+ +
+ {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} +
+

+

{{ $poster->value }} Posts Made

+ + @if ($poster->user->private_profile) + avatar + @else + avatar + @endif +
+ @endforeach +
+
+ @foreach ($thankers as $thanker) +
+

+ +
+ {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} +
+

+

{{ $thanker->value }} Thanks Given

+ + @if ($thanker->user->private_profile) + avatar + @else + avatar + @endif +
+ @endforeach +
+
+
diff --git a/resources/views/home/index.blade.php b/resources/views/home/index.blade.php index a1cae68af8..be1389fbb6 100644 --- a/resources/views/home/index.blade.php +++ b/resources/views/home/index.blade.php @@ -15,7 +15,7 @@ @livewire('random-media') @include('blocks.poll') @livewire('top-torrents') - @include('blocks.top_uploaders') + @include('blocks.top_users') @include('blocks.latest_topics') @include('blocks.latest_posts') @include('blocks.online') From 19f3f135634cf03e04231909e2587f1454c5a4ab Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Mon, 8 Apr 2024 19:06:12 -0400 Subject: [PATCH 17/61] update: homecontroller test --- tests/Feature/Http/Controllers/HomeControllerTest.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/Feature/Http/Controllers/HomeControllerTest.php b/tests/Feature/Http/Controllers/HomeControllerTest.php index 4a4ae752ec..e36775829c 100644 --- a/tests/Feature/Http/Controllers/HomeControllerTest.php +++ b/tests/Feature/Http/Controllers/HomeControllerTest.php @@ -29,7 +29,15 @@ $response->assertViewHas('featured'); $response->assertViewHas('poll'); $response->assertViewHas('uploaders'); - $response->assertViewHas('past_uploaders'); + $response->assertViewHas('downloaders'); + $response->assertViewHas('uploaded'); + $response->assertViewHas('downloaded'); + $response->assertViewHas('seeders'); + $response->assertViewHas('seedtimes'); + $response->assertViewHas('served'); + $response->assertViewHas('commenters'); + $response->assertViewHas('posters'); + $response->assertViewHas('thankers'); $response->assertViewHas('freeleech_tokens'); $response->assertViewHas('bookmarks'); }); From adb103fda0e9db87bc18e5fafbe583ff48173e01 Mon Sep 17 00:00:00 2001 From: EkoNesLeg <155665062+EkoNesLeg@users.noreply.github.com> Date: Tue, 9 Apr 2024 01:53:38 +0100 Subject: [PATCH 18/61] (Update) TMDb/IMDb icons for movie_meta partials --- resources/views/torrent/partials/movie_meta.blade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/torrent/partials/movie_meta.blade.php b/resources/views/torrent/partials/movie_meta.blade.php index 078495c349..31b69872a7 100755 --- a/resources/views/torrent/partials/movie_meta.blade.php +++ b/resources/views/torrent/partials/movie_meta.blade.php @@ -95,7 +95,7 @@ class="meta-id-tag" title="The Movie Database: {{ $meta->id }}" target="_blank" > - + @endif @@ -108,7 +108,7 @@ class="meta-id-tag" title="Internet Movie Database: {{ \str_pad((string) $meta->imdb_id, \max(\strlen((string) $meta->imdb_id), 7), '0', STR_PAD_LEFT) }}" target="_blank" > - + @endif From ec236053f7b267614988550b1a579f070bf2d007 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Thu, 11 Apr 2024 18:24:06 -0400 Subject: [PATCH 19/61] add: personal releases --- app/Http/Controllers/HomeController.php | 13 +++++++ resources/views/blocks/top_users.blade.php | 38 +++++++++++++++++++ .../Http/Controllers/HomeControllerTest.php | 1 + 3 files changed, 52 insertions(+) diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 87abf81549..bff3ee4237 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -234,6 +234,19 @@ public function index(Request $request): \Illuminate\Contracts\View\Factory|\Ill ->take(8) ->get() ), + 'personals' => cache()->remember( + 'top-users:personals', + 3_600, + fn () => Torrent::with(['user' , 'user.group']) + ->select(DB::raw('user_id, COUNT(user_id) as value')) + ->where('user_id', '!=', User::SYSTEM_USER_ID) + ->where('anon', '=', false) + ->where('personal_release', '=', 1) + ->groupBy('user_id') + ->orderByDesc('value') + ->take(8) + ->get() + ), 'freeleech_tokens' => FreeleechToken::where('user_id', $user->id)->get(), 'bookmarks' => Bookmark::where('user_id', $user->id)->get(), ]); diff --git a/resources/views/blocks/top_users.blade.php b/resources/views/blocks/top_users.blade.php index 8ed09eb2db..555ea2ee51 100644 --- a/resources/views/blocks/top_users.blade.php +++ b/resources/views/blocks/top_users.blade.php @@ -81,6 +81,14 @@ class="panel__tab" > Thankers +
@@ -381,5 +389,35 @@ class="user-stat-card__avatar" @endforeach
+
+ @foreach ($personals as $personal) +
+

+ +
+ {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} +
+

+

{{ $uploader->value }} Personal Releases

+ + @if ($personal->user->private_profile) + avatar + @else + avatar + @endif +
+ @endforeach +
diff --git a/tests/Feature/Http/Controllers/HomeControllerTest.php b/tests/Feature/Http/Controllers/HomeControllerTest.php index e36775829c..f8afa65986 100644 --- a/tests/Feature/Http/Controllers/HomeControllerTest.php +++ b/tests/Feature/Http/Controllers/HomeControllerTest.php @@ -38,6 +38,7 @@ $response->assertViewHas('commenters'); $response->assertViewHas('posters'); $response->assertViewHas('thankers'); + $response->assertViewHas('personals'); $response->assertViewHas('freeleech_tokens'); $response->assertViewHas('bookmarks'); }); From d0ba5f7b599135fcdddd19402c7bb9cfee9c916a Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Thu, 11 Apr 2024 20:05:10 -0400 Subject: [PATCH 20/61] chore: lint --- resources/views/torrent/partials/movie_meta.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/torrent/partials/movie_meta.blade.php b/resources/views/torrent/partials/movie_meta.blade.php index 31b69872a7..3ba4af03d8 100755 --- a/resources/views/torrent/partials/movie_meta.blade.php +++ b/resources/views/torrent/partials/movie_meta.blade.php @@ -95,7 +95,7 @@ class="meta-id-tag" title="The Movie Database: {{ $meta->id }}" target="_blank" > - + @endif From 25c898bdea85464278d133fe0bfaada47a826931 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Thu, 11 Apr 2024 20:10:11 -0400 Subject: [PATCH 21/61] update: meta icons --- resources/views/torrent/partials/movie_meta.blade.php | 2 +- resources/views/torrent/partials/tv_meta.blade.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/views/torrent/partials/movie_meta.blade.php b/resources/views/torrent/partials/movie_meta.blade.php index 3ba4af03d8..a11bd29216 100755 --- a/resources/views/torrent/partials/movie_meta.blade.php +++ b/resources/views/torrent/partials/movie_meta.blade.php @@ -95,7 +95,7 @@ class="meta-id-tag" title="The Movie Database: {{ $meta->id }}" target="_blank" > - + @endif diff --git a/resources/views/torrent/partials/tv_meta.blade.php b/resources/views/torrent/partials/tv_meta.blade.php index 9ff5da6aa1..f9970d6737 100755 --- a/resources/views/torrent/partials/tv_meta.blade.php +++ b/resources/views/torrent/partials/tv_meta.blade.php @@ -94,7 +94,7 @@ class="meta-id-tag" title="The Movie Database: {{ $meta->id }}" target="_blank" > - + @endif @@ -107,7 +107,7 @@ class="meta-id-tag" title="Internet Movie Database: {{ \str_pad((string) $meta->imdb_id, \max(\strlen((string) $meta->imdb_id), 7), '0', STR_PAD_LEFT) }}" target="_blank" > - + @endif From 1502f8fd912814f9e3586041238d94d852cc0b9e Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Thu, 11 Apr 2024 23:10:57 -0400 Subject: [PATCH 22/61] update: images --- .gitignore | 24 ++-- public/img/imdb-icon.png | Bin 2768 -> 0 bytes public/img/meta/anidb.svg | 123 ++++++++++++++++++ public/img/meta/imdb.svg | 3 + public/img/meta/tmdb.svg | 1 + public/img/meta/tvdb.svg | 1 + public/img/tmdb-icon.png | Bin 1207 -> 0 bytes public/img/tmdb_small.png | Bin 1207 -> 0 bytes .../torrent/partials/movie_meta.blade.php | 10 +- .../views/torrent/partials/tv_meta.blade.php | 10 +- 10 files changed, 147 insertions(+), 25 deletions(-) delete mode 100644 public/img/imdb-icon.png create mode 100644 public/img/meta/anidb.svg create mode 100644 public/img/meta/imdb.svg create mode 100644 public/img/meta/tmdb.svg create mode 100644 public/img/meta/tvdb.svg delete mode 100644 public/img/tmdb-icon.png delete mode 100644 public/img/tmdb_small.png diff --git a/.gitignore b/.gitignore index beaa2f9dd8..67ccbc9ae7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,29 +5,18 @@ # Ignore everything in the public/files directory EXCEPT the .gitkeep /public/files !.gitkeep - -/public/css -/public/fonts -/public/img -/public/js /public/sounds /public/vendor -/public/mix-manifest.json -/public/mix-sri.json - /storage/backups /storage/gitupdate /storage/*.key - -/vendor -/.vagrant -Homestead.json -Homestead.yaml -npm-debug.log .env laravel-echo-server.json laravel-echo-server.lock +# Composer +/vendor + # Vite /public/build @@ -43,7 +32,12 @@ laravel-echo-server.lock # Vim .*.swp -_ide_helper.php +# Miscellaneous +/.vagrant +Homestead.json +Homestead.yaml +npm-debug.log +_ide_helper.php supervisor.ini /.phpunit.cache/ diff --git a/public/img/imdb-icon.png b/public/img/imdb-icon.png deleted file mode 100644 index 892c8fc76b208363c66755a4d13e1536e021ec1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2768 zcmV;>3NQ7EP)o`qzJy|CiTOzj_yIv35d$U)2!dfO10TWcR-j`?d0_7ItkoM9X3pBx z=X%X_ZQ~p*=S*|V?lmpH?n9PqjG{5OP+8qDR)C*j_A)@t%uN-o1eq7U<(OwAd~FP! zyQaC$)J*RH?$qJV8x2YcT?v(MO5hVoc+1TQVDU)HPw;9-;C)7b8S75h&RDszZZ-~5 zSZaak9qKzD1ilRB17f|Mfy zcjnxzvMuYS4&6XrLQwEk%q|G8b9{eTkj`7V1u7f^`)yu97uQ#;AIJm|s)a1l;i1W@ zzHvif78BHrP+UP!(^kdm1ULhwN&&aIZH)3{<>L#li^7|N9wEFPSNQh#$+4#O_4#mO z#Z$T95MI|K5>{IoaMcOw_=?dmB!Y<%CMo)V#qnGvd~6Xuh9On;6Y`xgp(psv{}(vE z)^f}7Hy6WBi(^T5L!IDw*!Jo{NI zV8-7c+oIzIHN#Z7>G~BqLHOgJH&IOjm1X42HC@)00}uXn2Peref{}G#eYL~2>lwqm zWIT@i?H~J;Wh6%B?0SdOYk{)V7XF`RYN_);Kd&H^xder%^!kAZ|GB{%-t&FBS>Wl7 z1HSvkJBez%<6}SO^!flZ*xns;&sSc@P3Kp*>jOW*IU#uA(niiF-}?gIbldg3;Y0T^ z=zGi(bBEyQcRjbi{4}3>|8psd$ooF~0GGFNb`K(-dH+p(bk^zz0EGdVqI=cWHf$Mm|ln<`aVQw`^Y$DZ7y*Y%Z0Qck3Ha&-?8D5LS*8@^Z>T)<$N}H`+>JQqGI|9g$4&Fe!FOPZZUt>Dn z8o8$WSH)2dkr>?X=B8N$97p=&Ny{4ql`5}&w2o9++zlt zHOz#fG+z3=0k3@VGI?PWV_1`1n9b~NTRb^7*Fa2Tz^aE^143m~)>Z;%)_att64h8; z?r{2Kmon<)p_8I(A&!`XS$e*RFv=std`bwm(2Y&$)XWI0R<_hFvS_Iqcao~+LC>=? z=uoQR)L383SX&OnSP_0Bh$k*+cy`_cOvLdLn^V&3iB~wT>+STe6 zf-yIPsXWkTsp`RX2Y17@1Ds0=Tz9%hCrrYmF$}1Mhy7vX@uzdVPmJdssc>V;?NXG6_kwe- zs$R9a7S@&npZ@v&DrPDsoq0!uyNXTRIy#Heg+kLh+C`#WRCMIIfo7-c~oysT+*xxR=?o^kDFYK|q zU4RpYqgdUeB=4t6^zv3g@X3SA1JB*JokXLuy%+h{b|mWv4?dD};fXQ9!{%<}t+)0$ zz2-Q`V~UL?j6{%)-@FsaR5U;j{^dV$4o0Jr+g^SaGvmJBK8X{! z@m!x*yyO~wc;7{K_Y3ZN^%N3IAEl8?h`(4M2Z|?D& z^BuPLN`Cs=9S%l`&2E3`fImGlF2sRYEHK`J$SBH_F|Y! zm754Hhm136gcK6(YrhI(~ktZa8N2)M+whpR?|LdXkTxK ztUG$b*FMgi=9kcKsWDon!ADz}!<28E3AOBx(Kfc3owqJPNRkpEHwb3r9o(l0a^79RLx|!dazx2pXxX?d9@th zlB{fDpDq!o*-qsI2?DNq(!FMO3#KKtH~t&Kx9+zcOL#0<6|f)GsW_Nf#0LyMFXi}E zX8QUxNm6(GjftzENm`ndh2LGwZJZ~#X|)^qZP0I|eGQ92oHs2-^j6M{M|+pwgxT9M zyWPw>$15A!cGz`V{~VT}4iTPK;Spd6b}#5X5Co!uGkM|{Z)yFp2jV#Q>hJwu{Mh3! z-@KvO;?Dlq1K{F)Z%)G~5Hs~x+RJVK-NWL~Y8JO&+wp#A)}69WvkEP1O`i9zNBK9X W3vT4k=7ZG$0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/img/meta/imdb.svg b/public/img/meta/imdb.svg new file mode 100644 index 0000000000..b2a908bcb4 --- /dev/null +++ b/public/img/meta/imdb.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/public/img/meta/tmdb.svg b/public/img/meta/tmdb.svg new file mode 100644 index 0000000000..42f31f1544 --- /dev/null +++ b/public/img/meta/tmdb.svg @@ -0,0 +1 @@ +Asset 2 \ No newline at end of file diff --git a/public/img/meta/tvdb.svg b/public/img/meta/tvdb.svg new file mode 100644 index 0000000000..929914460c --- /dev/null +++ b/public/img/meta/tvdb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/tmdb-icon.png b/public/img/tmdb-icon.png deleted file mode 100644 index a6a07f053683c161dac79f81f594d83078ee8388..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1207 zcmV;o1W5adP)6$R#MK=y156>wQHNW1@*y;^f< z4Y;Da-ioL{>_4+U>s8S+-7`JY-NQ69;}72iYO1U2Gu8Fp_f?Ms08%nb`tATcKa6N# zYG>+BFm>SEA_A}u51Amr)oBXAK4?jT$!lsh1L!sFoIV=J?nNL!Y5?iq4IsVof%Luw zq>rs2eQt|hA6mpXn%*^o^kO5(&znI0s}YoQ<)CIy3*6CM}j`o0jS8RGUYn;DL13=M=*`lp{77GlbO`Y#1z_TW20C!eJ1i%#{O?f;q zX>ExGaI-cnfZSduyi>hJ)Y3wb1>4Y^_yZypQ)W^J7S@JJL1z{F>{3-HPzz;BhI04xuf0%&2>MS%aM zS3XAo7}IHOj&Q768?(V=#{!_mQw@D-Q5KMv0#GNWy9V%8dhJVUFZ7j{j&?Hf=`tQB zE(Whk>>nYU063`-FT@@{HGgubEzyhRg<#N- zv2U*$0D#RX#J|;t4ZM<4$BzN!c!@|}ED>Ux9zY#CnwP3tA6k>+8i4IY#sRw42HKcK zmLG^(f-awK1jw5V>YNNv&R2-f%?tJrdor*@)@K8tdz~>%?kyJKvpGNPBg9w8>x~wm zJGKBg89l(EC4SqW2fzt&*UHA^dtl~-#8?6B>u+OuK(pesFv|d-{AAMRy;7 z-GG+P0Mav0LXzQpqwfLP5_0n1E0e!GuQ^&Z++U|FK81=^KxO VxUYKSUM&Cs002ovPDHLkV1hD-He>(* diff --git a/public/img/tmdb_small.png b/public/img/tmdb_small.png deleted file mode 100644 index a6a07f053683c161dac79f81f594d83078ee8388..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1207 zcmV;o1W5adP)6$R#MK=y156>wQHNW1@*y;^f< z4Y;Da-ioL{>_4+U>s8S+-7`JY-NQ69;}72iYO1U2Gu8Fp_f?Ms08%nb`tATcKa6N# zYG>+BFm>SEA_A}u51Amr)oBXAK4?jT$!lsh1L!sFoIV=J?nNL!Y5?iq4IsVof%Luw zq>rs2eQt|hA6mpXn%*^o^kO5(&znI0s}YoQ<)CIy3*6CM}j`o0jS8RGUYn;DL13=M=*`lp{77GlbO`Y#1z_TW20C!eJ1i%#{O?f;q zX>ExGaI-cnfZSduyi>hJ)Y3wb1>4Y^_yZypQ)W^J7S@JJL1z{F>{3-HPzz;BhI04xuf0%&2>MS%aM zS3XAo7}IHOj&Q768?(V=#{!_mQw@D-Q5KMv0#GNWy9V%8dhJVUFZ7j{j&?Hf=`tQB zE(Whk>>nYU063`-FT@@{HGgubEzyhRg<#N- zv2U*$0D#RX#J|;t4ZM<4$BzN!c!@|}ED>Ux9zY#CnwP3tA6k>+8i4IY#sRw42HKcK zmLG^(f-awK1jw5V>YNNv&R2-f%?tJrdor*@)@K8tdz~>%?kyJKvpGNPBg9w8>x~wm zJGKBg89l(EC4SqW2fzt&*UHA^dtl~-#8?6B>u+OuK(pesFv|d-{AAMRy;7 z-GG+P0Mav0LXzQpqwfLP5_0n1E0e!GuQ^&Z++U|FK81=^KxO VxUYKSUM&Cs002ovPDHLkV1hD-He>(* diff --git a/resources/views/torrent/partials/movie_meta.blade.php b/resources/views/torrent/partials/movie_meta.blade.php index a11bd29216..eafb51c7c4 100755 --- a/resources/views/torrent/partials/movie_meta.blade.php +++ b/resources/views/torrent/partials/movie_meta.blade.php @@ -95,7 +95,7 @@ class="meta-id-tag" title="The Movie Database: {{ $meta->id }}" target="_blank" > - + @endif @@ -108,7 +108,7 @@ class="meta-id-tag" title="Internet Movie Database: {{ \str_pad((string) $meta->imdb_id, \max(\strlen((string) $meta->imdb_id), 7), '0', STR_PAD_LEFT) }}" target="_blank" > - + @endif @@ -121,7 +121,7 @@ class="meta-id-tag" title="My Anime List: {{ $torrent->mal }}" target="_blank" > - + @endif @@ -134,7 +134,7 @@ class="meta-id-tag" title="The TV Database: {{ $torrent->tvdb }}" target="_blank" > - + @endif @@ -147,7 +147,7 @@ class="meta-id-tag" title="Rotten Tomatoes: {{ $meta->title ?? '' }} ({{ substr($meta->release_date ?? '', 0, 4) ?? '' }})" target="_blank" > - + @endif diff --git a/resources/views/torrent/partials/tv_meta.blade.php b/resources/views/torrent/partials/tv_meta.blade.php index f9970d6737..e8ddd6922d 100755 --- a/resources/views/torrent/partials/tv_meta.blade.php +++ b/resources/views/torrent/partials/tv_meta.blade.php @@ -94,7 +94,7 @@ class="meta-id-tag" title="The Movie Database: {{ $meta->id }}" target="_blank" > - + @endif @@ -107,7 +107,7 @@ class="meta-id-tag" title="Internet Movie Database: {{ \str_pad((string) $meta->imdb_id, \max(\strlen((string) $meta->imdb_id), 7), '0', STR_PAD_LEFT) }}" target="_blank" > - + @endif @@ -120,7 +120,7 @@ class="meta-id-tag" title="My Anime List: {{ $torrent->mal }}" target="_blank" > - + @endif @@ -133,7 +133,7 @@ class="meta-id-tag" title="The TV Database: {{ $torrent->tvdb }}" target="_blank" > - + @endif @@ -145,7 +145,7 @@ class="meta-id-tag" title="Rotten Tomatoes: {{ $meta->name ?? '' }} ({{ substr($meta->first_air_date ?? '', 0, 4) ?? '' }})" target="_blank" > - + From 062f166f3b9866feebdc266789c1e1b3a88693bd Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Fri, 12 Apr 2024 03:11:56 +0000 Subject: [PATCH 23/61] Blade Style Change (Prettier Blade CI) --- .../torrent/partials/movie_meta.blade.php | 19 ++++++++++++++----- .../views/torrent/partials/tv_meta.blade.php | 19 ++++++++++++++----- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/resources/views/torrent/partials/movie_meta.blade.php b/resources/views/torrent/partials/movie_meta.blade.php index eafb51c7c4..303a432e60 100755 --- a/resources/views/torrent/partials/movie_meta.blade.php +++ b/resources/views/torrent/partials/movie_meta.blade.php @@ -95,7 +95,7 @@ class="meta-id-tag" title="The Movie Database: {{ $meta->id }}" target="_blank" > - + @endif @@ -108,7 +108,7 @@ class="meta-id-tag" title="Internet Movie Database: {{ \str_pad((string) $meta->imdb_id, \max(\strlen((string) $meta->imdb_id), 7), '0', STR_PAD_LEFT) }}" target="_blank" > - + @endif @@ -121,7 +121,7 @@ class="meta-id-tag" title="My Anime List: {{ $torrent->mal }}" target="_blank" > - + @endif @@ -134,7 +134,7 @@ class="meta-id-tag" title="The TV Database: {{ $torrent->tvdb }}" target="_blank" > - + @endif @@ -147,7 +147,16 @@ class="meta-id-tag" title="Rotten Tomatoes: {{ $meta->title ?? '' }} ({{ substr($meta->release_date ?? '', 0, 4) ?? '' }})" target="_blank" > - + @endif diff --git a/resources/views/torrent/partials/tv_meta.blade.php b/resources/views/torrent/partials/tv_meta.blade.php index e8ddd6922d..e91f8e899e 100755 --- a/resources/views/torrent/partials/tv_meta.blade.php +++ b/resources/views/torrent/partials/tv_meta.blade.php @@ -94,7 +94,7 @@ class="meta-id-tag" title="The Movie Database: {{ $meta->id }}" target="_blank" > - + @endif @@ -107,7 +107,7 @@ class="meta-id-tag" title="Internet Movie Database: {{ \str_pad((string) $meta->imdb_id, \max(\strlen((string) $meta->imdb_id), 7), '0', STR_PAD_LEFT) }}" target="_blank" > - + @endif @@ -120,7 +120,7 @@ class="meta-id-tag" title="My Anime List: {{ $torrent->mal }}" target="_blank" > - + @endif @@ -133,7 +133,7 @@ class="meta-id-tag" title="The TV Database: {{ $torrent->tvdb }}" target="_blank" > - + @endif @@ -145,7 +145,16 @@ class="meta-id-tag" title="Rotten Tomatoes: {{ $meta->name ?? '' }} ({{ substr($meta->first_air_date ?? '', 0, 4) ?? '' }})" target="_blank" > - + From 96984a4c6607429cb384b29daf652461135861e1 Mon Sep 17 00:00:00 2001 From: Audionut Date: Sun, 14 Apr 2024 17:58:46 +1000 Subject: [PATCH 24/61] (Update) User profile invite persmission - 2fa --- resources/views/user/profile/show.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/user/profile/show.blade.php b/resources/views/user/profile/show.blade.php index 838b5e7ca2..74a35ec206 100644 --- a/resources/views/user/profile/show.blade.php +++ b/resources/views/user/profile/show.blade.php @@ -924,7 +924,7 @@ class="{{ $user->last_action }}"
{{ __('user.can-invite') }}
- @if ($user->can_invite == 1) + @if ($user->can_invite == 1 && user->two_factor_confirmed_at !== null) @else From ea38a1cb38e36c3f8e6f9a824f839d80c347c670 Mon Sep 17 00:00:00 2001 From: Jay Sizzla Date: Sat, 13 Apr 2024 20:26:47 +0200 Subject: [PATCH 25/61] Add search for title and year --- app/Http/Livewire/MissingMediaSearch.php | 8 ++++ .../livewire/missing-media-search.blade.php | 39 ++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/app/Http/Livewire/MissingMediaSearch.php b/app/Http/Livewire/MissingMediaSearch.php index 8fe342ce3a..ce0602f66e 100644 --- a/app/Http/Livewire/MissingMediaSearch.php +++ b/app/Http/Livewire/MissingMediaSearch.php @@ -28,6 +28,12 @@ class MissingMediaSearch extends Component #TODO: Update URL attributes once Livewire 3 fixes upstream bug. See: https://github.com/livewire/livewire/discussions/7746 + #[Url(history: true)] + public string $name = ''; + + #[Url(history: true)] + public ?int $year = null; + #[Url(history: true)] public array $categories = []; @@ -47,6 +53,8 @@ class MissingMediaSearch extends Component final public function medias(): \Illuminate\Contracts\Pagination\LengthAwarePaginator { return Movie::with(['torrents:tmdb,resolution_id,type_id' => ['resolution:id,position,name']]) + ->when($this->name, fn ($query) => $query->where('title', 'LIKE', '%'.$this->name.'%')) + ->when($this->year, fn ($query) => $query->where('release_date', 'LIKE', '%'.$this->year.'%')) ->withCount(['requests' => fn ($query) => $query->whereNull('torrent_id')->whereNull('claimed')]) ->orderBy($this->sortField, $this->sortDirection) ->paginate($this->perPage); diff --git a/resources/views/livewire/missing-media-search.blade.php b/resources/views/livewire/missing-media-search.blade.php index 0e9ea1cdca..4594b097e5 100644 --- a/resources/views/livewire/missing-media-search.blade.php +++ b/resources/views/livewire/missing-media-search.blade.php @@ -1,10 +1,45 @@
-

Missing Media

+
+

Missing Media

+
+
+
+ + +
+
+
+
+ + +
+
+
+
- {{ __('common.name') }} + {{ __('torrent.title') }} @include('livewire.includes._sort-icon', ['field' => 'title']) From b40250f88d81221be4025232844591fbda1ebb9a Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Sun, 14 Apr 2024 18:21:36 -0400 Subject: [PATCH 26/61] fix: form request --- app/Http/Requests/Staff/StoreGroupRequest.php | 43 ++++++++++------- .../Requests/Staff/UpdateGroupRequest.php | 47 ++++++++++--------- 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/app/Http/Requests/Staff/StoreGroupRequest.php b/app/Http/Requests/Staff/StoreGroupRequest.php index f6d2d8fc4f..c6f0819fc3 100644 --- a/app/Http/Requests/Staff/StoreGroupRequest.php +++ b/app/Http/Requests/Staff/StoreGroupRequest.php @@ -15,6 +15,7 @@ use Illuminate\Foundation\Http\FormRequest; use Illuminate\Http\Request; +use Illuminate\Validation\Rule; class StoreGroupRequest extends FormRequest { @@ -31,7 +32,7 @@ public function authorize(Request $request): bool * * @return array|string> */ - public function rules(): array + public function rules(Request $request): array { return [ 'name' => [ @@ -112,29 +113,39 @@ public function rules(): array 'boolean', ], 'min_uploaded' => [ - 'sometimes', - 'integer', - 'min:0', + Rule::when($request->autogroup, [ + 'sometimes', + 'integer', + 'min:0', + ]), ], 'min_ratio' => [ - 'sometimes', - 'min:0', - 'max:99.99', + Rule::when($request->autogroup, [ + 'sometimes', + 'min:0', + 'max:99.99', + ]), ], 'min_age' => [ - 'sometimes', - 'integer', - 'min:0', + Rule::when($request->autogroup, [ + 'sometimes', + 'integer', + 'min:0', + ]), ], 'min_avg_seedtime' => [ - 'sometimes', - 'integer', - 'min:0', + Rule::when($request->autogroup, [ + 'sometimes', + 'integer', + 'min:0', + ]), ], 'min_seedsize' => [ - 'sometimes', - 'integer', - 'min:0', + Rule::when($request->autogroup, [ + 'sometimes', + 'integer', + 'min:0', + ]), ], ]; } diff --git a/app/Http/Requests/Staff/UpdateGroupRequest.php b/app/Http/Requests/Staff/UpdateGroupRequest.php index ccf7961c45..fcdef69066 100644 --- a/app/Http/Requests/Staff/UpdateGroupRequest.php +++ b/app/Http/Requests/Staff/UpdateGroupRequest.php @@ -40,7 +40,7 @@ public function rules(Request $request): array return [ 'name' => [ - Rule::when(!$group->system_required, [ + Rule::when(! $group->system_required, [ 'required', 'string', ]), @@ -119,34 +119,39 @@ public function rules(Request $request): array 'boolean', ], 'min_uploaded' => [ - 'sometimes', - 'nullable', - 'integer', - 'min:0', + Rule::when($group->autogroup, [ + 'sometimes', + 'integer', + 'min:0', + ]), ], 'min_ratio' => [ - 'sometimes', - 'nullable', - 'min:0', - 'max:99.99', + Rule::when($group->autogroup, [ + 'sometimes', + 'min:0', + 'max:99.99', + ]), ], 'min_age' => [ - 'sometimes', - 'nullable', - 'integer', - 'min:0', + Rule::when($group->autogroup, [ + 'sometimes', + 'integer', + 'min:0', + ]), ], 'min_avg_seedtime' => [ - 'sometimes', - 'nullable', - 'integer', - 'min:0', + Rule::when($group->autogroup, [ + 'sometimes', + 'integer', + 'min:0', + ]), ], 'min_seedsize' => [ - 'sometimes', - 'nullable', - 'integer', - 'min:0', + Rule::when($group->autogroup, [ + 'sometimes', + 'integer', + 'min:0', + ]), ], ]; } From fa2a5a2dabdff21a80e4e93704b11052b0d91af3 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Sun, 14 Apr 2024 18:53:08 -0400 Subject: [PATCH 27/61] chore: actions --- app/Http/Requests/Staff/StoreGroupRequest.php | 12 ++++++------ app/Http/Requests/Staff/UpdateGroupRequest.php | 10 +++++----- .../Http/Requests/Staff/StoreGroupRequestTest.php | 2 ++ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/Http/Requests/Staff/StoreGroupRequest.php b/app/Http/Requests/Staff/StoreGroupRequest.php index c6f0819fc3..23d859f556 100644 --- a/app/Http/Requests/Staff/StoreGroupRequest.php +++ b/app/Http/Requests/Staff/StoreGroupRequest.php @@ -30,7 +30,7 @@ public function authorize(Request $request): bool /** * Get the validation rules that apply to the request. * - * @return array|string> + * @return array|string> */ public function rules(Request $request): array { @@ -113,35 +113,35 @@ public function rules(Request $request): array 'boolean', ], 'min_uploaded' => [ - Rule::when($request->autogroup, [ + Rule::when((bool) $request->integer('autogroup'), [ 'sometimes', 'integer', 'min:0', ]), ], 'min_ratio' => [ - Rule::when($request->autogroup, [ + Rule::when((bool) $request->integer('autogroup'), [ 'sometimes', 'min:0', 'max:99.99', ]), ], 'min_age' => [ - Rule::when($request->autogroup, [ + Rule::when((bool) $request->integer('autogroup'), [ 'sometimes', 'integer', 'min:0', ]), ], 'min_avg_seedtime' => [ - Rule::when($request->autogroup, [ + Rule::when((bool) $request->integer('autogroup'), [ 'sometimes', 'integer', 'min:0', ]), ], 'min_seedsize' => [ - Rule::when($request->autogroup, [ + Rule::when((bool) $request->integer('autogroup'), [ 'sometimes', 'integer', 'min:0', diff --git a/app/Http/Requests/Staff/UpdateGroupRequest.php b/app/Http/Requests/Staff/UpdateGroupRequest.php index fcdef69066..6c9b53c746 100644 --- a/app/Http/Requests/Staff/UpdateGroupRequest.php +++ b/app/Http/Requests/Staff/UpdateGroupRequest.php @@ -119,35 +119,35 @@ public function rules(Request $request): array 'boolean', ], 'min_uploaded' => [ - Rule::when($group->autogroup, [ + Rule::when((bool) $group->autogroup, [ 'sometimes', 'integer', 'min:0', ]), ], 'min_ratio' => [ - Rule::when($group->autogroup, [ + Rule::when((bool) $group->autogroup, [ 'sometimes', 'min:0', 'max:99.99', ]), ], 'min_age' => [ - Rule::when($group->autogroup, [ + Rule::when((bool) $group->autogroup, [ 'sometimes', 'integer', 'min:0', ]), ], 'min_avg_seedtime' => [ - Rule::when($group->autogroup, [ + Rule::when((bool) $group->autogroup, [ 'sometimes', 'integer', 'min:0', ]), ], 'min_seedsize' => [ - Rule::when($group->autogroup, [ + Rule::when((bool) $group->autogroup, [ 'sometimes', 'integer', 'min:0', diff --git a/tests/Unit/Http/Requests/Staff/StoreGroupRequestTest.php b/tests/Unit/Http/Requests/Staff/StoreGroupRequestTest.php index 15e5c77b07..944790b3de 100644 --- a/tests/Unit/Http/Requests/Staff/StoreGroupRequestTest.php +++ b/tests/Unit/Http/Requests/Staff/StoreGroupRequestTest.php @@ -26,6 +26,8 @@ }); test('rules', function (): void { + $this->markTestIncomplete('This test case was generated by Shift. When you are ready, remove this line and complete this test case.'); + $actual = $this->subject->rules(); $this->assertValidationRules([ From 5682bd03f884cf4bf26f45e94e45344c9d136499 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Sun, 14 Apr 2024 20:25:09 -0400 Subject: [PATCH 28/61] update: rules --- app/Http/Requests/Staff/StoreGroupRequest.php | 20 +++++++++---------- .../Requests/Staff/UpdateGroupRequest.php | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/app/Http/Requests/Staff/StoreGroupRequest.php b/app/Http/Requests/Staff/StoreGroupRequest.php index 23d859f556..622a06b958 100644 --- a/app/Http/Requests/Staff/StoreGroupRequest.php +++ b/app/Http/Requests/Staff/StoreGroupRequest.php @@ -113,39 +113,39 @@ public function rules(Request $request): array 'boolean', ], 'min_uploaded' => [ - Rule::when((bool) $request->integer('autogroup'), [ + Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', - ]), + ], 'prohibited'), ], 'min_ratio' => [ - Rule::when((bool) $request->integer('autogroup'), [ + Rule::when($request->boolean('autogroup'), [ 'sometimes', 'min:0', 'max:99.99', - ]), + ], 'prohibited'), ], 'min_age' => [ - Rule::when((bool) $request->integer('autogroup'), [ + Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', - ]), + ], 'prohibited'), ], 'min_avg_seedtime' => [ - Rule::when((bool) $request->integer('autogroup'), [ + Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', - ]), + ], 'prohibited'), ], 'min_seedsize' => [ - Rule::when((bool) $request->integer('autogroup'), [ + Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', - ]), + ], 'prohibited'), ], ]; } diff --git a/app/Http/Requests/Staff/UpdateGroupRequest.php b/app/Http/Requests/Staff/UpdateGroupRequest.php index 6c9b53c746..d411075b4e 100644 --- a/app/Http/Requests/Staff/UpdateGroupRequest.php +++ b/app/Http/Requests/Staff/UpdateGroupRequest.php @@ -119,39 +119,39 @@ public function rules(Request $request): array 'boolean', ], 'min_uploaded' => [ - Rule::when((bool) $group->autogroup, [ + Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', - ]), + ], 'nullable'), ], 'min_ratio' => [ - Rule::when((bool) $group->autogroup, [ + Rule::when($request->boolean('autogroup'), [ 'sometimes', 'min:0', 'max:99.99', - ]), + ], 'nullable'), ], 'min_age' => [ - Rule::when((bool) $group->autogroup, [ + Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', - ]), + ], 'nullable'), ], 'min_avg_seedtime' => [ - Rule::when((bool) $group->autogroup, [ + Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', - ]), + ], 'nullable'), ], 'min_seedsize' => [ - Rule::when((bool) $group->autogroup, [ + Rule::when($request->boolean('autogroup'), [ 'sometimes', 'integer', 'min:0', - ]), + ], 'nullable'), ], ]; } From 3240dd696a18f310f1eae5fcf993f4c2f0c066b3 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Mon, 15 Apr 2024 14:26:10 -0400 Subject: [PATCH 29/61] update: notifications --- app/Console/Commands/AutoPreWarning.php | 21 +++++++++++---------- app/Console/Commands/AutoWarning.php | 13 ++++++++++--- app/Notifications/UserPreWarning.php | 17 +++++++---------- app/Notifications/UserWarning.php | 17 +++++++---------- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/app/Console/Commands/AutoPreWarning.php b/app/Console/Commands/AutoPreWarning.php index eb9d513d4d..348b63efe2 100644 --- a/app/Console/Commands/AutoPreWarning.php +++ b/app/Console/Commands/AutoPreWarning.php @@ -37,7 +37,7 @@ class AutoPreWarning extends Command * * @var string */ - protected $description = 'Automatically Sends Pre Warning PM To Users'; + protected $description = 'Automatically Sends Pre Warning Notifications To Users'; /** * Execute the console command. @@ -58,9 +58,9 @@ public function handle(): void ->where('updated_at', '<', $carbon->copy()->subDays(config('hitrun.prewarn'))->toDateTimeString()) ->get(); + $usersWithPreWarnings = []; + foreach ($prewarn as $pre) { - // Skip Prewarning if Torrent is NULL - // e.g. Torrent has been Rejected by a Moderator after it has been downloaded and not deleted if (null === $pre->torrent) { continue; } @@ -71,20 +71,21 @@ public function handle(): void ->where('user_id', '=', $pre->user->id) ->first(); - // Send Pre Warning PM If Actual Warning Doesnt Already Exsist if ($exsist === null) { - $timeleft = config('hitrun.grace') - config('hitrun.prewarn'); - - // Send Notifications - $pre->user->notify(new UserPreWarning($pre->user, $pre->torrent)); - - // Set History Prewarn $pre->prewarn = true; $pre->timestamps = false; $pre->save(); + + // Add user to usersWithWarnings array + $usersWithPreWarnings[$pre->user->id] = $pre->user; } } } + + // Send a single notification for each user with warnings + foreach ($usersWithPreWarnings as $user) { + $user->notify(new UserPreWarning($user)); + } } $this->comment('Automated User Pre-Warning Command Complete'); diff --git a/app/Console/Commands/AutoWarning.php b/app/Console/Commands/AutoWarning.php index 87178b3300..6516d3203c 100644 --- a/app/Console/Commands/AutoWarning.php +++ b/app/Console/Commands/AutoWarning.php @@ -61,6 +61,8 @@ public function handle(): void ->where('updated_at', '<', $carbon->copy()->subDays(config('hitrun.grace'))->toDateTimeString()) ->get(); + $usersWithWarnings = []; + foreach ($hitrun as $hr) { if (!$hr->user->group->is_immune && $hr->actual_downloaded > ($hr->torrent->size * (config('hitrun.buffer') / 100))) { $exsist = Warning::withTrashed() @@ -84,13 +86,18 @@ public function handle(): void $hr->user->hitandruns++; $hr->user->save(); - // Send Notifications - $hr->user->notify(new UserWarning($hr->user, $hr->torrent)); - $hr->timestamps = false; $hr->save(); + + // Add user to usersWithWarnings array + $usersWithWarnings[$hr->user->id] = $hr->user; } } + + // Send a single notification for each user with warnings + foreach ($usersWithWarnings as $user) { + $user->notify(new UserWarning($user)); + } } // Calculate User Warning Count and Disable DL Priv If Required. diff --git a/app/Notifications/UserPreWarning.php b/app/Notifications/UserPreWarning.php index 53e7d2de52..eaf2637d3b 100644 --- a/app/Notifications/UserPreWarning.php +++ b/app/Notifications/UserPreWarning.php @@ -13,7 +13,6 @@ namespace App\Notifications; -use App\Models\Torrent; use App\Models\User; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Messages\MailMessage; @@ -26,7 +25,7 @@ class UserPreWarning extends Notification /** * Create a new notification instance. */ - public function __construct(public User $user, public Torrent $torrent) + public function __construct(public User $user) { } @@ -45,12 +44,10 @@ public function via(object $notifiable): array */ public function toMail(object $notifiable): MailMessage { - $profileUrl = href_profile($this->user); - return (new MailMessage()) - ->greeting('Hit and Run Pre Warning!') - ->line('You have received a hit and run pre warning on one or more torrents!') - ->action('View Unsatisfied Torrents to seed off your warnings or wait until they expire!', $profileUrl) + ->greeting('Hit and Run Pre Warning Received!') + ->line('You have received an automated hit and run PRE WARNING on one or more torrents!') + ->action('View your unsatisfied torrents and start seeding before you are issued a permanent WARNING!', route('users.history.index', ['user' => $this->user])) ->line('Thank you for using 🚀'.config('other.title')); } @@ -62,9 +59,9 @@ public function toMail(object $notifiable): MailMessage public function toArray(object $notifiable): array { return [ - 'title' => $this->torrent->name.' Pre Warning Received', - 'body' => 'You have received an automated PRE WARNING from the system because you failed to follow the Hit and Run rules in relation to Torrent '.$this->torrent->name, - 'url' => sprintf('/torrents/%s', $this->torrent->id), + 'title' => 'Hit and Run Pre Warning Received!', + 'body' => 'You have received an automated hit and run PRE WARNING on one or more torrents! View your unsatisfied torrents and start seeding before you are issued a permanent WARNING!!', + 'url' => route('users.history.index', ['user' => $this->user]), ]; } } diff --git a/app/Notifications/UserWarning.php b/app/Notifications/UserWarning.php index d46facd838..14cbdeff7d 100644 --- a/app/Notifications/UserWarning.php +++ b/app/Notifications/UserWarning.php @@ -13,7 +13,6 @@ namespace App\Notifications; -use App\Models\Torrent; use App\Models\User; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Messages\MailMessage; @@ -26,7 +25,7 @@ class UserWarning extends Notification /** * Create a new notification instance. */ - public function __construct(public User $user, public Torrent $torrent) + public function __construct(public User $user) { } @@ -45,12 +44,10 @@ public function via(object $notifiable): array */ public function toMail(object $notifiable): MailMessage { - $profileUrl = href_profile($this->user); - return (new MailMessage()) - ->greeting('Hit and Run Warning!') - ->line('You have received a hit and run warning on one or more torrents!') - ->action('View Unsatisfied Torrents to seed off your warnings or wait until they expire!', $profileUrl) + ->greeting('Hit and Run Warning Received!') + ->line('You have received an automated hit and run WARNING on one or more torrents!') + ->action('View your unsatisfied torrents and seed off your warnings or wait until they expire!', route('users.history.index', ['user' => $this->user])) ->line('Thank you for using 🚀'.config('other.title')); } @@ -62,9 +59,9 @@ public function toMail(object $notifiable): MailMessage public function toArray(object $notifiable): array { return [ - 'title' => $this->torrent->name.' Warning Received', - 'body' => 'You have received an automated WARNING from the system because you failed to follow the Hit and Run rules in relation to Torrent '.$this->torrent->name, - 'url' => sprintf('/torrents/%s', $this->torrent->id), + 'title' => 'Hit and Run Warning Received!', + 'body' => 'You have received an automated hit and run WARNING on one or more torrents! View your unsatisfied torrents and seed off your warnings or wait until they expire!', + 'url' => route('users.history.index', ['user' => $this->user]), ]; } } From 567b0c6d813e33bfdc0138897f608e36eacb1e6b Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Tue, 16 Apr 2024 00:10:31 -0400 Subject: [PATCH 30/61] fix: permission check --- resources/views/playlist/show.blade.php | 57 +++++++++++++------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/resources/views/playlist/show.blade.php b/resources/views/playlist/show.blade.php index 2b9c2d7652..33e943aada 100755 --- a/resources/views/playlist/show.blade.php +++ b/resources/views/playlist/show.blade.php @@ -11,8 +11,8 @@ @endsection -@if (auth()->id() == $playlist->user_id || auth()->user()->group->is_modo) - @section('sidebar') +@section('sidebar') + @if (auth()->id() === $playlist->user_id || auth()->user()->group->is_modo)

{{ __('common.actions') }}

@@ -102,31 +102,32 @@ class="form__button form__button--filled form__button--centered"
-
-

{{ __('common.download') }}

- -
- @endsection -@endif + @endif + +
+

{{ __('common.download') }}

+ +
+@endsection @section('main')
@@ -179,7 +180,7 @@ class="playlist__author-avatar"
- @if (auth()->id() == $playlist->user_id || auth()->user()->group->is_modo) + @if (auth()->id() === $playlist->user_id || auth()->user()->group->is_modo)
Date: Wed, 17 Apr 2024 13:42:11 +0100 Subject: [PATCH 31/61] refactor: Change input type for better 2FA inference This change improves passwd manager detection for 2FA fields, ensuring auto clipboard copying or user prompt popups. It also improves mobile usage by calling the numeric keypad for the tel-set 2FA input field, rather than a full keyboard. Tested on ProtonPass; with input type set to `text`, no clipboard copying or popup occurs, requiring manual copy-pasting. But with type `tel`, 2FA autofill features are fully activated. --- resources/views/auth/two-factor-challenge.blade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/auth/two-factor-challenge.blade.php b/resources/views/auth/two-factor-challenge.blade.php index c06c216a05..448b816178 100644 --- a/resources/views/auth/two-factor-challenge.blade.php +++ b/resources/views/auth/two-factor-challenge.blade.php @@ -81,7 +81,7 @@ class="auth-form__text-input" inputmode="numeric" name="code" x-bind:required="!recovery" - type="text" + type="tel" value="{{ old('code') }}" x-ref="code" /> @@ -96,7 +96,7 @@ class="auth-form__text-input" autocomplete="one-time-code" name="recovery_code" x-bind:required="recovery" - type="text" + type="tel" x-ref="recovery_code" />

From 9bd216e227d5858259285e9239e2c5d5fce11484 Mon Sep 17 00:00:00 2001 From: EkoNesLeg <155665062+EkoNesLeg@users.noreply.github.com> Date: Wed, 17 Apr 2024 16:47:52 +0100 Subject: [PATCH 32/61] (Update) two-factor-challenge.blade.php Remove `tel` from the recovery-code form as codes are alphanumeric and passwd manager compatibility is not relevant. Added additional contraints to the input elements to prevent auto capping, autocorrect, spellcheck. Also added aria element for screenreader compatibility. --- .../views/auth/two-factor-challenge.blade.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/resources/views/auth/two-factor-challenge.blade.php b/resources/views/auth/two-factor-challenge.blade.php index 448b816178..6a9a7e7b5e 100644 --- a/resources/views/auth/two-factor-challenge.blade.php +++ b/resources/views/auth/two-factor-challenge.blade.php @@ -80,6 +80,13 @@ class="auth-form__text-input" autofocus inputmode="numeric" name="code" + inputmode="numeric" + autocomplete="one-time-code" + autocapitalize="off" + autocorrect="off" + spellcheck="false" + aria-invalid="false" + aria-label="Enter verification code" x-bind:required="!recovery" type="tel" value="{{ old('code') }}" @@ -95,8 +102,13 @@ class="auth-form__text-input" class="auth-form__text-input" autocomplete="one-time-code" name="recovery_code" + autocomplete="off" + autocapitalize="off" + autocorrect="off" + spellcheck="false" + aria-invalid="false" x-bind:required="recovery" - type="tel" + type="text" x-ref="recovery_code" />

From 134e5f0fde1f392f90cb21fc7210682ae120399c Mon Sep 17 00:00:00 2001 From: EkoNesLeg <155665062+EkoNesLeg@users.noreply.github.com> Date: Wed, 17 Apr 2024 17:11:12 +0100 Subject: [PATCH 33/61] update: two-factor-challenge.blade.php ARIA element's deleted per core-dev's request; dupe attirbutes removed too. --- resources/views/auth/two-factor-challenge.blade.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/resources/views/auth/two-factor-challenge.blade.php b/resources/views/auth/two-factor-challenge.blade.php index 6a9a7e7b5e..6b6fa6e9f9 100644 --- a/resources/views/auth/two-factor-challenge.blade.php +++ b/resources/views/auth/two-factor-challenge.blade.php @@ -80,13 +80,9 @@ class="auth-form__text-input" autofocus inputmode="numeric" name="code" - inputmode="numeric" - autocomplete="one-time-code" autocapitalize="off" autocorrect="off" spellcheck="false" - aria-invalid="false" - aria-label="Enter verification code" x-bind:required="!recovery" type="tel" value="{{ old('code') }}" @@ -100,13 +96,11 @@ class="auth-form__text-input" Date: Wed, 17 Apr 2024 13:54:58 -0400 Subject: [PATCH 34/61] fix: primary language metadata class Primary language meta class changed from "runtime" to "language" --- resources/views/torrent/partials/movie_meta.blade.php | 2 +- resources/views/torrent/partials/tv_meta.blade.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/torrent/partials/movie_meta.blade.php b/resources/views/torrent/partials/movie_meta.blade.php index 078495c349..dfc799088c 100755 --- a/resources/views/torrent/partials/movie_meta.blade.php +++ b/resources/views/torrent/partials/movie_meta.blade.php @@ -250,7 +250,7 @@ class="{{ config('other.font-awesome') }} fa-theater-masks meta-chip__icon" @endif -
+ @endif -
+

Primary Language

From 41db02b0ac979517d4796e044531ac3ed739efd7 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Wed, 17 Apr 2024 19:29:49 -0400 Subject: [PATCH 35/61] add: request #3745 - closes #3745 --- app/Http/Livewire/TorrentRequestSearch.php | 16 ++-- .../livewire/torrent-request-search.blade.php | 86 ++++++++++++++++++- 2 files changed, 91 insertions(+), 11 deletions(-) diff --git a/app/Http/Livewire/TorrentRequestSearch.php b/app/Http/Livewire/TorrentRequestSearch.php index 464e148776..d3efb00ab1 100644 --- a/app/Http/Livewire/TorrentRequestSearch.php +++ b/app/Http/Livewire/TorrentRequestSearch.php @@ -62,6 +62,12 @@ class TorrentRequestSearch extends Component #[Url(history: true)] public array $genres = []; + /** + * @var string[] + */ + #[Url(history: true)] + public array $primaryLanguages = []; + #[Url(history: true)] public ?int $tmdbId = null; @@ -107,19 +113,11 @@ class TorrentRequestSearch extends Component #[Url(history: true)] public string $sortDirection = 'desc'; - #[Url(history: true)] - public bool $showFilters = false; - final public function updating(string $field, mixed &$value): void { $this->castLivewireProperties($field, $value); } - final public function toggleShowFilters(): void - { - $this->showFilters = !$this->showFilters; - } - #[Computed] final public function torrentRequestStat(): ?object { @@ -165,6 +163,8 @@ final public function torrentRequests(): \Illuminate\Contracts\Pagination\Length ->when($this->imdbId !== '', fn ($query) => $query->ofImdb((int) (preg_match('/tt0*(?=(\d{7,}))/', $this->imdbId, $matches) ? $matches[1] : $this->imdbId))) ->when($this->tvdbId !== null, fn ($query) => $query->ofTvdb((int) $this->tvdbId)) ->when($this->malId !== null, fn ($query) => $query->ofMal((int) $this->malId)) + ->when($this->genres !== [], fn ($query) => $query->ofGenre($this->genres)) + ->when($this->primaryLanguages !== [], fn ($query) => $query->ofPrimaryLanguage($this->primaryLanguages)) ->when($this->unfilled || $this->claimed || $this->pending || $this->filled, function ($query): void { $query->where(function ($query): void { $query->where(function ($query): void { diff --git a/resources/views/livewire/torrent-request-search.blade.php b/resources/views/livewire/torrent-request-search.blade.php index 5359775769..9433ddb3fa 100644 --- a/resources/views/livewire/torrent-request-search.blade.php +++ b/resources/views/livewire/torrent-request-search.blade.php @@ -205,7 +205,14 @@ class="form__text"
{{ __('torrent.category') }}
- @foreach (App\Models\Category::select(['id', 'name', 'position'])->orderBy('position')->get() as $category) + @php + $categories = cache()->remember( + 'categories', + 3_600, + fn () => App\Models\Category::orderBy('position')->get() + ) + @endphp + @foreach ($categories as $category)

- @foreach (App\Models\Type::select(['id', 'name', 'position'])->orderBy('position')->get() as $type) + @php + $types = cache()->remember( + 'types', + 3_600, + fn () => App\Models\Type::orderBy('position')->get() + ) + @endphp + @foreach ($types as $type)

- @foreach (App\Models\Resolution::select(['id', 'name', 'position'])->orderBy('position')->get() as $resolution) + @php + $resolutions = cache()->remember( + 'resolutions', + 3_600, + fn () => App\Models\Resolution::orderBy('position')->get() + ) + @endphp + @foreach ($resolutions as $resolution)

+
+
+ {{ __('torrent.genre') }} +
+ @php + $genres = cache()->remember( + 'genres', + 3_600, + fn () => App\Models\Genre::orderBy('name')->get() + ) + @endphp + + @foreach ($genres as $genre) +

+ +

+ @endforeach +
+
+
+
+
+ Primary Language +
+ @php + $primaryLanguages = cache()->remember( + 'torrent-search:languages', + 3600, + fn () => App\Models\Movie::select('original_language') + ->distinct() + ->orderBy('original_language') + ->pluck('original_language') + ) + @endphp + + @foreach ($primaryLanguages as $primaryLanguage) +

+ +

+ @endforeach +
+
+
{{ __('common.status') }} From b27c533c72cfb86dec48a1aa3b9118c11ba81077 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Wed, 17 Apr 2024 23:30:49 +0000 Subject: [PATCH 36/61] Blade Style Change (Prettier Blade CI) --- resources/views/livewire/torrent-request-search.blade.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/views/livewire/torrent-request-search.blade.php b/resources/views/livewire/torrent-request-search.blade.php index 9433ddb3fa..39b3d7d1ae 100644 --- a/resources/views/livewire/torrent-request-search.blade.php +++ b/resources/views/livewire/torrent-request-search.blade.php @@ -212,6 +212,7 @@ class="form__text" fn () => App\Models\Category::orderBy('position')->get() ) @endphp + @foreach ($categories as $category)

@php $connectable = null; - if (cache()->has('peers:connectable:' . $active->ip . '-' . $active->port . '-' . $active->agent)) { + if (config('announce.external_tracker.is_enabled')) { + $connectable = $active->connectable; + } elseif (cache()->has('peers:connectable:' . $active->ip . '-' . $active->port . '-' . $active->agent)) { $connectable = cache()->get('peers:connectable:' . $active->ip . '-' . $active->port . '-' . $active->agent); } @endphp diff --git a/resources/views/torrent/peers.blade.php b/resources/views/torrent/peers.blade.php index 1d2092f309..03d1ae38f1 100644 --- a/resources/views/torrent/peers.blade.php +++ b/resources/views/torrent/peers.blade.php @@ -106,7 +106,9 @@ class="nav-tab__link" @if (\config('announce.connectable_check') == true) @php $connectable = false; - if (cache()->has('peers:connectable:' . $peer->ip . '-' . $peer->port . '-' . $peer->agent)) { + if (config('announce.external_tracker.is_enabled')) { + $connectable = $peer->connectable; + } elseif (cache()->has('peers:connectable:' . $peer->ip . '-' . $peer->port . '-' . $peer->agent)) { $connectable = cache()->get('peers:connectable:' . $peer->ip . '-' . $peer->port . '-' . $peer->agent); } @endphp diff --git a/resources/views/user/profile/show.blade.php b/resources/views/user/profile/show.blade.php index 74a35ec206..bd045c8109 100644 --- a/resources/views/user/profile/show.blade.php +++ b/resources/views/user/profile/show.blade.php @@ -303,7 +303,9 @@ class="user-search__avatar" @if (\config('announce.connectable_check') == true) @php $connectable = false; - if (cache()->has('peers:connectable:' . $client->ip . '-' . $client->port . '-' . $client->agent)) { + if (config('announce.external_tracker.is_enabled')) { + $connectable = $client->connectable; + } elseif (cache()->has('peers:connectable:' . $client->ip . '-' . $client->port . '-' . $client->agent)) { $connectable = cache()->get('peers:connectable:' . $client->ip . '-' . $client->port . '-' . $client->agent); } @endphp From b4f402a78247be08b5617e2256a6f7593c33c861 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Fri, 19 Apr 2024 11:07:24 -0400 Subject: [PATCH 41/61] fix: user profile - broken in https://github.com/HDInnovations/UNIT3D-Community-Edition/pull/3754 --- resources/views/user/profile/show.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/user/profile/show.blade.php b/resources/views/user/profile/show.blade.php index bd045c8109..96933c1690 100644 --- a/resources/views/user/profile/show.blade.php +++ b/resources/views/user/profile/show.blade.php @@ -926,7 +926,7 @@ class="{{ $user->last_action }}"
{{ __('user.can-invite') }}
- @if ($user->can_invite == 1 && user->two_factor_confirmed_at !== null) + @if ($user->can_invite == 1 && $user->two_factor_confirmed_at !== null) @else From c5377ae96b5bf0615332f60c27dd316fd99dc5ae Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Fri, 19 Apr 2024 11:28:11 -0400 Subject: [PATCH 42/61] fix: top_users.blade.php --- resources/views/blocks/top_users.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/blocks/top_users.blade.php b/resources/views/blocks/top_users.blade.php index 555ea2ee51..88f21d1b15 100644 --- a/resources/views/blocks/top_users.blade.php +++ b/resources/views/blocks/top_users.blade.php @@ -401,7 +401,7 @@ class="user-stat-card__avatar" {{ App\Helpers\StringHelper::ordinal($loop->iteration) }} -

{{ $uploader->value }} Personal Releases

+

{{ $personal->value }} Personal Releases

@if ($personal->user->private_profile) Date: Sat, 20 Apr 2024 01:03:27 +0000 Subject: [PATCH 43/61] fix: refresh the torrent before sending to external tracker We need to populate the status, seeders, leechers, and times_completed fields. --- app/Http/Controllers/API/TorrentController.php | 3 +++ app/Http/Controllers/TorrentController.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/app/Http/Controllers/API/TorrentController.php b/app/Http/Controllers/API/TorrentController.php index 3c31bef6b6..1c0dabb82d 100644 --- a/app/Http/Controllers/API/TorrentController.php +++ b/app/Http/Controllers/API/TorrentController.php @@ -314,6 +314,9 @@ public function store(Request $request): \Illuminate\Http\JsonResponse // Save The Torrent $torrent->save(); + // Populate the status/seeders/leechers/times_completed fields for the external tracker + $torrent->refresh(); + Unit3dAnnounce::addTorrent($torrent); if ($torrent->featured) { diff --git a/app/Http/Controllers/TorrentController.php b/app/Http/Controllers/TorrentController.php index 92d69eab75..10afaef78b 100644 --- a/app/Http/Controllers/TorrentController.php +++ b/app/Http/Controllers/TorrentController.php @@ -408,6 +408,9 @@ public function store(StoreTorrentRequest $request): \Illuminate\Http\RedirectRe 'moderated_by' => User::SYSTEM_USER_ID, ] + $request->safe()->except(['torrent'])); + // Populate the status/seeders/leechers/times_completed fields for the external tracker + $torrent->refresh(); + Unit3dAnnounce::addTorrent($torrent); if ($torrent->getAttribute('featured')) { From 9d8621fc3cd988ce242ee802050dd16366ff74fc Mon Sep 17 00:00:00 2001 From: Roardom Date: Sat, 20 Apr 2024 02:24:26 +0000 Subject: [PATCH 44/61] fix: ci `featured` is both an attribute and a relation. Using `getAttribute`, we always prioritize the attribute, which seems to satisfy CI. --- app/Http/Controllers/API/TorrentController.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/API/TorrentController.php b/app/Http/Controllers/API/TorrentController.php index 1c0dabb82d..37e7a7ee81 100644 --- a/app/Http/Controllers/API/TorrentController.php +++ b/app/Http/Controllers/API/TorrentController.php @@ -319,12 +319,12 @@ public function store(Request $request): \Illuminate\Http\JsonResponse Unit3dAnnounce::addTorrent($torrent); - if ($torrent->featured) { + if ($torrent->getAttribute('featured')) { Unit3dAnnounce::addFeaturedTorrent($torrent->id); } // Set torrent to featured - if ($torrent->featured == 1) { + if ($torrent->getAttribute('featured')) { $featuredTorrent = new FeaturedTorrent(); $featuredTorrent->user_id = $user->id; $featuredTorrent->torrent_id = $torrent->id; @@ -375,7 +375,7 @@ public function store(Request $request): \Illuminate\Http\JsonResponse $user = $torrent->user; $username = $user->username; $anon = $torrent->anon; - $featured = $torrent->featured; + $featured = $torrent->getAttribute('featured'); $free = $torrent->free; $doubleup = $torrent->doubleup; From 4444d9ce5b63f1cba5236726c09e189a624b7e7c Mon Sep 17 00:00:00 2001 From: Audionut Date: Sun, 21 Apr 2024 13:18:05 +0000 Subject: [PATCH 45/61] API - expose options Expose featured and personal_release --- app/Http/Resources/TorrentResource.php | 46 ++++++++++++++------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/app/Http/Resources/TorrentResource.php b/app/Http/Resources/TorrentResource.php index f8a4a634f0..e99f654f41 100644 --- a/app/Http/Resources/TorrentResource.php +++ b/app/Http/Resources/TorrentResource.php @@ -51,28 +51,30 @@ public function toArray($request): array 'name' => $file->name, 'size' => $file->size, ]), - 'freeleech' => $this->free.'%', - 'double_upload' => $this->doubleup, - 'refundable' => $this->refundable, - 'internal' => $this->internal, - 'uploader' => $this->anon ? 'Anonymous' : $this->user->username, - 'seeders' => $this->seeders, - 'leechers' => $this->leechers, - 'times_completed' => $this->times_completed, - 'tmdb_id' => $this->tmdb, - 'imdb_id' => $this->imdb, - 'tvdb_id' => $this->tvdb, - 'mal_id' => $this->mal, - 'igdb_id' => $this->igdb, - 'category_id' => $this->category_id, - 'type_id' => $this->type_id, - 'resolution_id' => $this->when($this->resolution_id !== null, $this->resolution_id), - 'distributor_id' => $this->when($this->distributor_id !== null, $this->distributor_id), - 'region_id' => $this->when($this->region_id !== null, $this->region_id), - 'created_at' => $this->created_at, - 'download_link' => route('torrent.download.rsskey', ['id' => $this->id, 'rsskey' => auth('api')->user()->rsskey]), - 'magnet_link' => $this->when(config('torrent.magnet') === true, 'magnet:?dn='.$this->name.'&xt=urn:btih:'.bin2hex($this->info_hash).'&as='.route('torrent.download.rsskey', ['id' => $this->id, 'rsskey' => auth('api')->user()->rsskey]).'&tr='.route('announce', ['passkey' => auth('api')->user()->passkey]).'&xl='.$this->size), - 'details_link' => route('torrents.show', ['id' => $this->id]), + 'freeleech' => $this->free.'%', + 'double_upload' => $this->doubleup, + 'refundable' => $this->refundable, + 'internal' => $this->internal, + 'featured' => $this->featured, + 'personal_release' => $this->personal_release, + 'uploader' => $this->anon ? 'Anonymous' : $this->user->username, + 'seeders' => $this->seeders, + 'leechers' => $this->leechers, + 'times_completed' => $this->times_completed, + 'tmdb_id' => $this->tmdb, + 'imdb_id' => $this->imdb, + 'tvdb_id' => $this->tvdb, + 'mal_id' => $this->mal, + 'igdb_id' => $this->igdb, + 'category_id' => $this->category_id, + 'type_id' => $this->type_id, + 'resolution_id' => $this->when($this->resolution_id !== null, $this->resolution_id), + 'distributor_id' => $this->when($this->distributor_id !== null, $this->distributor_id), + 'region_id' => $this->when($this->region_id !== null, $this->region_id), + 'created_at' => $this->created_at, + 'download_link' => route('torrent.download.rsskey', ['id' => $this->id, 'rsskey' => auth('api')->user()->rsskey]), + 'magnet_link' => $this->when(config('torrent.magnet') === true, 'magnet:?dn='.$this->name.'&xt=urn:btih:'.bin2hex($this->info_hash).'&as='.route('torrent.download.rsskey', ['id' => $this->id, 'rsskey' => auth('api')->user()->rsskey]).'&tr='.route('announce', ['passkey' => auth('api')->user()->passkey]).'&xl='.$this->size), + 'details_link' => route('torrents.show', ['id' => $this->id]), ], ]; } From 4bcc9cbf13d3eb6004b07086d3dfefef3a86d267 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Mon, 22 Apr 2024 15:11:50 -0400 Subject: [PATCH 46/61] add: bluray.com support --- public/img/meta/bluray.svg | 3 ++ resources/sass/components/_meta.scss | 4 +- .../torrent/partials/movie_meta.blade.php | 13 +++++ .../views/torrent/partials/tv_meta.blade.php | 53 ++++++++++++------- 4 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 public/img/meta/bluray.svg diff --git a/public/img/meta/bluray.svg b/public/img/meta/bluray.svg new file mode 100644 index 0000000000..6e833e0c73 --- /dev/null +++ b/public/img/meta/bluray.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/sass/components/_meta.scss b/resources/sass/components/_meta.scss index 40738dfffe..2af062c031 100644 --- a/resources/sass/components/_meta.scss +++ b/resources/sass/components/_meta.scss @@ -204,7 +204,7 @@ display: flex; column-gap: 0; list-style-type: none; - margin: 0; + margin: -10px; padding: 0; @media screen and (max-width: 480px) { @@ -215,7 +215,7 @@ .meta-id-tag { color: var(--meta-id-tag-fg); - font-size: 20px; + font-size: 25px; display: inline-block; padding: 0 10px; white-space: nowrap; diff --git a/resources/views/torrent/partials/movie_meta.blade.php b/resources/views/torrent/partials/movie_meta.blade.php index e3f7c99684..0306b50a11 100755 --- a/resources/views/torrent/partials/movie_meta.blade.php +++ b/resources/views/torrent/partials/movie_meta.blade.php @@ -160,6 +160,19 @@ class="fad fa-tomato" @endif + + @if ($meta->imdb_id ?? 0 > 0) +
  • + + + +
  • + @endif

    {{ $meta?->overview }}

    diff --git a/resources/views/torrent/partials/tv_meta.blade.php b/resources/views/torrent/partials/tv_meta.blade.php index 9360f34fa7..22ccc75c65 100755 --- a/resources/views/torrent/partials/tv_meta.blade.php +++ b/resources/views/torrent/partials/tv_meta.blade.php @@ -138,25 +138,40 @@ class="meta-id-tag" @endif -
  • - - - -
  • + @if ($meta->id ?? 0 > 0) +
  • + + + +
  • + @endif + + @if ($meta->imdb_id ?? 0 > 0) +
  • + + + +
  • + @endif

    {{ $meta?->overview }}

    From 6e4be4d83be73eb12b5eefb538129eeb6a170341 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Mon, 22 Apr 2024 15:22:22 -0400 Subject: [PATCH 47/61] chore: pint --- app/Http/Resources/TorrentResource.php | 48 +++++++++++++------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/app/Http/Resources/TorrentResource.php b/app/Http/Resources/TorrentResource.php index e99f654f41..14edfc8f77 100644 --- a/app/Http/Resources/TorrentResource.php +++ b/app/Http/Resources/TorrentResource.php @@ -51,30 +51,30 @@ public function toArray($request): array 'name' => $file->name, 'size' => $file->size, ]), - 'freeleech' => $this->free.'%', - 'double_upload' => $this->doubleup, - 'refundable' => $this->refundable, - 'internal' => $this->internal, - 'featured' => $this->featured, - 'personal_release' => $this->personal_release, - 'uploader' => $this->anon ? 'Anonymous' : $this->user->username, - 'seeders' => $this->seeders, - 'leechers' => $this->leechers, - 'times_completed' => $this->times_completed, - 'tmdb_id' => $this->tmdb, - 'imdb_id' => $this->imdb, - 'tvdb_id' => $this->tvdb, - 'mal_id' => $this->mal, - 'igdb_id' => $this->igdb, - 'category_id' => $this->category_id, - 'type_id' => $this->type_id, - 'resolution_id' => $this->when($this->resolution_id !== null, $this->resolution_id), - 'distributor_id' => $this->when($this->distributor_id !== null, $this->distributor_id), - 'region_id' => $this->when($this->region_id !== null, $this->region_id), - 'created_at' => $this->created_at, - 'download_link' => route('torrent.download.rsskey', ['id' => $this->id, 'rsskey' => auth('api')->user()->rsskey]), - 'magnet_link' => $this->when(config('torrent.magnet') === true, 'magnet:?dn='.$this->name.'&xt=urn:btih:'.bin2hex($this->info_hash).'&as='.route('torrent.download.rsskey', ['id' => $this->id, 'rsskey' => auth('api')->user()->rsskey]).'&tr='.route('announce', ['passkey' => auth('api')->user()->passkey]).'&xl='.$this->size), - 'details_link' => route('torrents.show', ['id' => $this->id]), + 'freeleech' => $this->free.'%', + 'double_upload' => $this->doubleup, + 'refundable' => $this->refundable, + 'internal' => $this->internal, + 'featured' => $this->featured, + 'personal_release' => $this->personal_release, + 'uploader' => $this->anon ? 'Anonymous' : $this->user->username, + 'seeders' => $this->seeders, + 'leechers' => $this->leechers, + 'times_completed' => $this->times_completed, + 'tmdb_id' => $this->tmdb, + 'imdb_id' => $this->imdb, + 'tvdb_id' => $this->tvdb, + 'mal_id' => $this->mal, + 'igdb_id' => $this->igdb, + 'category_id' => $this->category_id, + 'type_id' => $this->type_id, + 'resolution_id' => $this->when($this->resolution_id !== null, $this->resolution_id), + 'distributor_id' => $this->when($this->distributor_id !== null, $this->distributor_id), + 'region_id' => $this->when($this->region_id !== null, $this->region_id), + 'created_at' => $this->created_at, + 'download_link' => route('torrent.download.rsskey', ['id' => $this->id, 'rsskey' => auth('api')->user()->rsskey]), + 'magnet_link' => $this->when(config('torrent.magnet') === true, 'magnet:?dn='.$this->name.'&xt=urn:btih:'.bin2hex($this->info_hash).'&as='.route('torrent.download.rsskey', ['id' => $this->id, 'rsskey' => auth('api')->user()->rsskey]).'&tr='.route('announce', ['passkey' => auth('api')->user()->passkey]).'&xl='.$this->size), + 'details_link' => route('torrents.show', ['id' => $this->id]), ], ]; } From 51fa8ec46b3e9521979680335b0652ee24597673 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Tue, 23 Apr 2024 16:06:37 -0400 Subject: [PATCH 48/61] update: laravel - Laravel 11 introduces a new default application structure with fewer default files. Namely, new Laravel applications contain fewer service providers, middleware, and configuration files. However, it is not recommend that Laravel 10 applications upgrading to Laravel 11 attempt to migrate their application structure, as Laravel 11 has been carefully tuned to also support the Laravel 10 application structure. --- .env.example | 4 +- app/Console/Commands/AutoRefundDownload.php | 4 +- app/Http/Controllers/Controller.php | 2 +- app/Models/Apikey.php | 13 +- app/Models/Application.php | 14 +- app/Models/BonExchange.php | 19 +- app/Models/Bot.php | 20 +- app/Models/BotTransaction.php | 7 - app/Models/Category.php | 19 +- app/Models/EmailUpdate.php | 15 +- app/Models/ForumPermission.php | 17 +- app/Models/Gift.php | 13 +- app/Models/Group.php | 13 +- app/Models/History.php | 17 +- app/Models/Like.php | 15 +- app/Models/Passkey.php | 13 +- app/Models/Peer.php | 17 +- app/Models/PostTip.php | 13 +- app/Models/Resurrection.php | 13 +- app/Models/Rss.php | 24 +- app/Models/Rsskey.php | 13 +- app/Models/Subtitle.php | 14 +- app/Models/Ticket.php | 18 +- app/Models/Topic.php | 32 +- app/Models/Torrent.php | 29 +- app/Models/TorrentRequest.php | 25 +- app/Models/TorrentTip.php | 13 +- app/Models/User.php | 37 +- app/Models/UserAudible.php | 7 - app/Models/UserEcho.php | 7 - app/Models/UserNotification.php | 27 +- app/Models/UserPrivacy.php | 33 +- app/Models/Warning.php | 13 +- artisan | 50 +- bun.lockb | Bin 390106 -> 394405 bytes composer.json | 17 +- composer.lock | 1016 ++++++++++--------- config/database.php | 11 +- package.json | 4 +- public/index.php | 48 +- 40 files changed, 842 insertions(+), 844 deletions(-) diff --git a/.env.example b/.env.example index d26a7e4e96..ccca79796b 100644 --- a/.env.example +++ b/.env.example @@ -17,8 +17,8 @@ DB_USERNAME=root DB_PASSWORD= #PRISTINE_DB_FILE=/home/vagrant/code/database/unit3d_test.sql -BROADCAST_DRIVER=redis -CACHE_DRIVER=redis +BROADCAST_CONNECTION=redis +CACHE_STORE=redis SESSION_DRIVER=redis SESSION_CONNECTION=session SESSION_LIFETIME=120 diff --git a/app/Console/Commands/AutoRefundDownload.php b/app/Console/Commands/AutoRefundDownload.php index 78a156268e..e828a3fdc9 100644 --- a/app/Console/Commands/AutoRefundDownload.php +++ b/app/Console/Commands/AutoRefundDownload.php @@ -36,10 +36,8 @@ class AutoRefundDownload extends Command /** * Execute the console command. - * - * @return mixed */ - public function handle() + public function handle(): void { $now = Carbon::now(); $MIN_SEEDTIME = config('hitrun.seedtime'); diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index f4bfce53ee..96b99ca1c0 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -17,7 +17,7 @@ use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; -class Controller extends BaseController +abstract class Controller extends BaseController { use AuthorizesRequests; use ValidatesRequests; diff --git a/app/Models/Apikey.php b/app/Models/Apikey.php index 1d6da4f555..1bb34d227b 100644 --- a/app/Models/Apikey.php +++ b/app/Models/Apikey.php @@ -41,13 +41,16 @@ class Apikey extends Model protected $guarded = ['id']; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'deleted_at' => 'datetime', - ]; + protected function casts(): array + { + return [ + 'deleted_at' => 'datetime', + ]; + } /** * Belongs to a user. diff --git a/app/Models/Application.php b/app/Models/Application.php index 9c3b1fdd9a..c33ba21f6d 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -52,9 +52,17 @@ class Application extends Model 'moderated_at', ]; - protected $casts = [ - 'moderated_at' => 'datetime', - ]; + /** + * Get the attributes that should be cast. + * + * @return array + */ + protected function casts(): array + { + return [ + 'moderated_at' => 'datetime', + ]; + } /** * The attributes that aren't mass assignable. diff --git a/app/Models/BonExchange.php b/app/Models/BonExchange.php index 645ff8591e..c86432af7b 100644 --- a/app/Models/BonExchange.php +++ b/app/Models/BonExchange.php @@ -40,16 +40,19 @@ class BonExchange extends Model public $timestamps = false; /** - * The Attributes That Should Be Casted To Native Types. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'upload' => 'boolean', - 'download' => 'boolean', - 'personal_freeleech' => 'boolean', - 'invite' => 'boolean', - ]; + protected function casts(): array + { + return [ + 'upload' => 'boolean', + 'download' => 'boolean', + 'personal_freeleech' => 'boolean', + 'invite' => 'boolean', + ]; + } /** * The attributes that aren't mass assignable. diff --git a/app/Models/Bot.php b/app/Models/Bot.php index 92afed892f..dbdc351e06 100644 --- a/app/Models/Bot.php +++ b/app/Models/Bot.php @@ -51,20 +51,16 @@ class Bot extends Model use HasFactory; /** - * Indicates If The Model Should Be Timestamped. + * Get the attributes that should be cast. * - * @var bool + * @return array */ - public $timestamps = true; - - /** - * The Attributes That Should Be Cast To Native Types. - * - * @var array - */ - protected $casts = [ - 'name' => 'string', - ]; + protected function casts(): array + { + return [ + 'name' => 'string', + ]; + } /** * The attributes that aren't mass assignable. diff --git a/app/Models/BotTransaction.php b/app/Models/BotTransaction.php index 0d60790f2f..2eb0988d96 100644 --- a/app/Models/BotTransaction.php +++ b/app/Models/BotTransaction.php @@ -36,13 +36,6 @@ class BotTransaction extends Model use Auditable; use HasFactory; - /** - * Indicates If The Model Should Be Timestamped. - * - * @var bool - */ - public $timestamps = true; - /** * Belongs To A User. * diff --git a/app/Models/Category.php b/app/Models/Category.php index df538ef228..d37502464b 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -45,16 +45,19 @@ class Category extends Model public $timestamps = false; /** - * The Attributes That Should Be Mutated To Dates. + * Get the attributes that should be cast. * - * @var array + * @return array */ - public $casts = [ - 'music_meta' => 'boolean', - 'game_meta' => 'boolean', - 'tv_meta' => 'boolean', - 'movie_meta' => 'boolean', - ]; + protected function casts(): array + { + return [ + 'music_meta' => 'boolean', + 'game_meta' => 'boolean', + 'tv_meta' => 'boolean', + 'movie_meta' => 'boolean', + ]; + } /** * The attributes that aren't mass assignable. diff --git a/app/Models/EmailUpdate.php b/app/Models/EmailUpdate.php index e695d007bd..0b805a0995 100644 --- a/app/Models/EmailUpdate.php +++ b/app/Models/EmailUpdate.php @@ -40,14 +40,17 @@ class EmailUpdate extends Model protected $guarded = ['id']; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'created_at' => 'datetime', - 'deleted_at' => 'datetime', - ]; + protected function casts(): array + { + return [ + 'created_at' => 'datetime', + 'deleted_at' => 'datetime', + ]; + } /** * Belongs to a user. diff --git a/app/Models/ForumPermission.php b/app/Models/ForumPermission.php index 8fd6a2bde5..6b92e15265 100644 --- a/app/Models/ForumPermission.php +++ b/app/Models/ForumPermission.php @@ -42,15 +42,18 @@ class ForumPermission extends Model public $guarded = []; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'read_topic' => 'boolean', - 'reply_topic' => 'boolean', - 'start_topic' => 'boolean', - ]; + protected function casts(): array + { + return [ + 'read_topic' => 'boolean', + 'reply_topic' => 'boolean', + 'start_topic' => 'boolean', + ]; + } /** * Belongs To A Group. diff --git a/app/Models/Gift.php b/app/Models/Gift.php index 2a0d0445e9..66d1b656f3 100644 --- a/app/Models/Gift.php +++ b/app/Models/Gift.php @@ -32,13 +32,16 @@ class Gift extends Model public $timestamps = false; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'created_at' => 'datetime', - ]; + protected function casts(): array + { + return [ + 'created_at' => 'datetime', + ]; + } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo diff --git a/app/Models/Group.php b/app/Models/Group.php index e49f975b3b..b366cc613a 100644 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -56,13 +56,16 @@ class Group extends Model use HasFactory; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'system_required' => 'boolean', - ]; + protected function casts(): array + { + return [ + 'system_required' => 'boolean', + ]; + } /** * The attributes that aren't mass assignable. diff --git a/app/Models/History.php b/app/Models/History.php index 51490bc0d0..24a3cc43bc 100644 --- a/app/Models/History.php +++ b/app/Models/History.php @@ -57,15 +57,18 @@ class History extends Model protected $guarded = []; /** - * The Attributes That Should Be Mutated To Dates. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'completed_at' => 'datetime', - 'hitrun' => 'boolean', - 'prewarn' => 'boolean', - ]; + protected function casts(): array + { + return [ + 'completed_at' => 'datetime', + 'hitrun' => 'boolean', + 'prewarn' => 'boolean', + ]; + } /** * Belongs To A User. diff --git a/app/Models/Like.php b/app/Models/Like.php index 82d8b00682..f67b53ec0b 100644 --- a/app/Models/Like.php +++ b/app/Models/Like.php @@ -34,14 +34,17 @@ class Like extends Model use HasFactory; /** - * The Attributes That Should Be Mutated To Dates. + * Get the attributes that should be cast. * - * @var array + * @return array */ - public $casts = [ - 'like' => 'boolean', - 'dislike' => 'boolean', - ]; + protected function casts(): array + { + return [ + 'like' => 'boolean', + 'dislike' => 'boolean', + ]; + } /** * Belongs To A User. diff --git a/app/Models/Passkey.php b/app/Models/Passkey.php index f41257998b..be2d3204d7 100644 --- a/app/Models/Passkey.php +++ b/app/Models/Passkey.php @@ -41,13 +41,16 @@ class Passkey extends Model protected $guarded = ['id']; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'deleted_at' => 'datetime', - ]; + protected function casts(): array + { + return [ + 'deleted_at' => 'datetime', + ]; + } /** * Has Many Torrents. diff --git a/app/Models/Peer.php b/app/Models/Peer.php index 2a9f61c085..399e498574 100644 --- a/app/Models/Peer.php +++ b/app/Models/Peer.php @@ -41,15 +41,18 @@ class Peer extends Model use HasFactory; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'active' => 'boolean', - 'seeder' => 'boolean', - 'connectable' => 'boolean', - ]; + protected function casts(): array + { + return [ + 'active' => 'boolean', + 'seeder' => 'boolean', + 'connectable' => 'boolean', + ]; + } /** * Prepare a date for array / JSON serialization. diff --git a/app/Models/PostTip.php b/app/Models/PostTip.php index e63ef5f192..2d97eea486 100644 --- a/app/Models/PostTip.php +++ b/app/Models/PostTip.php @@ -32,13 +32,16 @@ class PostTip extends Model public $timestamps = false; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'created_at' => 'datetime', - ]; + protected function casts(): array + { + return [ + 'created_at' => 'datetime', + ]; + } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo diff --git a/app/Models/Resurrection.php b/app/Models/Resurrection.php index 8ef0e19294..63123f299a 100644 --- a/app/Models/Resurrection.php +++ b/app/Models/Resurrection.php @@ -41,13 +41,16 @@ class Resurrection extends Model protected $guarded = []; /** - * The Attributes That Should Be Mutated To Dates. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'rewarded' => 'boolean', - ]; + protected function casts(): array + { + return [ + 'rewarded' => 'boolean', + ]; + } /** * Belongs To A User. diff --git a/app/Models/Rss.php b/app/Models/Rss.php index 4bb9bdc942..c6447a7927 100644 --- a/app/Models/Rss.php +++ b/app/Models/Rss.php @@ -47,22 +47,18 @@ class Rss extends Model protected $table = 'rss'; /** - * Indicates If The Model Should Be Timestamped. + * Get the attributes that should be cast. * - * @var bool + * @return array */ - public $timestamps = true; - - /** - * The Attributes That Should Be Cast To Native Types. - * - * @var array - */ - protected $casts = [ - 'name' => 'string', - 'json_torrent' => 'array', - 'expected_fields' => 'array', - ]; + protected function casts(): array + { + return [ + 'name' => 'string', + 'json_torrent' => 'array', + 'expected_fields' => 'array', + ]; + } /** * The attributes that aren't mass assignable. diff --git a/app/Models/Rsskey.php b/app/Models/Rsskey.php index b31454c9dc..149d3a857b 100644 --- a/app/Models/Rsskey.php +++ b/app/Models/Rsskey.php @@ -41,13 +41,16 @@ class Rsskey extends Model protected $guarded = ['id']; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'deleted_at' => 'datetime', - ]; + protected function casts(): array + { + return [ + 'deleted_at' => 'datetime', + ]; + } /** * Belongs to a user. diff --git a/app/Models/Subtitle.php b/app/Models/Subtitle.php index 5e5fddf0be..463dfa3f4a 100644 --- a/app/Models/Subtitle.php +++ b/app/Models/Subtitle.php @@ -49,9 +49,17 @@ class Subtitle extends Model protected $guarded = []; - protected $casts = [ - 'moderated_at' => 'datetime', - ]; + /** + * Get the attributes that should be cast. + * + * @return array + */ + protected function casts(): array + { + return [ + 'moderated_at' => 'datetime', + ]; + } protected static function booted(): void { diff --git a/app/Models/Ticket.php b/app/Models/Ticket.php index 4a5102edc0..f0f639e397 100644 --- a/app/Models/Ticket.php +++ b/app/Models/Ticket.php @@ -41,13 +41,21 @@ class Ticket extends Model use Auditable; use HasFactory; - protected $casts = [ - 'closed_at' => 'datetime', - 'reminded_at' => 'datetime', - ]; - protected $guarded = []; + /** + * Get the attributes that should be cast. + * + * @return array + */ + protected function casts(): array + { + return [ + 'closed_at' => 'datetime', + 'reminded_at' => 'datetime', + ]; + } + /** * @param Builder $query * @return Builder diff --git a/app/Models/Topic.php b/app/Models/Topic.php index a03890aac4..7566e0e262 100644 --- a/app/Models/Topic.php +++ b/app/Models/Topic.php @@ -46,20 +46,28 @@ class Topic extends Model use Auditable; use HasFactory; - protected $casts = [ - 'last_post_created_at' => 'datetime', - 'pinned' => 'boolean', - 'approved' => 'boolean', - 'denied' => 'boolean', - 'solved' => 'boolean', - 'invalid' => 'boolean', - 'bug' => 'boolean', - 'suggestion' => 'boolean', - 'implemented' => 'boolean', - ]; - protected $guarded = []; + /** + * Get the attributes that should be cast. + * + * @return array + */ + protected function casts(): array + { + return [ + 'last_post_created_at' => 'datetime', + 'pinned' => 'boolean', + 'approved' => 'boolean', + 'denied' => 'boolean', + 'solved' => 'boolean', + 'invalid' => 'boolean', + 'bug' => 'boolean', + 'suggestion' => 'boolean', + 'implemented' => 'boolean', + ]; + } + /** * Belongs To A Forum. * diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index 7beeabf59a..068a2faccd 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -90,20 +90,23 @@ class Torrent extends Model protected $guarded = []; /** - * The Attributes That Should Be Mutated To Dates. + * Get the attributes that should be cast. * - * @var array - */ - protected $casts = [ - 'igdb' => 'integer', - 'fl_until' => 'datetime', - 'du_until' => 'datetime', - 'doubleup' => 'boolean', - 'refundable' => 'boolean', - 'featured' => 'boolean', - 'moderated_at' => 'datetime', - 'sticky' => 'boolean', - ]; + * @return array + */ + protected function casts(): array + { + return [ + 'igdb' => 'integer', + 'fl_until' => 'datetime', + 'du_until' => 'datetime', + 'doubleup' => 'boolean', + 'refundable' => 'boolean', + 'featured' => 'boolean', + 'moderated_at' => 'datetime', + 'sticky' => 'boolean', + ]; + } /** * The attributes that should not be included in audit log. diff --git a/app/Models/TorrentRequest.php b/app/Models/TorrentRequest.php index c70425da80..0cd86eaff3 100644 --- a/app/Models/TorrentRequest.php +++ b/app/Models/TorrentRequest.php @@ -55,17 +55,6 @@ class TorrentRequest extends Model use HasFactory; use TorrentFilter; - /** - * The Attributes That Should Be Mutated To Dates. - * - * @var array - */ - protected $casts = [ - 'filled_when' => 'datetime', - 'approved_when' => 'datetime', - 'igdb' => 'integer', - ]; - /** * The Database Table Used By The Model. * @@ -80,6 +69,20 @@ class TorrentRequest extends Model */ protected $guarded = ['id', 'created_at', 'updated_at']; + /** + * Get the attributes that should be cast. + * + * @return array + */ + protected function casts(): array + { + return [ + 'filled_when' => 'datetime', + 'approved_when' => 'datetime', + 'igdb' => 'integer', + ]; + } + /** * Belongs To A User. * diff --git a/app/Models/TorrentTip.php b/app/Models/TorrentTip.php index 139fbf6a9c..399d487670 100644 --- a/app/Models/TorrentTip.php +++ b/app/Models/TorrentTip.php @@ -32,13 +32,16 @@ class TorrentTip extends Model public $timestamps = false; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'created_at' => 'datetime', - ]; + protected function casts(): array + { + return [ + 'created_at' => 'datetime', + ]; + } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo diff --git a/app/Models/User.php b/app/Models/User.php index 79c07aface..7c65173d63 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -112,23 +112,6 @@ class User extends Authenticatable implements MustVerifyEmail 'two_factor_confirmed_at', ]; - /** - * The Attributes That Should Be Mutated To Dates. - * - * @var array - */ - protected $casts = [ - 'last_login' => 'datetime', - 'last_action' => 'datetime', - 'hidden' => 'boolean', - 'can_comment' => 'boolean', - 'can_download' => 'boolean', - 'can_request' => 'boolean', - 'can_invite' => 'boolean', - 'can_upload' => 'boolean', - 'can_chat' => 'boolean', - ]; - /** * The attributes that aren't mass assignable. * @@ -136,6 +119,26 @@ class User extends Authenticatable implements MustVerifyEmail */ protected $guarded = ['id', 'created_at', 'updated_at']; + /** + * Get the attributes that should be cast. + * + * @return array + */ + protected function casts(): array + { + return [ + 'last_login' => 'datetime', + 'last_action' => 'datetime', + 'hidden' => 'boolean', + 'can_comment' => 'boolean', + 'can_download' => 'boolean', + 'can_request' => 'boolean', + 'can_invite' => 'boolean', + 'can_upload' => 'boolean', + 'can_chat' => 'boolean', + ]; + } + /** * ID of the system user. */ diff --git a/app/Models/UserAudible.php b/app/Models/UserAudible.php index 7be7053703..4e1540124c 100644 --- a/app/Models/UserAudible.php +++ b/app/Models/UserAudible.php @@ -32,13 +32,6 @@ class UserAudible extends Model { use HasFactory; - /** - * Indicates If The Model Should Be Timestamped. - * - * @var bool - */ - public $timestamps = true; - /** * Belongs To A User. * diff --git a/app/Models/UserEcho.php b/app/Models/UserEcho.php index 6630b79be1..826225ca57 100644 --- a/app/Models/UserEcho.php +++ b/app/Models/UserEcho.php @@ -31,13 +31,6 @@ class UserEcho extends Model { use HasFactory; - /** - * Indicates If The Model Should Be Timestamped. - * - * @var bool - */ - public $timestamps = true; - /** * Belongs To A User. * diff --git a/app/Models/UserNotification.php b/app/Models/UserNotification.php index ecd5d3119d..dc1630cb2c 100644 --- a/app/Models/UserNotification.php +++ b/app/Models/UserNotification.php @@ -63,20 +63,23 @@ class UserNotification extends Model public $timestamps = false; /** - * The Attributes That Should Be Cast To Native Values. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'json_account_groups' => 'array', - 'json_mention_groups' => 'array', - 'json_request_groups' => 'array', - 'json_torrent_groups' => 'array', - 'json_forum_groups' => 'array', - 'json_following_groups' => 'array', - 'json_subscription_groups' => 'array', - 'json_bon_groups' => 'array', - ]; + protected function casts(): array + { + return [ + 'json_account_groups' => 'array', + 'json_mention_groups' => 'array', + 'json_request_groups' => 'array', + 'json_torrent_groups' => 'array', + 'json_forum_groups' => 'array', + 'json_following_groups' => 'array', + 'json_subscription_groups' => 'array', + 'json_bon_groups' => 'array', + ]; + } /** * Belongs To A User. diff --git a/app/Models/UserPrivacy.php b/app/Models/UserPrivacy.php index fc4d1efbca..02af000d4d 100644 --- a/app/Models/UserPrivacy.php +++ b/app/Models/UserPrivacy.php @@ -80,23 +80,26 @@ class UserPrivacy extends Model protected $table = 'user_privacy'; /** - * The Attributes That Should Be Cast To Native Values. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'json_profile_groups' => 'array', - 'json_torrent_groups' => 'array', - 'json_forum_groups' => 'array', - 'json_bon_groups' => 'array', - 'json_comment_groups' => 'array', - 'json_wishlist_groups' => 'array', - 'json_follower_groups' => 'array', - 'json_achievement_groups' => 'array', - 'json_rank_groups' => 'array', - 'json_request_groups' => 'array', - 'json_other_groups' => 'array', - ]; + protected function casts(): array + { + return [ + 'json_profile_groups' => 'array', + 'json_torrent_groups' => 'array', + 'json_forum_groups' => 'array', + 'json_bon_groups' => 'array', + 'json_comment_groups' => 'array', + 'json_wishlist_groups' => 'array', + 'json_follower_groups' => 'array', + 'json_achievement_groups' => 'array', + 'json_rank_groups' => 'array', + 'json_request_groups' => 'array', + 'json_other_groups' => 'array', + ]; + } /** * Belongs To A User. diff --git a/app/Models/Warning.php b/app/Models/Warning.php index debba613c9..84bb292626 100644 --- a/app/Models/Warning.php +++ b/app/Models/Warning.php @@ -43,13 +43,16 @@ class Warning extends Model protected $guarded = []; /** - * The Attributes That Should Be Mutated To Dates. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'active' => 'boolean', - ]; + protected function casts(): array + { + return [ + 'active' => 'boolean', + ]; + } /** * Belongs To A Torrent. diff --git a/artisan b/artisan index 5c23e2e24f..2b21b0d442 100644 --- a/artisan +++ b/artisan @@ -1,53 +1,15 @@ #!/usr/bin/env php make(Illuminate\Contracts\Console\Kernel::class); - -$status = $kernel->handle( - $input = new Symfony\Component\Console\Input\ArgvInput, - new Symfony\Component\Console\Output\ConsoleOutput -); - -/* -|-------------------------------------------------------------------------- -| Shutdown The Application -|-------------------------------------------------------------------------- -| -| Once Artisan has finished running, we will fire off the shutdown events -| so that any final work may be done by the application before we shut -| down the process. This is the last thing to happen to the request. -| -*/ - -$kernel->terminate($input, $status); +// Bootstrap Laravel and handle the command... +$status = (require_once __DIR__.'/bootstrap/app.php') + ->handleCommand(new ArgvInput()); exit($status); diff --git a/bun.lockb b/bun.lockb index 51e30da5a7f38bb4f52f96cec769fed49cb6b7be..363432e876cac4e3110b1e90b3ccf9100c3e6bce 100755 GIT binary patch delta 67921 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 B+a3S_ delta 65553 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 g)5erY>zS=BS2?ZLO>N8aROW+FGOd@UL=3.0", - "doctrine/dbal": ">=4.0", "mockery/mockery": "1.6.8", - "phpunit/phpunit": ">=11.0.0", "tightenco/collect": "<5.5.33" }, "provide": { @@ -2273,36 +2272,35 @@ "illuminate/testing": "self.version", "illuminate/translation": "self.version", "illuminate/validation": "self.version", - "illuminate/view": "self.version" + "illuminate/view": "self.version", + "spatie/once": "*" }, "require-dev": { "ably/ably-php": "^1.0", "aws/aws-sdk-php": "^3.235.5", - "doctrine/dbal": "^3.5.1", "ext-gmp": "*", - "fakerphp/faker": "^1.21", - "guzzlehttp/guzzle": "^7.5", + "fakerphp/faker": "^1.23", "league/flysystem-aws-s3-v3": "^3.0", "league/flysystem-ftp": "^3.0", "league/flysystem-path-prefixing": "^3.3", "league/flysystem-read-only": "^3.3", "league/flysystem-sftp-v3": "^3.0", - "mockery/mockery": "^1.5.1", + "mockery/mockery": "^1.6", "nyholm/psr7": "^1.2", - "orchestra/testbench-core": "^8.23.4", - "pda/pheanstalk": "^4.0", + "orchestra/testbench-core": "^9.0.6", + "pda/pheanstalk": "^5.0", "phpstan/phpstan": "^1.4.7", - "phpunit/phpunit": "^10.0.7", + "phpunit/phpunit": "^10.5|^11.0", "predis/predis": "^2.0.2", - "symfony/cache": "^6.2", - "symfony/http-client": "^6.2.4", - "symfony/psr-http-message-bridge": "^2.0" + "resend/resend-php": "^0.10.0", + "symfony/cache": "^7.0", + "symfony/http-client": "^7.0", + "symfony/psr-http-message-bridge": "^7.0" }, "suggest": { "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.235.5).", - "brianium/paratest": "Required to run tests in parallel (^6.0).", - "doctrine/dbal": "Required to rename columns and drop SQLite columns (^3.5.1).", + "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).", "ext-apcu": "Required to use the APC cache driver.", "ext-fileinfo": "Required to use the Filesystem class.", "ext-ftp": "Required to use the Flysystem FTP driver.", @@ -2314,31 +2312,31 @@ "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", "filp/whoops": "Required for friendly error pages in development (^2.14.3).", - "guzzlehttp/guzzle": "Required to use the HTTP Client and the ping methods on schedules (^7.5).", "laravel/tinker": "Required to use the tinker console command (^2.0).", "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.3).", "league/flysystem-read-only": "Required to use read-only disks (^3.3)", "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", - "mockery/mockery": "Required to use mocking (^1.5.1).", + "mockery/mockery": "Required to use mocking (^1.6).", "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", - "pda/pheanstalk": "Required to use the beanstalk queue driver (^4.0).", - "phpunit/phpunit": "Required to use assertions and run tests (^9.5.8|^10.0.7).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", + "phpunit/phpunit": "Required to use assertions and run tests (^10.5|^11.0).", "predis/predis": "Required to use the predis connector (^2.0.2).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^6.2).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^6.2).", - "symfony/http-client": "Required to enable support for the Symfony API mail transports (^6.2).", - "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.2).", - "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.2).", - "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." + "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^7.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.0).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "10.x-dev" + "dev-master": "11.x-dev" } }, "autoload": { @@ -2378,20 +2376,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-03-21T13:36:36+00:00" + "time": "2024-04-23T15:11:31+00:00" }, { "name": "laravel/prompts", - "version": "v0.1.17", + "version": "v0.1.20", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "8ee9f87f7f9eadcbe21e9e72cd4176b2f06cd5b5" + "reference": "bf9a360c484976692de0f3792f30066f4f4b34a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/8ee9f87f7f9eadcbe21e9e72cd4176b2f06cd5b5", - "reference": "8ee9f87f7f9eadcbe21e9e72cd4176b2f06cd5b5", + "url": "https://api.github.com/repos/laravel/prompts/zipball/bf9a360c484976692de0f3792f30066f4f4b34a2", + "reference": "bf9a360c484976692de0f3792f30066f4f4b34a2", "shasum": "" }, "require": { @@ -2433,9 +2431,9 @@ ], "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.1.17" + "source": "https://github.com/laravel/prompts/tree/v0.1.20" }, - "time": "2024-03-13T16:05:43+00:00" + "time": "2024-04-18T00:45:25+00:00" }, { "name": "laravel/serializable-closure", @@ -3034,30 +3032,31 @@ }, { "name": "marcreichel/igdb-laravel", - "version": "3.8.1", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/marcreichel/igdb-laravel.git", - "reference": "385feec1299e6ef5160ed8fae495cc8dbb1624c0" + "reference": "68d5fc11e66c8eac83d88a745f767b575fa81e1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/marcreichel/igdb-laravel/zipball/385feec1299e6ef5160ed8fae495cc8dbb1624c0", - "reference": "385feec1299e6ef5160ed8fae495cc8dbb1624c0", + "url": "https://api.github.com/repos/marcreichel/igdb-laravel/zipball/68d5fc11e66c8eac83d88a745f767b575fa81e1c", + "reference": "68d5fc11e66c8eac83d88a745f767b575fa81e1c", "shasum": "" }, "require": { "ext-json": "*", "guzzlehttp/guzzle": "~6.0|~7.0", - "laravel/framework": "^8.40.0|^9.0|^10.0", - "nesbot/carbon": "^2.53.1", - "php": "^8.0.2" + "illuminate/support": "^8.40.0|^9.0|^10.0|^11.0", + "nesbot/carbon": "^2.53.1|^3.0", + "php": "^8.1" }, "require-dev": { - "nunomaduro/collision": "^5.3|^6.1", + "laravel/pint": "^1.13", + "nunomaduro/collision": "^5.3|^6.1|^7.0|^8.0", "nunomaduro/larastan": "^1.0|^2.0", - "orchestra/testbench": "^6.23|^7.0|^8.0", - "phpunit/phpunit": "^9.5.4", + "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0", + "phpunit/phpunit": "^9.5.4 || ^10.0.0", "roave/security-advisories": "dev-latest" }, "type": "library", @@ -3094,7 +3093,7 @@ ], "support": { "issues": "https://github.com/marcreichel/igdb-laravel/issues", - "source": "https://github.com/marcreichel/igdb-laravel/tree/3.8.1" + "source": "https://github.com/marcreichel/igdb-laravel/tree/4.2.0" }, "funding": [ { @@ -3102,7 +3101,7 @@ "type": "github" } ], - "time": "2023-05-19T14:50:29+00:00" + "time": "2024-03-10T03:44:27+00:00" }, { "name": "masterminds/html5", @@ -3173,16 +3172,16 @@ }, { "name": "monolog/monolog", - "version": "3.5.0", + "version": "3.6.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448" + "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c915e2634718dbc8a4a15c61b0e62e7a44e14448", - "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/4b18b21a5527a3d5ffdac2fd35d3ab25a9597654", + "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654", "shasum": "" }, "require": { @@ -3205,7 +3204,7 @@ "phpstan/phpstan": "^1.9", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-strict-rules": "^1.4", - "phpunit/phpunit": "^10.1", + "phpunit/phpunit": "^10.5.17", "predis/predis": "^1.1 || ^2", "ruflin/elastica": "^7", "symfony/mailer": "^5.4 || ^6", @@ -3258,7 +3257,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.5.0" + "source": "https://github.com/Seldaek/monolog/tree/3.6.0" }, "funding": [ { @@ -3270,46 +3269,45 @@ "type": "tidelift" } ], - "time": "2023-10-27T15:32:31+00:00" + "time": "2024-04-12T21:02:21+00:00" }, { "name": "nesbot/carbon", - "version": "2.72.3", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83" + "reference": "7219739c4e01d4680c980545821733b6ed8ee880" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/0c6fd108360c562f6e4fd1dedb8233b423e91c83", - "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7219739c4e01d4680c980545821733b6ed8ee880", + "reference": "7219739c4e01d4680c980545821733b6ed8ee880", "shasum": "" }, "require": { "carbonphp/carbon-doctrine-types": "*", "ext-json": "*", - "php": "^7.1.8 || ^8.0", + "php": "^8.1", "psr/clock": "^1.0", + "symfony/clock": "^6.3 || ^7.0", "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + "symfony/translation": "^4.4.18 || ^5.2.1|| ^6.0 || ^7.0" }, "provide": { "psr/clock-implementation": "1.0" }, "require-dev": { - "doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0", - "doctrine/orm": "^2.7 || ^3.0", - "friendsofphp/php-cs-fixer": "^3.0", - "kylekatarnls/multi-tester": "^2.0", - "ondrejmirtes/better-reflection": "*", - "phpmd/phpmd": "^2.9", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12.99 || ^1.7.14", - "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", - "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", - "squizlabs/php_codesniffer": "^3.4" + "doctrine/dbal": "^3.6.3 || ^4.0", + "doctrine/orm": "^2.15.2 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.52.1", + "kylekatarnls/multi-tester": "^2.5.3", + "ondrejmirtes/better-reflection": "^6.25.0.4", + "phpmd/phpmd": "^2.15.0", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^1.10.65", + "phpunit/phpunit": "^10.5.15", + "squizlabs/php_codesniffer": "^3.9.0" }, "bin": [ "bin/carbon" @@ -3317,8 +3315,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev", - "dev-master": "2.x-dev" + "dev-master": "3.x-dev", + "dev-2.x": "2.x-dev" }, "laravel": { "providers": [ @@ -3377,7 +3375,7 @@ "type": "tidelift" } ], - "time": "2024-01-25T10:35:09+00:00" + "time": "2024-04-18T16:35:06+00:00" }, { "name": "nette/schema", @@ -3529,25 +3527,27 @@ }, { "name": "nikic/php-parser", - "version": "v4.19.1", + "version": "v5.0.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b" + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4e1b88d21c69391150ace211e9eaf05810858d0b", - "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-tokenizer": "*", - "php": ">=7.1" + "php": ">=7.4" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" @@ -3555,7 +3555,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.9-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -3579,39 +3579,38 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" }, - "time": "2024-03-17T08:10:35+00:00" + "time": "2024-03-05T20:51:40+00:00" }, { "name": "nunomaduro/termwind", - "version": "v1.15.1", + "version": "v2.0.1", "source": { "type": "git", "url": "https://github.com/nunomaduro/termwind.git", - "reference": "8ab0b32c8caa4a2e09700ea32925441385e4a5dc" + "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/8ab0b32c8caa4a2e09700ea32925441385e4a5dc", - "reference": "8ab0b32c8caa4a2e09700ea32925441385e4a5dc", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/58c4c58cf23df7f498daeb97092e34f5259feb6a", + "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": "^8.0", - "symfony/console": "^5.3.0|^6.0.0" - }, - "require-dev": { - "ergebnis/phpstan-rules": "^1.0.", - "illuminate/console": "^8.0|^9.0", - "illuminate/support": "^8.0|^9.0", - "laravel/pint": "^1.0.0", - "pestphp/pest": "^1.21.0", - "pestphp/pest-plugin-mock": "^1.0", - "phpstan/phpstan": "^1.4.6", - "phpstan/phpstan-strict-rules": "^1.1.0", - "symfony/var-dumper": "^5.2.7|^6.0.0", + "php": "^8.2", + "symfony/console": "^7.0.4" + }, + "require-dev": { + "ergebnis/phpstan-rules": "^2.2.0", + "illuminate/console": "^11.0.0", + "laravel/pint": "^1.14.0", + "mockery/mockery": "^1.6.7", + "pestphp/pest": "^2.34.1", + "phpstan/phpstan": "^1.10.59", + "phpstan/phpstan-strict-rules": "^1.5.2", + "symfony/var-dumper": "^7.0.4", "thecodingmachine/phpstan-strict-rules": "^1.0.0" }, "type": "library", @@ -3620,6 +3619,9 @@ "providers": [ "Termwind\\Laravel\\TermwindServiceProvider" ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -3651,7 +3653,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v1.15.1" + "source": "https://github.com/nunomaduro/termwind/tree/v2.0.1" }, "funding": [ { @@ -3667,7 +3669,7 @@ "type": "github" } ], - "time": "2023-02-08T01:06:31+00:00" + "time": "2024-03-06T16:17:14+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -5053,30 +5055,31 @@ }, { "name": "spatie/laravel-signal-aware-command", - "version": "1.3.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-signal-aware-command.git", - "reference": "46cda09a85aef3fd47fb73ddc7081f963e255571" + "reference": "49a5e671c3a3fd992187a777d01385fc6a84759d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-signal-aware-command/zipball/46cda09a85aef3fd47fb73ddc7081f963e255571", - "reference": "46cda09a85aef3fd47fb73ddc7081f963e255571", + "url": "https://api.github.com/repos/spatie/laravel-signal-aware-command/zipball/49a5e671c3a3fd992187a777d01385fc6a84759d", + "reference": "49a5e671c3a3fd992187a777d01385fc6a84759d", "shasum": "" }, "require": { - "illuminate/contracts": "^8.35|^9.0|^10.0", - "php": "^8.0", - "spatie/laravel-package-tools": "^1.4.3" + "illuminate/contracts": "^11.0", + "php": "^8.2", + "spatie/laravel-package-tools": "^1.4.3", + "symfony/console": "^7.0" }, "require-dev": { - "brianium/paratest": "^6.2", + "brianium/paratest": "^6.2|^7.0", "ext-pcntl": "*", - "nunomaduro/collision": "^5.3|^6.0", - "orchestra/testbench": "^6.16|^7.0|^8.0", - "pestphp/pest-plugin-laravel": "^1.3", - "phpunit/phpunit": "^9.5", + "nunomaduro/collision": "^5.3|^6.0|^7.0|^8.0", + "orchestra/testbench": "^9.0", + "pestphp/pest-plugin-laravel": "^1.3|^2.0", + "phpunit/phpunit": "^9.5|^10|^11", "spatie/laravel-ray": "^1.17" }, "type": "library", @@ -5115,7 +5118,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-signal-aware-command/issues", - "source": "https://github.com/spatie/laravel-signal-aware-command/tree/1.3.0" + "source": "https://github.com/spatie/laravel-signal-aware-command/tree/2.0.0" }, "funding": [ { @@ -5123,7 +5126,7 @@ "type": "github" } ], - "time": "2023-01-14T21:10:59+00:00" + "time": "2024-02-05T13:37:25+00:00" }, { "name": "spatie/macroable", @@ -5304,49 +5307,122 @@ ], "time": "2023-12-25T11:46:58+00:00" }, + { + "name": "symfony/clock", + "version": "v7.0.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "8b9d08887353d627d5f6c3bf3373b398b49051c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/8b9d08887353d627d5f6c3bf3373b398b49051c2", + "reference": "8b9d08887353d627d5f6c3bf3373b398b49051c2", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v7.0.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-03-02T12:46:12+00:00" + }, { "name": "symfony/console", - "version": "v6.4.6", + "version": "v7.0.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a2708a5da5c87d1d0d52937bdeac625df659e11f" + "reference": "fde915cd8e7eb99b3d531d3d5c09531429c3f9e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a2708a5da5c87d1d0d52937bdeac625df659e11f", - "reference": "a2708a5da5c87d1d0d52937bdeac625df659e11f", + "url": "https://api.github.com/repos/symfony/console/zipball/fde915cd8e7eb99b3d531d3d5c09531429c3f9e5", + "reference": "fde915cd8e7eb99b3d531d3d5c09531429c3f9e5", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0|^7.0" + "symfony/string": "^6.4|^7.0" }, "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0" + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -5380,7 +5456,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.6" + "source": "https://github.com/symfony/console/tree/v7.0.6" }, "funding": [ { @@ -5396,7 +5472,7 @@ "type": "tidelift" } ], - "time": "2024-03-29T19:07:53+00:00" + "time": "2024-04-01T11:04:53+00:00" }, { "name": "symfony/css-selector", @@ -5599,22 +5675,22 @@ }, { "name": "symfony/error-handler", - "version": "v6.4.6", + "version": "v7.0.6", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "64db1c1802e3a4557e37ba33031ac39f452ac5d4" + "reference": "46a4cc138f799886d4bd70477c55c699d3e9dfc8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/64db1c1802e3a4557e37ba33031ac39f452ac5d4", - "reference": "64db1c1802e3a4557e37ba33031ac39f452ac5d4", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/46a4cc138f799886d4bd70477c55c699d3e9dfc8", + "reference": "46a4cc138f799886d4bd70477c55c699d3e9dfc8", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^5.4|^6.0|^7.0" + "symfony/var-dumper": "^6.4|^7.0" }, "conflict": { "symfony/deprecation-contracts": "<2.5", @@ -5623,7 +5699,7 @@ "require-dev": { "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-kernel": "^6.4|^7.0", - "symfony/serializer": "^5.4|^6.0|^7.0" + "symfony/serializer": "^6.4|^7.0" }, "bin": [ "Resources/bin/patch-type-declarations" @@ -5654,7 +5730,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.4.6" + "source": "https://github.com/symfony/error-handler/tree/v7.0.6" }, "funding": [ { @@ -5670,7 +5746,7 @@ "type": "tidelift" } ], - "time": "2024-03-19T11:56:30+00:00" + "time": "2024-03-19T11:57:22+00:00" }, { "name": "symfony/event-dispatcher", @@ -5830,23 +5906,23 @@ }, { "name": "symfony/finder", - "version": "v6.4.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce" + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce", + "url": "https://api.github.com/repos/symfony/finder/zipball/6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "symfony/filesystem": "^6.0|^7.0" + "symfony/filesystem": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -5874,7 +5950,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.0" + "source": "https://github.com/symfony/finder/tree/v7.0.0" }, "funding": [ { @@ -5890,40 +5966,40 @@ "type": "tidelift" } ], - "time": "2023-10-31T17:30:12+00:00" + "time": "2023-10-31T17:59:56+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.4.4", + "version": "v7.0.6", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "ebc713bc6e6f4b53f46539fc158be85dfcd77304" + "reference": "8789625dcf36e5fbf753014678a1e090f1bc759c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ebc713bc6e6f4b53f46539fc158be85dfcd77304", - "reference": "ebc713bc6e6f4b53f46539fc158be85dfcd77304", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8789625dcf36e5fbf753014678a1e090f1bc759c", + "reference": "8789625dcf36e5fbf753014678a1e090f1bc759c", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.1", "symfony/polyfill-php83": "^1.27" }, "conflict": { - "symfony/cache": "<6.3" + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4" }, "require-dev": { - "doctrine/dbal": "^2.13.1|^3|^4", + "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.3|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", - "symfony/mime": "^5.4|^6.0|^7.0", - "symfony/rate-limiter": "^5.4|^6.0|^7.0" + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -5951,7 +6027,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.4" + "source": "https://github.com/symfony/http-foundation/tree/v7.0.6" }, "funding": [ { @@ -5967,76 +6043,75 @@ "type": "tidelift" } ], - "time": "2024-02-08T15:01:18+00:00" + "time": "2024-03-19T11:46:48+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.6", + "version": "v7.0.6", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "060038863743fd0cd982be06acecccf246d35653" + "reference": "34c872391046d59af804af62d4573b829cfe4824" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/060038863743fd0cd982be06acecccf246d35653", - "reference": "060038863743fd0cd982be06acecccf246d35653", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/34c872391046d59af804af62d4573b829cfe4824", + "reference": "34c872391046d59af804af62d4573b829cfe4824", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.4|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/browser-kit": "<5.4", - "symfony/cache": "<5.4", - "symfony/config": "<6.1", - "symfony/console": "<5.4", + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", "symfony/dependency-injection": "<6.4", - "symfony/doctrine-bridge": "<5.4", - "symfony/form": "<5.4", - "symfony/http-client": "<5.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", "symfony/http-client-contracts": "<2.5", - "symfony/mailer": "<5.4", - "symfony/messenger": "<5.4", - "symfony/translation": "<5.4", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", "symfony/translation-contracts": "<2.5", - "symfony/twig-bridge": "<5.4", + "symfony/twig-bridge": "<6.4", "symfony/validator": "<6.4", - "symfony/var-dumper": "<6.3", - "twig/twig": "<2.13" + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.0.4" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^5.4|^6.0|^7.0", - "symfony/clock": "^6.2|^7.0", - "symfony/config": "^6.1|^7.0", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", - "symfony/dom-crawler": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", "symfony/http-client-contracts": "^2.5|^3", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/property-access": "^5.4.5|^6.0.5|^7.0", - "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", "symfony/serializer": "^6.4.4|^7.0.4", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/uid": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0", - "symfony/var-exporter": "^6.2|^7.0", - "twig/twig": "^2.13|^3.0.4" + "symfony/var-exporter": "^6.4|^7.0", + "twig/twig": "^3.0.4" }, "type": "library", "autoload": { @@ -6064,7 +6139,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/v6.4.6" + "source": "https://github.com/symfony/http-kernel/tree/v7.0.6" }, "funding": [ { @@ -6080,43 +6155,43 @@ "type": "tidelift" } ], - "time": "2024-04-03T06:09:15+00:00" + "time": "2024-04-03T06:12:25+00:00" }, { "name": "symfony/mailer", - "version": "v6.4.6", + "version": "v7.0.6", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "677f34a6f4b4559e08acf73ae0aec460479e5859" + "reference": "eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/677f34a6f4b4559e08acf73ae0aec460479e5859", - "reference": "677f34a6f4b4559e08acf73ae0aec460479e5859", + "url": "https://api.github.com/repos/symfony/mailer/zipball/eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0", + "reference": "eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0", "shasum": "" }, "require": { "egulias/email-validator": "^2.1.10|^3|^4", - "php": ">=8.1", + "php": ">=8.2", "psr/event-dispatcher": "^1", "psr/log": "^1|^2|^3", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", - "symfony/mime": "^6.2|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", "symfony/service-contracts": "^2.5|^3" }, "conflict": { "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<5.4", - "symfony/messenger": "<6.2", - "symfony/mime": "<6.2", - "symfony/twig-bridge": "<6.2.1" + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/messenger": "^6.2|^7.0", - "symfony/twig-bridge": "^6.2|^7.0" + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6144,7 +6219,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.6" + "source": "https://github.com/symfony/mailer/tree/v7.0.6" }, "funding": [ { @@ -6160,25 +6235,24 @@ "type": "tidelift" } ], - "time": "2024-03-27T21:14:17+00:00" + "time": "2024-03-28T09:20:36+00:00" }, { "name": "symfony/mime", - "version": "v6.4.6", + "version": "v7.0.6", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "14762b86918823cb42e3558cdcca62e58b5227fe" + "reference": "99362408c9abdf8c7cadcf0529b6fc8b16f5ace2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/14762b86918823cb42e3558cdcca62e58b5227fe", - "reference": "14762b86918823cb42e3558cdcca62e58b5227fe", + "url": "https://api.github.com/repos/symfony/mime/zipball/99362408c9abdf8c7cadcf0529b6fc8b16f5ace2", + "reference": "99362408c9abdf8c7cadcf0529b6fc8b16f5ace2", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, @@ -6186,18 +6260,18 @@ "egulias/email-validator": "~3.0.0", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<5.4", - "symfony/serializer": "<6.3.2" + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4" }, "require-dev": { "egulias/email-validator": "^2.1.10|^3.1|^4", "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.4|^7.0", - "symfony/property-access": "^5.4|^6.0|^7.0", - "symfony/property-info": "^5.4|^6.0|^7.0", - "symfony/serializer": "^6.3.2|^7.0" + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6229,7 +6303,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.4.6" + "source": "https://github.com/symfony/mime/tree/v7.0.6" }, "funding": [ { @@ -6245,7 +6319,7 @@ "type": "tidelift" } ], - "time": "2024-03-21T19:36:20+00:00" + "time": "2024-03-21T19:37:36+00:00" }, { "name": "symfony/polyfill-ctype", @@ -7040,20 +7114,20 @@ }, { "name": "symfony/process", - "version": "v6.4.4", + "version": "v7.0.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "710e27879e9be3395de2b98da3f52a946039f297" + "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/710e27879e9be3395de2b98da3f52a946039f297", - "reference": "710e27879e9be3395de2b98da3f52a946039f297", + "url": "https://api.github.com/repos/symfony/process/zipball/0e7727191c3b71ebec6d529fa0e50a01ca5679e9", + "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "type": "library", "autoload": { @@ -7081,7 +7155,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.4" + "source": "https://github.com/symfony/process/tree/v7.0.4" }, "funding": [ { @@ -7097,40 +7171,38 @@ "type": "tidelift" } ], - "time": "2024-02-20T12:31:00+00:00" + "time": "2024-02-22T20:27:20+00:00" }, { "name": "symfony/routing", - "version": "v6.4.6", + "version": "v7.0.6", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "f2591fd1f8c6e3734656b5d6b3829e8bf81f507c" + "reference": "cded64e5bbf9f31786f1055fcc76718fdd77519c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/f2591fd1f8c6e3734656b5d6b3829e8bf81f507c", - "reference": "f2591fd1f8c6e3734656b5d6b3829e8bf81f507c", + "url": "https://api.github.com/repos/symfony/routing/zipball/cded64e5bbf9f31786f1055fcc76718fdd77519c", + "reference": "cded64e5bbf9f31786f1055fcc76718fdd77519c", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { - "doctrine/annotations": "<1.12", - "symfony/config": "<6.2", - "symfony/dependency-injection": "<5.4", - "symfony/yaml": "<5.4" + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" }, "require-dev": { - "doctrine/annotations": "^1.12|^2", "psr/log": "^1|^2|^3", - "symfony/config": "^6.2|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^5.4|^6.0|^7.0", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7164,7 +7236,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.6" + "source": "https://github.com/symfony/routing/tree/v7.0.6" }, "funding": [ { @@ -7180,7 +7252,7 @@ "type": "tidelift" } ], - "time": "2024-03-28T13:28:49+00:00" + "time": "2024-03-28T21:02:11+00:00" }, { "name": "symfony/service-contracts", @@ -7352,33 +7424,32 @@ }, { "name": "symfony/translation", - "version": "v6.4.4", + "version": "v7.0.4", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "bce6a5a78e94566641b2594d17e48b0da3184a8e" + "reference": "5b75e872f7d135d7abb4613809fadc8d9f3d30a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/bce6a5a78e94566641b2594d17e48b0da3184a8e", - "reference": "bce6a5a78e94566641b2594d17e48b0da3184a8e", + "url": "https://api.github.com/repos/symfony/translation/zipball/5b75e872f7d135d7abb4613809fadc8d9f3d30a0", + "reference": "5b75e872f7d135d7abb4613809fadc8d9f3d30a0", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.0", "symfony/translation-contracts": "^2.5|^3.0" }, "conflict": { - "symfony/config": "<5.4", - "symfony/console": "<5.4", - "symfony/dependency-injection": "<5.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<5.4", + "symfony/http-kernel": "<6.4", "symfony/service-contracts": "<2.5", - "symfony/twig-bundle": "<5.4", - "symfony/yaml": "<5.4" + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" }, "provide": { "symfony/translation-implementation": "2.3|3.0" @@ -7386,17 +7457,17 @@ "require-dev": { "nikic/php-parser": "^4.18|^5.0", "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/routing": "^6.4|^7.0", "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7427,7 +7498,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.4.4" + "source": "https://github.com/symfony/translation/tree/v7.0.4" }, "funding": [ { @@ -7443,7 +7514,7 @@ "type": "tidelift" } ], - "time": "2024-02-20T13:16:58+00:00" + "time": "2024-02-22T20:27:20+00:00" }, { "name": "symfony/translation-contracts", @@ -7525,24 +7596,24 @@ }, { "name": "symfony/uid", - "version": "v6.4.3", + "version": "v7.0.3", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "1d31267211cc3a2fff32bcfc7c1818dac41b6fc0" + "reference": "87cedaf3fabd7b733859d4d77aa4ca598259054b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/1d31267211cc3a2fff32bcfc7c1818dac41b6fc0", - "reference": "1d31267211cc3a2fff32bcfc7c1818dac41b6fc0", + "url": "https://api.github.com/repos/symfony/uid/zipball/87cedaf3fabd7b733859d4d77aa4ca598259054b", + "reference": "87cedaf3fabd7b733859d4d77aa4ca598259054b", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-uuid": "^1.15" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0" + "symfony/console": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7579,7 +7650,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v6.4.3" + "source": "https://github.com/symfony/uid/tree/v7.0.3" }, "funding": [ { @@ -7595,38 +7666,36 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-01-23T15:02:46+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.6", + "version": "v7.0.6", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "95bd2706a97fb875185b51ecaa6112ec184233d4" + "reference": "66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/95bd2706a97fb875185b51ecaa6112ec184233d4", - "reference": "95bd2706a97fb875185b51ecaa6112ec184233d4", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb", + "reference": "66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/console": "<5.4" + "symfony/console": "<6.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/error-handler": "^6.3|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/uid": "^5.4|^6.0|^7.0", - "twig/twig": "^2.13|^3.0.4" + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.0.4" }, "bin": [ "Resources/bin/var-dump-server" @@ -7664,7 +7733,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.6" + "source": "https://github.com/symfony/var-dumper/tree/v7.0.6" }, "funding": [ { @@ -7680,7 +7749,7 @@ "type": "tidelift" } ], - "time": "2024-03-19T11:56:30+00:00" + "time": "2024-03-19T11:57:22+00:00" }, { "name": "theodorejb/polycast", @@ -8758,16 +8827,16 @@ }, { "name": "larastan/larastan", - "version": "v2.9.2", + "version": "v2.9.5", "source": { "type": "git", "url": "https://github.com/larastan/larastan.git", - "reference": "a79b46b96060504b400890674b83f66aa7f5db6d" + "reference": "101f1a4470f87326f4d3995411d28679d8800abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/larastan/larastan/zipball/a79b46b96060504b400890674b83f66aa7f5db6d", - "reference": "a79b46b96060504b400890674b83f66aa7f5db6d", + "url": "https://api.github.com/repos/larastan/larastan/zipball/101f1a4470f87326f4d3995411d28679d8800abe", + "reference": "101f1a4470f87326f4d3995411d28679d8800abe", "shasum": "" }, "require": { @@ -8780,15 +8849,15 @@ "illuminate/pipeline": "^9.52.16 || ^10.28.0 || ^11.0", "illuminate/support": "^9.52.16 || ^10.28.0 || ^11.0", "php": "^8.0.2", - "phpmyadmin/sql-parser": "^5.8.2", - "phpstan/phpstan": "^1.10.50" + "phpmyadmin/sql-parser": "^5.9.0", + "phpstan/phpstan": "^1.10.66" }, "require-dev": { "doctrine/coding-standard": "^12.0", - "nikic/php-parser": "^4.17.1", - "orchestra/canvas": "^7.11.1 || ^8.11.0 || ^9.0.0", - "orchestra/testbench": "^7.33.0 || ^8.13.0 || ^9.0.0", - "phpunit/phpunit": "^9.6.13 || ^10.5" + "nikic/php-parser": "^4.19.1", + "orchestra/canvas": "^7.11.1 || ^8.11.0 || ^9.0.2", + "orchestra/testbench": "^7.33.0 || ^8.13.0 || ^9.0.3", + "phpunit/phpunit": "^9.6.13 || ^10.5.16" }, "suggest": { "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" @@ -8836,7 +8905,7 @@ ], "support": { "issues": "https://github.com/larastan/larastan/issues", - "source": "https://github.com/larastan/larastan/tree/v2.9.2" + "source": "https://github.com/larastan/larastan/tree/v2.9.5" }, "funding": [ { @@ -8856,20 +8925,20 @@ "type": "patreon" } ], - "time": "2024-02-27T03:16:03+00:00" + "time": "2024-04-16T19:13:34+00:00" }, { "name": "laravel/pint", - "version": "v1.15.1", + "version": "v1.15.2", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "5f288b5e79938cc72f5c298d384e639de87507c6" + "reference": "2c9f8004899815f3f0ee3cb28ef7281e2b589134" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/5f288b5e79938cc72f5c298d384e639de87507c6", - "reference": "5f288b5e79938cc72f5c298d384e639de87507c6", + "url": "https://api.github.com/repos/laravel/pint/zipball/2c9f8004899815f3f0ee3cb28ef7281e2b589134", + "reference": "2c9f8004899815f3f0ee3cb28ef7281e2b589134", "shasum": "" }, "require": { @@ -8880,13 +8949,13 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.52.1", - "illuminate/view": "^10.48.4", - "larastan/larastan": "^2.9.2", + "friendsofphp/php-cs-fixer": "^3.54.0", + "illuminate/view": "^10.48.8", + "larastan/larastan": "^2.9.5", "laravel-zero/framework": "^10.3.0", "mockery/mockery": "^1.6.11", "nunomaduro/termwind": "^1.15.1", - "pestphp/pest": "^2.34.5" + "pestphp/pest": "^2.34.7" }, "bin": [ "builds/pint" @@ -8922,7 +8991,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-04-02T14:28:47+00:00" + "time": "2024-04-23T15:42:34+00:00" }, { "name": "laravel/sail", @@ -9131,40 +9200,38 @@ }, { "name": "nunomaduro/collision", - "version": "v7.10.0", + "version": "v8.1.1", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "49ec67fa7b002712da8526678abd651c09f375b2" + "reference": "13e5d538b95a744d85f447a321ce10adb28e9af9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/49ec67fa7b002712da8526678abd651c09f375b2", - "reference": "49ec67fa7b002712da8526678abd651c09f375b2", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/13e5d538b95a744d85f447a321ce10adb28e9af9", + "reference": "13e5d538b95a744d85f447a321ce10adb28e9af9", "shasum": "" }, "require": { - "filp/whoops": "^2.15.3", - "nunomaduro/termwind": "^1.15.1", - "php": "^8.1.0", - "symfony/console": "^6.3.4" + "filp/whoops": "^2.15.4", + "nunomaduro/termwind": "^2.0.1", + "php": "^8.2.0", + "symfony/console": "^7.0.4" }, "conflict": { - "laravel/framework": ">=11.0.0" + "laravel/framework": "<11.0.0 || >=12.0.0", + "phpunit/phpunit": "<10.5.1 || >=12.0.0" }, "require-dev": { - "brianium/paratest": "^7.3.0", - "laravel/framework": "^10.28.0", - "laravel/pint": "^1.13.3", - "laravel/sail": "^1.25.0", - "laravel/sanctum": "^3.3.1", - "laravel/tinker": "^2.8.2", - "nunomaduro/larastan": "^2.6.4", - "orchestra/testbench-core": "^8.13.0", - "pestphp/pest": "^2.23.2", - "phpunit/phpunit": "^10.4.1", - "sebastian/environment": "^6.0.1", - "spatie/laravel-ignition": "^2.3.1" + "larastan/larastan": "^2.9.2", + "laravel/framework": "^11.0.0", + "laravel/pint": "^1.14.0", + "laravel/sail": "^1.28.2", + "laravel/sanctum": "^4.0.0", + "laravel/tinker": "^2.9.0", + "orchestra/testbench-core": "^9.0.0", + "pestphp/pest": "^2.34.1 || ^3.0.0", + "sebastian/environment": "^6.0.1 || ^7.0.0" }, "type": "library", "extra": { @@ -9172,6 +9239,9 @@ "providers": [ "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" ] + }, + "branch-alias": { + "dev-8.x": "8.x-dev" } }, "autoload": { @@ -9223,40 +9293,40 @@ "type": "patreon" } ], - "time": "2023-10-11T15:45:01+00:00" + "time": "2024-03-06T16:20:09+00:00" }, { "name": "pestphp/pest", - "version": "v2.33.4", + "version": "v2.34.7", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "4baf27911e088cd27c0114bd9b4ee579203f8810" + "reference": "a7a3e4240e341d0fee1c54814ce18adc26ce5a76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/4baf27911e088cd27c0114bd9b4ee579203f8810", - "reference": "4baf27911e088cd27c0114bd9b4ee579203f8810", + "url": "https://api.github.com/repos/pestphp/pest/zipball/a7a3e4240e341d0fee1c54814ce18adc26ce5a76", + "reference": "a7a3e4240e341d0fee1c54814ce18adc26ce5a76", "shasum": "" }, "require": { "brianium/paratest": "^7.3.1", - "nunomaduro/collision": "^7.10.0|^8.1.0", - "nunomaduro/termwind": "^1.15.1|^2.0.0", + "nunomaduro/collision": "^7.10.0|^8.1.1", + "nunomaduro/termwind": "^1.15.1|^2.0.1", "pestphp/pest-plugin": "^2.1.1", "pestphp/pest-plugin-arch": "^2.7.0", "php": "^8.1.0", - "phpunit/phpunit": "^10.5.9" + "phpunit/phpunit": "^10.5.17" }, "conflict": { - "phpunit/phpunit": ">10.5.9", + "phpunit/phpunit": ">10.5.17", "sebastian/exporter": "<5.1.0", "webmozart/assert": "<1.11.0" }, "require-dev": { "pestphp/pest-dev-tools": "^2.16.0", - "pestphp/pest-plugin-type-coverage": "^2.8.0", - "symfony/process": "^6.4.0|^7.0.3" + "pestphp/pest-plugin-type-coverage": "^2.8.1", + "symfony/process": "^6.4.0|^7.0.4" }, "bin": [ "bin/pest" @@ -9319,7 +9389,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v2.33.4" + "source": "https://github.com/pestphp/pest/tree/v2.34.7" }, "funding": [ { @@ -9331,7 +9401,7 @@ "type": "github" } ], - "time": "2024-02-02T16:54:54+00:00" + "time": "2024-04-05T07:44:17+00:00" }, { "name": "pestphp/pest-plugin", @@ -9474,99 +9544,29 @@ ], "time": "2024-01-26T09:46:42+00:00" }, - { - "name": "pestphp/pest-plugin-drift", - "version": "v2.5.0", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest-plugin-drift.git", - "reference": "78d189cb2921f2ccd3d0bbb97c68a3d13b22c4d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-drift/zipball/78d189cb2921f2ccd3d0bbb97c68a3d13b22c4d9", - "reference": "78d189cb2921f2ccd3d0bbb97c68a3d13b22c4d9", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.17.1", - "pestphp/pest": "^2.16.1", - "php": "^8.1.0", - "symfony/finder": "^6.3.0" - }, - "require-dev": { - "pestphp/pest-dev-tools": "^2.16.0" - }, - "type": "library", - "extra": { - "pest": { - "plugins": [ - "Pest\\Drift\\Plugin" - ] - } - }, - "autoload": { - "psr-4": { - "Pest\\Drift\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The Pest Drift Plugin", - "keywords": [ - "framework", - "laravel", - "pest", - "php", - "test", - "testing", - "unit" - ], - "support": { - "issues": "https://github.com/pestphp/pest-plugin-drift/issues", - "source": "https://github.com/pestphp/pest-plugin-drift/tree/v2.5.0" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/mandisma", - "type": "github" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - } - ], - "time": "2023-09-26T10:09:33+00:00" - }, { "name": "pestphp/pest-plugin-laravel", - "version": "v2.2.0", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/pestphp/pest-plugin-laravel.git", - "reference": "77a2838c1d3b09d147211e76a48987ba9a758279" + "reference": "2f6ea6233bb74ec65d969ecdea56bdbd3d1e2f0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/77a2838c1d3b09d147211e76a48987ba9a758279", - "reference": "77a2838c1d3b09d147211e76a48987ba9a758279", + "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/2f6ea6233bb74ec65d969ecdea56bdbd3d1e2f0e", + "reference": "2f6ea6233bb74ec65d969ecdea56bdbd3d1e2f0e", "shasum": "" }, "require": { - "laravel/framework": "^10.18.0|^11.0", - "pestphp/pest": "^2.13.0", + "laravel/framework": "^10.44.0|^11.0", + "pestphp/pest": "^2.33.6", "php": "^8.1.0" }, "require-dev": { - "laravel/dusk": "^7.9.3", - "orchestra/testbench": "^8.6.3", - "pestphp/pest-dev-tools": "^2.14.0" + "laravel/dusk": "^7.12.3", + "orchestra/testbench": "^8.21.1|^9.0.0", + "pestphp/pest-dev-tools": "^2.16.0" }, "type": "library", "extra": { @@ -9574,6 +9574,11 @@ "providers": [ "Pest\\Laravel\\PestServiceProvider" ] + }, + "pest": { + "plugins": [ + "Pest\\Laravel\\Plugin" + ] } }, "autoload": { @@ -9599,7 +9604,7 @@ "unit" ], "support": { - "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v2.2.0" + "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v2.3.0" }, "funding": [ { @@ -9611,7 +9616,7 @@ "type": "github" } ], - "time": "2023-08-10T15:37:09+00:00" + "time": "2024-02-17T10:04:08+00:00" }, { "name": "pestphp/pest-plugin-livewire", @@ -9852,28 +9857,35 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", + "version": "5.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + "reference": "298d2febfe79d03fe714eb871d5538da55205b1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/298d2febfe79d03fe714eb871d5538da55205b1a", + "reference": "298d2febfe79d03fe714eb871d5538da55205b1a", "shasum": "" }, "require": { + "doctrine/deprecations": "^1.1", "ext-filter": "*", - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7", "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" + "mockery/mockery": "~1.3.5", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^5.13" }, "type": "library", "extra": { @@ -9897,15 +9909,15 @@ }, { "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" + "email": "opensource@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.0" }, - "time": "2021-10-19T17:43:47+00:00" + "time": "2024-04-09T21:13:58+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -10102,16 +10114,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.66", + "version": "1.10.67", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "94779c987e4ebd620025d9e5fdd23323903950bd" + "reference": "16ddbe776f10da6a95ebd25de7c1dbed397dc493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/94779c987e4ebd620025d9e5fdd23323903950bd", - "reference": "94779c987e4ebd620025d9e5fdd23323903950bd", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/16ddbe776f10da6a95ebd25de7c1dbed397dc493", + "reference": "16ddbe776f10da6a95ebd25de7c1dbed397dc493", "shasum": "" }, "require": { @@ -10154,13 +10166,9 @@ { "url": "https://github.com/phpstan", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" } ], - "time": "2024-03-28T16:17:31+00:00" + "time": "2024-04-16T07:22:02+00:00" }, { "name": "phpunit/php-code-coverage", @@ -10485,16 +10493,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.9", + "version": "10.5.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe" + "reference": "c1f736a473d21957ead7e94fcc029f571895abf5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe", - "reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c1f736a473d21957ead7e94fcc029f571895abf5", + "reference": "c1f736a473d21957ead7e94fcc029f571895abf5", "shasum": "" }, "require": { @@ -10566,7 +10574,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.9" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.17" }, "funding": [ { @@ -10582,7 +10590,7 @@ "type": "tidelift" } ], - "time": "2024-01-22T14:35:40+00:00" + "time": "2024-04-05T04:39:01+00:00" }, { "name": "ryoluo/sail-ssl", @@ -11695,16 +11703,16 @@ }, { "name": "spatie/ignition", - "version": "1.13.1", + "version": "1.13.2", "source": { "type": "git", "url": "https://github.com/spatie/ignition.git", - "reference": "889bf1dfa59e161590f677728b47bf4a6893983b" + "reference": "952798e239d9969e4e694b124c2cc222798dbb28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/ignition/zipball/889bf1dfa59e161590f677728b47bf4a6893983b", - "reference": "889bf1dfa59e161590f677728b47bf4a6893983b", + "url": "https://api.github.com/repos/spatie/ignition/zipball/952798e239d9969e4e694b124c2cc222798dbb28", + "reference": "952798e239d9969e4e694b124c2cc222798dbb28", "shasum": "" }, "require": { @@ -11774,20 +11782,20 @@ "type": "github" } ], - "time": "2024-03-29T14:03:47+00:00" + "time": "2024-04-16T08:49:17+00:00" }, { "name": "spatie/laravel-ignition", - "version": "2.5.1", + "version": "2.5.2", "source": { "type": "git", "url": "https://github.com/spatie/laravel-ignition.git", - "reference": "0c864b3cbd66ce67a2096c5f743e07ce8f1d6ab9" + "reference": "c93fcadcc4629775c839ac9a90916f07a660266f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/0c864b3cbd66ce67a2096c5f743e07ce8f1d6ab9", - "reference": "0c864b3cbd66ce67a2096c5f743e07ce8f1d6ab9", + "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/c93fcadcc4629775c839ac9a90916f07a660266f", + "reference": "c93fcadcc4629775c839ac9a90916f07a660266f", "shasum": "" }, "require": { @@ -11797,7 +11805,7 @@ "illuminate/support": "^10.0|^11.0", "php": "^8.1", "spatie/flare-client-php": "^1.3.5", - "spatie/ignition": "^1.13", + "spatie/ignition": "^1.13.2", "symfony/console": "^6.2.3|^7.0", "symfony/var-dumper": "^6.2.3|^7.0" }, @@ -11866,7 +11874,7 @@ "type": "github" } ], - "time": "2024-04-02T06:30:22+00:00" + "time": "2024-04-16T08:57:16+00:00" }, { "name": "symfony/yaml", diff --git a/config/database.php b/config/database.php index bba2dd8b5b..ae26f5f336 100644 --- a/config/database.php +++ b/config/database.php @@ -33,7 +33,7 @@ 'connections' => [ 'sqlite' => [ 'driver' => 'sqlite', - 'url' => env('DATABASE_URL'), + 'url' => env('DB_URL'), 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), @@ -41,7 +41,7 @@ 'mysql' => [ 'driver' => 'mysql', - 'url' => env('DATABASE_URL'), + 'url' => env('DB_URL'), 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), @@ -67,7 +67,7 @@ 'pgsql' => [ 'driver' => 'pgsql', - 'url' => env('DATABASE_URL'), + 'url' => env('DB_URL'), 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '5432'), 'database' => env('DB_DATABASE', 'forge'), @@ -107,7 +107,10 @@ | */ - 'migrations' => 'migrations', + 'migrations' => [ + 'table' => 'migrations', + 'update_date_on_publish' => false, // disable to preserve original behavior for existing applications + ], /* |-------------------------------------------------------------------------- diff --git a/package.json b/package.json index d42de7e88f..5801aa667b 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,8 @@ "resolve-url-loader": "^5.0.0", "sass": "^1.49.9", "sass-loader": "^12.6.0", - "socket.io": "^2.4.0", - "socket.io-client": "^2.3.1", + "socket.io": "2.4.0", + "socket.io-client": "2.3.1", "sweetalert2": "^11.4.6", "virtual-select-plugin": "^1.0.26", "vue": "^2.6.14", diff --git a/public/index.php b/public/index.php index cfc538b892..3af429b852 100644 --- a/public/index.php +++ b/public/index.php @@ -1,55 +1,17 @@ make(Kernel::class); - -$response = $kernel->handle( - $request = Request::capture() -)->send(); - -$kernel->terminate($request, $response); +// Bootstrap Laravel and handle the request... +(require_once __DIR__.'/../bootstrap/app.php') + ->handleRequest(Request::capture()); From 1420eb454cda467d4978a1121f3cc629b78801f7 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Tue, 23 Apr 2024 16:35:06 -0400 Subject: [PATCH 49/61] remove: deprecated methods and dbal --- app/Console/Commands/AutoGroup.php | 27 ++++++---- ...017_12_10_020753_create_torrents_table.php | 2 +- ...021_10_03_180121_add_indexes_to_tables.php | 53 ++++++------------- 3 files changed, 33 insertions(+), 49 deletions(-) diff --git a/app/Console/Commands/AutoGroup.php b/app/Console/Commands/AutoGroup.php index 00044d45d6..bf04913974 100644 --- a/app/Console/Commands/AutoGroup.php +++ b/app/Console/Commands/AutoGroup.php @@ -14,7 +14,6 @@ namespace App\Console\Commands; use App\Enums\UserGroup; -use App\Helpers\ByteUnits; use App\Models\Group; use App\Models\User; use App\Services\Unit3dAnnounce; @@ -44,11 +43,11 @@ class AutoGroup extends Command /** * Execute the console command. */ - public function handle(ByteUnits $byteUnits): void + public function handle(): void { $now = now(); - // Temp Hard Coding of Immune Groups (Config Files To Come) $current = Carbon::now(); + $groups = Group::query() ->where('autogroup', '=', 1) ->orderBy('position') @@ -64,19 +63,25 @@ public function handle(ByteUnits $byteUnits): void $seedtime = null; foreach ($groups as $group) { + $seedtime ??= DB::table('history') + ->whereNull('deleted_at') + ->where('user_id', '=', $user->id) + ->avg('seedtime') ?? 0; + + $seedsize ??= $user->seedingTorrents()->sum('size'); + if ( //short circuit when the values are 0 or null - ($group->min_uploaded ? $group->min_uploaded <= $user->uploaded : true) - && ($group->min_ratio ? $group->min_ratio <= $user->ratio : true) - && ($group->min_age ? $user->created_at->addRealSeconds($group->min_age)->isBefore($current) : true) - && ($group->min_avg_seedtime ? $group->min_avg_seedtime <= ($seedtime ??= DB::table('history')->where('user_id', '=', $user->id)->avg('seedtime') ?? 0) : true) - && ($group->min_seedsize ? $group->min_seedsize <= ($seedsize ??= $user->seedingTorrents()->sum('size')) : true) + (!$group->min_uploaded || $group->min_uploaded <= $user->uploaded) + && (!$group->min_ratio || $group->min_ratio <= $user->ratio) + && (!$group->min_age || $user->created_at->addSeconds($group->min_age)->isBefore($current)) + && (!$group->min_avg_seedtime || $group->min_avg_seedtime <= ($seedtime)) + && (!$group->min_seedsize || $group->min_seedsize <= ($seedsize)) ) { $user->group_id = $group->id; // Leech ratio dropped below sites minimum - - if ($user->group_id == UserGroup::LEECH->value) { + if ($user->group_id === UserGroup::LEECH->value) { $user->can_request = false; $user->can_invite = false; $user->can_download = false; @@ -96,7 +101,7 @@ public function handle(ByteUnits $byteUnits): void } } - $elapsed = now()->floatDiffInSeconds($now); + $elapsed = now()->diffInSeconds($now); $this->comment('Automated User Group Command Complete ('.$elapsed.')'); } } diff --git a/database/migrations/2017_12_10_020753_create_torrents_table.php b/database/migrations/2017_12_10_020753_create_torrents_table.php index c88eccf54c..691e2a25cc 100644 --- a/database/migrations/2017_12_10_020753_create_torrents_table.php +++ b/database/migrations/2017_12_10_020753_create_torrents_table.php @@ -29,7 +29,7 @@ public function up(): void $table->string('info_hash')->index('info_hash'); $table->string('file_name'); $table->integer('num_file'); - $table->float('size', 10, 0); + $table->float('size'); $table->text('nfo')->nullable(); $table->integer('leechers')->default(0); $table->integer('seeders')->default(0); diff --git a/database/migrations/2021_10_03_180121_add_indexes_to_tables.php b/database/migrations/2021_10_03_180121_add_indexes_to_tables.php index 5691a3dce9..fa005c17a3 100644 --- a/database/migrations/2021_10_03_180121_add_indexes_to_tables.php +++ b/database/migrations/2021_10_03_180121_add_indexes_to_tables.php @@ -22,100 +22,79 @@ public function up(): void { Schema::table('articles', function (Blueprint $table): void { - $sm = Schema::getConnection()->getDoctrineSchemaManager(); - $doctrineTable = $sm->listTableDetails('articles'); - - if (!$doctrineTable->hasIndex('created_at')) { + if (!Schema::hasIndex('articles', 'created_at')) { $table->index('created_at'); } }); Schema::table('bon_transactions', function (Blueprint $table): void { - $sm = Schema::getConnection()->getDoctrineSchemaManager(); - $doctrineTable = $sm->listTableDetails('bon_transactions;'); - - if (!$doctrineTable->hasIndex('itemID')) { + if (!Schema::hasIndex('bon_transactions', 'itemID')) { $table->index('itemID'); } - if (!$doctrineTable->hasIndex('sender')) { + if (!Schema::hasIndex('bon_transactions', 'sender')) { $table->index('sender'); } - if (!$doctrineTable->hasIndex('receiver')) { + if (!Schema::hasIndex('bon_transactions', 'receiver')) { $table->index('receiver'); } - if (!$doctrineTable->hasIndex('torrent_id')) { + if (!Schema::hasIndex('bon_transactions', 'torrent_id')) { $table->index('torrent_id'); } }); Schema::table('bookmarks', function (Blueprint $table): void { - $sm = Schema::getConnection()->getDoctrineSchemaManager(); - $doctrineTable = $sm->listTableDetails('bookmarks'); - - if (!$doctrineTable->hasIndex('user_id')) { + if (!Schema::hasIndex('bookmarks', 'user_id')) { $table->index('user_id'); } - if (!$doctrineTable->hasIndex('torrent_id')) { + if (!Schema::hasIndex('bookmarks', 'torrent_id')) { $table->index('torrent_id'); } }); Schema::table('posts', function (Blueprint $table): void { - $sm = Schema::getConnection()->getDoctrineSchemaManager(); - $doctrineTable = $sm->listTableDetails('posts'); - - if (!$doctrineTable->hasIndex('created_at')) { + if (!Schema::hasIndex('posts', 'created_at')) { $table->index('created_at'); } }); Schema::table('topics', function (Blueprint $table): void { - $sm = Schema::getConnection()->getDoctrineSchemaManager(); - $doctrineTable = $sm->listTableDetails('topics'); - - if (!$doctrineTable->hasIndex('created_at')) { + if (!Schema::hasIndex('topics', 'created_at')) { $table->index('created_at'); } }); Schema::table('torrents', function (Blueprint $table): void { - $sm = Schema::getConnection()->getDoctrineSchemaManager(); - $doctrineTable = $sm->listTableDetails('torrents'); - - if (!$doctrineTable->hasIndex('status')) { + if (!Schema::hasIndex('torrents', 'status')) { $table->index('status'); } - if (!$doctrineTable->hasIndex('seeders')) { + if (!Schema::hasIndex('torrents', 'seeders')) { $table->index('seeders'); } - if (!$doctrineTable->hasIndex('leechers')) { + if (!Schema::hasIndex('torrents', 'leechers')) { $table->index('leechers'); } - if (!$doctrineTable->hasIndex('sticky')) { + if (!Schema::hasIndex('torrents', 'sticky')) { $table->index('sticky'); } - if (!$doctrineTable->hasIndex('created_at')) { + if (!Schema::hasIndex('torrents', 'created__at')) { $table->index('created_at'); } - if (!$doctrineTable->hasIndex('bumped_at')) { + if (!Schema::hasIndex('torrents', 'bumped_at')) { $table->index('bumped_at'); } }); Schema::table('users', function (Blueprint $table): void { - $sm = Schema::getConnection()->getDoctrineSchemaManager(); - $doctrineTable = $sm->listTableDetails('users'); - - if (!$doctrineTable->hasIndex('deleted_at')) { + if (!Schema::hasIndex('users', 'deleted_at')) { $table->index('deleted_at'); } }); From 0f52a11201bdfc17ac74ccf986b563bebaa9eb44 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Tue, 23 Apr 2024 17:01:17 -0400 Subject: [PATCH 50/61] fix: other.php config - This value needs to be a int and not a string due to carbon changes. - Tests: 390 incomplete, 334 passed (755 assertions) 23.5% Coverage --- config/other.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/other.php b/config/other.php index 72ad30f5d1..c2d34965e4 100644 --- a/config/other.php +++ b/config/other.php @@ -121,7 +121,7 @@ | Exempt these groups from the invite restrictions */ 'invite-only' => true, - 'invite_expire' => '14', + 'invite_expire' => 14, 'invites_restriced' => false, 'invite_groups' => [ From b3b04f63ecf586098211a6b4d0e62557895d243a Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Tue, 23 Apr 2024 17:10:12 -0400 Subject: [PATCH 51/61] update: mysql-schema.sql --- database/schema/mysql-schema.sql | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/database/schema/mysql-schema.sql b/database/schema/mysql-schema.sql index 9200da92af..b6b95e5ef6 100644 --- a/database/schema/mysql-schema.sql +++ b/database/schema/mysql-schema.sql @@ -163,7 +163,7 @@ DROP TABLE IF EXISTS `automatic_torrent_freeleeches`; CREATE TABLE `automatic_torrent_freeleeches` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `position` int unsigned NOT NULL, - `name_regex` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `name_regex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `size` bigint unsigned DEFAULT NULL, `category_id` int DEFAULT NULL, `type_id` int DEFAULT NULL, @@ -622,9 +622,9 @@ DROP TABLE IF EXISTS `forum_categories`; CREATE TABLE `forum_categories` ( `id` smallint unsigned NOT NULL AUTO_INCREMENT, `position` smallint unsigned NOT NULL, - `slug` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `description` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `slug` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`) @@ -666,7 +666,7 @@ CREATE TABLE `forums` ( `forum_category_id` smallint unsigned NOT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, - `default_topic_state_filter` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `default_topic_state_filter` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`), KEY `forums_last_post_user_id_foreign` (`last_post_user_id`), KEY `forums_last_topic_id_foreign` (`last_topic_id`), @@ -737,7 +737,7 @@ CREATE TABLE `gifts` ( `sender_id` int unsigned DEFAULT NULL, `recipient_id` int unsigned DEFAULT NULL, `bon` decimal(22,2) NOT NULL, - `message` text COLLATE utf8mb4_unicode_ci NOT NULL, + `message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `gifts_sender_id_foreign` (`sender_id`), @@ -770,6 +770,7 @@ CREATE TABLE `groups` ( `position` int NOT NULL, `level` int NOT NULL DEFAULT '0', `download_slots` int DEFAULT NULL, + `description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `color` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `effect` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'none', @@ -1674,7 +1675,7 @@ CREATE TABLE `ticket_notes` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `user_id` int unsigned NOT NULL, `ticket_id` int unsigned NOT NULL, - `message` text COLLATE utf8mb4_unicode_ci NOT NULL, + `message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), @@ -2283,7 +2284,7 @@ DROP TABLE IF EXISTS `whitelisted_image_urls`; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `whitelisted_image_urls` ( `id` int unsigned NOT NULL AUTO_INCREMENT, - `pattern` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `pattern` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), @@ -2632,3 +2633,4 @@ INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (289,'2024_02_26_00 INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (290,'2024_03_06_062526_add_open_topics_to_forums',5); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (291,'2024_03_06_154000_add_user_indexes_to_torrents_table',5); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (292,'2024_03_19_211512_create_ticket_notes_table',5); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (293,'2024_03_21_145139_add_group_description',6); From 4f10a0f15519b463b29efd850fc9652c2d34a9ac Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Tue, 23 Apr 2024 17:17:07 -0400 Subject: [PATCH 52/61] chore: composer bump --- composer.json | 10 +++++----- composer.lock | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index bd37a14161..df424e99f5 100644 --- a/composer.json +++ b/composer.json @@ -25,14 +25,14 @@ "intervention/image": "^2.7.2", "joypixels/assets": "^v7.0.1", "laravel/fortify": "1.20.0", - "laravel/framework": "^v11.4.0", + "laravel/framework": "^11.5.0", "laravel/tinker": "^2.9.0", "livewire/livewire": "^v3.4.10", "marcreichel/igdb-laravel": "^4.2.0", "paragonie/constant_time_encoding": "^2.6.3", "spatie/laravel-backup": "^8.6.0", "spatie/laravel-cookie-consent": "^3.3.0", - "spatie/laravel-image-optimizer": "^1.6.2", + "spatie/laravel-image-optimizer": "^1.8.0", "spatie/ssl-certificate": "^2.6.5", "symfony/dom-crawler": "^6.4.4", "theodorejb/polycast": "dev-master", @@ -44,8 +44,8 @@ "calebdw/larastan-livewire": "^1.0.1", "fakerphp/faker": "^1.23.1", "jasonmccreary/laravel-test-assertions": "^2.4", - "larastan/larastan": "^2.9.2", - "laravel/pint": "^1.15.1", + "larastan/larastan": "^2.9.5", + "laravel/pint": "^1.15.2", "laravel/sail": "^1.29.1", "mockery/mockery": "^1.6.11", "nunomaduro/collision": "^v8.1.1", @@ -54,7 +54,7 @@ "pestphp/pest-plugin-livewire": "^v2.1.0", "phpunit/phpunit": "10.5.17", "ryoluo/sail-ssl": "^1.3.2", - "spatie/laravel-ignition": "^2.5.1" + "spatie/laravel-ignition": "^2.5.2" }, "config": { "preferred-install": "dist", diff --git a/composer.lock b/composer.lock index ab57e7c797..89d1015162 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d1ef91bd9590b6b666bec3f9571947d9", + "content-hash": "2a9a83a02cc360d8214d30b2e8ee6017", "packages": [ { "name": "assada/laravel-achievements", From e4dd9bfa9b4466347c17abe79e56192dabeb7785 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Tue, 23 Apr 2024 22:29:21 -0400 Subject: [PATCH 53/61] update: configs --- config/broadcasting.php | 2 +- config/cache.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/broadcasting.php b/config/broadcasting.php index b9cb090f9d..6a5ac68f90 100644 --- a/config/broadcasting.php +++ b/config/broadcasting.php @@ -14,7 +14,7 @@ | */ - 'default' => env('BROADCAST_DRIVER', 'null'), + 'default' => env('BROADCAST_CONNECTION', 'null'), /* |-------------------------------------------------------------------------- diff --git a/config/cache.php b/config/cache.php index 632bea6726..257e444a7e 100644 --- a/config/cache.php +++ b/config/cache.php @@ -14,7 +14,7 @@ | */ - 'default' => env('CACHE_DRIVER', 'file'), + 'default' => env('CACHE_STORE', 'file'), /* |-------------------------------------------------------------------------- From bd54a2334d599ca0fe25acbcbc0d9d4f8df44d68 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Wed, 24 Apr 2024 10:15:54 -0400 Subject: [PATCH 54/61] fix: carbon issues --- app/Http/Controllers/API/TorrentController.php | 4 ++-- app/Http/Controllers/TorrentBuffController.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/API/TorrentController.php b/app/Http/Controllers/API/TorrentController.php index 37e7a7ee81..9ea139382c 100644 --- a/app/Http/Controllers/API/TorrentController.php +++ b/app/Http/Controllers/API/TorrentController.php @@ -167,13 +167,13 @@ public function store(Request $request): \Illuminate\Http\JsonResponse $du_until = $request->input('du_until'); if (($user->group->is_modo || $user->group->is_internal) && isset($du_until)) { - $torrent->du_until = Carbon::now()->addDays($request->input('du_until')); + $torrent->du_until = Carbon::now()->addDays($request->integer('du_until')); } $torrent->free = $user->group->is_modo || $user->group->is_internal ? ($request->input('free') ?? 0) : 0; $fl_until = $request->input('fl_until'); if (($user->group->is_modo || $user->group->is_internal) && isset($fl_until)) { - $torrent->fl_until = Carbon::now()->addDays($request->input('fl_until')); + $torrent->fl_until = Carbon::now()->addDays($request->integer('fl_until')); } $torrent->sticky = $user->group->is_modo || $user->group->is_internal ? ($request->input('sticky') ?? 0) : 0; $torrent->moderated_at = Carbon::now(); diff --git a/app/Http/Controllers/TorrentBuffController.php b/app/Http/Controllers/TorrentBuffController.php index 7f104090a6..6be490e6cf 100644 --- a/app/Http/Controllers/TorrentBuffController.php +++ b/app/Http/Controllers/TorrentBuffController.php @@ -102,7 +102,7 @@ public function grantFL(Request $request, int $id): \Illuminate\Http\RedirectRes if ($request->freeleech != 0) { if ($request->fl_until !== null) { - $torrent->fl_until = Carbon::now()->addDays($request->fl_until); + $torrent->fl_until = Carbon::now()->addDays($request->integer('fl_until')); $this->chatRepository->systemMessage( sprintf('Ladies and Gents, [url=%s]%s[/url] has been granted %s%% FreeLeech for '.$request->fl_until.' days.', $torrentUrl, $torrent->name, $request->freeleech) ); @@ -212,7 +212,7 @@ public function grantDoubleUp(Request $request, int $id): \Illuminate\Http\Redir $du_until = $request->input('du_until'); if ($du_until !== null) { - $torrent->du_until = Carbon::now()->addDays($request->input('du_until')); + $torrent->du_until = Carbon::now()->addDays($request->integer('du_until')); $this->chatRepository->systemMessage( sprintf('Ladies and Gents, [url=%s]%s[/url] has been granted Double Upload for '.$request->input('du_until').' days.', $torrentUrl, $torrent->name) ); From a7fc767051f78673a9fd1203e440a640e74fe843 Mon Sep 17 00:00:00 2001 From: HDVinnie Date: Wed, 24 Apr 2024 10:17:44 -0400 Subject: [PATCH 55/61] fix: user search - this was supposed to include soft deleted users not only soft deleted users. --- app/Http/Livewire/UserSearch.php | 2 +- resources/views/livewire/user-search.blade.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Livewire/UserSearch.php b/app/Http/Livewire/UserSearch.php index 0552df80e3..b2cbd00471 100644 --- a/app/Http/Livewire/UserSearch.php +++ b/app/Http/Livewire/UserSearch.php @@ -86,7 +86,7 @@ final public function users(): \Illuminate\Contracts\Pagination\LengthAwarePagin ->when($this->apikey !== '', fn ($query) => $query->where('api_token', 'LIKE', '%'.$this->apikey.'%')) ->when($this->passkey !== '', fn ($query) => $query->where('passkey', 'LIKE', '%'.$this->passkey.'%')) ->when($this->groupId !== null, fn ($query) => $query->where('group_id', '=', $this->groupId)) - ->when($this->show === true, fn ($query) => $query->onlyTrashed()) + ->when($this->show === true, fn ($query) => $query->withTrashed()) ->orderBy($this->sortField, $this->sortDirection) ->paginate($this->perPage); } diff --git a/resources/views/livewire/user-search.blade.php b/resources/views/livewire/user-search.blade.php index 56d5df9eed..7da924b9f7 100644 --- a/resources/views/livewire/user-search.blade.php +++ b/resources/views/livewire/user-search.blade.php @@ -93,7 +93,7 @@ class="form__checkbox" type="checkbox" wire:click="toggleProperties('show')" /> - +