197 lines
6.5 KiB
PHP
197 lines
6.5 KiB
PHP
<?php
|
|||
|
|
// ============================================
|
||
|
|
// 文件: lib/movies.php
|
||
|
|
// 说明: 电影 / 影院读取与搜索,以及表单提交时的关联数据处理
|
||
|
|
// ============================================
|
||
|
|
|
||
|
|
// ===== 电影列表 =====
|
||
|
|
function getMovies() {
|
||
|
|
$db = getDB();
|
||
|
|
$stmt = $db->query("
|
||
|
|
SELECT m.*, c.place, c.name as cinema_name, c.address as cinema_address, c.color as cinema_color
|
||
|
|
FROM movies m
|
||
|
|
LEFT JOIN cinemas c ON m.cinema_id = c.id
|
||
|
|
ORDER BY m.watch_date DESC, m.created_at DESC
|
||
|
|
");
|
||
|
|
$movies = $stmt->fetchAll();
|
||
|
|
attachViewersToMovies($movies);
|
||
|
|
return $movies;
|
||
|
|
}
|
||
|
|
|
||
|
|
function getMovie($id) {
|
||
|
|
$db = getDB();
|
||
|
|
$stmt = $db->prepare("
|
||
|
|
SELECT m.*, c.place, c.name as cinema_name, c.address as cinema_address, c.color as cinema_color
|
||
|
|
FROM movies m
|
||
|
|
LEFT JOIN cinemas c ON m.cinema_id = c.id
|
||
|
|
WHERE m.id = ?
|
||
|
|
");
|
||
|
|
$stmt->execute([$id]);
|
||
|
|
$movie = $stmt->fetch();
|
||
|
|
if ($movie) {
|
||
|
|
$stmt2 = $db->prepare("
|
||
|
|
SELECT v.id, v.movie_id, v.person_id,
|
||
|
|
COALESCE(p.name, v.name) as name,
|
||
|
|
p.color as person_color,
|
||
|
|
p.avatar as person_avatar
|
||
|
|
FROM viewers v
|
||
|
|
LEFT JOIN persons p ON v.person_id = p.id
|
||
|
|
WHERE v.movie_id = ?
|
||
|
|
ORDER BY v.id
|
||
|
|
");
|
||
|
|
$stmt2->execute([$id]);
|
||
|
|
$movie['viewers'] = $stmt2->fetchAll();
|
||
|
|
|
||
|
|
$stmt3 = $db->prepare("SELECT * FROM movie_photos WHERE movie_id = ? ORDER BY id");
|
||
|
|
$stmt3->execute([$id]);
|
||
|
|
$movie['photos'] = $stmt3->fetchAll();
|
||
|
|
}
|
||
|
|
return $movie;
|
||
|
|
}
|
||
|
|
|
||
|
|
function attachViewersToMovies(&$movies) {
|
||
|
|
if (empty($movies)) return;
|
||
|
|
$db = getDB();
|
||
|
|
$movie_ids = array_column($movies, 'id');
|
||
|
|
if (empty($movie_ids)) return;
|
||
|
|
$placeholders = implode(',', array_fill(0, count($movie_ids), '?'));
|
||
|
|
$stmt = $db->prepare("
|
||
|
|
SELECT v.movie_id, p.id as person_id, p.name, p.color, p.avatar
|
||
|
|
FROM viewers v
|
||
|
|
LEFT JOIN persons p ON v.person_id = p.id
|
||
|
|
WHERE v.movie_id IN ($placeholders)
|
||
|
|
ORDER BY v.id
|
||
|
|
");
|
||
|
|
$stmt->execute($movie_ids);
|
||
|
|
$rows = $stmt->fetchAll();
|
||
|
|
$viewers_map = [];
|
||
|
|
foreach ($rows as $row) {
|
||
|
|
$movie_id = $row['movie_id'];
|
||
|
|
if (!isset($viewers_map[$movie_id])) $viewers_map[$movie_id] = [];
|
||
|
|
$viewers_map[$movie_id][] = [
|
||
|
|
'person_id' => $row['person_id'],
|
||
|
|
'name' => $row['name'] ?? '未知',
|
||
|
|
'color' => $row['color'] ?? '#888888',
|
||
|
|
'avatar' => $row['avatar']
|
||
|
|
];
|
||
|
|
}
|
||
|
|
foreach ($movies as &$movie) {
|
||
|
|
$movie['viewers'] = $viewers_map[$movie['id']] ?? [];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== 影院 =====
|
||
|
|
function getCinemas() {
|
||
|
|
$db = getDB();
|
||
|
|
$stmt = $db->query("SELECT * FROM cinemas ORDER BY place, name");
|
||
|
|
return $stmt->fetchAll();
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== 搜索 =====
|
||
|
|
function searchMovies($keyword) {
|
||
|
|
return advancedSearch(['title' => $keyword]);
|
||
|
|
}
|
||
|
|
|
||
|
|
function advancedSearch($params) {
|
||
|
|
$db = getDB();
|
||
|
|
$sql = "
|
||
|
|
SELECT DISTINCT m.*,
|
||
|
|
c.place, c.name as cinema_name, c.address as cinema_address, c.color as cinema_color
|
||
|
|
FROM movies m
|
||
|
|
LEFT JOIN cinemas c ON m.cinema_id = c.id
|
||
|
|
LEFT JOIN viewers v ON m.id = v.movie_id
|
||
|
|
LEFT JOIN persons p ON v.person_id = p.id
|
||
|
|
WHERE 1=1
|
||
|
|
";
|
||
|
|
$bind = [];
|
||
|
|
if (!empty($params['title'])) {
|
||
|
|
$sql .= " AND m.title LIKE :title";
|
||
|
|
$bind[':title'] = '%' . $params['title'] . '%';
|
||
|
|
}
|
||
|
|
if (!empty($params['cinema_id']) && is_numeric($params['cinema_id'])) {
|
||
|
|
$sql .= " AND m.cinema_id = :cinema_id";
|
||
|
|
$bind[':cinema_id'] = (int)$params['cinema_id'];
|
||
|
|
}
|
||
|
|
if (!empty($params['person_id']) && is_numeric($params['person_id'])) {
|
||
|
|
$sql .= " AND v.person_id = :person_id";
|
||
|
|
$bind[':person_id'] = (int)$params['person_id'];
|
||
|
|
}
|
||
|
|
if (!empty($params['date_from'])) {
|
||
|
|
$sql .= " AND m.watch_date >= :date_from";
|
||
|
|
$bind[':date_from'] = $params['date_from'];
|
||
|
|
}
|
||
|
|
if (!empty($params['date_to'])) {
|
||
|
|
$sql .= " AND m.watch_date <= :date_to";
|
||
|
|
$bind[':date_to'] = $params['date_to'];
|
||
|
|
}
|
||
|
|
$sql .= " ORDER BY m.watch_date DESC, m.created_at DESC";
|
||
|
|
$stmt = $db->prepare($sql);
|
||
|
|
$stmt->execute($bind);
|
||
|
|
$movies = $stmt->fetchAll();
|
||
|
|
attachViewersToMovies($movies);
|
||
|
|
return $movies;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== 表单提交时的关联数据处理 =====
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 解析表单提交的电影院选择。
|
||
|
|
* 选择「新建」且填了名称时创建影院并返回新 id;未选择或信息不足时返回 null。
|
||
|
|
*/
|
||
|
|
function resolveCinemaId($cinema_id, $new_place, $new_name, $new_address) {
|
||
|
|
$db = getDB();
|
||
|
|
|
||
|
|
if ($cinema_id === 'new' && !empty($new_name)) {
|
||
|
|
$stmt = $db->prepare("INSERT INTO cinemas (place, name, address) VALUES (?, ?, ?)");
|
||
|
|
$stmt->execute([$new_place, $new_name, $new_address]);
|
||
|
|
$cinema_id = $db->lastInsertId();
|
||
|
|
} elseif ($cinema_id === 'new') {
|
||
|
|
$cinema_id = null;
|
||
|
|
} elseif (!empty($cinema_id) && is_numeric($cinema_id)) {
|
||
|
|
$cinema_id = (int)$cinema_id;
|
||
|
|
} else {
|
||
|
|
$cinema_id = null;
|
||
|
|
}
|
||
|
|
|
||
|
|
return $cinema_id;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 解析「一起看的人」表单行:已有观影人取 id,选择「新增」则按姓名建库或复用。
|
||
|
|
* 返回去重后的观影人 id 列表。
|
||
|
|
*/
|
||
|
|
function resolvePersonIds($viewer_selects, $viewer_news) {
|
||
|
|
$db = getDB();
|
||
|
|
$person_ids = [];
|
||
|
|
foreach ($viewer_selects as $idx => $val) {
|
||
|
|
if ($val === 'new') {
|
||
|
|
$new_name = trim($viewer_news[$idx] ?? '');
|
||
|
|
if (!empty($new_name)) {
|
||
|
|
$chk = $db->prepare("SELECT id FROM persons WHERE name = ?");
|
||
|
|
$chk->execute([$new_name]);
|
||
|
|
$existing = $chk->fetch();
|
||
|
|
if ($existing) {
|
||
|
|
$person_ids[] = $existing['id'];
|
||
|
|
} else {
|
||
|
|
$ins = $db->prepare("INSERT INTO persons (name) VALUES (?)");
|
||
|
|
$ins->execute([$new_name]);
|
||
|
|
$person_ids[] = $db->lastInsertId();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} elseif (is_numeric($val) && $val > 0) {
|
||
|
|
$person_ids[] = (int)$val;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return array_unique($person_ids);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 把观影人写入电影关联表
|
||
|
|
function linkViewers($movie_id, $person_ids) {
|
||
|
|
if (empty($person_ids)) return;
|
||
|
|
$db = getDB();
|
||
|
|
$stmt = $db->prepare("INSERT INTO viewers (movie_id, person_id, name) VALUES (?, ?, ?)");
|
||
|
|
foreach ($person_ids as $pid) {
|
||
|
|
$stmt->execute([$movie_id, $pid, '']);
|
||
|
|
}
|
||
|
|
}
|