isLoggedIn()) { die(json_encode(['success' => false, 'message' => 'Unauthorized'])); } if ($_SERVER['REQUEST_METHOD'] !== 'POST') { die(json_encode(['success' => false, 'message' => 'Invalid request method'])); } $db = Database::getInstance(); $project_id = isset($_POST['project_id']) ? (int)$_POST['project_id'] : 0; if (!$project_id) { die(json_encode(['success' => false, 'message' => 'Invalid project ID'])); } // Verify user has access to this project $stmt = $db->prepare("SELECT id FROM projects WHERE id = ? AND created_by = ?"); $stmt->bind_param('ii', $project_id, $_SESSION['user_id']); $stmt->execute(); if ($stmt->get_result()->num_rows === 0) { die(json_encode(['success' => false, 'message' => 'Access denied'])); } // Get all previously used panelist IDs in this project's selections $stmt = $db->prepare(" SELECT DISTINCT panelist_id FROM selection_members sm JOIN selections s ON sm.selection_id = s.id WHERE s.project_id = ? "); $stmt->bind_param('i', $project_id); $stmt->execute(); $used_panelists_result = $stmt->get_result(); $used_panelists = []; while ($row = $used_panelists_result->fetch_assoc()) { $used_panelists[] = $row['panelist_id']; } // Build WHERE clause based on filter criteria $where_conditions = []; // If we have used panelists, exclude them if (!empty($used_panelists)) { $used_panelists_str = "'" . implode("','", $used_panelists) . "'"; $where_conditions[] = "panelist_id NOT IN ($used_panelists_str)"; } // Process all form inputs $attributes = $db->query("SELECT id, name, choice_type FROM attributes ORDER BY created_at ASC"); while ($attr = $attributes->fetch_assoc()) { $attr_id = $attr['id']; if ($attr['choice_type'] === 'single') { // Single choice attributes if (isset($_POST["attr_{$attr_id}"]) && !empty($_POST["attr_{$attr_id}"])) { $value = $db->escape($_POST["attr_{$attr_id}"]); $where_conditions[] = "JSON_UNQUOTE(JSON_EXTRACT(attribute_values, '$.{$attr_id}')) = '{$value}'"; } } else if ($attr['choice_type'] === 'multiple') { // Multiple choice attributes if (isset($_POST["attr_{$attr_id}"]) && is_array($_POST["attr_{$attr_id}"]) && !empty($_POST["attr_{$attr_id}"])) { $values = array_map(function($value) use ($db) { return $db->escape($value); }, $_POST["attr_{$attr_id}"]); $or_conditions = []; foreach ($values as $value) { // Use JSON_CONTAINS to check if array contains the value $or_conditions[] = "JSON_CONTAINS(attribute_values, '\"{$value}\"', '$.{$attr_id}')"; } $where_conditions[] = '(' . implode(' OR ', $or_conditions) . ')'; } } } // For debugging error_log("Available samples query conditions: " . implode(' AND ', $where_conditions)); // Build the SQL query to get eligible panelists $sql = "SELECT COUNT(*) as available_samples FROM panel_data"; if (!empty($where_conditions)) { $sql .= " WHERE " . implode(' AND ', $where_conditions); } error_log("Available samples SQL: " . $sql); $result = $db->query($sql); if (!$result) { die(json_encode([ 'success' => false, 'message' => 'Error calculating available samples: ' . $db->getLastError() ])); } $available_samples = $result->fetch_assoc()['available_samples']; echo json_encode([ 'success' => true, 'available_samples' => (int)$available_samples ]);