57.956 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-07-09 17:09:58.733 [info] [fetchCompletions] Request 2e2d80ab-f793-4a03-9b54-ea0075d59eec at finished with 200 status after 335.80771600082517ms 2025-07-09 17:09:58.735 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-07-09 17:09:59.034 [info] [fetchCompletions] Request 3689defc-7016-431f-a01e-ca82de6b2418 at finished with 200 status after 1029.4881980009377ms 2025-07-09 17:10:10.467 [info] [fetchCompletions] Request a2dbdf25-5618-4fbf-89d6-d608ef06c145 at finished with 200 status after 244.60035099834204ms 2025-07-09 17:10:10.469 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-07-09 17:10:10.616 [info] [fetchCompletions] Request fe7d602c-2d1d-4b12-80b2-d38f33326a29 at finished with 200 status after 139.6412380002439ms 2025-07-09 17:10:10.617 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-07-09 17:10:27.741 [info] [fetchCompletions] Request fbf34dfe-6614-4882-85c1-86007ee58065 at finished with 200 status after 191.61710599809885ms 2025-07-09 17:10:27.743 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-07-09 17:10:28.017 [info] [fetchCompletions] Request 67a35c56-1050-455e-99cc-f61f63a1ff8e at finished with 200 status after 266.7756769992411ms 2025-07-09 17:10:28.019 [info] [streamChoices] solution 0 returned. finish reason: [null] 2025-07-09 17:11:06.734 [info] [fetchCompletions] Request d22a13bd-6ebf-4fd6-9dba-2266ea2d4c47 at finished with 200 status after 262.68914299830794ms 2025-07-09 17:11:06.736 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-07-09 17:37:23.700 [info] [fetcher] Using Helix fetcher, Electron fetcher is not available. 2025-07-09 17:37:23.700 [info] [code-referencing] Public code references are enabled. 2025-07-09 17:37:23.702 [info] [fetcher] Using Helix fetcher, Electron fetcher is not available. 2025-07-09 17:37:24.088 [info] [fetchCompletions] Request 20c9ef78-e184-43ce-b2b3-c0edf37d9496 at finished with 200 status after 375.827514000237ms 2025-07-09 17:37:24.090 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-07-09 17:37:51.380 [info] [fetchCompletions] Request d95914b5-bb17-488c-aa26-e380d7c1873e at finished with 200 status after 256.61812200024724ms 2025-07-09 17:37:51.381 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-07-09 17:37:51.684 [info] [fetchCompletions] Request d8e6dd08-e5e3-412b-a221-74ea7ba29ae8 at finished with 200 status after 186.63759499788284ms 2025-07-09 17:37:51.685 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-07-09 17:37:51.840 [info] [fetchCompletions] Request 13bd160f-d4bd-4377-88db-3cd899009188 at finished with 200 status after 148.39469899982214ms 2025-07-09 17:37:51.842 [info] [streamChoices] solution 0 returned. finish reason: [stop] 2025-07-09 17:37:52.859 [info] [fetchCompletions] Request 94e73f57-7053-4f45-98d7-7192cab0212c at finished with 200 status after 206.92477100342512ms 2025-07-09 17:37:52.861 [info] [streamChoices] solu null, 'field_config' => 'quick_view', 'fields' => [], 'max_records' => 200, 'environment' => null, 'demo_user_name'=> null, ], $options); do { // Construir URL y query string $query = [ 'max_records' => $opts['max_records'], 'field_config' => $opts['field_config'], ]; if ($opts['criteria']) { $query['criteria'] = $opts['criteria']; } if ($opts['field_config'] === 'custom' && $opts['fields']) { $query['fields'] = implode(',', $opts['fields']); } $url = "https://{$baseUrl}/creator/v2.1/data/{$owner}/{$appLink}/report/{$reportLink}" . '?' . http_build_query($query); // Inicializar cURL $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, // No usar CURLOPT_HEADER = true, sino un HEADERFUNCTION para capturar solo headers CURLOPT_HTTPHEADER => array_filter([ "Authorization: Zoho-oauthtoken {$accessToken}", "accept: application/json", $opts['environment'] ? "environment: {$opts['environment']}" : null, $opts['demo_user_name']? "demo_user_name: {$opts['demo_user_name']}" : null, $cursor ? "record_cursor: {$cursor}" : null, ]), // Capturar encabezados CURLOPT_HEADERFUNCTION => function($curl, $headerLine) use (&$responseHeaders) { $len = strlen($headerLine); if (strpos($headerLine, ':') !== false) { list($name, $value) = explode(':', trim($headerLine), 2); $responseHeaders[strtolower($name)] = trim($value); } return $len; }, ]); $body = curl_exec($ch); if ($body === false) { throw new Exception('cURL error: ' . curl_error($ch)); } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200) { $err = json_decode($body, true); $msg = $err['message'] ?? $body; throw new Exception("Error HTTP {$httpCode}: {$msg}"); } // Decodificar y acumular registros $data = json_decode($body, true); if (!isset($data['data']) || !is_array($data['data'])) { throw new Exception('Respuesta inesperada: falta la clave "data".'); } $allRecords = array_merge($allRecords, $data['data']); // Verificar paginación $nextCursor = $responseHeaders['record_cursor'] ?? null; $cursor = $nextCursor ?: null; // limpiar los headers previos $responseHeaders = []; } while ($cursor); return $allRecords; } try { // Antes de la primera llamada: $responseHeaders = []; $records = fetchZohoCreatorReport( '1000.afe37299bfdd8b0ad54a25c51cb4b7e5.5f273f165ac5b2f98e0a5bd152bbc575', 'www.zohoapis.com', 'arochiylindner.aptus', 'cfdi', 'cfdi_I_query', [ 'field_config' => 'all', 'max_records' => 200, ] ); echo json_encode([ 'error' => false, 'total' => count($records), 'records' => $records ], JSON_PRETTY_PRINT); } catch (Exception $e) { http_response_code(500); echo json_encode([ 'error' => true, 'message' => $e->getMessage() ]); exit; }