Add a function to get when feeds were last updated

This is an optimization for Fever, which returns this information with
every API call.
This commit is contained in:
J. King 2019-03-26 16:51:44 -04:00
parent acb3973149
commit d8407330a0
2 changed files with 40 additions and 4 deletions

View file

@ -10,7 +10,6 @@ use JKingWeb\DrUUID\UUID;
use JKingWeb\Arsse\Db\Statement;
use JKingWeb\Arsse\Misc\Query;
use JKingWeb\Arsse\Context\Context;
use JKingWeb\Arsse\Context\ExclusionContext;
use JKingWeb\Arsse\Misc\Date;
use JKingWeb\Arsse\Misc\ValueInfo;
@ -751,6 +750,8 @@ class Database {
arsse_subscriptions.feed as feed,
url,favicon,source,folder,pinned,err_count,err_msg,order_type,added,
arsse_feeds.updated as updated,
arsse_feeds.modified as edited,
arsse_subscriptions.modified as modified,
topmost.top as top_folder,
coalesce(arsse_subscriptions.title, arsse_feeds.title) as title,
(articles - marked) as unread
@ -946,6 +947,23 @@ class Database {
return (string) $this->db->prepare($q->getQuery(), $q->getTypes())->run($q->getValues())->getValue();
}
/** Returns the time at which any of a user's subscriptions (or a specific subscription) was last refreshed, as a DateTimeImmutable object */
public function subscriptionRefreshed(string $user, int $id = null) {
if (!Arsse::$user->authorize($user, __FUNCTION__)) {
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
}
$q = new Query("SELECT max(arsse_feeds.updated) from arsse_feeds join arsse_subscriptions on arsse_subscriptions.feed = arsse_feeds.id");
$q->setWhere("arsse_subscriptions.owner = ?", "str", $user);
if ($id) {
$q->setWhere("arsse_subscriptions.id = ?", "int", $id);
}
$out = $this->db->prepare($q->getQuery(), $q->getTypes())->run($q->getValues())->getValue();
if (!$out && $id) {
throw new Db\ExceptionInput("subjectMissing", ["action" => __FUNCTION__, "field" => "feed", 'id' => $id]);
}
return ValueInfo::normalize($out, ValueInfo::T_DATE | ValueInfo::M_NULL, "sql");
}
/** Ensures the specified subscription exists and raises an exception otherwise
*
* Returns an associative array containing the id of the subscription and the id of the underlying newsfeed

View file

@ -47,6 +47,7 @@ trait SeriesSubscription {
'title' => "str",
'username' => "str",
'password' => "str",
'updated' => "datetime",
'next_fetch' => "datetime",
'favicon' => "str",
],
@ -134,9 +135,9 @@ trait SeriesSubscription {
],
];
$this->data['arsse_feeds']['rows'] = [
[1,"http://example.com/feed1", "Ook", "", "",strtotime("now"),''],
[2,"http://example.com/feed2", "eek", "", "",strtotime("now - 1 hour"),'http://example.com/favicon.ico'],
[3,"http://example.com/feed3", "Ack", "", "",strtotime("now + 1 hour"),''],
[1,"http://example.com/feed1", "Ook", "", "",strtotime("now"),strtotime("now"),''],
[2,"http://example.com/feed2", "eek", "", "",strtotime("now - 1 hour"),strtotime("now - 1 hour"),'http://example.com/favicon.ico'],
[3,"http://example.com/feed3", "Ack", "", "",strtotime("now + 1 hour"),strtotime("now + 1 hour"),''],
];
// initialize a partial mock of the Database object to later manipulate the feedUpdate method
Arsse::$db = Phake::partialMock(Database::class, static::$drv);
@ -491,4 +492,21 @@ trait SeriesSubscription {
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1);
}
public function testGetRefreshTimeOfASubscription() {
$user = "john.doe@example.com";
$this->assertTime(strtotime("now + 1 hour"), Arsse::$db->subscriptionRefreshed($user));
$this->assertTime(strtotime("now - 1 hour"), Arsse::$db->subscriptionRefreshed($user, 1));
}
public function testGetRefreshTimeOfAMissingSubscription() {
$this->assertException("subjectMissing", "Db", "ExceptionInput");
$this->assertTime(strtotime("now - 1 hour"), Arsse::$db->subscriptionRefreshed("john.doe@example.com", 2));
}
public function testGetRefreshTimeOfASubscriptionWithoutAuthority() {
Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
$this->assertTime(strtotime("now + 1 hour"), Arsse::$db->subscriptionRefreshed("john.doe@example.com"));
}
}