## What changed
- derive the actualization mutex name from a SHA-256 hash of the canonical `DATA_PATH`
- keep `TMP_PATH` as the configurable location for the mutex file
- add coverage for deterministic per-instance names and independent locks
## Why
Multiple FreshRSS instances that use the default shared system temporary directory currently use the same actualization lock. The data path identifies the instance without exposing or depending on its configured salt.
## Validation
- `vendor/bin/phpunit --bootstrap ./tests/bootstrap.php ./tests/lib/ActualizeMutexTest.php --no-progress`
- `vendor/bin/phpcs app/actualize_script.php lib/lib_rss.php tests/lib/ActualizeMutexTest.php -s`
- `vendor/bin/phpstan analyse --memory-limit 512M --no-progress app/actualize_script.php lib/lib_rss.php tests/lib/ActualizeMutexTest.php`
Fixes#6370
Co-authored-by: Gerard Alvear <gerard.alvear@logiqd.me>
* feat: report new articles count per feed in actualize_script output
Closes#8291
## Changes proposed in this pull request
`app/actualize_script.php` now reports, for each feed that received new articles, how many new articles were fetched — in addition to the existing per-user summary. This makes batch refreshes (cron / systemd timers) much more informative.
Example output:
```
FreshRSS actualize admin…
10 new article(s) from feed: FreshRSS releases
3 new article(s) from feed: Some other blog
```
The feature is implemented **entirely within the CLI script**, reusing the existing extension-hook mechanism that the script already uses for the actualization mutex — no change to `feedController` or to any other behaviour:
- `FeedBeforeActualize` records each feed's name.
- `EntryBeforeAdd` counts new entries per feed. This hook fires only in the "genuinely new GUID" branch of the actualization loop (updated articles go through `EntryBeforeUpdate`), so the count matches the controller's own `$nbNewArticles` counter. Because the counting hook is registered after `$app->init()`, it runs last in the chain and is skipped for entries dropped by another extension — i.e. it counts only articles that are actually added.
Counts are printed through the script's existing `notice()` helper, so they reach STDOUT regardless of the `environment` setting (unlike `Minz_Log::notice`, which is suppressed in `production`).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Minor
* Remove tab
The tab character is escaped in some logs, e.g.
```
[notice] --- \x091 new article(s) from feed: L’Express
```
* Sort per-feed output and also report updated articles
Addresses review feedback on #8948:
- Sort the per-feed report by descending article count, then feed name.
- Also count updated articles (via EntryBeforeUpdate) and report them
alongside new ones, e.g. '10 new, 2 updated article(s) from feed: X'.
EntryBeforeAdd fires only for new articles (new-GUID branch), so
updated articles need the separate EntryBeforeUpdate hook.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Reduced code
* Do not report feeds with no new or updated articles
FeedBeforeActualize initializes every actualized feed in $feedStatistics
and fires before the TTL/mute skips, so skipped or unchanged feeds would
otherwise print an empty count (' article(s) from feed: X'). Skip them.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Minor code logic preference
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
* 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
1. `include`, `include_once`, `require` and `require_once` are expressions not functions, parentheses are not necessary.
2. to move up the directory tree, it's better to use the `dirname` function instead of relying on `/..`.
* PHPStan 2.0
fix https://github.com/FreshRSS/FreshRSS/issues/6989https://github.com/phpstan/phpstan/releases/tag/2.0.0https://github.com/phpstan/phpstan/blob/2.0.x/UPGRADING.md
* More
* More
* Done
* fix i18n CLI
* Restore a PHPStan Next test
For work towards PHPStan Level 10
* 4 more on Level 10
* fix getTagsForEntry
* API at Level 10
* More Level 10
* Finish Minz at Level 10
* Finish CLI at Level 10
* Finish Controllers at Level 10
* More Level 10
* More
* Pass bleedingEdge
* Clean PHPStan options and add TODOs
* Level 10 for main config
* More
* Consitency array vs. list
* Sanitize themes get_infos
* Simplify TagDAO->getTagsForEntries()
* Finish reportAnyTypeWideningInVarTag
* Prepare checkBenevolentUnionTypes and checkImplicitMixed
* Fixes
* Refix
* Another fix
* Casing of __METHOD__ constant
* Pass PHPStan level 8
And prepare for PHPStan level 9 https://phpstan.org/user-guide/rule-levels
* Revert wrong replace in comment
* Fix PHPStan level 8
* Update PHPStan and other dev dependencies
* Remove obsolete comment
* noVariableVariables and towards bleedingEdge
https://github.com/phpstan/phpstan-strict-ruleshttps://phpstan.org/blog/what-is-bleeding-edge
* More bleedingEdge
* A bit more PHPStan level 9
* More PHPStan level 9
* Prepare for booleansInConditions
Ignore int and null
* Revert wrong line
* More fixes
* Fix keep_max_n_unread
* Stricter attribute functions
* Stricter callHooks and more PHPStan level 9
* More typing
* A tiny more
* Little's optimisations and booleans in conditions
* Apply strict type
* Apply strict type
* Apply strict type
* Fix multiple bugs with PHP 8.2 and 8.3
* Many declares missing, more errors fixed
* Apply strict type
* Another approach
* Stronger typing for Minz_Session
* Fix case of SQLite
---------
Co-authored-by: Luc <sanchezluc+freshrss@gmail.com>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
* Complete PHPStan Level 6
Fix https://github.com/FreshRSS/FreshRSS/issues/4112
And initiate PHPStan Level 7
* PHPStan Level 6 for tests
* Use phpstan/phpstan-phpunit
* Update to PHPStan version 1.10
* Fix mixed bug
* Fix mixed return bug
* Fix paginator bug
* Fix FreshRSS_UserConfiguration
* A couple more Minz_Configuration bug fixes
* A few trivial PHPStan Level 7 fixes
* A few more simple PHPStan Level 7
* More files passing PHPStan Level 7
Add interface to replace removed class from https://github.com/FreshRSS/FreshRSS/pull/5251
* A few more PHPStan Level 7 preparations
* A few last details
* Fix extension freshrss_user_maintenance in actualize_script
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/3440
The hook was called before registering all the extensions for the current user
* PHPStan Level 6 for extensions
And remove 5-year old legacy format of enabled extensions < FreshRSS 1.11.1
* Fix multiple bugs in extensions
* Minor typing
* Don't change signature of methods supposed to be overridden
* PHPStan Level 9 and compatibility Intelliphense
* Set as final the methods not supposed to be overriden
* Simplify extension method
One parameter was not used
Furthermore, that unused parameter was preventing simpler calls (i.e. without a dedicated extension class). Now it is possible to register a call back with a lamda:
```php
Minz_ExtensionManager::addHook('feed_before_actualize', function () {
// Hello
});
```
* Mutex for actualize script
In the case of extremely long cron jobs that are refreshing feeds, a cron job might start before the previous one has completed, leading to an accumulation of cron jobs running in parallel.
Although we already have a mutex preventing concurrency problems on a single feed refresh, the problem occurs in particular if each feed can take a long time (e.g. due to heavy processing, which is my usecase).
https://github.com/FreshRSS/FreshRSS/pull/5234 must be merged first
* Fiw wrong return
* Automated test towards PHPStan level 6
Contributes to https://github.com/FreshRSS/FreshRSS/issues/4112
With this automated tests, files that are passing Level 6 are tested to avoid regressions towards Level 5 (which is the current baseline for the whole code-base)
It is included when calling `make test-all` or can be called specifically by `composer run-script phpstan-next`
* Test and example with 3 new passing files
* Use typographic quotes
* A few fixes
* Fix
* Fix not saved
* Implement feedback
* Detail
* Revert spoken English fixes
Left for a future dedicated discussion
* More reverts
* Final reverts
* Final minor
* Avoid manual intialisations of system or user configuration
More consistent use of Context
* Simplify FreshRSS_Context::initUser
* Remove a few manual get_user_configuration
* A bit of debugging
* Fix context user init
* Fix install
* Fix concurrency
Concurrent requests could lead to bad race condition
* Fix actualize cron
Fix case when system i initialised several times
* Minz allow parallel sessions
#fix https://github.com/FreshRSS/FreshRSS/issues/3093
* Array optimisation
* Array optimisation missing
* Reduce direct access to $_SESSION except in install process
* Fix session start headers warning
* Use cookie only the first time the session is started:
`PHP Warning: session_start(): Cannot start session when headers
already sent in /var/www/FreshRSS/lib/Minz/Session.php on line 39`
* New concept of volatile session for API calls
Optimisation: do not use cookies or local storage at all for API calls
without a Web session
Fix warning:
```
PHP Warning: session_destroy(): Trying to destroy uninitialized session
in Unknown on line 0
```
* Only call Minz_Session::init once in our index
It was called twice (once indirectly via FreshRSS->init())
* Whitespace
* Mutex for notifications
Implement mutex for notifications
https://github.com/FreshRSS/FreshRSS/pull/3208#discussion_r499509809
* Typo
* Install script is not ready for using Minz_Session
* Fix logging environment constants
* COPY_LOG_TO_SYSLOG was only working when Syslog was used
* FRESHRSS_ENV was not properly used to set logging level
* Simplify code
Always call `openlog()` even when it is not used
* Always specify syslog properties
https://github.com/FreshRSS/FreshRSS/pull/2745#discussion_r362207445
* $username is also needed further down
* No new line in syslog
* check requirements in actualize_script before executing, fixes#1710
* removed empty whiteline
* testing all requirements
* incorporated code review feedback
* removed code that is already executed in _cli.php
* added newline at eof
* fixed include problems
* fixed include problems
Temporary fix:
- Change syslog by Minz_Log::notice in most of the files
- Logs are stored in USERS_PATH/_/log.txt for actualize_script.php
- Simply comment syslog in SimplePie
See https://github.com/FreshRSS/FreshRSS/issues/711
https://github.com/FreshRSS/FreshRSS/issues/759
Suggestion: the static objects should be user-independent (or at least
with the possibility to be re-set), while the FreshRSS object and its
attributes should be user-dependent.