'Invalid or missing Widget ID.']); exit; } // --- Load Config --- $configFile = __DIR__.'/../configs/widgets/'.$widgetId.'.json'; if (!file_exists($configFile)) { http_response_code(404); echo json_encode(['error' => 'Configuration file not found for '.htmlspecialchars($widgetId)]); exit; } $config = json_decode(file_get_contents($configFile), true); $data = []; $sourceType = $config['dataSource']['type']; // --- Pagination --- $paginationEnabled = $config['displayOptions']['pagination']['enabled'] ?? false; $page = (int) ($_GET['page'] ?? 1); $limit = (int) ($config['displayOptions']['pagination']['limit'] ?? 10); $offset = ($page - 1) * $limit; $totalRecords = 0; try { switch ($sourceType) { case 'db': $dbConf = $config['dataSource']['connection']; $query = $config['dataSource']['query']; $pdo = new PDO( "mysql:host={$dbConf['host']};dbname={$dbConf['dbname']};charset=utf8mb4", $dbConf['user'], $dbConf['password'] ); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); if ($paginationEnabled) { // Get total records for pagination $countQuery = "SELECT COUNT(*) FROM (".$query.") AS total_count_query"; $totalRecords = (int) $pdo->query($countQuery)->fetchColumn(); // Add LIMIT and OFFSET to the original query $query .= " LIMIT :limit OFFSET :offset"; } $stmt = $pdo->prepare($query); if ($paginationEnabled) { $stmt->bindParam(':limit', $limit, PDO::PARAM_INT); $stmt->bindParam(':offset', $offset, PDO::PARAM_INT); } $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); break; case 'api': $apiConf = $config['dataSource']['request']; $ch = curl_init($apiConf['endpoint']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $apiConf['method'] ?? 'GET'); $headers = []; foreach ($apiConf['headers'] ?? [] as $key => $value) { $headers[] = "$key: $value"; } curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if (curl_errno($ch) || $httpCode >= 400) { throw new Exception("API request failed. HTTP Code: {$httpCode}. Error: ".curl_error($ch)); } curl_close($ch); $fullData = json_decode($response, true); if ($paginationEnabled) { $totalRecords = count($fullData); $data = array_slice($fullData, $offset, $limit); } else { $data = $fullData; } break; case 'csv': $csvPath = __DIR__.'/../'.$config['dataSource']['path']; if (!file_exists($csvPath)) { throw new Exception("CSV file not found at {$csvPath}"); } $file = fopen($csvPath, 'r'); $headers = fgetcsv($file, 0, ",", '"', '\\'); $fullData = []; while (($row = fgetcsv($file, 0, ",", '"', '\\')) !== false) { $fullData[] = array_combine($headers, $row); } fclose($file); if ($paginationEnabled) { $totalRecords = count($fullData); $data = array_slice($fullData, $offset, $limit); } else { $data = $fullData; } break; } } catch (Exception $e) { http_response_code(500); echo json_encode(['error' => 'Data source error']); exit; } $responsePayload = [ 'data' => $data ]; if ($paginationEnabled) { $responsePayload['pagination'] = [ 'totalRecords' => $totalRecords, 'currentPage' => $page, 'limit' => $limit, 'totalPages' => ceil($totalRecords / $limit) ]; } echo json_encode($responsePayload);