Bug: Reporting Cycle edit saves milestones field as literal "Array" string instead of JSON

Hi Gibbon Team!

Seems I found a bug. Find my setup and my attempt to explain it as good as possible. Let me know if it’s not a bug or I’m unclear in my description.**

Gibbon version:** v30.0.01
PHP version: 8.3
MySQL version: 8.0.46
OS: AlmaLinux (production) / Debian via Docker (development)

Description:

When editing a Reporting Cycle via:
Reports > Manage Reporting Cycles > Edit and saving, the milestones field in gibbonReportingCycle is written as the literal string "Array" instead of a valid JSON structure.

The following PHP warnings are shown on save:

Warning: Array to string conversion in /var/www/html/src/Database/Connection.php on line 182
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/src/Database/Connection.php:182) in /var/www/html/modules/Reports/reporting_cycles_manage_editProcess.php on line 96

To reproduce:

  1. Go to Reports > Manage Reporting Cycles

  2. Click Edit on any existing reporting cycle

  3. Make any change (e.g. extend the end date) and click Save

  4. Run: SELECT milestones FROM gibbonReportingCycle;

  5. Result: Array

Impact:

The corrupt milestones value causes Reports > Publish > Generate Reports to show “There are no records to display”, blocking PDF generation entirely.

Workaround:

sql:

UPDATE gibbonReportingCycle SET milestones=NULL WHERE name='your cycle name';

This restores Generate Reports functionality. Milestones were never intentionally configured; the corrupt value originates from the save processor passing a PHP array to the DB query without JSON encoding it first.

Suspected location of bug: modules/Reports/reporting_cycles_manage_editProcess.php line 96, where the milestones value is not serialised before the DB write.

Hope that helps!

Follow-up: Additional symptom on PHP 8.1+

After applying the workaround (SET milestones=NULL), a related deprecation warning appears on the My Reporting page:

Deprecated: json_decode(): Passing null to parameter #1 ($json) of type string is deprecated in modules/Reports/reporting_my.php on line 126

This occurs because reporting_my.php line 126 calls json_decode($reportingCycle['milestones'], true) without checking for NULL first. On PHP 8.1+, passing NULL to a typed string parameter is deprecated.

The fix would be to change line 126 to:

php

'milestones' => json_decode($reportingCycle['milestones'] ?? '[]', true),

This affects both the case where milestones is NULL (our workaround) and the original case where it contains the literal string “Array” (which also causes json_decode to return NULL silently). Both are symptoms of the same underlying issue in the save processor.

Hi @Xavier_Bit

Thank you for reporting the issue. The bug has been fixed in the upcoming v31 version. Here is the PR: Reports: Reporting Cycle edit saves milestones field as literal "Arra… by ali-ichk · Pull Request #2133 · GibbonEdu/core · GitHub. Thanks!