diff --git a/pandora_console/extras/mr/45.sql b/pandora_console/extras/mr/45.sql
new file mode 100644
index 0000000000..584908f813
--- /dev/null
+++ b/pandora_console/extras/mr/45.sql
@@ -0,0 +1,6 @@
+START TRANSACTION;
+
+ALTER TABLE `tnotification_source` ADD COLUMN `subtype_blacklist` TEXT;
+
+COMMIT;
+
diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql
index 946db364f7..64683c2096 100644
--- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql
+++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql
@@ -2392,6 +2392,7 @@ CREATE TABLE `tnotification_source` (
`enabled` int(1) DEFAULT NULL,
`user_editable` int(1) DEFAULT NULL,
`also_mail` int(1) DEFAULT NULL,
+ `subtype_blacklist` TEXT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/pandora_console/godmode/setup/setup_notifications.php b/pandora_console/godmode/setup/setup_notifications.php
index 102f47b634..a03812ddc4 100644
--- a/pandora_console/godmode/setup/setup_notifications.php
+++ b/pandora_console/godmode/setup/setup_notifications.php
@@ -65,6 +65,7 @@ if (get_parameter('remove_source_on_database', 0)) {
if (get_parameter('update_config', 0)) {
$element = (string) get_parameter('element', '');
$value = (int) get_parameter('value', 0);
+ $source = (string) get_parameter('source');
// Update the label value.
ob_clean();
@@ -75,6 +76,37 @@ if (get_parameter('update_config', 0)) {
$res = ($value) ? notifications_add_group_to_source($source, [0]) : notifications_remove_group_from_source($source, [0]);
break;
+ case 'subtype':
+ $data = explode('.', $source, 2);
+ $source_id = $data[0];
+ $subtype = $data[1];
+ $source = notifications_get_all_sources(
+ [ 'id' => $source_id ]
+ );
+
+ if ($source !== false && is_array($source[0]) === true) {
+ $source = $source[0];
+
+ $blacklist = json_decode($source['subtype_blacklist'], 1);
+ if (json_last_error() !== JSON_ERROR_NONE) {
+ $blacklist = [];
+ }
+
+ if ((bool) $value === true) {
+ unset($blacklist[$subtype]);
+ } else {
+ $blacklist[$subtype] = 1;
+ }
+
+ $source['subtype_blacklist'] = json_encode($blacklist, 1);
+ $res = (bool) db_process_sql_update(
+ 'tnotification_source',
+ ['subtype_blacklist' => $source['subtype_blacklist']],
+ ['id' => $source['id']]
+ );
+ }
+ break;
+
default:
$res = (bool) db_process_sql_update(
'tnotification_source',
@@ -337,7 +369,7 @@ function remove_source_elements(id, source_id) {
function notifications_handle_change_element(event) {
event.preventDefault();
- var match = /nt-([0-9]+)-(.*)/.exec(event.target.id);
+ var match = /nt-(.+)-(.*)/.exec(event.target.id);
if (!match) {
console.error(
"Cannot handle change element. Id not valid: ", event.target.id
@@ -356,6 +388,7 @@ function notifications_handle_change_element(event) {
var value;
switch (action.bit) {
case 'enabled':
+ case 'subtype':
case 'also_mail':
case 'user_editable':
case 'all_users':
@@ -383,6 +416,7 @@ function notifications_handle_change_element(event) {
} else {
switch (action.bit) {
case 'enabled':
+ case 'subtype':
case 'also_mail':
case 'user_editable':
case 'all_users':
diff --git a/pandora_console/include/class/ConsoleSupervisor.php b/pandora_console/include/class/ConsoleSupervisor.php
index cc52f2062f..017d4a1a80 100644
--- a/pandora_console/include/class/ConsoleSupervisor.php
+++ b/pandora_console/include/class/ConsoleSupervisor.php
@@ -115,12 +115,6 @@ class ConsoleSupervisor
} else {
$this->enabled = (bool) $source['enabled'];
$this->sourceId = $source['id'];
-
- // Assign targets.
- $targets = get_notification_source_targets($this->sourceId);
- $this->targetGroups = $targets['groups'];
- $this->targetUsers = $targets['users'];
- $this->targetUpdated = true;
}
return $this;
@@ -620,20 +614,28 @@ class ConsoleSupervisor
return;
}
- if ($this->targetUpdated === false) {
- $targets = get_notification_source_targets($this->sourceId);
- $this->targetGroups = $targets['groups'];
- $this->targetUsers = $targets['users'];
- $this->targetUpdated = false;
- }
-
if ($source_id === 0) {
$source_id = $this->sourceId;
- // Assign targets.
- $targets = get_notification_source_targets($source_id);
+ }
+
+ static $_cache_targets;
+ $key = $source_id.'|'.$data['type'];
+
+ if ($_cache_targets === null) {
+ $_cache_targets = [];
+ }
+
+ if ($_cache_targets[$key] !== null) {
+ $targets = $_cache_targets[$key];
+ } else {
+ $targets = get_notification_source_targets(
+ $source_id,
+ $data['type']
+ );
$this->targetGroups = $targets['groups'];
$this->targetUsers = $targets['users'];
- $this->targetUpdated = false;
+
+ $_cache_targets[$key] = $targets;
}
switch ($data['type']) {
diff --git a/pandora_console/include/functions_notifications.php b/pandora_console/include/functions_notifications.php
index 67e5c6e547..05371f6b3c 100644
--- a/pandora_console/include/functions_notifications.php
+++ b/pandora_console/include/functions_notifications.php
@@ -116,6 +116,68 @@ function get_notification_targets(int $id_message)
}
+/**
+ * Return subtypes.
+ *
+ * @param string|null $source Source filter or all.
+ *
+ * @return array
+ */
+function notifications_get_subtypes(?string $source=null)
+{
+ $subtypes = [
+ 'System status' => [
+ 'NOTIF.LICENSE.LIMITED',
+ 'NOTIF.LICENSE.EXPIRATION',
+ 'NOTIF.FILES.ATTACHMENT',
+ 'NOTIF.FILES.DATAIN',
+ 'NOTIF.FILES.DATAIN.BADXML',
+ 'NOTIF.PHP.SAFE_MODE',
+ 'NOTIF.PHP.INPUT_TIME',
+ 'NOTIF.PHP.EXECUTION_TIME',
+ 'NOTIF.PHP.UPLOAD_MAX_FILESIZE',
+ 'NOTIF.PHP.MEMORY_LIMIT',
+ 'NOTIF.PHP.DISABLE_FUNCTIONS',
+ 'NOTIF.PHP.PHANTOMJS',
+ 'NOTIF.PHP.VERSION',
+ 'NOTIF.HISTORYDB',
+ 'NOTIF.PANDORADB',
+ 'NOTIF.PANDORADB.HISTORICAL',
+ 'NOTIF.HISTORYDB.MR',
+ 'NOTIF.EXT.ELASTICSEARCH',
+ 'NOTIF.EXT.LOGSTASH',
+ 'NOTIF.METACONSOLE.DB_CONNECTION',
+ 'NOTIF.DOWNTIME',
+ 'NOTIF.UPDATEMANAGER.REGISTRATION',
+ 'NOTIF.MISC.EVENTSTORMPROTECTION',
+ 'NOTIF.MISC.DEVELOPBYPASS',
+ 'NOTIF.MISC.FONTPATH',
+ 'NOTIF.SECURITY.DEFAULT_PASSWORD',
+ 'NOTIF.UPDATEMANAGER.OPENSETUP',
+ 'NOTIF.UPDATEMANAGER.UPDATE',
+ 'NOTIF.UPDATEMANAGER.MINOR',
+ 'NOTIF.UPDATEMANAGER.MESSAGES',
+ 'NOTIF.CRON.CONFIGURED',
+ 'NOTIF.ALLOWOVERRIDE.MESSAGE',
+ 'NOTIF.HAMASTER.MESSAGE',
+ 'NOTIF.SERVER.STATUS',
+ 'NOTIF.SERVER.QUEUE',
+ 'NOTIF.SERVER.MASTER',
+ ],
+ ];
+
+ if ($source === null) {
+ return $subtypes;
+ }
+
+ if (isset($subtypes[$source]) === true) {
+ return $subtypes[$source];
+ }
+
+ return [];
+}
+
+
/**
* Check if current user has grants to read this notification
*
@@ -160,14 +222,28 @@ function check_notification_readable(int $id_message)
* Returns the target users and groups assigned to be notified on
* desired source.
*
- * @param integer $id_source Source identificator.
+ * @param integer $id_source Source identificator.
+ * @param string|null $subtype Subtype identification.
*
* @return array [users] and [groups] with the targets.
*/
-function get_notification_source_targets(int $id_source)
+function get_notification_source_targets(int $id_source, ?string $subtype=null)
{
$ret = [];
+ $filter = '';
+ if ($subtype !== null) {
+ $matches = [];
+ if (preg_match('/(.*)\.\d+$/', $subtype, $matches) > 0) {
+ $subtype = $matches[1];
+ }
+
+ $filter = sprintf(
+ ' AND ns.`subtype_blacklist` NOT LIKE "%%%s%%"',
+ $subtype
+ );
+ }
+
$users = db_get_all_rows_sql(
sprintf(
'SELECT
@@ -176,9 +252,11 @@ function get_notification_source_targets(int $id_source)
FROM tnotification_source_user nsu
INNER JOIN tnotification_source ns
ON ns.id=nsu.id_source
+ %s
WHERE ns.id = %d
AND ((ns.enabled is NULL OR ns.enabled != 0)
OR (nsu.enabled is NULL OR nsu.enabled != 0))',
+ $filter,
$id_source
)
);
@@ -197,8 +275,10 @@ function get_notification_source_targets(int $id_source)
FROM tnotification_source_group nsg
INNER JOIN tnotification_source ns
ON ns.id=nsg.id_source
+ %s
WHERE ns.id = %d
AND (ns.enabled is NULL OR ns.enabled != 0)',
+ $filter,
$id_source
)
);
@@ -700,8 +780,47 @@ function notifications_print_global_source_configuration($source)
);
$html_selectors .= '';
+ $html_checkboxes = '';
+
+ $blacklist = json_decode($source['subtype_blacklist'], 1);
+ if (json_last_error() !== JSON_ERROR_NONE) {
+ $blacklist = [];
+ }
+
+ if ($source['description'] === io_safe_input('System status')) {
+ $system_subtypes = notifications_get_subtypes('System status');
+
+ foreach ($system_subtypes as $type) {
+ $html_checkboxes .= html_print_input(
+ [
+ 'input_class' => 'flex flex-row w290px margin-soft',
+ 'label' => $type,
+ 'name' => 'check-'.$type,
+ 'type' => 'switch',
+ 'id' => 'nt-'.$source['id'].'.'.$type.'-subtype',
+ 'class' => 'elem-clickable',
+ 'value' => (isset($blacklist[$type]) === false),
+ 'return' => true,
+ ]
+ );
+ }
+
+ $html_checkboxes = ui_print_toggle(
+ [
+ 'content' => $html_checkboxes,
+ 'name' => __('Subtype customization'),
+ 'hidden_default' => false,
+ 'return' => true,
+ 'toggle_class' => '',
+ 'container_class' => 'flex flex-row flex-start w100p',
+ 'main_class' => '',
+ 'clean' => true,
+ ]
+ );
+ }
+
// Return all html.
- return $html_title.$html_selectors.$html_checkboxes.$html_select_pospone;
+ return $html_title.$html_selectors.$html_checkboxes;
}
diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php
index b9d75f69c6..27bcb1313e 100755
--- a/pandora_console/include/functions_ui.php
+++ b/pandora_console/include/functions_ui.php
@@ -3821,7 +3821,9 @@ function ui_toggle(
$main_class = '';
}
- $container_class = 'white-box-content-clean';
+ if (empty($container_class) === true) {
+ $container_class = 'white-box-content-clean';
+ }
}
// Link to toggle.
@@ -3943,7 +3945,24 @@ function ui_toggle(
/**
* Simplified way of ui_toggle ussage.
*
- * @param array $data Arguments.
+ * @param array $data Arguments:
+ * 'content'
+ * 'name'
+ * 'title'
+ * 'id'
+ * 'hidden_default'
+ * 'return'
+ * 'toggle_class'
+ * 'container_class'
+ * 'main_class'
+ * 'img_a'
+ * 'img_b'
+ * 'clean'
+ * 'reverseImg'
+ * 'switch'
+ * 'attributes_switch'
+ * 'toggl_attr'
+ * 'switch_on'.
*
* @return string HTML code with toggle content.
*/
diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css
index 31e7a60251..afb5b8ad5c 100644
--- a/pandora_console/include/styles/pandora.css
+++ b/pandora_console/include/styles/pandora.css
@@ -478,6 +478,10 @@ select:-internal-list-box {
width: 290px;
max-width: 290px;
}
+.w500px {
+ width: 500px;
+ max-width: 500px;
+}
.mw120px {
min-width: 120px;
}
@@ -626,6 +630,13 @@ select:-internal-list-box {
align-items: flex-start;
}
+.flex-row-reverse {
+ display: flex;
+ flex-direction: row-reverse;
+ flex-wrap: wrap;
+ align-items: flex-start;
+}
+
.flex-space-around {
justify-content: space-around;
}
@@ -652,6 +663,9 @@ select:-internal-list-box {
.padding-right-2-imp {
padding-right: 2em !important;
}
+.margin-soft {
+ margin: 0.3em 1em;
+}
.margin-right-1 {
margin-right: 1em;
}
diff --git a/pandora_console/operation/users/user_edit_notifications.php b/pandora_console/operation/users/user_edit_notifications.php
index 611530a3b4..6e227024fa 100644
--- a/pandora_console/operation/users/user_edit_notifications.php
+++ b/pandora_console/operation/users/user_edit_notifications.php
@@ -89,8 +89,9 @@ foreach ($sources as $source) {
echo '';
}
-if ($disabled_flag) {
- echo 'Disabled controls have been set by the system administrator';
+if ((bool) $disabled_flag === true) {
+ $s = __('Controls have been disabled by the system administrator');
+ echo ''.$s.'';
}
echo '';
diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql
index 090e87fd2e..32d025b128 100644
--- a/pandora_console/pandoradb.sql
+++ b/pandora_console/pandoradb.sql
@@ -1317,6 +1317,7 @@ CREATE TABLE `tnotification_source` (
`enabled` int(1) DEFAULT NULL,
`user_editable` int(1) DEFAULT NULL,
`also_mail` int(1) DEFAULT NULL,
+ `subtype_blacklist` TEXT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;