diff options
| author | 2023-09-04 10:09:37 +0200 | |
|---|---|---|
| committer | 2023-09-04 10:09:37 +0200 | |
| commit | 1c7c1016f4a5147003ed1c438b8a386a63a53cab (patch) | |
| tree | a0639042ac205cd20863cd24496e79ddae3f562e | |
| parent | da405ceee628dca739a12b234a6094a8ebae9c94 (diff) | |
Fix JSON export/import (#5626)
* Fix import with empty content
fix https://github.com/FreshRSS/FreshRSS/issues/5622
Cherry picks on https://github.com/FreshRSS/FreshRSS/pull/5584
* Fix export of tags / labels
Article-defined tags were wrongly exported as user-defined labels.
* Fix export of tags / labels
Article-defined tags were wrongly exported as user-defined labels.
* Fix bug with many labels
* Better typing
* Comments
| -rw-r--r-- | app/Controllers/importExportController.php | 13 | ||||
| -rw-r--r-- | app/Models/Entry.php | 9 | ||||
| -rw-r--r-- | app/Models/TagDAO.php | 13 | ||||
| -rw-r--r-- | app/views/helpers/export/articles.phtml | 6 | ||||
| -rw-r--r-- | lib/lib_rss.php | 1 | ||||
| -rw-r--r-- | p/api/greader.php | 6 |
6 files changed, 25 insertions, 23 deletions
diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 9c18b608f..807a355db 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -309,7 +309,7 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController { $limits = FreshRSS_Context::$system_conf->limits; // First, we check feeds of articles are in DB (and add them if needed). - foreach ($items as $item) { + foreach ($items as &$item) { if (!isset($item['guid']) && isset($item['id'])) { $item['guid'] = $item['id']; } @@ -382,7 +382,7 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController { // Then, articles are imported. $newGuids = []; $this->entryDAO->beginTransaction(); - foreach ($items as $item) { + foreach ($items as &$item) { if (empty($item['guid']) || empty($article_to_feed[$item['guid']])) { // Related feed does not exist for this entry, do nothing. continue; @@ -427,14 +427,17 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController { } else { $url = ''; } + if (!is_string($url)) { + $url = ''; + } $title = empty($item['title']) ? $url : $item['title']; - if (!empty($item['content']['content'])) { + if (isset($item['content']['content']) && is_string($item['content']['content'])) { $content = $item['content']['content']; - } elseif (!empty($item['summary']['content'])) { + } elseif (isset($item['summary']['content']) && is_string($item['summary']['content'])) { $content = $item['summary']['content']; - } elseif (!empty($item['content'])) { + } elseif (isset($item['content']) && is_string($item['content'])) { $content = $item['content']; //FeedBin } else { $content = ''; diff --git a/app/Models/Entry.php b/app/Models/Entry.php index 7da27e409..b70e7e2ab 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -846,12 +846,12 @@ HTML; /** * 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). + * @param array<string> $labels List of labels associated to this entry. * @return array<string,mixed> A representation of this entry in a format compatible with Google Reader API */ - public function toGReader(string $mode = ''): array { + public function toGReader(string $mode = '', array $labels = []): array { $feed = $this->feed(); $category = $feed == null ? null : $feed->category(); @@ -935,8 +935,11 @@ HTML; if ($this->isFavorite()) { $item['categories'][] = 'user/-/state/com.google/starred'; } + foreach ($labels as $labelName) { + $item['categories'][] = 'user/-/label/' . htmlspecialchars_decode($labelName, ENT_QUOTES); + } foreach ($this->tags() as $tagName) { - $item['categories'][] = 'user/-/label/' . htmlspecialchars_decode($tagName, ENT_QUOTES); + $item['categories'][] = htmlspecialchars_decode($tagName, ENT_QUOTES); } return $item; } diff --git a/app/Models/TagDAO.php b/app/Models/TagDAO.php index 0704fd9f7..80a0e7688 100644 --- a/app/Models/TagDAO.php +++ b/app/Models/TagDAO.php @@ -383,7 +383,11 @@ SQL; // Split a query with too many variables parameters $idsChunks = array_chunk($entries, FreshRSS_DatabaseDAO::MAX_VARIABLE_NUMBER); foreach ($idsChunks as $idsChunk) { - $values += $this->getTagsForEntries($idsChunk); + $valuesChunk = $this->getTagsForEntries($idsChunk); + if (!is_array($valuesChunk)) { + return false; + } + $values = array_merge($values, $valuesChunk); } return $values; } @@ -419,9 +423,10 @@ SQL; } /** - * For API - * @param array<FreshRSS_Entry|numeric-string> $entries - * @return array<string,array<string>> + * Produces an array: for each entry ID (prefixed by `e_`), associate a list of labels. + * Used by API and by JSON export, to speed up queries (would be very expensive to perform a label look-up on each entry individually). + * @param array<FreshRSS_Entry|numeric-string> $entries the list of entries for which to retrieve the labels. + * @return array<string,array<string>> An array of the shape `[e_id_entry => ["label 1", "label 2"]]` */ public function getEntryIdsTagNames(array $entries): array { $result = []; diff --git a/app/views/helpers/export/articles.phtml b/app/views/helpers/export/articles.phtml index 60041339b..1db627bf7 100644 --- a/app/views/helpers/export/articles.phtml +++ b/app/views/helpers/export/articles.phtml @@ -26,11 +26,7 @@ foreach ($this->entries as $entry) { $feed = $this->feed ?? FreshRSS_CategoryDAO::findFeed($this->categories, $entry->feedId()); $entry->_feed($feed); - if (isset($this->entryIdsTagNames['e_' . $entry->id()])) { - $entry->_tags($this->entryIdsTagNames['e_' . $entry->id()]); - } - - $article = $entry->toGReader('freshrss'); + $article = $entry->toGReader('freshrss', $this->entryIdsTagNames['e_' . $entry->id()] ?? []); $line = json_encode($article, $options); if ($line != '') { diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 9d995c6d6..356d5bc0d 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -330,7 +330,6 @@ function customSimplePie(array $attributes = array()): SimplePie { return $simplePie; } -/** @param string $data */ function sanitizeHTML(string $data, string $base = '', ?int $maxLength = null): string { if ($data === '' || ($maxLength !== null && $maxLength <= 0)) { return ''; diff --git a/p/api/greader.php b/p/api/greader.php index e42736869..a014a4db1 100644 --- a/p/api/greader.php +++ b/p/api/greader.php @@ -573,11 +573,7 @@ final class GReaderAPI { } $entry->_feed($feed); - if (isset($entryIdsTagNames['e_' . $entry->id()])) { - $entry->_tags($entryIdsTagNames['e_' . $entry->id()]); - } - - $items[] = $entry->toGReader('compat'); + $items[] = $entry->toGReader('compat', $entryIdsTagNames['e_' . $entry->id()] ?? []); } return $items; } |
