Task Issue 973 codetracker env check column - sebiboga/testlink-upgraded GitHub Wiki
Issue: #973
Status: IMPLEMENTED & VERIFIED (2026-09-25) — branch task/issue-973
Screen: gui/templates/codetracker/codetrackerView.html
BFF: api/codetracker/index.php
TestLink 1.9.20 showed an Environment column in the Code Tracker list: for every
configured tracker it reported whether the PHP environment can actually serve that
tracker's interface (extension/library availability) — OK, or a human message such as
"cURL extension is required for the GitHub code tracker interface".
Legacy path, in order:
| Step | Legacy code | What it does | |
|---|---|---|---|
| 1 | lib/codetrackers/codeTrackerView.php:23 |
$gui->items = $codeTrackerMgr->getAll(array('output' => 'add_link_count', 'checkEnv' => true)); — the checkEnv option is the only trigger of the probe |
|
| 2 | lib/functions/tlCodeTracker.class.php:527 |
checkEnv defaults to false in the option map |
|
| 3 | lib/functions/tlCodeTracker.class.php:562-563 |
every item seeded with env_check_ok = true, env_check_msg = ''
|
|
| 4 | lib/functions/tlCodeTracker.class.php:566-572 |
when enabled: $impl = getImplementationForType($type); $dummy = $impl::checkEnv(); → env_check_ok / env_check_msg
|
|
| 5 | lib/codetrackerintegration/codeTrackerInterface.class.php:325-332 |
base checkEnv() → ['status' => true, 'msg' => 'OK']
|
|
| 6 | lib/codetrackerintegration/githubrestCodeTrackerInterface.class.php:523-532 |
override: !function_exists('curl_init') → status=false, msg='cURL extension is required for the GitHub code tracker interface'
|
|
| 7 | gui/templates/dashio/codetrackers/codeTrackerView.tpl:42 |
<th>{$labels.th_codetracker_env}</th> — locale string $TLS_th_codetracker_env = 'Environment' (locale/*/strings.txt) |
|
| 8 | gui/templates/dashio/codetrackers/codeTrackerView.tpl:74 |
` | {$item_def.env_check_msg |
The 2.0.1 rewrite dropped steps 1–8 and replaced the column with a Server URL column:
-
api/codetracker/index.phplist route calledgetAll(['output' => 'add_link_count'])—checkEnvwas omitted, so it stayedfalseand the probe block never ran. -
trackerToJSON()returned noenv_check_*key at all. - The grid had 5 columns (
Name | Type | Server URL | Active | Actions) and no Environment column.
Notably, the sibling screens already had the feature — api/issuetracker/index.php:100-101
and gui/templates/issuetracker/issuetrackerView.html:246-256 implement exactly this
pattern. The asymmetry was the bug.
api/codetracker/index.php, list route:
// checkEnv parity with legacy codeTrackerView.php:23 — the per-tracker
// environment probe ($impl::checkEnv(), tlCodeTracker.class.php:566-572)
// runs here so env_check_ok/env_check_msg reach the grid's Environment
// column. Omitting it silently downgrades every row to "OK" (issue #973).
$all = $mgr->getAll(['output' => 'add_link_count', 'checkEnv' => true]);trackerToJSON() gained two keys next to link_count:
'env_check_ok' => (bool)($item['env_check_ok'] ?? true),
'env_check_msg' => (string)($item['env_check_msg'] ?? ''),trackerToJSON() is shared by the list, GET-by-id, POST, PUT and DELETE responses, so
every route carries the fields. The ?? true / ?? '' fallbacks mirror
tlCodeTracker.class.php:562-563 and keep the routes that do not request checkEnv
well-defined (they use getByID()), instead of dropping the key. The UI only renders the
GET list, so those fallbacks are never displayed.
gui/templates/codetracker/codetrackerView.html:
- CSS
.badge-env-ok(green#3a9c5c) /.badge-env-ko(red#e6605e), copied fromissuetrackerView.html:28-29so both integration grids look the same. -
<th data-i18n="ct.environment">Environment</th>between Server URL and Active. - In
renderTable():
var envOk = t.env_check_ok !== false;
var envMsg = t.env_check_msg ? esc(t.env_check_msg) : '';
var envHtml;
if (envOk) {
envHtml = '<span class="badge-env-ok" title="' + (envMsg || TLi18n.t('ct.envOk')) + '">'
+ TLi18n.t('ct.envOk') + '</span>';
} else {
envHtml = '<span class="badge-env-ko" title="' + TLi18n.t('ct.envKo') + '">'
+ (envMsg || TLi18n.t('ct.envKo')) + '</span>';
}OK → compact green OK badge with the implementation's message as tooltip;
KO → red badge whose label is the human failure message (the only information a
failing check has), tooltip = the localized "Environment check failed".
- Row arrays grew 5 → 6 entries, the DataTables
columnsmap grew anull, andtable.column(4).visible(canManage)becametable.column(5).visible(canManage)so the view-only-user collapse still targets the moved Actions column.
env_check_msg is passed through the existing esc() helper (issue #1581) — it is a
constant string from the implementation class, but server text is never trusted as HTML.
Three new keys in all 10 bundles (en, de, es, fr, it, ja, pt, ro, ru, zh):
ct.environment, ct.envOk, ct.envKo. The bundles mirror the already-shipped
it.environment / it.envOk / it.envKo values. The failing check's own text is
deliberately not translated — it comes verbatim from checkEnv(), exactly as legacy
rendered {$item_def.env_check_msg|escape}.
| bundle | ct.environment |
ct.envOk |
ct.envKo |
|---|---|---|---|
| en | Environment | OK | Environment check failed |
| de | Umgebung | OK | Umgebungsprüfung fehlgeschlagen |
| es | Entorno | OK | Falló la verificación del entorno |
| fr | Environnement | OK | Échec de la vérification de l'environnement |
| it | Ambiente | OK | Controllo ambiente non riuscito |
| ja | 環境 | OK | 環境チェックに失敗しました |
| pt | Ambiente | OK | Falha na verificação do ambiente |
| ro | Mediu | OK | Verificarea mediului a eșuat |
| ru | Окружение | OK | Проверка окружения не удалась |
| zh | 环境 | OK | 环境检查失败 |
The issue allowed either "keep the Server URL addition" or "merge into the same cell".
Merging was rejected: editTracker() prefills #editServerUrl from t.serverUrl
(codetrackerView.html:346), and Server URL is a deliberate 2.0.1 addition with no legacy
counterpart. The result is a superset: legacy Environment column and the modern
Server URL column.
The column is visible to view-only users, exactly like legacy: th_codetracker_env
(codeTrackerView.tpl:42) sits outside every {if $gui->canManage} block. The probe is a
credential-free function_exists() test, so exposing it needs no management right. The
#1576 gate on the raw cfg (which may hold a plaintext <token>) is untouched and stays
management-only.
Fixtures — tmp/fixtures_973.php (re-runnable), seeded through the real save path
tlCodeTracker::create(): a GitHub tracker (type 200) and two Stash trackers (type 1),
plus a view-only user ctview973 / viewonly (role 900 with right 52
codetracker_view only).
The KO branch is exercised end-to-end on a second instance started with
php -d disable_functions=curl_init -S 127.0.0.1:8085 -t . — precisely the condition
githubrestCodeTrackerInterface::checkEnv() tests. On that instance the two grids differ
per row while server, screen and data are identical:
| tracker | interface | :8082 (cURL present) | :8085 (disable_functions=curl_init) |
|---|---|---|---|
| GitHub Main | githubrestCodeTrackerInterface |
.badge-env-ok "OK" |
.badge-env-ko "cURL extension is required for the GitHub code tracker interface" |
| Stash Generic | stashrestInterface |
.badge-env-ok "OK" |
.badge-env-ok "OK" |
| Stash Second | stashrestInterface |
.badge-env-ok "OK" |
.badge-env-ok "OK" |
Suite 973 in tmp/TLU_Test_Cases.md records 13/13 PASS:
- Environment column present and localized (6 columns, 6 cells).
- OK state renders a green badge per row.
- KO state renders the implementation's message, per row.
- KO badge tooltip is the localized
ct.envKofallback. - Server URL column preserved (no regression).
- Create/Edit modal still prefills.
- Action icons still land in the last (Actions) column after the index shift.
- Search and sort still work with the extra column.
- View-only user still sees the Environment column, Actions/Create stay hidden.
- No credential leak —
cfgstill blank for non-managers. - create/delete round-trip keeps the column consistent.
- i18n coverage: 3 keys × 10 bundles, all valid JSON, pure additions.
- Event Viewer clean (only AUDIT rows), console clean on both instances.
Screenshots: docs/screenshots/issue-973-codetracker-env-column.png (OK state) and
docs/screenshots/issue-973-codetracker-env-column-ko.png (KO state, forced).