miniflux-legacy/fever/index.php
Mathias Kresin b5b5e91bb0 Fever API - Fix Mark all as read for feed unread
Zero is a valid super group id according to the "mark the Kindling super group
as read" example in the Fever API docs. But the php function empty considers 0
as an empty value and the condition is never true.

The condition has been changed to accept -1 for the "Sparks" super group,
0 for the "Kindling" super group and any other positive integer (feed and
item id must be positive integers).

The group id Zero is used by Reeder for iOS for the virtual feed "unread".
2014-11-06 19:54:12 +01:00

320 lines
7.4 KiB
PHP

<?php
require '../common.php';
use Model\Feed;
use PicoDb\Database;
// Route handler
function route($name, Closure $callback = null)
{
static $routes = array();
if ($callback !== null) {
$routes[$name] = $callback;
}
else if (isset($routes[$name])) {
$routes[$name]();
}
}
// Serialize the payload in Json (XML is not supported)
function response(array $response)
{
header('Content-Type: application/json');
echo json_encode($response);
exit;
}
// Fever authentication
function auth()
{
$credentials = Database::get('db')->table('config')
->columns('username', 'fever_token')
->findOne();
$api_key = md5($credentials['username'].':'.$credentials['fever_token']);
$response = array(
'api_version' => 3,
'auth' => (int) (@$_POST['api_key'] === $api_key),
'last_refreshed_on_time' => time(),
);
return $response;
}
// Call: ?api&groups
route('groups', function() {
$response = auth();
if ($response['auth']) {
$feed_ids = Database::get('db')
->table('feeds')
->findAllByColumn('id');
$response['groups'] = array(
array(
'id' => 1,
'title' => t('All'),
)
);
$response['feeds_groups'] = array(
array(
'group_id' => 1,
'feed_ids' => implode(',', $feed_ids),
)
);
}
response($response);
});
// Call: ?api&feeds
route('feeds', function() {
$response = auth();
if ($response['auth']) {
$response['feeds'] = array();
$feeds = Feed\get_all();
$feed_ids = array();
foreach ($feeds as $feed) {
$response['feeds'][] = array(
'id' => (int) $feed['id'],
'favicon_id' => 1,
'title' => $feed['title'],
'url' => $feed['feed_url'],
'site_url' => $feed['site_url'],
'is_spark' => 0,
'last_updated_on_time' => $feed['last_checked'] ?: time(),
);
$feed_ids[] = $feed['id'];
}
$response['feeds_groups'] = array(
array(
'group_id' => 1,
'feed_ids' => implode(',', $feed_ids),
)
);
}
response($response);
});
// Call: ?api&favicons
route('favicons', function() {
$response = auth();
if ($response['auth']) {
$response['favicons'] = array();
}
response($response);
});
// Call: ?api&items
route('items', function() {
$response = auth();
if ($response['auth']) {
$offset = 0;
$direction = 'ASC';
if (isset($_GET['since_id']) && is_numeric($_GET['since_id'])) {
$offset = $_GET['since_id'];
$direction = 'ASC';
}
else if (isset($_GET['max_id']) && is_numeric($_GET['max_id'])) {
$offset = $_GET['max_id'];
$direction = 'DESC';
}
$query = Database::get('db')
->table('items')
->columns(
'rowid',
'feed_id',
'title',
'author',
'content',
'url',
'updated',
'status',
'bookmark'
)
->orderby('rowid', $direction)
->offset($offset)
->limit(50);
if (! empty($_GET['with_ids'])) {
$query->in('rowid', explode(',', $_GET['with_ids']));
}
$items = $query->findAll();
$response['items'] = array();
foreach ($items as $item) {
$response['items'][] = array(
'id' => (int) $item['rowid'],
'feed_id' => (int) $item['feed_id'],
'title' => $item['title'],
'author' => $item['author'],
'html' => $item['content'],
'url' => $item['url'],
'is_saved' => (int) $item['bookmark'],
'is_read' => $item['status'] == 'read' ? 1 : 0,
'created_on_time' => $item['updated'],
);
}
$response['total_items'] = Database::get('db')
->table('items')
->neq('status', 'removed')
->count();
}
response($response);
});
// Call: ?api&links
route('links', function() {
$response = auth();
if ($response['auth']) {
$response['links'] = array();
}
response($response);
});
// Call: ?api&unread_item_ids
route('unread_item_ids', function() {
$response = auth();
if ($response['auth']) {
$item_ids = Database::get('db')
->table('items')
->eq('status', 'unread')
->findAllByColumn('rowid');
$response['unread_item_ids'] = implode(',', $item_ids);
}
response($response);
});
// Call: ?api&saved_item_ids
route('saved_item_ids', function() {
$response = auth();
if ($response['auth']) {
$item_ids = Database::get('db')
->table('items')
->eq('bookmark', 1)
->findAllByColumn('rowid');
$response['saved_item_ids'] = implode(',', $item_ids);
}
response($response);
});
// handle write items
route('write_items', function() {
$response = auth();
if ($response['auth']) {
$query = Database::get('db')
->table('items')
->eq('rowid', $_POST['id']);
if ($_POST['as'] === 'saved') {
$query->update(array('bookmark' => 1));
}
else if ($_POST['as'] === 'unsaved') {
$query->update(array('bookmark' => 0));
}
else if ($_POST['as'] === 'read') {
$query->update(array('status' => 'read'));
}
else if ($_POST['as'] === 'unread') {
$query->update(array('status' => 'unread'));
}
}
response($response);
});
// handle write feeds
route('write_feeds', function() {
$response = auth();
if ($response['auth']) {
Database::get('db')
->table('items')
->eq('feed_id', $_POST['id'])
->lte('updated', $_POST['before'])
->update(array('status' => $_POST['as'] === 'read' ? 'read' : 'unread'));
}
response($response);
});
// handle write groups
route('write_groups', function() {
$response = auth();
if ($response['auth']) {
Database::get('db')
->table('items')
->lte('updated', $_POST['before'])
->update(array('status' => $_POST['as'] === 'read' ? 'read' : 'unread'));
}
response($response);
});
foreach (array_keys($_GET) as $action) {
route($action);
}
if (! empty($_POST['mark']) && ! empty($_POST['as'])
&& ! is_null(filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT, array('options' => array('default' => NULL,'min_range' => -1)))) ){
if ($_POST['mark'] === 'item') {
route('write_items');
}
else if ($_POST['mark'] === 'feed' && ! empty($_POST['before'])) {
route('write_feeds');
}
else if ($_POST['mark'] === 'group' && ! empty($_POST['before'])) {
route('write_groups');
}
}
response(auth());