Merge pull request #10409 from annando/api-link-header

Set the "Link" header
This commit is contained in:
Hypolite Petovan 2021-06-16 16:16:35 -04:00 committed by GitHub
commit 59204d641d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 98 additions and 18 deletions

View file

@ -77,6 +77,7 @@ class Followers extends BaseApi
$followers = DBA::select('contact-relation', ['relation-cid'], $condition, $parameters);
while ($follower = DBA::fetch($followers)) {
self::setBoundaries($follower['relation-cid']);
$accounts[] = DI::mstdnAccount()->createFromContactId($follower['relation-cid'], $uid);
}
DBA::close($followers);
@ -85,6 +86,7 @@ class Followers extends BaseApi
array_reverse($accounts);
}
self::setLinkHeader();
System::jsonExit($accounts);
}
}

View file

@ -77,6 +77,7 @@ class Following extends BaseApi
$followers = DBA::select('contact-relation', ['cid'], $condition, $parameters);
while ($follower = DBA::fetch($followers)) {
self::setBoundaries($follower['cid']);
$accounts[] = DI::mstdnAccount()->createFromContactId($follower['cid'], $uid);
}
DBA::close($followers);
@ -85,6 +86,7 @@ class Following extends BaseApi
array_reverse($accounts);
}
self::setLinkHeader();
System::jsonExit($accounts);
}
}

View file

@ -108,6 +108,7 @@ class Statuses extends BaseApi
$statuses = [];
while ($item = Post::fetch($items)) {
self::setBoundaries($item['uri-id']);
$statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
}
DBA::close($items);
@ -116,6 +117,7 @@ class Statuses extends BaseApi
array_reverse($statuses);
}
self::setLinkHeader();
System::jsonExit($statuses);
}
}

View file

@ -77,6 +77,7 @@ class Blocks extends BaseApi
$followers = DBA::select('user-contact', ['cid'], $condition, $parameters);
while ($follower = DBA::fetch($followers)) {
self::setBoundaries($follower['cid']);
$accounts[] = DI::mstdnAccount()->createFromContactId($follower['cid'], $uid);
}
DBA::close($followers);
@ -85,6 +86,7 @@ class Blocks extends BaseApi
array_reverse($accounts);
}
self::setLinkHeader();
System::jsonExit($accounts);
}
}

View file

@ -72,6 +72,7 @@ class Bookmarks extends BaseApi
$statuses = [];
while ($item = Post::fetch($items)) {
self::setBoundaries($item['uri-id']);
$statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
}
DBA::close($items);
@ -80,6 +81,7 @@ class Bookmarks extends BaseApi
array_reverse($statuses);
}
self::setLinkHeader();
System::jsonExit($statuses);
}
}

View file

@ -85,6 +85,7 @@ class Conversations extends BaseApi
$conversations = [];
while ($conv = DBA::fetch($convs)) {
self::setBoundaries($conv['id']);
$conversations[] = DI::mstdnConversation()->CreateFromConvId($conv['id']);
}
@ -94,6 +95,7 @@ class Conversations extends BaseApi
array_reverse($conversations);
}
self::setLinkHeader();
System::jsonExit($conversations);
}
}

View file

@ -70,6 +70,7 @@ class Favourited extends BaseApi
$statuses = [];
while ($item = Post::fetch($items)) {
self::setBoundaries($item['thr-parent-id']);
$statuses[] = DI::mstdnStatus()->createFromUriId($item['thr-parent-id'], $uid);
}
DBA::close($items);
@ -78,6 +79,7 @@ class Favourited extends BaseApi
array_reverse($statuses);
}
self::setLinkHeader();
System::jsonExit($statuses);
}
}

View file

@ -92,8 +92,6 @@ class FollowRequests extends BaseApi
'limit' => 40, // Maximum number of results to return. Defaults to 40. Paginate using the HTTP Link header.
]);
$baseUrl = DI::baseUrl();
$introductions = DI::intro()->selectByBoundaries(
['`uid` = ? AND NOT `ignore`', $uid],
['order' => ['id' => 'DESC']],
@ -106,6 +104,7 @@ class FollowRequests extends BaseApi
foreach ($introductions as $key => $introduction) {
try {
self::setBoundaries($introduction->id);
$return[] = DI::mstdnFollowRequest()->createFromIntroduction($introduction);
} catch (HTTPException\InternalServerErrorException $exception) {
DI::intro()->delete($introduction);
@ -113,22 +112,7 @@ class FollowRequests extends BaseApi
}
}
$base_query = [];
if (isset($_GET['limit'])) {
$base_query['limit'] = $request['limit'];
}
$links = [];
if ($introductions->getTotalCount() > $request['limit']) {
$links[] = '<' . $baseUrl->get() . '/api/v1/follow_requests?' . http_build_query($base_query + ['max_id' => $introductions[count($introductions) - 1]->id]) . '>; rel="next"';
}
if (count($introductions)) {
$links[] = '<' . $baseUrl->get() . '/api/v1/follow_requests?' . http_build_query($base_query + ['min_id' => $introductions[0]->id]) . '>; rel="prev"';
}
header('Link: ' . implode(', ', $links));
self::setLinkHeader();
System::jsonExit($return);
}
}

View file

@ -95,6 +95,7 @@ class Accounts extends BaseApi
$members = DBA::select('group_member', ['contact-id'], $condition, $params);
while ($member = DBA::fetch($members)) {
self::setBoundaries($member['contact-id']);
$accounts[] = DI::mstdnAccount()->createFromContactId($member['contact-id'], $uid);
}
DBA::close($members);
@ -103,6 +104,7 @@ class Accounts extends BaseApi
array_reverse($accounts);
}
self::setLinkHeader();
System::jsonExit($accounts);
}
}

View file

@ -77,6 +77,7 @@ class Mutes extends BaseApi
$followers = DBA::select('user-contact', ['cid'], $condition, $parameters);
while ($follower = DBA::fetch($followers)) {
self::setBoundaries($follower['cid']);
$accounts[] = DI::mstdnAccount()->createFromContactId($follower['cid'], $uid);
}
DBA::close($followers);
@ -85,6 +86,7 @@ class Mutes extends BaseApi
array_reverse($accounts);
}
self::setLinkHeader();
System::jsonExit($accounts);
}
}

View file

@ -128,6 +128,7 @@ class Notifications extends BaseApi
$notify = DBA::select('notification', ['id'], $condition, $params);
while ($notification = DBA::fetch($notify)) {
self::setBoundaries($notification['id']);
$entry = DI::mstdnNotification()->createFromNotificationId($notification['id']);
if (!empty($entry)) {
$notifications[] = $entry;
@ -138,6 +139,7 @@ class Notifications extends BaseApi
array_reverse($notifications);
}
self::setLinkHeader();
System::jsonExit($notifications);
}
}

View file

@ -162,6 +162,7 @@ class Search extends BaseApi
$statuses = [];
while ($item = Post::fetch($items)) {
self::setBoundaries($item['uri-id']);
$statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
}
DBA::close($items);
@ -170,6 +171,7 @@ class Search extends BaseApi
array_reverse($statuses);
}
self::setLinkHeader();
return $statuses;
}

View file

@ -71,6 +71,7 @@ class Direct extends BaseApi
$statuses = [];
while ($mail = DBA::fetch($mails)) {
self::setBoundaries($mail['uri-id']);
$statuses[] = DI::mstdnStatus()->createFromMailId($mail['id']);
}
@ -78,6 +79,7 @@ class Direct extends BaseApi
array_reverse($statuses);
}
self::setLinkHeader();
System::jsonExit($statuses);
}
}

View file

@ -93,6 +93,7 @@ class Home extends BaseApi
$statuses = [];
while ($item = Post::fetch($items)) {
self::setBoundaries($item['uri-id']);
$statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
}
DBA::close($items);
@ -101,6 +102,7 @@ class Home extends BaseApi
array_reverse($statuses);
}
self::setLinkHeader();
System::jsonExit($statuses);
}
}

View file

@ -98,6 +98,7 @@ class ListTimeline extends BaseApi
$statuses = [];
while ($item = Post::fetch($items)) {
self::setBoundaries($item['uri-id']);
$statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
}
DBA::close($items);
@ -106,6 +107,7 @@ class ListTimeline extends BaseApi
array_reverse($statuses);
}
self::setLinkHeader();
System::jsonExit($statuses);
}
}

View file

@ -99,6 +99,7 @@ class PublicTimeline extends BaseApi
$statuses = [];
while ($item = Post::fetch($items)) {
self::setBoundaries($item['uri-id']);
$statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $item['uid']);
}
DBA::close($items);
@ -107,6 +108,7 @@ class PublicTimeline extends BaseApi
array_reverse($statuses);
}
self::setLinkHeader();
System::jsonExit($statuses);
}
}

View file

@ -107,6 +107,7 @@ class Tag extends BaseApi
$statuses = [];
while ($item = Post::fetch($items)) {
self::setBoundaries($item['uri-id']);
$statuses[] = DI::mstdnStatus()->createFromUriId($item['uri-id'], $uid);
}
DBA::close($items);
@ -115,6 +116,7 @@ class Tag extends BaseApi
array_reverse($statuses);
}
self::setLinkHeader();
System::jsonExit($statuses);
}
}

View file

@ -44,6 +44,16 @@ class BaseApi extends BaseModule
*/
protected static $format = 'json';
/**
* @var array
*/
protected static $boundaries = [];
/**
* @var array
*/
protected static $request = [];
public static function init(array $parameters = [])
{
$arguments = DI::args();
@ -129,6 +139,11 @@ class BaseApi extends BaseModule
$httpinput = HTTPInputData::process();
$input = array_merge($httpinput['variables'], $httpinput['files'], $_REQUEST);
self::$request = $input;
self::$boundaries = [];
unset(self::$request['pagename']);
$request = [];
foreach ($defaults as $parameter => $defaultvalue) {
@ -160,6 +175,55 @@ class BaseApi extends BaseModule
return $request;
}
/**
* Set boundaries for the "link" header
* @param array $boundaries
* @param int $id
* @return array
*/
protected static function setBoundaries(int $id)
{
if (!isset(self::$boundaries['min'])) {
self::$boundaries['min'] = $id;
}
if (!isset(self::$boundaries['max'])) {
self::$boundaries['max'] = $id;
}
self::$boundaries['min'] = min(self::$boundaries['min'], $id);
self::$boundaries['max'] = max(self::$boundaries['max'], $id);
}
/**
* Set the "link" header with "next" and "prev" links
* @return void
*/
protected static function setLinkHeader()
{
if (empty(self::$boundaries)) {
return;
}
$request = self::$request;
unset($request['min_id']);
unset($request['max_id']);
unset($request['since_id']);
$prev_request = $next_request = $request;
$prev_request['min_id'] = self::$boundaries['max'];
$next_request['max_id'] = self::$boundaries['min'];
$command = DI::baseUrl() . '/' . DI::args()->getCommand();
$prev = $command . '?' . http_build_query($prev_request);
$next = $command . '?' . http_build_query($next_request);
header('Link: <' . $next . '>; rel="next", <' . $prev . '>; rel="prev"');
}
/**
* Get current application token
*