aboutsummaryrefslogtreecommitdiff
path: root/app/Models
AgeCommit message (Collapse)Author
2025-08-14Minor change of signature on_http_response (#7825)Gravatar Alexandre Alapetite
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/7824
2025-08-14Fix regression on_http_response (#7824)Gravatar Alexandre Alapetite
Fix regression (bad merge) from https://github.com/FreshRSS/FreshRSS/pull/7775 * https://github.com/FreshRSS/simplepie/pull/50
2025-08-09Show warning when unsafe CSP policy is in use (#7804)Gravatar Inverle
* Show warning when unsafe CSP policy is in use * Fix bare markdown URL * i18n: fr * Minor i18n: fr * Add target="_blank" to i18n strings --------- Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-08-07Add more unicity criteria based on title and/or content (#7789)Gravatar Alexandre Alapetite
* Add more unicity criteria based on title and/or content https://github.com/FreshRSS/FreshRSS/discussions/7788 * More
2025-08-07PHPStan: finalise strictArrayFilter (#7794)Gravatar Alexandre Alapetite
As well as reportPossiblyNonexistentConstantArrayOffset. And disable PHPStan-next from GitHub Action, since the work is completed for now.
2025-08-06GReader API: fix incorrect favicon URL (#7792)Gravatar hilariousperson
* GReader API: fix incorrect favicon URL * Fix compatibility with custom favicons --------- Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-08-01Rework fetch favicons (#7767)Gravatar Alexandre Alapetite
* Use main function `httpGet()` instead of local one; * Use HTTP cache, also between users; * Do not default to feed URL when there is no website URL TODO for later: consider supporting Atom's `<icon>` and RSS 2.0's `<image>` https://github.com/FreshRSS/FreshRSS/issues/7774
2025-07-31Implement sudo mode / reauthentication (#7753)Gravatar Inverle
* Implement sudo mode / reauthentication * i18n: fr * generate flags * Improvements * Remove HMAC check * Don't require reauth to access logs when signed in as admin * Notify user of bad login via notification instead --------- Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-07-31Implement support for HTTP 429 Too Many Requests (#7760)Gravatar Alexandre Alapetite
* Implement support for HTTP 429 Too Many Requests Will obey the corresponding HTTP `Retry-After` header at domain level. * Implement 503 Service Unavailable * Sanitize Retry-After * Reduce default value when Retry-After is absent And make configuration parameter * Retry-After also for favicons
2025-07-30`before_login_btn` hook + system conf attributes (#7761)Gravatar Inverle
* `before_login_btn` hook + system conf attributes * phpstan fix * Refactoring --------- Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-07-26Include enclosures in entries hash (#7719)Gravatar Alexandre Alapetite
* Include enclosures in entries hash Fix https://github.com/FreshRSS/FreshRSS/issues/7718 Negative side-effect: users using the option to automatically mark updated articles as unread will have some articles with enclosures appear as unread * Changelog with warning
2025-07-19WebSub: only perform a redirect when coming from WebSub (#7738)Gravatar Alexandre Alapetite
And add support for HTTP Link header for "self" URL Changing URL based on "self" URL will only be done when coming from a WebSub push fix https://github.com/FreshRSS/FreshRSS/issues/7737
2025-07-15Sort by category title, feed title (#7702)Gravatar Alexandre Alapetite
* Sort by category name, feed name fix https://github.com/FreshRSS/FreshRSS/issues/7698 Note that sorting is done with the default SQL collation for now, meaning that lower-case vs. upper-case and diacritics are influencing the sorting order. Improvements left for future work. Watch out that those sorting criteria are slower due to additional joins, additional requests, and poorer indexes. * i18n:pl Co-authored-by: Inverle <inverle@proton.me> * i18n: nl Co-authored-by: Frans de Jonge <fransdejonge@gmail.com> * Fix preserve sort --------- Co-authored-by: Inverle <inverle@proton.me> Co-authored-by: Frans de Jonge <fransdejonge@gmail.com>
2025-07-07Disallow setting non-existent theme (#7722)Gravatar Inverle
Related: https://github.com/FreshRSS/xExtension-Demo/pull/2, https://github.com/FreshRSS/FreshRSS/pull/7559#issuecomment-2858083635 Mostly to make sure that no one is able to break the demo instance But the issues below could possibly be exploited in other scenarios too: * Setting a theme like `../../lib/core-extensions/UserJS`: this directory contains `metadata.json` like themes do, so FreshRSS treats it as a theme after setting it and doesn't load any CSS * Setting a theme like `x dropdown-menu`: the `dropdown-menu` class was able to get injected into the `<body>` element since https://github.com/FreshRSS/FreshRSS/pull/7559 and turn every page blank
2025-06-30Implement custom feed favicons (#7646)Gravatar Inverle
Closes #3789, #6503 Icon setting when no custom icon is set yet: ![image](https://github.com/user-attachments/assets/28b07dd0-7dac-4c76-b1d7-77035f91a87a) - `Change...` button opens a file dialog, and after selecting a file shows the chosen icon in the preview on the left. `Submit` must be clicked after selecting the icon. - `Reset to default` changes the preview icon to the default one, and also requires `Submit` to be clicked to apply the changes. Full list of changes: - CSP now includes `blob:` in `img-src` for - `indexAction()` and `feedAction()` in `subscriptionController.php` - all of the view actions in `indexController.php` - Introduce new attribute `customFavicon (boolean)` for feeds that indicates if the feed has a custom favicon - `hashFavicon()` in `Feed.php` is dependent on this attribute - `hashFavicon()` has a new parameter called `skipCache (boolean)` that allows the reset of the favicon hash for the Feed object - `resetFaviconHash()` just calls `hashFavicon(skipCache: true)` - `f.php` URLs now have the format of `/f.php?h=XXXXX&t=cachebuster`, where the `t` parameter is only used for serving custom favicons - if `t` parameter is set, `f.php` returns a `Cache-Control: immutable` header - `stripos` and `strpos` were changed to `str_contains` in various places (refactor) - JS for handling the custom favicon configuration logic is in `extra.js` inside `init_update_feed()` which is called when feed configuration is opened from the aside or when the subscription management page with the feed is loaded - Server-side code for uploading the icon in `subscriptionController.php` under `feedAction()` - Errors that may occur during the setting of a custom favicon: - Unsupported image file type (handled only server-side with `isImgMime()`) - When the file is bigger than 1 MiB (default), handled both client-side and server-side - Standard feed error when `updateFeed()` fails - JS vars `javascript_vars.phtml` are no longer escaped with `htmlspecialchars()`, instead with json encoding, - CSS for disabled buttons was added - Max favicon file size is configurable with the `max_favicon_upload_size` option in `config.php` (not exposed via UI) - Custom favicons are currently deleted only when they are either reset to the default icon, or the feed gets deleted. They do not get deleted when the user deletes their account without removing their feeds first. - ` faviconPrepare()` and `faviconRebuild()` are not allowed to be called when the `customFavicon` attribute is `true` - New i18n strings: - `'sub.feed.icon' => 'Icon'` - `'sub.feed.change_favicon' => 'Change…'` - `'sub.feed.reset_favicon' => 'Reset to default'` - `'sub.feed.favicon_changed_by_ext' => 'The icon has been set by the <b>%s</b> extension.'` - `'feedback.sub.feed.favicon.too_large' => 'Uploaded icon is too large. The maximum file size is <em>%s</em>.'` - `'feedback.sub.feed.favicon.unsupported_format' => 'Unsupported image file format!'` - Extension hook `custom_favicon_hash` - `setCustomFavicon()` method - `resetCustomFavicon()` method - `customFaviconExt` and `customFaviconDisallowDel` attributes - example of usage: https://github.com/FreshRSS/Extensions/pull/337 - Extension hook `custom_favicon_btn_url` - Allows extensions to implement a button for setting a custom favicon for individual feeds by providing an URL. The URL will be sent a POST request with the `extAction` field set to either `query_icon_info` or `update_icon`, along with an `id` field which describes the feed's ID.
2025-06-29Add search operator `c:` for categories (#7696)Gravatar Alexandre Alapetite
* Add search operator `c:` for categories fix https://github.com/FreshRSS/FreshRSS/discussions/7692 Allow searching for e.g. `c:23,34`
2025-06-22Exposed the reading modes for extensions through Minz (#7668)Gravatar Stefan
* + Exposed the reading modes for extensions through Minz. Now extensions can add a custom view mode. Graceful fallback to normal view in case the extension was disabled without resetting the view_mode through the uninstall method. In that case the user will be informed via Minz_Request::setBadNotification that the view has been reset to normal. + Added translation strings for de, en and en-us for the notification * + Added missing, generated translations * Simplify indexAction, performance * Minor settings htmlspecialchars * i18n: fr * Minor wording * Doc * Fix i18n --------- Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-06-22Handle redirects when scraping feed from HTML (#7654)Gravatar Inverle
* Handle redirects when scraping feed from HTML * pass codesniffer * pass PHPStan * Optimize * Another approach relying on HTML base Standard way to save an HTML document with relative references * Fix case of existing HTML base which should not be overriden --------- Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-06-15Remove several PHPStan ignore (#7665)Gravatar Alexandre Alapetite
* Remove several PHPStan ignore * One syntax error * PDO returns int, not bool (MySQL and SQLite Boolean types are aliases for tinyint). * A few missing type hints * Revert strange PHPStan bug
2025-06-06Install: add test PDO typing (#7651)Gravatar Alexandre Alapetite
fix https://github.com/FreshRSS/FreshRSS/issues/7647
2025-06-04PHPStan: pass checkImplicitMixed (#7642)Gravatar Alexandre Alapetite
* PHPStan: pass checkImplicitMixed * Complete
2025-05-17Add info about PDO::ATTR_CLIENT_VERSION (#7591)Gravatar Alexandre Alapetite
Help with https://github.com/FreshRSS/FreshRSS/issues/7586
2025-05-13Fix SQL request for user labels with custom sort (#7588)Gravatar Alexandre Alapetite
The list or articles with a user label with a custom sort was broken when using PostgreSQL Example: `https://freshrss.example.net/i/?a=normal&get=T&sort=title&order=ASC` ``` SQL error FreshRSS_EntryDAO::listWhereRaw["42P10",7,"ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list\nLINE 3: ...d_entry = e.id WHERE 1=1 AND e.id <= $1 ORDER BY e.title DE...\n ^"] ```
2025-05-10Fix newest articles not shown (#7577)Gravatar Alexandre Alapetite
* Fix newest articles not shown Case when processing was faster than 1 second. fix https://github.com/FreshRSS/FreshRSS/issues/7412 Regression from https://github.com/FreshRSS/FreshRSS/pull/7149 * Simplify uTimeString() PHPStan has become a bit smarter
2025-05-07Fix encoding of themes (#7565)Gravatar Alexandre Alapetite
* Fix encoding of themes Several HTML and URL encoding issues in the case of special chars in theme directory or in metadata. Also usefull to simplify https://github.com/FreshRSS/FreshRSS/pull/7559 * Minor simplification * Stricter decoding
2025-05-01Bump phpstan/phpstan from 2.1.11 to 2.1.13 (#7534)Gravatar dependabot[bot]
* Bump phpstan/phpstan from 2.1.11 to 2.1.13 Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 2.1.11 to 2.1.13. - [Release notes](https://github.com/phpstan/phpstan/releases) - [Changelog](https://github.com/phpstan/phpstan/blob/2.1.x/CHANGELOG.md) - [Commits](https://github.com/phpstan/phpstan/compare/2.1.11...2.1.13) --- updated-dependencies: - dependency-name: phpstan/phpstan dependency-version: 2.1.13 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump phpstan/phpstan from 2.1.11 to 2.1.13 Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 2.1.11 to 2.1.13. - [Release notes](https://github.com/phpstan/phpstan/releases) - [Changelog](https://github.com/phpstan/phpstan/blob/2.1.x/CHANGELOG.md) - [Commits](https://github.com/phpstan/phpstan/compare/2.1.11...2.1.13) --- updated-dependencies: - dependency-name: phpstan/phpstan dependency-version: 2.1.13 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Fix PHPStan --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-04-26Improve favicon hash (#7505)Gravatar Alexandre Alapetite
* Favicon hash proxy Content provided through a proxy may be completely different, so the feed hash must account for that * Fix typing * Hash of Web site in priority for favicons * Continue * Revert some minor changes
2025-04-02Pass phpstan-strict-rules 2.0.4 (#7488)Gravatar Alexandre Alapetite
New check for Boolean in while conditions Replace https://github.com/FreshRSS/FreshRSS/pull/7481
2025-04-01Make update URL readonly (#7477)Gravatar Alexandre Alapetite
The security risks look higher than the minor convinience Modify https://github.com/FreshRSS/FreshRSS/pull/1024
2025-03-24Support multiple JSON fragments in HTML+XPath+JSON mode (#7369)Gravatar Alexandre Alapetite
* Support multiple JSON fragments in HTML+XPath+JSON mode fix https://github.com/FreshRSS/FreshRSS/discussions/7352#discussioncomment-12295475 E.g. HTML with one `<script type="application/ld+json">...</script>` per item. * Better help messages
2025-03-13Mark as read button: config for the size (#7314)Gravatar maTh
* settings * i18n: mark_read_button * big, small, none * fix * Fixes * make fix-all --------- Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-03-05Use case-insensitive sort for categories (#7402)Gravatar Annika Backstrom
Changes proposed in this pull request: - Use `strnatcasecmp()` inside `listSortedCategories()` How to test the feature manually: 1. Create categories `A`, `b`, and `C` 2. Observe that categories are sorted case-insensitively on the feed index and Subscription Management pages
2025-03-03Fix dynamic OPML (#7394)Gravatar Alexandre Alapetite
Regression from https://github.com/FreshRSS/FreshRSS/pull/7155 Fix https://github.com/FreshRSS/FreshRSS/issues/7385
2025-02-26Fix bigint timestamps on 32-bit (#7375)Gravatar Alexandre Alapetite
* Fix bigint timestamps on 32-bit fix https://github.com/FreshRSS/FreshRSS/issues/7374 SQL requests for BIGINT fields may return a string on 32-bit systems instead of an integer * Calculations may also be string
2025-02-23PHPStan more checkImplicitMixed (#7339)Gravatar Alexandre Alapetite
* PHPStan more checkImplicitMixed * Draft Entry.php * Finish Entry.php * Finish FeedDAO.php and Themes.php
2025-02-23fix: properly set the priority field of feeds when adding new feed. (#7354)Gravatar Zihao Diao
Signed-off-by: Zihao Diao <hi@ericdiao.com>
2025-02-20Fix regression XPath XML encoding (#7345)Gravatar Alexandre Alapetite
* Fix regression XPath XML encoding fix https://github.com/FreshRSS/FreshRSS/discussions/7325 The categories (tags) were not correctly XML-escaped due to being an array https://github.com/FreshRSS/FreshRSS/pull/5305/files#r1964316119 * Improve typing
2025-02-03Shortcuts for adding labels (#7274)Gravatar maTh
* add shortcut in config * open my labels menu with shortcut * the first 9 items are selectable + input field * i18n * Update app/i18n/nl/conf.php Co-authored-by: Frans de Jonge <fransdejonge@gmail.com> * index.menu.mylabels * order fixed --------- Co-authored-by: Frans de Jonge <fransdejonge@gmail.com>
2025-01-31Pass PHPStan checkBenevolentUnionTypes (#7270)Gravatar Alexandre Alapetite
2025-01-29Fix unwanted feed description updates (#7269)Gravatar Alexandre Alapetite
fix https://github.com/FreshRSS/FreshRSS/discussions/7265
2025-01-25Add search operator intext: (#7228)Gravatar Alexandre Alapetite
* Add search operator intext: fix https://github.com/FreshRSS/FreshRSS/issues/6188 https://github.com/FreshRSS/FreshRSS/discussions/7220 * Add example to doc
2025-01-21Hide base theme (#7234)Gravatar Alexandre Alapetite
2025-01-11Fix stats for MySQL (#7212)Gravatar Alexandre Alapetite
fix https://github.com/FreshRSS/FreshRSS/issues/7210 MySQL returns decimal for some columns, which get converted to string instead of integer in PHP
2025-01-10Fix sqlite_version (#7205)Gravatar Alexandre Alapetite
* Fix sqlite_version for https://github.com/FreshRSS/FreshRSS/pull/7161 * Fix PostgreSQL
2025-01-10Reduce undeeded use of elvis operator ?: (#7204)Gravatar Alexandre Alapetite
2025-01-08Fix sharing integration (#7198)Gravatar Alexandre Alapetite
fix https://github.com/FreshRSS/FreshRSS/issues/7192
2025-01-08Add some missing PHP native types (#7191)Gravatar Alexandre Alapetite
* Add some missing PHP native types Replaces https://github.com/FreshRSS/FreshRSS/pull/7184 * Clean some types
2025-01-06Implement custom order-by (#7149)Gravatar Alexandre Alapetite
Add option to sort results by received date (existing, default), publication date, title, URL (link), random. fix https://github.com/FreshRSS/FreshRSS/issues/1771 fix https://github.com/FreshRSS/FreshRSS/issues/2083 fix https://github.com/FreshRSS/FreshRSS/issues/2119 fix https://github.com/FreshRSS/FreshRSS/issues/2596 fix https://github.com/FreshRSS/FreshRSS/issues/3204 fix https://github.com/FreshRSS/FreshRSS/issues/4405 fix https://github.com/FreshRSS/FreshRSS/issues/5529 fix https://github.com/FreshRSS/FreshRSS/issues/5864 fix https://github.com/FreshRSS/Extensions/issues/161 URL parameters: * `&sort=id` (current behaviour, sorting according to newest received articles) * `&sort=date` (publication date, which is not indicative of how new an article is) * `&sort=title` * `&sort=link` * `&sort=rand` (random order - which disables infinite scrolling, at least for now) combined with `&order=ASC` or `&order=DESC` ![image](https://github.com/user-attachments/assets/2de5aef1-604e-4a73-a147-569f6f42a1be) ## Implementation notes The sorting criteria by *received date* (id), which is the default, and which was the only one before this PR, is the one that has the best sorting characteristics: * *uniqueness*: no entries have the exact same received date * *monotonicity*: new entries always have a higher received date * *performance*: this field is efficiently indexed in database for fast usage, including for paging (indexing could also be done to other fields, but with lower effective performance) In contrary, sorting criteria such as by *publication date*, by *title*, or by *link* are neither unique nor monotonic. In particular, multiple articles may share the same *publication date*, and we may receive articles with a *publication date* far in the future, and then later some new articles with a *publication date* far in the past. To understand why sorting by *publication date* is problematic, it helps to think about sorting by *title* or by *link*, as sorting by *title* and by *publication date* share more or less the same characteristics. ### Problem 1: new articles New articles may be received in the background after what is shown on screen, and before the next user action such as *mark all as read*. Due to the lack of *monotonicity* when sorting by e.g. *publication date* or *title*, users risk marking as read a batch of articles containing some fresh articles without seeing them. Mitigation: A parameter `idMax` tracks the maximum ID related to a batch of actions such as *mark all as read* to exclude articles received after those that are displayed. ### Problem 2: paging / pagination When navigating articles, only a few articles are displayed, and a new "page" of articles needs to be received from the database when scrolling down or when clicking the button to show more articles. When sorting by e.g. *publication date* or *title*, it is not trivial to show the next page without re-showing some of the same articles, and without skipping any. Indeed, views are often with additional criteria such as showing only unread articles, and users may mark some articles as read while viewing them, hereby removing some articles from the previous pages. And like for *Problem 1*, new articles may have been received in the background. Consequently, it is not possible to use `OFFSET` to implement pagination (so the patches suggested by a few users were wrong due to that, in particular). Mitigation: `idMax` is also used (just like for *Problem 1*) and a *Keyset Pagination* approach is used, combining an unstable sorting criterion such as *publication date* or *title*, together with *id* to ensure stable sorting. (So, 2 sorting criteria + 1 filter criteria) See e.g. https://www.alwaysdeveloping.net/dailydrop/2022/07/01-keyset-pagination/ ### Problem 3: performance Sorting by anything else than *received date* (id) is doomed to be slow(er) due to the combination of 3 criteria (see *Problem 2*). An `OFFSET` approach (which is not possible anyway as explained) would be even slower. Furthermore, we have no SQL index at the moment, but they would not necessarily help much due to the multiple sorting criteria needed and involving some `OR` logic which is difficult to optimise for databases. The nicest syntax would be using tuples and corresponding indexes, but that is poorly supported by MySQL https://bugs.mysql.com/bug.php?id=104128 Mitigation: a compatibility SQL syntax is used to implement *Keyset Pagination* ### Problem 4: user confusion Several users have shown that they do not fully understand the difference between *received date* and *publication date*, and particularly not the pitfalls of *publication date*. Mitigation: the menus to mark-as-read *before 1 day* and *before 1 week* are disabled when sorting by anything else than *received date*. Likewise, the separation headers *Today* and *Yesterday* and *Before yesterday* are only shown when sorting by *received date*. Again here, to better understand why, it helps to think about sorting by *title* or by *link*, as sorting by *title* and by *publication date* share more or less the same characteristics. * [ ] We should write a Q&A and/or documentation about the problems associated to *sorting by publication date*: risks of not noticing new publication, of inadvertently marking them as read, of having some articles with a date in the future hanging at the top of the views (vice versa when sorting in ascending order), performance, etc. ### Problem 5: APIs Sorting by anything else than *received date* breaks the guarantees needed for a successful synchronisation via API. Mitigation: sorting by *received date* is ensured for all API calls.
2024-12-28Fix regressions on some array structures (#7155)Gravatar Alexandre Alapetite
regressions from https://github.com/FreshRSS/FreshRSS/pull/7131 fix https://github.com/FreshRSS/FreshRSS/issues/7154
2024-12-27Fix regression labels (#7150)Gravatar Alexandre Alapetite
Regression from https://github.com/FreshRSS/FreshRSS/pull/7131