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
18 changes: 18 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "cacti/plugin_intropage",
"description": "plugin_intropage plugin for Cacti",
"license": "GPL-2.0-or-later",
"require-dev": {
"pestphp/pest": "^1.23"
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
}
},
"autoload-dev": {
"files": [
"tests/bootstrap.php"
]
}
}
10 changes: 4 additions & 6 deletions include/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,7 @@ function intropage_reload_panel() {
}

$name = isset($data['name']) ? html_escape($data['name']) : __esc('Not Found', 'intropage');
$height = isset($panel['height']) ? $panel['height'] : 'normal';
$height = $panel['height'] ?? 'normal';
$alarm = isset($data['alarm']) && $data['alarm'] !== '' ? $data['alarm'] : 'grey';

print '<div class="panel_header color_' . $alarm . '">';
Expand Down Expand Up @@ -986,7 +986,7 @@ function get_panel($panel_id, $user_id = 0) {
$refresh_interval = $panel['refresh_interval'];
$trend_interval = $panel['trend_interval'];
$next_update = $last_update + $refresh_interval - time();
$panel['height'] = isset($panel['height']) ? $panel['height'] : 'normal';
$panel['height'] = $panel['height'] ?? 'normal';

$panel['name'] = $definition['name'] . __(' [Upd. in %s/%s]', intropage_readable_interval($next_update), intropage_readable_interval($refresh_interval), 'intropage');
} else {
Expand Down Expand Up @@ -1665,7 +1665,7 @@ function intropage_create_panel($panel_id, $dashboard_id) {
} else {
$width = $panels[$panel_type]['width'];
// we need actual height from db not from panel definition
$height = isset($act_height) ? $act_height : 'normal';
$height = $act_height ?? 'normal';
}

if ($width == 'quarter-panel') {
Expand Down Expand Up @@ -1824,9 +1824,7 @@ function intropage_graph_button($data) {
if (is_panel_allowed('favourite_graph')) {
$local_graph_id = $data[1]['local_graph_id'];

if (!isset($_SESSION['sess_current_timespan'])) {
$_SESSION['sess_current_timespan'] = read_user_setting('default_timespan');
}
$_SESSION['sess_current_timespan'] ??= read_user_setting('default_timespan');
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

??= is a PHP 7.4-only operator. If this plugin still targets PHP 7.0–7.3 (common with older Cacti installs), this will cause a parse error and take the page down. Either revert to an isset()/?? assignment pattern compatible with the supported minimum PHP version, or explicitly document/enforce PHP 7.4+ as a requirement for the plugin.

Suggested change
$_SESSION['sess_current_timespan'] ??= read_user_setting('default_timespan');
if (!isset($_SESSION['sess_current_timespan'])) {
$_SESSION['sess_current_timespan'] = read_user_setting('default_timespan');
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cacti 1.2.x requires PHP 7.4 minimum. The ??= operator is safe for all supported versions.


if ($_SESSION['sess_current_timespan'] == 0) { // zoom or custom timespan
$fav = '<i class="fa fa-eye-slash" title="' . __esc('Cannot add to Dashboard. Custom timespan.', 'intropage') . '"></i>';
Expand Down
14 changes: 7 additions & 7 deletions include/intropage.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
$(function() {
$('.grid_item').css('background-color', $('body').css('background-color'));

$(window).resize(function() {
$(window).on('resize', function() {
resizeGraphsPanel();
resizeCharts();
});
Expand Down Expand Up @@ -202,15 +202,15 @@ function setPageRefresh() {
}

function initPage() {
$('#intropage_addpanel').unbind().change(function() {
$('#intropage_addpanel').off().on('change', function() {
addPanel();
});

$('#intropage_action').unbind().change(function() {
$('#intropage_action').off().on('change', function() {
actionPanel();
});

$('#intropage_action_timespan').unbind().change(function() {
$('#intropage_action_timespan').off().on('change', function() {
timeSpan();
});

Expand Down Expand Up @@ -303,7 +303,7 @@ function initPage() {
}
});

$('.droppanel').click(function(event) {
$('.droppanel').on('click', function(event) {
event.preventDefault();

var panel_div_id = $(this).attr('data-panel');
Expand All @@ -319,7 +319,7 @@ function initPage() {
checkForRedirects(data, url);

$('#intropage_addpanel').selectmenu('destroy').replaceWith(data);
$('#intropage_addpanel').selectmenu().unbind().change(function() {
$('#intropage_addpanel').selectmenu().off().on('change', function() {

addPanel();
});
Expand Down Expand Up @@ -376,7 +376,7 @@ function initPage() {
title: intropage_text_panel_details,
});

$('#block').click(function() {
$('#block').on('click', function() {
$('#overlay').dialog('close');
});
})
Expand Down
10 changes: 5 additions & 5 deletions include/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ function intropage_user_admin_run_action($current_tab) {
draw_edit_form(
[
'config' => ['no_form_tag' => true],
'fields' => inject_form_variables($fields_intropage_user_edit, (isset($user) ? $user : []))
'fields' => inject_form_variables($fields_intropage_user_edit, ($user ?? []))
]
);

Expand Down Expand Up @@ -354,7 +354,7 @@ function intropage_user_group_admin_run_action($current_tab) {
draw_edit_form(
[
'config' => ['no_form_tag' => true],
'fields' => inject_form_variables($fields_intropage_group_edit, (isset($group) ? $group : []))
'fields' => inject_form_variables($fields_intropage_group_edit, ($group ?? []))
]
);

Expand Down Expand Up @@ -434,9 +434,9 @@ function intropage_user_admin_user_save($save) {

$save['last_update'] = '0000-00-00';
$save['data'] = '';
$save['priority'] = (isset($panel['priority']) ? $panel['priority'] : 99);
$save['alarm'] = (isset($panel['alarm']) ? $panel['alarm'] : 'green');
$save['refresh_interval'] = (isset($panel['refresh']) ? $panel['refresh'] : 300);
$save['priority'] = ($panel['priority'] ?? 99);
$save['alarm'] = ($panel['alarm'] ?? 'green');
$save['refresh_interval'] = ($panel['refresh'] ?? 300);

$id = sql_save($save, 'plugin_intropage_panel_data');
}
Expand Down
4 changes: 2 additions & 2 deletions panellib/analyze.php
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,7 @@ function analyse_tree_host_graph_detail() {
foreach ($data as $row) {
$sql_hosts = db_fetch_assoc('SELECT id, description, hostname
FROM host
WHERE hostname = ' . db_qstr($row['hostname']) . ' AND snmp_port=' . $row['snmp_port']);
WHERE hostname = ' . db_qstr($row['hostname']) . ' AND snmp_port=' . (int) $row['snmp_port']);

if (cacti_sizeof($sql_hosts)) {
foreach ($sql_hosts as $row2) {
Expand Down Expand Up @@ -1805,7 +1805,7 @@ function analyse_tree_host_graph_detail() {
$tree = $host['name'] . ' / ';

while ($parent != 0) {
$sql_parent = db_fetch_row('SELECT parent, title FROM graph_tree_items WHERE id = ' . $parent);
$sql_parent = db_fetch_row_prepared('SELECT parent, title FROM graph_tree_items WHERE id = ?', [(int) $parent]);
$parent = $sql_parent['parent'];
$tree .= $sql_parent['title'] . ' / ';
}
Expand Down
48 changes: 24 additions & 24 deletions panellib/busiest.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,9 @@ function busiest_cpu($panel, $user_id) {
WHERE h.disabled != 'on'
$q_host_cond
AND dsh.average IS NOT NULL
AND dtd.data_template_id = " . $ds['id'] . '
AND dtd.data_template_id = " . (int) $ds['id'] . '
ORDER BY dsh.average DESC
LIMIT ' . $lines;
LIMIT ' . (int) $lines;

$avg = db_fetch_cell('SELECT AVG(average)' . $query);
$result = db_fetch_assoc("SELECT $columns $query");
Expand Down Expand Up @@ -335,9 +335,9 @@ function busiest_load($panel, $user_id) {
WHERE h.disabled != 'on'
$q_host_cond
AND dsh.average IS NOT NULL
AND dtd.data_template_id = " . $ds['id'] . '
AND dtd.data_template_id = " . (int) $ds['id'] . '
ORDER BY dsh.average DESC
LIMIT ' . $lines;
LIMIT ' . (int) $lines;

$avg = db_fetch_cell('SELECT AVG(average)' . $query);
$result = db_fetch_assoc("SELECT $columns $query");
Expand Down Expand Up @@ -445,9 +445,9 @@ function busiest_hdd($panel, $user_id) {
WHERE h.disabled != 'on'
$q_host_cond
AND dsh.rrd_name = 'hdd_used'
AND dtd.data_template_id = " . $ds['id'] . '
AND dtd.data_template_id = " . (int) $ds['id'] . '
ORDER BY xvalue DESC
LIMIT ' . $lines;
LIMIT ' . (int) $lines;

$result = db_fetch_assoc("SELECT $columns $query");

Expand All @@ -461,7 +461,7 @@ function busiest_hdd($panel, $user_id) {
ON dl.id = dtd.local_data_id
WHERE dsh.rrd_name = 'hdd_used'
$q_host_cond
AND dtd.data_template_id = " . $ds['id'];
AND dtd.data_template_id = " . (int) $ds['id'];

$xavg = db_fetch_assoc('SELECT ' . $columns . ' ' . $query);
$avg = 0;
Expand Down Expand Up @@ -561,7 +561,7 @@ function busiest_uptime($panel, $user_id) {
WHERE disabled != 'on'
$q_host_cond
ORDER BY snmp_sysUpTimeInstance DESC
LIMIT " . $lines;
LIMIT " . (int) $lines;

$avg = db_fetch_cell('SELECT AVG(snmp_sysUpTimeInstance)' . $query);
$result = db_fetch_assoc("SELECT $columns $query");
Expand Down Expand Up @@ -656,10 +656,10 @@ function busiest_traffic($panel, $user_id) {
LEFT JOIN host as h on h.id = dl.host_id
WHERE h.disabled != 'on'
$q_host_cond
AND dtd.data_template_id = " . $ds['id'] . "
AND dtd.data_template_id = " . (int) $ds['id'] . "
AND rrd_name = 'traffic_out'
ORDER BY xvalue DESC
LIMIT " . $lines;
LIMIT " . (int) $lines;

$result = db_fetch_assoc("SELECT $columns $query");

Expand All @@ -668,7 +668,7 @@ function busiest_traffic($panel, $user_id) {
peak + (SELECT peak FROM data_source_stats_hourly WHERE local_data_id = ldid AND rrd_name='traffic_in') AS xpeak ";

$query = ' FROM data_template_data AS dtd LEFT JOIN data_source_stats_hourly AS dsh ON dtd.local_data_id = dsh.local_data_id
WHERE dtd.data_template_id = ' . $ds['id'] . '
WHERE dtd.data_template_id = ' . (int) $ds['id'] . '
AND rrd_name=\'traffic_out\' ';

$xavg = db_fetch_assoc('SELECT ' . $columns . ' ' . $query);
Expand Down Expand Up @@ -787,17 +787,17 @@ function busiest_interface_error($panel, $user_id) {
LEFT JOIN host as h on h.id = dl.host_id
WHERE h.disabled != 'on'
$q_host_cond
AND dtd.data_template_id = " . $ds['id'] . '
AND dtd.data_template_id = " . (int) $ds['id'] . '
AND dsh.average IS NOT NULL
ORDER BY dsh.average DESC
LIMIT ' . $lines;
LIMIT ' . (int) $lines;

$result = db_fetch_assoc("SELECT $columns $query");

$query = ' FROM data_template_data AS dtd
LEFT JOIN data_source_stats_hourly AS dsh
ON dtd.local_data_id = dsh.local_data_id
WHERE dtd.data_template_id = ' . $ds['id'] . '
WHERE dtd.data_template_id = ' . (int) $ds['id'] . '
AND dsh.average IS NOT NULL';

$avg = db_fetch_cell('SELECT AVG(average)' . $query);
Expand Down Expand Up @@ -907,7 +907,7 @@ function busiest_interface_util($panel, $user_id) {
LEFT JOIN host as h on h.id = dl.host_id
WHERE h.disabled != 'on'
$q_host_cond
AND dtd.data_template_id = " . $ds['id'] . '
AND dtd.data_template_id = " . (int) $ds['id'] . '
AND value > 0
AND time > DATE_SUB(NOW(), INTERVAL 5 MINUTE)
ORDER BY value DESC');
Expand Down Expand Up @@ -1031,7 +1031,7 @@ function busiest_cpu_detail() {
WHERE h.disabled != 'on'
$q_host_cond
AND dsh.average IS NOT NULL
AND dtd.data_template_id = " . $ds['id'] . '
AND dtd.data_template_id = " . (int) $ds['id'] . '
ORDER BY dsh.average DESC
LIMIT 30';

Expand Down Expand Up @@ -1144,7 +1144,7 @@ function busiest_load_detail() {
WHERE h.disabled != 'on'
$q_host_cond
AND dsh.average IS NOT NULL
AND dtd.data_template_id = " . $ds['id'] . '
AND dtd.data_template_id = " . (int) $ds['id'] . '
ORDER BY dsh.average DESC
LIMIT 30';

Expand Down Expand Up @@ -1259,7 +1259,7 @@ function busiest_hdd_detail() {
WHERE h.disabled != 'on'
$q_host_cond
AND dsh.rrd_name = 'hdd_used'
AND dtd.data_template_id = " . $ds['id'] . '
AND dtd.data_template_id = " . (int) $ds['id'] . '
ORDER BY xvalue DESC
LIMIT 30';

Expand All @@ -1275,7 +1275,7 @@ function busiest_hdd_detail() {
ON dl.id=dtd.local_data_id
WHERE dsh.rrd_name = 'hdd_used'
$q_host_cond
AND dtd.data_template_id = " . $ds['id'];
AND dtd.data_template_id = " . (int) $ds['id'];

$xavg = db_fetch_assoc('SELECT ' . $columns . ' ' . $query);
$avg = 0;
Expand Down Expand Up @@ -1469,7 +1469,7 @@ function busiest_traffic_detail() {
LEFT JOIN host as h on h.id = dl.host_id
WHERE h.disabled != 'on'
$q_host_cond
AND dtd.data_template_id = " . $ds['id'] . "
AND dtd.data_template_id = " . (int) $ds['id'] . "
AND rrd_name = 'traffic_out'
ORDER BY xvalue DESC
LIMIT 30";
Expand All @@ -1482,7 +1482,7 @@ function busiest_traffic_detail() {
$query = ' FROM data_template_data AS dtd
LEFT JOIN data_source_stats_hourly AS dsh
ON dtd.local_data_id = dsh.local_data_id
WHERE dtd.data_template_id = ' . $ds['id'] . '
WHERE dtd.data_template_id = ' . (int) $ds['id'] . '
AND rrd_name = \'traffic_out\' ';

$xavg = db_fetch_assoc('SELECT ' . $columns . ' ' . $query);
Expand Down Expand Up @@ -1604,7 +1604,7 @@ function busiest_interface_error_detail() {
LEFT JOIN host as h on h.id = dl.host_id
WHERE h.disabled != 'on'
$q_host_cond
AND dtd.data_template_id = " . $ds['id'] . '
AND dtd.data_template_id = " . (int) $ds['id'] . '
AND dsh.average IS NOT NULL
ORDER BY dsh.average DESC
LIMIT 30';
Expand All @@ -1614,7 +1614,7 @@ function busiest_interface_error_detail() {
$query = ' FROM data_template_data AS dtd
LEFT JOIN data_source_stats_hourly AS dsh
ON dtd.local_data_id = dsh.local_data_id
WHERE dtd.data_template_id = ' . $ds['id'] . '
WHERE dtd.data_template_id = ' . (int) $ds['id'] . '
AND dsh.average IS NOT NULL';

$avg = db_fetch_cell('SELECT AVG(average)' . $query);
Expand Down Expand Up @@ -1727,7 +1727,7 @@ function busiest_interface_util_detail() {
LEFT JOIN host as h on h.id = dl.host_id
WHERE h.disabled != 'on'
$q_host_cond
AND dtd.data_template_id = " . $ds['id'] . '
AND dtd.data_template_id = " . (int) $ds['id'] . '
AND value > 0
AND time > date_sub(now(), INTERVAL 5 MINUTE)
ORDER BY value DESC');
Expand Down
10 changes: 10 additions & 0 deletions tests/Pest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/

require_once __DIR__ . '/bootstrap.php';
Loading
Loading