pandorafms/pandora_console/include/lib/Dashboard/Widget.php

763 lines
18 KiB
PHP
Raw Normal View History

2020-03-26 12:29:38 +01:00
<?php
namespace PandoraFMS\Dashboard;
/**
* Dashboard manager.
*/
class Widget
{
/**
* Dasboard ID.
*
* @var integer
*/
2021-02-18 12:47:42 +01:00
protected $dashboardId;
2020-03-26 12:29:38 +01:00
/**
* Cell ID.
*
* @var integer
*/
2021-02-10 15:00:23 +01:00
protected $cellId;
2020-03-26 12:29:38 +01:00
/**
* Widget Id.
*
* @var integer
*/
2021-02-18 12:47:42 +01:00
protected $widgetId;
2020-03-26 12:29:38 +01:00
/**
* Values widget.
*
* @var array
*/
private $values;
2021-02-17 12:57:13 +01:00
/**
* Target node Id.
*
* @var integer
*/
2021-02-18 12:47:42 +01:00
protected $nodeId;
/**
* Should we show select node in metaconsole environments?
*
* @var boolean
*/
private $showSelectNodeMeta;
2021-02-17 12:57:13 +01:00
2020-03-26 12:29:38 +01:00
/**
* Contructor widget.
*
* @param integer $cellId Cell Id.
* @param integer $dashboardId Dashboard Id.
* @param integer $widgetId Widget Id.
*/
public function __construct(
int $cellId,
int $dashboardId,
int $widgetId
) {
// Check exists Cell id.
if (empty($widgetId) === false) {
$this->widgetId = $widgetId;
$this->cellId = $cellId;
$this->dashboardId = $dashboardId;
$this->fields = $this->get();
2021-02-18 12:47:42 +01:00
$this->className = $this->fields['class_name'];
2020-03-26 12:29:38 +01:00
$cellClass = new Cell($this->cellId, $this->dashboardId);
$this->dataCell = $cellClass->get();
2020-04-30 14:08:56 +02:00
$this->values = $this->decoders($this->getOptionsWidget());
2021-02-17 12:57:13 +01:00
if (isset($this->values['node']) === true) {
$this->nodeId = $this->values['node'];
}
2020-03-26 12:29:38 +01:00
}
return $this;
}
/**
* Retrieve a cell definition.
*
* @return array cell data.
*/
public function get()
{
$sql = sprintf(
'SELECT *
FROM twidget
WHERE id = %d',
$this->widgetId
);
$data = \db_get_row_sql($sql);
if ($data === false) {
return [];
}
return $data;
}
/**
* Get options Cell widget configuration.
*
* @return array
*/
public function getOptionsWidget():array
{
$result = [];
if (empty($this->dataCell['options']) === false) {
$result = \json_decode($this->dataCell['options'], true);
// Hack retrocompatibility.
if ($result === null) {
$result = \unserialize($this->dataCell['options']);
}
}
return $result;
}
/**
* Get options Cell widget configuration.
*
* @return array
*/
public function getPositionWidget():array
{
global $config;
$result = [];
if (empty($this->dataCell['position']) === false) {
$result = \json_decode($this->dataCell['position'], true);
// Hack retrocompatibility.
if ($result === null) {
$result = \unserialize($this->dataCell['position']);
}
}
return $result;
}
/**
* Insert widgets.
*
* @return void
*/
public function install()
{
$id = db_get_value(
'id',
'twidget',
'unique_name',
$this->getName()
);
if ($id !== false) {
return;
}
$values = [
'unique_name' => $this->getName(),
'description' => $this->getDescription(),
'options' => '',
'page' => $this->page,
'class_name' => $this->className,
];
$res = db_process_sql_insert('twidget', $values);
return $res;
}
/**
* Get all dashboard user can you see.
*
* @param integer $offset Offset query.
* @param integer $limit Limit query.
* @param string|null $search Search word.
*
* @return array Return info all dasboards.
*/
static public function getWidgets(
int $offset=-1,
int $limit=-1,
?string $search=''
):array {
global $config;
$sql_limit = '';
if ($offset !== -1 && $limit !== -1) {
$sql_limit = ' LIMIT '.$offset.','.$limit;
}
$sql_search = '';
if (empty($search) === false) {
$sql_search = 'AND description LIKE "%'.$search.'%" ';
}
// User admin view all dashboards.
$sql_widget = \sprintf(
'SELECT * FROM twidget
2020-07-17 10:33:40 +02:00
WHERE 1=1
2020-03-26 12:29:38 +01:00
%s
ORDER BY `description` %s',
$sql_search,
$sql_limit
);
$widgets = \db_get_all_rows_sql($sql_widget);
if ($widgets === false) {
$widgets = [];
}
return $widgets;
}
/**
* Install Widgets.
*
* @param integer $cellId Cell ID.
*
* @return void
*/
public static function dashboardInstallWidgets(int $cellId)
{
global $config;
$dir = $config['homedir'].'/include/lib/Dashboard/Widgets/';
$handle = opendir($dir);
if ($handle === false) {
return;
}
$ignores = [
'.',
'..',
];
2020-07-17 10:33:40 +02:00
while (false !== ($file = readdir($handle))) {
2020-03-26 12:29:38 +01:00
if (in_array($file, $ignores) === true) {
continue;
}
$filepath = realpath($dir.'/'.$file);
if (is_readable($filepath) === false
|| is_dir($filepath) === true
|| preg_match('/.*\.php$/', $filepath) === false
) {
continue;
}
$name = preg_replace('/.php/', '', $file);
$className = 'PandoraFMS\Dashboard';
$not_installed = false;
switch ($name) {
case 'agent_module':
$className .= '\AgentModuleWidget';
break;
case 'alerts_fired':
$className .= '\AlertsFiredWidget';
break;
case 'clock':
$className .= '\ClockWidget';
break;
case 'custom_graph':
$className .= '\CustomGraphWidget';
break;
case 'events_list':
$className .= '\EventsListWidget';
break;
case 'example':
$className .= '\WelcomeWidget';
break;
case 'graph_module_histogram':
$className .= '\GraphModuleHistogramWidget';
break;
case 'groups_status':
$className .= '\GroupsStatusWidget';
break;
case 'maps_made_by_user':
$className .= '\MapsMadeByUser';
break;
case 'maps_status':
$className .= '\MapsStatusWidget';
break;
case 'module_icon':
$className .= '\ModuleIconWidget';
break;
case 'module_status':
$className .= '\ModuleStatusWidget';
break;
case 'module_table_value':
$className .= '\ModuleTableValueWidget';
break;
case 'module_value':
$className .= '\ModuleValueWidget';
break;
case 'monitor_health':
$className .= '\MonitorHealthWidget';
break;
case 'network_map':
if (\enterprise_installed() === false) {
$not_installed = true;
}
$className .= '\NetworkMapWidget';
break;
case 'post':
$className .= '\PostWidget';
break;
case 'reports':
$className .= '\ReportsWidget';
break;
case 'service_map':
if (\enterprise_installed() === false) {
$not_installed = true;
}
$className .= '\ServiceMapWidget';
break;
2021-08-13 14:12:21 +02:00
case 'service_view':
if (\enterprise_installed() === false) {
$not_installed = true;
}
$className .= '\ServiceViewWidget';
break;
2020-03-26 12:29:38 +01:00
case 'single_graph':
$className .= '\SingleGraphWidget';
break;
case 'sla_percent':
$className .= '\SLAPercentWidget';
break;
case 'system_group_status':
$className .= '\SystemGroupStatusWidget';
break;
case 'tactical':
$className .= '\TacticalWidget';
break;
case 'top_n_events_by_module':
$className .= '\TopNEventByModuleWidget';
break;
case 'top_n_events_by_group':
$className .= '\TopNEventByGroupWidget';
break;
case 'top_n':
$className .= '\TopNWidget';
break;
case 'tree_view':
$className .= '\TreeViewWidget';
break;
case 'url':
$className .= '\UrlWidget';
break;
case 'wux_transaction_stats':
if (\enterprise_installed() === false) {
$not_installed = true;
}
$className .= '\WuxStatsWidget';
break;
case 'wux_transaction':
if (\enterprise_installed() === false) {
$not_installed = true;
}
$className .= '\WuxWidget';
break;
default:
$className = false;
break;
}
if ($not_installed === false && $className !== false) {
include_once $filepath;
$instance = new $className($cellId, 0, 0);
if (method_exists($instance, 'install') === true) {
$instance->install();
}
}
}
2020-07-17 10:33:40 +02:00
closedir($handle);
2020-03-26 12:29:38 +01:00
}
/**
* Draw html.
*
* @return string Html data.
*/
public function printHtml()
{
global $config;
$output = '';
2021-02-17 12:57:13 +01:00
if ((bool) \is_metaconsole() === true) {
\enterprise_include_once('include/functions_metaconsole.php');
2021-02-18 12:47:42 +01:00
if ($this->nodeId > 0) {
2021-02-17 12:57:13 +01:00
if (\metaconsole_connect(null, $this->nodeId) !== NOERR) {
$output .= '<div class="container-center">';
$output .= \ui_print_info_message(
__('Failed to connect to node %d', $this->nodeId),
'',
true
);
$output .= '</div>';
return $output;
}
2021-02-18 12:47:42 +01:00
$config['metaconsole'] = false;
2021-02-17 12:57:13 +01:00
}
}
2020-03-26 12:29:38 +01:00
if ($this->configurationRequired === true) {
$output .= '<div class="container-center">';
$output .= \ui_print_info_message(
__('Please configure this widget before usage'),
'',
true
);
$output .= '</div>';
} else if ($this->loadError === true) {
$output .= '<div class="container-center">';
$output .= \ui_print_error_message(
__('Widget cannot be loaded'),
'',
true
);
$output .= __('Please, configure the widget again to recover it');
$output .= '</div>';
} else {
$output .= $this->load();
}
2021-02-17 12:57:13 +01:00
if ((bool) \is_metaconsole() === true) {
2021-02-18 12:47:42 +01:00
if ($this->nodeId > 0) {
2021-02-17 12:57:13 +01:00
\metaconsole_restore_db();
2021-02-18 12:47:42 +01:00
$config['metaconsole'] = true;
2021-02-17 12:57:13 +01:00
}
}
2020-03-26 12:29:38 +01:00
return $output;
}
/**
* Generates inputs for form.
*
* @return array Of inputs.
*/
public function getFormInputs(): array
{
2021-04-14 12:07:38 +02:00
global $config;
2020-03-26 12:29:38 +01:00
$inputs = [];
$values = $this->values;
// Default values.
if (isset($values['title']) === false) {
$values['title'] = $this->getDescription();
}
if (empty($values['background']) === true) {
$values['background'] = '#ffffff';
2021-04-14 12:07:38 +02:00
2022-01-17 10:22:30 +01:00
if ($config['style'] === 'pandora_black' && !is_metaconsole()) {
2021-04-14 12:07:38 +02:00
$values['background'] = '#222222';
}
2020-03-26 12:29:38 +01:00
}
$inputs[] = [
'arguments' => [
'type' => 'hidden',
'name' => 'dashboardId',
'value' => $this->dashboardId,
],
];
$inputs[] = [
'arguments' => [
'type' => 'hidden',
'name' => 'cellId',
'value' => $this->cellId,
],
];
$inputs[] = [
'arguments' => [
'type' => 'hidden',
'name' => 'widgetId',
'value' => $this->widgetId,
],
];
$inputs[] = [
'label' => __('Title'),
'arguments' => [
'type' => 'text',
'name' => 'title',
'value' => $values['title'],
'return' => true,
'size' => 0,
],
];
$inputs[] = [
'label' => __('Background'),
'arguments' => [
'wrapper' => 'div',
'name' => 'background',
'type' => 'color',
'value' => $values['background'],
'return' => true,
],
];
2021-02-18 12:47:42 +01:00
if ((bool) \is_metaconsole() === true
&& $this->shouldSelectNode() === true
) {
2021-02-17 12:57:13 +01:00
\enterprise_include_once('include/functions_metaconsole.php');
$servers = \metaconsole_get_servers();
if (is_array($servers) === true) {
$servers = array_reduce(
$servers,
function ($carry, $item) {
$carry[$item['id']] = $item['server_name'];
return $carry;
}
);
} else {
$servers = [];
}
$inputs[] = [
'label' => __('Node'),
'arguments' => [
2021-02-18 12:47:42 +01:00
'wrapper' => 'div',
'name' => 'node',
'type' => 'select',
'fields' => $servers,
'selected' => $values['node'],
'nothing' => __('This metaconsole'),
'nothing_value' => -1,
'return' => true,
2021-02-17 12:57:13 +01:00
],
];
}
2020-03-26 12:29:38 +01:00
return $inputs;
}
/**
* Get Post for widget.
*
* @return array
*/
public function getPost():array
{
$values = [];
$values['title'] = \get_parameter('title', '');
$values['background'] = \get_parameter('background', '#ffffff');
2021-02-17 12:57:13 +01:00
if ((bool) \is_metaconsole() === true) {
2021-02-18 12:47:42 +01:00
if ($this->shouldSelectNode() === true) {
$values['node'] = \get_parameter('node', null);
} else {
$values['node'] = \get_parameter('metaconsoleId', null);
}
2021-02-17 12:57:13 +01:00
}
2020-03-26 12:29:38 +01:00
return $values;
}
2020-04-30 14:08:56 +02:00
/**
* Decoders hack for retrocompability.
*
* @param array $decoder Values.
*
* @return array Returns the values with the correct key.
*/
public function decoders(array $decoder):array
{
$values = [];
if (isset($decoder['title']) === true) {
$values['title'] = $decoder['title'];
}
if (isset($decoder['background-color']) === true) {
$values['background'] = $decoder['background-color'];
}
if (isset($decoder['background']) === true) {
$values['background'] = $decoder['background'];
}
2021-02-17 12:57:13 +01:00
if (isset($decoder['node']) === true) {
$values['node'] = $decoder['node'];
}
2020-04-30 14:08:56 +02:00
return $values;
}
2020-03-26 12:29:38 +01:00
/**
* Size Cell.
*
* @return array
*/
protected function getSize():array
{
$gridWidth = $this->gridWidth;
if ($this->gridWidth === 0) {
$gridWidth = 1170;
}
if ($this->width === 0) {
2021-03-03 13:42:02 +01:00
$width = (((int) $this->position['width'] / 12 * $gridWidth) - 60);
2020-03-26 12:29:38 +01:00
} else {
2021-03-03 13:42:02 +01:00
$width = (((int) $this->width / 12 * $gridWidth) - 60);
2020-03-26 12:29:38 +01:00
}
if ($this->height === 0) {
$height = ((((int) $this->position['height'] - 1) * 80) + 60 - 30);
} else {
$height = ((((int) $this->height - 1) * 80) + 60 - 30);
}
$result = [
'width' => $width,
'height' => $height,
];
return $result;
}
2021-02-18 12:47:42 +01:00
/**
* Should select for nodes been shown while in metaconsole environment?
*
* @return boolean
*/
protected function shouldSelectNode():bool
{
if ($this->showSelectNodeMeta !== null) {
return (bool) $this->showSelectNodeMeta;
}
switch ($this->className) {
case 'EventsListWidget':
case 'ReportsWidget':
2021-02-18 13:20:54 +01:00
case 'MapsMadeByUser':
case 'AlertsFiredWidget':
2021-02-18 12:47:42 +01:00
$this->showSelectNodeMeta = true;
break;
default:
$this->showSelectNodeMeta = false;
break;
}
return (bool) $this->showSelectNodeMeta;
}
2021-02-10 15:00:23 +01:00
/**
* Get description should be implemented for each child.
*
* @return string
*/
public static function getDescription()
{
return '**NOT DEFINED**';
}
/**
* Load should be implemented for each child.
*
* @return string
*/
public function load()
{
return '**NOT DEFINED**';
}
/**
* Get name should be implemented for each child.
*
* @return string
*/
public static function getName()
{
return '**NOT DEFINED**';
}
/**
* Return aux javascript code for forms.
*
* @return string
*/
public function getFormJS()
{
return '';
}
2020-03-26 12:29:38 +01:00
}