Commit graph

3 commits

Author SHA1 Message Date
Frédéric FRANCE
282e7dac6a
don't take care of some french comments and fix false positive (#39007)
* don't take care of some french comments

* Update LanguageOfCommentsSniff.php

* test a file

* Update doc_generic_asset_odt.modules.php

* Update auxaccount.php

* FIX: Translate French code comments to English in societe module

* fix phan

* fix phan
2026-06-29 19:28:28 +02:00
VIAL-GOUTEYRON Quentin
d67ac89a65
FIX : ModuleBuilder list page derives email trackid from object name (#38906)
The generated list page set $trackid = 'xxxx'.$object->id, where 'xxxx'
is not a NamingContract substitution token. It leaked verbatim into every
generated module and made the mass-emailing trackid collide across modules.

Align it with the card page (myobject_card.php) and core list pages
(comm/propal/list.php => 'pro', societe/list.php => 'thi') by using the
substitutable 'myobject' token, so the trackid derives from the object name.

Addresses #32460 (item 14, email/trackid handling).

Next: push to remote quentin, open upstream PR on Dolibarr/dolibarr:develop
Next: linking #32460 item 14

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-06-21 23:27:34 +02:00
VIAL-GOUTEYRON Quentin
fefbe81380
NEW : Replace MyObject MyModule occurences (#38370)
* [COREMB] Centralize myobject/mymodule substitutions via NamingContract value object

Introduce NamingContract (immutable value object) and NamingContractValidator
to replace 6 scattered ad-hoc $arrayreplacement blocks across index.php and
modulebuilder.lib.php. Fixes a critical bug where MYOBJECT token was commented
out in initobject, leaving generated class files with unsubstituted placeholders.

- NamingContract: canonical ordered substitution map (12 tokens with object,
  7 module-only), applyTo() via str_replace (not make_substitutions, to avoid
  processing Dolibarr __(key)__ patterns in raw templates), applyToFilename()
  for lowercase-only filename substitution
- StrictNamingContractValidator: post-generation scan for residual myobject/
  mymodule tokens, skipping /* BEGIN/END MODULEBUILDER */ structural markers
- modulebuilderValidateGeneratedFile() helper: non-blocking warnings with
  XSS-safe output via dol_escape_htmltag()
- Collision guard: InvalidArgumentException if module === object name
  (case-insensitive), wrapped in try-catch at all instantiation sites
- 24 PHPUnit tests, 52 assertions

* fix(initobject): apply object substitution to all module PHP files

After initmodule creates the module structure, files like index.php,
lib/module.lib.php, admin/setup.php and class/api_module.class.php
still contain myobject/mymodule placeholders. initobject now scans
ALL PHP files in the module directory and applies the full NamingContract
substitution, and deletes the orphan stats/myobject_index.php placeholder.

* fix(initmodule): prevent array_merge from renumbering the '500000' key

PHP casts numeric string keys like '500000' to int(500000) internally.
array_merge() then renumbers integer keys starting from 0, turning
'500000' into key 0. make_substitutions() then calls str_replace(0, ...)
which casts 0 to the string '0', replacing EVERY zero digit in every
generated file with the idmodule value.

Fix: replace the bare '500000' key with '$this->numero = 500000' so that
array_merge sees a non-numeric string key and preserves it as-is.

* Fix initapi: apply header substitution after addObjectsToApiFile

addObjectsToApiFile substitutes properties/constructor/includes via regex
but leaves PHPDoc header and class declaration with mymodule/myobject tokens.
Fix: apply $arrayreplacement (minus 'MYOBJECT' uppercase key) after
addObjectsToApiFile to resolve the remaining residuals.

'MYOBJECT' is excluded to preserve the /* BEGIN MODULEBUILDER API MYOBJECT */
placeholder that addObjectsToApiFile relies on for future object additions.

* Move NamingContractTest to core test directory

NamingContract and NamingContractValidator are core modulebuilder classes;
their tests belong alongside other Dolibarr core tests in test/phpunit/,
not in htdocs/modulebuilder/test/phpunit/ (the custom-module pattern).

Updated require_once paths accordingly.

* fix useless file

* fix(phpcs): add missing @param descriptions and function docblocks

- NamingContract: merge adjacent string literals in exception message,
  add description to @param $content in applyTo()
- NamingContractValidator: add descriptions to all bare @param tags
  in interface and StrictNamingContractValidator methods
- NamingContractTest: add /** @return void */ docblocks to all test
  methods, merge unnecessary string concat on template variable

* fix(phan/phpstan): remove readonly, add baselines for test file

- NamingContract: replace readonly properties with plain public string
  (readonly requires PHP 8.1, phan minimum target is PHP 7.2)
- dev/tools/phan/baseline.txt: add NamingContractTest.php suppression
  for PhanUndeclaredMethod (PHPUnit stubs not available in phan scope)
- NamingContractTest.php: add @phpstan-ignore class.notFound on class
  declaration and method.notFound on each assertion call (PHPUnit not
  in phpstan bootstrap, consistent with CommonClassTest.class.php)

* fix(phan/phpstan): suppress typed property warnings, NoopNew, class.notFound

- baseline.txt: add PhanCompatibleTypedProperty for NamingContract.class.php
  (typed properties require PHP 7.4, phan min target is 7.2 — warning only
  but phan exits 1 on any issue including warnings)
- baseline.txt: add PhanNoopNew for NamingContractTest.php (constructor
  called for exception side-effect in guard tests is intentional)
- NamingContractTest.php: move @phpstan-ignore class.notFound to inline
  comment on class declaration (docblock placement not picked up by phpstan)

* fix(phan/phpstan): add missing phan suppress on index.php l.574, fix phpstan class docblock

- index.php l.574: add @phan-suppress-next-line PhanPluginSuspiciousParamPosition
  (same pattern as l.577 and l.587 for identical dolReplaceInFile calls
  where local variable name $destfile matches parameter #3 of the function)
- NamingContractTest.php: use standalone /** @phpstan-ignore class.notFound */
  docblock before class declaration (inline // comment not picked up by phpstan
  on class declarations; separate docblock matches CommonClassTest.class.php pattern)

* Update baseline.txt

* fix(phan): add phan-file-suppress on NamingContractTest for PHPUnit undeclared methods

* fix(phan): suppress PhanNoopNew on expectException patterns in NamingContractTest

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-05-25 14:52:38 +02:00