request label counters conditionally
This commit is contained in:
parent
9313ebf2e7
commit
553548b689
|
@ -520,7 +520,7 @@ class API extends Handler {
|
||||||
|
|
||||||
/* API only: -4 All feeds, including virtual feeds */
|
/* API only: -4 All feeds, including virtual feeds */
|
||||||
if ($cat_id == -4 || $cat_id == -2) {
|
if ($cat_id == -4 || $cat_id == -2) {
|
||||||
$counters = Counters::get_labels(true);
|
$counters = Counters::get_labels();
|
||||||
|
|
||||||
foreach (array_values($counters) as $cv) {
|
foreach (array_values($counters) as $cv) {
|
||||||
|
|
||||||
|
|
|
@ -640,10 +640,41 @@ class Article extends Handler_Protected {
|
||||||
return [$article_image, $article_stream, $article_kind];
|
return [$article_image, $article_stream, $article_kind];
|
||||||
}
|
}
|
||||||
|
|
||||||
static function _feeds_of(array $article_ids) {
|
// only cached, returns label ids (not label feed ids)
|
||||||
|
static function _labels_of(array $article_ids) {
|
||||||
|
if (count($article_ids) == 0)
|
||||||
|
return [];
|
||||||
|
|
||||||
$id_qmarks = arr_qmarks($article_ids);
|
$id_qmarks = arr_qmarks($article_ids);
|
||||||
|
|
||||||
$sth = DB::pdo()->prepare("SELECT DISTINCT feed_id FROM ttrss_entries e, ttrss_user_entries ue
|
$sth = Db::pdo()->prepare("SELECT DISTINCT label_cache FROM ttrss_entries e, ttrss_user_entries ue
|
||||||
|
WHERE ue.ref_id = e.id AND id IN ($id_qmarks)");
|
||||||
|
|
||||||
|
$sth->execute($article_ids);
|
||||||
|
|
||||||
|
$rv = [];
|
||||||
|
|
||||||
|
while ($row = $sth->fetch()) {
|
||||||
|
$labels = json_decode($row["label_cache"]);
|
||||||
|
|
||||||
|
if (isset($labels) && is_array($labels)) {
|
||||||
|
foreach ($labels as $label) {
|
||||||
|
if (empty($label["no-labels"]))
|
||||||
|
array_push($rv, Labels::feed_to_label_id($label[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_unique($rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function _feeds_of(array $article_ids) {
|
||||||
|
if (count($article_ids) == 0)
|
||||||
|
return [];
|
||||||
|
|
||||||
|
$id_qmarks = arr_qmarks($article_ids);
|
||||||
|
|
||||||
|
$sth = Db::pdo()->prepare("SELECT DISTINCT feed_id FROM ttrss_entries e, ttrss_user_entries ue
|
||||||
WHERE ue.ref_id = e.id AND id IN ($id_qmarks)");
|
WHERE ue.ref_id = e.id AND id IN ($id_qmarks)");
|
||||||
|
|
||||||
$sth->execute($article_ids);
|
$sth->execute($article_ids);
|
||||||
|
|
|
@ -11,13 +11,14 @@ class Counters {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function get_for_feeds($feed_ids) {
|
static function get_conditional(array $feed_ids = null, array $label_ids = null) {
|
||||||
return array_merge(
|
return array_merge(
|
||||||
self::get_global(),
|
self::get_global(),
|
||||||
self::get_virt(),
|
self::get_virt(),
|
||||||
self::get_labels(),
|
self::get_labels($label_ids),
|
||||||
self::get_feeds($feed_ids),
|
self::get_feeds($feed_ids),
|
||||||
self::get_cats(Feeds::_cats_of($feed_ids, $_SESSION["uid"], true)));
|
self::get_cats(is_array($feed_ids) ? Feeds::_cats_of($feed_ids, $_SESSION["uid"], true) : null)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static private function get_cat_children($cat_id, $owner_uid) {
|
static private function get_cat_children($cat_id, $owner_uid) {
|
||||||
|
@ -40,7 +41,7 @@ class Counters {
|
||||||
return [$unread, $marked];
|
return [$unread, $marked];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function get_cats(array $cat_ids = []) {
|
private static function get_cats(array $cat_ids = null) {
|
||||||
$ret = [];
|
$ret = [];
|
||||||
|
|
||||||
/* Labels category */
|
/* Labels category */
|
||||||
|
@ -52,29 +53,10 @@ class Counters {
|
||||||
|
|
||||||
$pdo = Db::pdo();
|
$pdo = Db::pdo();
|
||||||
|
|
||||||
if (count($cat_ids) == 0) {
|
if (is_array($cat_ids)) {
|
||||||
$sth = $pdo->prepare("SELECT fc.id,
|
if (count($cat_ids) == 0)
|
||||||
SUM(CASE WHEN unread THEN 1 ELSE 0 END) AS count,
|
return [];
|
||||||
SUM(CASE WHEN marked THEN 1 ELSE 0 END) AS count_marked,
|
|
||||||
(SELECT COUNT(id) FROM ttrss_feed_categories fcc
|
|
||||||
WHERE fcc.parent_cat = fc.id) AS num_children
|
|
||||||
FROM ttrss_feed_categories fc
|
|
||||||
LEFT JOIN ttrss_feeds f ON (f.cat_id = fc.id)
|
|
||||||
LEFT JOIN ttrss_user_entries ue ON (ue.feed_id = f.id)
|
|
||||||
WHERE fc.owner_uid = :uid
|
|
||||||
GROUP BY fc.id
|
|
||||||
UNION
|
|
||||||
SELECT 0,
|
|
||||||
SUM(CASE WHEN unread THEN 1 ELSE 0 END) AS count,
|
|
||||||
SUM(CASE WHEN marked THEN 1 ELSE 0 END) AS count_marked,
|
|
||||||
0
|
|
||||||
FROM ttrss_feeds f, ttrss_user_entries ue
|
|
||||||
WHERE f.cat_id IS NULL AND
|
|
||||||
ue.feed_id = f.id AND
|
|
||||||
ue.owner_uid = :uid");
|
|
||||||
|
|
||||||
$sth->execute(["uid" => $_SESSION['uid']]);
|
|
||||||
} else {
|
|
||||||
$cat_ids_qmarks = arr_qmarks($cat_ids);
|
$cat_ids_qmarks = arr_qmarks($cat_ids);
|
||||||
|
|
||||||
$sth = $pdo->prepare("SELECT fc.id,
|
$sth = $pdo->prepare("SELECT fc.id,
|
||||||
|
@ -102,6 +84,29 @@ class Counters {
|
||||||
$cat_ids,
|
$cat_ids,
|
||||||
[$_SESSION['uid']]
|
[$_SESSION['uid']]
|
||||||
));
|
));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$sth = $pdo->prepare("SELECT fc.id,
|
||||||
|
SUM(CASE WHEN unread THEN 1 ELSE 0 END) AS count,
|
||||||
|
SUM(CASE WHEN marked THEN 1 ELSE 0 END) AS count_marked,
|
||||||
|
(SELECT COUNT(id) FROM ttrss_feed_categories fcc
|
||||||
|
WHERE fcc.parent_cat = fc.id) AS num_children
|
||||||
|
FROM ttrss_feed_categories fc
|
||||||
|
LEFT JOIN ttrss_feeds f ON (f.cat_id = fc.id)
|
||||||
|
LEFT JOIN ttrss_user_entries ue ON (ue.feed_id = f.id)
|
||||||
|
WHERE fc.owner_uid = :uid
|
||||||
|
GROUP BY fc.id
|
||||||
|
UNION
|
||||||
|
SELECT 0,
|
||||||
|
SUM(CASE WHEN unread THEN 1 ELSE 0 END) AS count,
|
||||||
|
SUM(CASE WHEN marked THEN 1 ELSE 0 END) AS count_marked,
|
||||||
|
0
|
||||||
|
FROM ttrss_feeds f, ttrss_user_entries ue
|
||||||
|
WHERE f.cat_id IS NULL AND
|
||||||
|
ue.feed_id = f.id AND
|
||||||
|
ue.owner_uid = :uid");
|
||||||
|
|
||||||
|
$sth->execute(["uid" => $_SESSION['uid']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($line = $sth->fetch()) {
|
while ($line = $sth->fetch()) {
|
||||||
|
@ -125,25 +130,16 @@ class Counters {
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function get_feeds(array $feed_ids = []) {
|
private static function get_feeds(array $feed_ids = null) {
|
||||||
|
|
||||||
$ret = [];
|
$ret = [];
|
||||||
|
|
||||||
$pdo = Db::pdo();
|
$pdo = Db::pdo();
|
||||||
|
|
||||||
if (count($feed_ids) == 0) {
|
if (is_array($feed_ids)) {
|
||||||
$sth = $pdo->prepare("SELECT f.id,
|
if (count($feed_ids) == 0)
|
||||||
f.title,
|
return [];
|
||||||
".SUBSTRING_FOR_DATE."(f.last_updated,1,19) AS last_updated,
|
|
||||||
f.last_error,
|
|
||||||
SUM(CASE WHEN unread THEN 1 ELSE 0 END) AS count,
|
|
||||||
SUM(CASE WHEN marked THEN 1 ELSE 0 END) AS count_marked
|
|
||||||
FROM ttrss_feeds f, ttrss_user_entries ue
|
|
||||||
WHERE f.id = ue.feed_id AND ue.owner_uid = :uid
|
|
||||||
GROUP BY f.id");
|
|
||||||
|
|
||||||
$sth->execute(["uid" => $_SESSION['uid']]);
|
|
||||||
} else {
|
|
||||||
$feed_ids_qmarks = arr_qmarks($feed_ids);
|
$feed_ids_qmarks = arr_qmarks($feed_ids);
|
||||||
|
|
||||||
$sth = $pdo->prepare("SELECT f.id,
|
$sth = $pdo->prepare("SELECT f.id,
|
||||||
|
@ -157,6 +153,18 @@ class Counters {
|
||||||
GROUP BY f.id");
|
GROUP BY f.id");
|
||||||
|
|
||||||
$sth->execute(array_merge([$_SESSION['uid']], $feed_ids));
|
$sth->execute(array_merge([$_SESSION['uid']], $feed_ids));
|
||||||
|
} else {
|
||||||
|
$sth = $pdo->prepare("SELECT f.id,
|
||||||
|
f.title,
|
||||||
|
".SUBSTRING_FOR_DATE."(f.last_updated,1,19) AS last_updated,
|
||||||
|
f.last_error,
|
||||||
|
SUM(CASE WHEN unread THEN 1 ELSE 0 END) AS count,
|
||||||
|
SUM(CASE WHEN marked THEN 1 ELSE 0 END) AS count_marked
|
||||||
|
FROM ttrss_feeds f, ttrss_user_entries ue
|
||||||
|
WHERE f.id = ue.feed_id AND ue.owner_uid = :uid
|
||||||
|
GROUP BY f.id");
|
||||||
|
|
||||||
|
$sth->execute(["uid" => $_SESSION['uid']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($line = $sth->fetch()) {
|
while ($line = $sth->fetch()) {
|
||||||
|
@ -269,23 +277,42 @@ class Counters {
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function get_labels($descriptions = false) {
|
static function get_labels(array $label_ids = null) {
|
||||||
|
|
||||||
$ret = [];
|
$ret = [];
|
||||||
|
|
||||||
$pdo = Db::pdo();
|
$pdo = Db::pdo();
|
||||||
|
|
||||||
$sth = $pdo->prepare("SELECT id,
|
if (is_array($label_ids)) {
|
||||||
caption,
|
if (count($label_ids) == 0)
|
||||||
SUM(CASE WHEN u1.unread = true THEN 1 ELSE 0 END) AS count_unread,
|
return [];
|
||||||
SUM(CASE WHEN u1.marked = true THEN 1 ELSE 0 END) AS count_marked,
|
|
||||||
COUNT(u1.unread) AS total
|
$label_ids_qmarks = arr_qmarks($label_ids);
|
||||||
FROM ttrss_labels2 LEFT JOIN ttrss_user_labels2 ON
|
|
||||||
(ttrss_labels2.id = label_id)
|
$sth = $pdo->prepare("SELECT id,
|
||||||
LEFT JOIN ttrss_user_entries AS u1 ON u1.ref_id = article_id AND u1.owner_uid = :uid
|
caption,
|
||||||
WHERE ttrss_labels2.owner_uid = :uid
|
SUM(CASE WHEN u1.unread = true THEN 1 ELSE 0 END) AS count_unread,
|
||||||
GROUP BY ttrss_labels2.id, ttrss_labels2.caption");
|
SUM(CASE WHEN u1.marked = true THEN 1 ELSE 0 END) AS count_marked,
|
||||||
$sth->execute([":uid" => $_SESSION['uid']]);
|
COUNT(u1.unread) AS total
|
||||||
|
FROM ttrss_labels2 LEFT JOIN ttrss_user_labels2 ON
|
||||||
|
(ttrss_labels2.id = label_id)
|
||||||
|
LEFT JOIN ttrss_user_entries AS u1 ON u1.ref_id = article_id AND u1.owner_uid = ?
|
||||||
|
WHERE ttrss_labels2.owner_uid = ? AND ttrss_labels2.id IN ($label_ids_qmarks)
|
||||||
|
GROUP BY ttrss_labels2.id, ttrss_labels2.caption");
|
||||||
|
$sth->execute(array_merge([$_SESSION["uid"], $_SESSION["uid"]], $label_ids));
|
||||||
|
} else {
|
||||||
|
$sth = $pdo->prepare("SELECT id,
|
||||||
|
caption,
|
||||||
|
SUM(CASE WHEN u1.unread = true THEN 1 ELSE 0 END) AS count_unread,
|
||||||
|
SUM(CASE WHEN u1.marked = true THEN 1 ELSE 0 END) AS count_marked,
|
||||||
|
COUNT(u1.unread) AS total
|
||||||
|
FROM ttrss_labels2 LEFT JOIN ttrss_user_labels2 ON
|
||||||
|
(ttrss_labels2.id = label_id)
|
||||||
|
LEFT JOIN ttrss_user_entries AS u1 ON u1.ref_id = article_id AND u1.owner_uid = :uid
|
||||||
|
WHERE ttrss_labels2.owner_uid = :uid
|
||||||
|
GROUP BY ttrss_labels2.id, ttrss_labels2.caption");
|
||||||
|
$sth->execute([":uid" => $_SESSION['uid']]);
|
||||||
|
}
|
||||||
|
|
||||||
while ($line = $sth->fetch()) {
|
while ($line = $sth->fetch()) {
|
||||||
|
|
||||||
|
@ -295,12 +322,10 @@ class Counters {
|
||||||
"id" => $id,
|
"id" => $id,
|
||||||
"counter" => (int) $line["count_unread"],
|
"counter" => (int) $line["count_unread"],
|
||||||
"auxcounter" => (int) $line["total"],
|
"auxcounter" => (int) $line["total"],
|
||||||
"markedcounter" => (int) $line["count_marked"]
|
"markedcounter" => (int) $line["count_marked"],
|
||||||
|
"description" => $line["caption"]
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($descriptions)
|
|
||||||
$cv["description"] = $line["caption"];
|
|
||||||
|
|
||||||
array_push($ret, $cv);
|
array_push($ret, $cv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1792,6 +1792,9 @@ class Feeds extends Handler_Protected {
|
||||||
}
|
}
|
||||||
|
|
||||||
static function _cats_of(array $feeds, int $owner_uid, bool $with_parents = false) {
|
static function _cats_of(array $feeds, int $owner_uid, bool $with_parents = false) {
|
||||||
|
if (count($feeds) == 0)
|
||||||
|
return [];
|
||||||
|
|
||||||
$pdo = Db::pdo();
|
$pdo = Db::pdo();
|
||||||
|
|
||||||
$feeds_qmarks = arr_qmarks($feeds);
|
$feeds_qmarks = arr_qmarks($feeds);
|
||||||
|
|
|
@ -73,11 +73,26 @@ class RPC extends Handler_Protected {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAllCounters() {
|
function getAllCounters() {
|
||||||
$feed_ids = array_map("intval", clean($_REQUEST["feed_ids"] ?? []));
|
|
||||||
@$seq = (int) $_REQUEST['seq'];
|
@$seq = (int) $_REQUEST['seq'];
|
||||||
|
|
||||||
|
$feed_id_count = (int)$_REQUEST["feed_id_count"];
|
||||||
|
$label_id_count = (int)$_REQUEST["label_id_count"];
|
||||||
|
|
||||||
|
// it seems impossible to distinguish empty array [] from a null - both become unset in $_REQUEST
|
||||||
|
// so, count is >= 0 means we had an array, -1 means null
|
||||||
|
// we need null because it means "return all counters"; [] would return nothing
|
||||||
|
if ($feed_id_count == -1)
|
||||||
|
$feed_ids = null;
|
||||||
|
else
|
||||||
|
$feed_ids = array_map("intval", clean($_REQUEST["feed_ids"] ?? []));
|
||||||
|
|
||||||
|
if ($label_id_count == -1)
|
||||||
|
$label_ids = null;
|
||||||
|
else
|
||||||
|
$label_ids = array_map("intval", clean($_REQUEST["label_ids"] ?? []));
|
||||||
|
|
||||||
// @phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
$counters = count($feed_ids) > 0 ? Counters::get_for_feeds($feed_ids) : Counters::get_all();
|
$counters = is_array($feed_ids) ? Counters::get_conditional($feed_ids, $label_ids) : Counters::get_all();
|
||||||
|
|
||||||
$reply = [
|
$reply = [
|
||||||
'counters' => $counters,
|
'counters' => $counters,
|
||||||
|
@ -95,16 +110,20 @@ class RPC extends Handler_Protected {
|
||||||
$ids = array_map("intval", clean($_REQUEST["ids"] ?? []));
|
$ids = array_map("intval", clean($_REQUEST["ids"] ?? []));
|
||||||
$cmode = (int)clean($_REQUEST["cmode"]);
|
$cmode = (int)clean($_REQUEST["cmode"]);
|
||||||
|
|
||||||
Article::_catchup_by_id($ids, $cmode);
|
if (count($ids) > 0)
|
||||||
|
Article::_catchup_by_id($ids, $cmode);
|
||||||
|
|
||||||
print json_encode(["message" => "UPDATE_COUNTERS", "feeds" => Article::_feeds_of($ids)]);
|
print json_encode(["message" => "UPDATE_COUNTERS",
|
||||||
|
"labels" => Article::_labels_of($ids),
|
||||||
|
"feeds" => Article::_feeds_of($ids)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function markSelected() {
|
function markSelected() {
|
||||||
$ids = array_map("intval", clean($_REQUEST["ids"] ?? []));
|
$ids = array_map("intval", clean($_REQUEST["ids"] ?? []));
|
||||||
$cmode = (int)clean($_REQUEST["cmode"]);
|
$cmode = (int)clean($_REQUEST["cmode"]);
|
||||||
|
|
||||||
$this->markArticlesById($ids, $cmode);
|
if (count($ids) > 0)
|
||||||
|
$this->markArticlesById($ids, $cmode);
|
||||||
|
|
||||||
print json_encode(["message" => "UPDATE_COUNTERS", "feeds" => Article::_feeds_of($ids)]);
|
print json_encode(["message" => "UPDATE_COUNTERS", "feeds" => Article::_feeds_of($ids)]);
|
||||||
}
|
}
|
||||||
|
@ -113,7 +132,8 @@ class RPC extends Handler_Protected {
|
||||||
$ids = array_map("intval", clean($_REQUEST["ids"] ?? []));
|
$ids = array_map("intval", clean($_REQUEST["ids"] ?? []));
|
||||||
$cmode = (int)clean($_REQUEST["cmode"]);
|
$cmode = (int)clean($_REQUEST["cmode"]);
|
||||||
|
|
||||||
$this->publishArticlesById($ids, $cmode);
|
if (count($ids) > 0)
|
||||||
|
$this->publishArticlesById($ids, $cmode);
|
||||||
|
|
||||||
print json_encode(["message" => "UPDATE_COUNTERS", "feeds" => Article::_feeds_of($ids)]);
|
print json_encode(["message" => "UPDATE_COUNTERS", "feeds" => Article::_feeds_of($ids)]);
|
||||||
}
|
}
|
||||||
|
|
13
js/Feeds.js
13
js/Feeds.js
|
@ -133,10 +133,15 @@ const Feeds = {
|
||||||
this._search_query = "";
|
this._search_query = "";
|
||||||
this.reloadCurrent();
|
this.reloadCurrent();
|
||||||
},
|
},
|
||||||
requestCounters: function(feed_ids = null) {
|
// null = get all data, [] would give empty response for specific type
|
||||||
xhr.json("backend.php", {op: "rpc", method: "getAllCounters", "feed_ids[]": feed_ids, seq: App.next_seq()}, () => {
|
requestCounters: function(feed_ids = null, label_ids = null) {
|
||||||
//
|
xhr.json("backend.php", {op: "rpc",
|
||||||
});
|
method: "getAllCounters",
|
||||||
|
"feed_ids[]": feed_ids,
|
||||||
|
"feed_id_count": feed_ids ? feed_ids.length : -1,
|
||||||
|
"label_ids[]": label_ids,
|
||||||
|
"label_id_count": label_ids ? label_ids.length : -1,
|
||||||
|
seq: App.next_seq()});
|
||||||
},
|
},
|
||||||
reload: function() {
|
reload: function() {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -175,6 +175,7 @@ const Headlines = {
|
||||||
|
|
||||||
Promise.all(promises).then((results) => {
|
Promise.all(promises).then((results) => {
|
||||||
let feeds = [];
|
let feeds = [];
|
||||||
|
let labels = [];
|
||||||
|
|
||||||
results.forEach((res) => {
|
results.forEach((res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
|
@ -183,6 +184,10 @@ const Headlines = {
|
||||||
|
|
||||||
if (obj.feeds)
|
if (obj.feeds)
|
||||||
feeds = feeds.concat(obj.feeds);
|
feeds = feeds.concat(obj.feeds);
|
||||||
|
|
||||||
|
if (obj.labels)
|
||||||
|
labels = labels.concat(obj.labels);
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(e, res);
|
console.warn(e, res);
|
||||||
}
|
}
|
||||||
|
@ -190,8 +195,8 @@ const Headlines = {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (feeds.length > 0) {
|
if (feeds.length > 0) {
|
||||||
console.log('requesting counters for', feeds);
|
console.log('requesting counters for', feeds, labels);
|
||||||
Feeds.requestCounters(feeds);
|
Feeds.requestCounters(feeds, labels);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue