diff options
Diffstat (limited to 'app/Models/Entry.php')
| -rw-r--r-- | app/Models/Entry.php | 148 |
1 files changed, 129 insertions, 19 deletions
diff --git a/app/Models/Entry.php b/app/Models/Entry.php index 72e59e38c..e383f9060 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -31,6 +31,7 @@ class FreshRSS_Entry extends Minz_Model { * @var bool|null */ private $is_read; + /** @var bool|null */ private $is_favorite; /** @@ -213,17 +214,22 @@ class FreshRSS_Entry extends Minz_Model { public function isFavorite() { return $this->is_favorite; } - public function feed($object = false) { - if ($object) { - if ($this->feed == null) { - $feedDAO = FreshRSS_Factory::createFeedDao(); - $this->feed = $feedDAO->searchById($this->feedId); - } - return $this->feed; - } else { - return $this->feedId; + + /** + * @return FreshRSS_Feed|null|false + */ + public function feed() { + if ($this->feed === null) { + $feedDAO = FreshRSS_Factory::createFeedDao(); + $this->feed = $feedDAO->searchById($this->feedId); } + return $this->feed; } + + public function feedId(): int { + return $this->feedId; + } + public function tags($asString = false) { if ($asString) { return $this->tags == null ? '' : '#' . implode(' #', $this->tags); @@ -331,18 +337,21 @@ class FreshRSS_Entry extends Minz_Model { $this->is_read = $value === null ? null : (bool)$value; } public function _isFavorite($value) { - $this->is_favorite = $value; + $this->is_favorite = $value === null ? null : (bool)$value; } - public function _feed($value) { - if ($value != null) { - $this->feed = $value; - $this->feedId = $this->feed->id(); - } + + /** @param FreshRSS_Feed|null $feed */ + public function _feed($feed) { + $this->feed = $feed; + $this->feedId = $this->feed == null ? 0 : $this->feed->id(); } - private function _feedId($value) { + + /** @param int|string $id */ + private function _feedId($id) { $this->feed = null; - $this->feedId = intval($value); + $this->feedId = intval($id); } + public function _tags($value) { $this->hash = ''; if (!is_array($value)) { @@ -558,7 +567,7 @@ class FreshRSS_Entry extends Minz_Model { public function loadCompleteContent(bool $force = false): bool { // Gestion du contenu // Trying to fetch full article content even when feeds do not propose it - $feed = $this->feed(true); + $feed = $this->feed(); if ($feed != null && trim($feed->pathEntries()) != '') { $entryDAO = FreshRSS_Factory::createEntryDao(); $entry = $force ? null : $entryDAO->searchByGuid($this->feedId, $this->guid); @@ -613,9 +622,110 @@ class FreshRSS_Entry extends Minz_Model { 'hash' => $this->hash(), 'is_read' => $this->isRead(), 'is_favorite' => $this->isFavorite(), - 'id_feed' => $this->feed(), + 'id_feed' => $this->feedId(), 'tags' => $this->tags(true), 'attributes' => $this->attributes(), ); } + + /** + * Integer format conversion for Google Reader API format + * @param string|int $dec Decimal number + * @return string 64-bit hexa http://code.google.com/p/google-reader-api/wiki/ItemId + */ + private static function dec2hex($dec): string { + return PHP_INT_SIZE < 8 ? // 32-bit ? + str_pad(gmp_strval(gmp_init($dec, 10), 16), 16, '0', STR_PAD_LEFT) : + str_pad(dechex($dec), 16, '0', STR_PAD_LEFT); + } + + /** + * N.B.: To avoid expensive lookups, ensure to set `$entry->_feed($feed)` before calling this function. + * N.B.: You might have to populate `$entry->_tags()` prior to calling this function. + * @param string $mode Set to `'compat'` to use an alternative Unicode representation for problematic HTML special characters not decoded by some clients; + * set to `'freshrss'` for using FreshRSS additions for internal use (e.g. export/import). + * @return array<string,mixed> A representation of this entry in a format compatible with Google Reader API + */ + public function toGReader(string $mode = ''): array { + + $feed = $this->feed(); + $category = $feed == null ? null : $feed->category(); + + $item = [ + 'id' => 'tag:google.com,2005:reader/item/' . self::dec2hex($this->id()), + 'crawlTimeMsec' => substr($this->dateAdded(true, true), 0, -3), + 'timestampUsec' => '' . $this->dateAdded(true, true), //EasyRSS & Reeder + 'published' => $this->date(true), + // 'updated' => $this->date(true), + 'title' => $this->title(), + 'summary' => ['content' => $this->content()], + 'canonical' => [ + ['href' => htmlspecialchars_decode($this->link(), ENT_QUOTES)], + ], + 'alternate' => [ + [ + 'href' => htmlspecialchars_decode($this->link(), ENT_QUOTES), + 'type' => 'text/html', + ], + ], + 'categories' => [ + 'user/-/state/com.google/reading-list', + ], + 'origin' => [ + 'streamId' => 'feed/' . $this->feedId, + ], + ]; + if ($mode === 'compat') { + $item['title'] = escapeToUnicodeAlternative($this->title(), false); + } elseif ($mode === 'freshrss') { + $item['guid'] = $this->guid(); + unset($item['summary']); + $item['content'] = ['content' => $this->content()]; + } + if ($category != null && $mode !== 'freshrss') { + $item['categories'][] = 'user/-/label/' . htmlspecialchars_decode($category->name(), ENT_QUOTES); + } + if ($feed != null) { + $item['origin']['htmlUrl'] = htmlspecialchars_decode($feed->website()); + $item['origin']['title'] = $feed->name(); //EasyRSS + if ($mode === 'compat') { + $item['origin']['title'] = escapeToUnicodeAlternative($feed->name(), true); + } elseif ($mode === 'freshrss') { + $item['origin']['feedUrl'] = htmlspecialchars_decode($feed->url()); + } + } + foreach ($this->enclosures() as $enclosure) { + if (!empty($enclosure['url']) && !empty($enclosure['type'])) { + $media = [ + 'href' => $enclosure['url'], + 'type' => $enclosure['type'], + ]; + if (!empty($enclosure['length'])) { + $media['length'] = intval($enclosure['length']); + } + $item['enclosure'][] = $media; + } + } + $author = $this->authors(true); + $author = trim($author, '; '); + if ($author != '') { + if ($mode === 'compat') { + $item['author'] = escapeToUnicodeAlternative($author, false); + } else { + $item['author'] = $author; + } + } + if ($this->isRead()) { + $item['categories'][] = 'user/-/state/com.google/read'; + } elseif ($mode === 'freshrss') { + $item['categories'][] = 'user/-/state/com.google/unread'; + } + if ($this->isFavorite()) { + $item['categories'][] = 'user/-/state/com.google/starred'; + } + foreach ($this->tags() as $tagName) { + $item['categories'][] = 'user/-/label/' . htmlspecialchars_decode($tagName, ENT_QUOTES); + } + return $item; + } } |
