Bugfix Issue 495 MainPage TestprojectOptions EWarning - sebiboga/testlink-upgraded GitHub Wiki
Issue 495 โ mainPage.php E_WARNING Undefined array key "testprojectOptions" (line 424)
Issue: #495
Branch: fix/issue-495 ยท Fix already landed in: 38c7d6f16, 3071beefb, 3266f4329, 8748128fb
Status: VERIFIED-FIXED & CLOSED (2026-08-24) โ no new code needed; ticket closed with verification evidence
Symptom
Event Viewer entry reported in the issue (2026โ08โ18 11:15:03):
E_WARNING Undefined array key "testprojectOptions" - in ...\lib\general\mainPage.php - Line 424
Every render of the main page (lib/general/mainPage.php) emitted the warning under PHP 8.
Root cause chain
getGrants()insidemainPage.phpread$_SESSION['testprojectOptions']->inventoryEnabledunconditionally. The session keytestprojectOptionsis never written anywhere in this codebase (grep -rn "\['testprojectOptions'\] *=" lib/ www/โ 0 hits), so PHP 8 threwUndefined array keyon every mainPage load.- Fix wave 1 โ
38c7d6f16(2026โ08โ18) added exactly the guard proposed in the issue body:isset($_SESSION['testprojectOptions']) && $_SESSION['testprojectOptions']->inventoryEnabled.3071beefbapplied the same double-guard to the sibling read at lines 187โ189 ($gui->opt_requirements). - Supersession (current behavior) โ
3266f4329+8748128fb(2026โ08โ21) replaced the dead session-key logic:getGrants()now reads LIVE options from the DB viatestproject::getOptions($tproject_id)and normalizes inventory grants to int1/0. Rationale: anisset()on a never-set key made that branch dead code and let raw'yes'/'no'strings fromhasRight()leak into grants โ'no'is truthy, which rendered the Inventory link while inventory was disabled. Current code:lib/general/mainPage.php:530-550.
Verification performed (2026-08-24)
Environment: fresh DB (events empty at baseline), app http://localhost:8082, admin/admin,
headless Chrome. Measured after EVERY step via SELECT id,log_level,description FROM events WHERE log_level>16.
| Path exercised | Result |
|---|---|
| Blind-folded path: fresh login, no testproject in session โ getGrants(tproject_id=0), redirect to project create | 0 warnings |
| First test project created through UI ("Issue495 Project", prefix I495, id=1) | audit only |
mainPage render with active project (index.php?tproject_id=1&tplan_id=0) |
0 warnings |
| Reload / project-switch path | 0 warnings |
Final sweep: the only warning-level rows in the entire events table were ids 3โ4 produced by a
DELIBERATE reproduction of the sibling bug (loading freeTestCases.php directly). Zero events are
sourced from mainPage.php. Static check confirms every remaining $_SESSION['testprojectOptions']
access in mainPage.php is guarded (lines 187โ189).
Regression suite: tmp/TLU_Test_Cases.md โ Suite 495 โ 8/8 PASS.
Sibling bugs (see GitHub issue #679)
The same never-written session key is still read UNGUARDED in other screens โ filed separately as #679:
lib/results/freeTestCases.php:25 (live-reproduced: Undefined array key + property-on-null)
lib/results/tcNotRunAnyPlatform.php:116,216,228
lib/plan/tc_exec_assignment.php:222
gui/templates/dashio/plan/tc_exec_assignment.tpl:175,221,229
The recommended fix there is the same pattern this issue ended with: drop the dead session key and
read live options via testproject::getOptions($tproject_id).