diff options
author | Andrew Dolgov <[email protected]> | 2023-10-25 12:55:09 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2023-10-25 12:55:09 +0300 |
commit | 865ecc87963dc3b26e66296616eef2a1cc41ac3f (patch) | |
tree | bf2ecd8a391103bdb2c8b70cd33c47467310754b /classes/Counters.php | |
parent | 0a5507d3bd79d04c860455664f919bf8e7274fda (diff) |
move to psr-4 autoloader
Diffstat (limited to 'classes/Counters.php')
-rw-r--r-- | classes/Counters.php | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/classes/Counters.php b/classes/Counters.php new file mode 100644 index 000000000..948e6ee1d --- /dev/null +++ b/classes/Counters.php @@ -0,0 +1,362 @@ +<?php +class Counters { + + /** + * @return array<int, array<string, int|string>> + */ + static function get_all(): array { + return [ + ...self::get_global(), + ...self::get_virt(), + ...self::get_labels(), + ...self::get_feeds(), + ...self::get_cats(), + ]; + } + + /** + * @param array<int> $feed_ids + * @param array<int> $label_ids + * @return array<int, array<string, int|string>> + */ + static function get_conditional(array $feed_ids = null, array $label_ids = null): array { + return [ + ...self::get_global(), + ...self::get_virt(), + ...self::get_labels($label_ids), + ...self::get_feeds($feed_ids), + ...self::get_cats(is_array($feed_ids) ? Feeds::_cats_of($feed_ids, $_SESSION["uid"], true) : null) + ]; + } + + /** + * @return array<int, int> + */ + static private function get_cat_children(int $cat_id, int $owner_uid): array { + $unread = 0; + $marked = 0; + + $cats = ORM::for_table('ttrss_feed_categories') + ->where('owner_uid', $owner_uid) + ->where('parent_cat', $cat_id) + ->find_many(); + + foreach ($cats as $cat) { + list ($tmp_unread, $tmp_marked) = self::get_cat_children($cat->id, $owner_uid); + + $unread += $tmp_unread + Feeds::_get_cat_unread($cat->id, $owner_uid); + $marked += $tmp_marked + Feeds::_get_cat_marked($cat->id, $owner_uid); + } + + return [$unread, $marked]; + } + + /** + * @param array<int> $cat_ids + * @return array<int, array<string, int|string>> + */ + private static function get_cats(array $cat_ids = null): array { + $ret = []; + + /* Labels category */ + + $cv = array("id" => Feeds::CATEGORY_LABELS, "kind" => "cat", + "counter" => Feeds::_get_cat_unread(Feeds::CATEGORY_LABELS)); + + array_push($ret, $cv); + + $pdo = Db::pdo(); + + if (is_array($cat_ids)) { + if (count($cat_ids) == 0) + return []; + + $cat_ids_qmarks = arr_qmarks($cat_ids); + + $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 = ? AND fc.id IN ($cat_ids_qmarks) + 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 = ?"); + + $sth->execute([$_SESSION['uid'], ...$cat_ids, $_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()) { + if ($line["num_children"] > 0) { + list ($child_counter, $child_marked_counter) = self::get_cat_children($line["id"], $_SESSION["uid"]); + } else { + $child_counter = 0; + $child_marked_counter = 0; + } + + $cv = [ + "id" => (int)$line["id"], + "kind" => "cat", + "markedcounter" => (int) $line["count_marked"] + $child_marked_counter, + "counter" => (int) $line["count"] + $child_counter + ]; + + array_push($ret, $cv); + } + + return $ret; + } + + /** + * @param array<int> $feed_ids + * @return array<int, array<string, int|string>> + */ + private static function get_feeds(array $feed_ids = null): array { + $span = Tracer::start(__METHOD__); + + $ret = []; + + $pdo = Db::pdo(); + + if (is_array($feed_ids)) { + if (count($feed_ids) == 0) + return []; + + $feed_ids_qmarks = arr_qmarks($feed_ids); + + $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 = ? AND f.id IN ($feed_ids_qmarks) + GROUP BY f.id"); + + $sth->execute([$_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()) { + + $id = $line["id"]; + $last_updated = TimeHelper::make_local_datetime($line['last_updated'], false); + + if (Feeds::_has_icon($id)) { + $ts = filemtime(Feeds::_get_icon_file($id)); + } else { + $ts = 0; + } + + // hide default un-updated timestamp i.e. 1970-01-01 (?) -fox + if ((int)date('Y') - (int)date('Y', strtotime($line['last_updated'] ?? '')) > 2) + $last_updated = ''; + + $cv = [ + "id" => $id, + "updated" => $last_updated, + "counter" => (int) $line["count"], + "markedcounter" => (int) $line["count_marked"], + "ts" => (int) $ts + ]; + + $cv["error"] = $line["last_error"]; + $cv["title"] = truncate_string($line["title"], 30); + + array_push($ret, $cv); + + } + + $span->end(); + + return $ret; + } + + /** + * @return array<int, array<string, int|string>> + */ + private static function get_global(): array { + $span = Tracer::start(__METHOD__); + + $ret = [ + [ + "id" => "global-unread", + "counter" => (int) Feeds::_get_global_unread() + ] + ]; + + $subcribed_feeds = ORM::for_table('ttrss_feeds') + ->where('owner_uid', $_SESSION['uid']) + ->count(); + + array_push($ret, [ + "id" => "subscribed-feeds", + "counter" => $subcribed_feeds + ]); + + $span->end(); + + return $ret; + } + + /** + * @return array<int, array<string, int|string>> + */ + private static function get_virt(): array { + $span = Tracer::start(__METHOD__); + + $ret = []; + + foreach ([Feeds::FEED_ARCHIVED, Feeds::FEED_STARRED, Feeds::FEED_PUBLISHED, + Feeds::FEED_FRESH, Feeds::FEED_ALL] as $feed_id) { + + $count = Feeds::_get_counters($feed_id, false, true); + + if (in_array($feed_id, [Feeds::FEED_ARCHIVED, Feeds::FEED_STARRED, Feeds::FEED_PUBLISHED])) + $auxctr = Feeds::_get_counters($feed_id, false); + else + $auxctr = 0; + + $cv = [ + "id" => $feed_id, + "counter" => (int) $count, + "auxcounter" => (int) $auxctr + ]; + + if ($feed_id == Feeds::FEED_STARRED) + $cv["markedcounter"] = $auxctr; + + array_push($ret, $cv); + } + + $feeds = PluginHost::getInstance()->get_feeds(Feeds::CATEGORY_SPECIAL); + + if (is_array($feeds)) { + foreach ($feeds as $feed) { + /** @var IVirtualFeed $feed['sender'] */ + + if (!implements_interface($feed['sender'], 'IVirtualFeed')) + continue; + + $cv = [ + "id" => PluginHost::pfeed_to_feed_id($feed['id']), + "counter" => $feed['sender']->get_unread($feed['id']) + ]; + + if (method_exists($feed['sender'], 'get_total')) + $cv["auxcounter"] = $feed['sender']->get_total($feed['id']); + + array_push($ret, $cv); + } + } + + $span->end(); + return $ret; + } + + /** + * @param array<int> $label_ids + * @return array<int, array<string, int|string>> + */ + static function get_labels(array $label_ids = null): array { + $span = Tracer::start(__METHOD__); + + $ret = []; + + $pdo = Db::pdo(); + + if (is_array($label_ids)) { + if (count($label_ids) == 0) + return []; + + $label_ids_qmarks = arr_qmarks($label_ids); + + $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 = ? + WHERE ttrss_labels2.owner_uid = ? AND ttrss_labels2.id IN ($label_ids_qmarks) + GROUP BY ttrss_labels2.id, ttrss_labels2.caption"); + $sth->execute([$_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()) { + + $id = Labels::label_to_feed_id($line["id"]); + + $cv = [ + "id" => $id, + "counter" => (int) $line["count_unread"], + "auxcounter" => (int) $line["total"], + "markedcounter" => (int) $line["count_marked"], + "description" => $line["caption"] + ]; + + array_push($ret, $cv); + } + + $span->end(); + return $ret; + } +} |