diff --git a/app/Http/Controllers/API/TorrentController.php b/app/Http/Controllers/API/TorrentController.php
index 96970a755..7bdf7b675 100644
--- a/app/Http/Controllers/API/TorrentController.php
+++ b/app/Http/Controllers/API/TorrentController.php
@@ -335,116 +335,37 @@ class TorrentController extends BaseController
{
$torrents = Torrent::with(['user:id,username,group_id', 'category', 'type', 'resolution'])
->withCount(['thanks', 'comments'])
- ->when($request->has('name'), function ($query) use ($request) {
- $terms = \explode(' ', (string) $request->input('name'));
- $search = '';
- foreach ($terms as $term) {
- $search .= '%'.$term.'%';
- }
-
- $query->where('name', 'LIKE', $search);
- })
- ->when($request->has('description'), function ($query) use ($request) {
- $query->where('description', 'LIKE', '%'.$request->input('description').'%');
- })
- ->when($request->has('mediainfo'), function ($query) use ($request) {
- $query->where('mediainfo', 'LIKE', '%'.$request->input('mediainfo').'%');
- })
- ->when($request->has('file_name'), function ($query) use ($request) {
- $query->whereHas('files', function ($q) use ($request) {
- $q->where('name', $request->input('file_name'));
- });
- })
- ->when($request->has('uploader'), function ($query) use ($request) {
- $match = User::where('username', 'LIKE', '%'.$request->input('uploader').'%')->oldest('username')->first();
- if ($match) {
- $query->where('user_id', '=', $match->id)->where('anon', '=', 0);
- }
- })
- ->when($request->has('keywords'), function ($query) use ($request) {
- $keywords = self::parseKeywords($request->input('keywords'));
- $keyword = Keyword::select(['torrent_id'])->whereIn('name', $keywords)->get();
- $query->whereIntegerInRaw('id', $keyword->torrent_id);
- })
- ->when($request->has('startYear') && $request->has('endYear'), function ($query) use ($request) {
- $query->whereBetween('release_year', [$request->input('startYear'), $request->input('endYear')]);
- })
- ->when($request->has('categories'), function ($query) use ($request) {
- $query->whereIntegerInRaw('category_id', $request->input('categories'));
- })
- ->when($request->has('types'), function ($query) use ($request) {
- $query->whereIntegerInRaw('type_id', $request->input('types'));
- })
- ->when($request->has('resolutions'), function ($query) use ($request) {
- $query->whereIntegerInRaw('resolution_id', $request->input('resolutions'));
- })
- ->when($request->has('genres'), function ($query) use ($request) {
- $tvCollection = DB::table('genre_tv')->whereIntegerInRaw('genre_id', $request->input('genres'))->pluck('tv_id');
- $movieCollection = DB::table('genre_movie')->whereIntegerInRaw('genre_id', $request->input('genres'))->pluck('movie_id');
- $mergedCollection = $tvCollection->merge($movieCollection);
-
- $query->whereIn('tmdb', $mergedCollection);
- })
- ->when($request->has('tmdbId'), function ($query) use ($request) {
- $query->where('tmdb', '=', $request->input('tmdbId'));
- })
- ->when($request->has('imdbId'), function ($query) use ($request) {
- $query->where('imdb', '=', $request->input('imdbId'));
- })
- ->when($request->has('tvdbId'), function ($query) use ($request) {
- $query->where('tvdb', '=', $request->input('tvdbId'));
- })
- ->when($request->has('malId'), function ($query) use ($request) {
- $query->where('mal', '=', $request->input('malId'));
- })
- ->when($request->has('seasonNumber'), function ($query) use ($request) {
- $query->where('season_number', '=', $request->input('seasonNumber'));
- })
- ->when($request->has('episodeNumber'), function ($query) use ($request) {
- $query->where('episode_number', '=', $request->input('episodeNumber'));
- })
- ->when($request->has('playlistId'), function ($query) use ($request) {
- $playlist = PlaylistTorrent::where('playlist_id', '=', $request->input('playlistId'))->pluck('torrent_id');
- $query->whereIntegerInRaw('id', $playlist);
- })
- ->when($request->has('collectionId'), function ($query) use ($request) {
- $categories = Category::where('movie_meta', '=', 1)->pluck('id');
- $collection = DB::table('collection_movie')->where('collection_id', '=', $request->input('collectionId'))->pluck('movie_id');
- $query->whereIntegerInRaw('category_id', $categories)->whereIn('tmdb', $collection);
- })
- ->when($request->has('free'), function ($query) {
- $query->where('free', '>=', 1);
- })
- ->when($request->has('doubleup'), function ($query) {
- $query->where('doubleup', '=', 1);
- })
- ->when($request->has('featured'), function ($query) {
- $query->where('featured', '=', 1);
- })
- ->when($request->has('stream'), function ($query) {
- $query->where('stream', '=', 1);
- })
- ->when($request->has('sd'), function ($query) {
- $query->where('sd', '=', 1);
- })
- ->when($request->has('highspeed'), function ($query) {
- $query->where('highspeed', '=', 1);
- })
- ->when($request->has('internal'), function ($query) {
- $query->where('internal', '=', 1);
- })
- ->when($request->has('personalRelease'), function ($query) {
- $query->where('personal_release', '=', 1);
- })
- ->when($request->has('alive'), function ($query) {
- $query->orWhere('seeders', '>=', 1);
- })
- ->when($request->has('dying'), function ($query) {
- $query->orWhere('seeders', '=', 1)->where('times_completed', '>=', 3);
- })
- ->when($request->has('dead'), function ($query) {
- $query->orWhere('seeders', '=', 0);
- })
+ ->when($request->has('name') , fn ($query) => $query->ofName($request->name))
+ ->when($request->has('description') , fn ($query) => $query->ofDescription($request->description))
+ ->when($request->has('mediainfo') , fn ($query) => $query->ofMediainfo($request->mediainfo))
+ ->when($request->has('uploader') , fn ($query) => $query->ofUploader($request->uploader))
+ ->when($request->has('keywords') , fn ($query) => $query->ofKeyword(\array_map('trim', explode(',', $request->keywords))))
+ ->when($request->has('startYear') , fn ($query) => $query->releasedAfterOrIn($request->startYear))
+ ->when($request->has('endYear') , fn ($query) => $query->releasedBeforeOrIn($request->endYear))
+ ->when($request->has('categories') , fn ($query) => $query->ofCategory($request->categories))
+ ->when($request->has('types') , fn ($query) => $query->ofType($request->types))
+ ->when($request->has('resolutions') , fn ($query) => $query->ofResolution($request->resolutions))
+ ->when($request->has('genres') , fn ($query) => $query->ofGenre($request->genres))
+ ->when($request->has('tmdbId') , fn ($query) => $query->ofTmdb($request->tmdbId))
+ ->when($request->has('imdbId') , fn ($query) => $query->ofImdb($request->imdbId))
+ ->when($request->has('tvdbId') , fn ($query) => $query->ofTvdb($request->tvdbId))
+ ->when($request->has('malId') , fn ($query) => $query->ofMal($request->malId))
+ ->when($request->has('playlistId') , fn ($query) => $query->ofPlaylist($request->playlistId))
+ ->when($request->has('collectionId') , fn ($query) => $query->ofCollection($request->collectionId))
+ ->when($request->has('free') , fn ($query) => $query->ofFreeleech([25, 50, 75, 100]))
+ ->when($request->has('doubleup') , fn ($query) => $query->doubleup())
+ ->when($request->has('featured') , fn ($query) => $query->featured())
+ ->when($request->has('stream') , fn ($query) => $query->streamOptimized())
+ ->when($request->has('sd') , fn ($query) => $query->sd())
+ ->when($request->has('highspeed') , fn ($query) => $query->highspeed())
+ ->when($request->has('internal') , fn ($query) => $query->internal())
+ ->when($request->has('personalRelease') , fn ($query) => $query->personalRelease())
+ ->when($request->has('alive') , fn ($query) => $query->alive())
+ ->when($request->has('dying') , fn ($query) => $query->dying())
+ ->when($request->has('dead') , fn ($query) => $query->dead())
+ ->when($request->has('file_name') , fn ($query) => $query->ofFilename($request->file_name))
+ ->when($request->has('seasonNumber') , fn ($query) => $query->ofSeason($request->seasonNumber))
+ ->when($request->has('episodeNumber') , fn ($query) => $query->ofEpisode($request->episodeNumber))
->latest('sticky')
->orderBy($request->input('sortField') ?? $this->sortField, $request->input('sortDirection') ?? $this->sortDirection)
->paginate($request->input('perPage') ?? $this->perPage);
diff --git a/app/Http/Controllers/RssController.php b/app/Http/Controllers/RssController.php
index b30c5eb65..5fbaa6856 100644
--- a/app/Http/Controllers/RssController.php
+++ b/app/Http/Controllers/RssController.php
@@ -148,171 +148,51 @@ class RssController extends Controller
$bannedGroup = \cache()->rememberForever('banned_group', fn () => Group::where('slug', '=', 'banned')->pluck('id'));
$disabledGroup = \cache()->rememberForever('disabled_group', fn () => Group::where('slug', '=', 'disabled')->pluck('id'));
- if ($user->group->id == $bannedGroup[0]) {
- \abort(404);
- }
+ abort_if($user->group->id == $bannedGroup[0] || $user->group->id == $disabledGroup[0] || ! $user->active, 404);
- if ($user->group->id == $disabledGroup[0]) {
- \abort(404);
- }
+ $rss = Rss::query()
+ ->where('id', '=', $id)
+ ->where(fn ($query) => $query
+ ->where('user_id', '=', $user->id)
+ ->orWhere('is_private', '=', 0)
+ )
+ ->firstOrFail();
- if ($user->active == 0) {
- \abort(404);
- }
+ $search = $rss->object_torrent;
- $rss = Rss::where('id', '=', $id)->whereRaw('(user_id = ? OR is_private != ?)', [$user->id, 1])->firstOrFail();
+ $torrents = Torrent::with('user', 'category', 'type', 'resolution')
+ ->when($search->search !== null, fn ($query) => $query->ofName($search->search))
+ ->when($search->description !== null, fn ($query) => $query->ofDescription($search->description)->orWhere->ofMediainfo($rss->mediainfo))
+ ->when($search->uploader !== null, fn ($query) => $query->ofUploader($search->uploader))
+ ->when($search->categories !== null, fn ($query) => $query->ofCategory($search->categories))
+ ->when($search->types !== null, fn ($query) => $query->ofType($search->types))
+ ->when($search->resolutions !== null, fn ($query) => $query->ofResolution($search->resolutions))
+ ->when($search->genres !== null, fn ($query) => $query->ofGenre($search->genres))
+ ->when($search->tmdb !== null, fn ($query) => $query->ofTmdb($search->tmdb))
+ ->when($search->imdb !== null, fn ($query) => $query->ofImdb(\preg_match('/tt0*(?=(\d{7,}))/', $search->imdb, $matches) ? $matches[1] : $search->imdb))
+ ->when($search->tvdb !== null, fn ($query) => $query->ofTvdb($rss->tvdb))
+ ->when($search->mal !== null, fn ($query) => $query->ofMal($rss->mal))
+ ->when($search->freeleech !== null, fn ($query) => $query->ofFreeleech([25, 50, 75, 100]))
+ ->when($search->doubleupload !== null, fn ($query) => $query->doubleup())
+ ->when($search->featured !== null, fn ($query) => $query->featured())
+ ->when($search->stream !== null, fn ($query) => $query->streamOptimized())
+ ->when($search->sd !== null, fn ($query) => $query->sd())
+ ->when($search->highspeed !== null, fn ($query) => $query->highspeed())
+ ->when($search->bookmark !== null, fn ($query) => $query->bookmarkedBy($user))
+ ->when($search->internal !== null, fn ($query) => $query->internal())
+ ->when($search->alive !== null, fn ($query) => $query->alive())
+ ->when($search->dying !== null, fn ($query) => $query->dying())
+ ->when($search->dead !== null, fn ($query) => $query->dead())
+ ->latest()
+ ->take(50)
+ ->get();
- $search = $rss->object_torrent->search;
- $description = $rss->object_torrent->description;
- $uploader = $rss->object_torrent->uploader;
- $imdb = $rss->object_torrent->imdb;
- $tvdb = $rss->object_torrent->tvdb;
- $tmdb = $rss->object_torrent->tmdb;
- $mal = $rss->object_torrent->mal;
- $categories = $rss->object_torrent->categories;
- $types = $rss->object_torrent->types;
- $resolutions = $rss->object_torrent->resolutions;
- $genres = $rss->object_torrent->genres;
- $freeleech = $rss->object_torrent->freeleech;
- $doubleupload = $rss->object_torrent->doubleupload;
- $featured = $rss->object_torrent->featured;
- $stream = $rss->object_torrent->stream;
- $highspeed = $rss->object_torrent->highspeed;
- $sd = $rss->object_torrent->sd;
- $internal = $rss->object_torrent->internal;
- $bookmark = $rss->object_torrent->bookmark;
- $alive = $rss->object_torrent->alive;
- $dying = $rss->object_torrent->dying;
- $dead = $rss->object_torrent->dead;
-
- $terms = \explode(' ', (string) $search);
- $search = '';
- foreach ($terms as $term) {
- $search .= '%'.$term.'%';
- }
-
- $usernames = \explode(' ', (string) $uploader);
- $uploader = '';
- foreach ($usernames as $username) {
- $uploader .= '%'.$username.'%';
- }
-
- $keywords = \explode(' ', (string) $description);
- $description = '';
- foreach ($keywords as $keyword) {
- $description .= '%'.$keyword.'%';
- }
-
- $builder = Torrent::with(['user', 'category', 'type', 'resolution']);
-
- if ($rss->object_torrent->search) {
- $builder->where(function ($query) use ($search) {
- $query->where('name', 'like', $search);
- });
- }
-
- if ($rss->object_torrent->description) {
- $builder->where(function ($query) use ($description) {
- $query->where('description', 'like', $description)->orWhere('mediainfo', 'like', $description);
- });
- }
-
- if ($rss->object_torrent->uploader && $rss->object_torrent->uploader != null) {
- $match = User::where('username', 'like', $uploader)->first();
- if (null === $match) {
- return ['result' => [], 'count' => 0];
- }
-
- $builder->where('user_id', '=', $match->id)->where('anon', '=', 0);
- }
-
- if ($rss->object_torrent->imdb && $rss->object_torrent->imdb != null) {
- if (\preg_match('/tt0*?(?=(\d{7,8}))/', (string) $imdb, $matches)) {
- $builder->where('imdb', '=', $matches[1]);
- } else {
- $builder->where('imdb', '=', $imdb);
- }
- }
-
- if ($rss->object_torrent->tvdb && $rss->object_torrent->tvdb != null) {
- $builder->where('tvdb', '=', $tvdb);
- }
-
- if ($rss->object_torrent->tmdb && $rss->object_torrent->tmdb != null) {
- $builder->where('tmdb', '=', $tmdb);
- }
-
- if ($rss->object_torrent->mal && $rss->object_torrent->mal != null) {
- $builder->where('mal', '=', $mal);
- }
-
- if ($rss->object_torrent->categories && \is_array($rss->object_torrent->categories)) {
- $builder->whereIntegerInRaw('category_id', $categories);
- }
-
- if ($rss->object_torrent->types && \is_array($rss->object_torrent->types)) {
- $builder->whereIntegerInRaw('type_id', $types);
- }
-
- if ($rss->object_torrent->resolutions && \is_array($rss->object_torrent->resolutions)) {
- $builder->whereIntegerInRaw('resolution_id', $resolutions);
- }
-
- if ($rss->object_torrent->genres && \is_array($rss->object_torrent->genres)) {
- $tvCollection = DB::table('genre_tv')->whereIntegerInRaw('genre_id', $genres)->pluck('tv_id');
- $movieCollection = DB::table('genre_movie')->whereIntegerInRaw('genre_id', $genres)->pluck('movie_id');
- $mergedCollection = $tvCollection->merge($movieCollection);
-
- $builder->whereRaw("tmdb in ('".\implode("','", $mergedCollection->toArray())."')"); // Protected with Validation that IDs passed are not malicious
- }
-
- if ($rss->object_torrent->freeleech && $rss->object_torrent->freeleech != null) {
- $builder->where('free', '>=', $freeleech);
- }
-
- if ($rss->object_torrent->doubleupload && $rss->object_torrent->doubleupload != null) {
- $builder->where('doubleup', '=', $doubleupload);
- }
-
- if ($rss->object_torrent->featured && $rss->object_torrent->featured != null) {
- $builder->where('featured', '=', $featured);
- }
-
- if ($rss->object_torrent->stream && $rss->object_torrent->stream != null) {
- $builder->where('stream', '=', $stream);
- }
-
- if ($rss->object_torrent->highspeed && $rss->object_torrent->highspeed != null) {
- $builder->where('highspeed', '=', $highspeed);
- }
-
- if ($rss->object_torrent->sd && $rss->object_torrent->sd != null) {
- $builder->where('sd', '=', $sd);
- }
-
- if ($rss->object_torrent->internal && $rss->object_torrent->internal != null) {
- $builder->where('internal', '=', $internal);
- }
-
- if ($rss->object_torrent->bookmark && $rss->object_torrent->bookmark != null) {
- $builder->whereIntegerInRaw('id', $user->bookmarks->pluck('id'));
- }
-
- if ($rss->object_torrent->alive && $rss->object_torrent->alive != null) {
- $builder->where('seeders', '>=', $alive);
- }
-
- if ($rss->object_torrent->dying && $rss->object_torrent->dying != null) {
- $builder->where('seeders', '=', $dying)->where('times_completed', '>=', 3);
- }
-
- if ($rss->object_torrent->dead && $rss->object_torrent->dead != null) {
- $builder->where('seeders', '=', $dead);
- }
-
- $torrents = $builder->latest()->take(50)->get();
-
- return \response()->view('rss.show', ['torrents' => $torrents, 'user' => $user, 'rss' => $rss])->header('Content-Type', 'text/xml');
+ return \response()->view('rss.show', [
+ 'torrents' => $torrents,
+ 'user' => $user,
+ 'rss' => $rss
+ ])
+ ->header('Content-Type', 'text/xml');
}
/**
diff --git a/app/Http/Livewire/GraveyardSearch.php b/app/Http/Livewire/GraveyardSearch.php
index 160d4eb9b..cf3acc29e 100644
--- a/app/Http/Livewire/GraveyardSearch.php
+++ b/app/Http/Livewire/GraveyardSearch.php
@@ -38,19 +38,19 @@ class GraveyardSearch extends Component
public string $malId = '';
- public $free;
+ public array $free = [];
- public $doubleup;
+ public bool $doubleup = false;
- public $featured;
+ public bool $featured = false;
- public $stream;
+ public bool $stream = false;
- public $sd;
+ public bool $sd = false;
- public $highspeed;
+ public bool $highspeed = false;
- public $internal;
+ public bool $internal = false;
public int $perPage = 25;
@@ -69,7 +69,7 @@ class GraveyardSearch extends Component
'imdbId' => ['except' => ''],
'tvdbId' => ['except' => ''],
'malId' => ['except' => ''],
- 'free' => ['except' => false],
+ 'free' => ['except' => []],
'doubleup' => ['except' => false],
'featured' => ['except' => false],
'stream' => ['except' => false],
@@ -105,54 +105,33 @@ class GraveyardSearch extends Component
final public function getTorrentsProperty(): \Illuminate\Contracts\Pagination\LengthAwarePaginator
{
+ $user = \auth()->user();
+ $isRegexAllowed = $user->group->is_modo;
+ $isRegex = fn ($field) => $isRegexAllowed
+ && \strlen($field) >= 2
+ && $field[0] === '/'
+ && $field[-1] === '/';
+
return Torrent::with('category', 'type', 'resolution')
->where('created_at', '<', Carbon::now()->copy()->subDays(30)->toDateTimeString())
- ->where('seeders', '=', 0)
- ->when($this->name, function ($query) {
- $query->where('name', 'LIKE', '%'.$this->name.'%');
- })
- ->when($this->categories, function ($query) {
- $query->whereIntegerInRaw('category_id', $this->categories);
- })
- ->when($this->types, function ($query) {
- $query->whereIntegerInRaw('type_id', $this->types);
- })
- ->when($this->resolutions, function ($query) {
- $query->whereIntegerInRaw('resolution_id', $this->resolutions);
- })
- ->when($this->tmdbId, function ($query) {
- $query->where('tmdb', '=', $this->tmdbId);
- })
- ->when($this->imdbId, function ($query) {
- $query->where('imdb', '=', $this->imdbId);
- })
- ->when($this->tvdbId, function ($query) {
- $query->where('tvdb', '=', $this->tvdbId);
- })
- ->when($this->malId, function ($query) {
- $query->where('mal', '=', $this->malId);
- })
- ->when($this->free, function ($query) {
- $query->where('free', '=', 1);
- })
- ->when($this->doubleup, function ($query) {
- $query->where('doubleup', '=', 1);
- })
- ->when($this->featured, function ($query) {
- $query->where('featured', '=', 1);
- })
- ->when($this->stream, function ($query) {
- $query->where('stream', '=', 1);
- })
- ->when($this->sd, function ($query) {
- $query->where('sd', '=', 1);
- })
- ->when($this->highspeed, function ($query) {
- $query->where('highspeed', '=', 1);
- })
- ->when($this->internal, function ($query) {
- $query->where('internal', '=', 1);
- })
+ ->dead()
+ ->when($this->name !== '' , fn ($query) => $query->ofName($this->name, $isRegex($this->name)))
+ ->when($this->categories !== [] , fn ($query) => $query->ofCategory($this->categories))
+ ->when($this->types !== [] , fn ($query) => $query->ofType($this->types))
+ ->when($this->resolutions !== [] , fn ($query) => $query->ofResolution($this->resolutions))
+ ->when($this->tmdbId !== '' , fn ($query) => $query->ofTmdb($this->tmdbId))
+ ->when($this->imdbId !== '' , fn ($query) => $query->ofImdb(\preg_match('/tt0*(?=(\d{7,}))/', $this->imdbId, $matches) ? $matches[1] : $this->imdbId))
+ ->when($this->tvdbId !== '' , fn ($query) => $query->ofTvdb($this->tvdbId))
+ ->when($this->malId !== '' , fn ($query) => $query->ofMal($this->malId))
+ ->when($this->free !== [] , fn ($query) => $query->ofFreeleech($this->free))
+ ->when($this->doubleup !== false, fn ($query) => $query->doubleup())
+ ->when($this->featured !== false, fn ($query) => $query->featured())
+ ->when($this->stream !== false, fn ($query) => $query->streamOptimized())
+ ->when($this->sd !== false, fn ($query) => $query->sd())
+ ->when($this->highspeed !== false, fn ($query) => $query->highspeed())
+ ->when($this->bookmarked !== false, fn ($query) => $query->bookmarkedBy($user))
+ ->when($this->wished !== false, fn ($query) => $query->wishedBy($user))
+ ->when($this->internal !== false, fn ($query) => $query->internal())
->orderBy($this->sortField, $this->sortDirection)
->paginate($this->perPage);
}
diff --git a/app/Http/Livewire/TorrentCardSearch.php b/app/Http/Livewire/TorrentCardSearch.php
index 50e60b605..7dba26a5f 100644
--- a/app/Http/Livewire/TorrentCardSearch.php
+++ b/app/Http/Livewire/TorrentCardSearch.php
@@ -68,49 +68,41 @@ class TorrentCardSearch extends Component
public string $collectionId = '';
- public $free0;
+ public array $free = [];
- public $free25;
+ public bool $doubleup = false;
- public $free50;
+ public bool $featured = false;
- public $free75;
+ public bool $stream = false;
- public $free100;
+ public bool $sd = false;
- public $doubleup;
+ public bool $highspeed = false;
- public $featured;
+ public bool $bookmarked = false;
- public $stream;
+ public bool $wished = false;
- public $sd;
+ public bool $internal = false;
- public $highspeed;
+ public bool $personalRelease = false;
- public $bookmarked;
+ public bool $alive = false;
- public $wished;
+ public bool $dying = false;
- public $internal;
+ public bool $dead = false;
- public $personalRelease;
+ public bool $notDownloaded = false;
- public $alive;
+ public bool $downloaded = false;
- public $dying;
+ public bool $seeding = false;
- public $dead;
+ public bool $leeching = false;
- public $notDownloaded;
-
- public $downloaded;
-
- public $seeding;
-
- public $leeching;
-
- public $incomplete;
+ public bool $incomplete = false;
public int $perPage = 24;
@@ -138,11 +130,7 @@ class TorrentCardSearch extends Component
'malId' => ['except' => ''],
'playlistId' => ['except' => ''],
'collectionId' => ['except' => ''],
- 'free0' => ['except' => false],
- 'free25' => ['except' => false],
- 'free50' => ['except' => false],
- 'free75' => ['except' => false],
- 'free100' => ['except' => false],
+ 'free' => ['except' => []],
'doubleup' => ['except' => false],
'featured' => ['except' => false],
'stream' => ['except' => false],
@@ -200,181 +188,52 @@ class TorrentCardSearch extends Component
final public function getTorrentsProperty(): \Illuminate\Contracts\Pagination\LengthAwarePaginator
{
+ $user = \auth()->user();
+ $isRegexAllowed = $user->group->is_modo;
+ $isRegex = fn ($field) => $isRegexAllowed
+ && \strlen($field) >= 2
+ && $field[0] === '/'
+ && $field[-1] === '/';
+
return Torrent::with(['user:id,username,group_id', 'user.group', 'category', 'type', 'resolution'])
->withCount(['thanks', 'comments'])
- ->when($this->name, function ($query) {
- $terms = \explode(' ', $this->name);
- $search = '';
- foreach ($terms as $term) {
- $search .= '%'.$term.'%';
- }
-
- $query->where('name', 'LIKE', $search);
- })
- ->when($this->description, function ($query) {
- $query->where('description', 'LIKE', '%'.$this->description.'%');
- })
- ->when($this->mediainfo, function ($query) {
- $query->where('mediainfo', 'LIKE', '%'.$this->mediainfo.'%');
- })
- ->when($this->uploader, function ($query) {
- $match = User::where('username', '=', $this->uploader)->first();
- if ($match) {
- $query->where('user_id', '=', $match->id)->where('anon', '=', 0);
- }
- })
- ->when($this->keywords, function ($query) {
- $keywords = self::parseKeywords($this->keywords);
- $keyword = Keyword::whereIn('name', $keywords)->pluck('torrent_id');
- $query->whereIntegerInRaw('id', $keyword);
- })
- ->when($this->startYear && $this->endYear, function ($query) {
- $query->whereBetween('release_year', [$this->startYear, $this->endYear]);
- })
- ->when($this->categories, function ($query) {
- $query->whereIntegerInRaw('category_id', $this->categories);
- })
- ->when($this->types, function ($query) {
- $query->whereIntegerInRaw('type_id', $this->types);
- })
- ->when($this->resolutions, function ($query) {
- $query->whereIntegerInRaw('resolution_id', $this->resolutions);
- })
- ->when($this->genres, function ($query) {
- $this->validate();
-
- $tvCollection = DB::table('genre_tv')->whereIntegerInRaw('genre_id', $this->genres)->pluck('tv_id');
- $movieCollection = DB::table('genre_movie')->whereIntegerInRaw('genre_id', $this->genres)->pluck('movie_id');
- $mergedCollection = $tvCollection->merge($movieCollection);
-
- $query->whereRaw("tmdb in ('".\implode("','", $mergedCollection->toArray())."')"); // Protected with Validation that IDs passed are not malicious
- })
- ->when($this->regions, function ($query) {
- $query->whereIntegerInRaw('region_id', $this->regions);
- })
- ->when($this->distributors, function ($query) {
- $query->whereIntegerInRaw('distributor_id', $this->distributors);
- })
- ->when($this->tmdbId === '0' || $this->tmdbId, function ($query) {
- $query->where('tmdb', '=', $this->tmdbId);
- })
- ->when($this->imdbId === '0' || $this->imdbId, function ($query) {
- if (\preg_match('/tt0*?(?=(\d{7,8}))/', $this->imdbId, $matches)) {
- $query->where('imdb', '=', $matches[1]);
- } else {
- $query->where('imdb', '=', $this->imdbId);
- }
- })
- ->when($this->tvdbId === '0' || $this->tvdbId, function ($query) {
- $query->where('tvdb', '=', $this->tvdbId);
- })
- ->when($this->malId === '0' || $this->malId, function ($query) {
- $query->where('mal', '=', $this->malId);
- })
- ->when($this->playlistId, function ($query) {
- $playlist = PlaylistTorrent::where('playlist_id', '=', $this->playlistId)->pluck('torrent_id');
- $query->whereIntegerInRaw('id', $playlist);
- })
- ->when($this->collectionId, function ($query) {
- $categories = Category::where('movie_meta', '=', 1)->pluck('id');
- $collection = DB::table('collection_movie')->where('collection_id', '=', $this->collectionId)->pluck('movie_id');
- $query->whereIntegerInRaw('category_id', $categories)->whereIntegerInRaw('tmdb', $collection);
- })
- ->when($this->free0 === '0' || $this->free0 || $this->free25 || $this->free50 || $this->free75 || $this->free100, function ($query) {
- $query->where(function ($query) {
- $query->where(function ($query) {
- if ($this->free0 === '0' || $this->free0) {
- $query->where('free', '=', 0);
- }
- })
- ->orWhere(function ($query) {
- if ($this->free25) {
- $query->where('free', '=', 25);
- }
- })
- ->orWhere(function ($query) {
- if ($this->free50) {
- $query->where('free', '=', 50);
- }
- })
- ->orWhere(function ($query) {
- if ($this->free75) {
- $query->where('free', '=', 75);
- }
- })
- ->orWhere(function ($query) {
- if ($this->free100) {
- $query->where('free', '=', 100);
- }
- });
- });
- })
- ->when($this->doubleup, function ($query) {
- $query->where('doubleup', '=', 1);
- })
- ->when($this->featured, function ($query) {
- $query->where('featured', '=', 1);
- })
- ->when($this->stream, function ($query) {
- $query->where('stream', '=', 1);
- })
- ->when($this->sd, function ($query) {
- $query->where('sd', '=', 1);
- })
- ->when($this->highspeed, function ($query) {
- $query->where('highspeed', '=', 1);
- })
- ->when($this->bookmarked, function ($query) {
- $bookmarks = Bookmark::where('user_id', '=', \auth()->user()->id)->pluck('torrent_id');
- $query->whereIntegerInRaw('id', $bookmarks);
- })
- ->when($this->wished, function ($query) {
- $wishes = Wish::where('user_id', '=', \auth()->user()->id)->pluck('tmdb');
- $query->whereIn('tmdb', $wishes);
- })
- ->when($this->internal, function ($query) {
- $query->where('internal', '=', 1);
- })
- ->when($this->personalRelease, function ($query) {
- $query->where('personal_release', '=', 1);
- })
- ->when($this->alive, function ($query) {
- $query->where('seeders', '>=', 1);
- })
- ->when($this->dying, function ($query) {
- $query->where('seeders', '=', 1)->where('times_completed', '>=', 3);
- })
- ->when($this->dead, function ($query) {
- $query->where('seeders', '=', 0);
- })
- ->when($this->notDownloaded, function ($query) {
- $history = History::where('user_id', '=', \auth()->user()->id)->pluck('torrent_id')->toArray();
- if (! $history || ! \is_array($history)) {
- $history = [];
- }
-
- $query->whereIntergerNotIn('id', $history);
- })
- ->when($this->downloaded, function ($query) {
- $query->whereHas('history', function ($query) {
- $query->where('user_id', '=', \auth()->user()->id);
- });
- })
- ->when($this->seeding, function ($query) {
- $query->whereHas('history', function ($q) {
- $q->where('user_id', '=', \auth()->user()->id)->where('active', '=', true)->where('seeder', '=', true);
- });
- })
- ->when($this->leeching, function ($query) {
- $query->whereHas('history', function ($q) {
- $q->where('user_id', '=', \auth()->user()->id)->where('active', '=', true)->where('seedtime', '=', '0');
- });
- })
- ->when($this->incomplete, function ($query) {
- $query->whereHas('history', function ($q) {
- $q->where('user_id', '=', \auth()->user()->id)->where('active', '=', false)->where('seeder', '=', false)->where('seedtime', '=', '0');
- });
- })
+ ->when($this->name !== '' , fn ($query) => $query->ofName($this->name, $isRegex($this->name)))
+ ->when($this->description !== '' , fn ($query) => $query->ofDescription($this->description, $isRegex($this->name)))
+ ->when($this->mediainfo !== '' , fn ($query) => $query->ofMediainfo($this->mediainfo, $isRegex($this->name)))
+ ->when($this->uploader !== '' , fn ($query) => $query->ofUploader($this->uploader))
+ ->when($this->keywords !== '' , fn ($query) => $query->ofKeyword(\array_map('trim', explode(',', $this->keywords))))
+ ->when($this->startYear !== '' , fn ($query) => $query->releasedAfterOrIn($this->startYear))
+ ->when($this->endYear !== '' , fn ($query) => $query->releasedBeforeOrIn($this->endYear))
+ ->when($this->categories !== [] , fn ($query) => $query->ofCategory($this->categories))
+ ->when($this->types !== [] , fn ($query) => $query->ofType($this->types))
+ ->when($this->resolutions !== [] , fn ($query) => $query->ofResolution($this->resolutions))
+ ->when($this->genres !== [] , fn ($query) => $query->ofGenre($this->genres))
+ ->when($this->regions !== [] , fn ($query) => $query->ofRegion($this->regions))
+ ->when($this->distributors !== [] , fn ($query) => $query->ofDistributor($this->distributors))
+ ->when($this->tmdbId !== '' , fn ($query) => $query->ofTmdb($this->tmdbId))
+ ->when($this->imdbId !== '' , fn ($query) => $query->ofImdb(\preg_match('/tt0*(?=(\d{7,}))/', $this->imdbId, $matches) ? $matches[1] : $this->imdbId))
+ ->when($this->tvdbId !== '' , fn ($query) => $query->ofTvdb($this->tvdbId))
+ ->when($this->malId !== '' , fn ($query) => $query->ofMal($this->malId))
+ ->when($this->playlistId !== '' , fn ($query) => $query->ofPlaylist($this->playlistId))
+ ->when($this->collectionId !== '' , fn ($query) => $query->ofCollection($this->collectionId))
+ ->when($this->free !== [] , fn ($query) => $query->ofFreeleech($this->free))
+ ->when($this->doubleup !== false, fn ($query) => $query->doubleup())
+ ->when($this->featured !== false, fn ($query) => $query->featured())
+ ->when($this->stream !== false, fn ($query) => $query->streamOptimized())
+ ->when($this->sd !== false, fn ($query) => $query->sd())
+ ->when($this->highspeed !== false, fn ($query) => $query->highspeed())
+ ->when($this->bookmarked !== false, fn ($query) => $query->bookmarkedBy($user))
+ ->when($this->wished !== false, fn ($query) => $query->wishedBy($user))
+ ->when($this->internal !== false, fn ($query) => $query->internal())
+ ->when($this->personalRelease !== false, fn ($query) => $query->personalRelease())
+ ->when($this->alive !== false, fn ($query) => $query->alive())
+ ->when($this->dying !== false, fn ($query) => $query->dying())
+ ->when($this->dead !== false, fn ($query) => $query->dead())
+ ->when($this->notDownloaded !== false, fn ($query) => $query->notDownloadedBy($user))
+ ->when($this->downloaded !== false, fn ($query) => $query->downloadedBy($user))
+ ->when($this->seeding !== false, fn ($query) => $query->seededBy($user))
+ ->when($this->leeching !== false, fn ($query) => $query->leechedBy($user))
+ ->when($this->incomplete !== false, fn ($query) => $query->uncompletedBy($user))
->latest('sticky')
->orderBy($this->sortField, $this->sortDirection)
->paginate($this->perPage);
diff --git a/app/Http/Livewire/TorrentListSearch.php b/app/Http/Livewire/TorrentListSearch.php
index 41effd86f..bead0ac00 100644
--- a/app/Http/Livewire/TorrentListSearch.php
+++ b/app/Http/Livewire/TorrentListSearch.php
@@ -13,15 +13,9 @@
namespace App\Http\Livewire;
-use App\Models\Bookmark;
-use App\Models\Category;
-use App\Models\History;
-use App\Models\Keyword;
use App\Models\PersonalFreeleech;
-use App\Models\PlaylistTorrent;
use App\Models\Torrent;
use App\Models\User;
-use App\Models\Wish;
use Illuminate\Support\Facades\DB;
use Livewire\Component;
use Livewire\WithPagination;
@@ -68,49 +62,41 @@ class TorrentListSearch extends Component
public string $collectionId = '';
- public $free0;
+ public array $free = [];
- public $free25;
+ public bool $doubleup = false;
- public $free50;
+ public bool $featured = false;
- public $free75;
+ public bool $stream = false;
- public $free100;
+ public bool $sd = false;
- public $doubleup;
+ public bool $highspeed = false;
- public $featured;
+ public bool $bookmarked = false;
- public $stream;
+ public bool $wished = false;
- public $sd;
+ public bool $internal = false;
- public $highspeed;
+ public bool $personalRelease = false;
- public $bookmarked;
+ public bool $alive = false;
- public $wished;
+ public bool $dying = false;
- public $internal;
+ public bool $dead = false;
- public $personalRelease;
+ public bool $notDownloaded = false;
- public $alive;
+ public bool $downloaded = false;
- public $dying;
+ public bool $seeding = false;
- public $dead;
+ public bool $leeching = false;
- public $notDownloaded;
-
- public $downloaded;
-
- public $seeding;
-
- public $leeching;
-
- public $incomplete;
+ public bool $incomplete = false;
public int $perPage = 25;
@@ -138,11 +124,7 @@ class TorrentListSearch extends Component
'malId' => ['except' => ''],
'playlistId' => ['except' => ''],
'collectionId' => ['except' => ''],
- 'free0' => ['except' => false],
- 'free25' => ['except' => false],
- 'free50' => ['except' => false],
- 'free75' => ['except' => false],
- 'free100' => ['except' => false],
+ 'free' => ['except' => []],
'doubleup' => ['except' => false],
'featured' => ['except' => false],
'stream' => ['except' => false],
@@ -200,200 +182,57 @@ class TorrentListSearch extends Component
final public function getTorrentsProperty(): \Illuminate\Contracts\Pagination\LengthAwarePaginator
{
+ $user = \auth()->user();
+ $isRegexAllowed = $user->group->is_modo;
+ $isRegex = fn ($field) => $isRegexAllowed
+ && \strlen($field) >= 2
+ && $field[0] === '/'
+ && $field[-1] === '/';
+
return Torrent::with(['user:id,username,group_id', 'user.group', 'category', 'type', 'resolution'])
->withCount(['thanks', 'comments'])
- ->when($this->name, function ($query) {
- $terms = \explode(' ', $this->name);
- $search = '';
- foreach ($terms as $term) {
- $search .= '%'.$term.'%';
- }
-
- $query->where('name', 'LIKE', $search);
- })
- ->when($this->description, function ($query) {
- $query->where('description', 'LIKE', '%'.$this->description.'%');
- })
- ->when($this->mediainfo, function ($query) {
- $query->where('mediainfo', 'LIKE', '%'.$this->mediainfo.'%');
- })
- ->when($this->uploader, function ($query) {
- $match = User::where('username', '=', $this->uploader)->first();
- if ($match) {
- $query->where('user_id', '=', $match->id)->where('anon', '=', 0);
- }
- })
- ->when($this->keywords, function ($query) {
- $keywords = self::parseKeywords($this->keywords);
- $keyword = Keyword::whereIn('name', $keywords)->pluck('torrent_id');
- $query->whereIntegerInRaw('id', $keyword);
- })
- ->when($this->startYear && $this->endYear, function ($query) {
- $query->whereBetween('release_year', [$this->startYear, $this->endYear]);
- })
- ->when($this->categories, function ($query) {
- $query->whereIntegerInRaw('category_id', $this->categories);
- })
- ->when($this->types, function ($query) {
- $query->whereIntegerInRaw('type_id', $this->types);
- })
- ->when($this->resolutions, function ($query) {
- $query->whereIntegerInRaw('resolution_id', $this->resolutions);
- })
- ->when($this->genres, function ($query) {
- $this->validate();
-
- $tvCollection = DB::table('genre_tv')->whereIntegerInRaw('genre_id', $this->genres)->pluck('tv_id');
- $movieCollection = DB::table('genre_movie')->whereIntegerInRaw('genre_id', $this->genres)->pluck('movie_id');
- $mergedCollection = $tvCollection->merge($movieCollection);
-
- $query->whereRaw("tmdb in ('".\implode("','", $mergedCollection->toArray())."')"); // Protected with Validation that IDs passed are not malicious
- })
- ->when($this->regions, function ($query) {
- $query->whereIntegerInRaw('region_id', $this->regions);
- })
- ->when($this->distributors, function ($query) {
- $query->whereIntegerInRaw('distributor_id', $this->distributors);
- })
- ->when($this->tmdbId === '0' || $this->tmdbId, function ($query) {
- $query->where('tmdb', '=', $this->tmdbId);
- })
- ->when($this->imdbId === '0' || $this->imdbId, function ($query) {
- if (\preg_match('/tt0*?(?=(\d{7,8}))/', $this->imdbId, $matches)) {
- $query->where('imdb', '=', $matches[1]);
- } else {
- $query->where('imdb', '=', $this->imdbId);
- }
- })
- ->when($this->tvdbId === '0' || $this->tvdbId, function ($query) {
- $query->where('tvdb', '=', $this->tvdbId);
- })
- ->when($this->malId === '0' || $this->malId, function ($query) {
- $query->where('mal', '=', $this->malId);
- })
- ->when($this->playlistId, function ($query) {
- $playlist = PlaylistTorrent::where('playlist_id', '=', $this->playlistId)->pluck('torrent_id');
- $query->whereIntegerInRaw('id', $playlist);
- })
- ->when($this->collectionId, function ($query) {
- $categories = Category::where('movie_meta', '=', 1)->pluck('id');
- $collection = DB::table('collection_movie')->where('collection_id', '=', $this->collectionId)->pluck('movie_id');
- $query->whereIntegerInRaw('category_id', $categories)->whereIntegerInRaw('tmdb', $collection);
- })
- ->when($this->free0 === '0' || $this->free0 || $this->free25 || $this->free50 || $this->free75 || $this->free100, function ($query) {
- $query->where(function ($query) {
- $query->where(function ($query) {
- if ($this->free0 === '0' || $this->free0) {
- $query->where('free', '=', 0);
- }
- })
- ->orWhere(function ($query) {
- if ($this->free25) {
- $query->where('free', '=', 25);
- }
- })
- ->orWhere(function ($query) {
- if ($this->free50) {
- $query->where('free', '=', 50);
- }
- })
- ->orWhere(function ($query) {
- if ($this->free75) {
- $query->where('free', '=', 75);
- }
- })
- ->orWhere(function ($query) {
- if ($this->free100) {
- $query->where('free', '=', 100);
- }
- });
- });
- })
- ->when($this->doubleup, function ($query) {
- $query->where('doubleup', '=', 1);
- })
- ->when($this->featured, function ($query) {
- $query->where('featured', '=', 1);
- })
- ->when($this->stream, function ($query) {
- $query->where('stream', '=', 1);
- })
- ->when($this->sd, function ($query) {
- $query->where('sd', '=', 1);
- })
- ->when($this->highspeed, function ($query) {
- $query->where('highspeed', '=', 1);
- })
- ->when($this->bookmarked, function ($query) {
- $bookmarks = Bookmark::where('user_id', '=', \auth()->user()->id)->pluck('torrent_id');
- $query->whereIntegerInRaw('id', $bookmarks);
- })
- ->when($this->wished, function ($query) {
- $wishes = Wish::where('user_id', '=', \auth()->user()->id)->pluck('tmdb');
- $query->whereIn('tmdb', $wishes);
- })
- ->when($this->internal, function ($query) {
- $query->where('internal', '=', 1);
- })
- ->when($this->personalRelease, function ($query) {
- $query->where('personal_release', '=', 1);
- })
- ->when($this->alive, function ($query) {
- $query->where('seeders', '>=', 1);
- })
- ->when($this->dying, function ($query) {
- $query->where('seeders', '=', 1)->where('times_completed', '>=', 3);
- })
- ->when($this->dead, function ($query) {
- $query->where('seeders', '=', 0);
- })
- ->when($this->notDownloaded, function ($query) {
- $history = History::where('user_id', '=', \auth()->user()->id)->pluck('torrent_id')->toArray();
- if (! $history || ! \is_array($history)) {
- $history = [];
- }
-
- $query->whereIntegerNotInRaw('id', $history);
- })
- ->when($this->downloaded, function ($query) {
- $query->whereHas('history', function ($query) {
- $query->where('user_id', '=', \auth()->user()->id);
- });
- })
- ->when($this->seeding, function ($query) {
- $query->whereHas('history', function ($q) {
- $q->where('user_id', '=', \auth()->user()->id)->where('active', '=', true)->where('seeder', '=', true);
- });
- })
- ->when($this->leeching, function ($query) {
- $query->whereHas('history', function ($q) {
- $q->where('user_id', '=', \auth()->user()->id)->where('active', '=', true)->where('seedtime', '=', '0');
- });
- })
- ->when($this->incomplete, function ($query) {
- $query->whereHas('history', function ($q) {
- $q->where('user_id', '=', \auth()->user()->id)->where('active', '=', false)->where('seeder', '=', false)->where('seedtime', '=', '0');
- });
- })
+ ->when($this->name !== '' , fn ($query) => $query->ofName($this->name, $isRegex($this->name)))
+ ->when($this->description !== '' , fn ($query) => $query->ofDescription($this->description, $isRegex($this->name)))
+ ->when($this->mediainfo !== '' , fn ($query) => $query->ofMediainfo($this->mediainfo, $isRegex($this->name)))
+ ->when($this->uploader !== '' , fn ($query) => $query->ofUploader($this->uploader))
+ ->when($this->keywords !== '' , fn ($query) => $query->ofKeyword(\array_map('trim', explode(',', $this->keywords))))
+ ->when($this->startYear !== '' , fn ($query) => $query->releasedAfterOrIn($this->startYear))
+ ->when($this->endYear !== '' , fn ($query) => $query->releasedBeforeOrIn($this->endYear))
+ ->when($this->categories !== [] , fn ($query) => $query->ofCategory($this->categories))
+ ->when($this->types !== [] , fn ($query) => $query->ofType($this->types))
+ ->when($this->resolutions !== [] , fn ($query) => $query->ofResolution($this->resolutions))
+ ->when($this->genres !== [] , fn ($query) => $query->ofGenre($this->genres))
+ ->when($this->regions !== [] , fn ($query) => $query->ofRegion($this->regions))
+ ->when($this->distributors !== [] , fn ($query) => $query->ofDistributor($this->distributors))
+ ->when($this->tmdbId !== '' , fn ($query) => $query->ofTmdb($this->tmdbId))
+ ->when($this->imdbId !== '' , fn ($query) => $query->ofImdb(\preg_match('/tt0*(?=(\d{7,}))/', $this->imdbId, $matches) ? $matches[1] : $this->imdbId))
+ ->when($this->tvdbId !== '' , fn ($query) => $query->ofTvdb($this->tvdbId))
+ ->when($this->malId !== '' , fn ($query) => $query->ofMal($this->malId))
+ ->when($this->playlistId !== '' , fn ($query) => $query->ofPlaylist($this->playlistId))
+ ->when($this->collectionId !== '' , fn ($query) => $query->ofCollection($this->collectionId))
+ ->when($this->free !== [] , fn ($query) => $query->ofFreeleech($this->free))
+ ->when($this->doubleup !== false, fn ($query) => $query->doubleup())
+ ->when($this->featured !== false, fn ($query) => $query->featured())
+ ->when($this->stream !== false, fn ($query) => $query->streamOptimized())
+ ->when($this->sd !== false, fn ($query) => $query->sd())
+ ->when($this->highspeed !== false, fn ($query) => $query->highspeed())
+ ->when($this->bookmarked !== false, fn ($query) => $query->bookmarkedBy($user))
+ ->when($this->wished !== false, fn ($query) => $query->wishedBy($user))
+ ->when($this->internal !== false, fn ($query) => $query->internal())
+ ->when($this->personalRelease !== false, fn ($query) => $query->personalRelease())
+ ->when($this->alive !== false, fn ($query) => $query->alive())
+ ->when($this->dying !== false, fn ($query) => $query->dying())
+ ->when($this->dead !== false, fn ($query) => $query->dead())
+ ->when($this->notDownloaded !== false, fn ($query) => $query->notDownloadedBy($user))
+ ->when($this->downloaded !== false, fn ($query) => $query->downloadedBy($user))
+ ->when($this->seeding !== false, fn ($query) => $query->seededBy($user))
+ ->when($this->leeching !== false, fn ($query) => $query->leechedBy($user))
+ ->when($this->incomplete !== false, fn ($query) => $query->uncompletedBy($user))
->latest('sticky')
->orderBy($this->sortField, $this->sortDirection)
->paginate($this->perPage);
}
- private static function parseKeywords($text): array
- {
- $parts = \explode(', ', (string) $text);
- $result = [];
- foreach ($parts as $part) {
- $part = \trim($part);
- if ($part != '') {
- $result[] = $part;
- }
- }
-
- return $result;
- }
-
final public function sortBy($field): void
{
if ($this->sortField === $field) {
diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php
index bd7db557c..1884a04ce 100644
--- a/app/Models/Torrent.php
+++ b/app/Models/Torrent.php
@@ -20,6 +20,7 @@ use App\Helpers\StringHelper;
use App\Notifications\NewComment;
use App\Notifications\NewThank;
use App\Traits\Auditable;
+use App\Traits\TorrentFilter;
use Hootlex\Moderation\Moderatable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
@@ -30,6 +31,7 @@ class Torrent extends Model
use HasFactory;
use Moderatable;
use Auditable;
+ use TorrentFilter;
/**
* Belongs To A User.
diff --git a/app/Traits/TorrentFilter.php b/app/Traits/TorrentFilter.php
new file mode 100644
index 000000000..46992ddcd
--- /dev/null
+++ b/app/Traits/TorrentFilter.php
@@ -0,0 +1,276 @@
+
+ * @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
+ */
+
+namespace App\Traits;
+
+use App\Models\Bookmark;
+use App\Models\Category;
+use App\Models\Keyword;
+use App\Models\PlaylistTorrent;
+use App\Models\User;
+use App\Models\Wish;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Support\Facades\DB;
+
+trait TorrentFilter
+{
+ public function scopeOfName(Builder $query, string $name, bool $isRegex = false): Builder
+ {
+ return $query->when($isRegex,
+ fn ($query) => $query->where('name', 'REGEXP', \substr($name, 1, -1)),
+ fn ($query) => $query->where('name', 'LIKE', '%'.\str_replace(' ', '%', $name).'%')
+ );
+ }
+
+ public function scopeOfDescription(Builder $query, string $description, bool $isRegex = false): Builder
+ {
+ return $query->when($isRegex,
+ fn ($query) => $query->where('description', 'REGEXP', \substr($description, 1, -1)),
+ fn ($query) => $query->where('description', 'LIKE', '%'.$description.'%')
+ );
+ }
+
+ public function scopeOfMediainfo(Builder $query, string $mediainfo, bool $isRegex = false): Builder
+ {
+ return $query->when($isRegex,
+ fn ($query) => $query->where('mediainfo', 'REGEXP', \substr($mediainfo, 1, -1)),
+ fn ($query) => $query->where('mediainfo', 'LIKE', '%'.$mediainfo.'%')
+ );
+ }
+
+ public function scopeOfUploader(Builder $query, string $username): Builder
+ {
+ return $query
+ ->whereIn('user_id', User::select('id')->where('username', '=', $username))
+ ->where('anon', '=', 0);
+ }
+
+ public function scopeOfKeywords(Builder $query, array $keywords): Builder
+ {
+ return $query->whereIn('id', Keyword::select('torrent_id')->whereIn('name', $keywords));
+ }
+
+ public function scopeReleasedAfterOrIn(Builder $query, int $year): Builder
+ {
+ return $query->where('release_year', '>=', $year);
+ }
+
+ public function scopeReleasedBeforeOrIn(Builder $query, int $year): Builder
+ {
+ return $query->where('release_year', '<=', $year);
+ }
+
+ public function scopeOfCategory(Builder $query, array $categories): Builder
+ {
+ return $query->whereIntegerInRaw('category_id', $categories);
+ }
+
+ public function scopeOfType(Builder $query, array $types): Builder
+ {
+ return $query->whereIntegerInRaw('type_id', $types);
+ }
+
+ public function scopeOfResolution(Builder $query, array $resolutions): Builder
+ {
+ return $query->whereIntegerInRaw('resolution_id', $resolutions);
+ }
+
+ public function scopeOfGenre(Builder $query, array $genres): Builder
+ {
+ return $query
+ ->where(fn ($query) => $query
+ ->where(fn ($query) => $query
+ ->whereIn('category_id', Category::select('id')->where('movie_meta', '=', 1))
+ ->whereIn('tmdb', DB::table('genre_movie')->select('movie_id')->whereIn('genre_id', $genres))
+ )
+ ->orWhere(fn ($query) => $query
+ ->whereIn('category_id', Category::select('id')->where('tv_meta', '=', 1))
+ ->whereIn('tmdb', DB::table('genre_tv')->select('tv_id')->whereIn('genre_id', $genres))
+ )
+ );
+ }
+
+ public function scopeOfRegion(Builder $query, array $regions): Builder
+ {
+ return $query->whereIntegerInRaw('region_id', $regions);
+ }
+
+ public function scopeOfDistributor(Builder $query, array $distributors): Builder
+ {
+ return $query->whereIntegerInRaw('distributor_id', $distributors);
+ }
+
+ public function scopeOfTmdb(Builder $query, int $tvdbId): Builder
+ {
+ return $query->where('tmdb', '=', $tvdbId);
+ }
+
+ public function scopeOfimdb(Builder $query, int $tvdbId): Builder
+ {
+ return $query->where('imdb', '=', $tvdbId);
+ }
+
+ public function scopeOfTvdb(Builder $query, int $tvdbId): Builder
+ {
+ return $query->where('tvdb', '=', $tvdbId);
+ }
+
+ public function scopeOfMal(Builder $query, int $malId): Builder
+ {
+ return $query->where('mal', '=', $malId);
+ }
+
+ public function scopeOfPlaylist(Builder $query, int $playlistId): Builder
+ {
+ return $query->whereIn('id', PlaylistTorrent::select('torrent_id')->where('playlist_id', '=', $playlistId));
+ }
+
+ public function scopeOfCollection(Builder $query, int $collectionId): Builder
+ {
+ return $query
+ ->whereIn('category_id', Category::select('id')->where('movie_meta', '=', 1))
+ ->whereIn('tmdb', DB::table('collection_movie')->select('movie_id')->where('collection_id', '=', $collectionId));
+ }
+
+ public function scopeOfFreeleech(Builder $query, array $free): Builder
+ {
+ return $query->whereIntegerInRaw('free', $free);
+ }
+
+ public function scopeDoubleup(Builder $query): Builder
+ {
+ return $query->where('doubleup', '=', 1);
+ }
+
+ public function scopeFeatured(Builder $query): Builder
+ {
+ return $query->where('featured', '=', 1);
+ }
+
+ public function scopeStreamOptimized(Builder $query): Builder
+ {
+ return $query->where('stream', '=', 1);
+ }
+
+ public function scopeSd(Builder $query): Builder
+ {
+ return $query->where('sd', '=', 1);
+ }
+
+ public function scopeHighSpeed(Builder $query): Builder
+ {
+ return $query->where('highspeed', '=', 1);
+ }
+
+ public function scopeBookmarkedBy(Builder $query, User $user): Builder
+ {
+ return $query->whereIn('id', Bookmark::select('torrent_id')->where('user_id', '=', $user->id));
+ }
+
+ public function scopeWishedBy(Builder $query, User $user): Builder
+ {
+ return $query->whereIn('tmdb', Wish::select('tmdb')->where('user_id', '=', $user->id));
+ }
+
+ public function scopeInternal(Builder $query): Builder
+ {
+ return $query->where('internal', '=', 1);
+ }
+
+ public function scopePersonalRelease(Builder $query): Builder
+ {
+ return $query->where('personal_release', '=', 1);
+ }
+
+ public function scopeAlive(Builder $query): Builder
+ {
+ return $query->where('seeders', '>', 0);
+ }
+
+ public function scopeDying(Builder $query): Builder
+ {
+ return $query
+ ->where('seeders', '=', 1)
+ ->where('times_completed', '>=', 3);
+ }
+
+ public function scopeDead(Builder $query): Builder
+ {
+ return $query->where('seeders', '=', 0);
+ }
+
+ public function scopeNotDownloadedBy(Builder $query, User $user): Builder
+ {
+ return $query
+ ->whereDoesntHave('history', fn ($query) => $query
+ ->where('user_id', '=', $user->id)
+ );
+ }
+
+ public function scopeDownloadedBy(Builder $query, User $user): Builder
+ {
+ return $query
+ ->whereHas('history', fn (Builder $query) => $query
+ ->where('user_id', '=', $user->id)
+ );
+ }
+
+ public function scopeSeededBy(Builder $query, User $user): Builder
+ {
+ return $query
+ ->whereHas('history', fn ($query) => $query
+ ->where('user_id', '=', $user->id)
+ ->where('active', '=', 1)
+ ->where('seeder', '=', 1)
+ );
+ }
+
+ public function scopeLeechedby(Builder $query, User $user): Builder
+ {
+ return $query
+ ->whereHas('history', fn ($query) => $query
+ ->where('user_id', '=', $user->id)
+ ->where('active', '=', 1)
+ ->where('seeder', '=', 0)
+ );
+ }
+
+ public function scopeUncompletedBy(Builder $query, User $user): Builder
+ {
+ return $query
+ ->whereHas('history', fn ($query) => $query
+ ->where('user_id', '=', $user->id)
+ ->where('active', '=', 0)
+ ->where('seeder', '=', 0)
+ ->where('seedtime', '=', 0)
+ );
+ }
+
+ public function scopeOfFilename(Builder $query, string $filename): Builder
+ {
+ return $query
+ ->whereHas('files', fn ($query) => $query
+ ->where('name', $filename)
+ );
+ }
+
+ public function scopeOfSeason(Builder $query, int $seasonNumber): Builder
+ {
+ return $query->where('season_number', '=', $seasonNumber);
+ }
+
+ public function scopeOfEpisode(Builder $query, int $episodeNumber): Builder
+ {
+ return $query->where('episode_number', '=', $episodeNumber);
+ }
+}
diff --git a/resources/views/livewire/graveyard-search.blade.php b/resources/views/livewire/graveyard-search.blade.php
index faf250c26..9a9f34600 100644
--- a/resources/views/livewire/graveyard-search.blade.php
+++ b/resources/views/livewire/graveyard-search.blade.php
@@ -96,8 +96,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/views/livewire/torrent-card-search.blade.php b/resources/views/livewire/torrent-card-search.blade.php
index 7d421ba50..b8df65d11 100644
--- a/resources/views/livewire/torrent-card-search.blade.php
+++ b/resources/views/livewire/torrent-card-search.blade.php
@@ -145,31 +145,31 @@
diff --git a/resources/views/livewire/torrent-list-search.blade.php b/resources/views/livewire/torrent-list-search.blade.php
index 162226f88..a2321f85d 100644
--- a/resources/views/livewire/torrent-list-search.blade.php
+++ b/resources/views/livewire/torrent-list-search.blade.php
@@ -160,31 +160,31 @@