mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
basic filter D:
This commit is contained in:
@@ -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
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 '<pre>';
|
||||
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
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user