'Authentication required.']); exit; } header('Content-Type: application/json'); switch ($_POST['action']) { case 'generate_ai_content': case 'generateaicontent': require_once 'api.php'; $api = new BlogAPI($pdo, OPENAI_API_KEY); $raw_content = $_POST['raw_content'] ?? $_POST['rawcontent'] ?? ''; $layout = $_POST['layout'] ?? 'news'; $model = $_POST['model'] ?? 'gpt-4.1-nano'; // Default to nano $images = isset($_POST['images']) ? json_decode($_POST['images'], true) : []; if (empty($raw_content)) { echo json_encode(['error' => 'Raw content cannot be empty.']); exit; } // Pass all new parameters to the API $result = $api->generateAIContent($raw_content, $images, $layout, $model); if ($result && !isset($result['error'])) { $featured_image_id = !empty($images) && isset($images[0]['id']) ? (int)$images[0]['id'] : null; $save_data = array_merge($result, [ 'raw_content_input' => $raw_content, 'layout' => $layout, 'featured_image_id' => $featured_image_id, 'model_name' => $model // Save the model used ]); $post_id = $api->savePost($save_data); $result['post_id'] = $post_id; $result['postid'] = $post_id; $result['model_name'] = $result['model_name'] ?? $model; $result['modelname'] = $result['model_name']; echo json_encode($result); } else { echo json_encode(['error' => 'Failed to generate content from AI.', 'details' => $result['error'] ?? 'No details.']); } exit; case 'upload_image': case 'uploadimage': if (isset($_FILES['image'])) { $file = $_FILES['image']; $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; if (!in_array($file['type'], $allowedTypes) || $file['size'] > MAX_FILE_SIZE) { echo json_encode(['error' => 'Invalid file type or size (Max 5MB).']); exit; } $uploadDir = UPLOAD_DIR; if (!is_dir($uploadDir)) mkdir($uploadDir, 0777, true); $filename = uniqid() . '-' . basename($file['name']); $filePath = $uploadDir . $filename; if (move_uploaded_file($file['tmp_name'], $filePath)) { $stmt = $pdo->prepare("INSERT INTO images (file_path) VALUES (?)"); $stmt->execute([$filePath]); $lastId = $pdo->lastInsertId(); echo json_encode(['success' => true, 'path' => $filePath, 'id' => $lastId]); } else { echo json_encode(['error' => 'Failed to move uploaded file. Check directory permissions.']); } } else { echo json_encode(['error' => 'No image file provided.']); } exit; case 'upload_image_url': case 'uploadimageurl': $url = filter_var($_POST['image_url'] ?? $_POST['imageurl'] ?? '', FILTER_VALIDATE_URL); if (!$url) { echo json_encode(['error' => 'Invalid or empty URL provided.']); exit; } $imageData = @file_get_contents($url); if ($imageData === false) { echo json_encode(['error' => 'Could not retrieve image from the URL.']); exit; } $imageInfo = @getimagesizefromstring($imageData); if ($imageInfo === false) { echo json_encode(['error' => 'URL does not point to a valid image.']); exit; } $extension = image_type_to_extension($imageInfo[2]); if (!$extension || !in_array($extension, ['.jpg', '.jpeg', '.png', '.gif', '.webp'])) { echo json_encode(['error' => 'Unsupported image type.']); exit; } $uploadDir = UPLOAD_DIR; if (!is_dir($uploadDir)) mkdir($uploadDir, 0777, true); $filename = uniqid() . bin2hex(random_bytes(5)) . $extension; $filePath = $uploadDir . $filename; if (file_put_contents($filePath, $imageData)) { $stmt = $pdo->prepare("INSERT INTO images (file_path) VALUES (?)"); $stmt->execute([$filePath]); $lastId = $pdo->lastInsertId(); echo json_encode(['success' => true, 'path' => $filePath, 'id' => $lastId]); } else { echo json_encode(['error' => 'Failed to save the image.']); } exit; case 'delete_images': case 'deleteimages': $image_ids = $_POST['image_ids'] ?? []; if (empty($image_ids) || !is_array($image_ids)) { echo json_encode(['error' => 'No image IDs provided.']); exit; } $ids_sanitized = array_map('intval', $image_ids); $placeholders = rtrim(str_repeat('?,', count($ids_sanitized)), ','); $stmt_select = $pdo->prepare("SELECT file_path FROM images WHERE id IN ($placeholders)"); $stmt_select->execute($ids_sanitized); $images = $stmt_select->fetchAll(PDO::FETCH_ASSOC); foreach ($images as $image) { if ($image['file_path'] && file_exists($image['file_path'])) { @unlink($image['file_path']); } } $stmt_delete = $pdo->prepare("DELETE FROM images WHERE id IN ($placeholders)"); $stmt_delete->execute($ids_sanitized); echo json_encode(['success' => true, 'deleted_count' => count($images)]); exit; case 'bulk_update_status_posts': $post_ids = $_POST['post_ids'] ?? []; $status = $_POST['status'] ?? ''; if (empty($post_ids) || !is_array($post_ids) || !in_array($status, ['published', 'draft'])) { echo json_encode(['error' => 'Invalid data provided.']); exit; } $ids_sanitized = array_map('intval', $post_ids); $placeholders = rtrim(str_repeat('?,', count($ids_sanitized)), ','); $stmt_update = $pdo->prepare("UPDATE posts SET status = ? WHERE id IN ($placeholders)"); $stmt_update->execute(array_merge([$status], $ids_sanitized)); echo json_encode(['success' => true, 'updated_count' => count($ids_sanitized)]); exit; case 'bulk_delete_posts': $post_ids = $_POST['post_ids'] ?? []; if (empty($post_ids) || !is_array($post_ids)) { echo json_encode(['error' => 'No post IDs provided.']); exit; } $ids_sanitized = array_map('intval', $post_ids); $placeholders = rtrim(str_repeat('?,', count($ids_sanitized)), ','); $stmt_delete = $pdo->prepare("DELETE FROM posts WHERE id IN ($placeholders)"); $stmt_delete->execute($ids_sanitized); echo json_encode(['success' => true, 'deleted_count' => count($ids_sanitized)]); exit; case 'duplicate_post': if (!ob_get_level()) ob_start(); header('Content-Type: application/json; charset=utf-8'); try { if (!isLoggedIn()) { ob_clean(); echo json_encode(['error' => 'Authentication required.']); exit; } $post_id = intval($_POST['post_id'] ?? 0); if ($post_id <= 0) { ob_clean(); echo json_encode(['error' => 'Invalid Post ID.']); exit; } $stmt = $pdo->prepare("SELECT * FROM posts WHERE id = ?"); $stmt->execute([$post_id]); $original_post = $stmt->fetch(PDO::FETCH_ASSOC); if (!$original_post) { ob_clean(); echo json_encode(['error' => 'Original post not found.']); exit; } $new_title = ($original_post['title'] ?? '') . " (Copy)"; $new_slug = ($original_post['slug'] ?? 'post') . "-copy-" . time(); $insert_stmt = $pdo->prepare(" INSERT INTO posts (title, slug, raw_content_input, ai_generated_content_html, featured_image_id, status, meta_title, meta_description, meta_keywords, word_count, layout, model_name, created_at) VALUES (?, ?, ?, ?, ?, 'draft', ?, ?, ?, ?, ?, ?, NOW()) "); $executed = $insert_stmt->execute([ $new_title, $new_slug, $original_post['raw_content_input'] ?? '', $original_post['ai_generated_content_html'] ?? '', !empty($original_post['featured_image_id']) ? (int)$original_post['featured_image_id'] : null, $original_post['meta_title'] ?? '', $original_post['meta_description'] ?? '', $original_post['meta_keywords'] ?? '', intval($original_post['word_count'] ?? 0), $original_post['layout'] ?? 'news', $original_post['model_name'] ?? 'gpt-4.1-nano' ]); if (!$executed || $insert_stmt->rowCount() === 0) { $err = $insert_stmt->errorInfo(); $pdoErr = isset($err[2]) ? $err[2] : 'Unknown PDO error during insert.'; error_log("Duplicate Post Insert Failed: " . $pdoErr); ob_clean(); echo json_encode(['error' => 'Server error while duplicating post.', 'details' => $pdoErr]); exit; } ob_clean(); echo json_encode(['success' => true, 'message' => 'Post duplicated successfully.']); exit; } catch (Exception $e) { error_log("Duplicate Post Exception: " . $e->getMessage()); ob_clean(); echo json_encode([ 'error' => 'Server error while duplicating post.', 'details' => $e->getMessage() ]); exit; } break; case 'save_settings': $allowed_keys = ['blog_layout']; $success = true; foreach ($_POST as $key => $value) { if (in_array($key, $allowed_keys)) { $stmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (:key, :value) ON DUPLICATE KEY UPDATE setting_value = :value"); $stmt->execute(['key' => $key, 'value' => $value]); } } echo json_encode(['success' => $success, 'message' => 'Settings saved successfully!']); exit; } } // Handle Login Form Submission if (isset($_POST['username']) && isset($_POST['password'])) { $username = trim($_POST['username']); $password = $_POST['password']; $error = "Invalid username or password."; // Default error try { $stmt = $pdo->prepare("SELECT id, username, password_hash FROM users WHERE username = ?"); $stmt->execute([$username]); $user = $stmt->fetch(); if ($user && password_verify($password, $user['password_hash'])) { $_SESSION['admin_id'] = $user['id']; $_SESSION['admin_username'] = $user['username']; header('Location: admin.php?login=success'); exit; } } catch(Exception $e) { error_log("Admin Login Error: " . $e->getMessage()); } } } // Handle Logout & Post Deletion from GET requests if (isset($_GET['action'])) { if ($_GET['action'] === 'logout') { session_destroy(); header('Location: admin.php?logout=success'); exit; } if ($_GET['action'] === 'delete_post' && isLoggedIn()) { $post_id = intval($_GET['id']); $stmt = $pdo->prepare("DELETE FROM posts WHERE id = ?"); $stmt->execute([$post_id]); header('Location: admin.php?deleted=success'); exit; } } // If not logged in, display the styled login form if (!isLoggedIn()) { ?>
Admin Dashboard
Success
You have been successfully logged out.
Login Failed
= htmlspecialchars($error) ?>
= $stats['total_posts'] ?>
= $stats['published_posts'] ?>
= $stats['draft_posts'] ?>
= $stats['total_images'] ?>