Commit Graph

981 Commits

Author SHA1 Message Date
Alexandre Alapetite
a8a544a2a2 Fix search encoding and quoting (#8311)
Revised the encoding approach for searches: the HTML encoding is done just before its use for DB search.
Fix also some cases with wrong quoting.
Fix https://github.com/FreshRSS/FreshRSS/pull/8306#issuecomment-3643865439
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/8293
2025-12-13 11:31:34 +01:00
Alexandre Alapetite
394411677e Add functions to modify a search expression (#8293)
* Allows easier modifications of the search expression.
* Add proper `__toString()` instead of just returning the raw input string. Allows in particular showing the result of the actual parsing of the raw input string in the UI.

Needed for https://github.com/FreshRSS/FreshRSS/pull/8294
2025-12-10 22:41:45 +01:00
Alexandre Alapetite
19975c22ec Fix minor backslashes (#8292) 2025-12-07 20:27:06 +01:00
Inverle
6d2bb24b37 Move unsafe autologin to an extension (#7958)
Completes the following TODO https://github.com/FreshRSS/FreshRSS/issues/7923:

de624dc8ce/app/Controllers/authController.php (L105)

Extension PR: https://github.com/FreshRSS/Extensions/pull/364

https://github.com/FreshRSS/Extensions/tree/main/xExtension-UnsafeAutologin
2025-12-04 20:10:20 +01:00
Alexandre Alapetite
78e40c6fe3 Scaling of user statistics (#8277)
Fix https://github.com/FreshRSS/FreshRSS/issues/8268
To better support user management on FreshRSS instance with many users.

SQL speed improved. On a reduced test with 5 users, including some large accounts (PostgreSQL on a very tiny and slow server), improving from ~2.3s to ~1.8s, which gives ~20% speed improvement.

Then tested with 1000 users, with only the default feed (on my old desktop computer):

```sh
for i in {1..1000}; do ./cli/create-user.php --user=freshrss$i --password=freshrss; done
app/actualize_script.php
cli/access-permissions.sh
```

SQLite:

```console
$ time cli/user-info.php | wc -l
1001

real    0m1.366s
user    0m0.908s
sys     0m0.475s
```

PostgreSQL:

```console
$ time cli/user-info.php | wc -l
1001

real    0m28.498s
user    0m12.137s
sys     0m2.217s
```

MariaDB:

```console
# time ./cli/user-info.php | wc -l
1001

real    0m49.485s
user    0m1.276s
sys     0m2.258s
```

Yes, SQLite is much faster - not a surprise for such use-cases, where the TCP connection is not re-used.

I have added some CLI options to disable some statistics:

```sh
cli/user-info.php --no-db-size --no-db-counts
```

For the Web UI, I have disabled detailed user statistics if it takes too long, and retrieve missing user statistics asynchronously via JavaScript. Lazy loading of the user details based on IntersectionObserver, with maximum 10 requests in parallel.
Web UI tested on 1000 users as well. Checked with SeaMonkey.
2025-12-04 19:11:31 +01:00
Inverle
60cf5ea297 Improve anonymous authentication logic (#8165)
* Improve anonymous authentication logic

* forgot to git add

* Fix incorrect token check

Because an empty parameter could be just passed if token for the user wasn't set: `&token=`
2025-12-04 08:46:11 +01:00
Alexandre Alapetite
a50e9a98db Fix MySQL / MariaDB database size calculation (#8282)
The `_` is a special character in the SQL `LIKE` expression and was not escaped, leading to users counting for other users size.
Stats for `freshrss` user included users `freshrss1` and `freshrss2` (but not vice versa).
Discovered during https://github.com/FreshRSS/FreshRSS/pull/8277
2025-12-03 23:43:03 +01:00
dependabot[bot]
6431520ae5 Bump phpstan/phpstan from 2.1.31 to 2.1.32 (#8275)
* Bump phpstan/phpstan from 2.1.31 to 2.1.32

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.1.32
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Ignore

---------

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-12-02 10:44:39 +01:00
Alexandre Alapetite
023cdf0d7a Web scraping support date format epoch milliseconds (#8266)
fix https://github.com/FreshRSS/FreshRSS/discussions/8264
Auto detect whether a `U` date format should be in seconds or milliseconds.
2025-11-30 21:42:46 +01:00
Alexandre Alapetite
76f5bee76d Better merging of custom HTTP headers (#8251)
Alternative to https://github.com/FreshRSS/FreshRSS/pull/8246
See https://github.com/FreshRSS/FreshRSS/issues/8189#issuecomment-3569434305
2025-11-27 23:31:03 +01:00
Alexandre Alapetite
5e0093aa00 Fix MariaDB updateCachedValues (#8255)
Changed syntax for an even wider compatibility.
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/8254
Regression from https://github.com/FreshRSS/FreshRSS/pull/6957
MariaDB images on Docker Hub go back to 10.6, so changed documentation to indicate support from that version, as I cannot easily test even older versions.
2025-11-26 23:47:29 +01:00
Alexandre Alapetite
b3cfc387b8 Fix MariaDB for updates (#8254)
fix https://github.com/FreshRSS/FreshRSS/issues/8252
regression from https://github.com/FreshRSS/FreshRSS/pull/6957
The current code works with MySQL 8+ (as well as PostgreSQL and SQLite), but not with MariaDB, because MariaDB does not support CTE (Common Table Expression) fully (which I was not aware of)...
2025-11-26 16:47:40 +01:00
Alexandre Alapetite
deb7633c49 Change SQL update query (#6957)
* Change SQL update query for MariaDB / MySQL
fix https://github.com/FreshRSS/FreshRSS/issues/5707

* No change for SQLite

* Fix merge error

* Update MySQL version on the model of PostgreSQL
Performance to be tested

* Fix LEFT JOIN, also for PostgreSQL / SQLite

* Fix alias

* Reduce MySQL deadlock

* Fix compatibility with SQLite

* Back to identical SQL for all databases
2025-11-17 13:48:48 +01:00
Alexandre Alapetite
419a1978b6 Fix MySQL commitNewEntries (#8223)
I just realised that `commitNewEntries()` was not sorting articles properly before insertion in database when using MySQL: Articles were not sorted by publication date as expected from the temporary table before insertion in the final table. MySQL was not picking the correct field, so fixed with an explicit alias.
Discovered because I did some tests with MySQL in https://github.com/FreshRSS/FreshRSS/pull/6957
At the same time, I did the same change for PostgreSQL and SQLite although those were not affected.
2025-11-17 13:46:28 +01:00
Martin Hartmann
b6314bee31 force correct index for MySQL when listing entries (#8211)
* force correct index for MySQL when listing entries

* Make special case for MySQL / MariaDB

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-11-15 23:17:13 +01:00
Alexandre Alapetite
45471871dd SQL: Optimise speed of updateCachedValues() (#8207)
For PostgreSQL and SQLite
fix https://github.com/FreshRSS/FreshRSS/issues/8206
2025-11-15 20:11:25 +01:00
Alexandre Alapetite
a18c35046d Housekeeping lib_rss.php (#8193)
* Housekeeping lib_rss.php
`lib_rss.php` had become much too large, especially after https://github.com/FreshRSS/FreshRSS/pull/7924
Moved most functions to other places.
Mostly no change of code otherwise (see comments).

* Extension: composer run-script phpstan-third-party
2025-11-11 08:17:12 +01:00
Alexandre Alapetite
b6c63d2239 Better transitions between groups of articles (#8174)
fix https://github.com/FreshRSS/FreshRSS/issues/7520
fix https://github.com/FreshRSS/FreshRSS/issues/8168
fix https://github.com/FreshRSS/FreshRSS/discussions/8172
2025-11-04 12:49:21 +01:00
Inverle
7d4854a0a4 Create separate Retry-After files for proxies (#8029)
* Create separate `Retry-After` files for proxies
Bad proxies are able to send a false `Retry-After` header and affect the availability of feeds (domain-wide) for other users.
This PR starts including the address of the proxy if present in filenames for `Retry-After` to mitigate the issue.

* Reduce code changes

* Sync SimplePie fork
https://github.com/FreshRSS/simplepie/pull/62

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-11-04 12:48:31 +01:00
scollovati
04c55fa1b8 [sqlite export] add username and timestamp (#8169)
* [sqlite export] add username and timestamp
add username and timestamp to sqlite user export, similar to the ZIP export. Useful for archiving purposes.

* Fix case of backups and other DB types
https://github.com/FreshRSS/FreshRSS/pull/8169#issuecomment-3476079108

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
2025-11-02 20:39:41 +01:00
Alexandre Alapetite
49a92c2437 Mark as read 1 or 7 days based on publication date (#8163)
Allow the UI for marking as read articles older than 1 or 7 days to also work when sorting by publication date (in which case, the publication date is used).

<img width="382" height="229" alt="image" src="https://github.com/user-attachments/assets/a630dec8-1e18-4766-8392-59fb593dd73d" />
2025-10-28 19:07:14 +01:00
Alexandre Alapetite
6440f9c9a9 Fix DOM fatal error while filtering retrieved full content (#8161)
https://github.com/FreshRSS/FreshRSS/pull/8132 was not sufficient.
Fix *PHP Fatal error: Uncaught Error: Couldn't fetch DOMElement. Node no longer exists*
2025-10-26 22:35:11 +01:00
dependabot[bot]
f1c91c84dd Bump phpstan/phpstan from 2.1.29 to 2.1.31 (#8156)
* Bump phpstan/phpstan from 2.1.29 to 2.1.31

Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) from 2.1.29 to 2.1.31.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.1.31
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fixes

---------

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-10-25 11:21:28 +02:00
Alexandre Alapetite
9833d81976 Better SQL auto-update f.kind (#8148)
Add a little help to make sure that feed.kind gets added during the first call.
Tested that replacing the DB with a backup from Febuary 2020 just works, automatically adding new columns since FreshRSS 1.20.0.
2025-10-24 12:49:29 +02:00
Alexandre Alapetite
1282d3a270 PostgreSQL: compatibility with PCRE word boundary (#8141)
Allow the use of regex `\b` for word boundary (and `\B` for the opposite) even when using PostgreSQL.
Follow up of:
* https://github.com/FreshRSS/FreshRSS/pull/6706

For instance, `intitle:/\bnew\B/` will find *newest* but not *new* nor *renewal*.

Useful in particular to minimise the differences between PHP and database in:
* https://github.com/FreshRSS/FreshRSS/pull/7959
2025-10-22 21:21:17 +02:00
Alexis Degrugillier
eee8b8c03f Add support for extension compatibility (#8081)
The compatibility does support only a minimum version of FreshRSS. If we need
something a bit more clever in the future, it is possible to handle a rule
with a bit more complexity.

See https://github.com/FreshRSS/FreshRSS/issues/5903

* Update app/Controllers/extensionController.php

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

* Update app/i18n/pl/admin.php

Co-authored-by: Inverle <inverle@proton.me>

* Minor move phpstan-type

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Co-authored-by: Inverle <inverle@proton.me>
2025-10-21 23:49:06 +02:00
Alexandre Alapetite
5909cc5756 Fix DOM error while filtering retrieved full content (#8132)
```
PHP Fatal error: Uncaught Error: Couldn't fetch DOMElement in app/Models/Entry.php:998
```
2025-10-17 15:56:19 +02:00
Alexandre Alapetite
1ef354a63e GReader API frss:priority (#7583)
* GReader API frss:priority
Experiment with a FreshRSS namespace in the GReader API to see whether there is any interest.
fix https://github.com/FreshRSS/FreshRSS/issues/1868

`'frss:priority'` can be: `'important'`, `'main'`, `'category'`, `'feed'` (there is also the value `hidden`, but which is filtered out and as such never sent through the API at the moment)

* Add visibility feed
https://github.com/FreshRSS/FreshRSS/pull/7972
2025-10-17 12:54:00 +02:00
Alexandre Alapetite
fbbb5a5e20 Fix API list by IDs (#8130)
fix https://github.com/FreshRSS/FreshRSS/issues/8129
Regression from https://github.com/FreshRSS/FreshRSS/pull/7886
2025-10-17 09:33:04 +02:00
Alexandre Alapetite
f08f7dcff9 Sort by article length (#8119)
* Sort by article length
fix https://github.com/FreshRSS/Extensions/issues/378
Very basic using simply SQL `LENGTH()` function.

<img width="492" height="217" alt="image" src="https://github.com/user-attachments/assets/7cf37303-76c8-4411-b8b1-075e81535b60" />

* Improve content length retrieval
2025-10-16 21:15:44 +02:00
Alexandre Alapetite
7e72033859 Filter on last user modified (#8093)
Example: `userdate:PT1H` to select only articles modified by user during the last hour
Fix https://github.com/FreshRSS/FreshRSS/issues/4280#issuecomment-3393078024

Useful for instance to bulk mark as unread recently marked articles by error:
1. Click on the toggle button to show the read articles (making sure the toggle for the unread articles is off)
2. Sort by *User modified 9→1*
3. Filter by *user modified date*, for instance to the last 3 hours by typing `userdate:PT3H`
4. Click in the drop-down menu *Mark selection as unread*

P.S.: I have added at the same time a bunch of unit tests for date-related logic
2025-10-15 00:12:19 +02:00
Alexandre Alapetite
e070c3ed2b Implement search form (#8103)
* Add UI for advanced search
To help users with the seach operators.
Obviously not as powerful as a manually-written search query.
Lack in particular negation and logical *and* for now, but I might try to do something about it.

<img width="939" height="1438" alt="image" src="https://github.com/user-attachments/assets/0bcad39b-eff3-4f44-876b-a2552af2af00" />

* Consistency: allow multiple user queries like S:1,2

* Fix user query and add tests
2025-10-15 00:08:40 +02:00
Alexandre Alapetite
1b8bc1ae8b Fix SQLite GREATEST() (#8118)
* Fix SQLite GREATEST()
fix https://github.com/FreshRSS/FreshRSS/pull/8105
Related to https://github.com/FreshRSS/FreshRSS/pull/7886
2025-10-14 23:56:57 +02:00
Alexandre Alapetite
b7bd18148e Option to show user labels instead of tags in RSS share (#8112)
* Option to show user labels instead of tags in RSS share
fix https://github.com/FreshRSS/FreshRSS/discussions/8108#discussioncomment-14668813

<img width="711" height="182" alt="image" src="https://github.com/user-attachments/assets/8effb2cd-fffb-4f00-b628-54e963e8b2dc" />
2025-10-14 15:43:43 +02:00
Alexandre Alapetite
5eba322cbd New stats overview of dates with most unread articles (#8089)
New view with direct links to dates with most unread articles:

<img width="734" height="581" alt="image" src="https://github.com/user-attachments/assets/159a39b3-3a06-4ae9-9cc0-62ae36d9db9c" />
2025-10-14 11:05:17 +02:00
Alexandre Alapetite
20ecbeb09c Fix drag&drop of user query losing information (#8113)
* Fix drag&drop of user query losing information
Information about RSS sharing was lost after a drag&drop

* Fix related type cast
2025-10-14 11:01:23 +02:00
Alexandre Alapetite
201c113041 Fix SQL updateEntry (#8105)
fix https://github.com/FreshRSS/FreshRSS/issues/8087#issuecomment-3395337832
Regression from https://github.com/FreshRSS/FreshRSS/pull/7886
2025-10-13 02:14:03 +02:00
Alexandre Alapetite
348b6e358b Fix SQL bind bug when adding tag (#8101)
Error in SQLite: `SQL error FreshRSS_TagDAO::addTag["HY000",25,"column index out of range"]`
2025-10-12 17:26:40 +02:00
Alexandre Alapetite
0551544287 Fix MySQL autoupdate Last user modified (#8090)
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/7886
(Probably wrong merge conflict resolution)
2025-10-11 12:02:40 +02:00
Federico Scodelaro
673067a52d Last user modified (#7886)
* feat: Add user modified functionality

Closes https://github.com/FreshRSS/FreshRSS/issues/7862

Changes proposed in this pull request:

This is an implementation of the proposed feature. It allows entries to have a new field that will be updated whenever an item is marked as read/unread or bookmark/removed from bookmarks. And a new sort criteria to sort by it.

How to test the feature manually:

1. Mark items from a feed as read/unread
2. Mark items from a feed as bookmark / remove bookmark
3. Sort by the new criteria

* feat: Add sort functionality
* feat: Add sort nav button
* fix: Use correct migrations
* fix: Add internationalization
* fix: Linter errors
* chore: PR comments

* Update app/i18n/fr/index.php
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>

* Update app/i18n/pl/index.php
Co-authored-by: Inverle <inverle@proton.me>

* Update app/i18n/nl/index.php
Co-authored-by: Frans de Jonge <fransdejonge@gmail.com>

* make fix-all
* Fixes
* More fixes sort
* Fix wrong index
* Fix unneeded column
* Fix auto-create indexes
* Some copilot suggestions
* One more fix
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Co-authored-by: Inverle <inverle@proton.me>
Co-authored-by: Frans de Jonge <fransdejonge@gmail.com>
2025-10-11 00:43:38 +02:00
Alexis Degrugillier
b6f4276c6c Change regional language codes (#8065)
* Change regional language codes

According to `ISO-639-1` and `ISO-3166-1 alpha-2` recommendations, regional
languages must be written with the language code in lowercase and the region
in uppercase. For instance, we should have `en-US` instead of `en-us`.

Folders have been updated to reflect those recommendations and regional
language codes have been updated in the translation files.

* Update README files

* Fix configuration for typos

* Revert language order in documentation

* Remove unnecessary code

* Change language configuration getter

* Fix phpstan error

* Fix typo

* Add types

* escape regex

* Move language logic to avoid magic or deprecated methods

* Minor fix on regex
2025-10-06 21:09:01 +02:00
Alexandre Alapetite
aeecba7b30 Do not mark important feeds as read from category (#8067)
Important feeds are not supposed to be marked as read from another view. This was already working for the main view, but this PR fixes the case of a category view.
Follow-up of:
* https://github.com/FreshRSS/FreshRSS/pull/5782
2025-10-04 23:53:44 +02:00
Alexandre Alapetite
57e1a375cb Strengthen some crypto (#8061)
For login, tokens, nonces
2025-10-04 14:32:18 +02:00
Alexandre Alapetite
df4b76f74b PHPStan 2.1.29 (#8052)
Replace:
* https://github.com/FreshRSS/FreshRSS/pull/8049
* https://github.com/FreshRSS/FreshRSS/pull/8050
2025-10-01 21:02:42 +02:00
Alexandre Alapetite
2601897c55 API optimisation: more streaming of outputs (#8041)
* API optimisation: more streaming of outputs
I spotted a memory issue when testing https://github.com/FreshRSS/FreshRSS/pull/7714
Attempt to stream results more, instead of keeping too much in memory.
Could be further improved.

* Apply suggestions from code review

Co-authored-by: Alexis Degrugillier <aledeg@users.noreply.github.com>

* Minor whitespace JSON formatting

---------

Co-authored-by: Alexis Degrugillier <aledeg@users.noreply.github.com>
2025-10-01 20:21:24 +02:00
maTh
2bcc090622 configurable notification timeout (#7942)
Ref #7931
Ref #5466
Ref #6409

added configuration in "Display"
<img width="636" height="167" alt="grafik" src="https://github.com/user-attachments/assets/7bbc9f26-d91b-4dd2-b715-1d3f9b7a9ad3" />

* i18n: fr

* Update app/i18n/pl/conf.php

Co-authored-by: Inverle <inverle@proton.me>

* make fix-all

* max()

* Minor whitespace
(I am not a fan of excessive vertical indenting)

---------

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Co-authored-by: Inverle <inverle@proton.me>
2025-10-01 10:48:07 +02:00
Alexis Degrugillier
72884813e1 Add hook enums (#8036)
- add an enum to handle hook types (enum are available since PHP 8.1)
- change hook calls from string value to enum value
2025-09-30 22:59:41 +02:00
Alexandre Alapetite
34532c0dd4 Add new visibility priority *Show in its feed* (#7972)
* Add new visibility priority *Show in its feed*
fix https://github.com/FreshRSS/FreshRSS/pull/7970#issuecomment-3293917428 (you can't directly filter a hidden feed, it just shows a 404 page)
And add a new visibility *Show in its feed* to show the feed in the list but not its articles.
Ensure that visibility *hidden* is not shown to API.

* TODO for later

* Update app/i18n/pl/sub.php

Co-authored-by: Inverle <inverle@proton.me>
2025-09-30 10:05:17 +02:00
Alexandre Alapetite
5e8c964f6c Stable IDs during SQL import (#7988)
* Stable IDs during SQL import
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/7949
Make sure that the original category IDs, feed IDs, and label IDs are kept identical during an SQL import.
Avoid breaking everything referring to categories, feeds, labels by their IDs such as searches and third-party extensions.

* Fix export of default category
2025-09-27 15:11:55 +02:00
Alexandre Alapetite
f8310a587c Clarify: Visibility hidden vs. archived (#7970)
fix https://github.com/FreshRSS/FreshRSS/issues/7887
We have two concepts: how much a feed is shown or not (controlled by priority), and how often a feed is refreshed (or not, in which case it is archived).
This PR removes the wording *Archived* from the *visibility* parameter, since this is not what it does.
2025-09-15 23:43:46 +02:00