From 87c3bee756380da6ff865ad7c0bae043c52c3188 Mon Sep 17 00:00:00 2001
From: Pablo Aragon <pablo.aragon@pandorafms.com>
Date: Wed, 15 Feb 2023 11:23:36 +0100
Subject: [PATCH] 9666-New widget Event cardboard

---
 .../images/widgets/EventCardboard.png         | Bin 0 -> 4179 bytes
 pandora_console/include/functions_events.php  |  55 ++
 .../include/lib/Dashboard/Widget.php          |   1 +
 .../lib/Dashboard/Widgets/EventCardboard.php  | 664 ++++++++++++++++++
 .../include/styles/meta_dashboards.css        |  15 +
 5 files changed, 735 insertions(+)
 create mode 100644 pandora_console/images/widgets/EventCardboard.png
 create mode 100644 pandora_console/include/lib/Dashboard/Widgets/EventCardboard.php

diff --git a/pandora_console/images/widgets/EventCardboard.png b/pandora_console/images/widgets/EventCardboard.png
new file mode 100644
index 0000000000000000000000000000000000000000..5dba098d468700d397496abf9f0341b9f9bb6cd4
GIT binary patch
literal 4179
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

literal 0
HcmV?d00001

diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php
index 48ef7b2c30..6d7de4a9b1 100644
--- a/pandora_console/include/functions_events.php
+++ b/pandora_console/include/functions_events.php
@@ -5826,3 +5826,58 @@ function get_events_get_response_target(
         }
     }
 }
+
+
+/**
+ * Gets the count of events by criticity.
+ *
+ * @param integer $utimestamp  Utimestamp to search.
+ * @param integer $eventType   Event type.
+ * @param array   $groupId     Groups.
+ * @param integer $eventStatus Event status.
+ * @param array   $criticityId Criticity to search.
+ *
+ * @return array
+ */
+function get_count_event_criticity(
+    $utimestamp,
+    $eventType,
+    $groupId,
+    $eventStatus,
+    $criticityId
+) {
+    $type = ' ';
+    if ($eventType !== '0') {
+        $type = 'AND event_type = "'.$eventType.'"';
+    }
+
+        $groups = ' ';
+    if ((int) $groupId !== 0) {
+        $groups = 'AND id_grupo IN ('.$groupId.')';
+    }
+
+        $status = ' ';
+    if ((int) $eventStatus !== -1) {
+        $status = 'AND estado = '.$eventStatus;
+    }
+
+        $criticity = ' ';
+    if (empty($criticityId) === false) {
+        $criticity = 'AND criticity IN ('.$criticityId.')';
+    }
+
+    $sql_meta = sprintf(
+        'SELECT COUNT(id_evento) AS count,
+        criticity
+        FROM tevento
+        WHERE utimestamp >= %d %s %s %s %s
+        GROUP BY criticity',
+        $utimestamp,
+        $type,
+        $groups,
+        $status,
+        $criticity
+    );
+
+    return db_get_all_rows_sql($sql_meta);
+}
diff --git a/pandora_console/include/lib/Dashboard/Widget.php b/pandora_console/include/lib/Dashboard/Widget.php
index 2753b8a55d..bb082de0c7 100644
--- a/pandora_console/include/lib/Dashboard/Widget.php
+++ b/pandora_console/include/lib/Dashboard/Widget.php
@@ -420,6 +420,7 @@ class Widget
                 case 'ColorModuleTabs':
                 case 'BlockHistogram':
                 case 'DataMatrix':
+                case 'EventCardboard':
                     $className .= '\\'.$name;
                 break;
 
diff --git a/pandora_console/include/lib/Dashboard/Widgets/EventCardboard.php b/pandora_console/include/lib/Dashboard/Widgets/EventCardboard.php
new file mode 100644
index 0000000000..87e592c8af
--- /dev/null
+++ b/pandora_console/include/lib/Dashboard/Widgets/EventCardboard.php
@@ -0,0 +1,664 @@
+<?php
+/**
+ * Widget Event cardboard Pandora FMS Console
+ *
+ * @category   Console Class
+ * @package    Pandora FMS
+ * @subpackage Widget Event cardboard
+ * @version    1.0.0
+ * @license    See below
+ *
+ *    ______                 ___                    _______ _______ ________
+ *   |   __ \.-----.--.--.--|  |.-----.----.-----. |    ___|   |   |     __|
+ *  |    __/|  _  |     |  _  ||  _  |   _|  _  | |    ___|       |__     |
+ * |___|   |___._|__|__|_____||_____|__| |___._| |___|   |__|_|__|_______|
+ *
+ * ============================================================================
+ * Copyright (c) 2005-2023 Artica Soluciones Tecnologicas
+ * Please see http://pandorafms.org for full contribution list
+ * 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 for version 2.
+ * 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.
+ * ============================================================================
+ */
+
+namespace PandoraFMS\Dashboard;
+use PandoraFMS\Enterprise\Metaconsole\Node;
+
+/**
+ * Event cardboard Widgets.
+ */
+class EventCardboard extends Widget
+{
+
+    /**
+     * Name widget.
+     *
+     * @var string
+     */
+    protected $name;
+
+    /**
+     * Title widget.
+     *
+     * @var string
+     */
+    protected $title;
+
+    /**
+     * Page widget;
+     *
+     * @var string
+     */
+    protected $page;
+
+    /**
+     * Class name widget.
+     *
+     * @var [type]
+     */
+    protected $className;
+
+    /**
+     * Values options for each widget.
+     *
+     * @var [type]
+     */
+    protected $values;
+
+    /**
+     * Configuration required.
+     *
+     * @var boolean
+     */
+    protected $configurationRequired;
+
+    /**
+     * Error load widget.
+     *
+     * @var boolean
+     */
+    protected $loadError;
+
+    /**
+     * Width.
+     *
+     * @var integer
+     */
+    protected $width;
+
+    /**
+     * Heigth.
+     *
+     * @var integer
+     */
+    protected $height;
+
+    /**
+     * Grid Width.
+     *
+     * @var integer
+     */
+    protected $gridWidth;
+
+    /**
+     * Cell ID.
+     *
+     * @var integer
+     */
+    protected $cellId;
+
+
+    /**
+     * Construct.
+     *
+     * @param integer      $cellId      Cell ID.
+     * @param integer      $dashboardId Dashboard ID.
+     * @param integer      $widgetId    Widget ID.
+     * @param integer|null $width       New width.
+     * @param integer|null $height      New height.
+     * @param integer|null $gridWidth   Grid width.
+     */
+    public function __construct(
+        int $cellId,
+        int $dashboardId=0,
+        int $widgetId=0,
+        ?int $width=0,
+        ?int $height=0,
+        ?int $gridWidth=0
+    ) {
+        global $config;
+
+        include_once $config['homedir'].'/include/functions_agents.php';
+        include_once $config['homedir'].'/include/functions_modules.php';
+
+        // WARNING: Do not edit. This chunk must be in the constructor.
+        parent::__construct(
+            $cellId,
+            $dashboardId,
+            $widgetId
+        );
+
+        // Width.
+        $this->width = $width;
+
+        // Height.
+        $this->height = $height;
+
+        // Grid Width.
+        $this->gridWidth = $gridWidth;
+
+        // Cell Id.
+        $this->cellId = $cellId;
+
+        // Options.
+        $this->values = $this->decoders($this->getOptionsWidget());
+
+        // Positions.
+        $this->position = $this->getPositionWidget();
+
+        // Page.
+        $this->page = basename(__FILE__);
+
+        // ClassName.
+        $class = new \ReflectionClass($this);
+        $this->className = $class->getShortName();
+
+        // Title.
+        $this->title = __('Event cardboard');
+
+        // Name.
+        if (empty($this->name) === true) {
+            $this->name = 'EventCardboard';
+        }
+
+        // This forces at least a first configuration.
+        $this->configurationRequired = false;
+        if (isset($this->values['groupId']) === false) {
+            $this->configurationRequired = true;
+        }
+
+        $this->overflow_scrollbars = false;
+    }
+
+
+    /**
+     * Decoders hack for retrocompability.
+     *
+     * @param array $decoder Values.
+     *
+     * @return array Returns the values ​​with the correct key.
+     */
+    public function decoders(array $decoder): array
+    {
+        $values = [];
+        // Retrieve global - common inputs.
+        $values = parent::decoders($decoder);
+
+        if (isset($decoder['eventType']) === true) {
+            $values['eventType'] = $decoder['eventType'];
+        }
+
+        if (isset($decoder['maxHours']) === true) {
+            $values['maxHours'] = $decoder['maxHours'];
+        }
+
+        if (isset($decoder['eventStatus']) === true) {
+            $values['eventStatus'] = $decoder['eventStatus'];
+        }
+
+        if (isset($decoder['severity']) === true) {
+            $values['severity'] = $decoder['severity'];
+        }
+
+        if (isset($decoder['groupId']) === true) {
+            $values['groupId'] = $decoder['groupId'];
+        }
+
+        if (isset($decoder['nodes']) === true) {
+            $values['nodes'] = $decoder['nodes'];
+        }
+
+        return $values;
+    }
+
+
+    /**
+     * Generates inputs for form (specific).
+     *
+     * @return array Of inputs.
+     *
+     * @throws Exception On error.
+     */
+    public function getFormInputs(): array
+    {
+        $values = $this->values;
+
+        // Retrieve global - common inputs.
+        $inputs = parent::getFormInputs();
+
+        // Remove background field, this widget doesn't use it.
+        foreach ($inputs as $kIn => $vIn) {
+            if ($vIn['label'] === 'Background') {
+                unset($inputs[$kIn]);
+            }
+        }
+
+        $blocks = [
+            'row1',
+            'row2',
+        ];
+
+        $inputs['blocks'] = $blocks;
+
+        foreach ($inputs as $kInput => $vInput) {
+            $inputs['inputs']['row1'][] = $vInput;
+        }
+
+        // Event Type.
+        $fields = get_event_types();
+        $fields['not_normal'] = __('Not normal');
+
+        $inputs['inputs']['row1'][] = [
+            'label'     => __('Event type'),
+            'arguments' => [
+                'type'          => 'select',
+                'fields'        => $fields,
+                'class'         => 'event-widget-input',
+                'name'          => 'eventType',
+                'selected'      => $values['eventType'],
+                'return'        => true,
+                'nothing'       => __('Any'),
+                'nothing_value' => 0,
+            ],
+        ];
+
+        // Max. hours old. Default 8.
+        if (isset($values['maxHours']) === false) {
+            $values['maxHours'] = 8;
+        }
+
+        $inputs['inputs']['row1'][] = [
+            'label'     => __('Max. hours old'),
+            'arguments' => [
+                'name'   => 'maxHours',
+                'type'   => 'number',
+                'class'  => 'event-widget-input',
+                'value'  => $values['maxHours'],
+                'return' => true,
+                'min'    => 0,
+            ],
+        ];
+
+        // Event status.
+        $fields = [
+            -1 => __('All event'),
+            1  => __('Only validated'),
+            0  => __('Only pending'),
+        ];
+
+        $inputs['inputs']['row1'][] = [
+            'label'     => __('Event status'),
+            'arguments' => [
+                'type'     => 'select',
+                'fields'   => $fields,
+                'class'    => 'event-widget-input',
+                'name'     => 'eventStatus',
+                'selected' => $values['eventStatus'],
+                'return'   => true,
+            ],
+        ];
+
+        // Groups.
+        $return_all_group = false;
+        $selected_groups_array = explode(',', $values['groupId'][0]);
+
+        if (empty($values['groupId'][0]) === true) {
+            $selected_groups_array = [0];
+        }
+
+        if ((bool) \users_can_manage_group_all('RM') === true
+            || ($selected_groups_array[0] !== ''
+            && in_array(0, $selected_groups_array) === true)
+        ) {
+            // Return all group if user has permissions or it is a currently
+            // selected group.
+            $return_all_group = true;
+        }
+
+        $inputs['inputs']['row1'][] = [
+            'label'     => __('Groups'),
+            'arguments' => [
+                'type'           => 'select_groups',
+                'name'           => 'groupId[]',
+                'class'          => 'event-widget-input',
+                'returnAllGroup' => true,
+                'privilege'      => 'AR',
+                'selected'       => $selected_groups_array,
+                'return'         => true,
+                'multiple'       => true,
+                'returnAllGroup' => $return_all_group,
+                'required'       => true,
+            ],
+        ];
+
+        // Nodes.
+        if (is_metaconsole() === true) {
+            $nodes_fields = [];
+            $servers_ids = metaconsole_get_servers();
+
+            foreach ($servers_ids as $server) {
+                $nodes_fields[$server['id']] = $server['server_name'];
+            }
+
+            $nodes_fields[0] = __('Metaconsola');
+
+            $nodes_selected = explode(',', $values['nodes']);
+
+            (isset($values['nodes']) === false) ? $nodes_selected = $servers_ids : '';
+
+            $nodes_height = count($nodes_fields);
+            if (count($nodes_fields) > 5) {
+                $nodes_height = 5;
+            }
+
+            $inputs['inputs']['row2'][] = [
+                'label'     => __('Servers'),
+                'arguments' => [
+                    'name'       => 'nodes',
+                    'type'       => 'select',
+                    'fields'     => $nodes_fields,
+                    'selected'   => $nodes_selected,
+                    'return'     => true,
+                    'multiple'   => true,
+                    'class'      => 'overflow-hidden',
+                    'size'       => $nodes_height,
+                    'select_all' => false,
+                    'required'   => true,
+                ],
+            ];
+        }
+
+        // Severity.
+        $fields = get_priorities();
+
+        $severity_selected = explode(',', $values['severity']);
+
+        if (isset($values['severity']) === false) {
+            $severity_selected = array_keys($fields);
+        }
+
+        $inputs['inputs']['row2'][] = [
+            'label'     => __('Severity'),
+            'arguments' => [
+                'type'     => 'select',
+                'fields'   => $fields,
+                'class'    => 'event-widget-input',
+                'name'     => 'severity',
+                'selected' => $severity_selected,
+                'return'   => true,
+                'multiple' => true,
+            ],
+        ];
+
+        return $inputs;
+    }
+
+
+    /**
+     * Get Post for widget.
+     *
+     * @return array
+     */
+    public function getPost():array
+    {
+        // Retrieve global - common inputs.
+        $values = parent::getPost();
+
+        $values['eventType'] = \get_parameter('eventType', 0);
+        $values['maxHours'] = \get_parameter('maxHours', 8);
+        $values['eventStatus'] = \get_parameter('eventStatus', -1);
+        $values['groupId'] = \get_parameter('groupId', []);
+        $values['severity'] = \get_parameter('severity', -1);
+        $values['nodes'] = \get_parameter('nodes', 0);
+
+        return $values;
+    }
+
+
+    /**
+     * Draw widget.
+     *
+     * @return string;
+     */
+    public function load()
+    {
+        $output = '';
+
+        ui_require_css_file('events', 'include/styles/', true);
+        ui_require_javascript_file('pandora_events', 'include/javascript/', true);
+
+        $eventType = $this->values['eventType'];
+        $groupId = implode(',', $this->values['groupId']);
+        $utimestamp = strtotime('-'.$this->values['maxHours'].' hours');
+        $eventStatus = $this->values['eventStatus'];
+        $severity = $this->values['severity'];
+
+        $priorities = explode(',', $severity);
+        // Sort criticity array.
+        asort($priorities);
+
+        $count_meta = [];
+        $count_meta_tmp = [];
+        if (is_metaconsole() === true) {
+            $meta = false;
+            $nodes = $this->values['nodes'];
+
+            if (isset($nodes) === true) {
+                $servers_ids = explode(',', $nodes);
+            }
+
+            if (in_array(0, $servers_ids) === true) {
+                $meta = true;
+                unset($servers_ids[0]);
+            }
+
+            if (is_metaconsole() === true && $meta === true) {
+                $events_meta_rows = get_count_event_criticity(
+                    $utimestamp,
+                    $eventType,
+                    $groupId,
+                    $eventStatus,
+                    $severity
+                );
+
+                array_push($count_meta_tmp, $events_meta_rows);
+            }
+
+            foreach ($servers_ids as $server_id) {
+                try {
+                    $node = new Node((int) $server_id);
+                    $node->connect();
+
+                    $events_meta_rows = get_count_event_criticity(
+                        $utimestamp,
+                        $eventType,
+                        $groupId,
+                        $eventStatus,
+                        $severity
+                    );
+
+                    array_push($count_meta_tmp, $events_meta_rows);
+                    $node->disconnect();
+                } catch (\Exception $e) {
+                    // Unexistent envents.
+                    $node->disconnect();
+                }
+            }
+
+            foreach ($count_meta_tmp as $tmpValue) {
+                foreach ($tmpValue as $value) {
+                    array_push($count_meta, $value);
+                }
+            }
+
+            $events_rows = [];
+            foreach ($priorities as $pKey) {
+                $count = 0;
+                $tmp['criticity'] = $pKey;
+                foreach ($count_meta as $kEventMeta => $vEventMeta) {
+                    if ((int) $pKey === (int) $vEventMeta['criticity']) {
+                        $count += (int) $vEventMeta['count'];
+                    }
+                }
+
+                $tmp['count'] = $count;
+                array_push($events_rows, $tmp);
+            }
+        } else {
+            $events_rows = get_count_event_criticity(
+                $utimestamp,
+                $eventType,
+                $groupId,
+                $eventStatus,
+                $severity
+            );
+        }
+
+        $output .= '<table class="w100p h100p table-border-0"><tbody><tr>';
+
+        $width_td = (100 / count(explode(',', $severity)));
+
+        $td_count = 0;
+        foreach ($priorities as $key) {
+            $count = 0;
+            foreach ($events_rows as $event) {
+                if ((int) $key === (int) $event['criticity']) {
+                    $count = $event['count'];
+                }
+            }
+
+            switch ((int) $key) {
+                case 0:
+                    $text = __('Maintenance');
+                    $color = get_priority_class((int) $key);
+                break;
+
+                case 1:
+                    $text = __('Informational');
+                    $color = get_priority_class((int) $key);
+                break;
+
+                case 2:
+                    $text = __('Normal');
+                    $color = get_priority_class((int) $key);
+                break;
+
+                case 3:
+                    $text = __('Warning');
+                    $color = get_priority_class((int) $key);
+                break;
+
+                case 4:
+                    $text = __('Critical');
+                    $color = get_priority_class((int) $key);
+                break;
+
+                case 5:
+                    $text = __('Minor');
+                    $color = get_priority_class((int) $key);
+                break;
+
+                case 6:
+                    $text = __('Major');
+                    $color = get_priority_class((int) $key);
+                break;
+
+                case 20:
+                    $text = __('Not normal');
+                    $color = get_priority_class((int) $key);
+                break;
+
+                case 21:
+                    $text = __('Critical').'/'.__('Normal');
+                    $color = get_priority_class((int) $key);
+                break;
+
+                case 34:
+                    $text = __('Warning').'/'.__('Critical');
+                    $color = get_priority_class((int) $key);
+                break;
+
+                default:
+                return false;
+            }
+
+            $border = '';
+            $td_count++;
+            if (count($priorities) > $td_count) {
+                $border = ' border-right: 1px solid white; border-collapse: collapse;';
+            }
+
+            $output .= '<td class="'.$color.'" style="width: '.$width_td.'%;'.$border.'"><span class="med_data">';
+            $output .= $count;
+            $output .= '</span><br>';
+            $output .= $text;
+            $output .= '</td>';
+        }
+
+        $output .= '</tr></tbody></table>';
+
+        return $output;
+    }
+
+
+    /**
+     * Get description.
+     *
+     * @return string.
+     */
+    public static function getDescription()
+    {
+        return __('Event cardboard');
+    }
+
+
+    /**
+     * Get Name.
+     *
+     * @return string.
+     */
+    public static function getName()
+    {
+        return 'EventCardboard';
+    }
+
+
+    /**
+     * Get size Modal Configuration.
+     *
+     * @return array
+     */
+    public function getSizeModalConfiguration(): array
+    {
+        if (is_metaconsole() === true) {
+            $size = [
+                'width'  => 950,
+                'height' => 450,
+            ];
+        } else {
+            $size = [
+                'width'  => 900,
+                'height' => 450,
+            ];
+        }
+
+        return $size;
+    }
+
+
+}
diff --git a/pandora_console/include/styles/meta_dashboards.css b/pandora_console/include/styles/meta_dashboards.css
index f75afafa93..f3716c0f81 100644
--- a/pandora_console/include/styles/meta_dashboards.css
+++ b/pandora_console/include/styles/meta_dashboards.css
@@ -29,3 +29,18 @@ li#select_multiple_modules_filtered {
 #menu_tab li.nomn form#form-select-dashboard {
   margin-top: 0px !important;
 }
+
+.table-border-0 {
+  border: none !important;
+  border-spacing: 0px !important;
+}
+
+.big_data {
+  text-decoration: none;
+  font-size: 2em;
+}
+
+.med_data {
+  text-decoration: none;
+  font-size: 1.5em;
+}