basic filter D:

This commit is contained in:
Lars Behrends
2025-10-24 17:12:36 +02:00
parent 218d0c28c0
commit e78c073f21
13 changed files with 1811 additions and 1120 deletions

View File

@@ -25,59 +25,92 @@ class AdultVideo extends Model
'external_id'
];
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = ''): array
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = '', array $genres = [], array $directors = []): array
{
$offset = ($page - 1) * $perPage;
$whereClause = '';
$params = [];
if (!empty($search)) {
$whereClause = "WHERE (title LIKE :search OR overview LIKE :search)";
$params['search'] = "%{$search}%";
}
$sql = "
SELECT av.*, s.display_name as source_name
FROM adult_videos av
JOIN sources s ON av.source_id = s.id
{$whereClause}
ORDER BY av.created_at DESC
LIMIT :limit OFFSET :offset
";
$params = [];
if (!empty($search)) {
$sql .= " WHERE (av.title LIKE :search OR av.overview LIKE :search)";
$params['search'] = "%{$search}%";
}
if (!empty($genres)) {
$placeholders = [];
foreach ($genres as $index => $genre) {
$placeholders[] = ":genre_{$index}";
$params["genre_{$index}"] = $genre;
}
$whereClause = !empty($search) ? " AND" : " WHERE";
$sql .= $whereClause . " av.genre IN (" . implode(',', $placeholders) . ")";
}
if (!empty($directors)) {
$placeholders = [];
foreach ($directors as $index => $director) {
$placeholders[] = ":director_{$index}";
$params["director_{$index}"] = $director;
}
$whereClause = (!empty($search) || !empty($genres)) ? " AND" : " WHERE";
$sql .= $whereClause . " av.director IN (" . implode(',', $placeholders) . ")";
}
$sql .= " ORDER BY av.created_at DESC LIMIT :limit OFFSET :offset";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':limit', $perPage, \PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, \PDO::PARAM_INT);
if (!empty($search)) {
$stmt->bindValue(':search', "%{$search}%", \PDO::PARAM_STR);
foreach ($params as $key => $value) {
$stmt->bindValue(":{$key}", $value);
}
$stmt->execute();
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
public static function getTotalCount(\PDO $pdo, string $search = ''): int
public static function getTotalCount(\PDO $pdo, string $search = '', array $genres = [], array $directors = []): int
{
$whereClause = '';
$sql = "SELECT COUNT(*) as count FROM adult_videos av JOIN sources s ON av.source_id = s.id";
$params = [];
if (!empty($search)) {
$whereClause = "WHERE (title LIKE :search OR overview LIKE :search)";
$sql .= " WHERE (av.title LIKE :search OR av.overview LIKE :search)";
$params['search'] = "%{$search}%";
}
$sql = "SELECT COUNT(*) as count FROM adult_videos {$whereClause}";
$stmt = $pdo->prepare($sql);
if (!empty($search)) {
$stmt->bindValue(':search', "%{$search}%", \PDO::PARAM_STR);
if (!empty($genres)) {
$placeholders = [];
foreach ($genres as $index => $genre) {
$placeholders[] = ":genre_{$index}";
$params["genre_{$index}"] = $genre;
}
$whereClause = !empty($search) ? " AND" : " WHERE";
$sql .= $whereClause . " av.genre IN (" . implode(',', $placeholders) . ")";
}
if (!empty($directors)) {
$placeholders = [];
foreach ($directors as $index => $director) {
$placeholders[] = ":director_{$index}";
$params["director_{$index}"] = $director;
}
$whereClause = (!empty($search) || !empty($genres)) ? " AND" : " WHERE";
$sql .= $whereClause . " av.director IN (" . implode(',', $placeholders) . ")";
}
$stmt = $pdo->prepare($sql);
foreach ($params as $key => $value) {
$stmt->bindValue(":{$key}", $value);
}
$stmt->execute();
return (int) $stmt->fetch(\PDO::FETCH_ASSOC)['count'];
return (int) $stmt->fetch()['count'];
}
public function markAsWatched(): bool
@@ -181,4 +214,32 @@ class AdultVideo extends Model
");
return $stmt->fetch(\PDO::FETCH_ASSOC);
}
/**
* Get available genres for filtering
*/
public static function getAvailableGenres(\PDO $pdo): array
{
$stmt = $pdo->query("
SELECT DISTINCT genre
FROM adult_videos
WHERE genre IS NOT NULL AND genre != ''
ORDER BY genre
");
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
}
/**
* Get available directors for filtering
*/
public static function getAvailableDirectors(\PDO $pdo): array
{
$stmt = $pdo->query("
SELECT DISTINCT director
FROM adult_videos
WHERE director IS NOT NULL AND director != ''
ORDER BY director
");
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
}
}

View File

@@ -262,16 +262,34 @@ class Game extends Model
/**
* Get total count of games for pagination
*/
public static function getTotalCount(\PDO $pdo, string $search = ''): int
public static function getTotalCount(\PDO $pdo, string $search = '', array $genres = [], array $platforms = []): int
{
$sql = "SELECT COUNT(*) as count FROM games";
$sql = "SELECT COUNT(*) as count FROM games WHERE game_key IS NOT NULL";
$params = [];
if (!empty($search)) {
$sql .= " WHERE title LIKE :search";
$sql .= " AND title LIKE :search";
$params['search'] = "%{$search}%";
}
if (!empty($genres)) {
$placeholders = [];
foreach ($genres as $index => $genre) {
$placeholders[] = ":genre_{$index}";
$params["genre_{$index}"] = $genre;
}
$sql .= " AND genre IN (" . implode(',', $placeholders) . ")";
}
if (!empty($platforms)) {
$placeholders = [];
foreach ($platforms as $index => $platform) {
$placeholders[] = ":platform_{$index}";
$params["platform_{$index}"] = $platform;
}
$sql .= " AND platform IN (" . implode(',', $placeholders) . ")";
}
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
return (int) $stmt->fetch()['count'];
@@ -280,7 +298,7 @@ class Game extends Model
/**
* Get grouped games with pagination and search support
*/
public static function getGroupedGamesWithPagination(\PDO $pdo, int $page, int $perPage, string $search = ''): array
public static function getGroupedGamesWithPagination(\PDO $pdo, int $page, int $perPage, string $search = '', array $genres = [], array $platforms = []): array
{
$offset = ($page - 1) * $perPage;
@@ -307,6 +325,24 @@ class Game extends Model
$params['search'] = "%{$search}%";
}
if (!empty($genres)) {
$placeholders = [];
foreach ($genres as $index => $genre) {
$placeholders[] = ":genre_{$index}";
$params["genre_{$index}"] = $genre;
}
$sql .= " AND genre IN (" . implode(',', $placeholders) . ")";
}
if (!empty($platforms)) {
$placeholders = [];
foreach ($platforms as $index => $platform) {
$placeholders[] = ":platform_{$index}";
$params["platform_{$index}"] = $platform;
}
$sql .= " AND platform IN (" . implode(',', $placeholders) . ")";
}
$sql .= " GROUP BY game_key, title ORDER BY last_played_at DESC, total_playtime DESC LIMIT :limit OFFSET :offset";
$stmt = $pdo->prepare($sql);
@@ -379,51 +415,31 @@ class Game extends Model
}
/**
* Get Playnite-specific series
* Get available genres for filtering
*/
public function getSeries(): array
public static function getAvailableGenres(\PDO $pdo): array
{
return $this->series_json ?? [];
$stmt = $pdo->query("
SELECT DISTINCT genre
FROM games
WHERE genre IS NOT NULL AND genre != ''
ORDER BY genre
");
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
}
/**
* Get Playnite-specific age ratings
* Get available platforms for filtering
*/
public function getAgeRatings(): array
public static function getAvailablePlatforms(\PDO $pdo): array
{
return $this->age_ratings_json ?? [];
}
/**
* Get formatted install size
*/
public function getFormattedInstallSize(): string
{
if (!$this->install_size) {
return 'Unknown';
}
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = $this->install_size;
$i = 0;
while ($bytes >= 1024 && $i < count($units) - 1) {
$bytes /= 1024;
$i++;
}
return round($bytes, 2) . ' ' . $units[$i];
}
/**
* Get Steam store URL if available
*/
public function getSteamUrl(): ?string
{
if (!$this->steam_app_id) {
return null;
}
return "https://store.steampowered.com/app/{$this->steam_app_id}";
$stmt = $pdo->query("
SELECT DISTINCT platform
FROM games
WHERE platform IS NOT NULL AND platform != ''
ORDER BY platform
");
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
}
/**
@@ -435,4 +451,3 @@ class Game extends Model
!empty($this->links_json) || !empty($this->background_image);
}
}

View File

@@ -109,22 +109,45 @@ class Movie extends Model
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
public static function getTotalCount(\PDO $pdo, string $search = ''): int
public static function getTotalCount(\PDO $pdo, string $search = '', array $genres = [], array $directors = []): int
{
$sql = "SELECT COUNT(*) as count FROM movies m JOIN sources s ON m.source_id = s.id";
$params = [];
if (!empty($search)) {
$sql .= " WHERE m.title LIKE :search";
$sql .= " WHERE (m.title LIKE :search OR m.overview LIKE :search)";
$params['search'] = "%{$search}%";
}
if (!empty($genres)) {
$placeholders = [];
foreach ($genres as $index => $genre) {
$placeholders[] = ":genre_{$index}";
$params["genre_{$index}"] = $genre;
}
$whereClause = !empty($search) ? " AND" : " WHERE";
$sql .= $whereClause . " m.genre IN (" . implode(',', $placeholders) . ")";
}
if (!empty($directors)) {
$placeholders = [];
foreach ($directors as $index => $director) {
$placeholders[] = ":director_{$index}";
$params["director_{$index}"] = $director;
}
$whereClause = (!empty($search) || !empty($genres)) ? " AND" : " WHERE";
$sql .= $whereClause . " m.director IN (" . implode(',', $placeholders) . ")";
}
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
foreach ($params as $key => $value) {
$stmt->bindValue(":{$key}", $value);
}
$stmt->execute();
return (int) $stmt->fetch()['count'];
}
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = ''): array
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = '', array $genres = [], array $directors = []): array
{
$offset = ($page - 1) * $perPage;
@@ -136,10 +159,30 @@ class Movie extends Model
$params = [];
if (!empty($search)) {
$sql .= " WHERE m.title LIKE :search";
$sql .= " WHERE (m.title LIKE :search OR m.overview LIKE :search)";
$params['search'] = "%{$search}%";
}
if (!empty($genres)) {
$placeholders = [];
foreach ($genres as $index => $genre) {
$placeholders[] = ":genre_{$index}";
$params["genre_{$index}"] = $genre;
}
$whereClause = !empty($search) ? " AND" : " WHERE";
$sql .= $whereClause . " m.genre IN (" . implode(',', $placeholders) . ")";
}
if (!empty($directors)) {
$placeholders = [];
foreach ($directors as $index => $director) {
$placeholders[] = ":director_{$index}";
$params["director_{$index}"] = $director;
}
$whereClause = (!empty($search) || !empty($genres)) ? " AND" : " WHERE";
$sql .= $whereClause . " m.director IN (" . implode(',', $placeholders) . ")";
}
$sql .= " ORDER BY m.title ASC LIMIT :limit OFFSET :offset";
$stmt = $pdo->prepare($sql);
@@ -226,4 +269,32 @@ class Movie extends Model
'cast' => $castString
]);
}
/**
* Get available genres for filtering
*/
public static function getAvailableGenres(\PDO $pdo): array
{
$stmt = $pdo->query("
SELECT DISTINCT genre
FROM movies
WHERE genre IS NOT NULL AND genre != ''
ORDER BY genre
");
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
}
/**
* Get available directors for filtering
*/
public static function getAvailableDirectors(\PDO $pdo): array
{
$stmt = $pdo->query("
SELECT DISTINCT director
FROM movies
WHERE director IS NOT NULL AND director != ''
ORDER BY director
");
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
}
}

View File

@@ -83,7 +83,7 @@ class TvShow extends Model
/**
* Get total count with optional search
*/
public static function getTotalCount(\PDO $pdo, string $search = ''): int
public static function getTotalCount(\PDO $pdo, string $search = '', array $genres = [], array $years = []): int
{
$sql = "SELECT COUNT(*) as count FROM tv_shows t JOIN sources s ON t.source_id = s.id";
$params = [];
@@ -93,15 +93,38 @@ class TvShow extends Model
$params['search'] = "%{$search}%";
}
if (!empty($genres)) {
$placeholders = [];
foreach ($genres as $index => $genre) {
$placeholders[] = ":genre_{$index}";
$params["genre_{$index}"] = $genre;
}
$whereClause = !empty($search) ? " AND" : " WHERE";
$sql .= $whereClause . " t.genre IN (" . implode(',', $placeholders) . ")";
}
if (!empty($years)) {
$placeholders = [];
foreach ($years as $index => $year) {
$placeholders[] = ":year_{$index}";
$params["year_{$index}"] = $year;
}
$whereClause = (!empty($search) || !empty($genres)) ? " AND" : " WHERE";
$sql .= $whereClause . " YEAR(first_air_date) IN (" . implode(',', $placeholders) . ")";
}
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
foreach ($params as $key => $value) {
$stmt->bindValue(":{$key}", $value);
}
$stmt->execute();
return (int) $stmt->fetch()['count'];
}
/**
* Get all TV shows with pagination and optional search
*/
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = ''): array
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = '', array $genres = [], array $years = []): array
{
$offset = ($page - 1) * $perPage;
@@ -117,6 +140,26 @@ class TvShow extends Model
$params['search'] = "%{$search}%";
}
if (!empty($genres)) {
$placeholders = [];
foreach ($genres as $index => $genre) {
$placeholders[] = ":genre_{$index}";
$params["genre_{$index}"] = $genre;
}
$whereClause = !empty($search) ? " AND" : " WHERE";
$sql .= $whereClause . " t.genre IN (" . implode(',', $placeholders) . ")";
}
if (!empty($years)) {
$placeholders = [];
foreach ($years as $index => $year) {
$placeholders[] = ":year_{$index}";
$params["year_{$index}"] = $year;
}
$whereClause = (!empty($search) || !empty($genres)) ? " AND" : " WHERE";
$sql .= $whereClause . " YEAR(first_air_date) IN (" . implode(',', $placeholders) . ")";
}
$sql .= " ORDER BY t.title ASC LIMIT :limit OFFSET :offset";
$stmt = $pdo->prepare($sql);
@@ -259,9 +302,8 @@ public function recordView(): bool
public static function getAvailableGenres(\PDO $pdo): array
{
$stmt = $pdo->query("
SELECT DISTINCT TRIM(value) as genre
FROM tv_shows,
json_each('[\"' || REPLACE(genre, ',', '\",\"') || '\"]')
SELECT DISTINCT genre
FROM tv_shows
WHERE genre IS NOT NULL AND genre != ''
ORDER BY genre
");
@@ -274,7 +316,7 @@ public static function getAvailableGenres(\PDO $pdo): array
public static function getAvailableYears(\PDO $pdo): array
{
$stmt = $pdo->query("
SELECT DISTINCT strftime('%Y', first_air_date) as year
SELECT DISTINCT YEAR(first_air_date) as year
FROM tv_shows
WHERE first_air_date IS NOT NULL
ORDER BY year DESC