diff --git a/pandora_console/extras/mr/68.sql b/pandora_console/extras/mr/68.sql
new file mode 100644
index 0000000000..669eceaecd
--- /dev/null
+++ b/pandora_console/extras/mr/68.sql
@@ -0,0 +1,7 @@
+START TRANSACTION;
+
+SET @widget_id = NULL;
+SELECT @widget_id := `id` FROM `twidget` WHERE `unique_name` = 'GisMap';
+INSERT IGNORE INTO `twidget` (`id`,`class_name`,`unique_name`,`description`,`options`,`page`) VALUES (@widget_id,'GisMap','GisMap','Gis map','','GisMap.php');
+
+COMMIT;
\ No newline at end of file
diff --git a/pandora_console/images/widgets/GisMap.png b/pandora_console/images/widgets/GisMap.png
new file mode 100644
index 0000000000..0cbfbf37b6
Binary files /dev/null and b/pandora_console/images/widgets/GisMap.png differ
diff --git a/pandora_console/include/lib/Dashboard/Widgets/GisMap.php b/pandora_console/include/lib/Dashboard/Widgets/GisMap.php
new file mode 100644
index 0000000000..3cb967cf8c
--- /dev/null
+++ b/pandora_console/include/lib/Dashboard/Widgets/GisMap.php
@@ -0,0 +1,541 @@
+width = $width;
+
+ // Height.
+ $this->height = $height;
+
+ // Grid Width.
+ $this->gridWidth = $gridWidth;
+
+ // Cell Id.
+ $this->cellId = $cellId;
+
+ // Options.
+ $this->values = $this->decoders($this->getOptionsWidget());
+
+ // Page.
+ $this->page = basename(__FILE__);
+
+ // ClassName.
+ $class = new \ReflectionClass($this);
+ $this->className = $class->getShortName();
+
+ // Title.
+ $this->title = __('Gis map');
+
+ // Name.
+ if (empty($this->name) === true) {
+ $this->name = 'GisMap';
+ }
+
+ // This forces at least a first configuration.
+ $this->configurationRequired = false;
+ if (empty($this->values['gis_map']) === true) {
+ $this->configurationRequired = true;
+ }
+ }
+
+
+ /**
+ * 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['gis_map']) === true) {
+ $values['gis_map'] = $decoder['gis_map'];
+ }
+
+ return $values;
+ }
+
+
+ /**
+ * Generates inputs for form (specific).
+ *
+ * @return array Of inputs.
+ *
+ * @throws Exception On error.
+ */
+ public function getFormInputs(): array
+ {
+ global $config;
+
+ include_once $config['homedir'].'/include/functions_gis.php';
+
+ // Retrieve global - common inputs.
+ $inputs = parent::getFormInputs();
+
+ if ((bool) $config['activate_gis'] === true) {
+ $maps = gis_get_maps();
+ }
+
+ $array_map = [];
+ foreach ($maps as $map) {
+ if (check_acl($config['id_user'], $map['group_id'], 'MR') === false
+ && check_acl($config['id_user'], $map['group_id'], 'MW') === false
+ && check_acl($config['id_user'], $map['group_id'], 'MM') === false
+ ) {
+ continue;
+ }
+
+ $array_map[$map['id_tgis_map']] = $map['map_name'];
+ }
+
+ // Filters.
+ $inputs[] = [
+ 'class' => 'flex flex-row',
+ 'label' => __('GIS maps'),
+ 'arguments' => [
+ 'type' => 'select',
+ 'fields' => $array_map,
+ 'name' => 'gis_map',
+ 'return' => true,
+ 'selected' => ($this->values['gis_map'] === null) ? 0 : $this->values['gis_map'],
+ ],
+ ];
+
+ return $inputs;
+ }
+
+
+ /**
+ * Get Post for widget.
+ *
+ * @return array
+ */
+ public function getPost(): array
+ {
+ // Retrieve global - common inputs.
+ $values = parent::getPost();
+
+ $values['gis_map'] = \get_parameter('gis_map', 0);
+
+ return $values;
+ }
+
+
+ /**
+ * Draw widget.
+ *
+ * @return string;
+ */
+ public function load()
+ {
+ global $config;
+
+ include_once $config['homedir'].'/include/functions_gis.php';
+ include_once $config['homedir'].'/include/functions_agents.php';
+
+ \ui_require_javascript_file('openlayers.pandora', 'include/javascript/', true);
+ \ui_require_javascript_file('OpenLayers/OpenLayers', 'include/javascript/', true);
+
+ $map = db_get_row('tgis_map', 'id_tgis_map', $this->values['gis_map']);
+
+ $output = '';
+ if (check_acl($config['id_user'], $map['group_id'], 'MR') === false
+ && check_acl($config['id_user'], $map['group_id'], 'MW') === false
+ && check_acl($config['id_user'], $map['group_id'], 'MM') === false
+ ) {
+ $output .= '
';
+ $output .= ui_print_error_message(
+ __('You don\'t have access'),
+ '',
+ true
+ );
+ $output .= '
';
+ return $output;
+ }
+
+ $confMap = gis_get_map_conf($this->values['gis_map']);
+
+ // Default open map (used to overwrite unlicensed google map view).
+ $confMapDefault = get_good_con();
+ $confMapDefaultFull = json_decode($confMapDefault['conection_data'], true);
+ $confMapUrlDefault = $confMapDefaultFull['url'];
+
+ $num_baselayer = 0;
+ // Initialy there is no Gmap base layer.
+ $gmap_layer = false;
+ if ($confMap !== false) {
+ foreach ($confMap as $mapC) {
+ $baselayers[$num_baselayer]['typeBaseLayer'] = $mapC['connection_type'];
+ $baselayers[$num_baselayer]['name'] = $mapC['conection_name'];
+ $baselayers[$num_baselayer]['num_zoom_levels'] = $mapC['num_zoom_levels'];
+ $decodeJSON = json_decode($mapC['conection_data'], true);
+
+ switch ($mapC['connection_type']) {
+ case 'OSM':
+ $baselayers[$num_baselayer]['url'] = $decodeJSON['url'];
+ break;
+
+ case 'Gmap':
+ if (!isset($decodeJSON['gmap_key']) || empty($decodeJSON['gmap_key'])) {
+ // If there is not gmap_key, show the default view.
+ $baselayers[$num_baselayer]['url'] = $confMapUrlDefault;
+ $baselayers[$num_baselayer]['typeBaseLayer'] = 'OSM';
+ } else {
+ $baselayers[$num_baselayer]['gmap_type'] = $decodeJSON['gmap_type'];
+ $baselayers[$num_baselayer]['gmap_key'] = $decodeJSON['gmap_key'];
+ $gmap_key = $decodeJSON['gmap_key'];
+ // Once a Gmap base layer is found we mark it to import the API.
+ $gmap_layer = true;
+ }
+ break;
+
+ case 'Static_Image':
+ $baselayers[$num_baselayer]['url'] = $decodeJSON['url'];
+ $baselayers[$num_baselayer]['bb_left'] = $decodeJSON['bb_left'];
+ $baselayers[$num_baselayer]['bb_right'] = $decodeJSON['bb_right'];
+ $baselayers[$num_baselayer]['bb_bottom'] = $decodeJSON['bb_bottom'];
+ $baselayers[$num_baselayer]['bb_top'] = $decodeJSON['bb_top'];
+ $baselayers[$num_baselayer]['image_width'] = $decodeJSON['image_width'];
+ $baselayers[$num_baselayer]['image_height'] = $decodeJSON['image_height'];
+ break;
+
+ case 'WMS':
+ $baselayers[$num_baselayer]['url'] = $decodeJSON['url'];
+ $baselayers[$num_baselayer]['layers'] = $decodeJSON['layers'];
+ break;
+
+ default:
+ // Do nothing.
+ break;
+ }
+
+ $num_baselayer++;
+ if ($mapC['default_map_connection'] == 1) {
+ $numZoomLevels = $mapC['num_zoom_levels'];
+ }
+ }
+ }
+
+ if ($gmap_layer === true) {
+ if (https_is_running()) {
+ ?>
+
+
+
+ values['gis_map']);
+
+ $output .= '';
+ gis_print_map(
+ 'map_'.$this->cellId,
+ $map['zoom_level'],
+ $map['initial_latitude'],
+ $map['initial_longitude'],
+ $baselayers,
+ $controls
+ );
+ $output .= '';
+
+ if (empty($layers) === false) {
+ foreach ($layers as $layer) {
+ gis_make_layer(
+ $layer['layer_name'],
+ $layer['view_layer'],
+ null,
+ $layer['id_tmap_layer']
+ );
+
+ // Calling agents_get_group_agents with none to obtain the names in the same case as they are in the DB.
+ $agentNamesByGroup = [];
+ if ($layer['tgrupo_id_grupo'] >= 0) {
+ $agentNamesByGroup = agents_get_group_agents(
+ $layer['tgrupo_id_grupo'],
+ false,
+ 'none',
+ true,
+ true,
+ false
+ );
+ }
+
+ $agentNamesByLayer = gis_get_agents_layer($layer['id_tmap_layer']);
+
+ $groupsByAgentId = gis_get_groups_layer_by_agent_id($layer['id_tmap_layer']);
+ $agentNamesOfGroupItems = [];
+ foreach ($groupsByAgentId as $agentId => $groupInfo) {
+ $agentNamesOfGroupItems[$agentId] = $groupInfo['agent_name'];
+ }
+
+ $agentNames = array_unique($agentNamesByGroup + $agentNamesByLayer + $agentNamesOfGroupItems);
+
+ foreach ($agentNames as $key => $agentName) {
+ $idAgent = $key;
+ $coords = gis_get_data_last_position_agent($idAgent);
+
+ if ($coords === false) {
+ $coords['stored_latitude'] = $map['default_latitude'];
+ $coords['stored_longitude'] = $map['default_longitude'];
+ } else {
+ if ($show_history == 'y') {
+ $lastPosition = [
+ 'longitude' => $coords['stored_longitude'],
+ 'latitude' => $coords['stored_latitude'],
+ ];
+ gis_add_path($layer['layer_name'], $idAgent, $lastPosition);
+ }
+ }
+
+ $status = agents_get_status($idAgent, true);
+ $icon = gis_get_agent_icon_map($idAgent, true, $status);
+ $icon_size = getimagesize($icon);
+ $icon_width = $icon_size[0];
+ $icon_height = $icon_size[1];
+
+ // Is a group item.
+ if (empty($groupsByAgentId[$idAgent]) === false) {
+ $groupId = (int) $groupsByAgentId[$idAgent]['id'];
+ $groupName = $groupsByAgentId[$idAgent]['name'];
+
+ gis_add_agent_point(
+ $layer['layer_name'],
+ io_safe_output($groupName),
+ $coords['stored_latitude'],
+ $coords['stored_longitude'],
+ $icon,
+ $icon_width,
+ $icon_height,
+ $idAgent,
+ $status,
+ 'point_group_info',
+ $groupId
+ );
+ } else {
+ $parent = db_get_value('id_parent', 'tagente', 'id_agente', $idAgent);
+
+ gis_add_agent_point(
+ $layer['layer_name'],
+ io_safe_output($agentName),
+ $coords['stored_latitude'],
+ $coords['stored_longitude'],
+ $icon,
+ $icon_width,
+ $icon_height,
+ $idAgent,
+ $status,
+ 'point_agent_info',
+ $parent
+ );
+ }
+ }
+ }
+
+ gis_add_parent_lines();
+
+ $timestampLastOperation = db_get_value_sql('SELECT UNIX_TIMESTAMP()');
+
+ gis_activate_select_control();
+ gis_activate_ajax_refresh($layers, $timestampLastOperation);
+ }
+
+ return $output;
+ }
+
+
+ /**
+ * Get description.
+ *
+ * @return string.
+ */
+ public static function getDescription()
+ {
+ return __('GIS map');
+ }
+
+
+ /**
+ * Get Name.
+ *
+ * @return string.
+ */
+ public static function getName()
+ {
+ return 'GisMap';
+ }
+
+
+ /**
+ * Get size Modal Configuration.
+ *
+ * @return array
+ */
+ public function getSizeModalConfiguration(): array
+ {
+ $size = [
+ 'width' => 500,
+ 'height' => 300,
+ ];
+
+ return $size;
+ }
+
+
+}
diff --git a/pandora_console/operation/gis_maps/render_view.php b/pandora_console/operation/gis_maps/render_view.php
index e6cfaaee99..d826095a50 100644
--- a/pandora_console/operation/gis_maps/render_view.php
+++ b/pandora_console/operation/gis_maps/render_view.php
@@ -304,23 +304,7 @@ if ($layers != false) {
gis_add_parent_lines();
- switch ($config['dbtype']) {
- case 'mysql':
- $timestampLastOperation = db_get_value_sql('SELECT UNIX_TIMESTAMP()');
- break;
-
- case 'postgresql':
- $timestampLastOperation = db_get_value_sql(
- "SELECT ceil(date_part('epoch', CURRENT_TIMESTAMP))"
- );
- break;
-
- case 'oracle':
- $timestampLastOperation = db_get_value_sql(
- "SELECT ceil((sysdate - to_date('19700101000000','YYYYMMDDHH24MISS')) * (".SECONDS_1DAY.')) FROM dual'
- );
- break;
- }
+ $timestampLastOperation = db_get_value_sql('SELECT UNIX_TIMESTAMP()');
gis_activate_select_control();
gis_activate_ajax_refresh($layers, $timestampLastOperation);
diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql
index a7df8d9764..25b7cc781d 100644
--- a/pandora_console/pandoradb_data.sql
+++ b/pandora_console/pandoradb_data.sql
@@ -2832,7 +2832,8 @@ INSERT INTO `twidget` (`id`,`class_name`,`unique_name`,`description`,`options`,`
(44,'WuxWidget','wux_transaction','Agent WUX transaction','','wux_transaction.php'),
(45,'WuxStatsWidget','wux_transaction_stats','WUX transaction stats','','wux_transaction_stats.php'),
(46,'SecurityHardening','security_hardening','Security Hardening','','security_hardening.php'),
- (47,'ServiceLevelWidget','service_level','Service Level','','service_level.php');
+ (47,'ServiceLevelWidget','service_level','Service Level','','service_level.php'),
+ (48,'GisMap','GisMap','Gis map','','GisMap.php');
INSERT INTO `tmap` (`id`,`id_group`,`id_user`,`type`,`subtype`,`name`,`description`,`height`,`width`,`center_x`,`center_y`,`background`,`background_options`,`source_period`,`source`,`source_data`,`generation_method`,`generated`,`filter`,`id_group_map`,`refresh_time`) VALUES (1,'0','admin',0,0,'Sample dynamic map','This is a sample dynamic map.',900,900,0,0,'',0,60,0,'0',6,0,'{\"dont_show_subgroups\":0,\"node_radius\":40,\"x_offs\":\"0\",\"y_offs\":\"0\",\"z_dash\":\"1\",\"node_sep\":\"0.25\",\"rank_sep\":\"0.5\",\"mindist\":\"1\",\"kval\":\"0.3\"}',0,300);
INSERT INTO `treport` (`id_report`,`id_user`,`name`,`description`,`private`,`id_group`,`custom_logo`,`header`,`first_page`,`footer`,`custom_font`,`id_template`,`id_group_edit`,`metaconsole`,`non_interactive`,`hidden`,`orientation`,`cover_page_render`,`index_render`) VALUES (1,'admin','Sample report #1','This is a sample report, just to show you some general report items.',0,0,NULL,NULL,'<p style="text-align: center;"> </p>
<p style="text-align: center;"> </p>
<p style="text-align: center;"> </p>
<p style="text-align: center;"> </p>
<p style="text-align: center;"> </p>
<p style="text-align: center;"> </p>
<p style="text-align: center;"> </p>
<p style="text-align: center;"><img src="http://localhost/pandora_console//images/pandora_report_logo.png" alt="" width="800" /></p>
<p style="text-align: center;"> </p>
<p style="text-align: center;"><span style="font-size: xx-large;">(_REPORT_NAME_)</span></p>
<p style="text-align: center;"><span style="font-size: large;">(_DATETIME_)</span></p>',NULL,'Lato-Regular.ttf',0,0,0,0,0,'vertical',1,1);
diff --git a/pandora_console/views/dashboard/listWidgets.php b/pandora_console/views/dashboard/listWidgets.php
index 01767c1f9c..2c4272ddeb 100644
--- a/pandora_console/views/dashboard/listWidgets.php
+++ b/pandora_console/views/dashboard/listWidgets.php
@@ -71,6 +71,10 @@ foreach ($widgets as $widget) {
continue;
}
+ if ($widget['unique_name'] === 'GisMap' && (bool) $config['activate_gis'] === false) {
+ continue;
+ }
+
$imageWidget = '/images/widgets/'.$widget['unique_name'].'.png';
$output .= '';