* NEW: Add phpunit test for Dolresource class
Add a CRUD test (create/fetch/update/delete) for the Dolresource
class, which had no test coverage yet.
Note: the update() test intentionally does not exercise note_public/
note_private - Dolresource::update()'s SQL UPDATE statement omits
these 2 columns, so changes to them are silently not persisted.
* FIX Dolresource::update() does not persist note_public/note_private
The SQL UPDATE statement was missing these 2 columns while every
other property of the object was included, so changes to a
resource's notes were silently dropped on update. Add them following
the same pattern as the other fields, and extend the phpunit test to
cover it.
* FIX pre-commit PHPStan hook errors on commits with no file in scope
phpstan.neon.dist only analyzes htdocs/ and scripts/, but the
pre-commit wrapper passed every staged file straight to phpstan
regardless of path. A commit touching only files outside that scope
(e.g. test/phpunit/) made phpstan exit with "No files found to
analyse", failing the hook for reasons unrelated to the change being
committed. Filter to htdocs/ and scripts/ first, and skip cleanly
when nothing remains.
* NEW: Auto-activate module resource in DolresourceTest if needed
Activate module resource in setUpBeforeClass() when it is not
already enabled, so the test does not depend on the environment's
module configuration. Same pattern as
OpensurveysondageTest::setUpBeforeClass().
Note: this activation is real and persists after the test run - it
is not undone by the transaction rollback in tearDownAfterClass().
Activating a module re-runs its SQL install scripts (CREATE/ALTER
TABLE), which causes an implicit commit in MySQL/InnoDB, same as an
admin enabling it from Setup > Modules would do.
* fix
dol_check_secure_access_document() built its protection query against a table
named socpepople, which does not exist. The query therefore always failed, so
document.php and viewimage.php never iterated its result and never lowered
$accessallowed back to 0.
Any external user having the permission to read contacts could consequently
download the documents of any contact, including the contacts of other third
parties.
Note that this also restores the intended behaviour for the contacts having no
third party: an external user no longer has access to their documents, since
the query returns a NULL fk_soc that cannot match their own.
The typo was introduced in 0dd9e6acc2 on 2026-07-20, so only develop and the
24.0 branch are affected, no released version is.
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
Password generator/validator classes (USER_PASSWORD_GENERATED,
modGeneratePassXxx extends ModeleGenPassword) could previously only live
under htdocs/core/modules/security/generate/ — every call site resolving
one by name hardcoded that path, so no third-party module could
contribute its own generator without patching core.
Reuse the modules_parts['models'] extension point already populated for
any enabled module declaring $this->module_parts['models'] = 1 (the same
mechanism every numbering-module scan in Dolibarr already uses — see e.g.
Facture::getNextNumRef()), and wire it into the password-generator scan
too:
- admin/security.php's generator listing now scans core plus every
enabled module declaring module_parts['models'], instead of only
core/modules/security/generate/.
- Added ModeleGenPassword::loadAndInstantiate($id, ...) in
modules_genpassword.php, a shared factory doing that same multi-root
resolution once, used by the four runtime call sites that previously
hardcoded the core-only path: User::setPassword(), getRandomPassword()
(security2.lib.php), FormSetupItem::generateInputFieldPassword()
(html.formsetup.class.php), and PasswordField::verifyFieldValue()
(passwordfield.class.php). getRandomPassword() falls back to the
'standard' generator (with a warning logged) if the configured
generator's class can't be resolved, rather than silently generating
and persisting an empty password.
Behavior for the built-in Standard/None/Perso generators is unchanged —
core is always the first root scanned, so it always wins for those ids.
* NEW: Add phpunit test for Workstation class
Add a CRUD test (create/fetch/update/setStatusCommon/delete) for the
Workstation class, which had no test coverage yet.
* FIX pre-commit PHPStan hook errors on commits with no file in scope
phpstan.neon.dist only analyzes htdocs/ and scripts/, but the
pre-commit wrapper passed every staged file straight to phpstan
regardless of path. A commit touching only files outside that scope
(e.g. test/phpunit/) made phpstan exit with "No files found to
analyse", failing the hook for reasons unrelated to the change being
committed. Filter to htdocs/ and scripts/ first, and skip cleanly
when nothing remains.
* NEW: Auto-activate module workstation in WorkstationTest if needed
Activate module workstation in setUpBeforeClass() when it is not
already enabled, so the test does not depend on the environment's
module configuration. Same pattern as
OpensurveysondageTest::setUpBeforeClass().
Note: this activation is real and persists after the test run - it
is not undone by the transaction rollback in tearDownAfterClass().
Activating a module re-runs its SQL install scripts (CREATE/ALTER
TABLE), which causes an implicit commit in MySQL/InnoDB, same as an
admin enabling it from Setup > Modules would do.
* fix
phpstan.neon.dist only analyzes htdocs/ and scripts/, but the
pre-commit wrapper passed every staged file straight to phpstan
regardless of path. A commit touching only files outside that scope
(e.g. test/phpunit/) made phpstan exit with "No files found to
analyse", failing the hook for reasons unrelated to the change being
committed. Filter to htdocs/ and scripts/ first, and skip cleanly
when nothing remains.
The four files below were modified by the automated merges from the 24.0 branch
into develop on 2026-08-13 and each brought a type warning. Phan reports them on
every pull request opened since, because the list of files it analyses on a pull
request includes the recent changes of develop, so every contributor gets a red
phan on files they never touched.
- mrp/mo_card.php: fetchAll() takes int for $limit and $offset, '1' and '' were
passed.
- commande/class/commande.class.php: escape() takes a string and
deposit_percent is numeric. The insert path of the same class already casts it
a few hundred lines above, only the update path was missing it.
- asset/class/asset.class.php: the note on disposal_amount_ht says the card
assigns an int, but asset/card.php now assigns the result of GETPOSTFLOAT().
- core/modules/dons/html_cerfafr.modules.php: modepaymentid is used as an array
index outside of the test that guarantees it is not null.
No functional change: the four values were already used as int, string, float
and int by PHP itself.
* Qual(ci): Fix phan notices (typing)
* Qual: Fix deposit_percent type (escaping)
# Qual: Fix deposit_percent type (escaping)
deposit_percent is a float but was escaped to string resulting in argument mismatch.
Fixed by casting to float.
* FIX pre-commit PHPStan hook errors on commits with no file in scope
phpstan.neon.dist only analyzes htdocs/ and scripts/, but the
pre-commit wrapper passed every staged file straight to phpstan
regardless of path. A commit touching only files outside that scope
(e.g. test/phpunit/) made phpstan exit with "No files found to
analyse", failing the hook for reasons unrelated to the change being
committed. Filter to htdocs/ and scripts/ first, and skip cleanly
when nothing remains.
* NEW: Add phpunit test for Opensurveysondage class
Add a CRUD test (create/fetch/update/delete) for the Opensurveysondage
class, which had no test coverage yet.
Note: create()'s return value is not used to identify the created
record - Opensurveysondage::create() returns $this->id, but this
class never sets $this->id (the real primary key is the caller-
supplied $this->id_sondage string), so the return value carries no
information. The test uses errors/re-fetch to check success instead.
* NEW: Auto-activate module opensurvey in OpensurveysondageTest if needed
Activate module opensurvey in setUpBeforeClass() when it is not
already enabled, so the test does not depend on the environment's
module configuration.
Note: this activation is real and persists after the test run - it
is not undone by the transaction rollback in tearDownAfterClass().
Activating a module re-runs its SQL install scripts (CREATE/ALTER
TABLE), which causes an implicit commit in MySQL/InnoDB, same as an
admin enabling it from Setup > Modules would do.