FreePBX 17 / PHP 8.2 compatibility patches#4
Conversation
- Fix PHP 8 undefined array keys in getrecords AJAX handler - Add CEL + disk fallback for missing recordingfile on outgoing calls - Fix PDF Footer() crash on null locale array - Fix Combined report PDF column mismatch - Replace deprecated each() with foreach() in FPDF - Cap color index in Distribution heatmap - Escape unfiltered superglobals in HTML/JS output - Remove dead Adobe Flash swf_bar_old() function
There was a problem hiding this comment.
Code Review
This pull request introduces compatibility patches for FreePBX 17 and PHP 8.2, addressing issues such as deprecated functions, PDF export crashes, missing recording files, and unescaped superglobals. The review feedback highlights several critical issues: removing the $total_bill > 0 check introduces a division-by-zero risk, $ftype and $fdisplay require sanitization to prevent XSS/JS injection, the $numcolor cap needs to be applied to the 1-day report block as well, and a ternary expression in the PDF footer can be simplified using the null coalescing operator.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| $percentage_bill = $val * 100 / $total_bill; | ||
| $percentage_bill = number_format($percentage_bill,2); |
There was a problem hiding this comment.
Removing the $total_bill > 0 check introduces a critical division by zero risk. If there are only missed calls or if the total billable time is zero, $total_bill will be 0, causing a fatal DivisionByZeroError or a warning that is converted to an exception by the Whoops error handler in FreePBX 17. Please restore the check or use a safe ternary operator.
$percentage_bill = $total_bill > 0 ? number_format($val * 100 / $total_bill, 2) : '0.00';| $ftype = $_REQUEST['type'] ?? 'tool'; | ||
| $fdisplay = $_REQUEST['display'] ?? 'asternic_cdr'; |
There was a problem hiding this comment.
The variables $ftype and $fdisplay are retrieved directly from $_REQUEST and later outputted unescaped inside a JavaScript onclick attribute (line 288). This creates a Cross-Site Scripting (XSS) and JavaScript injection vulnerability. Since these variables are expected to be simple alphanumeric identifiers (e.g., 'tool', 'asternic_cdr'), they should be sanitized to only allow alphanumeric characters, underscores, and hyphens.
$ftype = preg_replace('/[^a-zA-Z0-9_-]/', '', $_REQUEST['type'] ?? 'tool');
$fdisplay = preg_replace('/[^a-zA-Z0-9_-]/', '', $_REQUEST['display'] ?? 'asternic_cdr');| if(!isset($num[$chann][$date][$hour])) { $num[$chann][$date][$hour]=0;} | ||
| $numcolor = intval(($dur[$chann][$date][$hour]/60)/10); | ||
| if((intval($dur[$chann][$date][$hour]/60))==0) { $numcolor=6; } | ||
| if($numcolor > 6) { $numcolor = 6; } |
There was a problem hiding this comment.
While you successfully capped $numcolor at 6 to prevent undefined offset errors in the multi-day report block, the same bug is still present in the 1-day report block (around line 490). If a 1-day report has more than 60 minutes of calls in a single hour, $numcolor will exceed 6 and cause an 'Undefined array key' Whoops exception. Please ensure you also apply this cap to the 1-day report block.
| $this->SetFont('Arial','I',8); | ||
| //Print centered page number | ||
| $this->Cell(0,10,$lang["$language"]['page'].' '.$this->PageNo(),0,0,'C'); | ||
| $pageText = (isset($lang[$language]['page']) ? $lang[$language]['page'] : 'Page') . ' ' . $this->PageNo(); |
- Restore >0 guard in Combined report (division-by-zero risk) - Sanitize / with htmlspecialchars() before JS interpolation - Apply cap to 1-day distribution report block as well - Simplify PDF footer ternary: use ?? for nested key with isset() guard on parent
|
Thanks for the thorough review. I've pushed commit
Let me know if anything else needs adjustment. |
This PR applies 8 patches to make Asternic CDR Reports v1.6.6 compatible with FreePBX 17 (PHP 8.2, Whoops error handler, PJSIP channels, and the new CDR recording pipeline).
Background
FreePBX 17 ships with PHP 8.x and the Whoops error handler, which converts E_WARNING into exceptions. The upstream v1.6.6 code was written for PHP 5/7 where missing array keys silently returned null. This causes hard crashes on multiple
features.
Additionally, FreePBX 17's CDR backend does not populate recordingfile for outgoing calls, breaking the play/download icons that the module relies on.
Patches included
| Patch │ Commit │What it fixes │
| ----- | --- | --- |
│ PATCH-001 │ 6b54b0b │ $_REQUEST['type'] / $_REQUEST['display'] undefined in getrecords AJAX handler │
│ PATCH-002 │ a09b4b6 │ Missing recording icons for outgoing calls — adds CEL session + disk glob() fallback │
│ PATCH-003 │ 6978961 │ PDF Footer() crash on null $lang array │
│ PATCH-004 │ 4f4cbfd │ PDF Combined report column mismatch (12 data columns vs 11 headers) │
│ PATCH-005 │ 75840ed │ Replace deprecated each() with foreach() in bundled FPDF │
│ PATCH-006 │ e1e8507 │ Distribution heatmap color index overflow ($colorete has only 7 elements) │
│ PATCH-007 │ d779b70 │ Escape unfiltered $_SERVER['REQUEST_URI'] and $_REQUEST output in HTML/JS │
│ PATCH-008 │ 98d0882 │ Remove dead Adobe Flash swf_bar_old() function (no callers, no SWF assets) │
Testing performed
All functionality was tested on a live FreePBX 17.0.28 installation:
Backward compatibility
These changes are backward-compatible with PHP 7 / FreePBX 14-16:
Documentation
The README has been updated with a FreePBX 17 Compatibility section explaining the fixes and installation methods.
Thank you for maintaining this module. Let me know if you would like any changes before merging.