fields['id'] = 0; $this->fields['nombre'] = 'All'; } else if (is_numeric($id_group) === true) { parent::__construct('tgrupo', ['id_grupo' => $id_group]); if ($recursive === true) { // Customize certain fields. $this->fields['parent'] = new Group($this->fields['parent']); } } else { // Empty skel. parent::__construct('tgrupo'); } } /** * Return an array of ids with all children * * @param boolean $ids_only Return an array of id_groups or * entire rows. * @param boolean $ignorePropagationState Search all children ignoring or * depending on propagate_acl flag. * * @return array With all children. */ public function getChildren( bool $ids_only=false, bool $ignorePropagationState=false ):array { $available_groups = \groups_get_children( $this->id_grupo(), $ignorePropagationState ); if (is_array($available_groups) === false) { return []; } if ($ids_only === true) { return array_keys($available_groups); } return $available_groups; } /** * Alias of 'nombre'. * * @param string|null $name Name of group. * * @return string|void Name assigned or void if set operation. */ public function name(?string $name=null) { if ($name === null) { return $this->nombre(); } return $this->nombre($name); } /** * Retrieves a list of groups fitered. * * @param array $filter Filters to be applied. * * @return array With all results or false if error. * @throws Exception On error. */ private static function search(array $filter):array { // Default values. if (empty($filter['id_user']) === true) { // By default query current user groups. $filter['id_user'] = false; } else if ((bool) \users_is_admin() === false) { // Override user queried if user is not an admin. $filter['id_user'] = false; } if (empty($filter['id_user']) === true) { $filter['id_user'] = false; } if (empty($filter['keys_field']) === true) { $filter['keys_field'] = 'id_grupo'; } if (isset($filter['returnAllColumns']) === false) { $filter['returnAllColumns'] = true; } $groups = \users_get_groups( $filter['id_user'], $filter['privilege'], $filter['returnAllGroup'], // Return all columns. $filter['returnAllColumns'], // Field id_groups is not being used anymore. null, $filter['keys_field'], // Cache. true, // Search term. $filter['search'] ); if (is_array($groups) === false) { return []; } return $groups; } /** * Returns an hierarchical ordered array. * * @param array $groups All groups available. * * @return array Groups ordered. */ private static function prepareGroups(array $groups):array { $return = []; $tree_groups = \groups_get_groups_tree_recursive($groups); foreach ($tree_groups as $k => $v) { $return[] = [ 'id' => $k, 'text' => \io_safe_output( \ui_print_truncate_text( $v['nombre'], GENERIC_SIZE_TEXT, false, true, false ) ), 'level' => $v['deep'], ]; } $unassigned = []; $processed = array_keys($tree_groups); foreach ($groups as $k => $v) { if (in_array($k, $processed) === true) { continue; } $unassigned[] = [ 'id' => $k, 'text' => \io_safe_output( \ui_print_truncate_text( $v, GENERIC_SIZE_TEXT, false, true, false ) ), 'level' => 0, ]; } return array_merge($unassigned, $return); } /** * Saves current group definition to database. * * @return mixed Affected rows of false in case of error. * @throws \Exception On error. */ public function save() { if (\is_management_allowed() !== true) { $msg = 'cannot be modified in a centralized management environment'; throw new \Exception( get_class($this).' error, '.$msg ); } $updates = $this->fields; if (is_numeric($updates['parent']) === false) { $updates['parent'] = $this->parent()->id_grupo(); } // Clean null fields. foreach ($updates as $k => $v) { if ($v === null) { unset($updates[$k]); } } if (isset($updates['propagate']) === false) { $updates['propagate'] = 0; } if (isset($updates['disabled']) === false) { $updates['disabled'] = 0; } if ($this->fields['id_grupo'] > 0) { return \db_process_sql_update( 'tgrupo', $updates, ['id_grupo' => $this->fields['id_grupo']] ); } else { // Create new group. $this->fields['id_grupo'] = \db_process_sql_insert( '\tgrupo', $updates ); if ($this->fields['id_grupo'] === false) { global $config; $msg = __( 'Failed to save group %s', $config['dbconnection']->error ); throw new \Exception( get_class($this).' error, '.$msg ); } else { return true; } } return false; } /** * Delete this group. * * @return void */ public function delete() { // Propagate parents. \db_process_sql_update( 'tgrupo', ['parent' => $this->parent()->id_grupo()], ['parent' => $this->id_grupo()] ); // Remove stats. \db_process_sql_delete( 'tgroup_stat', ['id_group' => $this->id_grupo()] ); // Remove group. \db_process_sql_delete( 'tgrupo', ['id_grupo' => $this->id_grupo()] ); unset($this->fields['id_grupo']); } /** * Return error message to target. * * @param string $msg Error message. * * @return void */ public static function error(string $msg) { echo json_encode(['error' => $msg]); } /** * Verifies target method is allowed to be called using AJAX call. * * @param string $method Method to be invoked via AJAX. * * @return boolean Available (true), or not (false). */ public static function ajaxMethod(string $method):bool { return in_array($method, self::$ajaxMethods) === true; } /** * This method is being invoked by select2 to improve performance while * installation has a lot of groups (more than 5k). * * Security applied in controller include/ajax/group.php. * * @return void * @throws \Exception On error. */ public static function getGroupsForSelect() { $id_user = get_parameter('id_user', false); $privilege = get_parameter('privilege', 'AR'); $returnAllGroup = get_parameter('returnAllGroup', false); $id_group = get_parameter('id_group', false); $keys_field = get_parameter('keys_field', 'id_grupo'); $search = get_parameter('search', ''); $step = get_parameter('step', 1); $limit = get_parameter('limit', false); $not_condition = get_parameter('not_condition', false); $exclusions = get_parameter('exclusions', '[]'); $inclusions = get_parameter('inclusions', '[]'); if (empty($id_user) === true) { $id_user = false; } $groups = self::search( [ 'id_user' => $id_user, 'privilege' => $privilege, 'returnAllGroup' => $returnAllGroup, 'returnAllColumns' => true, 'id_group' => $id_group, 'keys_field' => $keys_field, 'search' => $search, ] ); $exclusions = json_decode(\io_safe_output($exclusions), true); if (empty($exclusions) === false) { foreach ($exclusions as $ex) { unset($groups[$ex]); } } $inclusions = json_decode(\io_safe_output($inclusions), true); if (empty($inclusions) === false) { foreach ($inclusions as $k => $g) { if (empty($groups[$k]) === true) { if (is_numeric($g) === true) { $groups[$k] = \groups_get_name($k); } if (empty($groups[$k]) === true) { // Group does not exist, direct value assigned. $groups[$k] = $g; } } } } $return = self::prepareGroups($groups); // When not_condition is select firts option text change All to None. if ($not_condition === 'true') { $return[0]['text'] = 'None'; } if (is_array($return) === false) { return; } // Use global block size configuration. global $config; $limit = $config['block_size']; $offset = (($step - 1) * $limit); // Pagination over effective groups retrieved. // Calculation is faster than transference. $count = count($return); if (is_numeric($offset) === true && $offset >= 0) { if (is_numeric($limit) === true && $limit > 0) { $return = array_splice($return, $offset, $limit); } } if ($step > 2) { $processed = (($step - 2) * $limit); } else { $processed = 0; } $current_ammount = (count($return) + $processed); echo json_encode( [ 'results' => $return, 'pagination' => [ 'more' => $current_ammount < $count, ], ] ); } /** * Draw a graph distribution so by group. * * @return void */ public static function distributionBySoGraph() { global $config; $id_group = get_parameter('id_group', ''); include_once $config['homedir'].'/include/functions_graph.php'; $out = '
'; $out .= graph_so_by_group($id_group, 300, 200, false, false); $out .= '
'; echo $out; return; } /** * Draw a graph events agent by group. * * @return void */ public static function groupEventsByAgent() { global $config; $id_group = get_parameter('id_group', ''); include_once $config['homedir'].'/include/functions_graph.php'; $out = '
'; $out .= graph_events_agent_by_group($id_group, 300, 200, false, true, true); $out .= '
'; echo $out; return; } /** * Draw in modal a agent info * * @return void */ public static function loadInfoAgent() { $extradata = get_parameter('extradata', ''); echo '
'; if (empty($extradata) === false) { $extradata = json_decode(io_safe_output($extradata), true); $agent = agents_get_agent($extradata['idAgent']); if (is_array($agent)) { $status_img = agents_tree_view_status_img( $agent['critical_count'], $agent['warning_count'], $agent['unknown_count'], $agent['total_count'], $agent['notinit_count'] ); $table = new \stdClass(); $table->class = 'table_modal_alternate'; $table->data = [ [ __('Id'), $agent['id_agente'], ], [ __('Agent name'), ''.$agent['nombre'].'', ], [ __('Alias'), $agent['alias'], ], [ __('Ip Address'), $agent['direccion'], ], [ __('Status'), $status_img, ], [ __('Group'), groups_get_name($agent['id_grupo']), ], [ __('Interval'), $agent['intervalo'], ], [ __('Operative system'), get_os_name($agent['id_os']), ], [ __('Server name'), $agent['server_name'], ], [ __('Description'), $agent['comentarios'], ], ]; html_print_table($table); } } echo '
'; } /** * Get agents by group for datatable. * * @return void */ public static function getAgentsByGroup() { global $config; $data = []; $id_group = get_parameter('id_group', ''); $id_groups = [$id_group]; $groups = groups_get_children($id_group); if (count($groups) > 0) { $id_groups = []; foreach ($groups as $key => $value) { $id_groups[] = $value['id_grupo']; } } $start = get_parameter('start', 0); $length = get_parameter('length', $config['block_size']); $orderDatatable = get_datatable_order(true); $pagination = ''; $order = ''; try { ob_start(); if (isset($orderDatatable)) { switch ($orderDatatable['field']) { case 'alerts': $orderDatatable['field'] = 'fired_count'; break; case 'status': $orderDatatable['field'] = 'total_count'; default: $orderDatatable['field'] = $orderDatatable['field']; break; } $order = sprintf( ' ORDER BY %s %s', $orderDatatable['field'], $orderDatatable['direction'] ); } if (isset($length) && $length > 0 && isset($start) && $start >= 0 ) { $pagination = sprintf( ' LIMIT %d OFFSET %d ', $length, $start ); } $sql = sprintf( 'SELECT id_agente, alias, critical_count, warning_count, unknown_count, total_count, notinit_count, ultimo_contacto_remoto, fired_count FROM tagente t LEFT JOIN tagent_secondary_group g ON g.id_agent = t.id_agente WHERE disabled = 0 AND total_count <> notinit_count AND (id_grupo IN (%s) OR id_group IN (%s)) %s %s', implode(',', $id_groups), implode(',', $id_groups), $order, $pagination ); $data = db_get_all_rows_sql($sql); $sql = sprintf( 'SELECT id_agente, alias, critical_count, warning_count, unknown_count, total_count, notinit_count, ultimo_contacto_remoto, fired_count FROM tagente t LEFT JOIN tagent_secondary_group g ON g.id_agent = t.id_agente WHERE disabled = 0 AND total_count <> notinit_count AND (id_grupo IN (%s) OR id_group IN (%s)) %s', implode(',', $id_groups), implode(',', $id_groups), $order, ); $count_agents = db_get_num_rows($sql); foreach ($data as $key => $agent) { $status_img = agents_tree_view_status_img( $agent['critical_count'], $agent['warning_count'], $agent['unknown_count'], $agent['total_count'], $agent['notinit_count'] ); $data[$key]['alias'] = ''.$agent['alias'].''; $data[$key]['status'] = $status_img; $data[$key]['alerts'] = agents_tree_view_alert_img($agent['fired_count']); } if (empty($data) === true) { $total = 0; $data = []; } else { $total = $count_agents; } echo json_encode( [ 'data' => $data, 'recordsTotal' => $total, 'recordsFiltered' => $total, ] ); // Capture output. $response = ob_get_clean(); } catch (\Exception $e) { echo json_encode(['error' => $e->getMessage()]); exit; } json_decode($response); if (json_last_error() === JSON_ERROR_NONE) { echo $response; } else { echo json_encode( [ 'success' => false, 'error' => $response, ] ); } exit; } }