Bugfix Issue 1820 ro_RO audit cfield labels - sebiboga/testlink-upgraded GitHub Wiki
Issue #1820 — ro_RO logged the two audit_cfield_{location,monitorable} LOCALIZATION warnings on every Save (labels clobbered by the closure commit)
Issue: #1820
Branch: fix/issue-1820-cfield-audit-i18n
Status: VERIFIED-FIXED — regression suite Issue #1820 6/6 PASS, suite gate 7/7
Symptom
Every Save on the modernized Custom Fields → Test Project screen
(gui/templates/cfields/cfieldsTprojectAssign.html) that touched a Location or the
Monitorable box wrote two extra Warning / LOCALIZATION rows into the Event Viewer
(events table) next to the legitimate SAVE audit rows:
id=56 32 LOCALIZATION string 'audit_cfield_location_changed' is not localized for locale 'ro_RO' - using en_GB
id=55 32 LOCALIZATION string 'audit_cfield_monitorable_on' is not localized for locale 'ro_RO' - using en_GB
The audit history itself stayed correct — only polluted with noise, so any reporter
filtering on log_level warnings got false positives. The issue was originally reported
under the default en_GB locale; en_GB was fixed by commit 36121574a. This run
isolated the live residual to ro_RO.
Investigation (measured before any code was touched)
Environment: app http://localhost:8082 (PHP built-in server, docroot = repo root),
PHP 8.3.35, DB testlink freshly imported (SELECT COUNT(*) FROM events = 0),
admin/admin. Fixture php tmp/fixtures_1816.php → testproject id 1 CFP Main,
custom field id 1 CFP1812 (design-time testcase CF with a Location dropdown),
linked to project 1. The acting user locale was forced to ro_RO
(UPDATE users SET locale='ro_RO' WHERE login='admin').
| probe | result |
|---|---|
Save with Location standard→Before steps + tick MONITORIZABIL, then open the Event Viewer |
id=55 …audit_cfield_monitorable_on…, id=56 …audit_cfield_location_changed… LOCALIZATION |
SELECT id,activity,description FROM events … LIMIT at save time |
audit rows stored as serialized tlMetaStringHelper objects (ids 51-53) — stringified only when the Event Viewer renders them |
static matrix over all 19 locale/*/strings.txt |
the three keys present in 18, absent only in ro_RO |
Root cause chain
| # | file:line | what happens |
|---|---|---|
| 1 | lib/functions/cfield_mgr.class.php:2102 |
setDisplayLocation() → logAuditEvent(TLS("audit_cfield_location_changed", $tproject_info['name']), …). |
| 2 | lib/functions/cfield_mgr.class.php:2990 |
setMonitorable() builds the label dynamically: $auditMsg = $val ? "audit_cfield_{$field}_on" : "audit_cfield_{$field}_off"; → TLS($auditMsg, …) at :3003. |
| 3 | lib/functions/logging.inc.php:37,73 |
logAuditEvent() → tLog() stores the tlMetaString object; the logger serialize()s it, so no stringification happens at write time. |
| 4 | lib/functions/metastring.class.php:138 |
rendering the event calls __toString() → localize() → lang_get($label) with the "fire warning" flag on. |
| 5 | lib/functions/lang_api.php:57-135 |
lang_get() does not find the key in ro_RO, falls back to en_GB, and calls logL18NWarningEvent("string '…' is not localized for locale 'ro_RO' - using en_GB", "LOCALIZATION") → the Warning row. |
Why it breaks NOW (regression source): commit 36121574a (fix #1820, 2026-10-04 06:25)
added the three labels to all 19 locales, including locale/ro_RO/strings.txt. Thirty-four
minutes later commit 35e838f67 (feat(closure) … Refs #1278) was authored on a base
without that fix; its rewrite of the tail of locale/ro_RO/strings.txt replaced the
three $TLS_audit_cfield_* lines (and the trailing blank) with $TLS_title_test_closure.
git show 35e838f67 -- locale/ro_RO/strings.txt shows the exact removal. ro_RO was then
the only one of 19 locales missing the labels.
Blast radius
- Static scan of all 19
locale/*/strings.txt:audit_cfield_location_changedpresent in 18, absent only inro_RO;audit_cfield_monitorable_on/_offidentical (18 / 1). - Runtime: any save on the Custom Fields → Test Project screen while the acting user locale
is
ro_ROand the Event Viewer is opened logs the Warning/LOCALIZATION rows.
The fix (minimal, 1 file, +4/-0)
locale/ro_RO/strings.txt — restore the three labels with the same English
wording/placeholders used by the other 18 locales, tagged // Refs #1820:
$TLS_audit_cfield_location_changed = "Custom field locations were saved on Test Project '{%1}'"; // Refs #1820
$TLS_audit_cfield_monitorable_on = "Custom field '{%1}' was set MONITORABLE on Test Project '{%2}'"; // Refs #1820
$TLS_audit_cfield_monitorable_off = "Custom field '{%1}' was set NOT MONITORABLE on Test Project '{%2}'"; // Refs #1820
Why this method (and what was rejected)
- Restore the labels (minimal).
36121574aintentionally defined these labels for every locale; the clobber removed them fromro_ROonly. Putting them back is exactly the documented fix and keepsro_ROconsistent with the other 18 bundles. - Rejected — globally suppress the fallback warning in
lang_get(). It would hide genuine gaps in every partial locale, changes long-standing TestLink behaviour, and is far beyond the issue scope. - Rejected — translate the three labels into Romanian. The three keys are authored in
English across all 19 locales (consistent with the sibling
$TLS_audit_cfield_*block); a lone Romanian translation would break that consistency.
After the fix
With ro_RO active, a Save that changes Location and/or Monitorable writes the SAVE audit
rows but produces no LOCALIZATION warning for audit_cfield_location_changed /
audit_cfield_monitorable_on / _off when the Event Viewer renders them. The other 18
locales keep resolving the labels.
Remaining LOCALIZATION rows under ro_RO (audit_cfield_display_order_changed,
audit_cfield_assigned, audit_login_succeeded, context_*, testsuite, …) are the
normal English fallback for a curated partial locale (199 lines vs 4240 in en_GB) and
are outside #1820's named keys.
Verification
Regression suite Issue #1820, appended to tmp/TLU_Test_Cases.md; suite gate
TLU_REQUIRE_SUITE="Issue #1820" bash ai/verify_test_suites.sh → 7/7 PASS.
| case | before | after |
|---|---|---|
grep -c audit_cfield_location_changed locale/ro_RO/strings.txt |
0 | 3 (all 19 locales = 3) |
php -l locale/ro_RO/strings.txt |
— | No syntax errors detected |
Save (Location + Monitorable) under a fresh ro_RO session, then Event Viewer |
id=55/56 LOCALIZATION for the two keys |
id=107/108 SAVE; no LOCALIZATION row for the fixed keys |
| Event Viewer, other keys | — | only _display_order_changed / _assigned (not #1820, never in partial ro_RO) |
Event Viewer after the fresh-session Save — the three SAVE rows are present and none of
them raises a LOCALIZATION warning for the restored keys:

How to re-test in one command
php tmp/fixtures_1816.php # tproject=1 (CFP Main), cfield 1 CFP1812
mysql -h 127.0.0.1 -utestlink -ptestlink testlink -e "UPDATE users SET locale='ro_RO' WHERE login='admin'"
# login admin/admin in a FRESH browser session; open each URL:
# http://localhost:8082/gui/templates/cfields/cfieldsTprojectAssign.html?tproject_id=1
# change Location + tick MONITORIZABIL -> Salvează atributele de afișare
# http://localhost:8082/gui/templates/eventviewer/eventviewer.html
mysql -h 127.0.0.1 -utestlink -ptestlink testlink -e \
"SELECT id,description FROM events WHERE activity='LOCALIZATION' AND description LIKE '%audit_cfield_location_changed%';" # expect: empty