Repository navigation
Task Issue 962 issuetracker Connection Check
Task 962 — Restore the issue-tracker connection check (checkConnection / isConnected) in the Issue Trackers screen (gap vs legacy)
Issue: #962 Status: IMPLEMENTED & VERIFIED (2026-09-23)
The modern Issue Trackers screen never validated that a tracker configuration actually works. Legacy offered two connection-check entry points that the modern screen dropped:
-
List wrench icon —
issueTrackerView.tpl:55-58renders per row an icon linking toissueTrackerView.php?id=<N>, which runstlIssueTracker::checkConnection()(tlIssueTracker.class.php:723-735) on the STORED config and rendersfa-heartbeat(ok) /fa-skull-crossbones(ko) withissueTracker_connection_ok/issueTracker_connection_kotitles. -
Create/Edit form "Check Connection" button —
issueTrackerEdit.tpl:226-229→issueTrackerCommands::checkConnection(issueTrackerCommands.class.php:253-281) instantiates the implementation from the CURRENT (possibly unsaved) form fields and shows analert-success/alert-dangerbox — theissue-tracker-integrationGUI per-trackerisConnected().
Both were issuetracker_management (canManage) gated in legacy.
![]()
BFF api/issuetracker/index.php — two new routes, both canManage gated
($writeDenied()), JSON out, \Throwable → 502:
-
GET /{id}/check-connection— reads stored cfg viagetByID, resolves the implementation from the tracker type and callsisConnected()(row-status path). -
POST /test-connection— takesname/type/cfgfrom the JSON body and tests UNSAVED config (modal path). POST-only on purpose: the cfg may contain an apikey (never ride a query string) and a GET variant would be a blind-SSRF probe from a canManage user's browser; the same-origin CSRF guard protects it. - Unknown tracker type → HTTP 400 (before calling
getImplementationForType(), which would otherwise raise PHP8 "array offset" warnings per request).
Screen gui/templates/issuetracker/issuetrackerView.html:
- Name cell (canManage only): wrench icon that fires the row-status check and
paints
fas fa-heartbeat(green) /fas fa-skull-crossbones(red) next to the name with a localized tooltip; a#conn-<id>holder is cleared on reload. - Modal: new "Check Connection" button (
#btnCheckConn) +#connAlertdiv;checkConnectionModal()POSTs the current fields and rendersalert alert-success/alert alert-danger; button disabled while in flight; alert reset on every modal-open path.
i18n — new keys it.checkConnection, it.connOk, it.connKo,
it.connCheckFailed in all 10 locale bundles.

The legacy tlIssueTracker::checkConnection() caches the interface object into
$_SESSION['its']; on PHP8 that object holds a CurlHandle, and the session
write at request end fails with Serialization of CurlHandle is not allowed,
killing the PHP dev-server process. The BFF therefore instantiates the interface
directly (new $impl(...) after a class_exists guard) instead of using the
legacy cache method — same logic as the already-ported codetracker BFF.
- Row status: local-DB tracker →
fa-heartbeat+ "Connection successful"; unreachable github tracker →fa-skull-crossbones+ "Connection failed (check type and configuration)". Both requests 200. - Modal: bogus github cfg →
alert-danger"Connection failed (check type and configuration)"; working bugzilla-db cfg →alert-success" Connection successful". BothPOST /test-connection200. - Unknown type → HTTP 400 "Unknown issue tracker type" (no PHP8 warnings).
- Event Viewer: 0 Error/Warning rows; browser console contains only the pre-existing a11y nits.
Test suite: tmp/TLU_Test_Cases.md → "Suite 962" (6/6 PASS).