feat(import): support category field in JSON feed import (#8786)

* Extension to JSON imports: interpret
      "origin": {
        "category": "..."
      },
as category for FreshRSS. When importing a new feed configure the feed
into this category. Creates missiong categories on the fly.

* Fix syntax

* fix(import): tighten JSON category import follow-ups

- Use strict comparison `!== false` after `addCategory()` so a (theoretical)
  zero return from auto-increment is not silently treated as failure
  (matches review feedback on #5638).
- Modernise property declaration to typed property syntax, matching the
  surrounding `$entryDAO`/`$feedDAO` style.
- Pass `$username` to `createCategoryDao()` in `importFile()` so CLI
  imports for a non-current user create categories on the right account,
  matching the adjacent entry/feed DAO instantiations.
- Trim the requested category name and skip if it is empty after trim,
  so a whitespace-only `"category"` value falls back to the default
  category instead of creating a junk row with an empty name. Also
  normalises trailing/leading whitespace so `"  Tech News  "` reuses an
  existing `"Tech News"` category.

* Update app/Controllers/importExportController.php

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>

---------

Co-authored-by: Robert Dahlem <robert.dahlem@gmx.net>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Co-authored-by: Bjørn A. Andersen <polybjorn@users.noreply.github.com>
This commit is contained in:
polybjorn
2026-05-04 13:02:03 +00:00
committed by GitHub
parent 92e34aec6d
commit 0c93b26cb5

View File

@@ -10,6 +10,8 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController {
private FreshRSS_FeedDAO $feedDAO;
private FreshRSS_CategoryDAO $categoryDAO;
/**
* This action is called before every other action in that class. It is
* the common boilerplate for every action. It is triggered by the
@@ -23,6 +25,7 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController {
$this->entryDAO = FreshRSS_Factory::createEntryDao();
$this->feedDAO = FreshRSS_Factory::createFeedDao();
$this->categoryDAO = FreshRSS_Factory::createCategoryDao();
}
/**
@@ -62,6 +65,7 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController {
$this->entryDAO = FreshRSS_Factory::createEntryDao($username);
$this->feedDAO = FreshRSS_Factory::createFeedDao($username);
$this->categoryDAO = FreshRSS_Factory::createCategoryDao($username);
$type_file = self::guessFileType($name);
@@ -573,10 +577,17 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController {
}
$name = empty($origin['title']) ? $website : $origin['title'];
$cat_id = FreshRSS_CategoryDAO::DEFAULTCATEGORYID;
$cat_name = trim($origin['category'] ?? '');
if ($cat_name !== '') {
$new_cat = $this->categoryDAO->searchByName($cat_name);
$cat_id = $new_cat?->id() ?: $this->categoryDAO->addCategory(['name' => $cat_name]) ?: FreshRSS_CategoryDAO::DEFAULTCATEGORYID;
}
try {
// Create a Feed object and add it in database.
$feed = new FreshRSS_Feed($url);
$feed->_categoryId(FreshRSS_CategoryDAO::DEFAULTCATEGORYID);
$feed->_categoryId($cat_id);
$feed->_name($name);
$feed->_website($website);
if (!empty($origin['disable'])) {