userFolder = $serverContainer->getUserFolder($UserId); } /** * @PublicPage * @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 = DateTime::createFromFormat(DateTime::RFC1123, $acceptDatetimeHeader) ->getTimestamp(); } 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'); $response->addHeader('Link', "<{$chosenMemento['originalUrl']}>; rel=\"original\""); 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]; }