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;