mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
280 lines
8.6 KiB
PHP
280 lines
8.6 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
class AdultVideo extends Model
|
|
{
|
|
protected string $table = 'adult_videos';
|
|
protected array $fillable = [
|
|
'title',
|
|
'overview',
|
|
'poster_url',
|
|
'backdrop_url',
|
|
'rating',
|
|
'runtime_minutes',
|
|
'release_date',
|
|
'director',
|
|
'writer',
|
|
'cast',
|
|
'genre',
|
|
'metadata',
|
|
'watched',
|
|
'watch_count',
|
|
'is_favorite',
|
|
'source_id',
|
|
'external_id'
|
|
];
|
|
|
|
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = '', array $genres = [], array $directors = [], string $sort = 'recent'): array
|
|
{
|
|
$offset = ($page - 1) * $perPage;
|
|
|
|
$sql = "
|
|
SELECT av.*, s.display_name as source_name
|
|
FROM adult_videos av
|
|
JOIN sources s ON av.source_id = s.id
|
|
";
|
|
$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) . ")";
|
|
}
|
|
|
|
// Add sorting
|
|
$sortOptions = [
|
|
'recent' => 'av.created_at DESC',
|
|
'oldest' => 'av.created_at ASC',
|
|
'title_asc' => 'av.title ASC',
|
|
'title_desc' => 'av.title DESC',
|
|
'year_asc' => 'av.release_date ASC',
|
|
'year_desc' => 'av.release_date DESC',
|
|
'rating_asc' => 'av.rating ASC',
|
|
'rating_desc' => 'av.rating DESC',
|
|
'views_asc' => 'av.watch_count ASC',
|
|
'views_desc' => 'av.watch_count DESC',
|
|
'runtime_asc' => 'av.runtime_minutes ASC',
|
|
'runtime_desc' => 'av.runtime_minutes DESC',
|
|
];
|
|
|
|
$sortOrder = $sortOptions[$sort] ?? $sortOptions['recent'];
|
|
$sql .= " ORDER BY " . $sortOrder . " LIMIT :limit OFFSET :offset";
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->bindValue(':limit', $perPage, \PDO::PARAM_INT);
|
|
$stmt->bindValue(':offset', $offset, \PDO::PARAM_INT);
|
|
|
|
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 = '', array $genres = [], array $directors = []): int
|
|
{
|
|
$sql = "SELECT COUNT(*) as count FROM adult_videos av JOIN sources s ON av.source_id = s.id";
|
|
$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) . ")";
|
|
}
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
foreach ($params as $key => $value) {
|
|
$stmt->bindValue(":{$key}", $value);
|
|
}
|
|
$stmt->execute();
|
|
return (int) $stmt->fetch()['count'];
|
|
}
|
|
|
|
public function markAsWatched(): bool
|
|
{
|
|
$stmt = $this->pdo->prepare("UPDATE adult_videos SET watched = 1, watch_count = watch_count + 1, updated_at = NOW() WHERE id = :id");
|
|
return $stmt->execute(['id' => $this->id]);
|
|
}
|
|
|
|
public function markAsUnwatched(): bool
|
|
{
|
|
$stmt = $this->pdo->prepare("UPDATE adult_videos SET watched = 0, updated_at = NOW() WHERE id = :id");
|
|
return $stmt->execute(['id' => $this->id]);
|
|
}
|
|
|
|
public function toggleFavorite(): bool
|
|
{
|
|
$stmt = $this->pdo->prepare("UPDATE adult_videos SET is_favorite = !is_favorite, updated_at = NOW() WHERE id = :id");
|
|
return $stmt->execute(['id' => $this->id]);
|
|
}
|
|
|
|
public function source(): ?Source
|
|
{
|
|
$stmt = $this->pdo->prepare("SELECT * FROM sources WHERE id = :source_id");
|
|
$stmt->execute(['source_id' => $this->source_id]);
|
|
$sourceData = $stmt->fetch(\PDO::FETCH_ASSOC);
|
|
|
|
return $sourceData ? new Source($this->pdo, $sourceData) : null;
|
|
}
|
|
|
|
/**
|
|
* Get all actors associated with this adult video
|
|
*/
|
|
public function actors($args)
|
|
{
|
|
$stmt = $this->pdo->prepare("
|
|
SELECT a.*
|
|
FROM actors a
|
|
JOIN actor_adult_video aav ON a.id = aav.actor_id
|
|
WHERE aav.adult_video_id = :adult_video_id
|
|
ORDER BY a.name ASC
|
|
");
|
|
$stmt->execute(['adult_video_id' => $args]);
|
|
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
/**
|
|
* Add an actor to this adult video
|
|
*/
|
|
public function addActor(int $actorId): bool
|
|
{
|
|
$stmt = $this->pdo->prepare("
|
|
INSERT IGNORE INTO actor_adult_video (adult_video_id, actor_id)
|
|
VALUES (:adult_video_id, :actor_id)
|
|
");
|
|
return $stmt->execute([
|
|
'adult_video_id' => $this->id,
|
|
'actor_id' => $actorId
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Remove an actor from this adult video
|
|
*/
|
|
public function removeActor(int $actorId): bool
|
|
{
|
|
$stmt = $this->pdo->prepare("
|
|
DELETE FROM actor_adult_video
|
|
WHERE adult_video_id = :adult_video_id AND actor_id = :actor_id
|
|
");
|
|
return $stmt->execute([
|
|
'adult_video_id' => $this->id,
|
|
'actor_id' => $actorId
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Update the cast field with actor names
|
|
*/
|
|
public function updateCastField(): bool
|
|
{
|
|
$actors = $this->actors();
|
|
$actorNames = array_column($actors, 'name');
|
|
$castString = implode(', ', $actorNames);
|
|
|
|
return $this->update($this->id, [
|
|
'cast' => $castString
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
|
|
/**
|
|
* Get TV show statistics
|
|
*/
|
|
public static function getStats(\PDO $pdo): array
|
|
{
|
|
$stmt = $pdo->query("
|
|
SELECT
|
|
COUNT(*) as total_adult_videos,
|
|
COUNT(CASE WHEN is_favorite = 1 THEN 1 END) as favorite_adult_videos,
|
|
AVG(rating) as avg_rating
|
|
FROM adult_videos
|
|
");
|
|
return $stmt->fetch(\PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
/**
|
|
* Search actors by name
|
|
*/
|
|
public static function searchActors(\PDO $pdo, string $query): array
|
|
{
|
|
$stmt = $pdo->prepare("
|
|
SELECT a.*
|
|
FROM actors a
|
|
WHERE a.name LIKE :query
|
|
ORDER BY a.name
|
|
LIMIT 10
|
|
");
|
|
|
|
$stmt->execute(['query' => "%{$query}%"]);
|
|
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
|
}
|
|
}
|