userFolder = $serverContainer->getUserFolder($UserId); $this->URLGenerator = $URLGenerator; } /** * @NoAdminRequired * @NoCSRFRequired */ public function timeGate($url) { $matchingMementos = findMementos($this->userFolder, $url); // Choose one of the matched mementos, if any. if (count($matchingMementos) === 0) { // No matches. :( $message = "

No snapshots found for requested URL. :(

"; return new DataDisplayResponse($message, 404); } else if (count($matchingMementos) === 1) { // One match; no need to choose. $chosenMemento = $matchingMementos[0]; } else { // Multiple matches: choose based on requested date. $acceptDatetimeHeader = $this->request->getHeader('Accept-Datetime'); if ($acceptDatetimeHeader) { try { $requestedDatetime = datetimeStringToTimestamp($acceptDatetimeHeader); } catch (Exception $e) { return new DataDisplayResponse("Invalid Accept-Datetime header.", 400); } } else { // Not sending the header means requesting the most recent version. $requestedDatetime = time(); } // Pick the one closest to the requested date (either before or after it). $chosenMemento = minBy($matchingMementos, function ($matchingMemento) use ($requestedDatetime) { return abs($matchingMemento['datetime'] - $requestedDatetime); } ); } // Send a 302 Found redirect pointing to the chosen memento. $response = new RedirectResponse($chosenMemento['mementoUrl']); $response->setStatus(302); $response->addHeader('Vary', 'accept-datetime'); // Add a link to the original and to the timemap. $originalLink = "<{$chosenMemento['originalUrl']}>;rel=\"original\""; // XXX hardcoding the route URL. $timeMapUrl = $this->URLGenerator->getAbsoluteUrl("/apps/memento/timemap/$url"); $firstDatetime = datetimeTimestampToString($matchingMementos[0]['datetime']); $lastMemento = $matchingMementos[count($matchingMementos)-1]; $lastDatetime = datetimeTimestampToString($lastMemento['datetime']); $timeMapLink = "<$timeMapUrl>" . ";rel=\"timemap\"" . ";type=\"application/link-format\"" . ";from=\"$firstDatetime\";until=\"$lastDatetime\""; $response->addHeader('Link', "$originalLink, $timeMapLink"); return $response; } } function minBy($array, $iteratee) { // is there any simpler way for this in php? $values = array_map($iteratee, $array); $argmin = array_search(min($values), $values); return $array[$argmin]; }