diff --git a/appinfo/routes.php b/appinfo/routes.php index 2704bd5..c305c6e 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -6,5 +6,7 @@ return [ 'requirements' => array('url' => '.+')], ['name' => 'timeGate#timeGate', 'url' => '/timegate/{url}', 'verb' => 'GET', 'requirements' => array('url' => '.+')], + ['name' => 'timeMap#timeMap', 'url' => '/timemap/{url}', 'verb' => 'GET', + 'requirements' => array('url' => '.+')], ] ]; diff --git a/lib/Controller/TimeMapController.php b/lib/Controller/TimeMapController.php new file mode 100644 index 0000000..2cceb54 --- /dev/null +++ b/lib/Controller/TimeMapController.php @@ -0,0 +1,82 @@ +userFolder = $serverContainer->getUserFolder($UserId); + $this->URLGenerator = $URLGenerator; + } + + /** + * @PublicPage + * @NoAdminRequired + * @NoCSRFRequired + */ + public function timeMap($url) { + $matchingMementos = findMementos($this->userFolder, $url); + + // Build the list of links. + // $timeMapUrl = $this->URLGenerator->linkToRouteAbsolute('timeMap#timeMap', [ 'url' => $url ]); + // $timeGateUrl = $this->URLGenerator->linkToRouteAbsolute('timeGate#timeGate', [ 'url' => $url ]); + // FIXME ...is linkToRouteAbsolute broken? Hardcoding the path then.. + $timeMapUrl = $this->URLGenerator->getAbsoluteUrl("/apps/memento/timemap/$url"); + $timeGateUrl = $this->URLGenerator->getAbsoluteUrl("/apps/memento/timegate/$url"); + if (count($matchingMementos) > 0) { + $firstDatetime = formatDatetime($matchingMementos[0]['datetime']); + $lastDatetime = formatDatetime($matchingMementos[count($matchingMementos)-1]['datetime']); + } + $links = [ + // FIXME Our $url param has its duplicate slashes removed, so it looks like 'http:/abc'. + "<$url>;rel=\"original\"", + "<$timeGateUrl>;rel=\"timegate\"", + "<$timeMapUrl>;rel=\"self\";type=\"application/link-format\"" . + ($firstDatetime && $lastDatetime ? ";from=\"$firstDatetime\";until=\"$lastDatetime\"" : "") + ]; + foreach ($matchingMementos as $index => $memento) { + $datetime = formatDatetime($memento['datetime']); + $maybeFirst = $index === 0 ? 'first ' : ''; + $maybeLast = $index === count($matchingMementos)-1 ? 'last ' : ''; + // Make absolute, as the spec says URLs are to be interpreted relative to the *original* url! + $absoluteMementoUrl = $this->URLGenerator->getAbsoluteURL($memento['mementoUrl']); + $links[] = "<$absoluteMementoUrl>" + . ";rel=\"{$maybeFirst}{$maybeLast}memento\"" + . ";datetime=\"$datetime\""; + } + $linksString = implode(",\n", $links); + + $headers = [ + "Content-Type" => "application/link-format" + ]; + + $response = new DataDisplayResponse($linksString, 200, $headers); + return $response; + } +} + +function formatDatetime($datetime) { + $datetime = new DateTime("@$datetime"); + $s = $datetime->format("D, d M Y H:i:s") . " GMT"; + return $s; +} diff --git a/lib/Controller/findMementos.php b/lib/Controller/findMementos.php index 3a104dd..b330aed 100644 --- a/lib/Controller/findMementos.php +++ b/lib/Controller/findMementos.php @@ -5,7 +5,7 @@ use DOMDocument; use DateTime; // Finds HTML files that claim to be a snapshot of the given URL; -// Returns an array, each item being a file's url + original url + snapshot datetime. +// Returns an array of each file's url + original url + snapshot datetime, sorted by datetime. function findMementos($folder, $url) { // Get all HTML files the user owns. $files = $folder->searchByMime('text/html'); @@ -40,6 +40,10 @@ function findMementos($folder, $url) { continue; } } + + // Sort mementos by their datetime. Oldest first. + usort($matchingMementos, function ($m1, $m2) { return $m1['datetime'] <=> $m2['datetime']; }); + return $matchingMementos; }