$name) { if ($_FILES['files']['error'][$key] === UPLOAD_ERR_OK) { $tmp_name = $_FILES['files']['tmp_name'][$key]; $file_size = $_FILES['files']['size'][$key]; $file_type = $_FILES['files']['type'][$key]; if ($file_size > $max_size) { // Optionally, collect and return errors continue; } if (!in_array($file_type, $allowed_types)) { // Optionally, collect and return errors continue; } $stored_filename = uniqid('', true) . '-' . basename($name); $destination = $upload_dir . $stored_filename; if (move_uploaded_file($tmp_name, $destination)) { $stmt = $pdo->prepare("INSERT INTO deal_files (deal_id, original_filename, stored_filename, file_type, file_size) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$deal_id, $name, $stored_filename, $file_type, $file_size]); } } } } } $action = $_GET['action'] ?? ''; try { require_login(); // All actions require a login $pdo = db(); $user_id = current_user_id(); switch ($action) { case 'get_deals': $category = $_GET['category'] ?? null; $tags = $_GET['tags'] ?? null; $params = []; $where_clauses = []; if (!is_admin()) { $where_clauses[] = 'd.user_id = ?'; $params[] = $user_id; } if ($category) { $where_clauses[] = 'd.category = ?'; $params[] = $category; } if ($tags) { $tag_list = explode(',', $tags); $tag_placeholders = implode(',', array_fill(0, count($tag_list), '?')); $tag_conditions = []; foreach ($tag_list as $tag) { $tag_conditions[] = 'FIND_IN_SET(?, d.tags)'; $params[] = trim($tag); } if(!empty($tag_conditions)) { $where_clauses[] = '(' . implode(' OR ', $tag_conditions) . ')'; } } $sql = 'SELECT d.id, d.name, d.vendor, d.website, d.purchase_date, d.price, d.currency, d.username, d.password, d.category, d.tags, d.rating, GROUP_CONCAT(df.id, ":", df.original_filename) as files FROM deals d LEFT JOIN deal_files df ON d.id = df.deal_id'; if (!empty($where_clauses)) { $sql .= ' WHERE ' . implode(' AND ', $where_clauses); } $sql .= ' GROUP BY d.id ORDER BY d.purchase_date DESC'; $stmt = $pdo->prepare($sql); $stmt->execute($params); $deals = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode(['success' => true, 'deals' => $deals]); break; case 'get_categories': $sql = 'SELECT DISTINCT category FROM deals WHERE category IS NOT NULL AND category != ""'; if (!is_admin()) { $sql .= ' AND user_id = ?'; $stmt = $pdo->prepare($sql); $stmt->execute([$user_id]); } else { $stmt = $pdo->query($sql); } $categories = $stmt->fetchAll(PDO::FETCH_COLUMN); echo json_encode(['success' => true, 'data' => $categories]); break; case 'get_tags': if (is_admin()) { $stmt = $pdo->query('SELECT tags FROM deals WHERE tags IS NOT NULL AND tags != ""'); } else { $stmt = $pdo->prepare('SELECT tags FROM deals WHERE user_id = ? AND tags IS NOT NULL AND tags != ""'); $stmt->execute([$user_id]); } $all_tags = []; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $tags = explode(',', $row['tags']); foreach ($tags as $tag) { $trimmed_tag = trim($tag); if (!empty($trimmed_tag)) { $all_tags[$trimmed_tag] = 1; } } } echo json_encode(['success' => true, 'data' => array_keys($all_tags)]); break; case 'add_deal': $data = $_POST; $sql = "INSERT INTO deals (user_id, name, vendor, website, purchase_date, price, currency, username, password, category, tags, rating) VALUES (:user_id, :name, :vendor, :website, :purchase_date, :price, :currency, :username, :password, :category, :tags, :rating)"; $stmt = $pdo->prepare($sql); $stmt->execute([ ':user_id' => $user_id, ':name' => $data['name'] ?? null, ':vendor' => $data['vendor'] ?? null, ':website' => $data['website'] ?? null, ':purchase_date' => !empty($data['purchaseDate']) ? $data['purchaseDate'] : null, ':price' => $data['price'] ?? 0.00, ':currency' => $data['currency'] ?? 'USD', ':username' => $data['username'] ?? null, ':password' => $data['password'] ?? null, ':category' => $data['category'] ?? null, ':tags' => $data['tags'] ?? null, ':rating' => $data['rating'] ?? 0 ]); $deal_id = $pdo->lastInsertId(); handle_file_uploads($deal_id, $pdo); echo json_encode(['success' => true, 'message' => 'Deal added successfully.']); break; case 'update_deal': $data = $_POST; $deal_id = $data['id'] ?? null; if (!$deal_id) { throw new Exception('Deal ID is required for update.'); } // Verify ownership before update $stmt = $pdo->prepare("SELECT user_id FROM deals WHERE id = ?"); $stmt->execute([$deal_id]); $deal_owner_id = $stmt->fetchColumn(); if (!$deal_owner_id || ($deal_owner_id != $user_id && !is_admin())) { http_response_code(403); throw new Exception('You do not have permission to update this deal.'); } $sql = "UPDATE deals SET name=:name, vendor=:vendor, website=:website, purchase_date=:purchase_date, price=:price, currency=:currency, username=:username, password=:password, category=:category, tags=:tags, rating=:rating WHERE id=:id"; $stmt = $pdo->prepare($sql); $stmt->execute([ ':id' => $deal_id, ':name' => $data['name'] ?? null, ':vendor' => $data['vendor'] ?? null, ':website' => $data['website'] ?? null, ':purchase_date' => !empty($data['purchaseDate']) ? $data['purchaseDate'] : null, ':price' => $data['price'] ?? 0.00, ':currency' => $data['currency'] ?? 'USD', ':username' => $data['username'] ?? null, ':password' => $data['password'] ?? null, ':category' => $data['category'] ?? null, ':tags' => $data['tags'] ?? null, ':rating' => $data['rating'] ?? 0 ]); handle_file_uploads($deal_id, $pdo); echo json_encode(['success' => true, 'message' => 'Deal updated successfully.']); break; case 'delete_deal': $data = json_decode(file_get_contents('php://input'), true); $deal_id = $data['id'] ?? null; if (!$deal_id) { throw new Exception('Deal ID is required.'); } // First, get file names to delete from server $stmt_files = $pdo->prepare("SELECT stored_filename FROM deal_files WHERE deal_id = ?"); $stmt_files->execute([$deal_id]); $files_to_delete = $stmt_files->fetchAll(PDO::FETCH_COLUMN); if (is_admin()) { $stmt = $pdo->prepare('DELETE FROM deals WHERE id = ?'); $stmt->execute([$deal_id]); } else { $stmt = $pdo->prepare('DELETE FROM deals WHERE id = ? AND user_id = ?'); $stmt->execute([$deal_id, $user_id]); } if ($stmt->rowCount() > 0) { foreach ($files_to_delete as $filename) { $file_path = __DIR__ . '/uploads/' . $filename; if (file_exists($file_path)) { unlink($file_path); } } echo json_encode(['success' => true, 'message' => 'Deal deleted successfully.']); } else { http_response_code(403); echo json_encode(['success' => false, 'error' => 'You do not have permission to delete this deal or it does not exist.']); } break; case 'delete_deal_file': $data = json_decode(file_get_contents('php://input'), true); $file_id = $data['id'] ?? null; if (!$file_id) { throw new Exception('File ID is required.'); } $stmt = $pdo->prepare("SELECT df.stored_filename, d.user_id FROM deal_files df JOIN deals d ON df.deal_id = d.id WHERE df.id = ?"); $stmt->execute([$file_id]); $file_info = $stmt->fetch(PDO::FETCH_ASSOC); if ($file_info && (is_admin() || $file_info['user_id'] == $user_id)) { $file_path = __DIR__ . '/uploads/' . $file_info['stored_filename']; if (file_exists($file_path)) { unlink($file_path); } $delete_stmt = $pdo->prepare("DELETE FROM deal_files WHERE id = ?"); $delete_stmt->execute([$file_id]); echo json_encode(['success' => true, 'message' => 'File deleted.']); } else { http_response_code(403); echo json_encode(['success' => false, 'error' => 'Permission denied.']); } break; // ... other cases from before ... default: http_response_code(400); echo json_encode(['success' => false, 'error' => 'Invalid action.']); break; } } catch (Exception $e) { // If the exception is due to require_login, the header is already sent. if (!headers_sent()) { http_response_code(500); echo json_encode(['success' => false, 'error' => $e->getMessage()]); } }