diff --git a/app/Controllers/AdultController.php b/app/Controllers/AdultController.php index 85b3bb9..45fc00f 100644 --- a/app/Controllers/AdultController.php +++ b/app/Controllers/AdultController.php @@ -28,11 +28,24 @@ class AdultController extends Controller // Get search parameters $search = trim($queryParams['search'] ?? ''); + // Get filter parameters + $genres = $queryParams['genres'] ?? []; + if (!is_array($genres)) { + $genres = [$genres]; + } + $genres = array_filter($genres); + + $directors = $queryParams['directors'] ?? []; + if (!is_array($directors)) { + $directors = [$directors]; + } + $directors = array_filter($directors); + // Get view mode $viewMode = $queryParams['view'] ?? 'grid'; // grid, list, covers - // Get adult videos with pagination and search - $adultVideos = AdultVideo::getAllWithPagination($this->pdo, $page, $perPage, $search); + // Get adult videos with pagination and filters + $adultVideos = AdultVideo::getAllWithPagination($this->pdo, $page, $perPage, $search, $genres, $directors); // Process metadata to extract local image paths for template compatibility foreach ($adultVideos as &$video) { @@ -54,7 +67,11 @@ class AdultController extends Controller } // Get total count for pagination - $totalCount = AdultVideo::getTotalCount($this->pdo, $search); + $totalCount = AdultVideo::getTotalCount($this->pdo, $search, $genres, $directors); + + // Get available filter options + $availableGenres = AdultVideo::getAvailableGenres($this->pdo); + $availableDirectors = AdultVideo::getAvailableDirectors($this->pdo); // Calculate pagination info $totalPages = ceil($totalCount / $perPage); @@ -76,7 +93,15 @@ class AdultController extends Controller ], 'search' => $search, 'view_mode' => $viewMode, - 'view_modes' => ['grid', 'list', 'covers'] + 'view_modes' => ['grid', 'list', 'covers'], + 'filters' => [ + 'genres' => $genres, + 'directors' => $directors + ], + 'available_filters' => [ + 'genres' => $availableGenres, + 'directors' => $availableDirectors + ] ]); } diff --git a/app/Controllers/GameController.php b/app/Controllers/GameController.php index 846b92d..dee3c59 100644 --- a/app/Controllers/GameController.php +++ b/app/Controllers/GameController.php @@ -28,14 +28,31 @@ class GameController extends Controller // Get search parameters $search = trim($queryParams['search'] ?? ''); + // Get filter parameters + $genres = $queryParams['genres'] ?? []; + if (!is_array($genres)) { + $genres = [$genres]; + } + $genres = array_filter($genres); + + $platforms = $queryParams['platforms'] ?? []; + if (!is_array($platforms)) { + $platforms = [$platforms]; + } + $platforms = array_filter($platforms); + // Get view mode $viewMode = $queryParams['view'] ?? 'grid'; // grid, list, covers - // Get games with pagination and search - $games = Game::getGroupedGamesWithPagination($this->pdo, $page, $perPage, $search); + // Get games with pagination and filters + $games = Game::getGroupedGamesWithPagination($this->pdo, $page, $perPage, $search, $genres, $platforms); // Get total count for pagination - $totalCount = Game::getTotalCount($this->pdo, $search); + $totalCount = Game::getTotalCount($this->pdo, $search, $genres, $platforms); + + // Get available filter options + $availableGenres = Game::getAvailableGenres($this->pdo); + $availablePlatforms = Game::getAvailablePlatforms($this->pdo); // Calculate pagination info $totalPages = ceil($totalCount / $perPage); @@ -57,7 +74,15 @@ class GameController extends Controller ], 'search' => $search, 'view_mode' => $viewMode, - 'view_modes' => ['grid', 'list', 'covers'] + 'view_modes' => ['grid', 'list', 'covers'], + 'filters' => [ + 'genres' => $genres, + 'platforms' => $platforms + ], + 'available_filters' => [ + 'genres' => $availableGenres, + 'platforms' => $availablePlatforms + ] ]); } diff --git a/app/Controllers/MovieController.php b/app/Controllers/MovieController.php index e020ac6..32d71a9 100644 --- a/app/Controllers/MovieController.php +++ b/app/Controllers/MovieController.php @@ -28,14 +28,31 @@ class MovieController extends Controller // Get search parameters $search = trim($queryParams['search'] ?? ''); + // Get filter parameters + $genres = $queryParams['genres'] ?? []; + if (!is_array($genres)) { + $genres = [$genres]; + } + $genres = array_filter($genres); + + $directors = $queryParams['directors'] ?? []; + if (!is_array($directors)) { + $directors = [$directors]; + } + $directors = array_filter($directors); + // Get view mode $viewMode = $queryParams['view'] ?? 'grid'; // grid, list, covers - // Get movies with pagination and search - $movies = Movie::getAllWithPagination($this->pdo, $page, $perPage, $search); + // Get movies with pagination and filters + $movies = Movie::getAllWithPagination($this->pdo, $page, $perPage, $search, $genres, $directors); // Get total count for pagination - $totalCount = Movie::getTotalCount($this->pdo, $search); + $totalCount = Movie::getTotalCount($this->pdo, $search, $genres, $directors); + + // Get available filter options + $availableGenres = Movie::getAvailableGenres($this->pdo); + $availableDirectors = Movie::getAvailableDirectors($this->pdo); // Calculate pagination info $totalPages = ceil($totalCount / $perPage); @@ -57,7 +74,15 @@ class MovieController extends Controller ], 'search' => $search, 'view_mode' => $viewMode, - 'view_modes' => ['grid', 'list', 'covers'] + 'view_modes' => ['grid', 'list', 'covers'], + 'filters' => [ + 'genres' => $genres, + 'directors' => $directors + ], + 'available_filters' => [ + 'genres' => $availableGenres, + 'directors' => $availableDirectors + ] ]); } diff --git a/app/Controllers/TvShowController.php b/app/Controllers/TvShowController.php index 8847311..edb0130 100644 --- a/app/Controllers/TvShowController.php +++ b/app/Controllers/TvShowController.php @@ -28,24 +28,37 @@ class TvShowController extends Controller // Get search parameters $search = trim($queryParams['search'] ?? ''); + // Get filter parameters + $genres = $queryParams['genres'] ?? []; + if (!is_array($genres)) { + $genres = [$genres]; + } + $genres = array_filter($genres); + + $years = $queryParams['years'] ?? []; + if (!is_array($years)) { + $years = [$years]; + } + $years = array_filter($years); + // Get view mode $viewMode = $queryParams['view'] ?? 'grid'; // grid, list, covers - // Get TV shows with pagination and search - $tvshows = TvShow::getAllWithPagination($this->pdo, $page, $perPage, $search); + // Get TV shows with pagination and filters + $tvshows = TvShow::getAllWithPagination($this->pdo, $page, $perPage, $search, $genres, $years); // Get total count for pagination - $totalCount = TvShow::getTotalCount($this->pdo, $search); + $totalCount = TvShow::getTotalCount($this->pdo, $search, $genres, $years); + + // Get available filter options + $availableGenres = TvShow::getAvailableGenres($this->pdo); + $availableYears = TvShow::getAvailableYears($this->pdo); // Calculate pagination info $totalPages = ceil($totalCount / $perPage); $hasNextPage = $page < $totalPages; $hasPrevPage = $page > 1; -/* - echo '
';
- print_r($tvshows);
- die();
-*/
+
return $this->view->render($response, 'tvshows/index.twig', [
'title' => 'TV Shows',
'tvshows' => $tvshows,
@@ -61,7 +74,15 @@ class TvShowController extends Controller
],
'search' => $search,
'view_mode' => $viewMode,
- 'view_modes' => ['grid', 'list', 'covers']
+ 'view_modes' => ['grid', 'list', 'covers'],
+ 'filters' => [
+ 'genres' => $genres,
+ 'years' => $years
+ ],
+ 'available_filters' => [
+ 'genres' => $availableGenres,
+ 'years' => $availableYears
+ ]
]);
}
diff --git a/app/Models/AdultVideo.php b/app/Models/AdultVideo.php
index 0e0e0da..e6cdc0c 100644
--- a/app/Models/AdultVideo.php
+++ b/app/Models/AdultVideo.php
@@ -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);
+ }
}
diff --git a/app/Models/Game.php b/app/Models/Game.php
index 313d049..ac3fdc6 100644
--- a/app/Models/Game.php
+++ b/app/Models/Game.php
@@ -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);
}
}
-
diff --git a/app/Models/Movie.php b/app/Models/Movie.php
index b121005..a67822a 100644
--- a/app/Models/Movie.php
+++ b/app/Models/Movie.php
@@ -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);
+ }
}
diff --git a/app/Models/TvShow.php b/app/Models/TvShow.php
index 67113cf..398cc54 100644
--- a/app/Models/TvShow.php
+++ b/app/Models/TvShow.php
@@ -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
diff --git a/app/Services/PlayniteImportService.php b/app/Services/PlayniteImportService.php
index de903a8..3bdfd12 100644
--- a/app/Services/PlayniteImportService.php
+++ b/app/Services/PlayniteImportService.php
@@ -75,6 +75,7 @@ class PlayniteImportService
*/
private function transformPlayniteGame(array $game, int $index): array
{
+ /*
// Validate required fields
if (empty($game['Name'])) {
throw new \Exception("Missing game name");
@@ -83,7 +84,7 @@ class PlayniteImportService
if (empty($game['GameId'])) {
throw new \Exception("Missing GameId");
}
-
+*/
// Find or create source
$source = $this->findOrCreateSource($game);
@@ -132,10 +133,10 @@ class PlayniteImportService
'steam_app_id' => $this->extractSteamAppId($game),
// Playnite-specific metadata
- 'is_installed' => $game['IsInstalled'] ?? false,
- 'is_favorite' => $game['Favorite'] ?? false,
- 'is_custom_game' => $game['IsCustomGame'] ?? false,
- 'installation_status' => $game['InstallationStatus'] ?? 0,
+ // 'is_installed' => $this->toBoolean($game['IsInstalled'] ?? false),
+ //'is_favorite' => $this->toBoolean($game['Favorite'] ?? false),
+ //'is_custom_game' => $this->toBoolean($game['IsCustomGame'] ?? false),
+ //'installation_status' => $game['InstallationStatus'] ?? 0,
// Timestamps
'added_at' => isset($game['Added']) ? date('Y-m-d H:i:s', strtotime($game['Added'])) : null,
@@ -147,20 +148,20 @@ class PlayniteImportService
'metadata' => json_encode([
'playnite_id' => $game['Id'] ?? null,
'version' => $game['Version'] ?? null,
- 'hidden' => $game['Hidden'] ?? false,
+ 'hidden' => $this->toBoolean($game['Hidden'] ?? false),
'notes' => $game['Notes'] ?? null,
'manual' => $game['Manual'] ?? null,
'pre_script' => $game['PreScript'] ?? null,
'post_script' => $game['PostScript'] ?? null,
'game_started_script' => $game['GameStartedScript'] ?? null,
'use_global_scripts' => [
- 'pre' => $game['UseGlobalPreScript'] ?? true,
- 'post' => $game['UseGlobalPostScript'] ?? true,
- 'game_started' => $game['UseGlobalGameStartedScript'] ?? true
+ 'pre' => $this->toBoolean($game['UseGlobalPreScript'] ?? true),
+ 'post' => $this->toBoolean($game['UseGlobalPostScript'] ?? true),
+ 'game_started' => $this->toBoolean($game['UseGlobalGameStartedScript'] ?? true)
]
])
];
-
+
return $transformed;
}
@@ -371,4 +372,21 @@ class PlayniteImportService
$gameModel = new Game($this->pdo);
$gameModel->update($gameId, $gameData);
}
+
+ /**
+ * Convert a value to boolean, handling empty strings properly
+ */
+ private function toBoolean($value): bool
+ {
+ if ($value === null || $value === false || $value === 0 || $value === '0') {
+ return false;
+ }
+ if ($value === true || $value === 1 || $value === '1') {
+ return true;
+ }
+ if (is_string($value)) {
+ return !empty(trim($value));
+ }
+ return (bool) $value;
+ }
}
diff --git a/resources/views/adult/index.twig b/resources/views/adult/index.twig
index fff684f..4e03bc0 100644
--- a/resources/views/adult/index.twig
+++ b/resources/views/adult/index.twig
@@ -1,299 +1,387 @@
{% extends "layouts/app.twig" %}
{% block content %}
-
-
-
-
- Adult Videos
- {% if pagination.total_items > 0 %}
-
- {{ pagination.total_items }} videos
- {% if search %}
- matching "{{ search }}"
- {% endif %}
-
- {% endif %}
-
-
-
-
-