public static function multiGetFromCiteServer($mode, $sets, $style = 'chicago-note-bibliography') { require_once "../include/RollingCurl.inc.php"; $t = microtime(true); $setIDs = array(); $data = array(); $requestCallback = function ($response, $info) use($mode, &$setIDs, &$data) { if ($info['http_code'] != 200) { error_log("WARNING: HTTP {$info['http_code']} from citeserver {$mode} request: " . $response); return; } $response = json_decode($response); if (!$response) { error_log("WARNING: Invalid response from citeserver {$mode} request: " . $response); return; } $str = parse_url($info['url']); $str = parse_str($str['query']); if ($mode == 'citation') { $data[$setIDs[$setID]] = Zotero_Cite::processCitationResponse($response); } else { if ($mode == "bib") { $data[$setIDs[$setID]] = Zotero_Cite::processBibliographyResponse($response); } } }; $rc = new RollingCurl($requestCallback); // Number of simultaneous requests $rc->window_size = 20; foreach ($sets as $key => $items) { $json = self::getJSONFromItems($items); $server = Z_CONFIG::$CITATION_SERVERS[array_rand(Z_CONFIG::$CITATION_SERVERS)]; $url = "http://{$server}/?responseformat=json&style={$style}"; if ($mode == 'citation') { $url .= "&citations=1&bibliography=0"; } // Include array position in URL so that the callback can figure // out what request this was $url .= "&setID=" . $key; // TODO: support multiple items per set, if necessary if (!$items instanceof Zotero_Item) { throw new Exception("items is not a Zotero_Item"); } $setIDs[$key] = $items->libraryID . "/" . $items->key; $request = new RollingCurlRequest($url); $request->options = array(CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $json, CURLOPT_HTTPHEADER => array("Expect:"), CURLOPT_CONNECTTIMEOUT => 1, CURLOPT_TIMEOUT => 4, CURLOPT_HEADER => 0, CURLOPT_RETURNTRANSFER => 1); $rc->add($request); } $rc->execute(); error_log(sizeOf($sets) . " {$mode} requests in " . round(microtime(true) - $t, 3)); return $data; }