refactor: move TorrentFilter trait into TorrentSearchFiltersDTO

The trait is only used in the one place (apart from being used in the request search, which it shouldn't have been used for in the first place).
This commit is contained in:
Roardom
2024-11-02 10:48:09 +00:00
parent 2618ebf308
commit 40c2889613
5 changed files with 365 additions and 661 deletions
+296 -52
View File
@@ -16,14 +16,15 @@ declare(strict_types=1);
namespace App\DTO;
use App\Models\PlaylistTorrent;
use App\Models\User;
use App\Traits\TorrentFilter;
use App\Models\Wish;
use Illuminate\Database\Eloquent\Builder;
use Closure;
use Illuminate\Support\Facades\DB;
readonly class TorrentSearchFiltersDTO
{
use TorrentFilter;
private ?User $user;
public function __construct(
@@ -103,56 +104,299 @@ readonly class TorrentSearchFiltersDTO
&& @preg_match($field, 'Validate regex') !== false;
return fn ($query) => $query
->when($this->name !== '', fn ($query) => $query->ofName($this->name, $isRegex($this->name)))
->when($this->description !== '', fn ($query) => $query->ofDescription($this->description, $isRegex($this->description)))
->when($this->mediainfo !== '', fn ($query) => $query->ofMediainfo($this->mediainfo, $isRegex($this->mediainfo)))
->when($this->uploader !== '', fn ($query) => $query->ofUploader($this->uploader))
->when($this->keywords !== [], fn ($query) => $query->ofKeyword($this->keywords))
->when($this->startYear !== null, fn ($query) => $query->releasedAfterOrIn($this->startYear))
->when($this->endYear !== null, fn ($query) => $query->releasedBeforeOrIn($this->endYear))
->when($this->minSize !== null, fn ($query) => $query->ofSizeGreaterOrEqualto($this->minSize))
->when($this->maxSize !== null, fn ($query) => $query->ofSizeLesserOrEqualTo($this->maxSize))
->when($this->categoryIds !== [], fn ($query) => $query->ofCategory($this->categoryIds))
->when($this->typeIds !== [], fn ($query) => $query->ofType($this->typeIds))
->when($this->resolutionIds !== [], fn ($query) => $query->ofResolution($this->resolutionIds))
->when($this->genreIds !== [], fn ($query) => $query->ofGenre($this->genreIds))
->when($this->regionIds !== [], fn ($query) => $query->ofRegion($this->regionIds))
->when($this->distributorIds !== [], fn ($query) => $query->ofDistributor($this->distributorIds))
->when($this->tmdbId !== null, fn ($query) => $query->ofTmdb($this->tmdbId))
->when($this->imdbId !== null, fn ($query) => $query->ofImdb($this->imdbId))
->when($this->tvdbId !== null, fn ($query) => $query->ofTvdb($this->tvdbId))
->when($this->malId !== null, fn ($query) => $query->ofMal($this->malId))
->when($this->episodeNumber !== null, fn ($query) => $query->ofEpisode($this->episodeNumber))
->when($this->seasonNumber !== null, fn ($query) => $query->ofSeason($this->seasonNumber))
->when($this->playlistId !== null, fn ($query) => $query->ofPlaylist($this->playlistId))
->when($this->collectionId !== null, fn ($query) => $query->ofCollection($this->collectionId))
->when($this->companyId !== null, fn ($query) => $query->ofCompany($this->companyId))
->when($this->networkId !== null, fn ($query) => $query->ofNetwork($this->networkId))
->when($this->primaryLanguageNames !== [], fn ($query) => $query->ofPrimaryLanguage($this->primaryLanguageNames))
->when($this->free !== [], fn ($query) => $query->ofFreeleech($this->free))
->when($this->filename !== '', fn ($query) => $query->ofFilename($this->filename))
->when($this->adult === true, fn ($query) => $query->ofAdult(true))
->when($this->adult === false, fn ($query) => $query->ofAdult(false))
->when($this->doubleup, fn ($query) => $query->doubleup())
->when($this->featured, fn ($query) => $query->featured())
->when($this->refundable, fn ($query) => $query->refundable())
->when($this->stream, fn ($query) => $query->streamOptimized())
->when($this->sd, fn ($query) => $query->sd())
->when($this->highspeed, fn ($query) => $query->highspeed())
->when($this->userBookmarked, fn ($query) => $query->bookmarkedBy($this->user))
->when($this->userWished, fn ($query) => $query->wishedBy($this->user))
->when($this->internal, fn ($query) => $query->internal())
->when($this->personalRelease, fn ($query) => $query->personalRelease())
->when($this->trumpable, fn ($query) => $query->trumpable())
->when($this->alive, fn ($query) => $query->alive())
->when($this->dying, fn ($query) => $query->dying())
->when($this->dead, fn ($query) => $query->dead())
->when($this->graveyard, fn ($query) => $query->graveyard())
->when($this->userDownloaded === false, fn ($query) => $query->notDownloadedBy($this->user))
->when($this->userDownloaded === true, fn ($query) => $query->downloadedBy($this->user))
->when($this->userSeeder === true && $this->userActive === true, fn ($query) => $query->seededBy($this->user))
->when($this->userSeeder === false && $this->userActive === true, fn ($query) => $query->leechedBy($this->user))
->when($this->userSeeder === false && $this->userActive === false, fn ($query) => $query->uncompletedBy($this->user));
->when(
$this->name !== '',
fn ($query) => $query
->when(
$isRegex($this->name),
fn ($query) => $query->where('name', 'REGEXP', substr($this->name, 1, -1)),
fn ($query) => $query->where('name', 'LIKE', '%'.str_replace(' ', '%', $this->name).'%')
)
)
->when(
$this->description !== '',
fn ($query) => $query
->when(
$isRegex($this->description),
fn ($query) => $query->where('description', 'REGEXP', substr($this->description, 1, -1)),
fn ($query) => $query->where('description', 'LIKE', '%'.$this->description.'%')
)
)
->when(
$this->mediainfo !== '',
fn ($query) => $query
->when(
$isRegex($this->mediainfo),
fn ($query) => $query->where('mediainfo', 'REGEXP', substr($this->mediainfo, 1, -1)),
fn ($query) => $query->where('mediainfo', 'LIKE', '%'.$this->mediainfo.'%')
)
)
->when(
$this->uploader !== '',
fn ($query) => $query
->whereRelation('user', 'username', '=', $this->uploader)
->when(
$this->user === null,
fn ($query) => $query->where('anon', '=', false),
fn ($query) => $query
->when(
!$this->user->group->is_modo,
fn ($query) => $query
->where(
fn ($query) => $query
->where('anon', '=', false)
->orWhere('user_id', '=', $this->user->id)
)
)
)
)
->when(
$this->keywords !== [],
fn ($query) => $query->whereHas('keywords', fn ($query) => $query->whereIn('name', $this->keywords))
)
->when(
$this->startYear !== null,
fn ($query) => $query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('movie', 'release_date', '>=', $this->startYear.'-01-01 00:00:00')
->whereRelation('category', 'movie_meta', '=', true)
)
->orWhere(
fn ($query) => $query
->whereRelation('tv', 'first_air_date', '>=', $this->startYear.'-01-01 00:00:00')
->whereRelation('category', 'tv_meta', '=', true)
)
)
)
->when(
$this->endYear !== null,
fn ($query) => $query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('movie', 'release_date', '<=', $this->endYear.'-12-31 23:59:59')
->whereRelation('category', 'movie_meta', '=', true)
)
->orWhere(
fn ($query) => $query
->orWhereRelation('tv', 'first_air_date', '<=', $this->endYear.'-12-31 23:59:59')
->whereRelation('category', 'tv_meta', '=', true)
)
)
)
->when($this->minSize !== null, fn ($query) => $query->where('size', '>=', $this->minSize))
->when($this->maxSize !== null, fn ($query) => $query->where('size', '<=', $this->maxSize))
->when($this->categoryIds !== [], fn ($query) => $query->whereIntegerInRaw('category_id', $this->categoryIds))
->when($this->typeIds !== [], fn ($query) => $query->whereIntegerInRaw('type_id', $this->typeIds))
->when($this->resolutionIds !== [], fn ($query) => $query->whereIntegerInRaw('resolution_id', $this->resolutionIds))
->when(
$this->genreIds !== [],
fn ($query) => $query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereIn('tmdb', DB::table('genre_movie')->select('movie_id')->whereIn('genre_id', $this->genreIds))
)
->orWhere(
fn ($query) => $query
->whereRelation('category', 'tv_meta', '=', true)
->whereIn('tmdb', DB::table('genre_tv')->select('tv_id')->whereIn('genre_id', $this->genreIds))
)
)
)
->when(
$this->regionIds !== [],
fn ($query) => $query
->where(
fn ($query) => $query
->whereIntegerInRaw('region_id', $this->regionIds)
->when(\in_array(0, $this->regionIds), fn ($query) => $query->orWhereNull('region_id'))
)
)
->when(
$this->distributorIds !== [],
fn ($query) => $query
->where(
fn ($query) => $query
->whereIntegerInRaw('distributor_id', $this->distributorIds)
->when(\in_array(0, $this->distributorIds), fn ($query) => $query->orWhereNull('distributor_id'))
)
)
->when($this->tmdbId !== null, fn ($query) => $query->where('tmdb', '=', $this->tvdbId))
->when($this->imdbId !== null, fn ($query) => $query->where('imdb', '=', $this->tvdbId))
->when($this->tvdbId !== null, fn ($query) => $query->where('tvdb', '=', $this->tvdbId))
->when($this->malId !== null, fn ($query) => $query->where('mal', '=', $this->malId))
->when($this->episodeNumber !== null, fn ($query) => $query->where('episode_number', '=', $this->episodeNumber))
->when($this->seasonNumber !== null, fn ($query) => $query->where('season_number', '=', $this->seasonNumber))
->when(
$this->playlistId !== null,
fn ($query) => $query
->whereIn(
'id',
PlaylistTorrent::select('torrent_id')
->where('playlist_id', '=', $this->playlistId)
->when(
$this->user === null,
fn ($query) => $query->whereRelation('playlist', 'is_private', '=', false),
fn ($query) => $query->when(
! $this->user->group->is_modo,
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('playlist', 'is_private', '=', false)
->orWhereRelation('playlist', 'user_id', '=', $this->user->id)
)
)
)
)
)
->when(
$this->collectionId !== null,
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereIn('tmdb', DB::table('collection_movie')->select('movie_id')->where('collection_id', '=', $this->collectionId))
)
->when(
$this->companyId !== null,
fn ($query) => $query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereIn('tmdb', DB::table('company_movie')->select('movie_id')->where('company_id', '=', $this->companyId))
)
->orWhere(
fn ($query) => $query
->whereRelation('category', 'tv_meta', '=', true)
->whereIn('tmdb', DB::table('company_tv')->select('tv_id')->where('company_id', '=', $this->companyId))
)
)
)
->when(
$this->networkId !== null,
fn ($query) => $query
->whereRelation('category', 'tv_meta', '=', true)
->whereIn('tmdb', DB::table('network_tv')->select('tv_id')->where('network_id', '=', $this->networkId))
)
->when(
$this->primaryLanguageNames !== [],
fn ($query) => $query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereHas('movie', fn ($query) => $query->whereIn('original_language', $this->primaryLanguageNames))
)
->orWhere(
fn ($query) => $query
->whereRelation('category', 'tv_meta', '=', true)
->whereHas('tv', fn ($query) => $query->whereIn('original_language', $this->primaryLanguageNames))
)
)
)
->when(
$this->free !== [],
fn ($query) => $query
->when(
config('other.freeleech'),
fn ($query) => $query->whereBetween('free', [0, 100]),
fn ($query) => $query->whereIntegerInRaw('free', (array) $this->free)
)
)
->when($this->filename !== '', fn ($query) => $query->whereRelation('files', 'name', '=', $this->filename))
->when(
$this->adult === true,
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereRelation('movie', 'adult', '=', true)
)
// Currently, only movies have an `adult` column.
->when(
$this->adult === false,
fn ($query) => $query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereRelation('movie', 'adult', '=', false)
)
->orWhere(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', false)
)
)
)
->when($this->doubleup, fn ($query) => $query->where('doubleup', '=', 1))
->when($this->featured, fn ($query) => $query->where('featured', '=', 1))
->when($this->refundable, fn ($query) => $query->where('refundable', '=', true))
->when($this->stream, fn ($query) => $query->where('stream', '=', 1))
->when($this->sd, fn ($query) => $query->where('sd', '=', 1))
->when($this->highspeed, fn ($query) => $query->where('highspeed', '=', 1))
->when($this->userBookmarked, fn ($query) => $query->whereRelation('bookmarks', 'user_id', '=', $this->user->id))
->when($this->userWished, fn ($query) => $query->whereIn('tmdb', Wish::select('tmdb')->where('user_id', '=', $this->user->id)))
->when($this->internal, fn ($query) => $query->where('internal', '=', 1))
->when($this->personalRelease, fn ($query) => $query->where('personal_release', '=', 1))
->when($this->trumpable, fn ($query) => $query->has('trump'))
->when($this->alive, fn ($query) => $query->where('seeders', '>', 0))
->when($this->dying, fn ($query) => $query->where('seeders', '=', 1)->where('times_completed', '>=', 3))
->when($this->dead, fn ($query) => $query->where('seeders', '=', 0))
->when($this->graveyard, fn ($query) => $query->where('seeders', '=', 0)->where('created_at', '<', now()->subDays(30)))
->when(
$this->userDownloaded === false,
fn ($query) => $query
->whereDoesntHave(
'history',
fn ($query) => $query
->where('user_id', '=', $this->user->id)
)
)
->when(
$this->userDownloaded === true,
fn ($query) => $query->whereRelation('history', 'user_id', '=', $this->user->id)
)
->when(
$this->userSeeder === true && $this->userActive === true,
fn ($query) => $query
->whereHas(
'history',
fn ($query) => $query
->where('user_id', '=', $this->user->id)
->where('active', '=', 1)
->where('seeder', '=', 1)
)
)
->when(
$this->userSeeder === false && $this->userActive === true,
fn ($query) => $query
->whereHas(
'history',
fn ($query) => $query
->where('user_id', '=', $this->user->id)
->where('active', '=', 1)
->where('seeder', '=', 0)
)
)
->when(
$this->userSeeder === false && $this->userActive === false,
fn ($query) => $query
->whereHas(
'history',
fn ($query) => $query
->where('user_id', '=', $this->user->id)
->where('active', '=', 0)
->where('seeder', '=', 0)
->where('seedtime', '=', 0)
)
);
}
/**
+69 -11
View File
@@ -209,17 +209,75 @@ class TorrentRequestSearch extends Component
return TorrentRequest::with(['user:id,username,group_id', 'user.group', 'category', 'type', 'resolution'])
->withCount(['comments'])
->when($this->name !== '', fn ($query) => $query->ofName($this->name, $isRegex($this->name)))
->when($this->requestor !== '', fn ($query) => $query->ofUploader($this->requestor))
->when($this->categoryIds !== [], fn ($query) => $query->ofCategory($this->categoryIds))
->when($this->typeIds !== [], fn ($query) => $query->ofType($this->typeIds))
->when($this->resolutionIds !== [], fn ($query) => $query->ofResolution($this->resolutionIds))
->when($this->tmdbId !== null, fn ($query) => $query->ofTmdb($this->tmdbId))
->when($this->imdbId !== '', fn ($query) => $query->ofImdb((int) (preg_match('/tt0*(?=(\d{7,}))/', $this->imdbId, $matches) ? $matches[1] : $this->imdbId)))
->when($this->tvdbId !== null, fn ($query) => $query->ofTvdb((int) $this->tvdbId))
->when($this->malId !== null, fn ($query) => $query->ofMal((int) $this->malId))
->when($this->genreIds !== [], fn ($query) => $query->ofGenre($this->genreIds))
->when($this->primaryLanguageNames !== [], fn ($query) => $query->ofPrimaryLanguage($this->primaryLanguageNames))
->when(
$this->name !== '',
fn ($query) => $query
->when(
$isRegex($this->name),
fn ($query) => $query->where('name', 'REGEXP', substr($this->name, 1, -1)),
fn ($query) => $query->where('name', 'LIKE', '%'.str_replace(' ', '%', $this->name).'%')
)
)
->when(
$this->requestor !== '',
fn ($query) => $query
->whereRelation('user', 'username', '=', $this->requestor)
->when(
$user === null,
fn ($query) => $query->where('anon', '=', false),
fn ($query) => $query
->when(
!$user->group->is_modo,
fn ($query) => $query
->where(
fn ($query) => $query
->where('anon', '=', false)
->orWhere('user_id', '=', $user->id)
)
)
)
)
->when($this->categoryIds !== [], fn ($query) => $query->whereIntegerInRaw('category_id', $this->categoryIds))
->when($this->typeIds !== [], fn ($query) => $query->whereIntegerInRaw('type_id', $this->typeIds))
->when($this->resolutionIds !== [], fn ($query) => $query->whereIntegerInRaw('resolution_id', $this->resolutionIds))
->when($this->tmdbId !== null, fn ($query) => $query->where('tmdb', '=', $this->tvdbId))
->when($this->imdbId !== null, fn ($query) => $query->where('imdb', '=', (int) (preg_match('/tt0*(?=(\d{7,}))/', $this->imdbId, $matches) ? $matches[1] : $this->imdbId)))
->when($this->tvdbId !== null, fn ($query) => $query->where('tvdb', '=', $this->tvdbId))
->when($this->malId !== null, fn ($query) => $query->where('mal', '=', $this->malId))
->when(
$this->genreIds !== [],
fn ($query) => $query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereIn('tmdb', DB::table('genre_movie')->select('movie_id')->whereIn('genre_id', $this->genreIds))
)
->orWhere(
fn ($query) => $query
->whereRelation('category', 'tv_meta', '=', true)
->whereIn('tmdb', DB::table('genre_tv')->select('tv_id')->whereIn('genre_id', $this->genreIds))
)
)
)
->when(
$this->primaryLanguageNames !== [],
fn ($query) => $query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereHas('movie', fn ($query) => $query->whereIn('original_language', $this->primaryLanguageNames))
)
->orWhere(
fn ($query) => $query
->whereRelation('category', 'tv_meta', '=', true)
->whereHas('tv', fn ($query) => $query->whereIn('original_language', $this->primaryLanguageNames))
)
)
)
->when($this->unfilled || $this->claimed || $this->pending || $this->filled, function ($query): void {
$query->where(function ($query): void {
$query->where(function ($query): void {
-2
View File
@@ -25,7 +25,6 @@ use App\Notifications\NewComment;
use App\Notifications\NewThank;
use App\Traits\Auditable;
use App\Traits\GroupedLastScope;
use App\Traits\TorrentFilter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
@@ -95,7 +94,6 @@ class Torrent extends Model
use HasFactory;
use Searchable;
use SoftDeletes;
use TorrentFilter;
protected $guarded = [];
-2
View File
@@ -19,7 +19,6 @@ namespace App\Models;
use App\Helpers\Bbcode;
use App\Helpers\Linkify;
use App\Traits\Auditable;
use App\Traits\TorrentFilter;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use voku\helper\AntiXSS;
@@ -58,7 +57,6 @@ class TorrentRequest extends Model
/** @use HasFactory<\Database\Factories\TorrentRequestFactory> */
use HasFactory;
use TorrentFilter;
/**
* The Database Table Used By The Model.
-594
View File
@@ -1,594 +0,0 @@
<?php
declare(strict_types=1);
/**
* NOTICE OF LICENSE.
*
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D Community Edition
*
* @author Roardom <roardom@protonmail.com>
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
*/
namespace App\Traits;
use App\Models\PlaylistTorrent;
use App\Models\Torrent;
use App\Models\TorrentRequest;
use App\Models\User;
use App\Models\Wish;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
trait TorrentFilter
{
/**
* @param Builder<Torrent|TorrentRequest> $query
*/
public function scopeOfName(Builder $query, string $name, bool $isRegex = false): void
{
$query->when(
$isRegex,
fn ($query) => $query->where('name', 'REGEXP', substr($name, 1, -1)),
fn ($query) => $query->where('name', 'LIKE', '%'.str_replace(' ', '%', $name).'%')
);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfDescription(Builder $query, string $description, bool $isRegex = false): void
{
$query->when(
$isRegex,
fn ($query) => $query->where('description', 'REGEXP', substr($description, 1, -1)),
fn ($query) => $query->where('description', 'LIKE', '%'.$description.'%')
);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfMediainfo(Builder $query, string $mediainfo, bool $isRegex = false): void
{
$query->when(
$isRegex,
fn ($query) => $query->where('mediainfo', 'REGEXP', substr($mediainfo, 1, -1)),
fn ($query) => $query->where('mediainfo', 'LIKE', '%'.$mediainfo.'%')
);
}
/**
* @param Builder<Torrent|TorrentRequest> $query
*/
public function scopeOfUploader(Builder $query, string $username, User $authenticatedUser = null): void
{
$authenticatedUser ??= auth()->user();
$query
->whereRelation('user', 'username', '=', $username)
->when(
$authenticatedUser === null,
fn ($query) => $query->where('anon', '=', false),
fn ($query) => $query->when(
!$authenticatedUser->group->is_modo,
fn ($query) => $query->where(fn ($query) => $query->where('anon', '=', false)->orWhere('user_id', '=', $authenticatedUser->id))
)
);
}
/**
* @param Builder<Torrent> $query
* @param array<string> $keywords
*/
public function scopeOfKeyword(Builder $query, array $keywords): void
{
$query->whereHas('keywords', fn ($query) => $query->whereIn('name', $keywords));
}
/**
* @param Builder<Torrent> $query
*/
public function scopeReleasedAfterOrIn(Builder $query, int $year): void
{
$query->where(function ($query) use ($year): void {
$query->where(function ($query) use ($year): void {
$query->whereRelation('movie', 'release_date', '>=', $year.'-01-01 00:00:00')
->whereRelation('category', 'movie_meta', '=', true);
})
->orWhere(function ($query) use ($year): void {
$query->whereRelation('tv', 'first_air_date', '>=', $year.'-01-01 00:00:00')
->whereRelation('category', 'tv_meta', '=', true);
});
});
}
/**
* @param Builder<Torrent> $query
*/
public function scopeReleasedBeforeOrIn(Builder $query, int $year): void
{
$query->where(function ($query) use ($year): void {
$query->where(function ($query) use ($year): void {
$query->whereRelation('movie', 'release_date', '<=', $year.'-12-31 23:59:59')
->whereRelation('category', 'movie_meta', '=', true);
})
->orWhere(function ($query) use ($year): void {
$query->orWhereRelation('tv', 'first_air_date', '<=', $year.'-12-31 23:59:59')
->whereRelation('category', 'tv_meta', '=', true);
});
});
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfSizeGreaterOrEqualTo(Builder $query, int $size): void
{
$query->where('size', '>=', $size);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfSizeLesserOrEqualTo(Builder $query, int $size): void
{
$query->where('size', '<=', $size);
}
/**
* @param Builder<Torrent|TorrentRequest> $query
* @param array<int> $categories
*/
public function scopeOfCategory(Builder $query, array $categories): void
{
$query->whereIntegerInRaw('category_id', $categories);
}
/**
* @param Builder<Torrent|TorrentRequest> $query
* @param array<int> $types
*/
public function scopeOfType(Builder $query, array $types): void
{
$query->whereIntegerInRaw('type_id', $types);
}
/**
* @param Builder<Torrent|TorrentRequest> $query
* @param array<int> $resolutions
*/
public function scopeOfResolution(Builder $query, array $resolutions): void
{
$query->whereIntegerInRaw('resolution_id', $resolutions);
}
/**
* @param Builder<Torrent> $query
* @param array<int> $genres
*/
public function scopeOfGenre(Builder $query, array $genres): void
{
$query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereIn('tmdb', DB::table('genre_movie')->select('movie_id')->whereIn('genre_id', $genres))
)
->orWhere(
fn ($query) => $query
->whereRelation('category', 'tv_meta', '=', true)
->whereIn('tmdb', DB::table('genre_tv')->select('tv_id')->whereIn('genre_id', $genres))
)
);
}
/**
* @param Builder<Torrent> $query
* @param array<int> $regions
*/
public function scopeOfRegion(Builder $query, array $regions): void
{
$query->where(
fn ($query) => $query
->whereIntegerInRaw('region_id', $regions)
->when(\in_array(0, $regions), fn ($query) => $query->orWhereNull('region_id'))
);
}
/**
* @param Builder<Torrent> $query
* @param array<int> $distributors
*/
public function scopeOfDistributor(Builder $query, array $distributors): void
{
$query->where(
fn ($query) => $query
->whereIntegerInRaw('distributor_id', $distributors)
->when(\in_array(0, $distributors), fn ($query) => $query->orWhereNull('distributor_id'))
);
}
/**
* @param Builder<Torrent|TorrentRequest> $query
*/
public function scopeOfTmdb(Builder $query, int $tvdbId): void
{
$query->where('tmdb', '=', $tvdbId);
}
/**
* @param Builder<Torrent|TorrentRequest> $query
*/
public function scopeOfImdb(Builder $query, int $tvdbId): void
{
$query->where('imdb', '=', $tvdbId);
}
/**
* @param Builder<Torrent|TorrentRequest> $query
*/
public function scopeOfTvdb(Builder $query, int $tvdbId): void
{
$query->where('tvdb', '=', $tvdbId);
}
/**
* @param Builder<Torrent|TorrentRequest> $query
*/
public function scopeOfMal(Builder $query, int $malId): void
{
$query->where('mal', '=', $malId);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfPlaylist(Builder $query, int $playlistId, ?User $authenticatedUser = null): void
{
$authenticatedUser ??= auth()->user();
$query->whereIn(
'id',
PlaylistTorrent::select('torrent_id')
->where('playlist_id', '=', $playlistId)
->when(
$authenticatedUser === null,
fn ($query) => $query->whereRelation('playlist', 'is_private', '=', false),
fn ($query) => $query->when(
! $authenticatedUser->group->is_modo,
fn ($query) => $query->where(fn ($query) => $query
->whereRelation('playlist', 'is_private', '=', false)
->orWhereRelation('playlist', 'user_id', '=', $authenticatedUser->id))
)
)
);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfCollection(Builder $query, int $collectionId): void
{
$query
->whereRelation('category', 'movie_meta', '=', true)
->whereIn('tmdb', DB::table('collection_movie')->select('movie_id')->where('collection_id', '=', $collectionId));
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfCompany(Builder $query, int $companyId): void
{
$query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereIn('tmdb', DB::table('company_movie')->select('movie_id')->where('company_id', '=', $companyId))
)
->orWhere(
fn ($query) => $query
->whereRelation('category', 'tv_meta', '=', true)
->whereIn('tmdb', DB::table('company_tv')->select('tv_id')->where('company_id', '=', $companyId))
)
);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfNetwork(Builder $query, int $networkId): void
{
$query
->whereRelation('category', 'tv_meta', '=', true)
->whereIn('tmdb', DB::table('network_tv')->select('tv_id')->where('network_id', '=', $networkId));
}
/**
* @param Builder<Torrent> $query
* @param int|array<int> $free
*/
public function scopeOfFreeleech(Builder $query, int|array $free): void
{
$query->when(
config('other.freeleech'),
fn ($query) => $query->whereBetween('free', [0, 100]),
fn ($query) => $query->whereIntegerInRaw('free', (array) $free)
);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeDoubleup(Builder $query): void
{
$query->where('doubleup', '=', 1);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeFeatured(Builder $query): void
{
$query->where('featured', '=', 1);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeRefundable(Builder $query): void
{
$query->where('refundable', '=', true);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeStreamOptimized(Builder $query): void
{
$query->where('stream', '=', 1);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeSd(Builder $query): void
{
$query->where('sd', '=', 1);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeHighSpeed(Builder $query): void
{
$query->where('highspeed', '=', 1);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeBookmarkedBy(Builder $query, User $user): void
{
$query->whereRelation('bookmarks', 'user_id', '=', $user->id);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeWishedBy(Builder $query, User $user): void
{
$query->whereIn('tmdb', Wish::select('tmdb')->where('user_id', '=', $user->id));
}
/**
* @param Builder<Torrent> $query
*/
public function scopeInternal(Builder $query): void
{
$query->where('internal', '=', 1);
}
/**
* @param Builder<Torrent> $query
*/
public function scopePersonalRelease(Builder $query): void
{
$query->where('personal_release', '=', 1);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeTrumpable(Builder $query): void
{
$query->has('trump');
}
/**
* @param Builder<Torrent> $query
*/
public function scopeAlive(Builder $query): void
{
$query->where('seeders', '>', 0);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeDying(Builder $query): void
{
$query
->where('seeders', '=', 1)
->where('times_completed', '>=', 3);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeDead(Builder $query): void
{
$query->where('seeders', '=', 0);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeGraveyard(Builder $query): void
{
$query->where('seeders', '=', 0)->where('created_at', '<', Carbon::now()->subDays(30));
}
/**
* @param Builder<Torrent> $query
*/
public function scopeNotDownloadedBy(Builder $query, User $user): void
{
$query
->whereDoesntHave(
'history',
fn ($query) => $query
->where('user_id', '=', $user->id)
);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeDownloadedBy(Builder $query, User $user): void
{
$query->whereRelation('history', 'user_id', '=', $user->id);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeSeededBy(Builder $query, User $user): void
{
$query
->whereHas(
'history',
fn ($query) => $query
->where('user_id', '=', $user->id)
->where('active', '=', 1)
->where('seeder', '=', 1)
);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeLeechedby(Builder $query, User $user): void
{
$query
->whereHas(
'history',
fn ($query) => $query
->where('user_id', '=', $user->id)
->where('active', '=', 1)
->where('seeder', '=', 0)
);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeUncompletedBy(Builder $query, User $user): void
{
$query
->whereHas(
'history',
fn ($query) => $query
->where('user_id', '=', $user->id)
->where('active', '=', 0)
->where('seeder', '=', 0)
->where('seedtime', '=', 0)
);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfFilename(Builder $query, string $filename): void
{
$query->whereRelation('files', 'name', '=', $filename);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfSeason(Builder $query, int $seasonNumber): void
{
$query->where('season_number', '=', $seasonNumber);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfEpisode(Builder $query, int $episodeNumber): void
{
$query->where('episode_number', '=', $episodeNumber);
}
/**
* @param Builder<Torrent> $query
* @param array<string> $languages
*/
public function scopeOfPrimaryLanguage(Builder $query, array $languages): void
{
$query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereHas('movie', fn ($query) => $query->whereIn('original_language', $languages))
)
->orWhere(
fn ($query) => $query
->whereRelation('category', 'tv_meta', '=', true)
->whereHas('tv', fn ($query) => $query->whereIn('original_language', $languages))
)
);
}
/**
* @param Builder<Torrent> $query
*/
public function scopeOfAdult(Builder $query, ?bool $isAdult = null): void
{
// Currently, only movies have an `adult` column.
$query
->when(
$isAdult === true,
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereRelation('movie', 'adult', '=', true),
)
->when(
$isAdult === false,
fn ($query) => $query
->where(
fn ($query) => $query
->where(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', true)
->whereRelation('movie', 'adult', '=', false)
)
->orWhere(
fn ($query) => $query
->whereRelation('category', 'movie_meta', '=', false)
)
)
);
}
}