You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Plugin version: 3.2.6 GLPI version: 11.x Severity: High Files:setup.php ~line 102, src/TicketTask.php, src/ProjectTask.php, src/PlanningExternalEvent.php, hook.php Related issue:#23
Description
Throughout the plugin, the options record is loaded with:
$opt = newOption();
$opt->getFromDB(1);
// Direct field access immediately after, no existence check$value = $opt->fields['use_timerepartition'];
CommonDBTM::getFromDB() returns false when the record does not exist, but its return value is never checked. When it returns false, $opt->fields remains an empty array, and every subsequent $opt->fields['any_key'] access generates an Undefined index / Undefined array key PHP notice or warning, which in GLPI 11 (strict mode) can escalate to a fatal error.
This happens in at least the following scenarios:
Fresh installation where plugin_activity_install() failed partway through (e.g., due to the typo in B2).
The glpi_plugin_activity_options table is empty for any reason.
A race condition during first install before INSERT into the options table completes.
Steps to reproduce
Truncate glpi_plugin_activity_options (or install with a partial migration failure).
Navigate to any page that loads the Activity plugin.
Observe PHP notices/errors in GLPI logs: Undefined array key "use_timerepartition", Undefined array key "is_cra_default", etc.
Proposed fix
Option A — Guard every call site (minimal change)
$opt = newOption();
if (!$opt->getFromDB(1)) {
// Record missing — insert defaults or skip optional behavior$opt->fields = $opt->getDefaultValues(); // see below
}
Option B — Add a getInstance() helper that guarantees a valid record (recommended)
Add a static method to Option that ensures the record exists before returning:
The ?? null-coalescing operator should be used as a safety net on all field accesses even after the guard, to prevent regressions if new fields are added without a corresponding migration.
Plugin version: 3.2.6
GLPI version: 11.x
Severity: High
Files:
setup.php~line 102,src/TicketTask.php,src/ProjectTask.php,src/PlanningExternalEvent.php,hook.phpRelated issue: #23
Description
Throughout the plugin, the options record is loaded with:
CommonDBTM::getFromDB()returnsfalsewhen the record does not exist, but its return value is never checked. When it returnsfalse,$opt->fieldsremains an empty array, and every subsequent$opt->fields['any_key']access generates anUndefined index/Undefined array keyPHP notice or warning, which in GLPI 11 (strict mode) can escalate to a fatal error.This happens in at least the following scenarios:
plugin_activity_install()failed partway through (e.g., due to the typo in B2).glpi_plugin_activity_optionstable is empty for any reason.INSERTinto the options table completes.Steps to reproduce
glpi_plugin_activity_options(or install with a partial migration failure).Undefined array key "use_timerepartition",Undefined array key "is_cra_default", etc.Proposed fix
Option A — Guard every call site (minimal change)
Option B — Add a
getInstance()helper that guarantees a valid record (recommended)Add a static method to
Optionthat ensures the record exists before returning:Then replace all
$opt->getFromDB(1)call sites:Also fix
setup.phpspecificallyAdditional context
??null-coalescing operator should be used as a safety net on all field accesses even after the guard, to prevent regressions if new fields are added without a corresponding migration.Undefined index - getFromDB(1)).