execute('SELECT id FROM kb3_esisso WHERE isEnabled = 1 ORDER by lastKillFetchTimestamp ASC'); } else { $qry->execute('SELECT id FROM kb3_esisso WHERE isEnabled = 1 ORDER by id'); } while($result = $qry->getRow()) { $resultObjects[] = ESIFetch::getByID($result['id']); } return $resultObjects; } public function setLastKillID($lastKillID) { $this->lastKillID = $lastKillID; if(is_null($this->id)) { return; } $updateParams = new \DBPreparedQuery(); $updateParams->prepare('UPDATE kb3_esisso SET lastKillID = ? WHERE id = ?'); $types = 'si'; $arr = array(&$types, &$this->lastKillID, &$this->id); $updateParams->bind_params($arr); if(!$updateParams->execute()) { return false; } return true; } public function getLastKillID() { return $this->lastKillID; } public function updateLastFetchTimestamp() { if(is_null($this->id)) { return false; } $qry = \DBFactory::getDBQuery(); $sql = 'UPDATE kb3_esisso SET lastKillFetchTimestamp = NOW() WHERE id = '.$this->id; if(!$qry->execute($sql)) { return false; } return true; } /** * * @param boolean $ignoreNPCOnlyKills flag indicating whether to ignore NPC only killmails */ public function setIgnoreNpcOnlyKills($ignoreNPCOnlyKills) { if($ignoreNPCOnlyKills === TRUE) { $this->ignoreNPCOnly = TRUE; } else { $this->ignoreNPCOnly = FALSE; } } /** * Reads the ESI killmails using the current ESI SSO configuration * @throws ESIFetchException * @throws \Swagger\Client\ApiException */ public function fetch() { if (is_null($this->id)) { return false; } // create killmail representation // get instance try { $EdkEsi = new ESI(); $EdkEsi->setAccessToken($this->accessToken); $KillmailsApi = new KillmailsApi($EdkEsi); $headers = array(); if($this->keyType == ESISSO::KEY_TYPE_PILOT) { list($this->killLog, , $headers) = $KillmailsApi->getCharactersCharacterIdKillmailsRecentWithHttpInfo($this->characterID, $EdkEsi->getDataSource(), null, $this->page); } else { $Pilot = new \Pilot(0, $this->characterID); $Corporation = $Pilot->getCorp(); list($this->killLog, , $headers) = $KillmailsApi->getCorporationsCorporationIdKillmailsRecentWithHttpInfo($Corporation->getExternalID(), $EdkEsi->getDataSource(), null, $this->page); } $this->resetFailCount(); $this->numberOfPages = $headers['x-pages']; } catch(ApiException $e) { $this->increaseFailCount(); throw new ESIFetchException(ESI::getApiExceptionReason($e), $e->getCode()); } } /** * Increases the failCount for this SSO key */ protected function increaseFailCount() { $qry = \DBFactory::getDBQuery(); $sql = 'UPDATE kb3_esisso SET failCount = failCount+1 WHERE id = '.$this->id; $qry->execute($sql); } /** * Resets the failCount for this SSO key */ protected function resetFailCount() { $qry = \DBFactory::getDBQuery(); $sql = 'UPDATE kb3_esisso SET failCount = 0 WHERE id = '.$this->id; $qry->execute($sql); } /** * processes all kills for this fetch cycle * @throws ESIFetchException */ public function processApi() { // remember the timestamp we started with $this->page = 0; $this->killLog = array(); // initialize fetch counter $cyclesFetched = 0; $startKill = $this->lastKillID; $previousParseCount = 0; $latestKillIdFetched = 0; // we need this loop to keep fetching until we don't get any data (because there is no new data) // or we get data containing a kill with a timestamp newer than the timestamp we started with $previousLog = array(); // start time to calculate Processing time $time_start = microtime(true); $this->updateLastFetchTimestamp(); // this will first fetch the oldest kills available, then work its way to the newest ones do { $this->page = $this->page + 1; try { $previousLog = $this->killLog; $this->fetch(); // no kills received if(empty($this->killLog)) { break; } $oldestKillIdOnPage = array_values(array_slice($this->killLog, -1))[0]->getKillmailId(); $newestKillIdOnPage = $this->killLog[0]->getKillmailId(); //Check if we reached the end which seems to append an empty array // OR if the latest kill ID fetched is the last kill ID we posted - in which case we need to process the previously fetched kills (if any) if ($this->page == $this->numberOfPages || ($this->killLog[0]->getKillmailId() > 0 && $oldestKillIdOnPage <= $startKill && $newestKillIdOnPage > $startKill)) { break; } } catch(ESIFetchException $e) { $this->parsemsg[] = $e->getMessage(); break; } catch(Exception $e) { throw $e; } $cyclesFetched++; if($cyclesFetched >= self::$MAXIMUM_NUMBER_OF_CYCLES) { $this->parsemsg[] = "Stopped fetching after ".(self::$MAXIMUM_NUMBER_OF_CYCLES*self::$NUMBER_OF_KILLS_PER_CALL)." kills."; break; } // the first fetch ever does not have a start kill and needs to || if we have a start kill, continue fetching until the oldest kill fetched is less // to continue fetching until the end, which seems to append an empty || than the start kill, and the newest is either newer or the same (no new kills) // array || } while(($startKill == 0 && $this->page == $this->numberOfPages )|| ($startKill > 0 && !($startKill > $oldestKillIdOnPage && $startKill <= $newestKillIdOnPage))); //If the last call returned ampty check the previous one if(empty($this->killLog)) { if($cyclesFetched > 1) { $this->killLog = $previousLog; } else { $this->parsemsg[] = "Did not get any Kills."; } } // add kills to accumulated number of kills fetched from zKB $this->numberOfKillsFetched += count($this->killLog); // loop over all kills foreach(array_reverse($this->killLog) AS $killData) { // check if we reached the maximum number of kills we may fetch if((microtime(true)-$time_start) >= $this->maximumProcessingTime) { $this->parsemsg[] = "Stopped parsing after reaching maximum processing time of ".$this->maximumProcessingTime." seconds."; break; } try { $this->processKill($killData); } catch(ESIFetchException $e) { $this->parsemsg[] = $e->getMessage(); } catch(EsiParserException $e) { $this->parsemsg[] = "Error communicating with ESI: ".$e->getMessage(); } } if (count(array_merge($this->posted, $this->skipped))) { $this->lastKillID = max(array_merge($this->posted, $this->skipped)); $this->setLastKillID($this->lastKillID); } $output = "