The items matching the criteria, lazily iterable */ private DocumentList $dbList; /** @var string The error message generated by executing a query */ public string $error = ''; /** * Is there an error condition associated with this list? * * @return bool True if there is an error condition associated with this list, false if not */ public function isError(): bool { return $this->error != ''; } /** @var bool Whether to render a link to the feed to which the item belongs */ public bool $linkFeed = false; /** @var bool Whether to display the feed to which the item belongs */ public bool $displayFeed = false; /** @var bool Whether to show read / bookmarked indicators on posts */ public bool $showIndicators = false; /** * Constructor * * @param string $itemType The type of item being displayed (unread, bookmark, etc.) * @param string $returnURL The URL to which the item page should return once the item has been viewed * @param array|Field[] $fields The fields to use to restrict the results * @param string $searchWhere Additional WHERE clause to use for searching */ private function __construct(public string $itemType, public string $returnURL = '', array $fields = [], string $searchWhere = '') { $allFields = [Data::userIdField(Table::FEED), ...$fields]; try { $this->dbList = Custom::list( ItemWithFeed::SELECT_WITH_FEED . ' WHERE ' . Query::whereByFields(array_filter($allFields, fn($it) => $it->paramName <> ':search')) . $searchWhere, Parameters::addFields($allFields, []), new DocumentMapper(ItemWithFeed::class)); } catch (DocumentException $ex) { $this->error = "$ex"; } } /** * Create an item list with all the current user's bookmarked items * * @return static An item list with all bookmarked items */ public static function allBookmarked(): static { $list = new static('Bookmarked', '/?bookmarked', [Data::bookmarkField(qualifier: Table::ITEM)]); $list->linkFeed = true; return $list; } /** * Create an item list with all the current user's unread items * * @return static An item list with all unread items */ public static function allUnread(): static { $list = new static('Unread', fields: [Data::unreadField(Table::ITEM)]); $list->linkFeed = true; return $list; } /** * Create an item list with all items for the given feed * * @param int $feedId The ID of the feed for which items should be retrieved * @return static An item list with all items for the given feed */ public static function allForFeed(int $feedId): static { $list = new static('', "/feed/items?id=$feedId", [Data::feedField($feedId, Table::FEED)]); $list->showIndicators = true; return $list; } /** * Create an item list with unread items for the given feed * * @param int $feedId The ID of the feed for which items should be retrieved * @return static An item list with unread items for the given feed */ public static function unreadForFeed(int $feedId): static { return new static('Unread', "/feed/items?id=$feedId&unread", [Data::feedField($feedId, Table::FEED), Data::unreadField(Table::ITEM)]); } /** * Create an item list with bookmarked items for the given feed * * @param int $feedId The ID of the feed for which items should be retrieved * @return static An item list with bookmarked items for the given feed */ public static function bookmarkedForFeed(int $feedId): static { return new static('Bookmarked', "/feed/items?id=$feedId&bookmarked", [Data::feedField($feedId, Table::FEED), Data::bookmarkField(qualifier: Table::ITEM)]); } /** * Create an item list with items matching given search terms * * @param string $search The item search terms / query * @param bool $isBookmarked Whether to restrict the search to bookmarked items * @return static An item list match the given search terms */ public static function matchingSearch(string $search, bool $isBookmarked): static { $fields = [Field::EQ('content', $search, ':search')]; if ($isBookmarked) $fields[] = Data::bookmarkField(qualifier: Table::ITEM); $list = new static('Matching' . ($isBookmarked ? ' Bookmarked' : ''), "/search?search=$search&items=" . ($isBookmarked ? 'bookmarked' : 'all'), $fields, ' AND ' . Table::ITEM . ".data->>'" . Configuration::$idField . "' IN " . '(SELECT ROWID FROM item_search WHERE content MATCH :search)'); $list->showIndicators = true; $list->displayFeed = true; return $list; } /** * Render this item list */ public function render(): void { if ($this->isError()) { echo "

Error retrieving list:
$this->error"; return; } $return = $this->returnURL == '' ? '' : '&from=' . urlencode($this->returnURL); $hasItems = false; echo '

'; foreach ($this->dbList->items() as $it) { $hasItems = true; echo '

' . hx_get("/item?id=$it->id$return", strip_tags($it->title)) . '
'; if ($this->showIndicators) { if (!$it->isRead()) echo 'Unread   '; if ($it->isBookmarked()) echo 'Bookmarked   '; } echo '' . date_time($it->updated_on ?? $it->published_on) . ''; if ($this->linkFeed) { echo ' • ' . hx_get("/feed/items?id={$it->feed->id}&" . strtolower($this->itemType), htmlentities($it->feed->title)); } elseif ($this->displayFeed) { echo ' • ' . htmlentities($it->feed->title); } echo ''; } if (!$hasItems) { echo '

There are no ' . strtolower($this->itemType) . ' items'; } echo '

'; } }