Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"require": {
"php": ">=8.0",
"reportico/adodb-php": "^8.1",
"twig/twig": "^3.0",
"twig/twig": "^3.19",
"tecnickcom/tcpdf": "^6.2",
"szymach/c-pchart": "^3.0",
"reportico/assetter": "^8.1",
Expand Down
4 changes: 2 additions & 2 deletions dyngraph.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/


ini_set("memory_limit","100M");
ini_set("memory_limit", getenv("REPORTICO_MEMORY_LIMIT") ?: "512M");
error_reporting(E_ALL);
date_default_timezone_set(@date_default_timezone_get());

Expand Down Expand Up @@ -258,7 +258,7 @@ function convertSpecialChars($intext)
$graph->Add($lplot[$lplotct]);
break;
case "LINE":
default;
default:
if ( count($v["data"]) == 1 )
$v["data"][] = 0;
$lplot[$lplotct]=new LinePlot($v["data"]);
Expand Down
2 changes: 1 addition & 1 deletion partial.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
error_reporting(E_ALL);
date_default_timezone_set(@date_default_timezone_get());

ini_set("memory_limit","100M");
ini_set("memory_limit", getenv("REPORTICO_MEMORY_LIMIT") ?: "512M");

//ob_start();
require_once('reportico.php');
Expand Down
4 changes: 2 additions & 2 deletions run.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
date_default_timezone_set(@date_default_timezone_get());

// Reserver 100Mb for running
ini_set("memory_limit","100M");
ini_set("memory_limit", getenv("REPORTICO_MEMORY_LIMIT") ?: "512M");

// Allow a good time for long reports to run. Set to 0 to allow unlimited time
ini_set("max_execution_time","90");
ini_set("max_execution_time", getenv("REPORTICO_MAX_EXECUTION_TIME") ?: "300");

// Instantiate Reportico
$q = new Reportico\Engine\Reportico();
Expand Down
2 changes: 1 addition & 1 deletion src/ChartJpgraph.php
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ function generateGraphImage ()
$graph->Add($lplot[$lplotct]);
break;
case "LINE":
default;
default:
if ( count($v["data"]) == 1 )
$v["data"][] = 0;
$lplot[$lplotct]=new LinePlot($v["data"]);
Expand Down
2 changes: 1 addition & 1 deletion src/ChartPchart.php
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ public function generateGraphImage($outputfile)
$image->writeValues($data->GetData(), $data->GetDataDescription(), $series2);
break;
case "LINE":
default;
default:
if ($linedrawn) {
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ChartPchart3.php
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ public function generateGraphImage($outputfile)

break;
case "LINE":
default;
default:

if (count($v["data"]) == 1) {
$v["data"][] = 0;
Expand Down
16 changes: 16 additions & 0 deletions src/QueryColumn.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,22 @@ public function __call($method, $args)
public function getValueDelimiter()
{
if (strtoupper($this->column_type) == "CHAR") {
// PostgreSQL (and the SQL standard) use single quotes for string literals.
// Double quotes delimit identifiers, so a date like "2026-05-13" is parsed as a
// column name and fails with "column does not exist" — uncaught PDOException → WSOD.
$driver = "";
if ($this->datasource && !empty($this->datasource->_conn_driver)) {
$driver = strtolower((string) $this->datasource->_conn_driver);
}
if (
$driver === "pdo_pgsql"
|| $driver === "postgres"
|| $driver === "pgsql"
|| str_contains($driver, "pgsql")
) {
return "'";
}

return ("\"");
}

Expand Down
7 changes: 7 additions & 0 deletions src/ReportHtml.php
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,13 @@ public function openGroup() {
*/
public function closeGroup() {

// PHP 8.1+: writing to $this->currentGroup[...] when it is `false` triggers
// an "Automatic conversion of false to array" deprecation. Treat closeGroup()
// with no open group as a no-op, matching the behaviour of openGroup() init paths.
if (!is_array($this->currentGroup)) {
return;
}

$x= $this->line_count;
$this->currentGroup["endrow"] = $this->line_count - 1;
$this->jar["pages"][$this->page_count]["rows"][$this->line_count]["closerowsection"] = true;
Expand Down
7 changes: 7 additions & 0 deletions src/ReportHtml2pdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,13 @@ public function openGroup() {
*/
public function closeGroup() {

// PHP 8.1+: writing to $this->currentGroup[...] when it is `false` triggers
// an "Automatic conversion of false to array" deprecation. Treat closeGroup()
// with no open group as a no-op.
if (!is_array($this->currentGroup)) {
return;
}

$x= $this->line_count;
$this->currentGroup["endrow"] = $this->line_count - 1;
$this->jar["pages"][$this->page_count]["rows"][$this->line_count]["closerowsection"] = true;
Expand Down
10 changes: 9 additions & 1 deletion src/ReportTCPDF.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ class ReportTCPDF extends Report
public $abs_col_left_margin;
public $abs_left_margin;
public $abs_right_margin;
// PHP 8.2+: declare these explicitly to avoid Creation-of-dynamic-property deprecations.
public $abs_row_right_margin;
public $abs_col_right_margin;
public $abs_row_width;
public $abs_columns_width;
public $column_spacing = 0;
public $abs_page_width = 0;
public $abs_page_height = 0;
public $abs_print_width = 0;
Expand Down Expand Up @@ -3244,7 +3250,9 @@ public function newReportPageLine($txt = "")
$this->newReportPageLineByStyle("LINEPAGE$txt", $this->mid_page_page_styles, false);
}

public function newReportPageLineByStyle($txt = "", &$styles, $blankline = false)
// PHP 8.0+: optional parameters cannot precede required ones; $styles is by-ref/required,
// so $txt must also be required (callers always pass it explicitly).
public function newReportPageLineByStyle($txt, &$styles, $blankline = false)
{
// Line page wrapper
$this->applyStyleTags("$txt", $styles);
Expand Down
2 changes: 1 addition & 1 deletion src/Reportico.php
Original file line number Diff line number Diff line change
Expand Up @@ -4963,7 +4963,7 @@ public function generateDropdownMenu(&$menu)
}

$filename = $proj_parent . "/" . $project . "/" . $menuitem["reportfile"];
if (!preg_match("/\.xml/", $filename)) {
if (!preg_match("/\.xml$/i", $filename)) {
$filename .= ".xml";
}

Expand Down
6 changes: 6 additions & 0 deletions src/ReporticoApp.php
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,12 @@ static function ErrorLogger($errno, $errstr, $errfile = false, $errline = false)
// error handler function
static function ErrorHandler($errno, $errstr, $errfile, $errline)
{
// PHP 8.x: deprecations must not be stored as blocking "system errors" — Reportico treats
// anything in that list like a fatal in several execute paths (blank / broken pages).
if ($errno === E_DEPRECATED || $errno === E_USER_DEPRECATED) {
return true;
}

switch ($errno) {
case E_ERROR:
$errtype = ReporticoLang::translate("Error");
Expand Down
34 changes: 29 additions & 5 deletions src/ReporticoSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,13 @@ static function setUpReporticoSession($namespace)
*/
static function existsReporticoSession()
{
if (isset($_SESSION[ReporticoApp::get("session_namespace_key")])) {
$key = ReporticoApp::get("session_namespace_key");
// PHP 8.1+: $_SESSION[null] triggers "Using null as an array offset is deprecated".
// When session_namespace_key has not been set yet, the namespace by definition does not exist.
if ($key === null || $key === "") {
return false;
}
if (isset($_SESSION[$key])) {
return true;
} else {
return false;
Expand Down Expand Up @@ -269,7 +275,12 @@ static function issetReporticoSessionParam($param, $session_name = false)
{
if (!$session_name)
$session_name = ReporticoApp::get("session_namespace_key");


// PHP 8.1+: $_SESSION[null] triggers "Using null as an array offset is deprecated".
if ($session_name === null || $session_name === "") {
return false;
}

return isset($_SESSION[$session_name][$param]);
}

Expand All @@ -288,6 +299,12 @@ static function setReporticoSessionParam($param, $value, $namespace = false, $ar
if (!$namespace)
$namespace = ReporticoApp::get("session_namespace_key");

// PHP 8.1+: $_SESSION[null] triggers "Using null as an array offset is deprecated".
// If the namespace key is not yet set there is no session bucket to write to.
if ($namespace === null || $namespace === "") {
return;
}

//echo "Set $namespace:$param<BR>";
if (!$array) {
$_SESSION[$namespace][$param] = $value;
Expand Down Expand Up @@ -321,8 +338,13 @@ static function getReporticoSessionParam($param)
*/
static function unsetReporticoSessionParam($param)
{
if (isset($_SESSION[ReporticoApp::get("session_namespace_key")][$param])) {
unset($_SESSION[ReporticoApp::get("session_namespace_key")][$param]);
$key = ReporticoApp::get("session_namespace_key");
// PHP 8.1+: $_SESSION[null] triggers "Using null as an array offset is deprecated".
if ($key === null || $key === "") {
return;
}
if (isset($_SESSION[$key][$param])) {
unset($_SESSION[$key][$param]);
}
}

Expand Down Expand Up @@ -370,7 +392,9 @@ static function reporticoNamespace()
static function initializeReporticoNamespace($namespace = "reportico")
{
$namespace = ReporticoApp::get("session_namespace_key");
if (isset($_SESSION[$namespace])) {
// PHP 8.1+: $_SESSION[null] triggers "Using null as an array offset is deprecated".
// Nothing to clear if the namespace key has not been set.
if ($namespace !== null && $namespace !== "" && isset($_SESSION[$namespace])) {
unset($_SESSION[$namespace]);
}

Expand Down
5 changes: 5 additions & 0 deletions src/ReporticoUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ static function backtrace()
// Look for a file in the include path, or the path of the current source file
static function findFileToInclude($file_path, &$new_file_path, &$rel_to_include = "")
{
if (!$file_path || !is_string($file_path)) {
$new_file_path = $file_path;
return false;
}

// First look in path of current file
static $_path_array = null;
if (__DIR__) {
Expand Down
40 changes: 23 additions & 17 deletions src/XmlReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -397,9 +397,10 @@ public function __construct(&$query, $filename, $xmlstring = false, $search_tag
$this->field_display["YTickLabelInterval"]["Type"] = "HIDE";
}

xml_set_object($this->parser, $this);
xml_set_element_handler($this->parser, 'startElement', 'endElement');
xml_set_character_data_handler($this->parser, 'cdata');
// PHP 8.4 deprecated xml_set_object() and string-name callbacks for xml_set_*_handler().
// Pass [object, methodName] callables instead, which are also valid in PHP 7.4+.
xml_set_element_handler($this->parser, [$this, 'startElement'], [$this, 'endElement']);
xml_set_character_data_handler($this->parser, [$this, 'cdata']);
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);

// 1 = single field, 2 = array field, 3 = record container
Expand Down Expand Up @@ -467,7 +468,11 @@ public function __construct(&$query, $filename, $xmlstring = false, $search_tag
echo "XML $filename<BR>";
}
if ($this->query) {
$readfile = $this->query->projects_folder . "/" . ReporticoApp::getConfig("project") . "/" . $filename;
if (!empty($this->query->reports_path)) {
$readfile = $this->query->reports_path . "/" . $filename;
} else {
$readfile = $this->query->projects_folder . "/" . ReporticoApp::getConfig("project") . "/" . $filename;
}
$adminfile = $this->query->admin_projects_folder . "/admin/" . $filename;
} else {
$readfile = $filename;
Expand All @@ -492,35 +497,36 @@ public function __construct(&$query, $filename, $xmlstring = false, $search_tag
if ($readfile && is_file($readfile)) {
$readfile = $readfile;
} else {
if (!is_file($adminfile)) {
if ($adminfile && !is_file($adminfile)) {
ReporticoUtility::findFileToInclude($adminfile, $readfile);
if (is_file($readfile)) {
$readfile = $readfile;
}

} else {
} elseif ($adminfile && is_file($adminfile)) {
$use_admin_xml = true;
$readfile = $adminfile;
}
}

if ($readfile) {
if ($readfile && is_file($readfile)) {
//if ( $use_admin_xml )
//Authenticator::flag("admin-report-selected");
if ( !file_exists($readfile) ) {
ReporticoApp::backtrace();
}
$x = join("", file($readfile));
} elseif ($this->search_tag) {
// Menu title lookup for a non-report path; skip without fatal error
$this->search_response = "";
} elseif ($readfile) {
$report_path = ($this->query && $this->query->reports_path) ? $this->query->reports_path : $readfile;
trigger_error("Report Definition File " . $report_path . "/" . $filename . " Not Found", E_USER_ERROR);
} else {
trigger_error("Report Definition File " . $this->query->reports_path . "/" . $filename . " Not Found", E_USER_ERROR);
$report_path = ($this->query && $this->query->reports_path) ? $this->query->reports_path : "";
trigger_error("Report Definition File " . $report_path . "/" . $filename . " Not Found", E_USER_ERROR);
}

}
}

if ($x) {
xml_parse($this->parser, $x);
xml_parser_free($this->parser);
// xml_parser_free() was deprecated in PHP 8.5 (no-op since 8.0).
// Parser is freed automatically when $this->parser goes out of scope.
}

//var_dump($this->data);
Expand Down Expand Up @@ -2306,7 +2312,7 @@ public function &draw_add_button($in_tag, $in_value = false)
break;
case "mainqueroutppgft":$importtype = "IMPORT";
break;
default;
default:
$importtype = false;
}

Expand Down
3 changes: 3 additions & 0 deletions src/widgets/AdminMenu.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ public function generateMenuList ()
if (is_dir(ReporticoApp::get("projpath"))) {
if ($dh = opendir(ReporticoApp::get("projpath"))) {
while (($file = readdir($dh)) !== false) {
if (!preg_match('/\.xml$/i', $file)) {
continue;
}
$mtch = "/" . $menuitem["report"] . "/";
if (preg_match($mtch, $file)) {
$repxml = new XmlReader($this->engine, $file, false, "ReportTitle");
Expand Down
4 changes: 4 additions & 0 deletions src/widgets/Criteria.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ class Criteria extends Widget
public $buttonTypes = array();
public $formTypes = array();

// PHP 8.2+: declared explicitly to avoid Creation-of-dynamic-property deprecation.
// Populated by Widget::handleUrlParameters() when criteria_type is "DATE" (passed by reference into ReporticoLocale::convertDateRangeDefaultsToDates()).
public $range_start = false;

public function __construct($engine, $load = false, $engineCriteria = false )
{

Expand Down
5 changes: 5 additions & 0 deletions src/widgets/CriteriaForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,14 @@ public function render()
}


$project = htmlspecialchars(ReporticoApp::getConfig("project", ""), ENT_QUOTES);
$xmlin = htmlspecialchars($this->engine->xmlinput ? $this->engine->xmlinput : "", ENT_QUOTES);

$sections["begin"] = "
<FORM class='reportico-prepare-form non-printable' id='reportico-form' method='POST' action='$submit_self'>
<input type='hidden' name='reportico_session_name' value='$sessionId' />
<input type='hidden' name='project' value='$project' />
<input type='hidden' name='xmlin' value='$xmlin' />
";

$sections["end"] = "</FORM>";
Expand Down
6 changes: 5 additions & 1 deletion src/widgets/DatePicker.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ class DatePicker extends Widget
public $range_raw = false;
public $range_start = false;
public $range_end = false;
// PHP 8.2+: declared explicitly to avoid Creation-of-dynamic-property deprecations
// (assigned in deriveValue()). Matches DateRangePicker / TimeRangePicker.
public $range_name = false;
public $range_start_raw = false;
public $range_end_raw = false;

public $options = [
"Today" => [
Expand Down Expand Up @@ -199,7 +204,6 @@ public function getCriteriaClause($lhs = true, $operand = true, $rhs = true, $rh
}

}
echo $cls;

$del = "";
if ($add_del) {
Expand Down
Loading