From 1f25998d499244a980ce25296da3474b4538d44f Mon Sep 17 00:00:00 2001 From: ramonn Date: Mon, 26 Nov 2012 16:44:41 +0000 Subject: [PATCH] 2012-11-26 Ramon Novoa * include/functions_groups.php, include/functions_agents.php, include/functions_treeview.php, include/functions_os.php, include/functions_tags.php, operation/tree.php: Added metaconsole support to the tree view. git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7184 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f --- pandora_console/ChangeLog | 9 + pandora_console/include/functions_agents.php | 56 +- pandora_console/include/functions_groups.php | 11 + pandora_console/include/functions_os.php | 5 + pandora_console/include/functions_tags.php | 195 +------ .../include/functions_treeview.php | 526 ++++++++++++++---- pandora_console/operation/tree.php | 340 ++++------- 7 files changed, 596 insertions(+), 546 deletions(-) diff --git a/pandora_console/ChangeLog b/pandora_console/ChangeLog index bb7d01ce51..cfb02695e3 100644 --- a/pandora_console/ChangeLog +++ b/pandora_console/ChangeLog @@ -1,3 +1,12 @@ +2012-11-26 Ramon Novoa + + * include/functions_groups.php, + include/functions_agents.php, + include/functions_treeview.php, + include/functions_os.php, + include/functions_tags.php, + operation/tree.php: Added metaconsole support to the tree view. + 2012-11-26 Sergio Martin * include/functions_ui.php diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index ea4c1e0a53..fc37ec9741 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -355,71 +355,31 @@ function agents_get_agents ($filter = false, $fields = false, $access = 'AR', $o } $status_sql = ' 1 = 1'; - if (isset($filter['status'])) { - $normal_modules = 'SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente_modulo.disabled = 0 AND estado = 0 - AND (utimestamp != 0)'; - - $warning_modules = 'SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente_modulo.disabled = 0 AND estado = 2 AND tagente_estado.utimestamp != 0'; - - - $critical_modules = 'SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente.disabled = 0 AND tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente_modulo.disabled = 0 AND estado = 1 AND tagente_estado.utimestamp != 0'; - - $unknown_modules = 'SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente.disabled = 0 AND tagente.id_agente = tagente_estado.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente_modulo.disabled = 0 AND estado = 3 AND utimestamp != 0'; - - $notinit_modules = 'SELECT tagente_estado.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente.disabled = 0 AND tagente.id_agente = tagente_estado.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente_modulo.disabled = 0 - AND tagente_modulo.id_tipo_modulo NOT IN (21,22,23) - AND utimestamp = 0'; - + if (isset($filter['status'])) { switch ($filter['status']) { // Normal case 0: - $status_sql = "id_agente IN ($normal_modules) && id_agente NOT IN ($warning_modules) && - id_agente NOT IN ($critical_modules) && id_agente NOT IN ($unknown_modules)"; //&& id_agente NOT IN ($notinit_modules)"; + $status_sql = "normal_count=total_count"; break; // Warning case 2: - $status_sql = "id_agente IN ($warning_modules) && - id_agente NOT IN ($critical_modules)"; //&& id_agente NOT IN ($notinit_modules)"; + $status_sql = "critical_count=0 AND warning_count>0"; break; // Critical case 1: - $status_sql = "id_agente IN ($critical_modules)"; + $status_sql = "critical_count>0"; break; // Unknown case 3: - $status_sql = "id_agente IN ($unknown_modules) && - id_agente NOT IN ($critical_modules) && id_agente NOT IN ($warning_modules)"; + $status_sql = "critical_count=0 AND warning_count=0 AND unknown_count>0"; break; // Not normal case 4: - //$status_sql = "id_agente NOT IN ($normal_modules)"; - $status_sql = "id_agente NOT IN ($normal_modules) || id_agente IN ($warning_modules) || - id_agente IN ($critical_modules) || id_agente IN ($unknown_modules)"; + $status_sql = "normal_count<>total_count"; break; // Not init case 5: - $status_sql = "id_agente NOT IN ($warning_modules) && - id_agente NOT IN ($critical_modules) && id_agente NOT IN ($unknown_modules) && id_agente NOT IN ($normal_modules)"; + $status_sql = "notinit_count=total_count"; break; } unset($filter['status']); @@ -2032,4 +1992,4 @@ function agents_tree_view_status_img ($critical, $warning, $unknown) { return ui_print_status_image (STATUS_AGENT_OK, __('All Monitors OK'), true); } } -?> \ No newline at end of file +?> diff --git a/pandora_console/include/functions_groups.php b/pandora_console/include/functions_groups.php index 595b8e67fd..c82f80bdfe 100644 --- a/pandora_console/include/functions_groups.php +++ b/pandora_console/include/functions_groups.php @@ -557,6 +557,17 @@ function groups_get_name ($id_group, $returnAllGroup = false) { return "All"; } +/** + * Return the id of a group given its name. + * + * @param string Name of the group. + * + * @return int The id of the given group. + */ +function groups_get_id ($group_name, $returnAllGroup = false) { + return db_get_value ('id_grupo', 'tgrupo', 'nombre', $group_name); +} + /** * Get all the users belonging to a group. * diff --git a/pandora_console/include/functions_os.php b/pandora_console/include/functions_os.php index 6a0bfc6b4b..6c85faa1f5 100755 --- a/pandora_console/include/functions_os.php +++ b/pandora_console/include/functions_os.php @@ -44,4 +44,9 @@ function os_agents_unknown ($id_os) { return db_get_sql ("SELECT COUNT(*) FROM tagente WHERE critical_count=0 AND warning_count=0 AND unknown_count>0 AND id_os=$id_os"); } +// Get the name of a group given its id. +function os_get_name ($id_os) { + return db_get_value ('name', 'tconfig_os', 'id_os', (int) $id_os); +} + ?> diff --git a/pandora_console/include/functions_tags.php b/pandora_console/include/functions_tags.php index 95d1b9345e..5cf15ab858 100644 --- a/pandora_console/include/functions_tags.php +++ b/pandora_console/include/functions_tags.php @@ -27,22 +27,12 @@ * @return mixed Returns count of agents in critical status or false if they aren't. */ function tags_agent_critical ($id_tag) { - - if (empty($id_tag)) - return false; - - //TODO REVIEW ORACLE AND POSTGRES - return db_get_sql ("SELECT COUNT( DISTINCT tagente_estado.id_agente) - FROM tagente_estado, tagente, tagente_modulo, ttag_module - WHERE tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo - AND tagente_modulo.id_agente_modulo = ttag_module.id_agente_modulo - AND tagente_estado.id_agente = tagente.id_agente - AND tagente_modulo.disabled = 0 - AND estado = 1 - AND tagente.disabled = 0 - AND tagente_estado.utimestamp != 0 - AND ttag_module.id_tag = $id_tag"); + return db_get_sql ("SELECT COUNT(*) FROM tagente, tagente_modulo, ttag_module + WHERE tagente.id_agente = tagente_modulo.id_agente + AND tagente_modulo.id_agente_modulo = ttag_module.id_agente_modulo + AND ttag_module.id_tag = $id_tag + AND critical_count>0"); } /** @@ -53,54 +43,12 @@ function tags_agent_critical ($id_tag) { * @return mixed Returns count of agents in unknown status or false if they aren't. */ function tags_agent_unknown ($id_tag) { - - if (empty($id_tag)) - return false; - - // Agent of module group X and critical status - $agents_critical = "SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND estado = 1 - AND tagente_estado.utimestamp != 0 - group by tagente.id_agente"; - // Agent of module group X and warning status - $agents_warning = "SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND estado = 2 - AND tagente_estado.utimestamp != 0 - group by tagente.id_agente"; - - // Agent of module group X and unknown status - $agents_unknown = "SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND estado = 3 - AND tagente_estado.utimestamp != 0 - group by tagente.id_agente"; - - return db_get_sql ("SELECT COUNT(*) FROM ( SELECT DISTINCT tagente.id_agente - FROM tagente, tagente_modulo, tagente_estado, ttag_module + return db_get_sql ("SELECT COUNT(*) FROM tagente, tagente_modulo, ttag_module WHERE tagente.id_agente = tagente_modulo.id_agente - AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo AND tagente_modulo.id_agente_modulo = ttag_module.id_agente_modulo - - AND ttag_module.id_tag = $id_tag - AND tagente.id_agente NOT IN ($agents_critical) - AND tagente.id_agente NOT IN ($agents_warning) - AND tagente.id_agente IN ($agents_unknown) ) AS t"); - + AND ttag_module.id_tag = $id_tag + AND critical_count=0 AND warning_count=0 AND unknown_count>0"); } /** @@ -125,29 +73,6 @@ function tags_total_agents ($id_tag) { return db_get_sql ($total_agents); } -/** - * Get total agents filtering by id_tag that are disabled. - * - * @param int $id_tag Id of the tag to search total agents - * - * @return mixed Returns count of agents with this tag or false if they aren't. - */ -function tags_agent_disabled ($id_tag) { - - // Avoid mysql error - if (empty($id_tag)) - return; - - $total_agents_disabled = "SELECT COUNT(DISTINCT tagente.id_agente) - FROM tagente, tagente_modulo, ttag_module - WHERE tagente.id_agente = tagente_modulo.id_agente - AND tagente_modulo.id_agente_modulo = ttag_module.id_agente_modulo - AND tagente.disabled = 1 - AND ttag_module.id_tag = " . $id_tag; - - return db_get_sql ($total_agents_disabled); -} - /** * Get normal agents by using the status code in modules by filtering by id_tag. * @@ -156,66 +81,12 @@ function tags_agent_disabled ($id_tag) { * @return mixed Returns count of agents in normal status or false if they aren't. */ function tags_agent_ok ($id_tag) { - - if (empty($id_tag)) - return false; - - // Agent of module group X and critical status - $agents_critical = "SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND estado = 1 - AND tagente_estado.utimestamp != 0 - group by tagente.id_agente"; - // Agent of module group X and warning status - $agents_warning = "SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND estado = 2 - AND tagente_estado.utimestamp != 0 - group by tagente.id_agente"; - - // Agent of module group X and unknown status - $agents_unknown = "SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND estado = 3 - AND tagente_estado.utimestamp != 0 - group by tagente.id_agente"; - - // Agent of module group X and ok status - $agents_ok = "SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND estado = 0 - AND tagente_estado.utimestamp != 0 - group by tagente.id_agente"; - - return db_get_sql ("SELECT COUNT(*) FROM ( SELECT DISTINCT tagente.id_agente - FROM tagente, tagente_modulo, tagente_estado, ttag_module + return db_get_sql ("SELECT COUNT(*) FROM tagente, tagente_modulo, ttag_module WHERE tagente.id_agente = tagente_modulo.id_agente - AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo AND tagente_modulo.id_agente_modulo = ttag_module.id_agente_modulo - AND ttag_module.id_tag = $id_tag - AND tagente.id_agente NOT IN ($agents_critical) - AND tagente.id_agente NOT IN ($agents_warning) - AND tagente.id_agente NOT IN ($agents_unknown) - AND tagente.id_agente IN ($agents_ok)) AS t"); - + AND normal_count=total_count"); } /** @@ -227,40 +98,11 @@ function tags_agent_ok ($id_tag) { */ function tags_agent_warning ($id_tag) { - if (empty($id_tag)) - return false; - - // Agent critical status - $agents_critical = "SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND estado = 1 - AND tagente_estado.utimestamp != 0 - group by tagente.id_agente"; - - // Agent warning status - $agents_warning = "SELECT tagente.id_agente - FROM tagente_estado, tagente, tagente_modulo - WHERE tagente_estado.id_agente = tagente.id_agente - AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo - AND tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND estado = 2 - AND tagente_estado.utimestamp != 0 - group by tagente.id_agente"; - - return db_get_sql ("SELECT COUNT(*) FROM ( SELECT DISTINCT tagente.id_agente - FROM tagente, tagente_modulo, tagente_estado, ttag_module + return db_get_sql ("SELECT COUNT(*) FROM tagente, tagente_modulo, ttag_module WHERE tagente.id_agente = tagente_modulo.id_agente - AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo AND tagente_modulo.id_agente_modulo = ttag_module.id_agente_modulo - AND ttag_module.id_tag = $id_tag - AND tagente.id_agente NOT IN ($agents_critical) - AND tagente.id_agente IN ($agents_warning)) AS t"); + AND critical_count=0 AND warning_count>0"); } /** @@ -373,6 +215,17 @@ function tags_get_name($id){ return db_get_value_filter ('name', 'ttag', array('id_tag' => $id)); } +/** + * Get tag id given the tag name. + * + * @param string Tag name. + * + * @return int Tag id. + */ +function tags_get_id($name){ + return db_get_value_filter ('id_tag', 'ttag', array('name' => $name)); +} + /** * Get tag description. * @@ -711,4 +564,4 @@ function tags_get_all_tags () { return $return; } -?> \ No newline at end of file +?> diff --git a/pandora_console/include/functions_treeview.php b/pandora_console/include/functions_treeview.php index 3fc3ed3390..18479d3057 100755 --- a/pandora_console/include/functions_treeview.php +++ b/pandora_console/include/functions_treeview.php @@ -191,17 +191,116 @@ function treeview_printTable($id_agente) { function treeview_printTree($type) { global $config; - $search_free = get_parameter('search_free', ''); - $select_status = get_parameter('status', -1); - echo ''; echo ''; + echo '
'; + if (! defined ('METACONSOLE')) { + $list = treeview_getData ($type); + } + else { + $servers = db_get_all_rows_sql ("SELECT * FROM tmetaconsole_setup WHERE disabled = 0"); + if ($servers === false) { + $servers = array(); + } + + $list = array (); + foreach ($servers as $server) { + if (metaconsole_connect($server) != NOERR) { + continue; + } + $server_list = treeview_getData ($type, $server); + foreach ($server_list as $server_item) { + if (! isset ($list[$server_item['_name_']])) { + $list[$server_item['_name_']] = $server_item; + } + // Merge! + else { + $list[$server_item['_name_']]['_num_ok_'] += $server_item['_num_ok_']; + $list[$server_item['_name_']]['_num_critical_'] += $server_item['_num_critical_']; + $list[$server_item['_name_']]['_num_warning_'] += $server_item['_num_warning_']; + $list[$server_item['_name_']]['_num_unknown_'] += $server_item['_num_unknown_']; + } + } + echo "
"; + } + + metaconsole_restore_db(); + } + + if ($list === false) { + ui_print_error_message("There aren't agents in this agrupation"); + echo '
'; + } + else { + echo "
    \n"; + + $first = true; + foreach ($list as $item) { + $lessBranchs = 0; + if ($first) { + if ($item != end($list)) { + $img = html_print_image ("operation/tree/first_closed.png", true, array ("style" => 'vertical-align: middle;', "id" => "tree_image_" . $type . "_" . $item['_id_'], "pos_tree" => "0")); + $first = false; + } + else { + $lessBranchs = 1; + $img = html_print_image ("operation/tree/one_closed.png", true, array ("style" => 'vertical-align: middle;', "id" => "tree_image_" . $type . "_" . $item['_id_'], "pos_tree" => "1")); + } + } + else { + if ($item != end($list)) + $img = html_print_image ("operation/tree/closed.png", true, array ("style" => 'vertical-align: middle;', "id" => "tree_image_" . $type . "_" . $item['_id_'], "pos_tree" => "2")); + else + { + $lessBranchs = 1; + $img = html_print_image ("operation/tree/last_closed.png", true, array ("style" => 'vertical-align: middle;', "id" => "tree_image_" . $type . "_" . $item['_id_'], "pos_tree" => "3")); + } + } + + echo "
  • "; + echo ""; + + echo $img . $item['_iconImg_'] ." " . __($item['_name_']) . ' ('. + ''.''.$item['_num_ok_'].''.''. + ' : '.$item['_num_critical_'].'' . + ' : '.$item['_num_warning_'].''. + ' : '.$item['_num_unknown_'].''.') '. ""; + + echo "
    "; + echo "
  • \n"; + } + echo "
\n"; + echo ''; + echo ''; + echo '
 
'; + echo ''; + echo ''; + } +} + +// Get data for the tree view +function treeview_getData ($type, $server=false) { + global $config; + + if ($server !== false) { + if (metaconsole_connect ($server) != NOERR) { + return array (); + } + } + + $search_free = get_parameter('search_free', ''); + $select_status = get_parameter('status', -1); + //Get all groups $avariableGroups = users_get_groups (); //db_get_all_rows_in_table('tgrupo', 'nombre'); //Get all groups with agents - $full_groups = db_get_all_rows_sql("SELECT DISTINCT id_grupo FROM tagente WHERE total_count > 0"); + //$full_groups = db_get_all_rows_sql("SELECT DISTINCT id_grupo FROM tagente WHERE total_count > 0"); + $full_groups = db_get_all_rows_sql("SELECT DISTINCT id_grupo FROM tagente"); + if ($full_groups === false) { + return array (); + } $fgroups = array(); @@ -268,10 +367,7 @@ function treeview_printTree($type) { // If there are not groups display error and return if (empty($avariableGroups)) { - ui_print_error_message("There aren't agents in this agrupation"); - echo ''; - echo ''; - return; + return array (); } } @@ -285,7 +381,6 @@ function treeview_printTree($type) { switch ($type) { - default: case 'os': //Skip agent with all modules in not init status $sql_search .= " AND total_count<>notinit_count"; @@ -506,6 +601,7 @@ function treeview_printTree($type) { array_push($list, array('id' => 0, 'name' => 'No policy')); } break; + default: case 'module': $avariableGroupsIds = implode(',',array_keys($avariableGroups)); if($avariableGroupsIds == ''){ @@ -554,105 +650,325 @@ function treeview_printTree($type) { } break; + case 'tag': + $list = db_get_all_rows_sql('SELECT DISTINCT ttag.name + FROM ttag, ttag_module, tagente_modulo + WHERE ttag.id_tag = ttag_module.id_tag AND + ttag_module.id_agente_modulo = tagente_modulo.id_agente_modulo'); + break; } + + + foreach ($list as $key => $item) { + switch ($type) { + case 'os': + $id = $item['id_os']; + $list[$key]['_id_'] = $id; + $list[$key]['_name_'] = $item['name']; + $list[$key]['_iconImg_'] = html_print_image(str_replace('.png' ,'_small.png', ui_print_os_icon ($item['id_os'], false, true, false)) . " ", true); + $list[$key]['_num_ok_'] = os_agents_ok($id); + $list[$key]['_num_critical_'] = os_agents_critical($id); + $list[$key]['_num_warning_'] = os_agents_warning($id); + $list[$key]['_num_unknown_'] = os_agents_unknown($id); + break; + case 'group': + $id = $item['id_grupo']; + $list[$key]['_id_'] = $id; + $list[$key]['_name_'] = $item['nombre']; + $list[$key]['_iconImg_'] = html_print_image ("images/groups_small/" . groups_get_icon($item['id_grupo']).".png", true, array ("style" => 'vertical-align: middle; width: 16px; height: 16px;')); + $list[$key]['_num_ok_'] = groups_agent_ok($id); + $list[$key]['_num_critical_'] = groups_agent_critical($id); + $list[$key]['_num_warning_'] = groups_agent_warning($id); + $list[$key]['_num_unknown_'] = groups_agent_unknown ($id); + break; + case 'module_group': + $id = $item['id_mg']; + $list[$key]['_id_'] = $id; + $list[$key]['_name_'] = $item['name']; + $list[$key]['_iconImg_'] = ''; + $list[$key]['_num_ok_'] = modules_group_agent_ok($id); + $list[$key]['_num_critical_'] = modules_group_agent_critical ($id); + $list[$key]['_num_warning_'] = modules_group_agent_warning($id); + $list[$key]['_num_unknown_'] = modules_group_agent_unknown($id); + break; + case 'policies': + $id = $item['id']; + $list[$key]['_id_'] = $id; + $list[$key]['_name_'] = $item['name']; + $list[$key]['_iconImg_'] = ''; + $list[$key]['_num_ok_'] = policies_agents_ok($id); + $list[$key]['_num_critical_'] = policies_agents_critical($id); + $list[$key]['_num_warning_'] = policies_agents_warning($id); + $list[$key]['_num_unknown_'] = policies_agents_unknown($id); + break; + default: + case 'module': + $id = str_replace(array(' ','#','/'), array('_articapandora_'.ord(' ').'_pandoraartica_', '_articapandora_'.ord('#').'_pandoraartica_', '_articapandora_'.ord('/').'_pandoraartica_'),io_safe_output($item['nombre'])); + $module_name = $item['nombre']; + $list[$key]['_id_'] = $id; + $list[$key]['_name_'] = io_safe_output($module_name); + $list[$key]['_iconImg_'] = ''; + $list[$key]['_num_ok_'] = modules_agents_ok($module_name); + $list[$key]['_num_critical_'] = modules_agents_critical($module_name); + $list[$key]['_num_warning_'] = modules_agents_warning($module_name); + $list[$key]['_num_unknown_'] = modules_agents_unknown($module_name); + break; + case 'tag': + $id = db_get_value('id_tag', 'ttag', 'name', $item['name']); + $list[$key]['_id_'] = $id; + $list[$key]['_name_'] = $item['name']; + $list[$key]['_iconImg_'] = html_print_image ("images/tag_red.png", true, array ("style" => 'vertical-align: middle; width: 16px; height: 16px;')); + $list[$key]['_num_ok_'] = tags_agent_ok($id); + $list[$key]['_num_critical_'] = tags_agent_critical($id); + $list[$key]['_num_warning_'] = tags_agent_warning($id); + $list[$key]['_num_unknown_'] = tags_agent_unknown($id); + break; + } + + if (defined ('METACONSOLE')) { + $list[$key]['_id_'] = $list[$key]['_name_']; + } + } + + return $list; +} + +// Get SQL for the first tree branch +function treeview_getFirstBranchSQL ($type, $id, $avariableGroupsIds, $statusSel, $search_free) { + + if (empty($avariableGroupsIds)) { + return false; + } + + //TODO CHANGE POLICY ACL FOR TAG ACL + $extra_sql = ''; + if($extra_sql != '') { + $extra_sql .= ' OR'; + } + $groups_sql = implode(', ', $avariableGroupsIds); - if ($list === false) { - ui_print_error_message("There aren't agents in this agrupation"); - echo ''; - echo ''; + if ($search_free != '') { + $search_sql = " AND nombre COLLATE utf8_general_ci LIKE '%$search_free%'"; } else { - echo "
    \n"; - - $first = true; - foreach ($list as $item) { - - $iconImg = ''; - switch ($type) { - default: - case 'os': - $id = $item['id_os']; - $name = $item['name']; - $iconImg = html_print_image(str_replace('.png' ,'_small.png', ui_print_os_icon ($item['id_os'], false, true, false)) . " ", true); - $num_ok = os_agents_ok($id); - $num_critical = os_agents_critical($id); - $num_warning = os_agents_warning($id); - $num_unknown = os_agents_unknown($id); - break; - case 'group': - $id = $item['id_grupo']; - $name = $item['nombre']; - $iconImg = html_print_image ("images/groups_small/" . groups_get_icon($item['id_grupo']).".png", true, array ("style" => 'vertical-align: middle; width: 16px; height: 16px;')); - $num_ok = groups_agent_ok($id); - $num_critical = groups_agent_critical($id); - $num_warning = groups_agent_warning($id); - $num_unknown = groups_agent_unknown ($id); - break; - case 'module_group': - $id = $item['id_mg']; - $name = $item['name']; - $num_ok = modules_group_agent_ok($id); - $num_critical = modules_group_agent_critical ($id); - $num_warning = modules_group_agent_warning($id); - $num_unknown = modules_group_agent_unknown($id); - break; - case 'policies': - $id = $item['id']; - $name = $item['name']; - $num_ok = policies_agents_ok($id); - $num_critical = policies_agents_critical($id); - $num_warning = policies_agents_warning($id); - $num_unknown = policies_agents_unknown($id); - break; - case 'module': - $id = str_replace(array(' ','#','/'), array('_articapandora_'.ord(' ').'_pandoraartica_', '_articapandora_'.ord('#').'_pandoraartica_', '_articapandora_'.ord('/').'_pandoraartica_'),io_safe_output($item['nombre'])); - $name = io_safe_output($item['nombre']); - $module_name = $item['nombre']; - $num_ok = modules_agents_ok($module_name); - $num_critical = modules_agents_critical($module_name); - $num_warning = modules_agents_warning($module_name); - $num_unknown = modules_agents_unknown($module_name); - break; - } - - $lessBranchs = 0; - if ($first) { - if ($item != end($list)) { - $img = html_print_image ("operation/tree/first_closed.png", true, array ("style" => 'vertical-align: middle;', "id" => "tree_image_" . $type . "_" . $id, "pos_tree" => "0")); - $first = false; - } - else { - $lessBranchs = 1; - $img = html_print_image ("operation/tree/one_closed.png", true, array ("style" => 'vertical-align: middle;', "id" => "tree_image_" . $type . "_" . $id, "pos_tree" => "1")); - } - } - else { - if ($item != end($list)) - $img = html_print_image ("operation/tree/closed.png", true, array ("style" => 'vertical-align: middle;', "id" => "tree_image_" . $type . "_" . $id, "pos_tree" => "2")); - else - { - $lessBranchs = 1; - $img = html_print_image ("operation/tree/last_closed.png", true, array ("style" => 'vertical-align: middle;', "id" => "tree_image_" . $type . "_" . $id, "pos_tree" => "3")); - } - } - - echo "
  • - " . - $img . $iconImg ." " . __($name) . ' ('. - ''.''.$num_ok.''.''. - ' : '.$num_critical.'' . - ' : '.$num_warning.''. - ' : '.$num_unknown.''.') '. ""; - - echo "
    "; - echo "
  • \n"; - } - echo "
\n"; - echo ''; - echo ''; - echo '
 
'; - echo ''; - echo ''; + $search_sql = ''; } + + //Extract all rows of data for each type + switch ($type) { + case 'group': + + if (defined ('METACONSOLE')) { + $id = groups_get_id ($id); + if ($id == '') { + return false; + } + } + + //Skip agents which only have not init modules + $search_sql .= " AND total_count<>notinit_count"; + + $sql = agents_get_agents(array ( + 'order' => 'nombre COLLATE utf8_general_ci ASC', + 'id_grupo' => $id, + 'disabled' => 0, + 'status' => $statusSel, + 'search' => $search_sql), + array ('*'), + 'AR', + false, + true); + break; + case 'os': + + //Skip agents which only have not init modules + $search_sql .= " AND total_count<>notinit_count"; + + + $sql = agents_get_agents(array ( + 'order' => 'nombre COLLATE utf8_general_ci ASC', + 'id_os' => $id, + 'disabled' => 0, + 'status' => $statusSel, + 'search' => $search_sql), + array ('*'), + 'AR', + false, + true); + break; + case 'module_group': + + //Skip agents which only have not init modules + $search_sql .= " AND total_count<>notinit_count"; + + $sql = agents_get_agents(array ( + 'order' => 'nombre COLLATE utf8_general_ci ASC', + 'disabled' => 0, + 'status' => $statusSel, + 'search' => $search_sql), + array ('*'), + 'AR', + false, + true); + + // Skip agents without modules + $sql .= ' AND total_count>0 AND disabled=0 AND id_agente IN + (SELECT DISTINCT (id_agente) + FROM tagente_modulo + WHERE id_module_group = ' . $id . ')'; + break; + case 'policies': + + $sql = agents_get_agents(array ( + 'order' => 'nombre COLLATE utf8_general_ci ASC', + 'disabled' => 0, + 'search' => $search_sql), + + array ('*'), + 'AR', + false, + true); + + if ($id != 0) { + // Skip agents without modules + $sql .= ' AND tagente.id_agente IN + (SELECT tagente.id_agente + FROM tagente, tagente_modulo, tagente_estado, tpolicy_modules + WHERE tagente.id_agente = tagente_modulo.id_agente + AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo + AND tagente_modulo.id_policy_module = tpolicy_modules.id + AND tagente.disabled = 0 + AND tagente_modulo.disabled = 0 + AND tagente_estado.utimestamp != 0 + AND tagente_modulo.id_policy_module != 0 + AND tpolicy_modules.id_policy = ' . $id . ' + group by tagente.id_agente + having COUNT(*) > 0)'; + } + else if ($statusSel == 0) { + + // If status filter is NORMAL add void agents + $sql .= " UNION SELECT * FROM tagente + WHERE tagente.disabled = 0 + AND tagente.id_agente NOT IN (SELECT tagente_estado.id_agente + FROM tagente_estado)"; + } + break; + case 'module': + //Replace separator token "articapandora_32_pandoraartica_" for " " + //example: + //"Load_articapandora_32_pandoraartica_Average" + //result -> "Load Average" + $name = str_replace(array('_articapandora_'.ord(' ').'_pandoraartica_', '_articapandora_'.ord('#').'_pandoraartica_','_articapandora_'.ord('/').'_pandoraartica_'),array(' ','#','/'),$id); + + $name = io_safe_input($name); + + + $sql = agents_get_agents(array ( + 'order' => 'nombre COLLATE utf8_general_ci ASC', + 'disabled' => 0, + 'status' => $statusSel, + 'search' => $search_sql), + + array ('*'), + 'AR', + false, + true); + $sql .= sprintf('AND id_agente IN ( + SELECT id_agente + FROM tagente_modulo + WHERE nombre = \'%s\' AND disabled = 0 + ) + ', $name); + break; + case 'tag': + $id = tags_get_id ($id); + if ($id === false) { + return false; + } + + $sql = "SELECT tagente.* + FROM tagente, tagente_modulo, ttag_module + WHERE tagente.id_agente = tagente_modulo.id_agente + AND tagente_modulo.id_agente_modulo = ttag_module.id_agente_modulo + AND ttag_module.id_tag = " . $id; + break; + } + + $sql .= ' AND tagente.disabled = 0'. $search_sql; + return $sql; } -?> \ No newline at end of file + +// Get SQL for the second tree branch +function treeview_getSecondBranchSQL ($fatherType, $id, $id_father) { + global $config; + + switch ($fatherType) { + case 'group': + $sql = 'SELECT * + FROM tagente_modulo AS t1 + INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo + WHERE t1.id_agente = ' . $id; + break; + case 'os': + $sql = 'SELECT * + FROM tagente_modulo AS t1 + INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo + WHERE t1.id_agente = ' . $id; + break; + case 'module_group': + $sql = 'SELECT * + FROM tagente_modulo AS t1 + INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo + WHERE t1.id_agente = ' . $id . ' AND id_module_group = ' . $id_father; + break; + case 'policies': + $whereQuery = ''; + if ($id_father != 0) + $whereQuery = ' AND t1.id_policy_module IN + (SELECT id FROM tpolicy_modules WHERE id_policy = ' . $id_father . ')'; + else + $whereQuery = ' AND t1.id_policy_module = 0 '; + + $sql = 'SELECT * + FROM tagente_modulo AS t1 + INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo + WHERE t1.id_agente = ' . $id . $whereQuery; + break; + default: + case 'module': + $name = str_replace(array('_articapandora_'.ord(' ').'_pandoraartica_', '_articapandora_'.ord('#').'_pandoraartica_','_articapandora_'.ord('/').'_pandoraartica_'),array(' ','#','/'),$id_father); + switch ($config["dbtype"]) { + case "mysql": + $sql = 'SELECT * + FROM tagente_modulo AS t1 + INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo + WHERE t1.id_agente = ' . $id . ' AND nombre = \'' . io_safe_input($name) . '\''; + break; + case "postgresql": + case "oracle": + $sql = 'SELECT * + FROM tagente_modulo AS t1 + INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo + WHERE t1.id_agente = ' . $id . ' AND nombre = \'' . io_safe_input($name) . '\''; + break; + } + break; + case 'tag': + $id_father = tags_get_id ($id_father); + if ($id_father === false) { + return false; + } + $sql = 'SELECT * FROM tagente_modulo, tagente_estado, ttag_module + WHERE tagente_modulo.id_agente_modulo = ttag_module.id_agente_modulo + AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo + AND tagente_modulo.id_agente=' . $id . ' AND ttag_module.id_tag = ' . $id_father; + break; + } + + // This line checks for initializated modules or (non-initialized) asyncronous modules + $sql .= ' AND disabled = 0 AND (utimestamp > 0 OR id_tipo_modulo IN (21,22,23))'; + return $sql; +} + +?> diff --git a/pandora_console/operation/tree.php b/pandora_console/operation/tree.php index 8304d5e5fa..476ddd9e0a 100644 --- a/pandora_console/operation/tree.php +++ b/pandora_console/operation/tree.php @@ -22,13 +22,21 @@ define('UNKNOWN', 3); global $config; -require_once ('include/functions_treeview.php'); +require_once ($config['homedir'] . '/include/functions_treeview.php'); + +if (defined ('METACONSOLE')) { + // For each server defined: + $servers = db_get_all_rows_sql ("SELECT * FROM tmetaconsole_setup WHERE disabled = 0"); + if ($servers === false) { + $servers = array(); + } +} if (is_ajax ()) { - require_once ('include/functions_reporting.php'); - require_once ('include/functions_users.php'); - require_once ('include/functions_servers.php'); + require_once ($config['homedir'] . '/include/functions_reporting.php'); + require_once ($config['homedir'] . '/include/functions_users.php'); + require_once ($config['homedir'] . '/include/functions_servers.php'); global $config; @@ -58,159 +66,46 @@ if (is_ajax ()) * 1 1 - hide 2 branch */ $lessBranchs = get_parameter('less_branchs'); - switch ($type) { case 'group': case 'os': case 'module_group': case 'policies': case 'module': - $avariableGroups = users_get_groups(); - $avariableGroupsIds = array_keys($avariableGroups); + case 'tag': $countRows = 0; - - if (!empty($avariableGroupsIds)) { - //TODO CHANGE POLICY ACL FOR TAG ACL - $extra_sql = ''; - if($extra_sql != '') { - $extra_sql .= ' OR'; + if (! defined ('METACONSOLE')) { + $avariableGroups = users_get_groups(); + $avariableGroupsIds = array_keys($avariableGroups); + $sql = treeview_getFirstBranchSQL ($type, $id, $avariableGroupsIds, $statusSel, $search_free); + if ($sql === false) { + $rows = array (); + } else { + $rows = db_get_all_rows_sql($sql); } - $groups_sql = implode(', ', $avariableGroupsIds); - - if ($search_free != '') { - $search_sql = " AND nombre COLLATE utf8_general_ci LIKE '%$search_free%'"; - } - else { - $search_sql = ''; - } - - //Extract all rows of data for each type - switch ($type) { - case 'group': - - //Skip agents which only have not init modules - $search_sql .= " AND total_count<>notinit_count"; - - $sql = agents_get_agents(array ( - 'order' => 'nombre COLLATE utf8_general_ci ASC', - 'id_grupo' => $id, - 'disabled' => 0, - 'status' => $statusSel, - 'search' => $search_sql), - array ('*'), - 'AR', - false, - true); - break; - case 'os': - - //Skip agents which only have not init modules - $search_sql .= " AND total_count<>notinit_count"; - - - $sql = agents_get_agents(array ( - 'order' => 'nombre COLLATE utf8_general_ci ASC', - 'id_os' => $id, - 'disabled' => 0, - 'status' => $statusSel, - 'search' => $search_sql), - array ('*'), - 'AR', - false, - true); - break; - case 'module_group': - - //Skip agents which only have not init modules - $search_sql .= " AND total_count<>notinit_count"; - - $sql = agents_get_agents(array ( - 'order' => 'nombre COLLATE utf8_general_ci ASC', - 'disabled' => 0, - 'status' => $statusSel, - 'search' => $search_sql), - array ('*'), - 'AR', - false, - true); - - // Skip agents without modules - $sql .= ' AND total_count>0 AND disabled=0 AND id_agente IN - (SELECT DISTINCT (id_agente) - FROM tagente_modulo - WHERE id_module_group = ' . $id . ')'; - break; - case 'policies': - - $sql = agents_get_agents(array ( - 'order' => 'nombre COLLATE utf8_general_ci ASC', - 'disabled' => 0, - 'search' => $search_sql), - - array ('*'), - 'AR', - false, - true); - - if ($id != 0) { - // Skip agents without modules - $sql .= ' AND tagente.id_agente IN - (SELECT tagente.id_agente - FROM tagente, tagente_modulo, tagente_estado, tpolicy_modules - WHERE tagente.id_agente = tagente_modulo.id_agente - AND tagente_modulo.id_agente_modulo = tagente_estado.id_agente_modulo - AND tagente_modulo.id_policy_module = tpolicy_modules.id - AND tagente.disabled = 0 - AND tagente_modulo.disabled = 0 - AND tagente_estado.utimestamp != 0 - AND tagente_modulo.id_policy_module != 0 - AND tpolicy_modules.id_policy = ' . $id . ' - group by tagente.id_agente - having COUNT(*) > 0)'; + } else { + $rows = array (); + foreach ($servers as $server) { + if (metaconsole_connect($server) != NOERR) { + continue; + } + $avariableGroups = users_get_groups(); + $avariableGroupsIds = array_keys($avariableGroups); + $sql = treeview_getFirstBranchSQL ($type, $id, $avariableGroupsIds, $statusSel, $search_free); + if ($sql === false) { + $server_rows = array (); + } else { + $server_rows = db_get_all_rows_sql($sql); + if ($server_rows === false) { + $server_rows = array (); } - else if ($statusSel == 0) { - - // If status filter is NORMAL add void agents - $sql .= " UNION SELECT * FROM tagente - WHERE tagente.disabled = 0 - AND tagente.id_agente NOT IN (SELECT tagente_estado.id_agente - FROM tagente_estado)"; - } - break; - case 'module': - //Replace separator token "articapandora_32_pandoraartica_" for " " - //example: - //"Load_articapandora_32_pandoraartica_Average" - //result -> "Load Average" - $name = str_replace(array('_articapandora_'.ord(' ').'_pandoraartica_', '_articapandora_'.ord('#').'_pandoraartica_','_articapandora_'.ord('/').'_pandoraartica_'),array(' ','#','/'),$id); - - $name = io_safe_input($name); - - - $sql = agents_get_agents(array ( - 'order' => 'nombre COLLATE utf8_general_ci ASC', - 'disabled' => 0, - 'status' => $statusSel, - 'search' => $search_sql), - - array ('*'), - 'AR', - false, - true); - $sql .= sprintf('AND id_agente IN ( - SELECT id_agente - FROM tagente_modulo - WHERE nombre = \'%s\' AND disabled = 0 - ) - ', $name); - break; + } + $rows = array_merge($rows, $server_rows); } - $sql .= ' AND tagente.disabled = 0'. $search_sql; + metaconsole_restore_db(); } - - $rows = db_get_all_rows_sql($sql); $countRows = count ($rows); //Empty Branch @@ -312,11 +207,7 @@ if (is_ajax ()) if ($agent_info["monitor_normal"] > 0) echo ' : '.$agent_info["monitor_normal"].''; echo ")"; - if ($agent_info["last_contact"]!='') { - echo " ("; - ui_print_timestamp ($agent_info["last_contact"]); - echo ")"; - } + if ($row['quiet']) { echo " "; html_print_image("images/dot_green.disabled.png", false, array("border" => '0', "title" => __('Quiet'), "alt" => "")); @@ -335,63 +226,28 @@ if (is_ajax ()) case 'agent_os': case 'agent_policies': case 'agent_module': + case 'agent_tag': $fatherType = str_replace('agent_', '', $type); - - switch ($fatherType) { - case 'group': - $sql = 'SELECT * - FROM tagente_modulo AS t1 - INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo - WHERE t1.id_agente = ' . $id; - break; - case 'os': - $sql = 'SELECT * - FROM tagente_modulo AS t1 - INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo - WHERE t1.id_agente = ' . $id; - break; - case 'module_group': - $sql = 'SELECT * - FROM tagente_modulo AS t1 - INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo - WHERE t1.id_agente = ' . $id . ' AND id_module_group = ' . $id_father; - break; - case 'policies': - $whereQuery = ''; - if ($id_father != 0) - $whereQuery = ' AND t1.id_policy_module IN - (SELECT id FROM tpolicy_modules WHERE id_policy = ' . $id_father . ')'; - else - $whereQuery = ' AND t1.id_policy_module = 0 '; - - $sql = 'SELECT * - FROM tagente_modulo AS t1 - INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo - WHERE t1.id_agente = ' . $id . $whereQuery; - break; - case 'module': - $name = str_replace(array('_articapandora_'.ord(' ').'_pandoraartica_', '_articapandora_'.ord('#').'_pandoraartica_','_articapandora_'.ord('/').'_pandoraartica_'),array(' ','#','/'),$id_father); - switch ($config["dbtype"]) { - case "mysql": - $sql = 'SELECT * - FROM tagente_modulo AS t1 - INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo - WHERE t1.id_agente = ' . $id . ' AND nombre = \'' . io_safe_input($name) . '\''; - break; - case "postgresql": - case "oracle": - $sql = 'SELECT * - FROM tagente_modulo AS t1 - INNER JOIN tagente_estado AS t2 ON t1.id_agente_modulo = t2.id_agente_modulo - WHERE t1.id_agente = ' . $id . ' AND nombre = \'' . io_safe_input($name) . '\''; - break; - } - break; - } - // This line checks for initializated modules or (non-initialized) asyncronous modules - $sql .= ' AND disabled = 0 AND (utimestamp > 0 OR id_tipo_modulo IN (21,22,23))'; - $rows = db_get_all_rows_sql($sql); + if (! defined ('METACONSOLE')) { + $sql = treeview_getSecondBranchSQL ($fatherType, $id, $id_father); + $rows = db_get_all_rows_sql($sql); + } else { + $rows = array (); + foreach ($servers as $server) { + if (metaconsole_connect($server) != NOERR) { + continue; + } + $sql = treeview_getSecondBranchSQL ($fatherType, $id, $id_father); + $server_rows = db_get_all_rows_sql($sql); + if ($server_rows === false) { + $server_rows = array (); + } + $rows = array_merge($rows, $server_rows); + } + + metaconsole_restore_db(); + } $countRows = count ($rows); if ($countRows === 0) { @@ -562,8 +418,6 @@ else { $module_tab = array('text' => "" . html_print_image ("images/brick.png", true, array ("title" => __('Modules'))) . "", 'active' => $activeTab == "module"); -$onheader = array('os' => $os_tab, 'group' => $group_tab, 'module_group' => $module_group_tab, 'policies' => $policies_tab, 'module' => $module_tab); - switch ($activeTab) { case 'group': $order = __('groups'); @@ -580,9 +434,39 @@ switch ($activeTab) { case 'os': $order = __('OS'); break; + case 'tag': + $order = __('tags'); + break; } -ui_print_page_header (__('Tree view')." - ".__('Sort the agents by ') .$order, "images/extensions.png", false, "", false, $onheader); +if (! defined ('METACONSOLE')) { + $onheader = array('os' => $os_tab, 'group' => $group_tab, 'module_group' => $module_group_tab, 'policies' => $policies_tab, 'module' => $module_tab); + ui_print_page_header (__('Tree view')." - ".__('Sort the agents by ') .$order, "images/extensions.png", false, "", false, $onheader); +} else { + + ui_meta_add_breadcrumb(array('link' => 'index.php?sec=monitoring&sec2=operation/tree', 'text' => __('Tree View'))); + ui_meta_print_page_header($nav_bar); + + $img_style = array ("class" => "top", "width" => 16); + $activeTab = get_parameter('tab','group'); + $group_tab = array('text' => "" + . html_print_image ("images/group.png", true, array ("title" => __('Groups'))) . "", + 'active' => $activeTab == "group"); + $tags_tab = array('text' => "" + . html_print_image ("images/tag_red.png", true, array ("title" => __('Tags'))) . "", 'active' => $activeTab == "tag"); + $subsections = array('group' => $group_tab, 'tag' => $tags_tab); + switch ($activeTab) { + case 'group': + $subsection = __('Groups'); + $tab = 'group'; + break; + case 'tag': + $subsection = __('Tags'); + $tab = 'tag'; + break; + } + ui_meta_print_header(__("Tree view"), $subsection, $subsections); +} echo "
"; echo '