> */ static function get_all(): array { return [ ...self::get_global(), ...self::get_virt(), ...self::get_labels(), ...self::get_feeds(), ...self::get_cats(), ]; } /** * @param array|null $feed_ids * @param array|null $label_ids * @return array> */ 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 */ 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|null $cat_ids * @return array> */ 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|null $feed_ids * @return array> */ private static function get_feeds(?array $feed_ids = null): array { $ret = []; if (is_array($feed_ids) && count($feed_ids) === 0) return $ret; $feeds = ORM::for_table('ttrss_feeds') ->table_alias('f') ->select_many('f.id', 'f.title', 'f.last_error') ->select_many_expr([ 'count' => 'SUM(CASE WHEN ue.unread THEN 1 ELSE 0 END)', 'count_marked' => 'SUM(CASE WHEN ue.marked THEN 1 ELSE 0 END)', 'last_updated' => 'SUBSTRING_FOR_DATE(f.last_updated,1,19)', ]) ->join('ttrss_user_entries', [ 'ue.feed_id', '=', 'f.id'], 'ue') ->where('ue.owner_uid', $_SESSION['uid']) ->group_by('f.id'); if (is_array($feed_ids)) $feeds->where_in('f.id', $feed_ids); foreach ($feeds->find_many() as $feed) { $ret[] = [ 'id' => $feed->id, 'title' => truncate_string($feed->title, 30), 'error' => $feed->last_error, 'updated' => TimeHelper::make_local_datetime($feed->last_updated), 'counter' => (int) $feed->count, 'markedcounter' => (int) $feed->count_marked, 'ts' => Feeds::_has_icon($feed->id) ? (int) filemtime(Feeds::_get_icon_file($feed->id)) : 0, ]; } return $ret; } /** * @return array> */ private static function get_global(): array { $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 ]); return $ret; } /** * @return array> */ private static function get_virt(): array { $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); } foreach (PluginHost::getInstance()->get_feeds(Feeds::CATEGORY_SPECIAL) as $feed) { if (!implements_interface($feed['sender'], 'IVirtualFeed')) continue; /** @var Plugin&IVirtualFeed $feed['sender'] */ $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); } return $ret; } /** * @param array|null $label_ids * @return array> */ static function get_labels(?array $label_ids = null): array { $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); } return $ret; } }