Files
TheWitnessandTheWitness 1e226aa6c5 security: move filter inline onChange/onClick handlers into ready() for CSP (#849)
* security: move filter inline onChange/onClick handlers into ready() for CSP

The threshold, notification list, notification queue, template and
device/log status filter forms still carried inline onChange/onClick
attributes on their selects and Clear/Go/Import/Export controls. Under
Cacti's Content-Security-Policy these trip the script-src-attr directive
(inline event handlers). Bind them in each view's existing
$(function(){...}) ready block instead.

Scope: thold.php, notify_queue.php, thold_templates.php, notify_lists.php,
thold_graph.php (all gate-allowlisted UI files; no measured source changed).
The cactiReturnTo() cancel buttons on the bulk-action confirmation pages are
left as-is (shared Cacti-core pattern). Regenerated locales/po/cacti.pot for
the shifted source line references.

* security: convert cactiReturnTo cancel buttons to the CSP-safe class

The confirmation pages' Cancel buttons used an inline
onClick='cactiReturnTo()' handler, which trips Cacti's Content-Security-Policy
script-src-attr directive. Switch them to the CSP-safe cactiReturnTo CSS
class (class='cactiReturnTo', plus an optional data-url when a target is
passed).

Cacti 1.2.31 and later bind this class automatically. The README documents a
one-time include/layout.js applySkin() snippet for operators still on an
earlier release - no shim is baked into the core or the plugin.

* fix: give Thresholds/Devices filter Clear buttons the id the ready() handler binds

The hosts() and tholds() filter views used name='clear' on the Clear button, but the ready() handler binds to #clear, so Clear was a no-op on those two views. Switch them to id='clear' to match the other views and the handler.

---------

Co-authored-by: TheWitness <larry@thewitness.org>
2026-10-07 21:00:03 -04:00

2509 lines
87 KiB
PHP

<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDTool-based Graphing Solution |
+-------------------------------------------------------------------------+
| This code is designed, written, and maintained by the Cacti Group. See |
| about.php and/or the AUTHORS file for specific developer information. |
+-------------------------------------------------------------------------+
| http://www.cacti.net/ |
+-------------------------------------------------------------------------+
*/
chdir('../..');
include('./include/auth.php');
include_once($config['base_path'] . '/lib/reports.php');
include_once($config['base_path'] . '/plugins/thold/includes/functions.php');
include($config['base_path'] . '/plugins/thold/includes/arrays.php');
$actions = [
1 => __('Delete', 'thold'),
2 => __('Duplicate', 'thold')
];
$assoc_actions = [
1 => __('Associate', 'thold'),
2 => __('Disassociate', 'thold')
];
// present a tabbed interface
$tabs_thold = [
'general' => __('General', 'thold'),
'hosts' => __('Devices', 'thold'),
'tholds' => __('Thresholds', 'thold'),
'templates' => __('Templates', 'thold')
];
$tabs_thold = api_plugin_hook_function('notify_list_tabs', $tabs_thold);
set_default_action();
switch (get_request_var('action')) {
case 'save':
form_save();
break;
case 'actions':
form_actions();
break;
case 'edit':
top_header();
edit();
bottom_footer();
break;
default:
top_header();
lists();
bottom_footer();
break;
}
/* --------------------------
The Save Function
-------------------------- */
/**
* Validates and saves the notification list edit form's submitted
* fields, rejecting the save if the same email address appears in both
* the To and BCC lists, then redirects back to the edit form for the
* saved (or original) list id. Called from this script's main
* request-dispatch switch when action=save.
*
* @return void
*/
function form_save() {
if (isset_request_var('save_component')) {
$save['id'] = get_filter_request_var('id');
$save['name'] = form_input_validate(get_nfilter_request_var('name'), 'name', '', false, 3);
$save['enabled'] = isset_request_var('enabled') ? 'on' : '';
$save['description'] = form_input_validate(get_nfilter_request_var('description'), 'description', '', false, 3);
$save['emails'] = form_input_validate(get_nfilter_request_var('emails'), 'emails', '', true, 3);
$save['bcc_emails'] = form_input_validate(get_nfilter_request_var('bcc_emails'), 'bcc_emails', '', true, 3);
$save['format_file'] = form_input_validate(get_nfilter_request_var('format_file'), 'format_file', '', true, 3);
$bccs = explode(',', $save['bcc_emails']);
$emails = explode(',', $save['emails']);
$bad = false;
foreach ($bccs as $email) {
if (array_search(trim($email), $emails, true) !== false) {
raise_message(
'duplicate_email',
__('ERROR: You can not have your Email in both the To and BCC lines. The Email below is invalid!<br><br>%s', $email, 'THOLD'),
MESSAGE_LEVEL_WARN
);
$_SESSION['sess_error_fields']['bcc_emails'] = 'bcc_emails';
$bad = true;
break;
}
}
if (!$bad) {
foreach ($emails as $email) {
if (array_search(trim($email), $bccs, true) !== false) {
raise_message(
'duplicate_email',
__('ERROR: You can not have your Email in both the To and BCC lines. The Email below is invalid!<br><br>%s', $email, 'THOLD'),
MESSAGE_LEVEL_WARN
);
$_SESSION['sess_error_fields']['bcc_emails'] = 'bcc_emails';
$bad = true;
break;
}
}
}
if (!is_error_message()) {
$id = sql_save($save, 'plugin_notification_lists');
if ($id) {
raise_message(1);
} else {
raise_message(2);
}
}
}
header('Location: notify_lists.php?header=false&action=edit&id=' . (empty($id) ? get_request_var('id') : $id));
}
/* ------------------------
The 'actions' function
------------------------ */
/**
* Handles the bulk-action confirmation page/submission for the
* notification lists view and its host/threshold/template association
* sub-views, validating the requested action against the combined set
* of list-level and association-level allowed actions before
* dispatching. Called from this script's main request-dispatch switch
* when action=actions.
*
* @return void
*
* @global array $actions Map of drp_action value => action label
* for list-level bulk actions.
* @global array $assoc_actions Map of drp_action value => action label
* for host/threshold/template association
* bulk actions.
*/
function form_actions() {
global $actions, $assoc_actions;
// ================= input validation =================
/*
* get_filter_request_var() stores the value as an int, so the comparison
* has to be made on strings for the strict check to mean anything.
*/
get_filter_request_var('drp_action');
$valid_actions = array_map('strval', array_keys($actions + $assoc_actions));
if (!in_array((string) get_request_var('drp_action'), $valid_actions, true)) {
raise_message(40);
header('Location: notify_lists.php?header=false');
exit;
}
// ====================================================
// if we are to save this form, instead of display it
if (isset_request_var('selected_items')) {
$selected_items = sanitize_unserialize_selected_items(get_nfilter_request_var('selected_items'));
if (isset_request_var('save_list')) {
if ($selected_items != false) {
if (get_request_var('drp_action') == '1') { // delete
/*
* Bind positionally on the values: sanitize_unserialize_selected_items()
* preserves the submitted array's keys, and a string key would be read
* as a named parameter.
*/
$ids = array_map('intval', array_values($selected_items));
$placeholders = implode(', ', array_fill(0, cacti_sizeof($ids), '?'));
/*
* Issued as SQL rather than through db_begin_transaction() and
* friends: Cacti's db_commit_transaction() gates the commit on
* SELECT @@in_transaction, which only MariaDB defines. On MySQL that
* query fails, the commit is skipped, and every write here is
* discarded when the connection closes.
*/
db_execute('START TRANSACTION');
/*
* The host reset deliberately omits the deleted = "" predicate its
* siblings carry: a soft-deleted device that is later restored must
* not come back pointing at a list that no longer exists.
*/
$statements = [
'DELETE FROM plugin_notification_lists WHERE id IN (' . $placeholders . ')',
'UPDATE host SET thold_send_email = 0 WHERE thold_send_email = 2 AND deleted = "" AND thold_host_email IN (' . $placeholders . ')',
'UPDATE host SET thold_send_email = 1 WHERE thold_send_email = 3 AND deleted = "" AND thold_host_email IN (' . $placeholders . ')',
'UPDATE host SET thold_host_email = 0 WHERE thold_host_email IN (' . $placeholders . ')',
'UPDATE thold_data SET notify_warning = 0 WHERE notify_warning IN (' . $placeholders . ')',
'UPDATE thold_data SET notify_alert = 0 WHERE notify_alert IN (' . $placeholders . ')',
'UPDATE thold_template SET notify_warning = 0 WHERE notify_warning IN (' . $placeholders . ')',
'UPDATE thold_template SET notify_alert = 0 WHERE notify_alert IN (' . $placeholders . ')'
];
$ok = true;
foreach ($statements as $sql) {
if (!db_execute_prepared($sql, $ids)) {
$ok = false;
break;
}
}
if ($ok) {
db_execute('COMMIT');
} else {
db_execute('ROLLBACK');
}
} elseif (get_request_var('drp_action') == '2') { // duplicate
$i = 1;
foreach ($selected_items as $item) {
// get list to be duplicated
$list = db_fetch_row_prepared('SELECT *
FROM plugin_notification_lists
WHERE id = ?',
[$item]);
// see if there is already a list with the new name
$exists = db_fetch_cell_prepared('SELECT COUNT(*)
FROM plugin_notification_lists
WHERE name = ?',
[get_nfilter_request_var('name')]);
if ($exists > 0) {
$name = get_nfilter_request_var('name') . ' (' . $i . ')';
$i ++;
} else {
$name = get_nfilter_request_var('name');
}
$save['id'] = 0;
$save['name'] = $name;
$save['description'] = $list['description'];
$save['emails'] = $list['emails'];
$save['bcc_emails'] = $list['bcc_emails'];
$id = sql_save($save, 'plugin_notification_lists');
if ($id) {
raise_message(1);
} else {
raise_message(2);
}
}
}
}
header('Location: notify_lists.php?header=false');
exit;
}
if (isset_request_var('save_associate')) {
if ($selected_items != false) {
get_filter_request_var('id');
get_filter_request_var('notification_action');
get_filter_request_var('notification_warning_action');
get_filter_request_var('notification_alert_action');
db_execute('START TRANSACTION');
$ok = true;
if (get_request_var('drp_action') == '1') { // associate
for ($i = 0; ($i < cacti_sizeof($selected_items)); $i++) {
// set the notification list
$ok = db_execute_prepared('UPDATE host
SET thold_host_email = ?
WHERE id = ?
AND deleted = ""',
[get_request_var('id'), $selected_items[$i]]) && $ok;
// set the global/list election
$ok = db_execute_prepared('UPDATE host
SET thold_send_email = ?
WHERE id = ?
AND deleted = ""',
[get_request_var('notification_action'), $selected_items[$i]]) && $ok;
if (get_request_var('notification_warning_action') > 0) {
// clear other settings
if (get_request_var('notification_warning_action') == 1) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data AS td
LEFT JOIN thold_template AS tt
ON td.thold_template_id = tt.id
SET td.notify_warning = ?
WHERE td.host_id = ?
AND (tt.notify_templated = "" OR tt.notify_templated IS NULL)',
[get_request_var('id'), $selected_items[$i]]) && $ok;
// clear other items
$ok = db_execute_prepared('UPDATE thold_data AS td
LEFT JOIN thold_template AS tt
ON td.thold_template_id = tt.id
SET td.notify_warning_extra = \'\'
WHERE td.host_id = ?
AND (tt.notify_templated = "" OR tt.notify_templated IS NULL)',
[$selected_items[$i]]) && $ok;
} else {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data AS td
LEFT JOIN thold_template AS tt
ON td.thold_template_id = tt.id
SET td.notify_warning = ?
WHERE td.host_id = ?
AND (tt.notify_templated = "" OR tt.notify_templated IS NULL)',
[get_request_var('id'), $selected_items[$i]]) && $ok;
}
}
if (get_request_var('notification_alert_action') > 0) {
// clear other settings
if (get_request_var('notification_alert_action') == 1) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data AS td
LEFT JOIN thold_template AS tt
ON td.thold_template_id = tt.id
SET td.notify_alert = ?
WHERE td.host_id = ?
AND (tt.notify_templated = "" OR tt.notify_templated IS NULL)',
[get_request_var('id'), $selected_items[$i]]) && $ok;
// clear other items
$ok = db_execute_prepared('UPDATE thold_data AS td
LEFT JOIN thold_template AS tt
ON td.thold_template_id = tt.id
SET td.notify_extra = \'\'
WHERE host_id = ?
AND (tt.notify_templated = "" OR tt.notify_templated IS NULL)',
[$selected_items[$i]]) && $ok;
// remove legacy contacts
$ok = db_execute_prepared('DELETE pttc
FROM plugin_thold_threshold_contact AS pttc
INNER JOIN thold_data AS td
ON pttc.thold_id = td.id
LEFT JOIN thold_template AS tt
ON td.thold_template_id = tt.id
WHERE td.host_id = ?
AND (tt.notify_templated = "" OR tt.notify_templated IS NULL)',
[$selected_items[$i]]) && $ok;
} else {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data AS td
LEFT JOIN thold_template AS tt
ON td.thold_template_id = tt.id
SET td.notify_alert = ?
WHERE td.host_id = ?
AND (tt.notify_templated = "" OR tt.notify_templated IS NULL)',
[get_request_var('id'), $selected_items[$i]]) && $ok;
}
}
if (!$ok) {
break;
}
}
} elseif (get_request_var('drp_action') == '2') { // disassociate
for ($i = 0; ($i < cacti_sizeof($selected_items)); $i++) {
// set the notification list
$ok = db_execute_prepared('UPDATE host
SET thold_host_email = 0
WHERE id = ?
AND deleted = ""',
[$selected_items[$i]]) && $ok;
// set the global/list election
$ok = db_execute_prepared('UPDATE host
SET thold_send_email = ?
WHERE id = ?
AND deleted = ""',
[get_request_var('notification_action'), $selected_items[$i]]) && $ok;
if (get_request_var('notification_warning_action') > 0) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data AS td
LEFT JOIN thold_template AS tt
ON td.thold_template_id = tt.id
SET td.notify_warning = 0
WHERE td.host_id = ?
AND (tt.notify_templated = "" OR tt.notify_templated IS NULL)
AND td.notify_warning = ?',
[$selected_items[$i], get_request_var('id')]) && $ok;
}
if (get_request_var('notification_alert_action') > 0) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data AS td
LEFT JOIN thold_template AS tt
ON td.thold_template_id = tt.id
SET td.notify_alert = 0
WHERE td.host_id = ?
AND (tt.notify_templated = "" OR tt.notify_templated IS NULL)
AND td.notify_alert = ?',
[$selected_items[$i], get_request_var('id')]) && $ok;
}
if (!$ok) {
break;
}
}
}
if ($ok) {
db_execute('COMMIT');
} else {
db_execute('ROLLBACK');
}
}
header('Location: notify_lists.php?header=false&action=edit&tab=hosts&id=' . get_request_var('id'));
exit;
}
if (isset_request_var('save_templates')) {
if ($selected_items != false) {
get_filter_request_var('id');
get_filter_request_var('notification_action');
get_filter_request_var('notification_warning_action');
get_filter_request_var('notification_alert_action');
db_execute('START TRANSACTION');
$ok = true;
$update_template = [];
if (get_request_var('drp_action') == '1') { // associate
for ($i = 0; ($i < cacti_sizeof($selected_items)); $i++) {
if (get_request_var('notification_warning_action') > 0) {
// clear other settings
if (get_request_var('notification_warning_action') == 1) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_template
SET notify_warning = ?
WHERE id = ?',
[get_request_var('id'), $selected_items[$i]]) && $ok;
// clear other items
$ok = db_execute_prepared("UPDATE thold_template
SET notify_warning_extra = ''
WHERE id = ?",
[$selected_items[$i]]) && $ok;
} else {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_template
SET notify_warning = ?
WHERE id = ?',
[get_request_var('id'), $selected_items[$i]]) && $ok;
}
}
if (get_request_var('notification_alert_action') > 0) {
// clear other settings
if (get_request_var('notification_alert_action') == 1) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_template
SET notify_alert = ?
WHERE id = ?',
[get_request_var('id'), $selected_items[$i]]) && $ok;
// clear other items
$ok = db_execute_prepared("UPDATE thold_template
SET notify_extra = ''
WHERE id = ?",
[$selected_items[$i]]) && $ok;
$ok = db_execute_prepared('DELETE FROM plugin_thold_template_contact
WHERE template_id = ?',
[$selected_items[$i]]) && $ok;
} else {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_template
SET notify_alert = ?
WHERE id = ?',
[get_request_var('id'), $selected_items[$i]]) && $ok;
}
}
$update_template[] = $selected_items[$i];
if (!$ok) {
break;
}
}
} elseif (get_request_var('drp_action') == '2') { // disassociate
for ($i = 0; ($i < cacti_sizeof($selected_items)); $i++) {
if (get_request_var('notification_warning_action') > 0) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_template
SET notify_warning = 0
WHERE id = ?
AND notify_warning = ?',
[$selected_items[$i], get_request_var('id')]) && $ok;
}
if (get_request_var('notification_alert_action') > 0) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_template
SET notify_alert = 0
WHERE id = ?
AND notify_alert = ?',
[$selected_items[$i], get_request_var('id')]) && $ok;
}
$update_template[] = $selected_items[$i];
if (!$ok) {
break;
}
}
}
if ($ok) {
db_execute('COMMIT');
// Propagate template changes to threshold instances after the
// notification assignment is committed so this cascade does not
// participate in the transaction boundary.
foreach ($update_template as $template_id) {
thold_template_update_thresholds($template_id);
}
} else {
db_execute('ROLLBACK');
}
}
header('Location: notify_lists.php?header=false&action=edit&tab=templates&id=' . get_request_var('id'));
exit;
}
if (isset_request_var('save_tholds')) {
if ($selected_items != false) {
get_filter_request_var('id');
get_filter_request_var('notification_action');
get_filter_request_var('notification_warning_action');
get_filter_request_var('notification_alert_action');
db_execute('START TRANSACTION');
$ok = true;
if (get_request_var('drp_action') == '1') { // associate
for ($i = 0; ($i < cacti_sizeof($selected_items)); $i++) {
if (get_request_var('notification_warning_action') > 0) {
// clear other settings
if (get_request_var('notification_warning_action') == 1) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data
SET notify_warning = ?
WHERE id = ?',
[get_request_var('id'), $selected_items[$i]]) && $ok;
// clear other items
$ok = db_execute_prepared("UPDATE thold_data
SET notify_warning_extra = ''
WHERE id = ?",
[$selected_items[$i]]) && $ok;
} else {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data
SET notify_warning = ?
WHERE id = ?',
[get_request_var('id'), $selected_items[$i]]) && $ok;
}
}
if (get_request_var('notification_alert_action') > 0) {
// clear other settings
if (get_request_var('notification_alert_action') == 1) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data
SET notify_alert = ?
WHERE id = ?',
[get_request_var('id'), $selected_items[$i]]) && $ok;
// clear other items
$ok = db_execute_prepared("UPDATE thold_data
SET notify_extra = ''
WHERE id = ?",
[$selected_items[$i]]) && $ok;
$ok = db_execute_prepared('DELETE FROM plugin_thold_threshold_contact
WHERE thold_id = ?',
[$selected_items[$i]]) && $ok;
} else {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data
SET notify_alert = ?
WHERE id = ?',
[get_request_var('id'), $selected_items[$i]]) && $ok;
}
}
if (!$ok) {
break;
}
}
} elseif (get_request_var('drp_action') == '2') { // disassociate
for ($i = 0; ($i < cacti_sizeof($selected_items)); $i++) {
if (get_request_var('notification_warning_action') > 0) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data
SET notify_warning = 0
WHERE id = ?
AND notify_warning = ?',
[$selected_items[$i], get_request_var('id')]) && $ok;
}
if (get_request_var('notification_alert_action') > 0) {
// set the notification list
$ok = db_execute_prepared('UPDATE thold_data
SET notify_alert = 0
WHERE id = ?
AND notify_alert = ?',
[$selected_items[$i], get_request_var('id')]) && $ok;
}
if (!$ok) {
break;
}
}
}
if ($ok) {
db_execute('COMMIT');
} else {
db_execute('ROLLBACK');
}
}
header('Location: notify_lists.php?header=false&action=edit&tab=tholds&id=' . get_request_var('id'));
exit;
} else {
api_plugin_hook_function('notify_list_save', $_POST);
header('Location: notify_lists.php?header=false&action=edit&tab=tholds&id=' . get_request_var('id'));
exit;
}
}
// setup some variables
$list = '';
$array = [];
$list_name = '';
if (isset_request_var('id')) {
$list_name = db_fetch_cell_prepared('SELECT name
FROM plugin_notification_lists
WHERE id = ?',
[get_filter_request_var('id')]);
}
if (isset_request_var('save_list')) {
// loop through each of the notification lists selected on the previous page and get more info about them
foreach ($_POST as $var => $val) {
if (preg_match('/^chk_([0-9]+)$/', $var, $matches)) {
// ================= input validation =================
input_validate_input_number($matches[1]);
// ====================================================
$name = db_fetch_cell_prepared('SELECT name
FROM plugin_notification_lists
WHERE id = ?',
[$matches[1]]);
$list .= '<li>' . html_escape($name) . '</li>';
$array[] = $matches[1];
}
}
top_header();
form_start('notify_lists.php');
html_start_box($actions[get_request_var('drp_action')] . ' ' . html_escape($list_name) , '80%', false, '3', 'center', '');
if (cacti_sizeof($array)) {
if (get_request_var('drp_action') == '1') { // delete
print "<tr>
<td class='textArea'>
<p>" . __('Click \'Continue\' to Delete Notification Lists(s). Any Device(s) or Threshold(s) associated with the List(s) will be reverted to the default.', 'thold') . "</p>
<div class='itemlist'><ul>$list</ul></div>
</td>
</tr>";
$save_html = "<input class='cactiReturnTo' type='button' value='" . __esc('Cancel', 'thold') . "'>&nbsp;<input type='submit' value='" . __esc('Continue', 'thold') . "' title='" . __esc('Delete Notification List(s)', 'thold') . "'>";
} elseif (get_request_var('drp_action') == '2') { // duplicate
print "<tr>
<td class='textArea'>
<p>" . __('Click \'Continue\' to Duplicate the following Notification List(s).', 'thold') . "</p>
<div class='itemlist'><ul>$list</ul></div>
<p>" . __('New List Name') . '<br>';
form_text_box('name', __('New Notification List'), '', '255', '40', 'text');
print '</p></td>
</tr>';
$save_html = "<input class='cactiReturnTo' type='button' value='" . __esc('Cancel', 'thold') . "'>&nbsp;<input type='submit' value='" . __esc('Continue', 'thold') . "' title='" . __esc('Duplicate Notification List(s)', 'thold') . "'>";
}
} else {
raise_message(40);
header('Location: notify_lists.php?action=edit&header=false&id=' . get_request_var('id') . '&tab=' . get_request_var('tab'));
exit;
}
print "<tr>
<td class='saveRow'>
<input type='hidden' name='action' value='actions'>
<input type='hidden' name='save_list' value='1'>
<input type='hidden' name='selected_items' value='" . (isset($array) ? serialize($array) : '') . "'>
<input type='hidden' name='drp_action' value='" . html_escape(get_request_var('drp_action')) . "'>
$save_html
</td>
</tr>";
html_end_box();
form_end();
bottom_footer();
} elseif (isset_request_var('save_templates')) {
// loop through each of the notification lists selected on the previous page and get more info about them
foreach ($_POST as $var => $val) {
if (preg_match('/^chk_([0-9]+)$/', $var, $matches)) {
// ================= input validation =================
input_validate_input_number($matches[1]);
// ====================================================
$name = db_fetch_cell_prepared('SELECT name
FROM thold_template
WHERE id = ?',
[$matches[1]]);
$list .= '<li>' . html_escape($name) . '</li>';
$array[] = $matches[1];
}
}
top_header();
form_start('notify_lists.php');
html_start_box(__('%s Threshold Template(s)', $assoc_actions[get_request_var('drp_action')], 'thold'), '80%', false, '3', 'center', '');
if (cacti_sizeof($array)) {
if (get_request_var('drp_action') == '1') { // associate
print "<tr>
<td class='textArea'>
<p>" . __esc('Click \'Continue\' to Association the Notification List \'%s\' with the Threshold Template(s) below.', $list_name, 'thold') . "</p>
<div class='itemlist'><ul>$list</ul></div>
<p>" . __('Warning Membership:', 'thold') . '<br>';
form_dropdown('notification_warning_action', [0 => __('No Change', 'thold'), 1 => __('Notification List Only', 'thold'), 2 => __('Notification List, Retain Other Settings', 'thold')], '', '', 1, '', '');
print '</p>
<p>' . __('Alert Membership:', 'thold') . '<br>';
form_dropdown('notification_alert_action', [0 => __('No Change', 'thold'), 1 => __('Notification List Only', 'thold'), 2 => __('Notification List, Retain Other Settings', 'thold')], '', '', 1, '', '');
print '</p>
</td>
</tr>';
$save_html = "<input class='cactiReturnTo' type='button' value='" . __esc('Cancel', 'thold') . "'>&nbsp;<input type='submit' value='" . __esc('Continue', 'thold') . "' title='" . __esc('Associate Notification List(s)', 'thold') . "'>";
} elseif (get_request_var('drp_action') == '2') { // disassociate
print "<tr>
<td class='textArea'>
<p>" . __esc('Click \'Continue\' to Disassociate the Notification List \'%s\' from the Thresholds Template(s) below.', $list_name, 'thold') . "</p>
<div class='itemlist'><ul>$list</ul></div>
<p>" . __('Warning Membership:', 'thold') . '<br>';
form_dropdown('notification_warning_action', [0 => __('No Change', 'thold'), 1 => __('Remove List', 'thold')], '', '', 1, '', '');
print '</p>
<p>' . __('Alert Membership:', 'thold') . '<br>';
form_dropdown('notification_alert_action', [0 => __('No Change', 'thold'), 1 => __('Remove List', 'thold')], '', '', 1, '', '');
print '</p>
</td>
</tr>';
$save_html = "<input class='cactiReturnTo' type='button' value='" . __esc('Cancel', 'thold') . "'>&nbsp;<input type='submit' value='" . __esc('Continue', 'thold') . "' title='" . __esc('Disassociate Notification List(s)', 'thold') . "'>";
}
} else {
raise_message(40);
header('Location: notify_lists.php?action=edit&header=false&id=' . get_request_var('id') . '&tab=' . get_request_var('tab'));
exit;
}
print " <tr>
<td class='saveRow'>
<input type='hidden' name='action' value='actions'>
<input type='hidden' name='id' value='" . html_escape(get_request_var('id')) . "'>
<input type='hidden' name='save_templates' value='1'>
<input type='hidden' name='selected_items' value='" . (isset($array) ? serialize($array) : '') . "'>
<input type='hidden' name='drp_action' value='" . html_escape(get_request_var('drp_action')) . "'>
$save_html
</td>
</tr>";
html_end_box();
form_end();
bottom_footer();
} elseif (isset_request_var('save_tholds')) {
// loop through each of the notification lists selected on the previous page and get more info about them
foreach ($_POST as $var => $val) {
if (preg_match('/^chk_([0-9]+)$/', $var, $matches)) {
// ================= input validation =================
input_validate_input_number($matches[1]);
// ====================================================
$name = db_fetch_cell_prepared('SELECT name_cache
FROM thold_data
WHERE id = ?',
[$matches[1]]);
$list .= '<li>' . html_escape($name) . '</li>';
$array[] = $matches[1];
}
}
top_header();
form_start('notify_lists.php');
html_start_box(__('%s Threshold(s)', $assoc_actions[get_request_var('drp_action')], 'thold'), '80%', false, '3', 'center', '');
if (cacti_sizeof($array)) {
if (get_request_var('drp_action') == '1') { // associate
print "<tr>
<td class='textArea'>
<p>" . __esc('Click \'Continue\' to Associate the Notification List \'%s\' with the Threshold(s) below.', $list_name, 'thold') . "</p>
<div class='itemlist'><ul>$list</ul></div>
<p>" . __('Warning Membership:', 'thold') . '<br>';
form_dropdown('notification_warning_action', [0 => __('No Change', 'thold'), 1 => __('Notification List Only', 'thold'), 2 => __('Notification List, Retain Other Settings', 'thold')], '', '', 1, '', '');
print '</p>
<p>' . __('Alert Membership:', 'thold') . '<br>';
form_dropdown('notification_alert_action', [0 => __('No Change', 'thold'), 1 => __('Notification List Only', 'thold'), 2 => __('Notification List, Retain Other Settings', 'thold')], '', '', 1, '', '');
print '</p>
</td>
</tr>';
$save_html = "<input class='cactiReturnTo' type='button' value='" . __esc('Cancel', 'thold') . "'>&nbsp;<input type='submit' value='" . __esc('Continue', 'thold') . "' title='" . __esc('Associate Notification List(s)', 'thold') . "'>";
} elseif (get_request_var('drp_action') == '2') { // disassociate
print "<tr>
<td class='textArea'>
<p>" . __esc('Click \'Continue\' to Disassociate the Notification List \'%s\' from the Thresholds(s) below.', $list_name, 'thold') . "</p>
<div class='itemlist'><ul>$list</ul></div>
<p>" . __('Warning Membership:', 'thold') . '<br>';
form_dropdown('notification_warning_action', [0 => __('No Change', 'thold'), 1 => __('Remove List', 'thold')], '', '', 1, '', '');
print '</p>
<p>' . __('Alert Membership:', 'thold') . '<br>';
form_dropdown('notification_alert_action', [0 => __('No Change', 'thold'), 1 => __('Remove List', 'thold')], '', '', 1, '', '');
print '</p>
</td>
</tr>';
$save_html = "<input class='cactiReturnTo' type='button' value='" . __esc('Cancel', 'thold') . "'>&nbsp;<input type='submit' value='" . __esc('Continue', 'thold') . "' title='" . __esc('Disassociate Notification List(s)', 'thold') . "'>";
}
} else {
raise_message(40);
header('Location: notify_lists.php?action=edit&header=false&id=' . get_request_var('id') . '&tab=' . get_request_var('tab'));
exit;
}
print " <tr>
<td class='saveRow'>
<input type='hidden' name='action' value='actions'>
<input type='hidden' name='id' value='" . html_escape(get_request_var('id')) . "'>
<input type='hidden' name='save_tholds' value='1'>
<input type='hidden' name='selected_items' value='" . (isset($array) ? serialize($array) : '') . "'>
<input type='hidden' name='drp_action' value='" . html_escape(get_request_var('drp_action')) . "'>
$save_html
</td>
</tr>";
html_end_box();
form_end();
bottom_footer();
} elseif (isset_request_var('save_associate')) {
// loop through each of the notification lists selected on the previous page and get more info about them
foreach ($_POST as $var => $val) {
if (preg_match('/^chk_([0-9]+)$/', $var, $matches)) {
// ================= input validation =================
input_validate_input_number($matches[1]);
// ====================================================
$name = db_fetch_cell_prepared('SELECT description
FROM host WHERE id = ?',
[$matches[1]]);
$list .= '<li>' . html_escape($name) . '</li>';
$array[] = $matches[1];
}
}
top_header();
form_start('notify_lists.php');
html_start_box($assoc_actions[get_request_var('drp_action')] . ' Device(s)', '80%', false, '3', 'center', '');
if (cacti_sizeof($array)) {
if (get_request_var('drp_action') == '1') { // associate
print "<tr>
<td class='textArea'>
<p>" . __esc('Click \'Continue\' to Associate the Notification List \'%s\' with the Device(s) below.', $list_name, 'thold') . '</p>
<p>' . __('You may also Associate the Devices Thresholds as well. However, these Device Thresholds will allow the Threshold Notification List to be overwritten.', 'thold') . "</p>
<div class='itemlist'><ul>$list</ul></div>
<p>" . __('Resulting Membership:', 'thold') . '<br>';
form_dropdown('notification_action', [2 => __('Notification List Only', 'thold'), 3 => __('Notification and Global Lists', 'thold')], '', '', 2, '', '');
print '</p>
<p>' . __('Device Threshold Warning Membership:', 'thold') . '<br>';
form_dropdown('notification_warning_action', [0 => __('No Change', 'thold'), 1 => __('Notification List Only', 'thold'), 2 => __('Notification List, Retain Other Settings', 'thold')], '', '', 1, '', '');
print '</p>
<p>' . __('Device Threshold Alert Membership:', 'thold') . '<br>';
form_dropdown('notification_alert_action', [0 => __('No Change', 'thold'), 1 => __('Notification List Only', 'thold'), 2 => __('Notification List, Retain Other Settings', 'thold')], '', '', 1, '', '');
print '</p>
</td>
</tr>';
$save_html = "<input class='cactiReturnTo' type='button' value='" . __esc('Cancel', 'thold') . "'>&nbsp;<input type='submit' value='" . __esc('Continue', 'thold') . "' title='" . __esc('Associate Notification List(s)', 'thold') . "'>";
} elseif (get_request_var('drp_action') == '2') { // disassociate
print "<tr>
<td class='textArea'>
<p>" . __esc('Click \'Continue\' to Disassociate the Notification List \'%s\' from the Device(s) below.', $list_name, 'thold') . '</p>
<p>' . __('You may also Disassociate the Devices Thresholds as well. However, these Device Thresholds will allow the Threshold Notification List to be overwritten.', 'thold') . "</p>
<div class='itemlist'><ul>$list</ul></div>
<p>" . __('Resulting Membership:', 'thold') . '<br>';
form_dropdown('notification_action', [1 => __('Global List', 'thold'), 0 => __('Disabled', 'thold')], '', '', 1, '', '');
print '</p>
<p>' . __('Device Threshold Warning Membership:', 'thold') . '<br>';
form_dropdown('notification_warning_action', [0 => __('No Change', 'thold'), 1 => __('Remove List', 'thold')], '', '', 1, '', '');
print '</p>
<p>' . __('Device Threshold Alert Membership:', 'thold') . '<br>';
form_dropdown('notification_alert_action', [0 => __('No Change', 'thold'), 1 => __('Remove List', 'thold')], '', '', 1, '', '');
print '</p>
</td>
</tr>';
$save_html = "<input class='cactiReturnTo' type='button' value='" . __esc('Cancel', 'thold') . "'>&nbsp;<input type='submit' value='" . __('Continue', 'thold') . "' title='" . __esc('Disassociate Notification List(s)', 'thold') . "'>";
}
} else {
raise_message(40);
header('Location: notify_lists.php?action=edit&header=false&id=' . get_request_var('id') . '&tab=' . get_request_var('tab'));
exit;
}
print "<tr>
<td class='saveRow'>
<input type='hidden' name='action' value='actions'>
<input type='hidden' name='id' value='" . html_escape(get_request_var('id')) . "'>
<input type='hidden' name='save_associate' value='1'>
<input type='hidden' name='selected_items' value='" . (isset($array) ? serialize($array) : '') . "'>
<input type='hidden' name='drp_action' value='" . html_escape(get_request_var('drp_action')) . "'>
$save_html
</td>
</tr>";
html_end_box();
form_end();
bottom_footer();
} else {
$save = ['post' => $_POST, 'selected_items' => isset($selected_items) ? $selected_items : ''];
api_plugin_hook_function('notify_list_form_confirm', $save);
}
}
/* ----------------------------
Notification List Edit
---------------------------- */
/**
* Builds the "[edit: name]" or "[new]" header suffix label for the
* notification list edit page, based on whether an existing list id
* request variable is present.
*
* @return string The escaped header label suffix.
*/
function get_notification_header_label() {
if (!isempty_request_var('id')) {
$list = db_fetch_row_prepared('SELECT *
FROM plugin_notification_lists
WHERE id = ?',
[get_filter_request_var('id')]);
$header_label = __esc('[edit: %s]', $list['name'], 'thold');
} else {
$header_label = __('[new]', 'thold');
}
return $header_label;
}
/**
* Renders the tabbed add/edit page for a notification list: displays
* the tab bar (General, Devices, Thresholds, Templates) when editing
* an existing list, then renders the currently selected tab's content
* (the general settings form on the 'general' tab, or delegates to
* hosts()/tholds()/templates() for the association tabs). Called from
* this script's main request-dispatch switch when action=edit.
*
* @return void
*
* @global array $tabs_thold Map of tab short-name => display label,
* used to render the tab bar.
* @global array $config Cacti global configuration array; used to
* build tab URLs.
*/
function edit() {
global $tabs_thold, $config;
// ================= input validation =================
get_filter_request_var('id');
get_filter_request_var('tab', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^([a-zA-Z]+)$/']]);
// ====================================================
// set the default tab
load_current_session_value('tab', 'sess_thold_notify_tab', 'general');
$current_tab = get_request_var('tab');
if (cacti_sizeof($tabs_thold) && isset_request_var('id')) {
print "<div class='tabs'><nav><ul>";
foreach (array_keys($tabs_thold) as $tab_short_name) {
print "<li><a class='pic" . (($tab_short_name == $current_tab) ? ' selected' : '') . "' href='" . $config['url_path'] .
'plugins/thold/notify_lists.php' .
'?action=edit&id=' . get_filter_request_var('id') .
'&tab=' . $tab_short_name .
"'>" . $tabs_thold[$tab_short_name] . '</a></li>';
}
print '</ul></nav></div>';
}
$header_label = get_notification_header_label();
$formats = reports_get_format_files();
if (isset_request_var('id')) {
$list = db_fetch_row_prepared('SELECT *
FROM plugin_notification_lists
WHERE id = ?',
[get_request_var('id')]);
} else {
$list = [];
$current_tab = 'general';
}
if ($current_tab == 'general') {
form_start('notify_lists.php');
html_start_box(__('List General Settings', 'thold') . ' ' . html_escape($header_label), '100%', false, '3', 'center', '');
$fields_notification = [
'name' => [
'method' => 'textbox',
'friendly_name' => __('Name', 'thold'),
'description' => __('Enter a name for this Notification List.', 'thold'),
'value' => '|arg1:name|',
'max_length' => '80'
],
'description' => [
'method' => 'textarea',
'friendly_name' => __('Description', 'thold'),
'description' => __('Enter a description for this Notification List.', 'thold'),
'value' => '|arg1:description|',
'class' => 'textAreaNotes',
'textarea_rows' => '2',
'textarea_cols' => '80'
],
'enabled' => [
'method' => 'checkbox',
'friendly_name' => __('Enabled'),
'description' => __('To disable all notifications from this Notification List, you can simply disable it here.', 'thold'),
'default' => '',
'value' => '|arg1:enabled|'
],
'emails' => [
'method' => 'textarea',
'friendly_name' => __('To Email Addresses', 'thold'),
'description' => __('Enter a comma separated list of Email addresses for this Notification List.', 'thold'),
'value' => '|arg1:emails|',
'class' => 'textAreaNotes',
'textarea_rows' => '4',
'textarea_cols' => '80'
],
'bcc_emails' => [
'method' => 'textarea',
'friendly_name' => __('BCC Email Addresses', 'thold'),
'description' => __('Enter a comma separated list of Email addresses for this Notification List to be blind copied.', 'thold'),
'value' => '|arg1:bcc_emails|',
'class' => 'textAreaNotes',
'textarea_rows' => '4',
'textarea_cols' => '80'
],
'format_file' => [
'friendly_name' => __('Email Style/Format File', 'thold'),
'method' => 'drop_array',
'default' => 'default.format',
'description' => __('Choose the custom html wrapper and CSS file to use. This file contains both html and CSS to wrap around your report. If it contains more than simply CSS, you need to place a special <REPORT> tag inside of the file. This format tag will be replaced by the report content. These files are located in the \'formats\' directory.', 'thold'),
'value' => '|arg1:format_file|',
'array' => $formats
],
'id' => [
'method' => 'hidden_zero',
'value' => '|arg1:id|'
],
'save_component' => [
'method' => 'hidden',
'value' => '1'
]
];
draw_edit_form(
[
'config' => [],
'fields' => inject_form_variables($fields_notification, (isset($list) ? $list : []))
]
);
html_end_box();
form_save_button('notify_lists.php', 'return');
} elseif ($current_tab == 'hosts') {
hosts($header_label);
} elseif ($current_tab == 'tholds') {
tholds($header_label);
} elseif ($current_tab == 'templates') {
templates($header_label);
} else {
$save = [
'current_tab' => $current_tab,
'header_label' => $header_label
];
api_plugin_hook_function('notify_list_display', $save);
}
}
/**
* Renders the notification list's \"Devices\" tab: validates/stores this
* tab's filter request variables, displays the device filter form, then
* displays a filtered, sorted, paginated table of devices with their
* association status to this list and a bulk-actions dropdown to
* associate/disassociate them.
*
* @param string $header_label The \"[edit: name]\"/\"[new]\" header label
* suffix to display in the box title.
*
* @return void
*
* @global array $assoc_actions Map of drp_action value => action label,
* used for the bulk-actions dropdown.
* @global array $item_rows Default number of rows per page from
* Cacti settings.
* @global array $config Cacti global configuration array.
*/
function hosts($header_label) {
global $assoc_actions, $item_rows, $config;
// ================= input validation and session storage =================
$filters = [
'rows' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
],
'page' => [
'filter' => FILTER_VALIDATE_INT,
'default' => '1'
],
'site_id' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
],
'rfilter' => [
'filter' => FILTER_VALIDATE_IS_REGEX,
'pageset' => true,
'default' => ''
],
'sort_column' => [
'filter' => FILTER_CALLBACK,
'default' => 'description',
'options' => ['options' => 'sanitize_search_string']
],
'sort_direction' => [
'filter' => FILTER_CALLBACK,
'default' => 'ASC',
'options' => ['options' => 'sanitize_search_string']
],
'associated' => [
'filter' => FILTER_CALLBACK,
'default' => 'true',
'options' => ['options' => 'sanitize_search_string']
],
'host_template_id' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
]
];
validate_store_request_vars($filters, 'sess_nlh');
// ================= input validation =================
// if the number of rows is -1, set it to the default
if (get_request_var('rows') == -1) {
$rows = read_config_option('num_rows_table');
} else {
$rows = get_request_var('rows');
}
html_start_box(__('Associated Devices', 'thold') . ' ' . html_escape($header_label), '100%', false, '3', 'center', '');
?>
<tr class='even'>
<td>
<form id='form_devices' method='post' action='notify_lists.php'>
<table class='filterTable'>
<tr>
<td>
<?php print __('Search', 'thold'); ?>
</td>
<td>
<input type='text' id='rfilter' size='30' value='<?php print html_escape_request_var('rfilter'); ?>'>
</td>
<td>
<?php print __('Site'); ?>
</td>
<td>
<select id='site_id'>
<option value='-1'<?php if (get_request_var('site_id') == '-1') {?> selected<?php }?>><?php print __('Any'); ?></option>
<option value='0'<?php if (get_request_var('site_id') == '0') {?> selected<?php }?>><?php print __('None'); ?></option>
<?php
$sites = db_fetch_assoc('SELECT id, name FROM sites ORDER BY name');
if (cacti_sizeof($sites)) {
foreach ($sites as $site) {
print "<option value='" . $site['id'] . "'" . (get_request_var('site_id') == $site['id'] ? ' selected' : '') . '>' . html_escape($site['name']) . '</option>';
}
}
?>
</select>
</td>
<td>
<?php print __('Device Template', 'thold'); ?>
</td>
<td>
<select id='host_template_id'>
<option value='-1'<?php if (get_request_var('host_template_id') == '-1') {?> selected<?php }?>><?php print __('Any', 'thold'); ?></option>
<option value='0'<?php if (get_request_var('host_template_id') == '0') {?> selected<?php }?>><?php print __('None', 'thold'); ?></option>
<?php
$host_templates = db_fetch_assoc('SELECT id, name
FROM host_template
ORDER BY name');
if (cacti_sizeof($host_templates)) {
foreach ($host_templates as $host_template) {
print "<option value='" . $host_template['id'] . "'" . (get_request_var('host_template_id') == $host_template['id'] ? ' selected' : '') . '>' . html_escape($host_template['name']) . '</option>';
}
}
?>
</select>
</td>
<td>
<?php print __('Devices', 'thold'); ?>
</td>
<td>
<select id='rows'>
<option value='-1'<?php if (get_request_var('rows') == '-1') {?> selected<?php }?>><?php print __('Default', 'thold'); ?></option>
<?php
if (cacti_sizeof($item_rows)) {
foreach ($item_rows as $key => $value) {
print "<option value='" . $key . "'" . (get_request_var('rows') == $key ? ' selected' : '') . '>' . html_escape($value) . '</option>';
}
}
?>
</select>
</td>
<td>
<span>
<input type='checkbox' id='associated' <?php print(get_request_var('associated') == 'true' || get_request_var('associated') == 'on' ? 'checked' : ''); ?>>
<label for='associated'><?php print __('Associated', 'thold'); ?></label>
</span>
</td>
<td>
<span>
<input type='submit' value='<?php print __esc('Go', 'thold'); ?>' title='<?php print __esc('Set/Refresh Filters', 'thold'); ?>'>
<input type='button' id='clear' value='<?php print __esc('Clear', 'thold'); ?>' title='<?php print __esc('Clear Filters', 'thold'); ?>'>
</span>
</td>
</tr>
</table>
</form>
<script type='text/javascript' <?php print plugin_thold_csp_nonce(); ?>>
function applyFilter() {
strURL = '?header=false&action=edit&id=<?php print get_request_var('id'); ?>'
strURL += '&rows=' + encodeURIComponent($('#rows').val());
strURL += '&host_template_id=' + encodeURIComponent($('#host_template_id').val());
strURL += '&site_id=' + encodeURIComponent($('#site_id').val());
strURL += '&associated=' + $('#associated').is(':checked');
strURL += '&rfilter=' + encodeURIComponent(base64_encode($('#rfilter').val()));
loadPageNoHeader(strURL);
}
function clearFilter() {
strURL = 'notify_lists.php?header=false&action=edit&id=<?php print get_request_var('id'); ?>&clear=true'
loadPageNoHeader(strURL);
}
$(function() {
$('#form_devices').submit(function(event) {
event.preventDefault();
applyFilter();
});
$('#site_id').off('change').on('change', function() {
applyFilter();
});
$('#rfilter, #host_template_id, #rows, #associated').off('change').on('change', function() {
applyFilter();
});
$('#clear').click(function() {
clearFilter();
});
});
</script>
</td>
</tr>
<?php
html_end_box();
$sql_where = '';
$sql_params = [];
// form the 'where' clause for our main sql query
if (strlen(get_request_var('rfilter'))) {
$sql_where = 'WHERE (
h.hostname RLIKE ?
OR h.description RLIKE ?)';
$sql_params[] = get_request_var('rfilter');
$sql_params[] = get_request_var('rfilter');
}
if (get_request_var('site_id') == '-1') {
// Show all items
} elseif (get_request_var('site_id') == '0') {
$sql_where .= ($sql_where == '' ? 'WHERE' : ' AND ') . ' h.site_id = 0';
} elseif (!isempty_request_var('site_id')) {
$sql_where .= ($sql_where == '' ? 'WHERE' : ' AND ') . ' h.site_id = ?';
$sql_params[] = get_request_var('site_id');
}
if (get_request_var('host_template_id') == '-1') {
// Show all items
} elseif (get_request_var('host_template_id') == '0') {
$sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . ' h.host_template_id = 0';
} elseif (!isempty_request_var('host_template_id')) {
$sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . ' h.host_template_id = ?';
$sql_params[] = get_request_var('host_template_id');
}
if (get_request_var('associated') == 'false') {
// Show all items
} else {
$sql_where .= ($sql_where != '' ? ' AND ' : 'WHERE ') . ' (h.thold_send_email > 1 AND h.thold_host_email = ?)';
$sql_params[] = get_request_var('id');
}
$sql_limit = 'LIMIT ' . ($rows * (intval(get_request_var('page')) - 1)) . ',' . $rows;
$sql_order = get_order_string();
$total_rows = db_fetch_cell_prepared("SELECT
COUNT(h.id)
FROM host AS h
$sql_where",
$sql_params);
$host_graphs = array_rekey(
db_fetch_assoc('SELECT host_id, COUNT(*) AS graphs
FROM graph_local
GROUP BY host_id'),
'host_id', 'graphs'
);
$host_data_sources = array_rekey(
db_fetch_assoc('SELECT host_id, COUNT(*) AS data_sources
FROM data_local
GROUP BY host_id'),
'host_id', 'data_sources'
);
$sql_query = "SELECT h.*, s.name AS site_name
FROM host AS h
LEFT JOIN sites AS s
ON h.site_id = s.id
$sql_where
$sql_order
$sql_limit";
$hosts = db_fetch_assoc_prepared($sql_query, $sql_params);
$nav = html_nav_bar('notify_lists.php?action=edit&id=' . get_request_var('id'), MAX_DISPLAY_PAGES, get_request_var('page'), $rows, $total_rows, 10, __('Devices', 'thold'), 'page', 'main');
form_start('notify_lists.php', 'chk');
print $nav;
html_start_box('', '100%', false, '3', 'center', '');
$display_text = [
'description' => [
'display' => __('Description', 'thold'),
'align' => 'left',
'sort' => 'ASC',
],
'site_name' => [
'display' => __('Site', 'thold'),
'align' => 'left',
'sort' => 'ASC',
],
'h.id' => [
'display' => __('ID', 'thold'),
'align' => 'left',
'sort' => 'ASC',
],
'h.status' => [
'display' => __('Status', 'thold'),
'align' => 'left',
'sort' => 'ASC',
],
'nosort0' => [
'display' => __('Associated Lists', 'thold'),
'align' => 'left',
'sort' => 'ASC',
],
'nosort1' => [
'display' => __('Graphs', 'thold'),
'align' => 'right',
'sort' => 'DESC',
],
'nosort2' => [
'display' => __('Data Sources', 'thold'),
'align' => 'right',
'sort' => 'DESC',
],
'h.hostname' => [
'display' => __('Hostname', 'thold'),
'align' => 'right',
'sort' => 'ASC',
]
];
html_header_sort_checkbox($display_text, get_request_var('sort_column'), get_request_var('sort_direction'), false, 'notify_lists.php?action=edit&id=' . get_filter_request_var('id'));
if (cacti_sizeof($hosts)) {
foreach ($hosts as $host) {
form_alternate_row('line' . $host['id'], true);
form_selectable_cell(filter_value($host['description'], get_request_var('rfilter'), $config['url_path'] . 'host.php?action=edit&id=' . $host['id']), $host['id'],250);
form_selectable_ecell($host['site_name'] != '' ? $host['site_name'] : __('None', 'thold'), $host['id']);
form_selectable_cell($host['id'], $host['id']);
form_selectable_cell(get_colored_device_status(($host['disabled'] == 'on' ? true : false), $host['status']), $host['id']);
if ($host['thold_send_email'] == 0) {
form_selectable_cell('<span class="deviceDisabled">' . __('Disabled', 'thold') . '</span>', $host['id']);
} elseif ($host['thold_send_email'] == 1) {
form_selectable_cell('<span class="deviceRecovering">' . __('Global List', 'thold') . '</span>', $host['id']);
} elseif ($host['thold_host_email'] == get_request_var('id')) {
if ($host['thold_send_email'] == 2) {
form_selectable_cell('<span class="deviceUp">' . __('Current List Only', 'thold') . '</span>', $host['id']);
} else {
form_selectable_cell('<span class="deviceUp">' . __('Current and Global List(s)', 'thold') . '</span>', $host['id']);
}
} elseif ($host['thold_host_email'] == '0') {
form_selectable_cell('<span class="deviceUp">' . __('None', 'thold') . '</span>', $host['id']);
} else {
$name = db_fetch_cell_prepared('SELECT name
FROM plugin_notification_lists
WHERE id = ?',
[get_request_var('id')]);
form_selectable_cell('<span class="deviceDown">' . html_escape($name) . '</span>', $host['id']);
}
form_selectable_cell((isset($host_graphs[$host['id']]) ? $host_graphs[$host['id']] : 0), $host['id'], '', 'right');
form_selectable_cell((isset($host_data_sources[$host['id']]) ? $host_data_sources[$host['id']] : 0), $host['id'], '', 'right');
form_selectable_cell(filter_value($host['hostname'], get_request_var('rfilter')), $host['id'], '', 'right');
form_checkbox_cell($host['description'], $host['id']);
form_end_row();
}
} else {
print '<tr><td colspan="' . (cacti_sizeof($display_text) + 1) . '"><em>' . __('No Associated Devices Found', 'thold') . '</em></td></tr>';
}
html_end_box();
if (cacti_sizeof($hosts)) {
print $nav;
}
form_hidden_box('tab', 'hosts', '');
form_hidden_box('id', get_request_var('id'), '');
form_hidden_box('save_associate', '1', '');
draw_actions_dropdown($assoc_actions);
form_end();
}
/**
* Renders the notification list's \"Thresholds\" tab: validates/stores
* this tab's filter request variables, displays the threshold filter
* form, then displays a filtered, sorted, paginated table of
* thresholds with their association status to this list and a
* bulk-actions dropdown to associate/disassociate them.
*
* @param string $header_label The \"[edit: name]\"/\"[new]\" header label
* suffix to display in the box title.
*
* @return void
*/
function tholds($header_label) {
global $item_rows, $assoc_actions, $config;
include($config['base_path'] . '/plugins/thold/includes/arrays.php');
thold_request_validation();
$statefilter = '';
if (isset_request_var('state')) {
if (get_request_var('state') == '-1') {
$statefilter = '';
} elseif (get_request_var('state') == '0') {
$statefilter = "td.thold_enabled = 'off'";
} elseif (get_request_var('state') == '2') {
$statefilter = "td.thold_enabled = 'on'";
} elseif (get_request_var('state') == '1') {
$statefilter = '(td.thold_alert != 0 OR td.bl_alert > 0)';
} elseif (get_request_var('state') == '3') {
$statefilter = '(td.thold_alert != 0 AND td.thold_fail_count >= td.thold_fail_trigger) OR (td.bl_alert > 0 AND td.bl_fail_count >= td.bl_fail_trigger)';
}
}
// if the number of rows is -1, set it to the default
if (get_request_var('rows') == -1) {
$rows = read_config_option('num_rows_table');
} else {
$rows = get_request_var('rows');
}
$sql_where = '';
$sort = get_request_var('sort_column') . ' ' . get_request_var('sort_direction');
$limit = ($rows * (intval(get_request_var('page')) - 1)) . ", $rows";
if (!isempty_request_var('template') && get_request_var('template') != '-1') {
$sql_where .= ($sql_where == '' ? '' : ' AND ') . 'td.data_template_id = ' . get_request_var('template');
}
if (get_request_var('site_id') == '-1') {
// Show all items
} elseif (get_request_var('site_id') == '0') {
$sql_where .= ($sql_where == '' ? '' : ' AND ') . ' h.site_id=0';
} elseif (!isempty_request_var('site_id')) {
$sql_where .= ($sql_where == '' ? '' : ' AND ') . ' h.site_id=' . get_request_var('site_id');
}
if (strlen(get_request_var('rfilter'))) {
// rfilter is pre-validated as a legal PHP regex by FILTER_VALIDATE_IS_REGEX in the
// request validation array; db_qstr() SQL-escapes the already-validated value.
$sql_where .= (!strlen($sql_where) ? '' : ' AND ') . 'td.name_cache ' . thold_rlike_clause(get_request_var('rfilter'));
}
if ($statefilter != '') {
$sql_where .= (!strlen($sql_where) ? '' : ' AND ') . $statefilter;
}
if (get_request_var('associated') == 'true') {
$sql_where .= (!strlen($sql_where) ? '' : ' AND ') . '(td.notify_warning=' . get_request_var('id') . ' OR td.notify_alert=' . get_request_var('id') . ')';
}
$result = get_allowed_thresholds($sql_where, $sort, $limit, $total_rows);
$data_templates = db_fetch_assoc('SELECT DISTINCT dt.id, dt.name
FROM data_template AS dt
INNER JOIN thold_data AS td
ON td.data_template_id = dt.id
ORDER BY dt.name');
html_start_box(__('Associated Thresholds', 'thold') . ' ' . html_escape($header_label) , '100%', false, '3', 'center', '');
?>
<tr class='even'>
<td>
<form id='listthold' method='get' action='notify_lists.php'>
<table class='filterTable'>
<tr>
<td>
<?php print __('Search', 'thold'); ?>
</td>
<td>
<input type='text' id='rfilter' size='30' value='<?php print html_escape_request_var('rfilter'); ?>'>
</td>
<td>
<?php print __('Site'); ?>
</td>
<td>
<select id='site_id'>
<option value='-1'<?php if (get_request_var('site_id') == '-1') {?> selected<?php }?>><?php print __('Any'); ?></option>
<option value='0'<?php if (get_request_var('site_id') == '0') {?> selected<?php }?>><?php print __('None'); ?></option>
<?php
$sites = db_fetch_assoc('SELECT id, name FROM sites ORDER BY name');
if (cacti_sizeof($sites)) {
foreach ($sites as $site) {
print "<option value='" . $site['id'] . "'" . (get_request_var('site_id') == $site['id'] ? ' selected' : '') . '>' . html_escape($site['name']) . '</option>';
}
}
?>
</select>
</td>
<td>
<?php print __('Template', 'thold'); ?>
</td>
<td>
<select id='template'>
<option value='-1'><?php print __('Any', 'thold'); ?></option>
<?php
foreach ($data_templates as $row) {
print "<option value='" . $row['id'] . "'" . (isset_request_var('template') && $row['id'] == get_request_var('template') ? ' selected' : '') . '>' . $row['name'] . '</option>';
}
?>
</select>
</td>
<td>
<?php print __('State', 'thold'); ?>
</td>
<td>
<select id='state'>
<option value='-1'<?php if (get_request_var('state') == '-1') {?> selected<?php }?>><?php print __('All', 'thold'); ?></option>
<option value='1'<?php if (get_request_var('state') == '1') {?> selected<?php }?>><?php print __('Breached', 'thold'); ?></option>
<option value='3'<?php if (get_request_var('state') == '3') {?> selected<?php }?>><?php print __('Triggered', 'thold'); ?></option>
<option value='2'<?php if (get_request_var('state') == '2') {?> selected<?php }?>><?php print __('Enabled', 'thold'); ?></option>
<option value='0'<?php if (get_request_var('state') == '0') {?> selected<?php }?>><?php print __('Disabled', 'thold'); ?></option>
</select>
</td>
<td>
<?php print __('Thresholds', 'thold'); ?>
</td>
<td>
<select id='rows'>
<option value='-1'<?php if (get_request_var('rows') == '-1') {?> selected<?php }?>><?php print __('Default', 'thold'); ?></option>
<?php
if (cacti_sizeof($item_rows)) {
foreach ($item_rows as $key => $value) {
print "<option value='" . $key . "'" . (get_request_var('rows') == $key ? ' selected' : '') . '>' . html_escape($value) . '</option>';
}
}
?>
</select>
</td>
<td>
<span>
<input type='checkbox' id='associated' <?php print(get_request_var('associated') == 'true' || get_request_var('associated') == 'on' ? 'checked' : ''); ?>>
<label for='associated'><?php print __('Associated', 'thold'); ?></label>
</span>
</td>
<td>
<span>
<input type='submit' value='<?php print __esc('Go', 'thold'); ?>' title='<?php print __esc('Set/Refresh Filters', 'thold'); ?>'>
<input type='button' id='clear' value='<?php print __esc('Clear', 'thold'); ?>' title='<?php print __esc('Clear Filters', 'thold'); ?>'>
</span>
</td>
</tr>
</table>
</form>
<script type='text/javascript' <?php print plugin_thold_csp_nonce(); ?>>
function applyFilter() {
strURL = 'notify_lists.php?header=false&action=edit&tab=tholds&id=<?php print get_request_var('id'); ?>'
strURL += '&associated=' + $('#associated').is(':checked');
strURL += '&state=' + encodeURIComponent($('#state').val());
strURL += '&site_id=' + encodeURIComponent($('#site_id').val());
strURL += '&rows=' + encodeURIComponent($('#rows').val());
strURL += '&template=' + encodeURIComponent($('#template').val());
strURL += '&rfilter=' + encodeURIComponent(base64_encode($('#rfilter').val()));
loadPageNoHeader(strURL);
}
function clearFilter() {
strURL = 'notify_lists.php?header=false&action=edit&tab=tholds&id=<?php print get_request_var('id'); ?>&clear=true'
loadPageNoHeader(strURL);
}
$(function() {
$('#listthold').submit(function(event) {
event.preventDefault();
applyFilter();
});
$('#site_id').off('change').on('change', function() {
applyFilter();
});
$('#rfilter, #template, #state, #rows, #associated').off('change').on('change', function() {
applyFilter();
});
$('#clear').click(function() {
clearFilter();
});
});
</script>
</td>
</tr>
<?php
html_end_box();
$nav = html_nav_bar('notify_lists.php?action=edit&tab=tholds&id=' . get_filter_request_var('id'), MAX_DISPLAY_PAGES, get_request_var('page'), $rows, $total_rows, 10, __('Thresholds', 'thold'), 'page', 'main');
form_start('notify_lists.php', 'chk');
print $nav;
html_start_box('', '100%', false, '3', 'center', '');
$display_text = [
'name_cache' => [
'display' => __('Name', 'thold'),
'sort' => 'ASC'
],
'id' => [
'display' => __('ID', 'thold'),
'sort' => 'ASC'
],
'nosort1' => [
'display' => __('Warning Lists', 'thold'),
'sort' => 'ASC'
],
'nosort2' => [
'display' => __('Alert Lists', 'thold'),
'sort' => 'ASC'
],
'thold_type' => [
'display' => __('Type', 'thold'),
'sort' => 'ASC'
],
'thold_alert' => [
'display' => __('Triggered', 'thold'),
'sort' => 'ASC'
],
'nosort3' => [
'display' => __('Templated', 'thold'),
'sort' => 'ASC'
],
'thold_enabled' => [
'display' => __('Enabled', 'thold'),
'sort' => 'ASC'
]
];
html_header_sort_checkbox($display_text, get_request_var('sort_column'), get_request_var('sort_direction'), false, 'notify_lists.php?action=edit&tab=tholds&id=' . get_filter_request_var('id'));
$c = 0;
if (cacti_sizeof($result)) {
foreach ($result as $row) {
$c++;
$alertstat = __('No', 'thold');
if ($row['thold_type'] != 1) {
if ($row['thold_alert'] != 0) {
$alertstat = __('Yes', 'thold');
}
} else {
if ($row['bl_alert'] == 1) {
$alertstat = __('baseline-LOW', 'thold');
} elseif ($row['bl_alert'] == 2) {
$alertstat = __('baseline-HIGH', 'thold');
}
}
// show alert stats first
$alert_stat = '';
$list = db_fetch_cell_prepared('SELECT count(*)
FROM plugin_thold_threshold_contact
WHERE thold_id = ?',
[$row['id']]);
if ($list > 0) {
$alert_stat = "<span class='deviceUp'>" . __('Select Users', 'thold') . '</span>';
}
if (strlen($row['notify_extra'])) {
$alert_stat .= (strlen($alert_stat) ? ', ' : '') . "<span class='deviceRecovering'>" . __('Specific Emails', 'thold') . '</span>';
}
if (!empty($row['notify_alert'])) {
if (get_request_var('id') == $row['notify_alert']) {
$alert_stat .= (strlen($alert_stat) ? ', ' : '') . "<span class='deviceUp'>" . __('Current List', 'thold') . '</span>';
} else {
$alert_info = db_fetch_cell_prepared('SELECT name
FROM plugin_notification_lists
WHERE id = ?',
[$row['notify_alert']]);
if ($alert_info != '') {
$alert_stat .= (strlen($alert_stat) ? ', ' : '') . "<span class='deviceDown'>" . html_escape($alert_info) . '</span>';
} else {
$alert_stat .= (strlen($alert_stat) ? ', ' : '') . "<span class='deviceDown'>" . __('Unknown Threshold', 'thold') . '</span>';
}
}
}
if (!strlen($alert_stat)) {
$alert_stat = "<span class='deviceUnknown'>" . __('Log Only', 'thold') . '</span>';
}
// show warning stats first
$warn_stat = '';
if (strlen($row['notify_warning_extra'])) {
$warn_stat .= (strlen($warn_stat) ? ', ' : '') . "<span class='deviceRecovering'>" . __('Specific Emails', 'thold') . '</span>';
}
if (!empty($row['notify_warning'])) {
if (get_request_var('id') == $row['notify_warning']) {
$warn_stat .= (strlen($warn_stat) ? ', ' : '') . "<span class='deviceUp'>" . __('Current List', 'thold') . '</span>';
} else {
$warn_list = db_fetch_cell_prepared('SELECT name
FROM plugin_notification_lists
WHERE id = ?',
[$row['notify_warning']]);
$warn_stat .= (strlen($warn_stat) ? ', ' : '') . "<span class='deviceDown'>" . html_escape($warn_list) . '</span>';
}
}
if ((!strlen($warn_stat)) &&
(($row['thold_type'] == 0 && $row['thold_warning_hi'] == '' && $row['thold_warning_low'] == '') ||
($row['thold_type'] == 2 && $row['time_warning_hi'] == '' && $row['time_warning_low'] == ''))) {
$warn_stat = "<span class='deviceDown'>" . __('None', 'thold') . '</span>';
} elseif (!strlen($warn_stat)) {
$warn_stat = "<span class='deviceUnknown'>" . __('Log Only', 'thold') . '</span>';
}
if ($row['template_enabled'] == 'on') {
$templated = db_fetch_cell_prepared('SELECT notify_templated
FROM thold_template
WHERE id = ?',
[$row['thold_template_id']]);
if ($templated == 'on') {
$disabled = true;
} else {
$disabled = false;
}
} else {
$disabled = false;
}
form_alternate_row('line' . $row['id'], true, $disabled);
form_selectable_cell(filter_value($row['name_cache'], get_request_var('rfilter')), $row['id']);
form_selectable_cell($row['id'], $row['id']);
form_selectable_cell($warn_stat, $row['id']);
form_selectable_cell($alert_stat, $row['id']);
form_selectable_cell($thold_types[$row['thold_type']], $row['id']);
form_selectable_cell($alertstat, $row['id']);
form_selectable_cell($disabled ? __('Read Only', 'thold') : __('Editable', 'thold'), $row['id']);
form_selectable_cell((($row['thold_enabled'] == 'off') ? __('Disabled', 'thold') : __('Enabled', 'thold')), $row['id']);
form_checkbox_cell($row['name'], $row['id'], $disabled);
form_end_row();
}
} else {
print "<tr class='even'><td colspan='" . (cacti_sizeof($display_text) + 1) . "'><i>" . __('No Thresholds Found', 'thold') . '</i></td></tr>';
}
html_end_box(false);
if (cacti_sizeof($result)) {
print $nav;
}
form_hidden_box('tab', 'tholds', '');
form_hidden_box('id', get_request_var('id'), '');
form_hidden_box('save_tholds', '1', '');
draw_actions_dropdown($assoc_actions);
form_end();
}
/**
* Renders the notification list's \"Templates\" tab: validates/stores
* this tab's filter request variables, displays the template filter
* form, then displays a filtered, sorted, paginated table of threshold
* templates with their association status to this list and a
* bulk-actions dropdown to associate/disassociate them.
*
* @param string $header_label The \"[edit: name]\"/\"[new]\" header label
* suffix to display in the box title.
*
* @return void
*/
function templates($header_label) {
global $config, $item_rows, $assoc_actions;
include($config['base_path'] . '/plugins/thold/includes/arrays.php');
thold_template_request_validation();
// if the number of rows is -1, set it to the default
if (get_request_var('rows') == -1) {
$rows = read_config_option('num_rows_table');
} else {
$rows = get_request_var('rows');
}
$sql_where = '';
$sql_order = get_order_string();
$sql_limit = ' LIMIT ' . ($rows * (intval(get_request_var('page')) - 1)) . ',' . $rows;
if (get_request_var('associated') == 'true') {
$sql_where .= (!strlen($sql_where) ? 'WHERE ' : ' AND ') . '(notify_warning=' . get_request_var('id') . ' OR notify_alert=' . get_request_var('id') . ')';
}
if (strlen(get_request_var('rfilter'))) {
// rfilter is pre-validated as a legal PHP regex by FILTER_VALIDATE_IS_REGEX in the
// request validation array; db_qstr() SQL-escapes the already-validated value.
$sql_where .= (!strlen($sql_where) ? 'WHERE ' : ' AND ') . 'thold_template.name ' . thold_rlike_clause(get_request_var('rfilter'));
}
$sql = "SELECT *
FROM thold_template
$sql_where
$sql_order
$sql_limit";
$result = db_fetch_assoc($sql);
html_start_box(__('Associated Templates', 'thold') . ' ' . html_escape($header_label), '100%', false, '3', 'center', '');
?>
<tr class='even'>
<td>
<form id='listthold' method='get' action='notify_lists.php'>
<table class='filterTable'>
<tr>
<td>
<?php print __('Search', 'thold'); ?>
</td>
<td>
<input type='text' id='rfilter' size='30' value='<?php print html_escape_request_var('rfilter'); ?>'>
</td>
<td>
<?php print __('Rows', 'thold'); ?>
</td>
<td>
<select id='rows'>
<option value='-1'<?php if (get_request_var('rows') == '-1') {?> selected<?php }?>><?php print __('Default', 'thold'); ?></option>
<?php
if (cacti_sizeof($item_rows)) {
foreach ($item_rows as $key => $value) {
print "<option value='" . $key . "'" . (get_request_var('rows') == $key ? ' selected' : '') . '>' . html_escape($value) . '</option>';
}
}
?>
</select>
</td>
<td>
<span>
<input type='checkbox' id='associated' <?php print(get_request_var('associated') == 'true' || get_request_var('associated') == 'on' ? 'checked' : ''); ?>>
<label for='associated'><?php print __('Associated', 'thold'); ?></label>
</span>
</td>
<td>
<span>
<input type='submit' value='<?php print __esc('Go', 'thold'); ?>' title='<?php print __esc('Set/Refresh Filters', 'thold'); ?>'>
<input type='button' id='clear' value='<?php print __esc('Clear', 'thold'); ?>' title='<?php print __esc('Clear Filters', 'thold'); ?>'>
</span>
</td>
</tr>
</table>
</form>
<script type='text/javascript' <?php print plugin_thold_csp_nonce(); ?>>
function applyFilter() {
strURL = 'notify_lists.php?header=false&action=edit&tab=templates&id=<?php print get_request_var('id'); ?>'
strURL += '&associated=' + $('#associated').is(':checked');
strURL += '&rows=' + encodeURIComponent($('#rows').val());
strURL += '&rfilter=' + encodeURIComponent(base64_encode($('#rfilter').val()));
loadPageNoHeader(strURL);
}
function clearFilter() {
strURL = 'notify_lists.php?header=false&action=edit&tab=templates&id=<?php print get_request_var('id'); ?>&clear=true'
loadPageNoHeader(strURL);
}
$(function() {
$('#listthold').submit(function(event) {
event.preventDefault();
applyFilter();
});
$('#rfilter, #rows, #associated').off('change').on('change', function() {
applyFilter();
});
$('#clear').click(function() {
clearFilter();
});
});
</script>
</td>
</tr>
<?php
html_end_box();
$total_rows = db_fetch_cell("SELECT count(*)
FROM thold_template
$sql_where");
$nav = html_nav_bar('notify_lists.php?action=edit&tab=templates&id=' . get_filter_request_var('id'), MAX_DISPLAY_PAGES, get_request_var('page'), $rows, $total_rows, 10, 'Lists', 'page', 'main');
form_start('notify_lists.php', 'chk');
print $nav;
html_start_box('', '100%', false, '3', 'center', '');
$display_text = [
'name' => [__('Name', 'thold'), 'ASC'],
'id' => [__('ID', 'thold'), 'ASC'],
'nosort1' => [__('Warning Lists', 'thold'), 'ASC'],
'nosort2' => [__('Alert Lists', 'thold'), 'ASC'],
'thold_type' => [__('Type', 'thold'), 'ASC']];
html_header_sort_checkbox($display_text, get_request_var('sort_column'), get_request_var('sort_direction'), false, 'notify_lists.php?action=edit&tab=templates&id=' . get_filter_request_var('id'));
$c = 0;
if (cacti_sizeof($result)) {
foreach ($result as $row) {
$c++;
// show alert stats first
$alert_stat = '';
$list = db_fetch_cell_prepared('SELECT COUNT(*)
FROM plugin_thold_template_contact
WHERE template_id = ?',
[$row['id']]);
if ($list > 0) {
$alert_stat = "<span class='deviceUp'>" . __('Select Users', 'thold') . '</span>';
}
if (strlen($row['notify_extra'])) {
$alert_stat .= (strlen($alert_stat) ? ', ' : '') . "<span class='deviceRecovering'>" . __('Specific Emails', 'thold') . '</span>';
}
if (!empty($row['notify_alert'])) {
if (get_request_var('id') == $row['notify_alert']) {
$alert_stat .= (strlen($alert_stat) ? ', ' : '') . "<span class='deviceUp'>" . __('Current List', 'thold') . '</span>';
} else {
$alert_info = db_fetch_cell_prepared('SELECT name
FROM plugin_notification_lists
WHERE id = ?',
[$row['notify_alert']]);
if ($alert_info != '') {
$alert_stat .= (strlen($alert_stat) ? ', ' : '') . "<span class='deviceDown'>" . html_escape($alert_info) . '</span>';
} else {
$alert_stat .= (strlen($alert_stat) ? ', ' : '') . "<span class='deviceDown'>" . __('Unknown Template', 'thold') . '</span>';
}
}
}
if (!strlen($alert_stat)) {
$alert_stat = "<span class='deviceUnknown'>" . __('Log Only', 'thold') . '</span>';
}
// show warning stats first
$warn_stat = '';
if (strlen($row['notify_warning_extra'])) {
$warn_stat .= (strlen($warn_stat) ? ', ' : '') . "<span class='deviceRecovering'>" . __('Specific Emails', 'thold') . '</span>';
}
if (!empty($row['notify_warning'])) {
if (get_request_var('id') == $row['notify_warning']) {
$warn_stat .= (strlen($warn_stat) ? ', ' : '') . "<span class='deviceUp'>" . __('Current List', 'thold') . '</span>';
} else {
$warn_list = db_fetch_cell_prepared('SELECT name
FROM plugin_notification_lists
WHERE id = ?',
[$row['notify_warning']]);
$warn_stat .= (strlen($warn_stat) ? ', ' : '') . "<span class='deviceDown'>" . html_escape($warn_list) . '</span>';
}
}
if ((!strlen($warn_stat)) &&
(($row['thold_type'] == 0 && $row['thold_warning_hi'] == '' && $row['thold_warning_low'] == '') ||
($row['thold_type'] == 2 && $row['time_warning_hi'] == '' && $row['time_warning_low'] == ''))) {
$warn_stat = "<span class='deviceDown'>" . __('None', 'thold') . '</span>';
} elseif (!strlen($warn_stat)) {
$warn_stat = "<span class='deviceUnknown'>" . __('Log Only', 'thold') . '</span>';
}
form_alternate_row('line' . $row['id'], true);
form_selectable_cell(filter_value($row['name'], get_request_var('rfilter')), $row['id']);
form_selectable_cell($row['id'], $row['id']);
form_selectable_cell($warn_stat, $row['id']);
form_selectable_cell($alert_stat, $row['id']);
form_selectable_cell($thold_types[$row['thold_type']], $row['id']);
form_checkbox_cell($row['name'], $row['id']);
form_end_row();
}
} else {
print "<tr class='even'><td colspan='" . (cacti_sizeof($display_text) + 1) . "'><i>" . __('No Threshold Templates', 'thold') . '</i></td></tr>';
}
html_end_box(false);
if (cacti_sizeof($result)) {
print $nav;
}
form_hidden_box('tab', 'templates', '');
form_hidden_box('id', get_request_var('id'), '');
form_hidden_box('save_templates', '1', '');
draw_actions_dropdown($assoc_actions);
form_end();
}
/**
* Validates and stores the threshold-templates-tab filter request
* variables (rows, page, filter text, sort column/direction,
* associated flag) into the session for the notification list's
* Templates tab.
*
* @return void
*/
function thold_template_request_validation() {
// ================= input validation and session storage =================
$filters = [
'rows' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
],
'page' => [
'filter' => FILTER_VALIDATE_INT,
'default' => '1'
],
'rfilter' => [
'filter' => FILTER_VALIDATE_IS_REGEX,
'pageset' => true,
'default' => ''
],
'sort_column' => [
'filter' => FILTER_CALLBACK,
'default' => 'name',
'options' => ['options' => 'sanitize_search_string']
],
'sort_direction' => [
'filter' => FILTER_CALLBACK,
'default' => 'ASC',
'options' => ['options' => 'sanitize_search_string']
],
'associated' => [
'filter' => FILTER_CALLBACK,
'default' => 'true',
'options' => ['options' => 'sanitize_search_string']
]
];
validate_store_request_vars($filters, 'sess_nltt');
// ================= input validation =================
}
/**
* Validates and stores the thresholds-tab filter request variables
* (rows, page, filter text, sort column/direction, associated flag)
* into the session for the notification list's Thresholds tab.
*
* @return void
*/
function thold_request_validation() {
// ================= input validation and session storage =================
$filters = [
'rows' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
],
'page' => [
'filter' => FILTER_VALIDATE_INT,
'default' => '1'
],
'site_id' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
],
'rfilter' => [
'filter' => FILTER_VALIDATE_IS_REGEX,
'pageset' => true,
'default' => ''
],
'sort_column' => [
'filter' => FILTER_CALLBACK,
'default' => 'thold_alert',
'options' => ['options' => 'sanitize_search_string']
],
'sort_direction' => [
'filter' => FILTER_CALLBACK,
'default' => 'DESC',
'options' => ['options' => 'sanitize_search_string']
],
'state' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1',
],
'template' => [
'filter' => FILTER_VALIDATE_INT,
'default' => '',
],
'associated' => [
'filter' => FILTER_CALLBACK,
'default' => 'true',
'options' => ['options' => 'sanitize_search_string']
]
];
validate_store_request_vars($filters, 'sess_nlt');
// ================= input validation =================
}
/**
* Renders the main notification lists list page: validates/stores this
* view's filter request variables, then displays a filtered, sorted,
* paginated table of notification lists with a bulk-actions dropdown.
* Called from this script's main request-dispatch switch as the
* default view.
*
* @return void
*
* @global array $actions Map of drp_action value => action label,
* used for the bulk-actions dropdown.
* @global array $item_rows Default number of rows per page from Cacti
* settings.
*/
function lists() {
global $actions, $item_rows;
// ================= input validation and session storage =================
$filters = [
'rows' => [
'filter' => FILTER_VALIDATE_INT,
'pageset' => true,
'default' => '-1'
],
'page' => [
'filter' => FILTER_VALIDATE_INT,
'default' => '1'
],
'rfilter' => [
'filter' => FILTER_VALIDATE_IS_REGEX,
'pageset' => true,
'default' => ''
],
'sort_column' => [
'filter' => FILTER_CALLBACK,
'default' => 'description',
'options' => ['options' => 'sanitize_search_string']
],
'sort_direction' => [
'filter' => FILTER_CALLBACK,
'default' => 'ASC',
'options' => ['options' => 'sanitize_search_string']
]
];
validate_store_request_vars($filters, 'sess_lists');
// ================= input validation =================
// if the number of rows is -1, set it to the default
if (get_request_var('rows') == -1) {
$rows = read_config_option('num_rows_table');
} else {
$rows = get_request_var('rows');
}
html_start_box(__('Notification Lists', 'thold'), '100%', false, '3', 'center', 'notify_lists.php?action=edit');
?>
<tr class='even'>
<td>
<form id='lists' action='notify_lists.php'>
<table class='filterTable'>
<tr>
<td>
<?php print __('Search', 'thold')?>
</td>
<td>
<input type='text' id='rfilter' size='30' value='<?php print html_escape_request_var('rfilter'); ?>'>
</td>
<td>
<?php print __('Lists', 'thold')?>
</td>
<td>
<select id='rows'>
<option value='-1'<?php if (get_request_var('rows') == '-1') {?> selected<?php }?>><?php print __('Default', 'thold'); ?></option>
<?php
if (cacti_sizeof($item_rows)) {
foreach ($item_rows as $key => $value) {
print "<option value='" . $key . "'" . (get_request_var('rows') == $key ? ' selected' : '') . '>' . html_escape($value) . '</option>';
}
}
?>
</select>
</td>
<td>
<input id='refresh' type='button' value='<?php print __esc('Go', 'thold'); ?>' title='<?php print __esc('Set/Refresh Filters', 'thold'); ?>'>
</td>
<td>
<input id='clear' type='button' value='<?php print __esc('Clear', 'thold'); ?>' title='<?php print __esc('Clear Filters', 'thold'); ?>'>
</td>
</tr>
</table>
</form>
<script type='text/javascript' <?php print plugin_thold_csp_nonce(); ?>>
function applyFilter() {
strURL = 'notify_lists.php?header=false';
strURL += '&rows=' + encodeURIComponent($('#rows').val());
strURL += '&rfilter=' + encodeURIComponent(base64_encode($('#rfilter').val()));
loadPageNoHeader(strURL);
}
function clearFilter() {
strURL = 'notify_lists.php?header=false&clear=1';
loadPageNoHeader(strURL);
}
$(function() {
$('#lists').submit(function(event) {
event.preventDefault();
applyFilter();
});
$('#rows').off('change').on('change', function() {
applyFilter();
});
$('#clear').click(function() {
clearFilter();
});
});
</script>
</td>
</tr>
<?php
html_end_box();
// form the 'where' clause for our main sql query
if (strlen(get_request_var('rfilter'))) {
// rfilter is pre-validated as a legal PHP regex by FILTER_VALIDATE_IS_REGEX in the
// request validation array; db_qstr() SQL-escapes the already-validated value.
$sql_where = 'WHERE (
name ' . thold_rlike_clause(get_request_var('rfilter')) . '
OR description ' . thold_rlike_clause(get_request_var('rfilter')) . '
OR emails ' . thold_rlike_clause(get_request_var('rfilter')) . ')';
} else {
$sql_where = '';
}
$total_rows = db_fetch_cell("SELECT
COUNT(*)
FROM plugin_notification_lists
$sql_where");
$sql_order = get_order_string();
$sql_limit = ' LIMIT ' . ($rows * (intval(get_request_var('page')) - 1)) . ',' . $rows;
$lists = db_fetch_assoc("SELECT id, name, enabled, description, emails,
(SELECT COUNT(id) FROM thold_data WHERE notify_alert = nl.id) as thold_alerts,
(SELECT COUNT(id) FROM thold_data WHERE notify_warning = nl.id) as thold_warnings,
(SELECT COUNT(id) FROM thold_template WHERE notify_alert = nl.id) as template_alerts,
(SELECT COUNT(id) FROM thold_template WHERE notify_warning = nl.id) as template_warnings,
(SELECT COUNT(id) FROM host WHERE thold_host_email = nl.id) as hosts
FROM plugin_notification_lists nl
$sql_where
$sql_order
$sql_limit");
$nav = html_nav_bar('notify_lists.php', MAX_DISPLAY_PAGES, get_request_var('page'), $rows, $total_rows, 10, __('Lists', 'thold'), 'page', 'main');
form_start('notify_lists.php', 'chk');
print $nav;
html_start_box('', '100%', false, '3', 'center', '');
$display_text = [
'name' => [__('List Name', 'thold'), 'ASC'],
'enabled' => [__('Enabled', 'thold'), 'ASC'],
'nosort1' => [__('Devices', 'thold'), ''],
'nosort2' => [__('Thresholds', 'thold'), ''],
'nosort3' => [__('Templates', 'thold'), ''],
'description' => [__('Description', 'thold'), 'ASC'],
'emails' => [__('Emails', 'thold'), 'ASC']];
html_header_sort_checkbox($display_text, get_request_var('sort_column'), get_request_var('sort_direction'), false);
if (cacti_sizeof($lists)) {
foreach ($lists as $item) {
// Add wrappable characters to emails
$item['emails'] = implode(', ', explode(',', $item['emails']));
form_alternate_row('line' . $item['id'], true);
form_selectable_cell(filter_value($item['name'], get_request_var('rfilter'), 'notify_lists.php?action=edit&id=' . $item['id']), $item['id']);
form_selectable_cell($item['enabled'] == 'on' ? __('Yes', 'thold') : __('No', 'thold'), $item['id'], '', 'white-space:pre-wrap');
form_selectable_cell(filter_value($item['hosts'], get_request_var('rfilter'), 'notify_lists.php?tab=hosts&action=edit&id=' . $item['id']), $item['id']);
form_selectable_cell(filter_value('Warn: ' . $item['thold_warnings'] . ', Alert: ' . $item['thold_alerts'] , get_request_var('rfilter'), 'notify_lists.php?tab=tholds&action=edit&id=' . $item['id']), $item['id']);
form_selectable_cell(filter_value('Warn: ' . $item['template_warnings'] . ', Alert: ' . $item['template_alerts'] , get_request_var('rfilter'), 'notify_lists.php?tab=templates&action=edit&id=' . $item['id']), $item['id']);
form_selectable_cell(filter_value($item['description'], get_request_var('rfilter')), $item['id'], '', 'wrap');
form_selectable_cell(filter_value($item['emails'], get_request_var('rfilter')), $item['id'], '', 'white-space:pre-wrap');
form_checkbox_cell($item['name'], $item['id']);
form_end_row();
}
} else {
print '<tr><td colspan="' . (cacti_sizeof($display_text) + 1) . '"><em>' . __('No Notification Lists', 'thold') . '</em></td></tr>';
}
html_end_box(false);
if (cacti_sizeof($lists)) {
print $nav;
}
form_hidden_box('save_list', '1', '');
// draw the dropdown containing a list of available actions for this form
draw_actions_dropdown($actions);
form_end();
}