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];
}