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.', 'رفع وإدارة إعلانات الصور والفيديوهات لعرضها على شاشة الطابور.') ); ?>
= qh_h(qh_t('These videos will be played sequentially on the display screen.', 'سيتم تشغيل هذه الفيديوهات بالتتابع على شاشة العرض.')) ?>
+= qh_h(qh_t('Videos play until they end, while images stay on screen for 10 seconds in the same rotation.', 'تعمل الفيديوهات حتى نهايتها، بينما تبقى الصور على الشاشة لمدة 10 ثوانٍ ضمن نفس التدوير.')) ?>