$value) { $lines[] = $name . ': ' . $value; } $context = stream_context_create(array('http' => array( 'method' => $method, 'header' => implode("\r\n", $lines), 'content' => $body === null ? '' : json_encode($body), 'ignore_errors' => true, 'timeout' => 15, ))); $raw = file_get_contents(C1K_BASE . $path, false, $context); $status = 0; $etag = null; $retry = null; foreach (isset($http_response_header) ? $http_response_header : array() as $line) { if (preg_match('#^HTTP/\S+ (\d{3})#', $line, $m)) { $status = (int) $m[1]; } elseif (stripos($line, 'ETag:') === 0) { $etag = trim(substr($line, 5)); } elseif (stripos($line, 'Retry-After:') === 0) { $retry = trim(substr($line, 12)); } } $payload = json_decode((string) $raw, true); if ($status < 200 || $status >= 300) { $e = isset($payload['error']) ? $payload['error'] : array('code' => 'network', 'message' => 'No answer from C1K.', 'request_id' => '-'); throw new RuntimeException($status . ' ' . $e['code'] . ': ' . $e['message'] . ($retry !== null ? ' (retry after ' . $retry . 's)' : '') . ' [' . $e['request_id'] . ']'); } return array($payload, $etag); } // Create with an idempotency key, so a retry after a lost response cannot duplicate the link. list($created, $etag) = c1k('POST', '/links', array( 'destination_url' => 'https://venture.example/launch', 'title' => 'Launch page', 'utm' => array('source' => 'newsletter', 'medium' => 'email'), ), array('Idempotency-Key' => 'example-' . bin2hex(random_bytes(8)))); $link = $created['data']; echo 'created ', $link['short_url'], ' version ', $link['version'], "\n"; // Edit with If-Match carrying the current version from the ETag (API-07). list($edited) = c1k('PATCH', '/links/' . $link['id'], array('title' => 'Launch page (v2)'), array('If-Match' => $etag)); echo 'edited to version ', $edited['data']['version'], "\n"; // List every page. $cursor = null; do { list($page) = c1k('GET', '/links?limit=100' . ($cursor !== null ? '&cursor=' . rawurlencode($cursor) : '')); foreach ($page['data'] as $item) { echo $item['short_url'], ' -> ', $item['destination_url'], "\n"; } $cursor = $page['meta']['next_cursor']; } while ($cursor !== null); // Analytics, then one poll of the change feed; keep meta.next_cursor for the next poll. list($stats) = c1k('GET', '/analytics'); echo 'recorded requests ', $stats['data']['totals']['total'], "\n"; list($feed) = c1k('GET', '/events'); foreach ($feed['data'] as $event) { echo $event['id'], ' ', $event['time'], ' ', $event['action'], "\n"; } echo 'next cursor ', var_export($feed['meta']['next_cursor'], true), "\n";