diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 69a14186b7..538fdb7061 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,6 +96,11 @@ Common syntax | Shorter and more readable syntax `->orderBy('age', 'desc')` | `->latest('age')` `->orderBy('created_at', 'asc')` | `->oldest()` +### CSS + +CSS should follow the [BEM methodology](https://getbem.com/) and the [7-1 SCSS Architecture](https://sass-guidelin.es/#the-7-1-pattern). + +Any new pages should use the existing component styles unless a new block, element and/or modifier is being added. It is highly discouraged to add new components when an existing one will do. ## Other diff --git a/README.md b/README.md index ad536e3a6e..26af8d14c7 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@

UNIT3D Community Edition

- + - +

- 🎉A Big Thanks To All Our Contributors and Sponsors🎉 + 🎉 A Big Thanks To All Our Contributors and Subscribers 🎉

## 📝 Table of Contents @@ -20,15 +20,14 @@ 1. [Introduction](#introduction) 2. [Installation](#installation) 3. [Updating](#updating) -4. [Demo Site](#demo) -5. [Support UNIT3D](#support) -6. [Funding Issues/Requests](#funding) -7. [Special Thanks](#thanks) +4. [Support UNIT3D](#support) +5. [Funding Issues/Requests](#funding) +6. [Special Thanks](#thanks) ## 🧐 Introduction -We have been developing a Private Torrent Tracker Software called `UNIT3D`. This is a PHP software based on Laravel 10, Livewire and AlpineJS. It is MySQL Strict Mode Compliant, and PHP 8.2 Ready. The code is well-designed and follows the PSR-2 coding style. It uses an MVC Architecture to ensure clarity between logic and presentation. As a hashing algorithm of Bcrypt or Argon2 is used, to ensure a safe and proper way to store the passwords for the users. A lightweight Blade Templating Engine. Caching System Supporting: "apc,” "array,” "database,” "file," "memcached," and "redis" methods. Eloquent and much more! +We have been developing a Private Torrent Tracker Software called `UNIT3D`. This is a PHP software based on Laravel 11, Livewire and AlpineJS. It is MySQL Strict Mode Compliant, and PHP 8.3 Ready. The code is well-designed and follows the PSR-2 coding style. It uses an MVC Architecture to ensure clarity between logic and presentation. As a hashing algorithm of Bcrypt or Argon2 is used, to ensure a safe and proper way to store the passwords for the users. A lightweight Blade Templating Engine. Caching System Supporting: "apc,” "array,” "database,” "file," "memcached," and "redis" methods. Eloquent and much more! ## 🖥️ Installation @@ -43,8 +42,6 @@ Use this command to generate demo users and torrents for testing purposes in a d ## 🖥️ Updating `php artisan git:update` -## 🖥️ Demo Site -https://unit3d.dev ## ✨ Support UNIT3D @@ -61,8 +58,8 @@ Bitcoin (BTC) - 3HUVkv3Q8b5nbxa9DtXG1dm4RdTJaTFRfc Bitcoin Cash (BCH) - qp3wgpnwzpj4v9sq90wflsca8p5s75glrvga9tweu2 Ether (ETH) - 0x5eFF42F65234aD9c6A0CA5B9495f3c6D205bBC27 - -ETC - 0xd644C7C7009eC3824f3305ff6C7E2Ee90497d56e + +ETC - 0xd644C7C7009eC3824f3305ff6C7E2Ee90497d56e Litecoin (LTC) - MDLKyHzupt1mchuo8mrjW9mihkKp1LD4nG diff --git a/app/Bots/NerdBot.php b/app/Bots/NerdBot.php index d5804e5969..4d9b3af2cc 100644 --- a/app/Bots/NerdBot.php +++ b/app/Bots/NerdBot.php @@ -156,14 +156,25 @@ public function getBans(): string $bans = cache()->remember( 'nerdbot-bans', $this->expiresAt, - fn () => Ban::whereNull('unban_reason') - ->whereNull('removed_at') + fn () => Ban::whereNotNull('ban_reason') ->where('created_at', '>', $this->current->subDay())->count() ); return "In the last 24 hours, {$bans} users have been banned from {$this->site}"; } + public function getUnbans(): string + { + $unbans = cache()->remember( + 'nerdbot-unbans', + $this->expiresAt, + fn () => Ban::whereNotNull('unban_reason') + ->where('removed_at', '>', $this->current->subDay())->count() + ); + + return "In the last 24 hours, {$unbans} users have been unbanned from {$this->site}"; + } + public function getWarnings(): string { $warnings = cache()->remember( @@ -254,6 +265,7 @@ public function process(string $type, User $user, string $message = '', int $tar $log = match($command[$x]) { 'banker' => $this->getBanker(), 'bans' => $this->getBans(), + 'unbans' => $this->getUnbans(), 'doubleupload' => $this->getDoubleUpload(), 'freeleech' => $this->getFreeleech(), 'help' => $this->getHelp(), diff --git a/app/Console/Commands/AutoNerdStat.php b/app/Console/Commands/AutoNerdStat.php index ba3593f799..55f557152a 100644 --- a/app/Console/Commands/AutoNerdStat.php +++ b/app/Console/Commands/AutoNerdStat.php @@ -71,6 +71,7 @@ final public function handle(): void 'du', 'peers', 'bans', + 'unbans', 'warnings', 'king', ])->random(); @@ -87,7 +88,8 @@ final public function handle(): void 'fl100' => 'There Are Currently [color=#93c47d][b]'.DB::table('torrents')->where('free', '=', 100)->count().'[/b][/color] 100% Freeleech Torrents On '.config('other.title').'!', 'du' => 'There Are Currently [color=#93c47d][b]'.DB::table('torrents')->where('doubleup', '=', 1)->count().'[/b][/color] Double Upload Torrents On '.config('other.title').'!', 'peers' => 'Currently There Are [color=#93c47d][b]'.DB::table('peers')->where('active', '=', 1)->count().'[/b][/color] Peers On '.config('other.title').'!', - 'bans' => 'In The Last 24 Hours [color=#dd7e6b][b]'.DB::table('bans')->whereNull('unban_reason')->whereNull('removed_at')->where('created_at', '>', now()->subDay())->count().'[/b][/color] Users Have Been Banned From '.config('other.title').'!', + 'bans' => 'In The Last 24 Hours [color=#dd7e6b][b]'.DB::table('bans')->whereNotNull('ban_reason')->where('created_at', '>', now()->subDay())->count().'[/b][/color] Users Have Been Banned From '.config('other.title').'!', + 'unbans' => 'In The Last 24 Hours [color=#dd7e6b][b]'.DB::table('bans')->whereNotNull('unban_reason')->where('removed_at', '>', now()->subDay())->count().'[/b][/color] Users Have Been Unbanned From '.config('other.title').'!', 'warnings' => 'In The Last 24 Hours [color=#dd7e6b][b]'.DB::table('warnings')->where('created_at', '>', now()->subDay())->count().'[/b][/color] Hit and Run Warnings Have Been Issued On '.config('other.title').'!', 'king' => config('other.title').' Is King!', default => 'Nerd Stat Error!', diff --git a/app/Console/Commands/AutoRefundDownload.php b/app/Console/Commands/AutoRefundDownload.php index cf7897521c..6e933b1d29 100644 --- a/app/Console/Commands/AutoRefundDownload.php +++ b/app/Console/Commands/AutoRefundDownload.php @@ -64,8 +64,8 @@ final public function handle(): void ->whereColumn('torrents.user_id', '!=', 'history.user_id') ->when(!config('other.refundable'), fn ($query) => $query->where( fn ($query) => $query - ->where('groups.is_refundable', '=', 1) - ->orWhere('torrents.refundable', '=', 1) + ->where('groups.is_refundable', '=', true) + ->orWhere('torrents.refundable', '=', true) )) ->update([ 'history.refunded_download' => DB::raw('history.refunded_download + (@delta := LEAST(1, history.seedtime / '.(int) $FULL_REFUND_SEEDTIME.') * torrents.size - history.refunded_download)'), diff --git a/app/Console/Commands/AutoRemoveTimedTorrentBuffs.php b/app/Console/Commands/AutoRemoveTimedTorrentBuffs.php index 0607b63a61..321e2ad969 100644 --- a/app/Console/Commands/AutoRemoveTimedTorrentBuffs.php +++ b/app/Console/Commands/AutoRemoveTimedTorrentBuffs.php @@ -70,6 +70,10 @@ final public function handle(): void Unit3dAnnounce::addTorrent($torrent); } + Torrent::query()->whereNotNull('bumped_at')->where('bumped_at', '<', now()->subWeek())->update([ + 'bumped_at' => null, + ]); + $this->comment('Automated Removal Of Expired Torrent Buffs Command Complete'); } } diff --git a/app/Console/Commands/AutoSyncPeopleToMeilisearch.php b/app/Console/Commands/AutoSyncPeopleToMeilisearch.php new file mode 100644 index 0000000000..ff9055cad2 --- /dev/null +++ b/app/Console/Commands/AutoSyncPeopleToMeilisearch.php @@ -0,0 +1,65 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Console\Commands; + +use App\Models\Person; +use Exception; +use Illuminate\Console\Command; +use Meilisearch\Client; + +class AutoSyncPeopleToMeilisearch extends Command +{ + /** + * The name and signature of the console command. + * + * @var string + */ + protected $signature = 'auto:sync_people_to_meilisearch'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Syncs people to Meilisearch'; + + /** + * Execute the console command. + * + * @throws Exception + */ + public function handle(): void + { + $start = now(); + + $client = new Client(config('scout.meilisearch.host'), config('scout.meilisearch.key')); + $index = $client->index('people'); + + $people = Person::all(['id', 'name', 'birthday', 'still']); + + $documents = $people->map(fn ($person) => [ + 'id' => $person->id, + 'name' => $person->name, + 'birthday' => $person->birthday, + 'still' => $person->still, + ])->toArray(); + + $index->addDocuments($documents); + + $this->comment('Synced all people to Meilisearch in '.(now()->diffInMilliseconds($start) / 1000).' seconds.'); + } +} diff --git a/app/Console/Commands/AutoSyncTorrentsToMeilisearch.php b/app/Console/Commands/AutoSyncTorrentsToMeilisearch.php index b627596494..201d4d7e89 100644 --- a/app/Console/Commands/AutoSyncTorrentsToMeilisearch.php +++ b/app/Console/Commands/AutoSyncTorrentsToMeilisearch.php @@ -19,6 +19,7 @@ use App\Models\Torrent; use Exception; use Illuminate\Console\Command; +use Meilisearch\Client; class AutoSyncTorrentsToMeilisearch extends Command { @@ -45,6 +46,14 @@ public function handle(): void { $start = now(); + $client = new Client(config('scout.meilisearch.host'), config('scout.meilisearch.key')); + + $index = $client->getIndex('torrents'); + + $index->updatePagination([ + 'maxTotalHits' => max(1, Torrent::query()->count()) + 1000, + ]); + if ($this->option('wipe')) { Torrent::removeAllFromSearch(); Torrent::query()->selectRaw(Torrent::SEARCHABLE)->searchable(); diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 3cbbd25513..ddcbc93385 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -64,6 +64,7 @@ protected function schedule(Schedule $schedule): void $schedule->command('auto:refund_download')->daily(); $schedule->command('auth:clear-resets')->daily(); $schedule->command('auto:sync_torrents_to_meilisearch')->everyFifteenMinutes(); + $schedule->command('auto:sync_people_to_meilisearch')->daily(); $schedule->command('auto:remove_expired_donors')->daily(); //$schedule->command('auto:ban_disposable_users')->weekends(); $schedule->command('backup:clean')->daily(); diff --git a/app/DTO/TorrentSearchFiltersDTO.php b/app/DTO/TorrentSearchFiltersDTO.php index 88b295599c..6f8c5313c1 100644 --- a/app/DTO/TorrentSearchFiltersDTO.php +++ b/app/DTO/TorrentSearchFiltersDTO.php @@ -176,7 +176,7 @@ final public function toMeilisearchFilter(): array } if ($this->keywords !== []) { - $filters[] = 'keywords.name IN '.json_encode($this->keywords); + $filters[] = 'keywords IN '.json_encode($this->keywords); } if ($this->startYear !== null) { @@ -330,6 +330,10 @@ final public function toMeilisearchFilter(): array $filters[] = 'internal = true'; } + if ($this->trumpable) { + $filters[] = 'trumpable = true'; + } + if ($this->personalRelease) { $filters[] = 'personal_release = true'; } @@ -368,11 +372,15 @@ final public function toMeilisearchFilter(): array } if ($this->userDownloaded === true) { - $filters[] = 'history_complete.user_id = '.$this->user->id; + $filters[] = [ + 'history_complete.user_id = '.$this->user->id, + 'history_incomplete.user_id = '.$this->user->id, + ]; } if ($this->userDownloaded === false) { - $filters[] = 'history_incomplete.user_id = '.$this->user->id; + $filters[] = 'history_complete.user_id != '.$this->user->id; + $filters[] = 'history_incomplete.user_id != '.$this->user->id; } if ($this->userSeeder === false) { diff --git a/app/Exceptions/TrackerException.php b/app/Exceptions/TrackerException.php index 8cbcddb9c0..33b25e670c 100644 --- a/app/Exceptions/TrackerException.php +++ b/app/Exceptions/TrackerException.php @@ -53,7 +53,7 @@ class TrackerException extends Exception 138 => 'You have reached a rate limit. You can only seed/leech a single torrent from upto :limit locations.', // Error message about User Account - 140 => 'Passkey does not esist! Please Re-download the .torrent', + 140 => 'Passkey does not exist! Please Re-download the .torrent', 141 => 'Your account is not enabled! ( Current `:status` )', 142 => 'Your downloading privileges have been disabled! (Read the rules)', diff --git a/app/Helpers/Bbcode.php b/app/Helpers/Bbcode.php index 54122fe37c..fae28105ea 100755 --- a/app/Helpers/Bbcode.php +++ b/app/Helpers/Bbcode.php @@ -280,6 +280,7 @@ public function parse(?string $source, bool $replaceLineBreaks = true): string { // Replace all void elements since they don't have closing tags $source = str_replace('[*]', '
  • ', (string) $source); + $source = str_replace('[hr]', '
    ', $source); $source = preg_replace_callback( '/\[url](.*?)\[\/url]/i', fn ($matches) => ''.$this->sanitizeUrl($matches[1]).'', @@ -511,7 +512,7 @@ private function sanitizeUrl(string $url, ?bool $isImage = null): string }); if (!$isWhitelisted) { - $url = 'https://wsrv.nl/?n=-1&url='.urlencode($url); + $url = 'https://wsrv.nl/?n=-1&ll&url='.urlencode($url); } } diff --git a/app/Http/Controllers/API/QuickSearchController.php b/app/Http/Controllers/API/QuickSearchController.php new file mode 100644 index 0000000000..2fccf05053 --- /dev/null +++ b/app/Http/Controllers/API/QuickSearchController.php @@ -0,0 +1,109 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Http\Controllers\API; + +use App\Http\Controllers\Controller; +use Illuminate\Http\Request; +use Meilisearch\Client; +use Meilisearch\Contracts\FederationOptions; +use Meilisearch\Contracts\MultiSearchFederation; +use Meilisearch\Contracts\SearchQuery; + +class QuickSearchController extends Controller +{ + public function index(Request $request): \Illuminate\Http\JsonResponse + { + $query = $request->input('query'); + + $filters = [ + 'deleted_at IS NULL', + 'status = 1', + [ + 'category.movie_meta = true', + 'category.tv_meta = true', + ], + [ + 'movie.name EXISTS', + 'tv.name EXISTS', + ] + ]; + + // Check if the query is an IMDb or TMDB ID + $searchById = false; + + if (preg_match('/^(\d+)$/', $query, $matches)) { + $filters[] = 'tmdb = '.$matches[1]; + $searchById = true; + } + + if (preg_match('/tt0*(?=(\d{7,}))/', $query, $matches)) { + $filters[] = 'imdb = '.$matches[1]; + $searchById = true; + } + + $client = new Client(config('scout.meilisearch.host'), config('scout.meilisearch.key')); + + // Prepare the search queries + $searchQueries = [ + (new SearchQuery()) + ->setIndexUid('torrents') + ->setQuery($searchById ? '' : $query) + ->setFilter($filters) + ->setDistinct('imdb') + ]; + + // Add the people search query only if it's not an ID search + if (!$searchById) { + $searchQueries[] = (new SearchQuery()) + ->setIndexUid('people') + ->setQuery($query); + //->setFederationOptions((new FederationOptions())->setWeight(0.9)); + } + + // Perform multi-search with MultiSearchFederation + $multiSearchResults = $client->multiSearch($searchQueries, ((new MultiSearchFederation()))->setLimit(20)); + + $results = []; + + // Process the hits from the multiSearchResults + foreach ($multiSearchResults['hits'] as $hit) { + if ($hit['_federation']['indexUid'] === 'torrents') { + $type = $hit['category']['movie_meta'] === true ? 'movie' : 'tv'; + + $results[] = [ + 'id' => $hit['id'], + 'name' => $hit[$type]['name'], + 'year' => $hit[$type]['year'], + 'image' => $hit[$type]['poster'] ? tmdb_image('poster_small', $hit[$type]['poster']) : 'https://via.placeholder.com/90x135', + 'url' => route('torrents.similar', ['category_id' => $hit['category']['id'], 'tmdb' => $hit['tmdb']]), + 'type' => $type === 'movie' ? 'Movie' : 'TV Series', + ]; + } elseif ($hit['_federation']['indexUid'] === 'people') { + $results[] = [ + 'id' => $hit['id'], + 'name' => $hit['name'], + 'year' => $hit['birthday'], + 'image' => $hit['still'] ? tmdb_image('poster_small', $hit['still']) : 'https://via.placeholder.com/90x135', + 'url' => route('mediahub.persons.show', ['id' => $hit['id']]), + 'type' => 'Person', + ]; + } + } + + return response()->json(['results' => $results]); + } +} diff --git a/app/Http/Controllers/API/TorrentController.php b/app/Http/Controllers/API/TorrentController.php index 17783916e6..f8b4a30db5 100644 --- a/app/Http/Controllers/API/TorrentController.php +++ b/app/Http/Controllers/API/TorrentController.php @@ -169,7 +169,7 @@ public function store(Request $request): \Illuminate\Http\JsonResponse $torrent->internal = $user->group->is_modo || $user->group->is_internal ? ($request->input('internal') ?? 0) : 0; $torrent->featured = $user->group->is_modo || $user->group->is_internal ? ($request->input('featured') ?? false) : false; $torrent->doubleup = $user->group->is_modo || $user->group->is_internal ? ($request->input('doubleup') ?? 0) : 0; - $torrent->refundable = $user->group->is_modo || $user->group->is_internal ? ($request->input('refundable') ?? 0) : 0; + $torrent->refundable = $user->group->is_modo || $user->group->is_internal ? ($request->input('refundable') ?? false) : false; $du_until = $request->input('du_until'); if (($user->group->is_modo || $user->group->is_internal) && isset($du_until)) { @@ -486,9 +486,9 @@ public function show(int $id): TorrentResource */ public function filter(Request $request): TorrentsResource|\Illuminate\Http\JsonResponse { - $user = auth()->user(); + $user = auth()->user()->load('group'); $isRegexAllowed = $user->group->is_modo; - $isSqlAllowed = $user->group->is_modo && $request->driver === 'sql'; + $isSqlAllowed = ($user->group->is_modo || $user->group->is_editor) && $request->driver === 'sql'; $request->validate([ 'sortField' => [ diff --git a/app/Http/Controllers/ClaimedPrizeController.php b/app/Http/Controllers/ClaimedPrizeController.php new file mode 100644 index 0000000000..163bada7ae --- /dev/null +++ b/app/Http/Controllers/ClaimedPrizeController.php @@ -0,0 +1,90 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Http\Controllers; + +use App\Models\ClaimedPrize; +use App\Models\Event; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; + +class ClaimedPrizeController extends Controller +{ + /** + * Store a newly created resource in storage. + */ + public function store(Request $request, Event $event): \Illuminate\Http\RedirectResponse + { + if (!$event->active) { + return back()->withErrors('Event is not active.'); + } + + if (!now()->isBetween($event->starts_at, $event->ends_at)) { + return back()->withErrors('Prizes are not currently available.'); + } + + return DB::transaction(function () use ($request, $event) { + $prizeExists = ClaimedPrize::query() + ->whereBelongsTo($request->user()) + ->whereBelongsTo($event) + ->where('created_at', '>', now()->startOfDay()) + ->exists(); + + if ($prizeExists) { + return back()->withErrors('You have already claimed your daily prize. Check back tomorrow!'); + } + + $prizes = $event->prizes; + $randomNumber = random_int(1, $prizes->sum('weight') ?: 1); + $selectedPrize = null; + + foreach ($prizes as $prize) { + if ($randomNumber <= $prize->weight) { + $selectedPrize = $prize; + + break; + } + + $randomNumber -= $prize->weight; + } + + $bon_won = 0; + $fl_tokens_won = 0; + + switch ($selectedPrize?->type) { + case 'bon': + $bon_won = random_int($selectedPrize->min, $selectedPrize->max); + $request->user()->increment('seedbonus', $bon_won); + + break; + case 'fl_tokens': + $fl_tokens_won = random_int($selectedPrize->min, $selectedPrize->max); + $request->user()->increment('fl_tokens', $fl_tokens_won); + + break; + } + + ClaimedPrize::create([ + 'user_id' => $request->user()->id, + 'event_id' => $event->id, + 'bon' => $bon_won, + 'fl_tokens' => $fl_tokens_won, + ]); + + return to_route('events.show', ['event' => $event])->withSuccess('Congrats! You have won a prize!'); + }); + } +} diff --git a/app/Http/Controllers/EventController.php b/app/Http/Controllers/EventController.php new file mode 100644 index 0000000000..632c7cbcb3 --- /dev/null +++ b/app/Http/Controllers/EventController.php @@ -0,0 +1,48 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Http\Controllers; + +use App\Models\Event; +use Illuminate\Http\Request; + +class EventController extends Controller +{ + /** + * Display a listing of the resource. + */ + public function index(): \Illuminate\Contracts\View\Factory|\Illuminate\View\View + { + return view('event.index', [ + 'events' => Event::query()->where('active', '=', true)->orderBy('starts_at')->get(), + ]); + } + + /** + * Display the specified resource. + */ + public function show(Request $request, Event $event): \Illuminate\Contracts\View\Factory|\Illuminate\View\View + { + return view('event.show', [ + 'event' => $event, + 'userPrizes' => $event + ->claimedPrizes() + ->where('user_id', '=', $request->user()->id) + ->get() + ->groupBy(fn ($claimedPrize) => $claimedPrize->created_at->diffInDays($event->starts_at)), + ]); + } +} diff --git a/app/Http/Controllers/RssController.php b/app/Http/Controllers/RssController.php index 86b1d7ce43..924fb2bb6e 100644 --- a/app/Http/Controllers/RssController.php +++ b/app/Http/Controllers/RssController.php @@ -41,8 +41,8 @@ public function index(Request $request, ?string $hash = null): \Illuminate\Contr { return view('rss.index', [ 'hash' => $hash, - 'public_rss' => Rss::where('is_private', '=', 0)->oldest('position')->get(), - 'private_rss' => Rss::where('is_private', '=', 1)->where('user_id', '=', $request->user()->id)->latest()->get(), + 'public_rss' => Rss::where('is_private', '=', false)->oldest('position')->get(), + 'private_rss' => Rss::where('is_private', '=', true)->where('user_id', '=', $request->user()->id)->latest()->get(), 'user' => $request->user(), ]); } @@ -144,7 +144,7 @@ public function show(int $id, string $rsskey): \Illuminate\Http\Response ->where( fn ($query) => $query ->where('user_id', '=', $user->id) - ->orWhere('is_private', '=', 0) + ->orWhere('is_private', '=', false) ) ->findOrFail($id); @@ -217,7 +217,7 @@ function (Indexes $meilisearch, string $query, array $options) use ($filters) { public function edit(Request $request, int $id): \Illuminate\Contracts\View\Factory|\Illuminate\View\View { $user = $request->user(); - $rss = Rss::where('is_private', '=', 1)->findOrFail($id); + $rss = Rss::where('is_private', '=', true)->findOrFail($id); abort_unless($user->group->is_modo || $user->id === $rss->user_id, 403); @@ -237,7 +237,7 @@ public function edit(Request $request, int $id): \Illuminate\Contracts\View\Fact public function update(Request $request, int $id): \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response { $user = $request->user(); - $rss = Rss::where('is_private', '=', 1)->findOrFail($id); + $rss = Rss::where('is_private', '=', true)->findOrFail($id); abort_unless($user->group->is_modo || $user->id === $rss->user_id, 403); @@ -305,7 +305,7 @@ public function update(Request $request, int $id): \Illuminate\Http\RedirectResp public function destroy(Request $request, int $id): \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response { $user = $request->user(); - $rss = Rss::where('is_private', '=', 1)->findOrFail($id); + $rss = Rss::where('is_private', '=', true)->findOrFail($id); abort_unless($user->group->is_modo || $user->id === $rss->user_id, 403); diff --git a/app/Http/Controllers/Staff/ChatBotController.php b/app/Http/Controllers/Staff/ChatBotController.php index f44cfed851..fe27cbcb02 100644 --- a/app/Http/Controllers/Staff/ChatBotController.php +++ b/app/Http/Controllers/Staff/ChatBotController.php @@ -80,7 +80,7 @@ public function destroy(Bot $bot): \Illuminate\Http\RedirectResponse public function disable(Bot $bot): \Illuminate\Http\RedirectResponse { $bot->update([ - 'active' => 0, + 'active' => false, ]); return to_route('staff.bots.index') @@ -93,7 +93,7 @@ public function disable(Bot $bot): \Illuminate\Http\RedirectResponse public function enable(Bot $bot): \Illuminate\Http\RedirectResponse { $bot->update([ - 'active' => 1, + 'active' => true, ]); return to_route('staff.bots.index') diff --git a/app/Http/Controllers/Staff/EventController.php b/app/Http/Controllers/Staff/EventController.php new file mode 100644 index 0000000000..b386ffeb03 --- /dev/null +++ b/app/Http/Controllers/Staff/EventController.php @@ -0,0 +1,71 @@ + Event::all(), + ]); + } + + /** + * Show the form for creating a new resource. + */ + public function create(): \Illuminate\Contracts\View\Factory|\Illuminate\View\View + { + return view('Staff.event.create'); + } + + /** + * Store a newly created resource in storage. + */ + public function store(StoreEventRequest $request): \Illuminate\Http\RedirectResponse + { + Event::create($request->validated()); + + return to_route('staff.events.index'); + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(Event $event): \Illuminate\Contracts\View\Factory|\Illuminate\View\View + { + return view('Staff.event.edit', [ + 'event' => $event->load('prizes'), + ]); + } + + /** + * Update the specified resource in storage. + */ + public function update(UpdateEventRequest $request, Event $event): \Illuminate\Http\RedirectResponse + { + $event->update($request->validated()); + + return to_route('staff.events.index'); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(Event $event): \Illuminate\Http\RedirectResponse + { + $event->delete(); + + return to_route('staff.events.index'); + } +} diff --git a/app/Http/Controllers/Staff/PrizeController.php b/app/Http/Controllers/Staff/PrizeController.php new file mode 100644 index 0000000000..0c8a651342 --- /dev/null +++ b/app/Http/Controllers/Staff/PrizeController.php @@ -0,0 +1,65 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Http\Controllers\Staff; + +use App\Http\Controllers\Controller; +use App\Http\Requests\Staff\StorePrizeRequest; +use App\Http\Requests\Staff\UpdatePrizeRequest; +use App\Models\Event; +use App\Models\Prize; + +class PrizeController extends Controller +{ + /** + * Store a newly created resource in storage. + */ + public function store(StorePrizeRequest $request, Event $event): \Illuminate\Http\RedirectResponse + { + $event->prizes()->create($request->validated()); + + return to_route('staff.events.edit', [ + 'event' => $event + ]) + ->withSuccess('Prize added to event.'); + } + + /** + * Update the specified resource in storage. + */ + public function update(UpdatePrizeRequest $request, Event $event, Prize $prize): \Illuminate\Http\RedirectResponse + { + $prize->update($request->validated()); + + return to_route('staff.events.edit', [ + 'event' => $event + ]) + ->withSuccess('Prize updated.'); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(Event $event, Prize $prize): \Illuminate\Http\RedirectResponse + { + $prize->delete(); + + return to_route('staff.events.edit', [ + 'event' => $event + ]) + ->withSuccess('Prize removed from event.'); + } +} diff --git a/app/Http/Controllers/Staff/RssController.php b/app/Http/Controllers/Staff/RssController.php index acca3f2bdc..42b581c922 100644 --- a/app/Http/Controllers/Staff/RssController.php +++ b/app/Http/Controllers/Staff/RssController.php @@ -38,7 +38,7 @@ class RssController extends Controller public function index(): \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View { return view('Staff.rss.index', [ - 'public_rss' => Rss::where('is_private', '=', 0)->oldest('position')->get(), + 'public_rss' => Rss::where('is_private', '=', false)->oldest('position')->get(), ]); } diff --git a/app/Http/Controllers/TorrentBuffController.php b/app/Http/Controllers/TorrentBuffController.php index 001f6debed..f057ff574e 100644 --- a/app/Http/Controllers/TorrentBuffController.php +++ b/app/Http/Controllers/TorrentBuffController.php @@ -292,7 +292,7 @@ public function setRefundable(Request $request, int $id): \Illuminate\Http\Redir \sprintf('Ladies and Gents, [url=%s]%s[/url] is now refundable! Grab It While You Can!', $torrent_url, $torrent->name) ); } else { - $torrent->refundable = 0; + $torrent->refundable = false; $this->chatRepository->systemMessage( \sprintf('Ladies and Gents, [url=%s]%s[/url] is no longer refundable!', $torrent_url, $torrent->name) diff --git a/app/Http/Controllers/TorrentController.php b/app/Http/Controllers/TorrentController.php index cbd9bb5118..3050088cad 100644 --- a/app/Http/Controllers/TorrentController.php +++ b/app/Http/Controllers/TorrentController.php @@ -104,7 +104,10 @@ public function show(Request $request, int|string $id): \Illuminate\Contracts\Vi 'credits' => ['person', 'occupation'], 'companies', 'networks', - 'recommendedTv:id,name,poster,first_air_date' + 'recommendedTv' => fn ($query) => $query + ->select('tv.id', 'tv.name', 'tv.poster', 'tv.first_air_date') + ->withMin('torrents', 'category_id') + ->has('torrents'), ])->find($torrent->tmdb); } @@ -114,7 +117,10 @@ public function show(Request $request, int|string $id): \Illuminate\Contracts\Vi 'credits' => ['person', 'occupation'], 'companies', 'collection', - 'recommendedMovies:id,title,poster,release_date' + 'recommendedMovies' => fn ($query) => $query + ->select('movies.id', 'movies.title', 'movies.poster', 'movies.release_date') + ->withMin('torrents', 'category_id') + ->has('torrents'), ]) ->find($torrent->tmdb); } diff --git a/app/Http/Controllers/User/UserController.php b/app/Http/Controllers/User/UserController.php index 17627f1a03..0eec210095 100644 --- a/app/Http/Controllers/User/UserController.php +++ b/app/Http/Controllers/User/UserController.php @@ -47,7 +47,8 @@ public function show(Request $request, User $user): \Illuminate\Contracts\View\F 'tickets' => fn ($query) => $query->orderByRaw('ISNULL(closed_at) desc')->orderByDesc('id'), ]) ->loadCount([ - 'torrents', + 'torrents as anon_uploads_count' => fn ($query) => $query->where('anon', '=', true), + 'torrents as non_anon_uploads_count' => fn ($query) => $query->where('anon', '=', false), 'topics', 'posts', 'filledRequests' => fn ($query) => $query->whereNotNull('approved_by'), diff --git a/app/Http/Controllers/YearlyOverviewController.php b/app/Http/Controllers/YearlyOverviewController.php index 25abdd2fed..9e952b5536 100644 --- a/app/Http/Controllers/YearlyOverviewController.php +++ b/app/Http/Controllers/YearlyOverviewController.php @@ -34,15 +34,8 @@ class YearlyOverviewController extends Controller */ public function index(): \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory { - // Site Years - $siteYears = collect(); - - for ($currentYear = (int) date('Y', strtotime('-1 year')); $currentYear >= date('Y', strtotime(config('other.birthdate'))); $currentYear--) { - $siteYears->push($currentYear); - } - return view('stats.yearly_overviews.index', [ - 'siteYears' => $siteYears, + 'siteYears' => range(now()->subYear()->year, Carbon::parse(config('other.birthdate'))->year), ]); } diff --git a/app/Http/Livewire/QuickSearchDropdown.php b/app/Http/Livewire/QuickSearchDropdown.php deleted file mode 100755 index b0fae99167..0000000000 --- a/app/Http/Livewire/QuickSearchDropdown.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 - */ - -namespace App\Http\Livewire; - -use App\Models\Person; -use App\Models\Torrent; -use Livewire\Component; -use Meilisearch\Endpoints\Indexes; - -class QuickSearchDropdown extends Component -{ - public string $quicksearchRadio = 'movies'; - - public string $quicksearchText = ''; - - public function render(): \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View - { - $search = '%'.str_replace(' ', '%', $this->quicksearchText).'%'; - - $filters = [ - 'deleted_at IS NULL', - 'status = 1', - ]; - - $searchById = false; - - if (preg_match('/^(\d+)$/', $this->quicksearchText, $matches)) { - $filters[] = 'tmdb = '.$matches[1]; - $searchById = true; - } - - if (preg_match('/tt0*(?=(\d{7,}))/', $this->quicksearchText, $matches)) { - $filters[] = 'imdb = '.$matches[1]; - $searchById = true; - } - - $searchResults = []; - - switch ($this->quicksearchRadio) { - case 'movies': - $filters[] = 'category.movie_meta = true'; - $filters[] = 'movie.name EXISTS'; - - $searchResults = Torrent::search( - $searchById ? '' : $this->quicksearchText, - function (Indexes $meilisearch, string $query, array $options) use ($filters) { - $options['filter'] = $filters; - $options['distinct'] = 'movie.id'; - - return $meilisearch->search($query, $options); - } - ) - ->simplePaginateRaw(20); - - break; - case 'series': - $filters[] = 'category.tv_meta = true'; - $filters[] = 'tv.name EXISTS'; - - $searchResults = Torrent::search( - $searchById ? '' : $this->quicksearchText, - function (Indexes $meilisearch, string $query, array $options) use ($filters) { - $options['filter'] = $filters; - $options['distinct'] = 'tv.id'; - - return $meilisearch->search($query, $options); - } - ) - ->simplePaginateRaw(20); - - break; - case 'persons': - $searchResults = Person::query() - ->select(['id', 'still', 'name']) - ->where('name', 'LIKE', $search) - ->oldest('name') - ->take(10) - ->get() - ->toArray(); - } - - return view('livewire.quick-search-dropdown', [ - 'search_results' => $searchResults, - ]); - } -} diff --git a/app/Http/Livewire/TorrentSearch.php b/app/Http/Livewire/TorrentSearch.php index a0f595cafe..e0d3b19a4d 100644 --- a/app/Http/Livewire/TorrentSearch.php +++ b/app/Http/Livewire/TorrentSearch.php @@ -35,8 +35,9 @@ use Livewire\Attributes\Url; use Livewire\Component; use Livewire\WithPagination; -use Meilisearch\Endpoints\Indexes; use Closure; +use Illuminate\Pagination\LengthAwarePaginator; +use Meilisearch\Client; class TorrentSearch extends Component { @@ -399,14 +400,15 @@ final public function filters(): TorrentSearchFiltersDTO default => null, }, userSeeder: match (true) { - $this->seeding => true, - $this->leeching => false, - default => null, + $this->seeding => true, + $this->leeching, $this->incomplete => false, + default => null, }, userActive: match (true) { - $this->seeding => true, - $this->leeching => true, - default => null, + $this->seeding => true, + $this->leeching => true, + $this->incomplete => false, + default => null, }, )); } @@ -417,11 +419,12 @@ final public function filters(): TorrentSearchFiltersDTO #[Computed] final public function torrents(): \Illuminate\Contracts\Pagination\LengthAwarePaginator { - $user = auth()->user(); + $user = auth()->user()->load('group'); // Whitelist which columns are allowed to be ordered by if (!\in_array($this->sortField, [ 'name', + 'rating', 'size', 'seeders', 'leechers', @@ -432,10 +435,7 @@ final public function torrents(): \Illuminate\Contracts\Pagination\LengthAwarePa $this->reset('sortField'); } - // Only allow sql for now to prevent user complaints of limiting page count to 1000 results (meilisearch limitation). - // However, eventually we want to switch to meilisearch only to reduce server load. - // $isSqlAllowed = $user->group->is_modo && $this->driver === 'sql'; - $isSqlAllowed = $this->driver !== 'sql'; + $isSqlAllowed = (($user->group->is_modo || $user->group->is_editor) && $this->driver === 'sql') || $this->description || $this->mediainfo; $eagerLoads = fn (Builder $query) => $query ->with(['user:id,username,group_id', 'user.group', 'category', 'type', 'resolution']) @@ -486,23 +486,30 @@ final public function torrents(): \Illuminate\Contracts\Pagination\LengthAwarePa $eagerLoads($torrents); $torrents = $torrents->paginate(min($this->perPage, 100)); } else { - $torrents = Torrent::search( - $this->name, - function (Indexes $meilisearch, string $query, array $options) { - $options['sort'] = [ - 'sticky:desc', - $this->sortField.':'.$this->sortDirection, - ]; - $options['filter'] = $this->filters()->toMeilisearchFilter(); - $options['matchingStrategy'] = 'all'; - - $results = $meilisearch->search($query, $options); - - return $results; - } - ) - ->query($eagerLoads) - ->paginate(min($this->perPage, 100)); + $client = new Client(config('scout.meilisearch.host'), config('scout.meilisearch.key')); + $index = $client->getIndex('torrents'); + + $results = $index->search($this->name, [ + 'sort' => [ + 'sticky:desc', + $this->sortField.':'.$this->sortDirection, + ], + 'filter' => $this->filters()->toMeilisearchFilter(), + 'matchingStrategy' => 'all', + 'page' => $this->getPage(), + 'hitsPerPage' => min($this->perPage, 100), + 'attributesToRetrieve' => ['id'], + ]); + + $ids = array_column($results->getHits(), 'id'); + + $torrents = Torrent::query()->whereIntegerInRaw('id', $ids); + + $eagerLoads($torrents); + + $torrents = $torrents->get()->sortBy(fn ($torrent) => array_search($torrent->id, $ids)); + + $torrents = new LengthAwarePaginator($torrents, $results->getTotalHits(), $this->perPage, $this->getPage()); } // See app/Traits/TorrentMeta.php diff --git a/app/Http/Livewire/UserSearch.php b/app/Http/Livewire/UserSearch.php index 5466439822..60f36e5d56 100644 --- a/app/Http/Livewire/UserSearch.php +++ b/app/Http/Livewire/UserSearch.php @@ -34,7 +34,7 @@ class UserSearch extends Component #TODO: Update URL attributes once Livewire 3 fixes upstream bug. See: https://github.com/livewire/livewire/discussions/7746 #[Url(history: true)] - public bool $show = false; + public bool $show = true; #[Url(history: true)] public int $perPage = 25; diff --git a/app/Http/Requests/Staff/StoreEventRequest.php b/app/Http/Requests/Staff/StoreEventRequest.php new file mode 100644 index 0000000000..0e5328641f --- /dev/null +++ b/app/Http/Requests/Staff/StoreEventRequest.php @@ -0,0 +1,60 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Http\Requests\Staff; + +use Illuminate\Foundation\Http\FormRequest; + +class StoreEventRequest extends FormRequest +{ + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'name' => [ + 'required', + 'string', + 'max:255', + ], + 'description' => [ + 'required', + 'string', + 'max:65535', + ], + 'icon' => [ + 'required', + 'string', + 'max:255', + ], + 'starts_at' => [ + 'required', + 'date', + ], + 'ends_at' => [ + 'required', + 'date', + ], + 'active' => [ + 'required', + 'boolean', + ], + ]; + } +} diff --git a/app/Http/Requests/Staff/StorePrizeRequest.php b/app/Http/Requests/Staff/StorePrizeRequest.php new file mode 100644 index 0000000000..840bd1b09b --- /dev/null +++ b/app/Http/Requests/Staff/StorePrizeRequest.php @@ -0,0 +1,54 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Http\Requests\Staff; + +use Illuminate\Foundation\Http\FormRequest; + +class StorePrizeRequest extends FormRequest +{ + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'type' => [ + 'required', + 'string', + 'in:bon,fl_tokens', + ], + 'min' => [ + 'required', + 'integer', + 'min:0', + 'lte:max', + ], + 'max' => [ + 'required', + 'integer', + 'gte:min', + ], + 'weight' => [ + 'required', + 'integer', + 'min:0', + ], + ]; + } +} diff --git a/app/Http/Requests/Staff/UpdateEventRequest.php b/app/Http/Requests/Staff/UpdateEventRequest.php new file mode 100644 index 0000000000..e51cc1b8ce --- /dev/null +++ b/app/Http/Requests/Staff/UpdateEventRequest.php @@ -0,0 +1,60 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Http\Requests\Staff; + +use Illuminate\Foundation\Http\FormRequest; + +class UpdateEventRequest extends FormRequest +{ + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'name' => [ + 'required', + 'string', + 'max:255', + ], + 'description' => [ + 'required', + 'string', + 'max:65535', + ], + 'icon' => [ + 'required', + 'string', + 'max:255', + ], + 'starts_at' => [ + 'required', + 'date', + ], + 'ends_at' => [ + 'required', + 'date', + ], + 'active' => [ + 'required', + 'boolean', + ], + ]; + } +} diff --git a/app/Http/Requests/Staff/UpdatePrizeRequest.php b/app/Http/Requests/Staff/UpdatePrizeRequest.php new file mode 100644 index 0000000000..245fe8fda9 --- /dev/null +++ b/app/Http/Requests/Staff/UpdatePrizeRequest.php @@ -0,0 +1,54 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Http\Requests\Staff; + +use Illuminate\Foundation\Http\FormRequest; + +class UpdatePrizeRequest extends FormRequest +{ + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'type' => [ + 'required', + 'string', + 'in:bon,fl_tokens', + ], + 'min' => [ + 'required', + 'integer', + 'min:0', + 'lte:max', + ], + 'max' => [ + 'required', + 'integer', + 'gte:min', + ], + 'weight' => [ + 'required', + 'integer', + 'min:0', + ], + ]; + } +} diff --git a/app/Models/Bot.php b/app/Models/Bot.php index 2af3e78913..e3fc43f5b4 100644 --- a/app/Models/Bot.php +++ b/app/Models/Bot.php @@ -31,10 +31,10 @@ * @property string|null $icon * @property string|null $emoji * @property string|null $help - * @property int $active - * @property int $is_protected - * @property int $is_nerdbot - * @property int $is_systembot + * @property bool $active + * @property bool $is_protected + * @property bool $is_nerdbot + * @property bool $is_systembot * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at */ @@ -51,6 +51,7 @@ class Bot extends Model * @return array{ * name: 'string', * cost: 'decimal:2', + * active: 'bool', * is_protected: 'bool', * is_nerdbot: 'bool', * is_systembot: 'bool', @@ -61,6 +62,7 @@ protected function casts(): array return [ 'name' => 'string', 'cost' => 'decimal:2', + 'active' => 'bool', 'is_protected' => 'bool', 'is_nerdbot' => 'bool', 'is_systembot' => 'bool', diff --git a/app/Models/ClaimedPrize.php b/app/Models/ClaimedPrize.php new file mode 100644 index 0000000000..e691203b4a --- /dev/null +++ b/app/Models/ClaimedPrize.php @@ -0,0 +1,60 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Models; + +use Illuminate\Database\Eloquent\Model; + +/** + * App\Models\ClaimedPrize. + * + * @property int $id + * @property int $user_id + * @property int $prize_id + * @property int $bon + * @property int $fl_tokens + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + */ +class ClaimedPrize extends Model +{ + /** + * The attributes that aren't mass assignable. + * + * @var string[] + */ + protected $guarded = []; + + /** + * Belongs to a user. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo + { + return $this->belongsTo(User::class); + } + + /** + * Belongs to an event. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function event(): \Illuminate\Database\Eloquent\Relations\BelongsTo + { + return $this->belongsTo(Event::class); + } +} diff --git a/app/Models/Event.php b/app/Models/Event.php new file mode 100644 index 0000000000..53a70957d2 --- /dev/null +++ b/app/Models/Event.php @@ -0,0 +1,77 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Models; + +use App\Traits\Auditable; +use Illuminate\Database\Eloquent\Model; + +/** + * App\Models\Event. + * + * @property int $id + * @property string $name + * @property string $icon + * @property string $description + * @property \Illuminate\Support\Carbon|null $starts_at + * @property \Illuminate\Support\Carbon|null $ends_at + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + */ +class Event extends Model +{ + use Auditable; + + /** + * The attributes that aren't mass assignable. + * + * @var string[] + */ + protected $guarded = []; + + /** + * Get the attributes that should be cast. + * + * @return array{starts_at: 'datetime', ends_at: 'datetime'} + */ + protected function casts(): array + { + return [ + 'starts_at' => 'datetime', + 'ends_at' => 'datetime', + ]; + } + + /** + * Has many claimed prizes. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function claimedPrizes(): \Illuminate\Database\Eloquent\Relations\HasMany + { + return $this->hasMany(ClaimedPrize::class); + } + + /** + * Has many prizes. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function prizes(): \Illuminate\Database\Eloquent\Relations\HasMany + { + return $this->hasMany(Prize::class); + } +} diff --git a/app/Models/Prize.php b/app/Models/Prize.php new file mode 100644 index 0000000000..ee0150f015 --- /dev/null +++ b/app/Models/Prize.php @@ -0,0 +1,51 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +namespace App\Models; + +use Illuminate\Database\Eloquent\Model; + +/** + * App\Models\Prize. + * + * @property int $id + * @property int $event_id + * @property string $type + * @property int $min + * @property int $max + * @property int $weight + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + */ +class Prize extends Model +{ + /** + * The attributes that aren't mass assignable. + * + * @var string[] + */ + protected $guarded = []; + + /** + * Belongs to a prize. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function event(): \Illuminate\Database\Eloquent\Relations\BelongsTo + { + return $this->belongsTo(Event::class); + } +} diff --git a/app/Models/Rss.php b/app/Models/Rss.php index db737ee69a..2283dd67b5 100644 --- a/app/Models/Rss.php +++ b/app/Models/Rss.php @@ -29,7 +29,7 @@ * @property int $position * @property string $name * @property int $user_id - * @property int $is_private + * @property bool $is_private * @property int $is_torrent * @property array $json_torrent * @property \Illuminate\Support\Carbon|null $deleted_at @@ -54,7 +54,7 @@ class Rss extends Model /** * Get the attributes that should be cast. * - * @return array{name: 'string', json_torrent: 'array', expected_fields: 'array'} + * @return array{name: 'string', json_torrent: 'array', expected_fields: 'array', is_private: 'bool'} */ protected function casts(): array { @@ -62,6 +62,7 @@ protected function casts(): array 'name' => 'string', 'json_torrent' => 'array', 'expected_fields' => 'array', + 'is_private' => 'bool', ]; } diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index 903f8683a0..8d0fee4b39 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -282,6 +282,33 @@ protected function casts(): array WHERE torrents.resolution_id = resolutions.id LIMIT 1 ) AS json_resolution, + ( + SELECT vote_average + FROM movies + WHERE + torrents.tmdb = movies.id + AND torrents.category_id in ( + SELECT id + FROM categories + WHERE movie_meta = 1 + ) + UNION + SELECT vote_average + FROM tv + WHERE + torrents.tmdb = tv.id + AND torrents.category_id in ( + SELECT id + FROM categories + WHERE tv_meta = 1 + ) + LIMIT 1 + ) AS rating, + EXISTS( + SELECT * + FROM torrent_trumps + WHERE torrents.id = torrent_trumps.torrent_id + ) AS trumpable, ( SELECT JSON_OBJECT( 'id', movies.id, @@ -290,6 +317,7 @@ protected function casts(): array 'poster', movies.poster, 'original_language', movies.original_language, 'adult', movies.adult != 0, + 'rating', movies.vote_average, 'companies', ( SELECT COALESCE(JSON_ARRAYAGG(JSON_OBJECT( 'id', companies.id, @@ -314,8 +342,10 @@ protected function casts(): array WHERE genre_movie.movie_id = torrents.tmdb ) ), - 'collection_id', ( - SELECT collection_movie.collection_id + 'collection', ( + SELECT JSON_OBJECT( + 'id', collection_movie.collection_id + ) FROM collection_movie WHERE movies.id = collection_movie.movie_id LIMIT 1 @@ -344,6 +374,7 @@ protected function casts(): array 'year', YEAR(tv.first_air_date), 'poster', tv.poster, 'original_language', tv.original_language, + 'rating', tv.vote_average, 'companies', ( SELECT COALESCE(JSON_ARRAYAGG(JSON_OBJECT( 'id', companies.id, @@ -831,6 +862,8 @@ public function toSearchableArray(): array 'region_id', 'personal_release', 'info_hash', + 'trumpable', + 'rating', 'json_user', 'json_type', 'json_category', @@ -901,6 +934,8 @@ public function toSearchableArray(): array 'region_id' => $torrent->region_id, 'personal_release' => (bool) $torrent->personal_release, 'info_hash' => bin2hex($torrent->info_hash), + 'rating' => (float) $torrent->rating, /** @phpstan-ignore property.notFound (This property is selected in the query but doesn't exist on the model) */ + 'trumpable' => (bool) $torrent->trumpable, /** @phpstan-ignore property.notFound (This property is selected in the query but doesn't exist on the model) */ 'user' => json_decode($torrent->json_user ?? 'null'), 'type' => json_decode($torrent->json_type ?? 'null'), 'category' => json_decode($torrent->json_category ?? 'null'), diff --git a/app/Models/User.php b/app/Models/User.php index 525d6f53fd..3d3c24c0c2 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -957,6 +957,16 @@ public function audits(): \Illuminate\Database\Eloquent\Relations\HasMany return $this->hasMany(Audit::class); } + /** + * Has many claimed prizes. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function claimedPrizes(): \Illuminate\Database\Eloquent\Relations\HasMany + { + return $this->hasMany(ClaimedPrize::class); + } + /** * Has many donations. * diff --git a/app/Traits/TorrentFilter.php b/app/Traits/TorrentFilter.php index 378c2a84d8..ab0d4925bf 100644 --- a/app/Traits/TorrentFilter.php +++ b/app/Traits/TorrentFilter.php @@ -347,7 +347,7 @@ public function scopeFeatured(Builder $query): void */ public function scopeRefundable(Builder $query): void { - $query->where('refundable', '=', 1); + $query->where('refundable', '=', true); } /** diff --git a/composer.json b/composer.json index 71301fc718..0d1a94aaa3 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "ext-zip": "*", "assada/laravel-achievements": "^2.7", "bjeavons/zxcvbn-php": "^1.3.1", - "doctrine/dbal": "^3.9.1", + "doctrine/dbal": "^3.9.3", "gabrielelana/byte-units": "^0.5.0", "guzzlehttp/guzzle": "^7.9.2", "hdvinnie/laravel-html-purifier": "^v3.0.0", @@ -25,11 +25,11 @@ "intervention/image": "^2.7.2", "joypixels/assets": "^v7.0.1", "laravel/fortify": "1.20.0", - "laravel/framework": "^11.23.5", - "laravel/octane": "^2.5.5", - "laravel/scout": "^10.11.3", - "laravel/tinker": "^2.9.0", - "livewire/livewire": "^3.5.6", + "laravel/framework": "^11.28.1", + "laravel/octane": "^2.5.9", + "laravel/scout": "^10.11.4", + "laravel/tinker": "^2.10.0", + "livewire/livewire": "^3.5.12", "marcreichel/igdb-laravel": "^4.3.0", "meilisearch/meilisearch-php": "^1.10.1", "nesbot/carbon": "2.72.3", @@ -38,23 +38,23 @@ "spatie/laravel-backup": "^8.8.2", "spatie/laravel-cookie-consent": "^3.3.2", "spatie/laravel-image-optimizer": "^1.8.0", - "spatie/ssl-certificate": "^2.6.7", - "symfony/dom-crawler": "^6.4.8", + "spatie/ssl-certificate": "^2.6.8", + "symfony/dom-crawler": "^6.4.12", "theodorejb/polycast": "dev-master", "voku/anti-xss": "^4.1.42", "vstelmakh/url-highlight": "^3.1.1" }, "require-dev": { - "barryvdh/laravel-debugbar": "^3.13.5", + "barryvdh/laravel-debugbar": "^3.14.6", "brianium/paratest": "v7.4.0", "calebdw/larastan": "2.10.5", "calebdw/larastan-livewire": "^1.1.0", "fakerphp/faker": "^1.23.1", "jasonmccreary/laravel-test-assertions": "^2.4.1", - "laravel/pint": "^1.17.3", + "laravel/pint": "^1.18.1", "laravel/sail": "1.31.1", "mockery/mockery": "^1.6.12", - "nunomaduro/collision": "^8.4.0", + "nunomaduro/collision": "^8.5.0", "pestphp/pest": "^2.35.1", "pestphp/pest-plugin-laravel": "^2.4.0", "pestphp/pest-plugin-livewire": "^v2.1.0", diff --git a/composer.lock b/composer.lock index bb7d628ed4..a3efa44f83 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": "a1d1d02a0746eb57c23f4e57613040be", + "content-hash": "895a01f2f75fc1b56e7e2a33b78b32dc", "packages": [ { "name": "assada/laravel-achievements", @@ -523,16 +523,16 @@ }, { "name": "doctrine/dbal", - "version": "3.9.1", + "version": "3.9.3", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "d7dc08f98cba352b2bab5d32c5e58f7e745c11a7" + "reference": "61446f07fcb522414d6cfd8b1c3e5f9e18c579ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/d7dc08f98cba352b2bab5d32c5e58f7e745c11a7", - "reference": "d7dc08f98cba352b2bab5d32c5e58f7e745c11a7", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/61446f07fcb522414d6cfd8b1c3e5f9e18c579ba", + "reference": "61446f07fcb522414d6cfd8b1c3e5f9e18c579ba", "shasum": "" }, "require": { @@ -548,7 +548,7 @@ "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.12.0", + "phpstan/phpstan": "1.12.6", "phpstan/phpstan-strict-rules": "^1.6", "phpunit/phpunit": "9.6.20", "psalm/plugin-phpunit": "0.18.4", @@ -616,7 +616,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.9.1" + "source": "https://github.com/doctrine/dbal/tree/3.9.3" }, "funding": [ { @@ -632,7 +632,7 @@ "type": "tidelift" } ], - "time": "2024-09-01T13:49:23+00:00" + "time": "2024-10-10T17:56:43+00:00" }, { "name": "doctrine/deprecations", @@ -942,16 +942,16 @@ }, { "name": "dragonmantank/cron-expression", - "version": "v3.3.3", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a" + "reference": "8c784d071debd117328803d86b2097615b457500" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/adfb1f505deb6384dc8b39804c5065dd3c8c8c0a", - "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/8c784d071debd117328803d86b2097615b457500", + "reference": "8c784d071debd117328803d86b2097615b457500", "shasum": "" }, "require": { @@ -964,10 +964,14 @@ "require-dev": { "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^1.0", - "phpstan/phpstan-webmozart-assert": "^1.0", "phpunit/phpunit": "^7.0|^8.0|^9.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, "autoload": { "psr-4": { "Cron\\": "src/Cron/" @@ -991,7 +995,7 @@ ], "support": { "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.3" + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.4.0" }, "funding": [ { @@ -999,7 +1003,7 @@ "type": "github" } ], - "time": "2023-08-10T19:36:49+00:00" + "time": "2024-10-09T13:47:03+00:00" }, { "name": "egulias/email-validator", @@ -1439,16 +1443,16 @@ }, { "name": "guzzlehttp/promises", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8" + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", - "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", + "url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455", "shasum": "" }, "require": { @@ -1502,7 +1506,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.0.3" + "source": "https://github.com/guzzle/promises/tree/2.0.4" }, "funding": [ { @@ -1518,7 +1522,7 @@ "type": "tidelift" } ], - "time": "2024-07-18T10:29:17+00:00" + "time": "2024-10-17T10:06:22+00:00" }, { "name": "guzzlehttp/psr7", @@ -2116,23 +2120,26 @@ }, { "name": "laminas/laminas-diactoros", - "version": "3.4.0", + "version": "3.5.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "2cce7e77ca4c6c4183e9e8d4edeba483afc14487" + "reference": "143a16306602ce56b8b092a7914fef03c37f9ed2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/2cce7e77ca4c6c4183e9e8d4edeba483afc14487", - "reference": "2cce7e77ca4c6c4183e9e8d4edeba483afc14487", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/143a16306602ce56b8b092a7914fef03c37f9ed2", + "reference": "143a16306602ce56b8b092a7914fef03c37f9ed2", "shasum": "" }, "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", - "psr/http-factory": "^1.0.2", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", + "psr/http-factory": "^1.1", "psr/http-message": "^1.1 || ^2.0" }, + "conflict": { + "amphp/amp": "<2.6.4" + }, "provide": { "psr/http-factory-implementation": "^1.0", "psr/http-message-implementation": "^1.1 || ^2.0" @@ -2145,9 +2152,9 @@ "http-interop/http-factory-tests": "^2.2.0", "laminas/laminas-coding-standard": "~2.5.0", "php-http/psr7-integration-tests": "^1.4.0", - "phpunit/phpunit": "^10.5.31", + "phpunit/phpunit": "^10.5.36", "psalm/plugin-phpunit": "^0.19.0", - "vimeo/psalm": "^5.25.0" + "vimeo/psalm": "^5.26.1" }, "type": "library", "extra": { @@ -2197,7 +2204,7 @@ "type": "community_bridge" } ], - "time": "2024-09-11T00:55:07+00:00" + "time": "2024-10-14T11:59:49+00:00" }, { "name": "laravel/fortify", @@ -2265,16 +2272,16 @@ }, { "name": "laravel/framework", - "version": "v11.23.5", + "version": "v11.28.1", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "16b31ab0e1dad5cb2ed6dcc1818c02f02fc48453" + "reference": "3ef5c8a85b4c598d5ffaf98afd72f6a5d6a0be2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/16b31ab0e1dad5cb2ed6dcc1818c02f02fc48453", - "reference": "16b31ab0e1dad5cb2ed6dcc1818c02f02fc48453", + "url": "https://api.github.com/repos/laravel/framework/zipball/3ef5c8a85b4c598d5ffaf98afd72f6a5d6a0be2c", + "reference": "3ef5c8a85b4c598d5ffaf98afd72f6a5d6a0be2c", "shasum": "" }, "require": { @@ -2293,7 +2300,7 @@ "fruitcake/php-cors": "^1.3", "guzzlehttp/guzzle": "^7.8", "guzzlehttp/uri-template": "^1.0", - "laravel/prompts": "^0.1.18", + "laravel/prompts": "^0.1.18|^0.2.0|^0.3.0", "laravel/serializable-closure": "^1.3", "league/commonmark": "^2.2.1", "league/flysystem": "^3.8.0", @@ -2379,7 +2386,7 @@ "league/flysystem-sftp-v3": "^3.0", "mockery/mockery": "^1.6", "nyholm/psr7": "^1.2", - "orchestra/testbench-core": "^9.4.0", + "orchestra/testbench-core": "^9.5", "pda/pheanstalk": "^5.0", "phpstan/phpstan": "^1.11.5", "phpunit/phpunit": "^10.5|^11.0", @@ -2438,6 +2445,7 @@ "src/Illuminate/Filesystem/functions.php", "src/Illuminate/Foundation/helpers.php", "src/Illuminate/Log/functions.php", + "src/Illuminate/Support/functions.php", "src/Illuminate/Support/helpers.php" ], "psr-4": { @@ -2469,26 +2477,26 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-09-13T13:36:30+00:00" + "time": "2024-10-16T16:32:21+00:00" }, { "name": "laravel/octane", - "version": "v2.5.5", + "version": "v2.5.9", "source": { "type": "git", "url": "https://github.com/laravel/octane.git", - "reference": "a6cb30a609a997386533201344196f01bcd90e2b" + "reference": "d8d432eb1e51a8ab2575854963d94e70d4592e15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/octane/zipball/a6cb30a609a997386533201344196f01bcd90e2b", - "reference": "a6cb30a609a997386533201344196f01bcd90e2b", + "url": "https://api.github.com/repos/laravel/octane/zipball/d8d432eb1e51a8ab2575854963d94e70d4592e15", + "reference": "d8d432eb1e51a8ab2575854963d94e70d4592e15", "shasum": "" }, "require": { "laminas/laminas-diactoros": "^3.0", "laravel/framework": "^10.10.1|^11.0", - "laravel/prompts": "^0.1.24", + "laravel/prompts": "^0.1.24|^0.2.0|^0.3.0", "laravel/serializable-closure": "^1.3.0", "nesbot/carbon": "^2.66.0|^3.0", "php": "^8.1.0", @@ -2559,25 +2567,25 @@ "issues": "https://github.com/laravel/octane/issues", "source": "https://github.com/laravel/octane" }, - "time": "2024-09-11T20:54:55+00:00" + "time": "2024-10-06T21:09:20+00:00" }, { "name": "laravel/prompts", - "version": "v0.1.25", + "version": "v0.3.1", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95" + "reference": "0f3848a445562dac376b27968f753c65e7e1036e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/7b4029a84c37cb2725fc7f011586e2997040bc95", - "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95", + "url": "https://api.github.com/repos/laravel/prompts/zipball/0f3848a445562dac376b27968f753c65e7e1036e", + "reference": "0f3848a445562dac376b27968f753c65e7e1036e", "shasum": "" }, "require": { + "composer-runtime-api": "^2.2", "ext-mbstring": "*", - "illuminate/collections": "^10.0|^11.0", "php": "^8.1", "symfony/console": "^6.2|^7.0" }, @@ -2586,6 +2594,7 @@ "laravel/framework": ">=10.17.0 <10.25.0" }, "require-dev": { + "illuminate/collections": "^10.0|^11.0", "mockery/mockery": "^1.5", "pestphp/pest": "^2.3", "phpstan/phpstan": "^1.11", @@ -2597,7 +2606,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "0.1.x-dev" + "dev-main": "0.3.x-dev" } }, "autoload": { @@ -2615,22 +2624,22 @@ "description": "Add beautiful and user-friendly forms to your command-line applications.", "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.1.25" + "source": "https://github.com/laravel/prompts/tree/v0.3.1" }, - "time": "2024-08-12T22:06:33+00:00" + "time": "2024-10-09T19:42:26+00:00" }, { "name": "laravel/scout", - "version": "v10.11.3", + "version": "v10.11.4", "source": { "type": "git", "url": "https://github.com/laravel/scout.git", - "reference": "642b4750127b5242a089571c9314037a7453cc0a" + "reference": "f9cf4f79163e3c5f13f81369d4992d66e6700502" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/scout/zipball/642b4750127b5242a089571c9314037a7453cc0a", - "reference": "642b4750127b5242a089571c9314037a7453cc0a", + "url": "https://api.github.com/repos/laravel/scout/zipball/f9cf4f79163e3c5f13f81369d4992d66e6700502", + "reference": "f9cf4f79163e3c5f13f81369d4992d66e6700502", "shasum": "" }, "require": { @@ -2695,20 +2704,20 @@ "issues": "https://github.com/laravel/scout/issues", "source": "https://github.com/laravel/scout" }, - "time": "2024-09-11T21:32:42+00:00" + "time": "2024-10-01T14:39:33+00:00" }, { "name": "laravel/serializable-closure", - "version": "v1.3.4", + "version": "v1.3.5", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "61b87392d986dc49ad5ef64e75b1ff5fee24ef81" + "reference": "1dc4a3dbfa2b7628a3114e43e32120cce7cdda9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/61b87392d986dc49ad5ef64e75b1ff5fee24ef81", - "reference": "61b87392d986dc49ad5ef64e75b1ff5fee24ef81", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/1dc4a3dbfa2b7628a3114e43e32120cce7cdda9c", + "reference": "1dc4a3dbfa2b7628a3114e43e32120cce7cdda9c", "shasum": "" }, "require": { @@ -2756,20 +2765,20 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2024-08-02T07:48:17+00:00" + "time": "2024-09-23T13:33:08+00:00" }, { "name": "laravel/tinker", - "version": "v2.9.0", + "version": "v2.10.0", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe" + "reference": "ba4d51eb56de7711b3a37d63aa0643e99a339ae5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/502e0fe3f0415d06d5db1f83a472f0f3b754bafe", - "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe", + "url": "https://api.github.com/repos/laravel/tinker/zipball/ba4d51eb56de7711b3a37d63aa0643e99a339ae5", + "reference": "ba4d51eb56de7711b3a37d63aa0643e99a339ae5", "shasum": "" }, "require": { @@ -2820,9 +2829,9 @@ ], "support": { "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.9.0" + "source": "https://github.com/laravel/tinker/tree/v2.10.0" }, - "time": "2024-01-04T16:10:04+00:00" + "time": "2024-09-23T13:32:56+00:00" }, { "name": "league/commonmark", @@ -3014,16 +3023,16 @@ }, { "name": "league/flysystem", - "version": "3.28.0", + "version": "3.29.1", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c" + "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c", - "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/edc1bb7c86fab0776c3287dbd19b5fa278347319", + "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319", "shasum": "" }, "require": { @@ -3091,22 +3100,22 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.28.0" + "source": "https://github.com/thephpleague/flysystem/tree/3.29.1" }, - "time": "2024-05-22T10:09:12+00:00" + "time": "2024-10-08T08:58:34+00:00" }, { "name": "league/flysystem-local", - "version": "3.28.0", + "version": "3.29.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40" + "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/13f22ea8be526ea58c2ddff9e158ef7c296e4f40", - "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/e0e8d52ce4b2ed154148453d321e97c8e931bd27", + "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27", "shasum": "" }, "require": { @@ -3140,22 +3149,22 @@ "local" ], "support": { - "source": "https://github.com/thephpleague/flysystem-local/tree/3.28.0" + "source": "https://github.com/thephpleague/flysystem-local/tree/3.29.0" }, - "time": "2024-05-06T20:05:52+00:00" + "time": "2024-08-09T21:24:39+00:00" }, { "name": "league/mime-type-detection", - "version": "1.15.0", + "version": "1.16.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301" + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301", - "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", "shasum": "" }, "require": { @@ -3186,7 +3195,7 @@ "description": "Mime-type detection for Flysystem", "support": { "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.15.0" + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" }, "funding": [ { @@ -3198,20 +3207,20 @@ "type": "tidelift" } ], - "time": "2024-01-28T23:22:08+00:00" + "time": "2024-09-21T08:32:55+00:00" }, { "name": "livewire/livewire", - "version": "v3.5.6", + "version": "v3.5.12", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "597a2808d8d3001cc3ed5ce89a6ebab00f83b80f" + "reference": "3c8d1f9d7d9098aaea663093ae168f2d5d2ae73d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/597a2808d8d3001cc3ed5ce89a6ebab00f83b80f", - "reference": "597a2808d8d3001cc3ed5ce89a6ebab00f83b80f", + "url": "https://api.github.com/repos/livewire/livewire/zipball/3c8d1f9d7d9098aaea663093ae168f2d5d2ae73d", + "reference": "3c8d1f9d7d9098aaea663093ae168f2d5d2ae73d", "shasum": "" }, "require": { @@ -3219,7 +3228,7 @@ "illuminate/routing": "^10.0|^11.0", "illuminate/support": "^10.0|^11.0", "illuminate/validation": "^10.0|^11.0", - "laravel/prompts": "^0.1.24", + "laravel/prompts": "^0.1.24|^0.2|^0.3", "league/mime-type-detection": "^1.9", "php": "^8.1", "symfony/console": "^6.0|^7.0", @@ -3266,7 +3275,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v3.5.6" + "source": "https://github.com/livewire/livewire/tree/v3.5.12" }, "funding": [ { @@ -3274,7 +3283,7 @@ "type": "github" } ], - "time": "2024-08-19T11:52:18+00:00" + "time": "2024-10-15T19:35:06+00:00" }, { "name": "marcreichel/igdb-laravel", @@ -3689,24 +3698,24 @@ }, { "name": "nette/schema", - "version": "v1.3.0", + "version": "v1.3.2", "source": { "type": "git", "url": "https://github.com/nette/schema.git", - "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188" + "reference": "da801d52f0354f70a638673c4a0f04e16529431d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/a6d3a6d1f545f01ef38e60f375d1cf1f4de98188", - "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188", + "url": "https://api.github.com/repos/nette/schema/zipball/da801d52f0354f70a638673c4a0f04e16529431d", + "reference": "da801d52f0354f70a638673c4a0f04e16529431d", "shasum": "" }, "require": { "nette/utils": "^4.0", - "php": "8.1 - 8.3" + "php": "8.1 - 8.4" }, "require-dev": { - "nette/tester": "^2.4", + "nette/tester": "^2.5.2", "phpstan/phpstan-nette": "^1.0", "tracy/tracy": "^2.8" }, @@ -3745,9 +3754,9 @@ ], "support": { "issues": "https://github.com/nette/schema/issues", - "source": "https://github.com/nette/schema/tree/v1.3.0" + "source": "https://github.com/nette/schema/tree/v1.3.2" }, - "time": "2023-12-11T11:54:22+00:00" + "time": "2024-10-06T23:10:23+00:00" }, { "name": "nette/utils", @@ -3837,16 +3846,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.2.0", + "version": "v5.3.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb" + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", - "reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", "shasum": "" }, "require": { @@ -3889,38 +3898,37 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.2.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" }, - "time": "2024-09-15T16:40:33+00:00" + "time": "2024-10-08T18:51:32+00:00" }, { "name": "nunomaduro/termwind", - "version": "v2.1.0", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/termwind.git", - "reference": "e5f21eade88689536c0cdad4c3cd75f3ed26e01a" + "reference": "42c84e4e8090766bbd6445d06cd6e57650626ea3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/e5f21eade88689536c0cdad4c3cd75f3ed26e01a", - "reference": "e5f21eade88689536c0cdad4c3cd75f3ed26e01a", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/42c84e4e8090766bbd6445d06cd6e57650626ea3", + "reference": "42c84e4e8090766bbd6445d06cd6e57650626ea3", "shasum": "" }, "require": { "ext-mbstring": "*", "php": "^8.2", - "symfony/console": "^7.0.4" + "symfony/console": "^7.1.5" }, "require-dev": { - "ergebnis/phpstan-rules": "^2.2.0", - "illuminate/console": "^11.1.1", - "laravel/pint": "^1.15.0", - "mockery/mockery": "^1.6.11", - "pestphp/pest": "^2.34.6", - "phpstan/phpstan": "^1.10.66", - "phpstan/phpstan-strict-rules": "^1.5.2", - "symfony/var-dumper": "^7.0.4", + "illuminate/console": "^11.28.0", + "laravel/pint": "^1.18.1", + "mockery/mockery": "^1.6.12", + "pestphp/pest": "^2.36.0", + "phpstan/phpstan": "^1.12.6", + "phpstan/phpstan-strict-rules": "^1.6.1", + "symfony/var-dumper": "^7.1.5", "thecodingmachine/phpstan-strict-rules": "^1.0.0" }, "type": "library", @@ -3963,7 +3971,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v2.1.0" + "source": "https://github.com/nunomaduro/termwind/tree/v2.2.0" }, "funding": [ { @@ -3979,7 +3987,7 @@ "type": "github" } ], - "time": "2024-09-05T15:25:50+00:00" + "time": "2024-10-15T16:15:16+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -4050,16 +4058,16 @@ }, { "name": "php-http/discovery", - "version": "1.19.4", + "version": "1.20.0", "source": { "type": "git", "url": "https://github.com/php-http/discovery.git", - "reference": "0700efda8d7526335132360167315fdab3aeb599" + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/discovery/zipball/0700efda8d7526335132360167315fdab3aeb599", - "reference": "0700efda8d7526335132360167315fdab3aeb599", + "url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d", "shasum": "" }, "require": { @@ -4123,9 +4131,9 @@ ], "support": { "issues": "https://github.com/php-http/discovery/issues", - "source": "https://github.com/php-http/discovery/tree/1.19.4" + "source": "https://github.com/php-http/discovery/tree/1.20.0" }, - "time": "2024-03-29T13:00:05+00:00" + "time": "2024-10-02T11:20:13+00:00" }, { "name": "phpoption/phpoption", @@ -5147,16 +5155,16 @@ }, { "name": "spatie/db-dumper", - "version": "3.6.0", + "version": "3.7.0", "source": { "type": "git", "url": "https://github.com/spatie/db-dumper.git", - "reference": "faca5056830bccea04eadf07e8074669cb9e905e" + "reference": "22553ab8c34a9bb70645cb9bc2d9f236f3135705" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/db-dumper/zipball/faca5056830bccea04eadf07e8074669cb9e905e", - "reference": "faca5056830bccea04eadf07e8074669cb9e905e", + "url": "https://api.github.com/repos/spatie/db-dumper/zipball/22553ab8c34a9bb70645cb9bc2d9f236f3135705", + "reference": "22553ab8c34a9bb70645cb9bc2d9f236f3135705", "shasum": "" }, "require": { @@ -5194,7 +5202,7 @@ "spatie" ], "support": { - "source": "https://github.com/spatie/db-dumper/tree/3.6.0" + "source": "https://github.com/spatie/db-dumper/tree/3.7.0" }, "funding": [ { @@ -5206,7 +5214,7 @@ "type": "github" } ], - "time": "2024-04-24T14:54:13+00:00" + "time": "2024-09-23T08:58:35+00:00" }, { "name": "spatie/image-optimizer", @@ -5695,16 +5703,16 @@ }, { "name": "spatie/ssl-certificate", - "version": "2.6.7", + "version": "2.6.8", "source": { "type": "git", "url": "https://github.com/spatie/ssl-certificate.git", - "reference": "61daa1569f82e177e7989f403c49e9c0033a27f5" + "reference": "47f35ef3836cadd2a1314a8a0d3d0b3c1a5e8f6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/ssl-certificate/zipball/61daa1569f82e177e7989f403c49e9c0033a27f5", - "reference": "61daa1569f82e177e7989f403c49e9c0033a27f5", + "url": "https://api.github.com/repos/spatie/ssl-certificate/zipball/47f35ef3836cadd2a1314a8a0d3d0b3c1a5e8f6e", + "reference": "47f35ef3836cadd2a1314a8a0d3d0b3c1a5e8f6e", "shasum": "" }, "require": { @@ -5747,7 +5755,7 @@ "ssl-certificate" ], "support": { - "source": "https://github.com/spatie/ssl-certificate/tree/2.6.7" + "source": "https://github.com/spatie/ssl-certificate/tree/2.6.8" }, "funding": [ { @@ -5759,7 +5767,7 @@ "type": "other" } ], - "time": "2024-06-28T07:58:30+00:00" + "time": "2024-09-20T13:11:59+00:00" }, { "name": "spatie/temporary-directory", @@ -5824,16 +5832,16 @@ }, { "name": "symfony/console", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111" + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/1eed7af6961d763e7832e874d7f9b21c3ea9c111", - "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111", + "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee", "shasum": "" }, "require": { @@ -5897,7 +5905,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.4" + "source": "https://github.com/symfony/console/tree/v7.1.5" }, "funding": [ { @@ -5913,7 +5921,7 @@ "type": "tidelift" } ], - "time": "2024-08-15T22:48:53+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/css-selector", @@ -6049,16 +6057,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v6.4.8", + "version": "v6.4.12", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "105b56a0305d219349edeb60a800082eca864e4b" + "reference": "9d307ecbcb917001692be333cdc58f474fdb37f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/105b56a0305d219349edeb60a800082eca864e4b", - "reference": "105b56a0305d219349edeb60a800082eca864e4b", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/9d307ecbcb917001692be333cdc58f474fdb37f0", + "reference": "9d307ecbcb917001692be333cdc58f474fdb37f0", "shasum": "" }, "require": { @@ -6096,7 +6104,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.4.8" + "source": "https://github.com/symfony/dom-crawler/tree/v6.4.12" }, "funding": [ { @@ -6112,7 +6120,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:49:08+00:00" + "time": "2024-09-15T06:35:36+00:00" }, { "name": "symfony/error-handler", @@ -6411,16 +6419,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a" + "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f602d5c17d1fa02f8019ace2687d9d136b7f4a1a", - "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e30ef73b1e44eea7eb37ba69600a354e553f694b", + "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b", "shasum": "" }, "require": { @@ -6468,7 +6476,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.1.3" + "source": "https://github.com/symfony/http-foundation/tree/v7.1.5" }, "funding": [ { @@ -6484,20 +6492,20 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:41:01+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "6efcbd1b3f444f631c386504fc83eeca25963747" + "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6efcbd1b3f444f631c386504fc83eeca25963747", - "reference": "6efcbd1b3f444f631c386504fc83eeca25963747", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/44204d96150a9df1fc57601ec933d23fefc2d65b", + "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b", "shasum": "" }, "require": { @@ -6582,7 +6590,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.1.4" + "source": "https://github.com/symfony/http-kernel/tree/v7.1.5" }, "funding": [ { @@ -6598,20 +6606,20 @@ "type": "tidelift" } ], - "time": "2024-08-30T17:02:28+00:00" + "time": "2024-09-21T06:09:21+00:00" }, { "name": "symfony/mailer", - "version": "v7.1.2", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee" + "reference": "bbf21460c56f29810da3df3e206e38dfbb01e80b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/8fcff0af9043c8f8a8e229437cea363e282f9aee", - "reference": "8fcff0af9043c8f8a8e229437cea363e282f9aee", + "url": "https://api.github.com/repos/symfony/mailer/zipball/bbf21460c56f29810da3df3e206e38dfbb01e80b", + "reference": "bbf21460c56f29810da3df3e206e38dfbb01e80b", "shasum": "" }, "require": { @@ -6662,7 +6670,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.1.2" + "source": "https://github.com/symfony/mailer/tree/v7.1.5" }, "funding": [ { @@ -6678,20 +6686,20 @@ "type": "tidelift" } ], - "time": "2024-06-28T08:00:31+00:00" + "time": "2024-09-08T12:32:26+00:00" }, { "name": "symfony/mime", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "ccaa6c2503db867f472a587291e764d6a1e58758" + "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/ccaa6c2503db867f472a587291e764d6a1e58758", - "reference": "ccaa6c2503db867f472a587291e764d6a1e58758", + "url": "https://api.github.com/repos/symfony/mime/zipball/711d2e167e8ce65b05aea6b258c449671cdd38ff", + "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff", "shasum": "" }, "require": { @@ -6746,7 +6754,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.1.4" + "source": "https://github.com/symfony/mime/tree/v7.1.5" }, "funding": [ { @@ -6762,7 +6770,7 @@ "type": "tidelift" } ], - "time": "2024-08-13T14:28:19+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/polyfill-ctype", @@ -7547,16 +7555,16 @@ }, { "name": "symfony/process", - "version": "v7.1.3", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca" + "reference": "5c03ee6369281177f07f7c68252a280beccba847" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/7f2f542c668ad6c313dc4a5e9c3321f733197eca", - "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca", + "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", + "reference": "5c03ee6369281177f07f7c68252a280beccba847", "shasum": "" }, "require": { @@ -7588,7 +7596,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.3" + "source": "https://github.com/symfony/process/tree/v7.1.5" }, "funding": [ { @@ -7604,7 +7612,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:44:47+00:00" + "time": "2024-09-19T21:48:23+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -7855,16 +7863,16 @@ }, { "name": "symfony/string", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b" + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/6cd670a6d968eaeb1c77c2e76091c45c56bc367b", - "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b", + "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", "shasum": "" }, "require": { @@ -7922,7 +7930,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.4" + "source": "https://github.com/symfony/string/tree/v7.1.5" }, "funding": [ { @@ -7938,20 +7946,20 @@ "type": "tidelift" } ], - "time": "2024-08-12T09:59:40+00:00" + "time": "2024-09-20T08:28:38+00:00" }, { "name": "symfony/translation", - "version": "v6.4.10", + "version": "v6.4.12", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "94041203f8ac200ae9e7c6a18fa6137814ccecc9" + "reference": "cf8360b8352b086be620fae8342c4d96e391a489" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/94041203f8ac200ae9e7c6a18fa6137814ccecc9", - "reference": "94041203f8ac200ae9e7c6a18fa6137814ccecc9", + "url": "https://api.github.com/repos/symfony/translation/zipball/cf8360b8352b086be620fae8342c4d96e391a489", + "reference": "cf8360b8352b086be620fae8342c4d96e391a489", "shasum": "" }, "require": { @@ -8017,7 +8025,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.4.10" + "source": "https://github.com/symfony/translation/tree/v6.4.12" }, "funding": [ { @@ -8033,7 +8041,7 @@ "type": "tidelift" } ], - "time": "2024-07-26T12:30:32+00:00" + "time": "2024-09-16T06:02:54+00:00" }, { "name": "symfony/translation-contracts", @@ -8115,16 +8123,16 @@ }, { "name": "symfony/uid", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "82177535395109075cdb45a70533aa3d7a521cdf" + "reference": "8c7bb8acb933964055215d89f9a9871df0239317" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/82177535395109075cdb45a70533aa3d7a521cdf", - "reference": "82177535395109075cdb45a70533aa3d7a521cdf", + "url": "https://api.github.com/repos/symfony/uid/zipball/8c7bb8acb933964055215d89f9a9871df0239317", + "reference": "8c7bb8acb933964055215d89f9a9871df0239317", "shasum": "" }, "require": { @@ -8169,7 +8177,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.1.4" + "source": "https://github.com/symfony/uid/tree/v7.1.5" }, "funding": [ { @@ -8185,20 +8193,20 @@ "type": "tidelift" } ], - "time": "2024-08-12T09:59:40+00:00" + "time": "2024-09-17T09:16:35+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa" + "reference": "e20e03889539fd4e4211e14d2179226c513c010d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a5fa7481b199090964d6fd5dab6294d5a870c7aa", - "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e20e03889539fd4e4211e14d2179226c513c010d", + "reference": "e20e03889539fd4e4211e14d2179226c513c010d", "shasum": "" }, "require": { @@ -8252,7 +8260,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.1.4" + "source": "https://github.com/symfony/var-dumper/tree/v7.1.5" }, "funding": [ { @@ -8268,7 +8276,7 @@ "type": "tidelift" } ], - "time": "2024-08-30T16:12:47+00:00" + "time": "2024-09-16T10:07:02+00:00" }, { "name": "theodorejb/polycast", @@ -8837,23 +8845,23 @@ "packages-dev": [ { "name": "barryvdh/laravel-debugbar", - "version": "v3.13.5", + "version": "v3.14.6", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-debugbar.git", - "reference": "92d86be45ee54edff735e46856f64f14b6a8bb07" + "reference": "14e4517bd49130d6119228107eb21ae47ae120ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/92d86be45ee54edff735e46856f64f14b6a8bb07", - "reference": "92d86be45ee54edff735e46856f64f14b6a8bb07", + "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/14e4517bd49130d6119228107eb21ae47ae120ab", + "reference": "14e4517bd49130d6119228107eb21ae47ae120ab", "shasum": "" }, "require": { "illuminate/routing": "^9|^10|^11", "illuminate/session": "^9|^10|^11", "illuminate/support": "^9|^10|^11", - "maximebf/debugbar": "~1.22.0", + "maximebf/debugbar": "~1.23.0", "php": "^8.0", "symfony/finder": "^6|^7" }, @@ -8866,7 +8874,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.13-dev" + "dev-master": "3.14-dev" }, "laravel": { "providers": [ @@ -8905,7 +8913,7 @@ ], "support": { "issues": "https://github.com/barryvdh/laravel-debugbar/issues", - "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.13.5" + "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.14.6" }, "funding": [ { @@ -8917,7 +8925,7 @@ "type": "github" } ], - "time": "2024-04-12T11:20:37+00:00" + "time": "2024-10-18T13:15:12+00:00" }, { "name": "brianium/paratest", @@ -9300,26 +9308,26 @@ }, { "name": "filp/whoops", - "version": "2.15.4", + "version": "2.16.0", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546" + "reference": "befcdc0e5dce67252aa6322d82424be928214fa2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546", - "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546", + "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2", + "reference": "befcdc0e5dce67252aa6322d82424be928214fa2", "shasum": "" }, "require": { - "php": "^5.5.9 || ^7.0 || ^8.0", + "php": "^7.1 || ^8.0", "psr/log": "^1.0.1 || ^2.0 || ^3.0" }, "require-dev": { - "mockery/mockery": "^0.9 || ^1.0", - "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^4.0 || ^5.0" }, "suggest": { "symfony/var-dumper": "Pretty print complex values better with var-dumper available", @@ -9359,7 +9367,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.15.4" + "source": "https://github.com/filp/whoops/tree/2.16.0" }, "funding": [ { @@ -9367,7 +9375,7 @@ "type": "github" } ], - "time": "2023-11-03T12:00:00+00:00" + "time": "2024-09-25T12:00:00+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -9531,16 +9539,16 @@ }, { "name": "laravel/pint", - "version": "v1.17.3", + "version": "v1.18.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "9d77be916e145864f10788bb94531d03e1f7b482" + "reference": "35c00c05ec43e6b46d295efc0f4386ceb30d50d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/9d77be916e145864f10788bb94531d03e1f7b482", - "reference": "9d77be916e145864f10788bb94531d03e1f7b482", + "url": "https://api.github.com/repos/laravel/pint/zipball/35c00c05ec43e6b46d295efc0f4386ceb30d50d9", + "reference": "35c00c05ec43e6b46d295efc0f4386ceb30d50d9", "shasum": "" }, "require": { @@ -9593,7 +9601,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-09-03T15:00:28+00:00" + "time": "2024-09-24T17:22:50+00:00" }, { "name": "laravel/sail", @@ -9660,16 +9668,16 @@ }, { "name": "maximebf/debugbar", - "version": "v1.22.6", + "version": "v1.23.2", "source": { "type": "git", "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "d7881b498f9e649610bf6ae91cdd6353859f75d2" + "reference": "689720d724c771ac4add859056744b7b3f2406da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/d7881b498f9e649610bf6ae91cdd6353859f75d2", - "reference": "d7881b498f9e649610bf6ae91cdd6353859f75d2", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/689720d724c771ac4add859056744b7b3f2406da", + "reference": "689720d724c771ac4add859056744b7b3f2406da", "shasum": "" }, "require": { @@ -9691,7 +9699,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.22-dev" + "dev-master": "1.23-dev" } }, "autoload": { @@ -9722,9 +9730,9 @@ ], "support": { "issues": "https://github.com/maximebf/php-debugbar/issues", - "source": "https://github.com/maximebf/php-debugbar/tree/v1.22.6" + "source": "https://github.com/maximebf/php-debugbar/tree/v1.23.2" }, - "time": "2024-09-16T11:47:59+00:00" + "time": "2024-09-16T11:23:09+00:00" }, { "name": "mockery/mockery", @@ -9871,23 +9879,23 @@ }, { "name": "nunomaduro/collision", - "version": "v8.4.0", + "version": "v8.5.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a" + "reference": "f5c101b929c958e849a633283adff296ed5f38f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/e7d1aa8ed753f63fa816932bbc89678238843b4a", - "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/f5c101b929c958e849a633283adff296ed5f38f5", + "reference": "f5c101b929c958e849a633283adff296ed5f38f5", "shasum": "" }, "require": { - "filp/whoops": "^2.15.4", - "nunomaduro/termwind": "^2.0.1", + "filp/whoops": "^2.16.0", + "nunomaduro/termwind": "^2.1.0", "php": "^8.2.0", - "symfony/console": "^7.1.3" + "symfony/console": "^7.1.5" }, "conflict": { "laravel/framework": "<11.0.0 || >=12.0.0", @@ -9895,14 +9903,14 @@ }, "require-dev": { "larastan/larastan": "^2.9.8", - "laravel/framework": "^11.19.0", - "laravel/pint": "^1.17.1", - "laravel/sail": "^1.31.0", - "laravel/sanctum": "^4.0.2", - "laravel/tinker": "^2.9.0", - "orchestra/testbench-core": "^9.2.3", - "pestphp/pest": "^2.35.0 || ^3.0.0", - "sebastian/environment": "^6.1.0 || ^7.0.0" + "laravel/framework": "^11.28.0", + "laravel/pint": "^1.18.1", + "laravel/sail": "^1.36.0", + "laravel/sanctum": "^4.0.3", + "laravel/tinker": "^2.10.0", + "orchestra/testbench-core": "^9.5.3", + "pestphp/pest": "^2.36.0 || ^3.4.0", + "sebastian/environment": "^6.1.0 || ^7.2.0" }, "type": "library", "extra": { @@ -9964,7 +9972,7 @@ "type": "patreon" } ], - "time": "2024-08-03T15:32:23+00:00" + "time": "2024-10-15T16:06:32+00:00" }, { "name": "pestphp/pest", @@ -10737,16 +10745,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.30.1", + "version": "1.33.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "51b95ec8670af41009e2b2b56873bad96682413e" + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/51b95ec8670af41009e2b2b56873bad96682413e", - "reference": "51b95ec8670af41009e2b2b56873bad96682413e", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140", "shasum": "" }, "require": { @@ -10778,9 +10786,9 @@ "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.30.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.33.0" }, - "time": "2024-09-07T20:13:05+00:00" + "time": "2024-10-13T11:25:22+00:00" }, { "name": "phpstan/phpstan", @@ -11494,16 +11502,16 @@ }, { "name": "sebastian/comparator", - "version": "5.0.2", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53" + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53", - "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "shasum": "" }, "require": { @@ -11514,7 +11522,7 @@ "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^10.4" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { @@ -11559,7 +11567,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.2" + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" }, "funding": [ { @@ -11567,7 +11575,7 @@ "type": "github" } ], - "time": "2024-08-12T06:03:08+00:00" + "time": "2024-10-18T14:56:07+00:00" }, { "name": "sebastian/complexity", @@ -12622,16 +12630,16 @@ }, { "name": "symfony/yaml", - "version": "v7.1.4", + "version": "v7.1.5", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "92e080b851c1c655c786a2da77f188f2dccd0f4b" + "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/92e080b851c1c655c786a2da77f188f2dccd0f4b", - "reference": "92e080b851c1c655c786a2da77f188f2dccd0f4b", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4e561c316e135e053bd758bf3b3eb291d9919de4", + "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4", "shasum": "" }, "require": { @@ -12673,7 +12681,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.1.4" + "source": "https://github.com/symfony/yaml/tree/v7.1.5" }, "funding": [ { @@ -12689,7 +12697,7 @@ "type": "tidelift" } ], - "time": "2024-08-12T09:59:40+00:00" + "time": "2024-09-17T12:49:58+00:00" }, { "name": "ta-tikoma/phpunit-architecture-test", diff --git a/config/scout.php b/config/scout.php index f4ad3aa42a..a6bae993c5 100644 --- a/config/scout.php +++ b/config/scout.php @@ -178,6 +178,7 @@ 'internal', 'deleted_at', 'personal_release', + 'trumpable', 'info_hash', 'history_seeders.user_id', 'history_leechers.user_id', @@ -193,17 +194,21 @@ 'resolution.id', 'movie.id', 'movie.name', + 'movie.year', 'movie.original_language', 'movie.adult', 'movie.genres.id', 'movie.collection.id', 'movie.companies.id', + 'movie.wishes.user_id', 'tv.id', 'tv.name', + 'tv.year', 'tv.original_language', 'tv.genres.id', 'tv.networks.id', 'tv.companies.id', + 'tv.wishes.user_id', 'playlists.id', 'bookmarks.user_id', 'freeleech_tokens.user_id', @@ -214,6 +219,7 @@ ], 'sortableAttributes' => [ 'name', + 'rating', 'size', 'seeders', 'leechers', diff --git a/config/unit3d.php b/config/unit3d.php index 401ff72f43..845de2c7d9 100755 --- a/config/unit3d.php +++ b/config/unit3d.php @@ -23,7 +23,7 @@ | */ - 'powered-by' => 'Powered By UNIT3D Community Edition v8.3.1', + 'powered-by' => 'Powered By UNIT3D Community Edition v8.3.2', /* |-------------------------------------------------------------------------- @@ -45,7 +45,7 @@ | */ - 'version' => 'v8.3.1', + 'version' => 'v8.3.2', /* |-------------------------------------------------------------------------- diff --git a/database/migrations/2024_10_13_221353_create_events_claimed_prizes_tables.php b/database/migrations/2024_10_13_221353_create_events_claimed_prizes_tables.php new file mode 100644 index 0000000000..eb01f1714a --- /dev/null +++ b/database/migrations/2024_10_13_221353_create_events_claimed_prizes_tables.php @@ -0,0 +1,64 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class () extends Migration { + /** + * Run the migrations. + */ + public function up(): void + { + Schema::create('events', function (Blueprint $table): void { + $table->increments('id'); + $table->string('name'); + $table->text('description'); + $table->string('icon'); + $table->boolean('active'); + $table->date('starts_at'); + $table->date('ends_at'); + $table->timestamps(); + }); + + Schema::create('prizes', function (Blueprint $table): void { + $table->increments('id'); + $table->unsignedInteger('event_id'); + $table->string('type'); + $table->unsignedInteger('min'); + $table->unsignedInteger('max'); + $table->unsignedInteger('weight'); + + $table->foreign('event_id')->references('id')->on('events'); + + $table->timestamps(); + }); + + Schema::create('claimed_prizes', function (Blueprint $table): void { + $table->increments('id'); + $table->unsignedInteger('user_id'); + $table->unsignedInteger('event_id'); + $table->unsignedBigInteger('bon'); + $table->unsignedInteger('fl_tokens'); + + $table->foreign('event_id')->references('id')->on('events'); + $table->foreign('user_id')->references('id')->on('users'); + + $table->timestamps(); + }); + } +}; diff --git a/database/schema/mysql-schema.sql b/database/schema/mysql-schema.sql index 69d0bf73f1..4483d57eb8 100644 --- a/database/schema/mysql-schema.sql +++ b/database/schema/mysql-schema.sql @@ -154,6 +154,7 @@ CREATE TABLE `audits` ( `updated_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), KEY `audits_user_id_foreign` (`user_id`), + KEY `audits_user_id_action_created_at_index` (`user_id`,`action`,`created_at`), CONSTRAINT `audits_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -303,7 +304,7 @@ DROP TABLE IF EXISTS `categories`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `categories` ( - `id` int NOT NULL AUTO_INCREMENT, + `id` smallint unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `position` int NOT NULL, @@ -313,7 +314,6 @@ CREATE TABLE `categories` ( `game_meta` tinyint(1) NOT NULL DEFAULT '0', `tv_meta` tinyint(1) NOT NULL DEFAULT '0', `movie_meta` tinyint(1) NOT NULL DEFAULT '0', - `num_torrent` int NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -344,6 +344,24 @@ CREATE TABLE `chatrooms` ( UNIQUE KEY `chatrooms_name_unique` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `claimed_prizes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `claimed_prizes` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `user_id` int unsigned NOT NULL, + `event_id` int unsigned NOT NULL, + `bon` bigint unsigned NOT NULL, + `fl_tokens` int unsigned NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `claimed_prizes_event_id_foreign` (`event_id`), + KEY `claimed_prizes_user_id_foreign` (`user_id`), + CONSTRAINT `claimed_prizes_event_id_foreign` FOREIGN KEY (`event_id`) REFERENCES `events` (`id`), + CONSTRAINT `claimed_prizes_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `collection_movie`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; @@ -438,7 +456,7 @@ DROP TABLE IF EXISTS `conversations`; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `conversations` ( `id` int unsigned NOT NULL AUTO_INCREMENT, - `subject` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `subject` 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`), @@ -478,6 +496,62 @@ CREATE TABLE `distributors` ( KEY `distributors_name_index` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `donation_gateways`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `donation_gateways` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `position` int NOT NULL, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `address` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `is_active` tinyint(1) NOT NULL DEFAULT '0', + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `donation_packages`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `donation_packages` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `position` int NOT NULL, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `description` text COLLATE utf8mb4_unicode_ci NOT NULL, + `cost` decimal(6,2) NOT NULL, + `upload_value` bigint unsigned DEFAULT NULL, + `invite_value` bigint unsigned DEFAULT NULL, + `bonus_value` bigint unsigned DEFAULT NULL, + `donor_value` bigint unsigned DEFAULT NULL, + `is_active` tinyint(1) NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `donation_packages_position_index` (`position`), + KEY `donation_packages_is_active_index` (`is_active`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `donations`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `donations` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `user_id` int unsigned NOT NULL, + `gifted_user_id` int unsigned DEFAULT NULL, + `status` tinyint NOT NULL DEFAULT '0', + `package_id` int unsigned NOT NULL, + `transaction` text COLLATE utf8mb4_unicode_ci NOT NULL, + `is_gifted` tinyint(1) NOT NULL DEFAULT '0', + `starts_at` date DEFAULT NULL, + `ends_at` date DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `donations_user_id_index` (`user_id`), + KEY `donations_gifted_user_id_index` (`gifted_user_id`), + KEY `donations_package_id_index` (`package_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `email_updates`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; @@ -518,6 +592,22 @@ CREATE TABLE `episodes` ( CONSTRAINT `episodes_tv_id_foreign` FOREIGN KEY (`tv_id`) REFERENCES `tv` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `events`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `events` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `description` text COLLATE utf8mb4_unicode_ci NOT NULL, + `icon` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `active` tinyint(1) NOT NULL, + `starts_at` date NOT NULL, + `ends_at` date NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `failed_jobs`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; @@ -749,6 +839,7 @@ CREATE TABLE `groups` ( `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', + `is_uploader` tinyint(1) NOT NULL DEFAULT '0', `is_internal` tinyint(1) NOT NULL DEFAULT '0', `is_editor` tinyint(1) NOT NULL DEFAULT '0', `is_owner` tinyint(1) NOT NULL DEFAULT '0', @@ -759,6 +850,10 @@ CREATE TABLE `groups` ( `is_freeleech` tinyint(1) NOT NULL DEFAULT '0', `is_double_upload` tinyint(1) NOT NULL DEFAULT '0', `is_refundable` tinyint(1) NOT NULL DEFAULT '0', + `can_chat` tinyint(1) NOT NULL, + `can_comment` tinyint(1) NOT NULL, + `can_invite` tinyint(1) NOT NULL, + `can_request` tinyint(1) NOT NULL, `can_upload` tinyint(1) NOT NULL DEFAULT '1', `is_incognito` tinyint(1) NOT NULL DEFAULT '0', `autogroup` tinyint(1) NOT NULL DEFAULT '0', @@ -779,7 +874,6 @@ DROP TABLE IF EXISTS `history`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `history` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, `user_id` int unsigned NOT NULL, `torrent_id` int unsigned NOT NULL, `agent` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, @@ -799,14 +893,14 @@ CREATE TABLE `history` ( `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, `completed_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `history_user_id_torrent_id_unique` (`user_id`,`torrent_id`), + PRIMARY KEY (`user_id`,`torrent_id`), KEY `history_user_id_foreign` (`user_id`), KEY `history_immune_index` (`immune`), KEY `history_hitrun_index` (`hitrun`), KEY `history_user_id_torrent_id_index` (`user_id`,`torrent_id`), KEY `history_torrent_id_foreign` (`torrent_id`), KEY `history_idx_prewa_hitru_immun_activ_actua` (`prewarned_at`,`hitrun`,`immune`,`active`,`actual_downloaded`), + KEY `history_torrent_id_completed_at_created_at_index` (`torrent_id`,`completed_at`,`created_at`), CONSTRAINT `history_torrent_id_foreign` FOREIGN KEY (`torrent_id`) REFERENCES `torrents` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `history_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -1113,6 +1207,18 @@ CREATE TABLE `passkeys` ( CONSTRAINT `passkeys_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `password_reset_histories`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `password_reset_histories` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `user_id` int unsigned NOT NULL, + `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `password_reset_histories_user_id_foreign` (`user_id`), + CONSTRAINT `password_reset_histories_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `password_resets`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; @@ -1129,7 +1235,6 @@ DROP TABLE IF EXISTS `peers`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `peers` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, `peer_id` binary(20) NOT NULL, `ip` varbinary(16) NOT NULL, `port` smallint unsigned NOT NULL, @@ -1145,8 +1250,7 @@ CREATE TABLE `peers` ( `connectable` tinyint(1) NOT NULL DEFAULT '0', `active` tinyint(1) NOT NULL, `visible` tinyint(1) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `peers_user_id_torrent_id_peer_id_unique` (`user_id`,`torrent_id`,`peer_id`), + PRIMARY KEY (`user_id`,`torrent_id`,`peer_id`), KEY `peers_idx_seeder_user_id` (`seeder`,`user_id`), KEY `peers_torrent_id_foreign` (`torrent_id`), KEY `peers_active_index` (`active`), @@ -1238,6 +1342,7 @@ CREATE TABLE `polls` ( `user_id` int unsigned NOT NULL DEFAULT '0', `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `multiple_choice` tinyint(1) NOT NULL DEFAULT '0', + `expires_at` datetime DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), @@ -1299,6 +1404,23 @@ CREATE TABLE `private_messages` ( CONSTRAINT `private_messages_sender_id_foreign` FOREIGN KEY (`sender_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `prizes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `prizes` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `event_id` int unsigned NOT NULL, + `type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `min` int unsigned NOT NULL, + `max` int unsigned NOT NULL, + `weight` int unsigned NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `prizes_event_id_foreign` (`event_id`), + CONSTRAINT `prizes_event_id_foreign` FOREIGN KEY (`event_id`) REFERENCES `events` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `recommendations`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; @@ -1353,6 +1475,7 @@ CREATE TABLE `reports` ( `reported_user` int unsigned DEFAULT NULL, `torrent_id` int unsigned DEFAULT NULL, `request_id` int unsigned DEFAULT NULL, + `snoozed_until` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), KEY `reports_reporter_id_foreign` (`reporter_id`), KEY `reports_staff_id_foreign` (`staff_id`), @@ -1404,7 +1527,7 @@ DROP TABLE IF EXISTS `requests`; CREATE TABLE `requests` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, - `category_id` int NOT NULL, + `category_id` smallint unsigned NOT NULL, `imdb` int unsigned DEFAULT NULL, `tvdb` int unsigned DEFAULT NULL, `tmdb` int unsigned DEFAULT NULL, @@ -1424,8 +1547,8 @@ CREATE TABLE `requests` ( `filled_anon` tinyint(1) NOT NULL DEFAULT '0', `approved_by` int unsigned DEFAULT NULL, `approved_when` datetime DEFAULT NULL, - `type_id` int NOT NULL, - `resolution_id` int DEFAULT NULL, + `type_id` smallint unsigned NOT NULL, + `resolution_id` smallint unsigned DEFAULT NULL, PRIMARY KEY (`id`), KEY `category_id` (`category_id`), KEY `imdb` (`imdb`), @@ -1440,8 +1563,11 @@ CREATE TABLE `requests` ( KEY `requests_approved_by_foreign` (`approved_by`), KEY `requests_torrent_id_foreign` (`torrent_id`), CONSTRAINT `requests_approved_by_foreign` FOREIGN KEY (`approved_by`) REFERENCES `users` (`id`) ON UPDATE CASCADE, + CONSTRAINT `requests_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE RESTRICT, CONSTRAINT `requests_filled_by_foreign` FOREIGN KEY (`filled_by`) REFERENCES `users` (`id`) ON UPDATE CASCADE, + CONSTRAINT `requests_resolution_id_foreign` FOREIGN KEY (`resolution_id`) REFERENCES `resolutions` (`id`) ON DELETE RESTRICT, CONSTRAINT `requests_torrent_id_foreign` FOREIGN KEY (`torrent_id`) REFERENCES `torrents` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `requests_type_id_foreign` FOREIGN KEY (`type_id`) REFERENCES `types` (`id`) ON DELETE RESTRICT, CONSTRAINT `requests_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE, CONSTRAINT `check_requests_bounty` CHECK ((`bounty` >= 0)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -1450,7 +1576,7 @@ DROP TABLE IF EXISTS `resolutions`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `resolutions` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `id` smallint unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `position` int NOT NULL, PRIMARY KEY (`id`) @@ -1735,7 +1861,7 @@ CREATE TABLE `topics` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `state` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `pinned` tinyint(1) NOT NULL DEFAULT '0', + `priority` tinyint unsigned NOT NULL, `approved` tinyint(1) NOT NULL DEFAULT '0', `denied` tinyint(1) NOT NULL DEFAULT '0', `solved` tinyint(1) NOT NULL DEFAULT '0', @@ -1802,6 +1928,23 @@ CREATE TABLE `torrent_tips` ( CONSTRAINT `torrent_tips_torrent_id_foreign` FOREIGN KEY (`torrent_id`) REFERENCES `torrents` (`id`) ON DELETE SET NULL ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `torrent_trumps`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `torrent_trumps` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `torrent_id` int unsigned NOT NULL, + `user_id` int unsigned NOT NULL, + `reason` text COLLATE utf8mb4_unicode_ci NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `torrent_trumps_torrent_id_user_id_unique` (`torrent_id`,`user_id`), + KEY `torrent_trumps_user_id_foreign` (`user_id`), + CONSTRAINT `torrent_trumps_torrent_id_foreign` FOREIGN KEY (`torrent_id`) REFERENCES `torrents` (`id`) ON DELETE CASCADE, + CONSTRAINT `torrent_trumps_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `torrents`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; @@ -1809,7 +1952,7 @@ CREATE TABLE `torrents` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, - `mediainfo` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, + `mediainfo` longtext COLLATE utf8mb4_unicode_ci, `bdinfo` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, `file_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `num_file` int NOT NULL, @@ -1819,7 +1962,7 @@ CREATE TABLE `torrents` ( `leechers` int NOT NULL DEFAULT '0', `seeders` int NOT NULL DEFAULT '0', `times_completed` int NOT NULL DEFAULT '0', - `category_id` int DEFAULT NULL, + `category_id` smallint unsigned DEFAULT NULL, `user_id` int unsigned NOT NULL, `imdb` int unsigned NOT NULL DEFAULT '0', `tvdb` int unsigned NOT NULL DEFAULT '0', @@ -1847,9 +1990,8 @@ CREATE TABLE `torrents` ( `deleted_at` timestamp NULL DEFAULT NULL, `fl_until` datetime DEFAULT NULL, `du_until` datetime DEFAULT NULL, - `release_year` smallint unsigned DEFAULT NULL, - `type_id` int NOT NULL, - `resolution_id` int DEFAULT NULL, + `type_id` smallint unsigned DEFAULT NULL, + `resolution_id` smallint unsigned DEFAULT NULL, `distributor_id` int DEFAULT NULL, `region_id` int DEFAULT NULL, `personal_release` int NOT NULL DEFAULT '0', @@ -1865,7 +2007,6 @@ CREATE TABLE `torrents` ( KEY `mal` (`mal`), KEY `moderated_by` (`moderated_by`), KEY `torrents_igdb_index` (`igdb`), - KEY `torrents_release_year_index` (`release_year`), KEY `torrents_type_id_index` (`type_id`), KEY `torrents_resolution_id_index` (`resolution_id`), KEY `torrents_personal_release_index` (`personal_release`), @@ -1888,7 +2029,12 @@ CREATE TABLE `torrents` ( KEY `torrents_info_hash_index` (`info_hash`), KEY `torrents_user_id_anon_status_created_at_index` (`user_id`,`anon`,`status`,`created_at`), KEY `torrents_status_sticky_created_at_index` (`status`,`sticky`,`created_at`), - CONSTRAINT `category_id` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT, + KEY `torrents_user_id_status_anon_deleted_at_index` (`user_id`,`status`,`anon`,`deleted_at`), + KEY `torrents_name_index` (`name`), + KEY `torrents_category_id_status_deleted_at_tmdb_size_index` (`category_id`,`status`,`deleted_at`,`tmdb`,`size`), + CONSTRAINT `torrents_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE RESTRICT, + CONSTRAINT `torrents_resolution_id_foreign` FOREIGN KEY (`resolution_id`) REFERENCES `resolutions` (`id`) ON DELETE RESTRICT, + CONSTRAINT `torrents_type_id_foreign` FOREIGN KEY (`type_id`) REFERENCES `types` (`id`) ON DELETE RESTRICT, CONSTRAINT `torrents_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1934,7 +2080,7 @@ DROP TABLE IF EXISTS `types`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `types` ( - `id` int NOT NULL AUTO_INCREMENT, + `id` smallint unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `position` int NOT NULL, PRIMARY KEY (`id`) @@ -2149,14 +2295,14 @@ CREATE TABLE `user_settings` ( `user_id` int unsigned NOT NULL, `censor` tinyint(1) NOT NULL DEFAULT '0', `chat_hidden` tinyint(1) NOT NULL DEFAULT '0', - `locale` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'en', + `locale` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'en', `style` tinyint unsigned NOT NULL DEFAULT '0', `torrent_layout` tinyint unsigned NOT NULL DEFAULT '0', `torrent_filters` tinyint(1) NOT NULL DEFAULT '0', - `custom_css` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `standalone_css` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `custom_css` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `standalone_css` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `show_poster` tinyint(1) NOT NULL DEFAULT '0', - `torrent_sort_field` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `torrent_sort_field` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `torrent_search_autofocus` tinyint(1) NOT NULL DEFAULT '1', `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, @@ -2182,6 +2328,7 @@ CREATE TABLE `users` ( `uploaded` bigint unsigned NOT NULL DEFAULT '0', `downloaded` bigint unsigned NOT NULL DEFAULT '0', `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `about` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, `signature` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, @@ -2192,12 +2339,14 @@ CREATE TABLE `users` ( `rsskey` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `chatroom_id` int unsigned NOT NULL DEFAULT '1', `read_rules` tinyint(1) NOT NULL DEFAULT '0', - `can_chat` tinyint(1) NOT NULL DEFAULT '1', - `can_comment` tinyint(1) NOT NULL DEFAULT '1', + `can_chat` tinyint(1) DEFAULT NULL, + `can_comment` tinyint(1) DEFAULT NULL, `can_download` tinyint(1) NOT NULL DEFAULT '1', - `can_request` tinyint(1) NOT NULL DEFAULT '1', - `can_invite` tinyint(1) NOT NULL DEFAULT '1', - `can_upload` tinyint(1) NOT NULL DEFAULT '1', + `can_invite` tinyint(1) DEFAULT NULL, + `can_request` tinyint(1) DEFAULT NULL, + `can_upload` tinyint(1) DEFAULT NULL, + `is_donor` tinyint(1) NOT NULL DEFAULT '0', + `is_lifetime` tinyint(1) NOT NULL DEFAULT '0', `remember_token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `api_token` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `last_login` datetime DEFAULT NULL, @@ -2650,3 +2799,25 @@ INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (302,'2024_06_06_04 INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (303,'2024_06_09_052006_drop_useless_columns_from_bots',7); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (304,'2024_06_14_005443_add_soft_deletes_to_torrents_table',7); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (305,'2024_06_23_202341_add_prewarned_at_to_history',7); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (306,'2024_05_06_212348_create_donations_table',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (307,'2024_05_06_212410_create_donation_packages_table',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (308,'2024_05_06_212446_create_donation_gateways_table',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (309,'2024_06_13_125854_add_is_uploader_to_groups_table',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (310,'2024_06_13_185043_add_donation_columns_to_users_table',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (311,'2024_07_02_082323_add_indexes_to_torrents_table',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (312,'2024_07_16_083832_add_composite_primary_key_to_peers',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (313,'2024_07_19_143828_add_priority_to_topics',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (314,'2024_07_23_054141_add_composite_primary_key_to_history',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (315,'2024_07_23_054751_create_torrent_trumps_table',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (316,'2024_07_23_153202_add_poll_expiry',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (317,'2024_07_26_211112_fix_some_user_group_perms',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (318,'2024_07_28_231553_update_cat_type_res_table',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (319,'2024_08_14_012412_drop_release_year_from_torrents_table',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (320,'2024_08_17_140412_create_password_reset_history',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (321,'2024_08_25_121227_drop_num_torrent_from_categories',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (322,'2024_08_26_085452_fix_bot_systembot_nerdbot_flags',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (323,'2024_09_02_224259_alter_reports_add_snooze_until',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (324,'2024_09_27_072554_add_indexes_to_audits',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (325,'2024_09_29_041904_add_indexes_for_top10_performance',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (326,'2024_10_10_140532_update_mediainfo_from_text_to_longtext',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (327,'2024_10_13_221353_create_events_claimed_prizes_tables',8); diff --git a/lang/en/event.php b/lang/en/event.php new file mode 100644 index 0000000000..785eb158f1 --- /dev/null +++ b/lang/en/event.php @@ -0,0 +1,30 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ + +return [ + 'add-event' => 'Add Event', + 'add-prize' => 'Add Prize', + 'edit-event' => 'Edit Event', + 'edit-prize' => 'Edit Prize', + 'ends-at' => 'Ends At', + 'events' => 'Events', + 'minimum' => 'Minimum', + 'maximum' => 'Maximum', + 'no-prizes' => 'No prizes.', + 'prize' => 'Prize', + 'prizes' => 'Prizes', + 'starts-at' => 'Starts At', + 'weight' => 'Weight', +]; diff --git a/lang/es/event.php b/lang/es/event.php new file mode 100644 index 0000000000..b1af04e521 --- /dev/null +++ b/lang/es/event.php @@ -0,0 +1,30 @@ + + * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 + */ +return [ + 'add-event' => 'Añadir evento', + 'add-prize' => 'Añadir premio', + 'edit-event' => 'Editar evento', + 'edit-prize' => 'Editar premio', + 'ends-at' => 'Termina en', + 'events' => 'Eventos', + 'minimum' => 'Mínimo', + 'maximum' => 'Máximo', + 'no-prizes' => 'No hay premios.', + 'prize' => 'Premio', + 'prizes' => 'Premios', + 'starts-at' => 'A partir de', + 'weight' => 'Peso', +]; diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 60eb6b81a2..82c944aa27 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -310,11 +310,6 @@ parameters: count: 1 path: app/Http/Controllers/HomeController.php - - - message: "#^Property App\\\\Models\\\\Rss\\:\\:\\$is_private \\(int\\) does not accept true\\.$#" - count: 2 - path: app/Http/Controllers/RssController.php - - message: "#^Unable to resolve the template type TKey in call to function collect$#" count: 2 @@ -325,11 +320,6 @@ parameters: count: 2 path: app/Http/Controllers/SimilarTorrentController.php - - - message: "#^Parameter \\#1 \\$boolean of function abort_if expects bool, int given\\.$#" - count: 1 - path: app/Http/Controllers/Staff/ChatBotController.php - - message: "#^Call to function is_int\\(\\) with string\\|null will always evaluate to false\\.$#" count: 1 @@ -365,16 +355,6 @@ parameters: count: 1 path: app/Http/Controllers/Staff/DonationGatewayController.php - - - message: "#^Parameter \\#1 \\$boolean of function abort_if expects bool, int given\\.$#" - count: 3 - path: app/Http/Controllers/Staff/RssController.php - - - - message: "#^Property App\\\\Models\\\\Rss\\:\\:\\$is_private \\(int\\) does not accept false\\.$#" - count: 1 - path: app/Http/Controllers/Staff/RssController.php - - message: "#^Access to an undefined property App\\\\Models\\\\Group\\|Illuminate\\\\Database\\\\Eloquent\\\\Collection\\\\:\\:\\$level\\.$#" count: 1 @@ -390,11 +370,6 @@ parameters: count: 1 path: app/Http/Controllers/TopicController.php - - - message: "#^Property App\\\\Models\\\\Torrent\\:\\:\\$refundable \\(bool\\) does not accept int\\.$#" - count: 1 - path: app/Http/Controllers/TorrentBuffController.php - - message: "#^Unable to resolve the template type TKey in call to function collect$#" count: 2 @@ -415,11 +390,6 @@ parameters: count: 2 path: app/Http/Controllers/User/UserController.php - - - message: "#^Parameter \\#2 \\$timestamp of function date expects int\\|null, int\\|false given\\.$#" - count: 1 - path: app/Http/Controllers/YearlyOverviewController.php - - message: "#^Property App\\\\Http\\\\Livewire\\\\AttachmentUpload\\:\\:\\$attachment has no type specified\\.$#" count: 1 diff --git a/public/vendor/livewire/livewire.js b/public/vendor/livewire/livewire.js index c740e266b2..670591055f 100644 --- a/public/vendor/livewire/livewire.js +++ b/public/vendor/livewire/livewire.js @@ -712,7 +712,7 @@ uploadManager.cancelUpload(name, cancelledCallback); } - // node_modules/alpinejs/dist/module.esm.js + // ../alpine/packages/alpinejs/dist/module.esm.js var flushPending = false; var flushing = false; var queue = []; @@ -851,10 +851,9 @@ }); } function cleanupElement(el) { - if (el._x_cleanups) { - while (el._x_cleanups.length) - el._x_cleanups.pop()(); - } + el._x_effects?.forEach(dequeueJob); + while (el._x_cleanups?.length) + el._x_cleanups.pop()(); } var observer = new MutationObserver(onMutate); var currentlyObserving = false; @@ -1092,27 +1091,23 @@ magics[name] = callback; } function injectMagics(obj, el) { + let memoizedUtilities = getUtilities(el); Object.entries(magics).forEach(([name, callback]) => { - let memoizedUtilities = null; - function getUtilities() { - if (memoizedUtilities) { - return memoizedUtilities; - } else { - let [utilities, cleanup2] = getElementBoundUtilities(el); - memoizedUtilities = { interceptor, ...utilities }; - onElRemoved(el, cleanup2); - return memoizedUtilities; - } - } Object.defineProperty(obj, `$${name}`, { get() { - return callback(el, getUtilities()); + return callback(el, memoizedUtilities); }, enumerable: false }); }); return obj; } + function getUtilities(el) { + let [utilities, cleanup2] = getElementBoundUtilities(el); + let utils = { interceptor, ...utilities }; + onElRemoved(el, cleanup2); + return utils; + } function tryCatch(el, expression, callback, ...args) { try { return callback(...args); @@ -1486,8 +1481,8 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } function destroyTree(root, walker = walk) { walker(root, (el) => { - cleanupAttributes(el); cleanupElement(el); + cleanupAttributes(el); }); } function warnAboutMissingPlugins() { @@ -1980,7 +1975,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } } function bindInputValue(el, value) { - if (el.type === "radio") { + if (isRadio(el)) { if (el.attributes.value === void 0) { el.value = value; } @@ -1991,7 +1986,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); el.checked = checkedAttrLooseCompare(el.value, value); } } - } else if (el.type === "checkbox") { + } else if (isCheckbox(el)) { if (Number.isInteger(value)) { el.value = value; } else if (!Array.isArray(value) && typeof value !== "boolean" && ![null, void 0].includes(value)) { @@ -2067,34 +2062,37 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } return rawValue ? Boolean(rawValue) : null; } + var booleanAttributes = /* @__PURE__ */ new Set([ + "allowfullscreen", + "async", + "autofocus", + "autoplay", + "checked", + "controls", + "default", + "defer", + "disabled", + "formnovalidate", + "inert", + "ismap", + "itemscope", + "loop", + "multiple", + "muted", + "nomodule", + "novalidate", + "open", + "playsinline", + "readonly", + "required", + "reversed", + "selected", + "shadowrootclonable", + "shadowrootdelegatesfocus", + "shadowrootserializable" + ]); function isBooleanAttr(attrName) { - const booleanAttributes = [ - "disabled", - "checked", - "required", - "readonly", - "open", - "selected", - "autofocus", - "itemscope", - "multiple", - "novalidate", - "allowfullscreen", - "allowpaymentrequest", - "formnovalidate", - "autoplay", - "controls", - "loop", - "muted", - "playsinline", - "default", - "ismap", - "reversed", - "async", - "defer", - "nomodule" - ]; - return booleanAttributes.includes(attrName); + return booleanAttributes.has(attrName); } function attributeShouldntBePreservedIfFalsy(name) { return !["aria-pressed", "aria-checked", "aria-expanded", "aria-selected"].includes(name); @@ -2127,6 +2125,12 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } return attr; } + function isCheckbox(el) { + return el.type === "checkbox" || el.localName === "ui-checkbox" || el.localName === "ui-switch"; + } + function isRadio(el) { + return el.type === "radio" || el.localName === "ui-radio"; + } function debounce(func, wait) { var timeout; return function() { @@ -2195,10 +2199,10 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); return stores[name]; } stores[name] = value; + initInterceptors(stores[name]); if (typeof value === "object" && value !== null && value.hasOwnProperty("init") && typeof value.init === "function") { stores[name].init(); } - initInterceptors(stores[name]); } function getStores() { return stores; @@ -2280,7 +2284,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); get raw() { return raw; }, - version: "3.14.1", + version: "3.14.3", flushAndStopDeferringMutations, dontAutoEvaluateFunctions, disableEffectScheduling, @@ -3136,7 +3140,10 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); placeInDom(el._x_teleport, target2, modifiers); }); }; - cleanup2(() => clone2.remove()); + cleanup2(() => mutateDom(() => { + clone2.remove(); + destroyTree(clone2); + })); }); var teleportContainerDuringClone = document.createElement("div"); function getTarget(expression) { @@ -3360,7 +3367,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); setValue(getInputValue(el, modifiers, e, getValue())); }); if (modifiers.includes("fill")) { - if ([void 0, null, ""].includes(getValue()) || el.type === "checkbox" && Array.isArray(getValue()) || el.tagName.toLowerCase() === "select" && el.multiple) { + if ([void 0, null, ""].includes(getValue()) || isCheckbox(el) && Array.isArray(getValue()) || el.tagName.toLowerCase() === "select" && el.multiple) { setValue(getInputValue(el, modifiers, { target: el }, getValue())); } } @@ -3400,7 +3407,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); return mutateDom(() => { if (event instanceof CustomEvent && event.detail !== void 0) return event.detail !== null && event.detail !== void 0 ? event.detail : event.target.value; - else if (el.type === "checkbox") { + else if (isCheckbox(el)) { if (Array.isArray(currentValue)) { let newValue = null; if (modifiers.includes("number")) { @@ -3431,7 +3438,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); }); } else { let newValue; - if (el.type === "radio") { + if (isRadio(el)) { if (event.target.checked) { newValue = event.target.value; } else { @@ -3624,7 +3631,10 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); el._x_lookup = {}; effect3(() => loop(el, iteratorNames, evaluateItems, evaluateKey)); cleanup2(() => { - Object.values(el._x_lookup).forEach((el2) => el2.remove()); + Object.values(el._x_lookup).forEach((el2) => mutateDom(() => { + destroyTree(el2); + el2.remove(); + })); delete el._x_prevKeys; delete el._x_lookup; }); @@ -3693,11 +3703,12 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } for (let i = 0; i < removes.length; i++) { let key = removes[i]; - if (!!lookup[key]._x_effects) { - lookup[key]._x_effects.forEach(dequeueJob); - } - lookup[key].remove(); - lookup[key] = null; + if (!(key in lookup)) + continue; + mutateDom(() => { + destroyTree(lookup[key]); + lookup[key].remove(); + }); delete lookup[key]; } for (let i = 0; i < moves.length; i++) { @@ -3818,12 +3829,10 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); }); el._x_currentIfEl = clone2; el._x_undoIf = () => { - walk(clone2, (node) => { - if (!!node._x_effects) { - node._x_effects.forEach(dequeueJob); - } + mutateDom(() => { + destroyTree(clone2); + clone2.remove(); }); - clone2.remove(); delete el._x_currentIfEl; }; return clone2; @@ -4762,7 +4771,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } }; - // node_modules/@alpinejs/collapse/dist/module.esm.js + // ../../../../usr/local/lib/node_modules/@alpinejs/collapse/dist/module.esm.js function src_default2(Alpine3) { Alpine3.directive("collapse", collapse); collapse.inline = (el, { modifiers }) => { @@ -4812,7 +4821,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); start: { height: current + "px" }, end: { height: full + "px" } }, () => el._x_isShown = true, () => { - if (Math.abs(el.getBoundingClientRect().height - full) < 1) { + if (el.getBoundingClientRect().height == full) { el.style.overflow = null; } }); @@ -4856,7 +4865,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } var module_default2 = src_default2; - // node_modules/@alpinejs/focus/dist/module.esm.js + // ../../../../usr/local/lib/node_modules/@alpinejs/focus/dist/module.esm.js var candidateSelectors = ["input", "select", "textarea", "a[href]", "button", "[tabindex]:not(slot)", "audio[controls]", "video[controls]", '[contenteditable]:not([contenteditable="false"])', "details>summary:first-of-type", "details"]; var candidateSelector = /* @__PURE__ */ candidateSelectors.join(","); var NoElement = typeof Element === "undefined"; @@ -4968,11 +4977,11 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); var checked = getCheckedRadio(radioSet, node.form); return !checked || checked === node; }; - var isRadio = function isRadio2(node) { + var isRadio2 = function isRadio22(node) { return isInput(node) && node.type === "radio"; }; var isNonTabbableRadio = function isNonTabbableRadio2(node) { - return isRadio(node) && !isTabbableRadio(node); + return isRadio2(node) && !isTabbableRadio(node); }; var isZeroArea = function isZeroArea2(node) { var _node$getBoundingClie = node.getBoundingClientRect(), width = _node$getBoundingClie.width, height = _node$getBoundingClie.height; @@ -5805,7 +5814,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } var module_default3 = src_default3; - // node_modules/@alpinejs/persist/dist/module.esm.js + // ../../../../usr/local/lib/node_modules/@alpinejs/persist/dist/module.esm.js function src_default4(Alpine3) { let persist = () => { let alias; @@ -5867,7 +5876,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } var module_default4 = src_default4; - // node_modules/@alpinejs/intersect/dist/module.esm.js + // ../../../../usr/local/lib/node_modules/@alpinejs/intersect/dist/module.esm.js function src_default5(Alpine3) { Alpine3.directive("intersect", Alpine3.skipDuringClone((el, { value, expression, modifiers }, { evaluateLater: evaluateLater2, cleanup: cleanup2 }) => { let evaluate3 = evaluateLater2(expression); @@ -5967,7 +5976,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } var module_default6 = src_default6; - // node_modules/@alpinejs/anchor/dist/module.esm.js + // ../alpine/packages/anchor/dist/module.esm.js var min = Math.min; var max = Math.max; var round = Math.round; @@ -7471,8 +7480,10 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } }; queueMicrotask(() => { - scroll(document.body); - document.querySelectorAll(["[x-navigate\\:scroll]", "[wire\\:scroll]"]).forEach(scroll); + queueMicrotask(() => { + scroll(document.body); + document.querySelectorAll(["[x-navigate\\:scroll]", "[wire\\:scroll]"]).forEach(scroll); + }); }); } @@ -7620,6 +7631,44 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); document.head.appendChild(style); } + // js/plugins/navigate/popover.js + function packUpPersistedPopovers(persistedEl) { + persistedEl.querySelectorAll(":popover-open").forEach((el) => { + el.setAttribute("data-navigate-popover-open", ""); + let animations = el.getAnimations(); + el._pausedAnimations = animations.map((animation) => ({ + keyframes: animation.effect.getKeyframes(), + options: { + duration: animation.effect.getTiming().duration, + easing: animation.effect.getTiming().easing, + fill: animation.effect.getTiming().fill, + iterations: animation.effect.getTiming().iterations + }, + currentTime: animation.currentTime, + playState: animation.playState + })); + animations.forEach((i) => i.pause()); + }); + } + function unPackPersistedPopovers(persistedEl) { + persistedEl.querySelectorAll("[data-navigate-popover-open]").forEach((el) => { + el.removeAttribute("data-navigate-popover-open"); + queueMicrotask(() => { + if (!el.isConnected) + return; + el.showPopover(); + el.getAnimations().forEach((i) => i.finish()); + if (el._pausedAnimations) { + el._pausedAnimations.forEach(({ keyframes, options, currentTime, now, playState }) => { + let animation = el.animate(keyframes, options); + animation.currentTime = currentTime; + }); + delete el._pausedAnimations; + } + }); + }); + } + // js/plugins/navigate/page.js var oldBodyScriptTagHashes = []; var attributesExemptFromScriptTagHashing = [ @@ -7758,7 +7807,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); function navigate_default(Alpine3) { Alpine3.navigate = (url) => { let destination = createUrlObjectFromString(url); - let prevented = fireEventForOtherLibariesToHookInto("alpine:navigate", { + let prevented = fireEventForOtherLibrariesToHookInto("alpine:navigate", { url: destination, history: false, cached: false @@ -7789,7 +7838,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); storeThePrefetchedHtmlForWhenALinkIsClicked(html, destination, finalDestination); }); whenItIsReleased(() => { - let prevented = fireEventForOtherLibariesToHookInto("alpine:navigate", { + let prevented = fireEventForOtherLibrariesToHookInto("alpine:navigate", { url: destination, history: false, cached: false @@ -7803,7 +7852,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); function navigateTo(destination, shouldPushToHistoryState = true) { showProgressBar && showAndStartProgressBar(); fetchHtmlOrUsePrefetchedHtml(destination, (html, finalDestination) => { - fireEventForOtherLibariesToHookInto("alpine:navigating"); + fireEventForOtherLibrariesToHookInto("alpine:navigating"); restoreScroll && storeScrollInformationInHtmlBeforeNavigatingAway(); showProgressBar && finishAndHideProgressBar(); cleanupAlpineElementsOnThePageThatArentInsideAPersistedElement(); @@ -7811,6 +7860,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); preventAlpineFromPickingUpDomChanges(Alpine3, (andAfterAllThis) => { enablePersist && storePersistantElementsForLater((persistedEl) => { packUpPersistedTeleports(persistedEl); + packUpPersistedPopovers(persistedEl); }); if (shouldPushToHistoryState) { updateUrlAndStoreLatestHtmlForFutureBackButtons(html, finalDestination); @@ -7821,6 +7871,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); removeAnyLeftOverStaleTeleportTargets(document.body); enablePersist && putPersistantElementsBack((persistedEl, newStub) => { unPackPersistedTeleports(persistedEl); + unPackPersistedPopovers(persistedEl); }); restoreScrollPositionOrScrollToTop(); afterNewScriptsAreDoneLoading(() => { @@ -7829,7 +7880,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); autofocus && autofocusElementsWithTheAutofocusAttribute(); }); nowInitializeAlpineOnTheNewPage(Alpine3); - fireEventForOtherLibariesToHookInto("alpine:navigated"); + fireEventForOtherLibrariesToHookInto("alpine:navigated"); }); }); }); @@ -7839,7 +7890,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); whenTheBackOrForwardButtonIsClicked((ifThePageBeingVisitedHasntBeenCached) => { ifThePageBeingVisitedHasntBeenCached((url) => { let destination = createUrlObjectFromString(url); - let prevented = fireEventForOtherLibariesToHookInto("alpine:navigate", { + let prevented = fireEventForOtherLibrariesToHookInto("alpine:navigate", { url: destination, history: true, cached: false @@ -7851,7 +7902,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); }); }, (html, url, currentPageUrl, currentPageKey) => { let destination = createUrlObjectFromString(url); - let prevented = fireEventForOtherLibariesToHookInto("alpine:navigate", { + let prevented = fireEventForOtherLibrariesToHookInto("alpine:navigate", { url: destination, history: true, cached: true @@ -7859,29 +7910,31 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); if (prevented) return; storeScrollInformationInHtmlBeforeNavigatingAway(); - fireEventForOtherLibariesToHookInto("alpine:navigating"); + fireEventForOtherLibrariesToHookInto("alpine:navigating"); updateCurrentPageHtmlInSnapshotCacheForLaterBackButtonClicks(currentPageUrl, currentPageKey); preventAlpineFromPickingUpDomChanges(Alpine3, (andAfterAllThis) => { enablePersist && storePersistantElementsForLater((persistedEl) => { packUpPersistedTeleports(persistedEl); + packUpPersistedPopovers(persistedEl); }); swapCurrentPageWithNewHtml(html, () => { removeAnyLeftOverStaleProgressBars(); removeAnyLeftOverStaleTeleportTargets(document.body); enablePersist && putPersistantElementsBack((persistedEl, newStub) => { unPackPersistedTeleports(persistedEl); + unPackPersistedPopovers(persistedEl); }); restoreScrollPositionOrScrollToTop(); andAfterAllThis(() => { autofocus && autofocusElementsWithTheAutofocusAttribute(); nowInitializeAlpineOnTheNewPage(Alpine3); - fireEventForOtherLibariesToHookInto("alpine:navigated"); + fireEventForOtherLibrariesToHookInto("alpine:navigated"); }); }); }); }); setTimeout(() => { - fireEventForOtherLibariesToHookInto("alpine:navigated"); + fireEventForOtherLibrariesToHookInto("alpine:navigated"); }); } function fetchHtmlOrUsePrefetchedHtml(fromDestination, callback) { @@ -7898,7 +7951,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); }); }); } - function fireEventForOtherLibariesToHookInto(name, detail) { + function fireEventForOtherLibrariesToHookInto(name, detail) { let event = new CustomEvent(name, { cancelable: true, bubbles: true, @@ -8132,7 +8185,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); return data2; } - // node_modules/@alpinejs/morph/dist/module.esm.js + // ../alpine/packages/morph/dist/module.esm.js function morph(from, toHtml, options) { monkeyPatchDomSetAttributeToAllowAtSymbols(); let fromEl; @@ -8467,7 +8520,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); } var module_default8 = src_default8; - // node_modules/@alpinejs/mask/dist/module.esm.js + // ../../../../usr/local/lib/node_modules/@alpinejs/mask/dist/module.esm.js function src_default9(Alpine3) { Alpine3.directive("mask", (el, { value, expression }, { effect: effect3, evaluateLater: evaluateLater2, cleanup: cleanup2 }) => { let templateFn = () => expression; @@ -8905,6 +8958,7 @@ ${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); }, lookahead: false }); + trigger2("morphed", { el, component }); } function isntElement(el) { return typeof el.hasAttribute !== "function"; diff --git a/public/vendor/livewire/manifest.json b/public/vendor/livewire/manifest.json index f1e923336a..960dcd7bec 100644 --- a/public/vendor/livewire/manifest.json +++ b/public/vendor/livewire/manifest.json @@ -1,2 +1,2 @@ -{"/livewire.js":"cc800bf4"} +{"/livewire.js":"38dc8241"} diff --git a/resources/sass/components/_bbcode-rendered.scss b/resources/sass/components/_bbcode-rendered.scss index 856ee8f33d..e600b1b737 100644 --- a/resources/sass/components/_bbcode-rendered.scss +++ b/resources/sass/components/_bbcode-rendered.scss @@ -86,7 +86,7 @@ overflow: hidden; background: transparent; border-bottom: 1px solid var(--bbcode-rendered-border-muted); - height: 0.25em; + height: 1px; padding: 0; margin: 24px 0; background-color: var(--bbcode-rendered-border-default); diff --git a/resources/sass/components/_event.scss b/resources/sass/components/_event.scss new file mode 100644 index 0000000000..b7d5ee4976 --- /dev/null +++ b/resources/sass/components/_event.scss @@ -0,0 +1,57 @@ +.events__list { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + grid-auto-rows: 1fr; + grid-auto-flow: dense; + grid-gap: 2rem; + list-style-type: none; + margin: 0; + padding: 0; +} + +.events__prize { + background-color: var(--prize-bg); + color: var(--prize-fg); + border-radius: var(--prize-border-radius); + box-shadow: var(--prize-box-shadow); + border: var(--prize-border); + padding: 12px; + display: flex; + flex-direction: column; + gap: 1rem; + height: 100%; + align-items: center; +} + +.events__prize-heading { + margin: 0; + text-align: center; + color: var(--prize-heading-fg); + margin-bottom: 12px; +} + +.events__prize-icon { + font-size: 64px; + margin-bottom: 8px; +} + +.events__prize-icon--today-unclaimed, +.events__prize-icon--future { + --fa-secondary-opacity: 1; + --fa-primary-color: var(--prize-icon-primary-color); + --fa-secondary-color: var(--prize-icon-secondary-color); +} + +.events__prize-message { + margin: 10px 0 10px 0; + text-align: center; +} + +.events__prize-winnings-list { + margin: 10px 0 0 0; + padding: 0; + list-style-type: none; + display: flex; + flex-direction: column; + align-items: center; +} diff --git a/resources/sass/components/_quick_search.scss b/resources/sass/components/_quick_search.scss index 8ed2335560..da6b6691a2 100755 --- a/resources/sass/components/_quick_search.scss +++ b/resources/sass/components/_quick_search.scss @@ -1,6 +1,6 @@ .quick-search { position: relative; - max-width: 360px; + max-width: 250px; flex-grow: 1; z-index: 5; @@ -56,60 +56,6 @@ display: none; } -.quick-search__radios { - display: flex; - align-items: stretch; - background-color: inherit; - cursor: pointer; - width: min-content; -} - -.quick-search__radio-label { - cursor: pointer; - color: var(--quick-search-selector-fg); - display: flex; -} - -.quick-search__radio-label:hover, -.quick-search__radio-label:focus-within { - color: var(--quick-search-selector-hover-fg); -} - -.quick-search__radio-icon { - height: 100%; -} - -.quick-search__radio-icon:before { - display: block; - height: 100%; - width: 32px; - padding: 8px 0; - text-align: center; - font-size: 14px; -} - -.quick-search__radio-icon:hover, -.quick-search__radio-label:focus-within .quick-search__radio-icon { - background-color: var(--quick-search-selector-hover-bg); -} - -.quick-search__radio:checked ~ .quick-search__radio-icon:before { - background-color: var(--quick-search-selector-selected-bg); - color: var(--quick-search-selector-selected-fg); -} - -.quick-search__radio { - position: absolute !important; - opacity: 0; - width: 0 !important; - height: 0 !important; - - &::after { - width: 0 !important; - height: 0 !important; - } -} - .quick-search__results { position: absolute; left: 0; diff --git a/resources/sass/components/form/_text.scss b/resources/sass/components/form/_text.scss index 219499fa3c..571e4301c6 100644 --- a/resources/sass/components/form/_text.scss +++ b/resources/sass/components/form/_text.scss @@ -50,7 +50,8 @@ &:valid:not(:placeholder-shown), &:focus:placeholder-shown, - &:read-only { + &:read-only, + &[type='date'][required] { & + .form__label--floating { top: -5px; font-size: 11px; diff --git a/resources/sass/main.scss b/resources/sass/main.scss index 100e69b05b..adf5d55455 100755 --- a/resources/sass/main.scss +++ b/resources/sass/main.scss @@ -31,6 +31,7 @@ @import 'components/dialog'; @import 'components/donation-package'; @import 'components/emoji'; +@import 'components/event'; @import 'components/featured-pane'; @import 'components/form/button'; @import 'components/form/checkbox'; diff --git a/resources/sass/pages/_torrents.scss b/resources/sass/pages/_torrents.scss index 6734d285ca..ac9e277b14 100644 --- a/resources/sass/pages/_torrents.scss +++ b/resources/sass/pages/_torrents.scss @@ -124,7 +124,7 @@ .torrent-search--list__row { display: grid; grid-template-rows: auto; - grid-template-columns: 60px 100px 1fr 150px 60px 100px 50px 50px 50px 120px; + grid-template-columns: 60px 100px 1fr 150px 68px 100px 50px 50px 50px 120px; grid-template-areas: 'poster format overview buttons rating size seeders leechers completed age'; } @@ -132,7 +132,7 @@ .torrent-search--list__no-poster-row { display: grid; grid-template-rows: auto; - grid-template-columns: 100px 1fr 150px 60px 100px 50px 50px 50px 120px; + grid-template-columns: 100px 1fr 150px 68px 100px 50px 50px 50px 120px; grid-template-areas: 'format overview buttons rating size seeders leechers completed age'; } @@ -292,6 +292,7 @@ } .torrent-search--list__name-header, + .torrent-search--list__ratings-header, .torrent-search--list__size-header, .torrent-search--list__seeders-header, .torrent-search--list__leechers-header, @@ -302,8 +303,7 @@ .torrent-search--list__poster-header, .torrent-search--list__format-header, - .torrent-search--list__actions-header, - .torrent-search--list__ratings-header { + .torrent-search--list__actions-header { display: none; } diff --git a/resources/sass/themes/_cosmic-void.scss b/resources/sass/themes/_cosmic-void.scss index bae9e5a205..0fe6409485 100644 --- a/resources/sass/themes/_cosmic-void.scss +++ b/resources/sass/themes/_cosmic-void.scss @@ -211,6 +211,16 @@ --post-aside-fg: #ccc; --post-footer-fg: var(--text-color); + --prize-bg: #111; + --prize-border-radius: 10px; + --prize-border: none; + --prize-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), + 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2); + --prize-fg: #bbb; + --prize-heading-fg: #bbb; + --prize-icon-primary-color: mediumseagreen; + --prize-icon-secondary-color: linen; + --quick-search-bg: #444; --quick-search-fg: #b6b6b6; --quick-search-border: 1px solid transparent; diff --git a/resources/sass/themes/_galactic.scss b/resources/sass/themes/_galactic.scss index 4e3e90456a..a96c65abaf 100644 --- a/resources/sass/themes/_galactic.scss +++ b/resources/sass/themes/_galactic.scss @@ -235,6 +235,16 @@ --playlist-card-missing-image-bg: #202020; --playlist-card-missing-image-fg: #b5b5b5; + --prize-bg: #111; + --prize-border-radius: 10px; + --prize-border: none; + --prize-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), + 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2); + --prize-fg: #bbb; + --prize-heading-fg: #bbb; + --prize-icon-primary-color: mediumseagreen; + --prize-icon-secondary-color: linen; + --post-bg: #2b2b2b; --post-fg: #ccc; --post-shadow: none; diff --git a/resources/sass/themes/_light.scss b/resources/sass/themes/_light.scss index 33a372161c..a0c117052f 100644 --- a/resources/sass/themes/_light.scss +++ b/resources/sass/themes/_light.scss @@ -222,6 +222,16 @@ --post-aside-fg: #696969; --post-footer-fg: var(--panel-fg); + --prize-bg: #f6f6f6; + --prize-border-radius: 10px; + --prize-border: none; + --prize-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), + 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2); + --prize-fg: #222; + --prize-heading-fg: #222; + --prize-icon-primary-color: mediumseagreen; + --prize-icon-secondary-color: linen; + --quick-search-bg: #e5e5e5; --quick-search-fg: #444; --quick-search-border: none; diff --git a/resources/sass/themes/_material-design-v3-amoled.scss b/resources/sass/themes/_material-design-v3-amoled.scss index df110e02bf..0ffa25817a 100644 --- a/resources/sass/themes/_material-design-v3-amoled.scss +++ b/resources/sass/themes/_material-design-v3-amoled.scss @@ -221,6 +221,16 @@ --post-aside-fg: #696969; --post-footer-fg: var(--panel-fg); + --prize-bg: #000; + --prize-border-radius: 20px; + --prize-border: 1px solid #222; + --prize-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), + 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2); + --prize-fg: #d8d7dc; + --prize-heading-fg: #d8d7dc; + --prize-icon-primary-color: mediumseagreen; + --prize-icon-secondary-color: linen; + --quick-search-bg: #000; --quick-search-fg: #aaa; --quick-search-border: 1px solid #444; diff --git a/resources/sass/themes/_material-design-v3-dark.scss b/resources/sass/themes/_material-design-v3-dark.scss index 2ed17969c3..bf4fe2847a 100644 --- a/resources/sass/themes/_material-design-v3-dark.scss +++ b/resources/sass/themes/_material-design-v3-dark.scss @@ -222,6 +222,16 @@ --post-aside-fg: #696969; --post-footer-fg: var(--panel-fg); + --prize-bg: #343338; + --prize-border-radius: 20px; + --prize-border: none; + --prize-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), + 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2); + --prize-fg: #d8d7dc; + --prize-heading-fg: #d8d7dc; + --prize-icon-primary-color: mediumseagreen; + --prize-icon-secondary-color: linen; + --quick-search-bg: #3b3b42; --quick-search-fg: #a0a0ac; --quick-search-border: none; diff --git a/resources/sass/themes/_material-design-v3-light.scss b/resources/sass/themes/_material-design-v3-light.scss index 45de7e3862..dc4b1b0906 100644 --- a/resources/sass/themes/_material-design-v3-light.scss +++ b/resources/sass/themes/_material-design-v3-light.scss @@ -221,6 +221,16 @@ --post-aside-fg: #696969; --post-footer-fg: var(--panel-fg); + --prize-bg: #fff; + --prize-border-radius: 20px; + --prize-border: none; + --prize-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), + 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2); + --prize-fg: #222; + --prize-heading-fg: #222; + --prize-icon-primary-color: mediumseagreen; + --prize-icon-secondary-color: linen; + --quick-search-bg: #f3f3f5; --quick-search-fg: #444; --quick-search-border: none; diff --git a/resources/sass/themes/_nord.scss b/resources/sass/themes/_nord.scss index 0bc56d9a28..2202e8aa93 100644 --- a/resources/sass/themes/_nord.scss +++ b/resources/sass/themes/_nord.scss @@ -237,6 +237,16 @@ --post-aside-fg: #d8dee9; --post-footer-fg: #d8dee9; + --prize-bg: #434c5e; + --prize-border-radius: 10px; + --prize-border: none; + --prize-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), + 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2); + --prize-fg: #d8dee9; + --prize-heading-fg: #d8dee9; + --prize-icon-primary-color: mediumseagreen; + --prize-icon-secondary-color: linen; + --quick-search-bg: #3b4252; --quick-search-fg: #d8dee9; --quick-search-border: none; diff --git a/resources/sass/themes/_revel.scss b/resources/sass/themes/_revel.scss index e87df6e916..eb8e6a7d44 100644 --- a/resources/sass/themes/_revel.scss +++ b/resources/sass/themes/_revel.scss @@ -242,6 +242,15 @@ --post-aside-fg: #ccc; --post-footer-fg: var(--text-color); + --prize-bg: #2c2c2c; + --prize-border-radius: 0; + --prize-border: none; + --prize-box-shadow: none; + --prize-fg: #aaa; + --prize-heading-fg: #aaa; + --prize-icon-primary-color: mediumseagreen; + --prize-icon-secondary-color: linen; + --quick-search-bg: #1a1a1a; --quick-search-fg: #b6b6b6; --quick-search-border: 1px solid #363636; diff --git a/resources/views/Staff/dashboard/index.blade.php b/resources/views/Staff/dashboard/index.blade.php index d9c9134cb6..524c9ed19f 100644 --- a/resources/views/Staff/dashboard/index.blade.php +++ b/resources/views/Staff/dashboard/index.blade.php @@ -159,6 +159,15 @@ class="form__button form__button--text" {{ __('staff.articles') }}

    +

    + + + {{ __('event.events') }} + +

    $ {{ $package->cost }} - {{ App\Helpers\StringHelper::formatBytes($package->upload_value) }} + {{ App\Helpers\StringHelper::formatBytes($package->upload_value ?? 0) }} - {{ $package->invite_value }} - {{ $package->bonus_value }} + {{ $package->invite_value ?? 0 }} + {{ $package->bonus_value ?? 0 }} @if ($package->donor_value === null) Lifetime diff --git a/resources/views/Staff/event/create.blade.php b/resources/views/Staff/event/create.blade.php new file mode 100644 index 0000000000..7dff64d88a --- /dev/null +++ b/resources/views/Staff/event/create.blade.php @@ -0,0 +1,103 @@ +@extends('layout.default') + +@section('breadcrumbs') +

  • + + +@endsection + +@section('page', 'page__event--index') + +@section('main') +
    +

    {{ __('event.add-event') }}

    +
    + @csrf +

    + + +

    +

    + + +

    +

    + + +

    +
    +

    + + +

    +

    + + +

    +
    +

    + + + +

    +

    + + +

    +
    +
    +@endsection diff --git a/resources/views/Staff/event/edit.blade.php b/resources/views/Staff/event/edit.blade.php new file mode 100644 index 0000000000..e179d58e00 --- /dev/null +++ b/resources/views/Staff/event/edit.blade.php @@ -0,0 +1,397 @@ +@extends('layout.default') + +@section('breadcrumbs') + + + + +@endsection + +@section('page', 'page__event--index') + +@section('main') +
    +

    {{ __('event.edit-event') }}

    +
    + @csrf + @method('PATCH') +

    + + +

    +

    + + +

    +

    + + +

    +
    +

    + + +

    +

    + + +

    +
    +

    + + active) + /> + +

    +

    + + +

    +
    +
    +
    +
    +

    {{ __('event.prizes') }}

    +
    +
    + + +

    {{ __('event.add-prize') }}

    +
    + @csrf + +

    + + +

    +

    + + +

    +

    + + +

    +

    + + +

    +

    + + +

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + @forelse ($event->prizes as $prize) + + + + + + + + @empty + + + + @endforelse + +
    {{ __('common.type') }}{{ __('event.minimum') }}{{ __('event.maximum') }}{{ __('event.weight') }}{{ __('common.actions') }}
    + @switch($prize->type) + @case('bon') + {{ __('bon.bon') }} + + @break + @case('fl_tokens') + {{ __('common.fl_tokens') }} + + @break + @endswitch + {{ $prize->min }}{{ $prize->max }}{{ $prize->weight }} + +
  • + + +

    + {{ __('event.edit-prize') }} +

    +
    + @csrf + @method('PATCH') + +

    + + +

    +

    + + +

    +

    + + +

    +

    + + +

    +

    + + +

    +
    +
    +
  • +
  • +
    + @csrf + @method('DELETE') + +
    +
  • +
    +
    {{ __('event.no-prizes') }}
    +
    +
    +@endsection diff --git a/resources/views/Staff/event/index.blade.php b/resources/views/Staff/event/index.blade.php new file mode 100644 index 0000000000..f34ae774d6 --- /dev/null +++ b/resources/views/Staff/event/index.blade.php @@ -0,0 +1,112 @@ +@extends('layout.default') + +@section('breadcrumbs') + + +@endsection + +@section('page', 'page__event--index') + +@section('main') +
    +
    +

    {{ __('event.events') }}

    + +
    +
    + + + + + + + + + + + + @foreach ($events as $event) + + + + + + + + @endforeach + +
    {{ __('common.name') }}Starts AtEnds At{{ __('common.active') }}{{ __('common.actions') }}
    + + {{ $event->name }} + + + + + + + @if ($event->active) + + @else + + @endif + + +
  • + + {{ __('common.edit') }} + +
  • +
  • +
    + @csrf + @method('DELETE') + +
    +
  • +
    +
    +
    +
    +@endsection diff --git a/resources/views/donation/index.blade.php b/resources/views/donation/index.blade.php index 93b717aad9..947e78b1a6 100644 --- a/resources/views/donation/index.blade.php +++ b/resources/views/donation/index.blade.php @@ -121,53 +121,66 @@ class="dialog__form" x-on:click.outside="$refs.dialog{{ $package->id }}.close()" > @csrf - To make a donation you must complete the following steps: -
    + + To make a donation you must complete the following steps: + +
    @foreach ($gateways->sortBy('position') as $gateway) -
    - {{ $gateway->name }} -
    - +

    + + +

    @endforeach - 2: Send - $ {{ $package->cost }} {{ config('donation.currency') }} - to gateway of your choice. -
    - 3: Take note of the tx hash, receipt number, etc and input it below. -
    +

    + Send + + $ {{ $package->cost }} {{ config('donation.currency') }} + + to gateway of your choice. Take note of the tx hash, receipt number, etc + and input it below. +

    - Info: -
    -
    - Amount: -
    +
    +

    -

    -
    - Transaction Proof: -
    + +

    +

    -

    + +

    - * Transactions may take up to 48 hours to process. + + * Transactions may take up to 48 hours to process. +

    diff --git a/resources/views/event/index.blade.php b/resources/views/event/index.blade.php new file mode 100644 index 0000000000..ac0bc7f768 --- /dev/null +++ b/resources/views/event/index.blade.php @@ -0,0 +1,65 @@ +@extends('layout.default') + +@section('breadcrumbs') +

    +@endsection + +@section('page', 'page__event--index') + +@section('main') +
    +

    {{ __('event.events') }}

    +
    + + + + + + + + + + + @foreach ($events as $event) + + + + + + + @endforeach + +
    {{ __('common.name') }}{{ __('event.starts-at') }}{{ __('event.ends-at') }}{{ __('common.active') }}
    + + {{ $event->name }} + + + + + + + @if ($event->active) + + @else + + @endif +
    +
    +
    +@endsection diff --git a/resources/views/event/show.blade.php b/resources/views/event/show.blade.php new file mode 100644 index 0000000000..ed9cce0335 --- /dev/null +++ b/resources/views/event/show.blade.php @@ -0,0 +1,106 @@ +@extends('layout.default') + +@section('breadcrumbs') + + +@endsection + +@section('page', 'page__event--index') + +@section('main') +
    +

    {{ $event->name }}

    +
    +
      + @foreach (\Carbon\CarbonPeriod::create($event->starts_at, $event->ends_at) as $i => $date) +
    1. +
      +

      + {{ $date->format('M j') }} +

      + + @if ($prize = $userPrizes->get($i)?->first()) + + @if ($prize->bon > 0 || $prize->fl_tokens > 0) +
        + @if ($prize->bon > 0) +
      • + + {{ $prize->bon }} {{ __('bon.bon') }} + +
      • + @endif + + @if ($prize->fl_tokens > 0) +
      • + + @if ($prize->fl_tokens === 1) + {{ $prize->fl_tokens }} + {{ __('torrent.freeleech-token') }} + @else + {{ $prize->fl_tokens }} + {{ __('common.fl_tokens') }} + @endif + +
      • + @endif +
      + @else + No winnings :( + @endif + @else + @if (now()->isBefore($date)) + + Check back later! + @elseif (now()->isAfter($date->addDay(1))) + + {{ __('common.expired') }} + @else + +
      + @csrf +

      + +

      +
      + @endif + @endif +
      +
    2. + @endforeach +
    +
    +
    +@endsection + +@section('sidebar') +
    +

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

    +
    + {{ $event->description }} +
    +
    +@endsection diff --git a/resources/views/livewire/quick-search-dropdown.blade.php b/resources/views/livewire/quick-search-dropdown.blade.php deleted file mode 100755 index a88a8c5b77..0000000000 --- a/resources/views/livewire/quick-search-dropdown.blade.php +++ /dev/null @@ -1,169 +0,0 @@ - diff --git a/resources/views/livewire/similar-torrent.blade.php b/resources/views/livewire/similar-torrent.blade.php index b3ad1ca745..fb1bfec7dc 100644 --- a/resources/views/livewire/similar-torrent.blade.php +++ b/resources/views/livewire/similar-torrent.blade.php @@ -977,7 +977,16 @@ class="form__checkbox"
    {{ __('request.add-request') }} diff --git a/resources/views/livewire/torrent-search.blade.php b/resources/views/livewire/torrent-search.blade.php index 758e389652..c1a62b7ce4 100644 --- a/resources/views/livewire/torrent-search.blade.php +++ b/resources/views/livewire/torrent-search.blade.php @@ -84,26 +84,38 @@ class="form__text"
    -

    +

    -

    +

    + + + +
    + +
    diff --git a/resources/views/partials/top_nav.blade.php b/resources/views/partials/top_nav.blade.php index efef6ed08f..fe57a53ce2 100755 --- a/resources/views/partials/top_nav.blade.php +++ b/resources/views/partials/top_nav.blade.php @@ -4,7 +4,7 @@
    - + @include('partials.quick-search-dropdown')
  • + @php + $events = \App\Models\Event::query() + ->where('active', '=', true) + ->withExists([ + 'claimedPrizes' => fn ($query) => $query + ->where('created_at', '>', now()->startOfDay()) + ->where('user_id', '=', auth()->id()), + ]) + ->get() + @endphp +
    {{ __('common.other') }} + @if ($events->contains(fn ($event) => ! $event->claimed_prizes_exists && $event->ends_at->isFuture())) + + @endif