From 0172a197518358e2930bc8b6213edfe2d35efe75 Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Mon, 20 Mar 2017 12:53:38 +0545 Subject: Redmine 7182 Allow multiple copies of widgets on dashboard --- src/usr/local/www/index.php | 155 ++++-- .../www/widgets/javascript/thermal_sensors.js | 81 ++- .../widgets/captive_portal_status.widget.php | 8 +- .../www/widgets/widgets/dyn_dns_status.widget.php | 88 +-- .../local/www/widgets/widgets/gateways.widget.php | 306 +++++----- .../www/widgets/widgets/gmirror_status.widget.php | 4 +- .../widgets/widgets/installed_packages.widget.php | 4 +- .../widgets/interface_statistics.widget.php | 30 +- .../www/widgets/widgets/interfaces.widget.php | 17 +- src/usr/local/www/widgets/widgets/ipsec.widget.php | 22 +- src/usr/local/www/widgets/widgets/log.widget.php | 52 +- .../www/widgets/widgets/ntp_status.widget.php | 11 +- .../local/www/widgets/widgets/openvpn.widget.php | 615 +++++++++++---------- .../local/www/widgets/widgets/picture.widget.php | 21 +- src/usr/local/www/widgets/widgets/rss.widget.php | 47 +- .../www/widgets/widgets/services_status.widget.php | 17 +- .../www/widgets/widgets/smart_status.widget.php | 15 +- .../widgets/widgets/system_information.widget.php | 80 +-- .../www/widgets/widgets/thermal_sensors.widget.php | 163 +++--- .../www/widgets/widgets/wake_on_lan.widget.php | 23 +- 20 files changed, 944 insertions(+), 815 deletions(-) (limited to 'src/usr') diff --git a/src/usr/local/www/index.php b/src/usr/local/www/index.php index 2b74a9e..e4ac5c2 100644 --- a/src/usr/local/www/index.php +++ b/src/usr/local/www/index.php @@ -108,16 +108,16 @@ foreach ($phpincludefiles as $includename) { ##build list of widgets foreach (glob("/usr/local/www/widgets/widgets/*.widget.php") as $file) { - $name = basename($file, '.widget.php'); + $basename = basename($file, '.widget.php'); // Get the widget title that should be in a var defined in the widget's inc file. - $widgettitle = ${$name . '_title'}; + $widgettitle = ${$basename . '_title'}; if (empty(trim($widgettitle))) { // Fall back to constructing a title from the file name of the widget. - $widgettitle = ucwords(str_replace('_', ' ', $name)); + $widgettitle = ucwords(str_replace('_', ' ', $basename)); } - $widgets[ $name ] = array('name' => $widgettitle, 'display' => 'none'); + $known_widgets[$basename . '-0'] = array('basename' => $basename, 'title' => $widgettitle, 'display' => 'none'); } ##if no config entry found, initialize config entry @@ -133,11 +133,54 @@ if ($_POST && $_POST['sequence']) { // Start with the user's widget settings. $widget_settings = $user_settings['widgets']; - $widget_settings['sequence'] = rtrim($_POST['sequence'], ','); + $widget_sep = ','; + $widget_seq_array = explode($widget_sep, rtrim($_POST['sequence'], $widget_sep)); + $widget_counter_array = array(); + $widget_sep = ''; - foreach ($widgets as $widgetname => $widgetconfig) { - if ($_POST[$widgetname . '-config']) { - $widget_settings[$widgetname . '-config'] = $_POST[$widgetname . '-config']; + // Make a record of the counter of each widget that is in use. + foreach ($widget_seq_array as $widget_seq_data) { + list($basename, $col, $display, $widget_counter) = explode(':', $widget_seq_data); + + if ($widget_counter != 'next') { + $widget_counter_array[$basename][$widget_counter] = true; + $widget_sequence .= $widget_sep . $widget_seq_data; + $widget_sep = ','; + } + } + + // Find any new entry (and do not assume there is only 1 new entry) + foreach ($widget_seq_array as $widget_seq_data) { + list($basename, $col, $display, $widget_counter) = explode(':', $widget_seq_data); + + if ($widget_counter == 'next') { + // Construct the widget counter of the new widget instance by finding + // the first non-negative integer that is not in use. + // The reasoning here is that if you just deleted a widget instance, + // e.g. had System Information 0,1,2 and deleted 1, + // then when you add System Information again it will become instance 1, + // which will bring back whatever filter selections happened to be on + // the previous instance 1. + $instance_num = 0; + + while (isset($widget_counter_array[$basename][$instance_num])) { + $instance_num++; + } + + $widget_sequence .= $widget_sep . $basename . ':' . $col . ':' . $display . ':' . $instance_num; + $widget_counter_array[$basename][$instance_num] = true; + $widget_sep = ','; + } + } + + $widget_settings['sequence'] = $widget_sequence; + + foreach ($widget_counter_array as $basename => $instances) { + foreach ($instances as $instance => $value) { + $widgetconfigname = $basename . '-' . $instance . '-config'; + if ($_POST[$widgetconfigname]) { + $widget_settings[$widgetconfigname] = $_POST[$widgetconfigname]; + } } } @@ -230,13 +273,20 @@ if ($user_settings['widgets']['sequence'] != "") { $widgetsfromconfig = array(); foreach (explode(',', $pconfig['sequence']) as $line) { - list($file, $col, $display) = explode(':', $line); + $line_items = explode(':', $line); + if (count($line_items) == 3) { + // There can be multiple copies of a widget on the dashboard. + // Default the copy number if it is not present (e.g. from old configs) + $line_items[] = 0; + } + + list($basename, $col, $display, $copynum) = $line_items; // be backwards compatible // If the display column information is missing, we will assign a temporary // column here. Next time the user saves the dashboard it will fix itself if ($col == "") { - if ($file == "system_information") { + if ($basename == "system_information") { $col = "col1"; } else { $col = "col2"; @@ -248,28 +298,32 @@ if ($user_settings['widgets']['sequence'] != "") { $col = "col" . $dashboardcolumns; } - $offset = strpos($file, '-container'); + $offset = strpos($basename, '-container'); if (false !== $offset) { - $file = substr($file, 0, $offset); + $basename = substr($basename, 0, $offset); } // Get the widget title that should be in a var defined in the widget's inc file. - $widgettitle = ${$file . '_title'}; + $widgettitle = ${$basename . '_title'}; if (empty(trim($widgettitle))) { // Fall back to constructing a title from the file name of the widget. - $widgettitle = ucwords(str_replace('_', ' ', $file)); + $widgettitle = ucwords(str_replace('_', ' ', $basename)); } - $widgetsfromconfig[ $file ] = array( - 'name' => $widgettitle, + $widgetkey = $basename . '-' . $copynum; + + $widgetsfromconfig[$widgetkey] = array( + 'basename' => $basename, + 'title' => $widgettitle, 'col' => $col, 'display' => $display, + 'copynum' => $copynum, ); } // add widgets that may not be in the saved configuration, in case they are to be displayed later - $widgets = $widgetsfromconfig + $widgets; + $widgets = $widgetsfromconfig + $known_widgets; ##find custom configurations of a particular widget and load its info to $pconfig foreach ($widgets as $widgetname => $widgetconfig) { @@ -317,15 +371,13 @@ pfSense_handle_custom_code("/usr/local/pkg/dashboard/pre_dashboard");
$widgetconfig): - if ($widgetconfig['display'] == 'none'): +foreach ($available as $widgetkey => $widgetconfig): ?> - - +
@@ -340,20 +392,20 @@ foreach ($available as $widgetname => $widgetconfig): $widgetconfig) { +foreach ($widgets as $widgetkey => $widgetconfig) { if ($widgetconfig['display'] == 'none') { continue; } - if (!file_exists('/usr/local/www/widgets/widgets/'. $widgetname.'.widget.php')) { + if (!file_exists('/usr/local/www/widgets/widgets/'. $widgetconfig['basename'].'.widget.php')) { continue; } - if (!isset($widgetColumns[ $widgetconfig['col'] ])) { - $widgetColumns[ $widgetconfig['col'] ] = array(); + if (!isset($widgetColumns[$widgetconfig['col']])) { + $widgetColumns[$widgetconfig['col']] = array(); } - $widgetColumns[ $widgetconfig['col'] ][ $widgetname ] = $widgetconfig; + $widgetColumns[$widgetconfig['col']][$widgetkey] = $widgetconfig; } ?> @@ -369,36 +421,55 @@ foreach ($widgets as $widgetname => $widgetconfig) { echo '
'; $columnWidgets = $widgetColumns['col'.$currentColumnNumber]; - foreach ($columnWidgets as $widgetname => $widgetconfig) { + foreach ($columnWidgets as $widgetkey => $widgetconfig) { + // Construct some standard names for the ids this widget will use for its commonly-used elements. + // Included widget.php code can rely on and use these, so the format does not have to be repeated in every widget.php + $widget_panel_body_id = 'widget-' . $widgetkey . '_panel-body'; + $widget_panel_footer_id = 'widget-' . $widgetkey . '_panel-footer'; + $widget_showallnone_id = 'widget-' . $widgetkey . '_showallnone'; + // Compose the widget title and include the title link if available - $widgetlink = ${$widgetname . '_title_link'}; + $widgetlink = ${$widgetconfig['basename'] . '_title_link'}; if ((strlen($widgetlink) > 0)) { - $wtitle = ' ' . $widgetconfig['name'] . ''; + $wtitle = ' ' . $widgetconfig['title'] . ''; } else { - $wtitle = $widgetconfig['name']; + $wtitle = $widgetconfig['title']; } ?> -
+
-
- +
+
Temperature data could not be read.'); + buildThermalSensorsDataRaw('Temperature data could not be read.', widgetKey); } }); ajaxBusy = false; } //call itself in 11 seconds - window.setTimeout(showThermalSensorsData, 11000); + window.setTimeout(function(){showThermalSensorsData(widgetKey, tsParams, firstTime);}, 11000); } -function buildThermalSensorsData(thermalSensorsData) { - //NOTE: variable thermal_sensors_widget_showRawOutput is declared/set in "thermal_sensors.widget.php" - if (thermal_sensors_widget_showRawOutput) { - buildThermalSensorsDataRaw(thermalSensorsData); +function buildThermalSensorsData(thermalSensorsData, widgetKey, tsParams, firstTime) { + if (tsParams.showRawOutput) { + buildThermalSensorsDataRaw(thermalSensorsData, widgetKey); } else { - if (warningTemp == 9999) { - buildThermalSensorsDataGraph(thermalSensorsData); + if (firstTime) { + buildThermalSensorsDataGraph(thermalSensorsData, tsParams, widgetKey); } - updateThermalSensorsDataGraph(thermalSensorsData); + updateThermalSensorsDataGraph(thermalSensorsData, tsParams, widgetKey); } } -function buildThermalSensorsDataRaw(thermalSensorsData) { +function buildThermalSensorsDataRaw(thermalSensorsData, widgetKey) { var thermalSensorsContent = ""; @@ -71,20 +72,20 @@ function buildThermalSensorsDataRaw(thermalSensorsData) { //rawData = thermalSensorsData.split("|").join("
"); } - loadThermalSensorsContainer(thermalSensorsContent); + loadThermalSensorsContainer(thermalSensorsContent, widgetKey); } -function loadThermalSensorsContainer (thermalSensorsContent) { +function loadThermalSensorsContainer (thermalSensorsContent, widgetKey) { if (thermalSensorsContent && thermalSensorsContent != "") { //load generated graph (or raw data) into thermalSensorsContainer (thermalSensorsContainer DIV defined in "thermal_sensors.widget.php") - $('#thermalSensorsContainer').html(thermalSensorsContent); + $('#thermalSensorsContainer-' + widgetKey).html(thermalSensorsContent); } else { - $('#thermalSensorsContainer').html("No Thermal Sensors data available."); + $('#thermalSensorsContainer-' + widgetKey).html("No Thermal Sensors data available."); } } -function buildThermalSensorsDataGraph(thermalSensorsData) { +function buildThermalSensorsDataGraph(thermalSensorsData, tsParams, widgetKey) { var thermalSensorsArray = new Array(); @@ -103,26 +104,25 @@ function buildThermalSensorsDataGraph(thermalSensorsData) { //set thresholds if (sensorName.indexOf("cpu") > -1) { //check CPU Threshold config settings - warningTemp = thermal_sensors_widget_coreWarningTempThreshold; - criticalTemp = thermal_sensors_widget_coreCriticalTempThreshold; + warningTemp = tsParams.coreWarningTempThreshold; + criticalTemp = tsParams.coreCriticalTempThreshold; } else { //assuming sensor is for a zone, check Zone Threshold config settings - warningTemp = thermal_sensors_widget_zoneWarningTempThreshold; - criticalTemp = thermal_sensors_widget_zoneCriticalTempThreshold; + warningTemp = tsParams.zoneWarningTempThreshold; + criticalTemp = tsParams.zoneCriticalTempThreshold; } - //NOTE: variable thermal_sensors_widget_showFullSensorName is declared/set in "thermal_sensors.widget.php" - if (!thermal_sensors_widget_showFullSensorName) { + if (!tsParams.showFullSensorName) { sensorName = getSensorFriendlyName(sensorName); } //build temperature item/row for a sensor var thermalSensorRow = '
' + - '
' + - '
' + - '
' + + '
' + + '
' + + '
' + '
' + - '' + sensorName + ': ' + '' + thermalSensorValue + ' °C'; + '' + sensorName + ': ' + '' + thermalSensorValue + ' °C'; thermalSensorsHTMLContent = thermalSensorsHTMLContent + thermalSensorRow; @@ -130,12 +130,12 @@ function buildThermalSensorsDataGraph(thermalSensorsData) { } //load generated graph into thermalSensorsContainer (DIV defined in "thermal_sensors.widget.php") - loadThermalSensorsContainer(thermalSensorsHTMLContent); + loadThermalSensorsContainer(thermalSensorsHTMLContent, widgetKey); } -function updateThermalSensorsDataGraph(thermalSensorsData) { +function updateThermalSensorsDataGraph(thermalSensorsData, tsParams, widgetKey) { var thermalSensorsArray = new Array(); if (thermalSensorsData && thermalSensorsData != "") { @@ -152,19 +152,18 @@ function updateThermalSensorsDataGraph(thermalSensorsData) { //set thresholds if (sensorName.indexOf("cpu") > -1) { //check CPU Threshold config settings - warningTemp = thermal_sensors_widget_coreWarningTempThreshold; - criticalTemp = thermal_sensors_widget_coreCriticalTempThreshold; + warningTemp = tsParams.coreWarningTempThreshold; + criticalTemp = tsParams.coreCriticalTempThreshold; } else { //assuming sensor is for a zone, check Zone Threshold config settings - warningTemp = thermal_sensors_widget_zoneWarningTempThreshold; - criticalTemp = thermal_sensors_widget_zoneCriticalTempThreshold; + warningTemp = tsParams.zoneWarningTempThreshold; + criticalTemp = tsParams.zoneCriticalTempThreshold; } - //NOTE: variable thermal_sensors_widget_showFullSensorName is declared/set in "thermal_sensors.widget.php" - if (!thermal_sensors_widget_showFullSensorName) { + if (!tsParams.showFullSensorName) { sensorName = getSensorFriendlyName(sensorName); } - setTempProgress(i, thermalSensorValue); + setTempProgress(i, thermalSensorValue, widgetKey); } } @@ -189,7 +188,7 @@ function getThermalSensorValue(stringValue) { // Update the progress indicator // transition = true allows the bar to move at default speed, false = instantaneous -function setTempProgress(bar, percent) { +function setTempProgress(bar, percent, widgetKey) { var barTempL, barTempM, barTempH; if (percent <= warningTemp) { @@ -207,9 +206,9 @@ function setTempProgress(bar, percent) { } - $('#' + 'temperaturebarL' + bar).css('width', barTempL + '%').attr('aria-valuenow', barTempL); - $('#' + 'temperaturebarM' + bar).css('width', barTempM + '%').attr('aria-valuenow', barTempM); - $('#' + 'temperaturebarH' + bar).css('width', barTempH + '%').attr('aria-valuenow', barTempH); + $('#' + 'temperaturebarL' + bar + widgetKey).css('width', barTempL + '%').attr('aria-valuenow', barTempL); + $('#' + 'temperaturebarM' + bar + widgetKey).css('width', barTempM + '%').attr('aria-valuenow', barTempM); + $('#' + 'temperaturebarH' + bar + widgetKey).css('width', barTempH + '%').attr('aria-valuenow', barTempH); - $('#' + 'temperaturemsg' + bar).html(percent + ' °C'); + $('#' + 'temperaturemsg' + bar + widgetKey).html(percent + ' °C'); } diff --git a/src/usr/local/www/widgets/widgets/captive_portal_status.widget.php b/src/usr/local/www/widgets/widgets/captive_portal_status.widget.php index 65c8b4a..725ca60 100644 --- a/src/usr/local/www/widgets/widgets/captive_portal_status.widget.php +++ b/src/usr/local/www/widgets/widgets/captive_portal_status.widget.php @@ -54,9 +54,11 @@ unset($cpzone); flush(); -function clientcmp($a, $b) { - global $order; - return strcmp($a[$order], $b[$order]); +if (!function_exists('clientcmp')) { + function clientcmp($a, $b) { + global $order; + return strcmp($a[$order], $b[$order]); + } } $cpdb_all = array(); diff --git a/src/usr/local/www/widgets/widgets/dyn_dns_status.widget.php b/src/usr/local/www/widgets/widgets/dyn_dns_status.widget.php index 1776dbb..c5dfd98 100644 --- a/src/usr/local/www/widgets/widgets/dyn_dns_status.widget.php +++ b/src/usr/local/www/widgets/widgets/dyn_dns_status.widget.php @@ -29,17 +29,21 @@ require_once("functions.inc"); require_once("/usr/local/www/widgets/include/dyn_dns_status.inc"); // Constructs a unique key that will identify a Dynamic DNS entry in the filter list. -function get_dyndnsent_key($dyndns) { - return $dyndns['id']; +if (!function_exists('get_dyndnsent_key')) { + function get_dyndnsent_key($dyndns) { + return $dyndns['id']; + } } -function get_dyndns_hostname_text($dyndns) { - global $dyndns_split_domain_types; - if (in_array($dyndns['type'], $dyndns_split_domain_types)) { - return $dyndns['host'] . "." . $dyndns['domainname']; - } +if (!function_exists('get_dyndns_hostname_text')) { + function get_dyndns_hostname_text($dyndns) { + global $dyndns_split_domain_types; + if (in_array($dyndns['type'], $dyndns_split_domain_types)) { + return $dyndns['host'] . "." . $dyndns['domainname']; + } - return $dyndns['host']; + return $dyndns['host']; + } } if (!is_array($config['dyndnses']['dyndns'])) { @@ -64,9 +68,8 @@ array_walk($all_dyndns, function(&$dyndns) { } }); -$skipdyndns = explode(",", $user_settings['widgets']['dyn_dns_status']['filter']); - if ($_REQUEST['getdyndnsstatus']) { + $skipdyndns = explode(",", $user_settings['widgets'][$_REQUEST['getdyndnsstatus']]['filter']); $first_entry = true; foreach ($all_dyndns as $dyndns) { if (in_array(get_dyndnsent_key($dyndns), $skipdyndns)) { @@ -114,7 +117,7 @@ if ($_REQUEST['getdyndnsstatus']) { } } exit; -} else if ($_POST) { +} else if ($_POST['widgetkey']) { $validNames = array(); @@ -123,9 +126,9 @@ if ($_REQUEST['getdyndnsstatus']) { } if (is_array($_POST['show'])) { - $user_settings['widgets']['dyn_dns_status']['filter'] = implode(',', array_diff($validNames, $_POST['show'])); + $user_settings['widgets'][$_POST['widgetkey']]['filter'] = implode(',', array_diff($validNames, $_POST['show'])); } else { - $user_settings['widgets']['dyn_dns_status']['filter'] = implode(',', $validNames); + $user_settings['widgets'][$_POST['widgetkey']]['filter'] = implode(',', $validNames); } save_widget_settings($_SESSION['Username'], $user_settings["widgets"], gettext("Saved Dynamic DNS Filter via Dashboard.")); @@ -134,28 +137,34 @@ if ($_REQUEST['getdyndnsstatus']) { $iflist = get_configured_interface_with_descr(); -function get_dyndns_interface_text($dyndns_iface) { - global $iflist; - if (isset($iflist[$dyndns_iface])) { - return $iflist[$dyndns_iface]; - } +if (!function_exists('get_dyndns_interface_text')) { + function get_dyndns_interface_text($dyndns_iface) { + global $iflist; + if (isset($iflist[$dyndns_iface])) { + return $iflist[$dyndns_iface]; + } - // This will be a gateway group name. - return $dyndns_iface; + // This will be a gateway group name. + return $dyndns_iface; + } } $dyndns_providers = array_combine(explode(" ", DYNDNS_PROVIDER_VALUES), explode(",", DYNDNS_PROVIDER_DESCRIPTIONS)); +$skipdyndns = explode(",", $user_settings['widgets'][$widgetkey]['filter']); +$widgetkey_nodash = str_replace("-", "", $widgetkey); -function get_dyndns_service_text($dyndns_type) { - global $dyndns_providers; +if (!function_exists('get_dyndns_service_text')) { + function get_dyndns_service_text($dyndns_type) { + global $dyndns_providers; - if (isset($dyndns_providers[$dyndns_type])) { - return $dyndns_providers[$dyndns_type]; - } else if ($dyndns_type == '_rfc2136_') { - return "RFC 2136"; - } + if (isset($dyndns_providers[$dyndns_type])) { + return $dyndns_providers[$dyndns_type]; + } else if ($dyndns_type == '_rfc2136_') { + return "RFC 2136"; + } - return $dyndns_type; + return $dyndns_type; + } } ?> @@ -215,11 +224,12 @@ function get_dyndns_service_text($dyndns_type) {
-