diff --git a/admin_ads.php b/admin_ads.php index 45e6532..f91c974 100644 --- a/admin_ads.php +++ b/admin_ads.php @@ -4,17 +4,45 @@ require_once __DIR__ . '/queue_bootstrap.php'; qh_boot(); qh_admin_handle_request(); -// Ensure the table exists +// Ensure the tables exist $pdo = db(); + +function qh_ads_column_exists(PDO $pdo, string $column): bool +{ + static $cache = []; + + if (array_key_exists($column, $cache)) { + return $cache[$column]; + } + + $stmt = $pdo->prepare( + "SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = 'hospital_ads' AND COLUMN_NAME = ?" + ); + $stmt->execute([DB_NAME, $column]); + + return $cache[$column] = ((int) $stmt->fetchColumn() > 0); +} + $pdo->exec("CREATE TABLE IF NOT EXISTS hospital_ads ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255) NULL, video_path VARCHAR(255) NOT NULL, + media_type VARCHAR(20) NOT NULL DEFAULT 'video', + media_path VARCHAR(255) NULL, is_active TINYINT(1) DEFAULT 1, sort_order INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )"); +if (!qh_ads_column_exists($pdo, 'media_type')) { + $pdo->exec("ALTER TABLE hospital_ads ADD COLUMN media_type VARCHAR(20) NOT NULL DEFAULT 'video' AFTER video_path"); +} +if (!qh_ads_column_exists($pdo, 'media_path')) { + $pdo->exec("ALTER TABLE hospital_ads ADD COLUMN media_path VARCHAR(255) NULL AFTER media_type"); +} +$pdo->exec("UPDATE hospital_ads SET media_type = 'video' WHERE media_type IS NULL OR media_type = ''"); +$pdo->exec("UPDATE hospital_ads SET media_path = video_path WHERE (media_path IS NULL OR media_path = '') AND video_path <> ''"); + $pdo->exec("CREATE TABLE IF NOT EXISTS hospital_news ( id INT AUTO_INCREMENT PRIMARY KEY, phrase VARCHAR(1000) NOT NULL, @@ -26,18 +54,30 @@ $pdo->exec("CREATE TABLE IF NOT EXISTS hospital_news ( // Handle Form Submissions $message = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { - if (isset($_POST['action']) && $_POST['action'] === 'add_video' && !empty($_FILES['video']['name'])) { - $uploadDir = __DIR__ . '/assets/videos/uploads/'; - if (!is_dir($uploadDir)) { - mkdir($uploadDir, 0777, true); - } - - $ext = strtolower(pathinfo($_FILES['video']['name'], PATHINFO_EXTENSION)); - $allowed = ['mp4', 'webm', 'ogg']; - - if (!in_array($ext, $allowed)) { - $message = qh_t("Invalid video format (.$ext). Allowed formats: MP4, WebM, OGG.", "تنسيق فيديو غير صالح (.$ext). الصيغ المسموحة: MP4, WebM, OGG."); - } elseif ($_FILES['video']['error'] !== UPLOAD_ERR_OK) { + $action = (string) ($_POST['action'] ?? ''); + $adId = (int) ($_POST['ad_id'] ?? $_POST['video_id'] ?? 0); + + if ($action === 'add_media' && !empty($_FILES['media']['name'])) { + $mediaFile = $_FILES['media']; + $title = trim((string) ($_POST['title'] ?? '')); + $ext = strtolower(pathinfo($mediaFile['name'], PATHINFO_EXTENSION)); + $typeMap = [ + 'mp4' => 'video', + 'webm' => 'video', + 'ogg' => 'video', + 'jpg' => 'image', + 'jpeg' => 'image', + 'png' => 'image', + 'webp' => 'image', + 'gif' => 'image', + ]; + + if (!isset($typeMap[$ext])) { + $message = qh_t( + "Invalid media format (.$ext). Allowed formats: JPG, JPEG, PNG, WEBP, GIF, MP4, WebM, OGG.", + "تنسيق وسائط غير صالح (.$ext). الصيغ المسموحة: JPG, JPEG, PNG, WEBP, GIF, MP4, WebM, OGG." + ); + } elseif ($mediaFile['error'] !== UPLOAD_ERR_OK) { $errorMap = [ UPLOAD_ERR_INI_SIZE => 'File exceeds max size in php.ini.', UPLOAD_ERR_FORM_SIZE => 'File exceeds max size in HTML form.', @@ -45,53 +85,66 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { UPLOAD_ERR_NO_FILE => 'No file was uploaded.', UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder.', UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.', - UPLOAD_ERR_EXTENSION => 'A PHP extension stopped the upload.' + UPLOAD_ERR_EXTENSION => 'A PHP extension stopped the upload.', ]; - $errMsg = $errorMap[$_FILES['video']['error']] ?? 'Unknown error'; + $errMsg = $errorMap[$mediaFile['error']] ?? 'Unknown error'; $message = qh_t('Upload error: ' . $errMsg, 'خطأ في الرفع: ' . $errMsg); } else { - $filename = uniqid('vid_') . '.' . $ext; + $mediaType = $typeMap[$ext]; + $uploadDir = __DIR__ . ($mediaType === 'video' ? '/assets/videos/uploads/' : '/assets/images/uploads/'); + if (!is_dir($uploadDir)) { + mkdir($uploadDir, 0777, true); + } + + $filename = uniqid($mediaType === 'video' ? 'vid_' : 'img_') . '.' . $ext; $dest = $uploadDir . $filename; - - if (move_uploaded_file($_FILES['video']['tmp_name'], $dest)) { - $title = $_POST['title'] ?? ''; - $path = 'assets/videos/uploads/' . $filename; - - $stmt = $pdo->prepare("INSERT INTO hospital_ads (title, video_path, is_active) VALUES (?, ?, 1)"); - $stmt->execute([$title, $path]); - $message = qh_t('Video uploaded successfully.', 'تم رفع الفيديو بنجاح.'); + + if (move_uploaded_file($mediaFile['tmp_name'], $dest)) { + $path = ($mediaType === 'video' ? 'assets/videos/uploads/' : 'assets/images/uploads/') . $filename; + $legacyVideoPath = $mediaType === 'video' ? $path : ''; + + $stmt = $pdo->prepare( + "INSERT INTO hospital_ads (title, video_path, media_type, media_path, is_active) VALUES (?, ?, ?, ?, 1)" + ); + $stmt->execute([$title, $legacyVideoPath, $mediaType, $path]); + $message = $mediaType === 'video' + ? qh_t('Video uploaded successfully.', 'تم رفع الفيديو بنجاح.') + : qh_t('Image uploaded successfully.', 'تم رفع الصورة بنجاح.'); } else { $message = qh_t('Failed to save uploaded file.', 'فشل في حفظ الملف المرفوع.'); } } - } elseif (isset($_POST['action']) && $_POST['action'] === 'delete_video' && !empty($_POST['video_id'])) { - $id = (int) $_POST['video_id']; - $stmt = $pdo->prepare("SELECT video_path FROM hospital_ads WHERE id = ?"); - $stmt->execute([$id]); - $video = $stmt->fetch(); - if ($video) { - $fullPath = __DIR__ . '/' . $video['video_path']; - if (file_exists($fullPath)) { - unlink($fullPath); + } elseif ($action === 'delete_media' && $adId > 0) { + $stmt = $pdo->prepare( + "SELECT COALESCE(NULLIF(media_path, ''), NULLIF(video_path, '')) AS file_path FROM hospital_ads WHERE id = ?" + ); + $stmt->execute([$adId]); + $media = $stmt->fetch(); + if ($media) { + $filePath = (string) ($media['file_path'] ?? ''); + if ($filePath !== '') { + $fullPath = __DIR__ . '/' . $filePath; + if (file_exists($fullPath)) { + unlink($fullPath); + } } - $pdo->prepare("DELETE FROM hospital_ads WHERE id = ?")->execute([$id]); - $message = qh_t('Video deleted successfully.', 'تم حذف الفيديو بنجاح.'); + $pdo->prepare("DELETE FROM hospital_ads WHERE id = ?")->execute([$adId]); + $message = qh_t('Ad deleted successfully.', 'تم حذف الإعلان بنجاح.'); } - } elseif (isset($_POST['action']) && $_POST['action'] === 'toggle_status' && !empty($_POST['video_id'])) { - $id = (int) $_POST['video_id']; + } elseif ($action === 'toggle_status' && $adId > 0) { $stmt = $pdo->prepare("UPDATE hospital_ads SET is_active = NOT is_active WHERE id = ?"); - $stmt->execute([$id]); - $message = qh_t('Video status updated.', 'تم تحديث حالة الفيديو.'); - } elseif (isset($_POST['action']) && $_POST['action'] === 'add_news' && !empty($_POST['phrase'])) { + $stmt->execute([$adId]); + $message = qh_t('Ad status updated.', 'تم تحديث حالة الإعلان.'); + } elseif ($action === 'add_news' && !empty($_POST['phrase'])) { $phrase = trim($_POST['phrase']); $stmt = $pdo->prepare("INSERT INTO hospital_news (phrase, is_active) VALUES (?, 1)"); $stmt->execute([$phrase]); $message = qh_t('Phrase added successfully.', 'تمت إضافة العبارة بنجاح.'); - } elseif (isset($_POST['action']) && $_POST['action'] === 'delete_news' && !empty($_POST['news_id'])) { + } elseif ($action === 'delete_news' && !empty($_POST['news_id'])) { $id = (int) $_POST['news_id']; $pdo->prepare("DELETE FROM hospital_news WHERE id = ?")->execute([$id]); $message = qh_t('Phrase deleted successfully.', 'تم حذف العبارة بنجاح.'); - } elseif (isset($_POST['action']) && $_POST['action'] === 'toggle_news_status' && !empty($_POST['news_id'])) { + } elseif ($action === 'toggle_news_status' && !empty($_POST['news_id'])) { $id = (int) $_POST['news_id']; $pdo->prepare("UPDATE hospital_news SET is_active = NOT is_active WHERE id = ?")->execute([$id]); $message = qh_t('Phrase status updated.', 'تم تحديث حالة العبارة.'); @@ -99,7 +152,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } // Fetch existing ads -$stmt = $pdo->query("SELECT * FROM hospital_ads ORDER BY sort_order ASC, id DESC"); +$stmt = $pdo->query( + "SELECT *, + COALESCE(NULLIF(media_type, ''), 'video') AS effective_media_type, + COALESCE(NULLIF(media_path, ''), NULLIF(video_path, '')) AS effective_media_path + FROM hospital_ads + ORDER BY sort_order ASC, id DESC" +); $ads = $stmt->fetchAll(); $stmt2 = $pdo->query("SELECT * FROM hospital_news ORDER BY sort_order ASC, id DESC"); @@ -108,7 +167,7 @@ $newsPhrases = $stmt2->fetchAll(); qh_page_start( 'admin_ads', qh_t('Manage Advertisements', 'إدارة الإعلانات'), - qh_t('Upload and manage videos to display on the queue screen.', 'رفع وإدارة الفيديوهات لعرضها على شاشة الطابور.') + qh_t('Upload and manage image and video ads for the queue display.', 'رفع وإدارة إعلانات الصور والفيديوهات لعرضها على شاشة الطابور.') ); ?>
@@ -120,8 +179,8 @@ qh_page_start(
-

-

+

+

@@ -131,22 +190,22 @@ qh_page_start(
-
+
- +
- +
- - -
+ + +
- +
@@ -154,7 +213,7 @@ qh_page_start(
-
+
@@ -163,6 +222,7 @@ qh_page_start( + @@ -170,19 +230,28 @@ qh_page_start( - + - + + <?= qh_h($ad['title'] ?: qh_t('Advertisement preview', 'معاينة الإعلان')) ?> + + + + + + + + @@ -194,14 +263,14 @@ qh_page_start(
- +
-
- - + + +
diff --git a/display.php b/display.php index 1714eda..dcb9386 100644 --- a/display.php +++ b/display.php @@ -6,11 +6,68 @@ qh_boot(); $activeCalls = qh_fetch_tickets(['called', 'in_progress', 'nursing_called'], null, 8); $queueOverview = qh_queue_overview(); -$activeVideos = []; +function qh_display_ads_column_exists(PDO $pdo, string $column): bool +{ + static $cache = []; + + if (array_key_exists($column, $cache)) { + return $cache[$column]; + } + + $stmt = $pdo->prepare( + "SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = 'hospital_ads' AND COLUMN_NAME = ?" + ); + $stmt->execute([DB_NAME, $column]); + + return $cache[$column] = ((int) $stmt->fetchColumn() > 0); +} + +$activeAds = []; try { - $stmt = db()->query("SELECT video_path FROM hospital_ads WHERE is_active = 1 ORDER BY sort_order ASC, id DESC "); + $pdo = db(); + $hasMediaType = qh_display_ads_column_exists($pdo, 'media_type'); + $hasMediaPath = qh_display_ads_column_exists($pdo, 'media_path'); + + if ($hasMediaType && $hasMediaPath) { + $stmt = $pdo->query( + "SELECT id, title, + COALESCE(NULLIF(media_type, ''), 'video') AS media_type, + COALESCE(NULLIF(media_path, ''), NULLIF(video_path, '')) AS media_path + FROM hospital_ads + WHERE is_active = 1 + ORDER BY sort_order ASC, id DESC" + ); + } elseif ($hasMediaPath) { + $stmt = $pdo->query( + "SELECT id, title, 'video' AS media_type, + COALESCE(NULLIF(media_path, ''), NULLIF(video_path, '')) AS media_path + FROM hospital_ads + WHERE is_active = 1 + ORDER BY sort_order ASC, id DESC" + ); + } else { + $stmt = $pdo->query( + "SELECT id, title, 'video' AS media_type, video_path AS media_path + FROM hospital_ads + WHERE is_active = 1 + ORDER BY sort_order ASC, id DESC" + ); + } + if ($stmt) { - $activeVideos = $stmt->fetchAll(PDO::FETCH_COLUMN); + foreach ($stmt->fetchAll() as $ad) { + $mediaPath = (string) ($ad['media_path'] ?? ''); + if ($mediaPath === '') { + continue; + } + $activeAds[] = [ + 'id' => (int) ($ad['id'] ?? 0), + 'title' => (string) ($ad['title'] ?? ''), + 'type' => (($ad['media_type'] ?? 'video') === 'image') ? 'image' : 'video', + 'path' => $mediaPath, + 'duration' => 10, + ]; + } } } catch (Throwable $e) { // Table might not exist yet, safe to ignore @@ -189,108 +246,193 @@ qh_page_start(
- +
- +
+ + <?= qh_h(qh_t('Hospital advertisement', 'إعلان المستشفى')) ?> +