Bugfix Issue 1716 ReqMgrSystem CfgTemplate LOCALIZE Marker - sebiboga/testlink-upgraded GitHub Wiki
Bug fix — Issue #1716: getreqmgrsystemcfgtemplate.php answered LOCALIZE: <key> and logged a localization Event Viewer row
lib/ajax/getreqmgrsystemcfgtemplate.php ships a developer-facing missing-key
marker in its JSON payload and writes a log_level 32 (LOCALIZATION) row into
the events table (Event Viewer source) at the same time. Both lang_get() keys
the endpoint uses exist in no locale bundle:
| Request | Pre-fix payload | Post-fix payload |
|---|---|---|
...getreqmgrsystemcfgtemplate.php?type=1 (line 41) |
{"sucess":true,"cfg":"LOCALIZE: reqmgrsystem_interface_not_implemented"} |
{"sucess":true,"cfg":"Configuration example not available: the 'contoursoapInterface' interface is not implemented"} |
...getreqmgrsystemcfgtemplate.php?type=99 (line 46) |
{"sucess":true,"cfg":"LOCALIZE: reqmgrsystem_invalid_type"} |
{"sucess":true,"cfg":"Invalid requirement management system type: 99"} |
bare URL, no type (line 46) |
LOCALIZE: reqmgrsystem_invalid_type |
Invalid requirement management system type: 0 |

Entry point: http://localhost:8082/lib/ajax/getreqmgrsystemcfgtemplate.php?type=1
(session-authenticated; the legacy Ext.Ajax caller was
reqMgrSystemEdit.tpl's displayCfgExample(), retired by #1727 — the endpoint
itself is still reachable and still answered the marker).
Pre-fix events (measured this run, fresh database, rows 2 and 3):
id log_level description
2 32 string 'reqmgrsystem_interface_not_implemented' is not localized for locale 'en_GB'
3 32 string 'reqmgrsystem_invalid_type' is not localized for locale 'en_GB'
-
TestLink 2.0.1, PHP 8.3.35, PHP built-in server on
http://localhost:8082, MariaDBtestlinkon127.0.0.1:3306(testlink/testlink), database freshly imported, loginadmin/admin(localeen_GB). -
Branch
fix/issue-1716; fix commitd9adca617. -
Minimal reproduction (no fixtures needed — the endpoint needs only a session):
curl -s -c c.txt -d "tl_login=admin&tl_password=admin" -o /dev/null http://localhost:8082/login.php curl -s -b c.txt "http://localhost:8082/lib/ajax/getreqmgrsystemcfgtemplate.php?type=1" curl -s -b c.txt "http://localhost:8082/lib/ajax/getreqmgrsystemcfgtemplate.php?type=99" mysql -h 127.0.0.1 -utestlink -ptestlink testlink \ -e "SELECT id,log_level,description FROM events ORDER BY id DESC LIMIT 6;"
-
lib/ajax/getreqmgrsystemcfgtemplate.php:41/:46calllang_get('reqmgrsystem_interface_not_implemented')andlang_get('reqmgrsystem_invalid_type'). -
lang_get()(lib/functions/lang_api.php:41-89) looks the key up in the session locale, then force-loadsen_GBas the fallback (:78-87). Neither bundle — nor any of the other 17 — defines either key (grep -rn 'reqmgrsystem_invalid_type' locale/ → 0 hits), so$loc_strstaysNULL. -
lang_api.php:118then returnsTL_LOCALIZE_TAG . $p_string, i.e. the literalLOCALIZE: <key>, and:48json_encode()s it straight into the response. - The same
$missingL18Nbranch callslogL18nWarningEvent()(lang_api.php:137) → thelog_level 32row, de-duped once per key per session by$_SESSION['missingL18N'](:133).
Why it never blew up: sprintf() on the marker (which contains no %s)
silently returns the marker unchanged, so there is no fatal, no HTTP error and no
notice — only the Event Viewer row and the visible marker. The keys were
introduced with the req-mgmt-system config-example feature (1.9.6) and never added
to any bundle; git log -S'reqmgrsystem_invalid_type' -- locale/ shows they never
existed anywhere (a never-added gap, not a rename).
Blast radius: exactly 2 call sites repo-wide (both in this endpoint).
?type=1 is not an edge case: tlReqMgrSystem::$systems registers only
1 => contour/soap (lib/functions/tlReqMgrSystem.class.php:33) and
contoursoapInterface.class.php ships nowhere, so stream_resolve_include_path()
is FALSE and every type=1 request took the line-41 branch. Any other/absent
type (intval() of a missing param is 0) took line 46.
Add the two keys to all 19 locale/*/strings.txt bundles — no PHP changed.
| File | Change |
|---|---|
locale/{cs_CZ,de_DE,en_GB,en_US,es_AR,es_ES,fi_FI,fr_FR,id_ID,it_IT,ja_JP,ko_KR,nl_NL,pl_PL,pt_BR,pt_PT,ro_RO,ru_RU,zh_CN}/strings.txt |
+$TLS_reqmgrsystem_interface_not_implemented and +$TLS_reqmgrsystem_invalid_type, each with exactly one %s matching the sprintf(..., $iname) / sprintf(..., $type) call sites (+2 lines per file, 19 files) |
CHANGELOG |
one [KEY BUGFIX] entry |
Insertion is byte-preserving: next to the existing $TLS_check_reqmgrsystem_*
block in the 12 bundles that have it, before the closing ?> (de_DE, es_ES,
it_IT, ru_RU) or at EOF in the 7 bundles without the block (es_AR, fi_FI,
id_ID, ko_KR, ro_RO) — all LF, all UTF-8, nothing else in any file touched.
Native translation in every non-English bundle; php -l clean on all 19 before and
after (the bundles are required as PHP by lang_load(), lang_api.php:244).
-
Hardcode English at
:41/:46— user-facing text with no locale entry, and it would drop the$iname/$typecontext the message exists for. -
Reuse an existing generic key (
$TLS_reqmgrsystem_cfg_example) — would hide which interface/type failed. -
Change the endpoint to swallow the miss (
lang_get(..., null, true)) — stops the event but still ships the raw marker; treats the symptom, not the cause. -
Fix only
en_GB—lang_get()falls back toen_GBfor every locale, so the marker would disappear, but each non-English locale would keep firing the- using en_GBLOCALIZATION row forever (the exact noise #1820/#549 removed).
?type=1 -> {"sucess":true,"cfg":"Configuration example not available: the 'contoursoapInterface' interface is not implemented"}
?type=99 -> {"sucess":true,"cfg":"Invalid requirement management system type: 99"}
?type= -> {"sucess":true,"cfg":"Invalid requirement management system type: 0"}
users.locale=it_IT ?type=1 -> "Esempio di configurazione non disponibile: l'interfaccia 'contoursoapInterface' non è implementata"
users.locale=ru_RU ?type=1 -> "Пример конфигурации недоступен: интерфейс 'contoursoapInterface' не реализован"
events after 4 fresh sessions x 3 requests x 3 locales: only log_level 16 (login audits)
-> 0 new log_level 32 rows (pre-fix rows 2/3 remain as historical evidence)
php -l locale/<each>/strings.txt -> 19/19 "No syntax errors detected" (same as HEAD copies)
bash ai/verify_i18n_coverage.sh -> PASS 9/9 bundles
git diff --stat -> 19 files, +2 lines each, nothing else
TLU_REQUIRE_SUITE="Issue #1716" bash ai/verify_test_suites.sh -> 7 PASS / 0 FAIL
Browser pass: gui/templates/reqmgrsystems/reqMgrSystemView.html → + Create →
show configuration example renders Interface contoursoapInterface not implemented
(the modern BFF path, i18n key rms.connNotImplemented — unaffected by this change
and confirmed still correct), console clean apart from the pre-existing favicon 404.
Code review (subagent) found two garbled translations — ko_KR 시스텀 → 시스템
and cs_CZ požadavkö → požadavků — both corrected before commit; all other
categories (string validity, %s count, key names, insertion position, diff scope)
came back clean.
Regression suite: tmp/TLU_Test_Cases.md → ## Regression — Issue #1716
(8 cases, TC-1716-01..08, all PASS).
-
#1879 — a bare request (no
typeparam) makesintval($_REQUEST['type'])atgetreqmgrsystemcfgtemplate.php:23raiseE_WARNING "Undefined array key \"type\""→ aneventsrow withlog_level 2. Independent of this fix (the #1716 diff touches onlylocale/*/strings.txt). - The other 6 req-mgmt keys (
$TLS_reqmgrsystem_check_ok,_management,_deleted,$TLS_reqmgrsystem_show_cfg_example, …) are still missing from the 7 bundles that carry no req-mgmt block at all (es_AR,fi_FI,id_ID,it_IT,ko_KR,ro_RO,ru_RU), so those locales keep firing- using en_GBLOCALIZATION rows whenever the Req Mgmt System screens are used — pre-existing, out of scope for this issue.
- #1626 — the sibling of this issue (filed it while fixing
tlReqMgrSystem::getTypes()) - #549, #1820 — the same "missing locale key" family, fixed the same way
- #1727 — retired the legacy
reqMgrSystemEdit.tplcaller (the endpoint itself remains reachable and is what this fix repairs)