From a87a37ca7b7e79d259330718aa2e5406a6f3d3a4 Mon Sep 17 00:00:00 2001
From: Sae126V
Date: Thu, 31 Aug 2023 11:16:26 +0000
Subject: [PATCH] [GT-187] Add feature selecting multiple sites
---
.../controllers/downtime/add_downtime.php | 70 ++++----
.../controllers/downtime/downtime_utils.php | 169 ++++++++++++++++++
.../controllers/downtime/edit_downtime.php | 67 ++++---
.../downtime/view_endpoint_tree.php | 35 +++-
.../views/downtime/add_downtime.php | 98 +++++++---
.../views/downtime/added_downtime.php | 26 ++-
.../views/downtime/confirm_add_downtime.php | 82 ++++++---
...wntime_edit_view_nested_endpoints_list.php | 14 +-
.../views/downtime/edit_downtime.php | 28 ++-
.../downtime/view_nested_endpoints_list.php | 17 +-
10 files changed, 461 insertions(+), 145 deletions(-)
create mode 100644 htdocs/web_portal/controllers/downtime/downtime_utils.php
diff --git a/htdocs/web_portal/controllers/downtime/add_downtime.php b/htdocs/web_portal/controllers/downtime/add_downtime.php
index becb0c73f..1238f731d 100644
--- a/htdocs/web_portal/controllers/downtime/add_downtime.php
+++ b/htdocs/web_portal/controllers/downtime/add_downtime.php
@@ -24,6 +24,7 @@
require_once __DIR__.'/../../../../lib/Gocdb_Services/Factory.php';
require_once __DIR__.'/../utils.php';
require_once __DIR__.'/../../../web_portal/components/Get_User_Principle.php';
+require_once __DIR__ . '/downtime_utils.php';
/**
* Controller for a new_downtime request.
@@ -71,53 +72,52 @@ function submit(\User $user = null) {
if($confirmed == true){
//Downtime is confirmed, submit it
//$downtimeInfo = unserialize($_REQUEST['newValues']); // didn't cater for UTF-8 chars
+ /**
+ * If confirmed by an user, submit the details of affected services
+ * and endpoints along with other details for each individual site.
+ */
$downtimeInfo = json_decode($_POST['newValues'], TRUE);
$serv = \Factory::getDowntimeService();
+ $downtimeInfo = unsetVariables($downtimeInfo, 'add');
+ $params = [];
+
+ foreach ($downtimeInfo['SITE_LEVEL_DETAILS'] as $siteID) {
+ $downtimeInfo['Impacted_Services'] = $siteID['services'];
+ $downtimeInfo['Impacted_Endpoints'] = $siteID['endpoints'];
+
+ $params['submittedDowntimes'][$siteID['siteName']] =
+ $serv->addDowntime($downtimeInfo, $user);
+ }
- $params['dt'] = $serv->addDowntime($downtimeInfo, $user);
show_view("downtime/added_downtime.php", $params);
}else{
//Show user confirmation screen with their input
$downtimeInfo = getDtDataFromWeb();
- //Need to sort the impacted_ids into impacted services and impacted endpoints
- $impactedids = $downtimeInfo['IMPACTED_IDS'];
+ list(
+ $siteLevelDetails,
+ $serviceWithEndpoints
+ ) = endpointToServiceMapping($downtimeInfo['IMPACTED_IDS']);
- $services=array();
- $endpoints=array();
+ // Delete the unsorted IDs from the downtime info
+ unset($downtimeInfo['IMPACTED_IDS']);
- //For each impacted id sort between endpoints and services using the prepended letter
- foreach($impactedids as $id){
- if (strpos($id, 's') !== FALSE){
- //This is a service id
- $services[] = str_replace('s', '', $id); //trim off the identifying char before storing in array
- }else{
- //This is an endpoint id
- $endpoints[] = str_replace('e', '', $id); //trim off the identifying char before storing in array
- }
+ if (!count($siteLevelDetails) > 1) {
+ $downtimeInfo['SINGLE_TIMEZONE'] = true;
}
- unset($downtimeInfo['IMPACTED_IDS']); //Delete the unsorted Ids from the downtime info
-
- $downtimeInfo['Impacted_Endpoints'] = $endpoints;
-
-
- $serv = \Factory::getServiceService();
-
- /** For endpoint put into downtime we want the parent service also. If a user has selected
- * endpoints but not the parent service here we will add the service to maintain the link beteween
- * a downtime having both the service and the endpoint.
- */
- foreach($downtimeInfo['Impacted_Endpoints'] as $endpointIds){
- $endpoint = $serv->getEndpoint($endpointIds);
- $services[] = $endpoint->getService()->getId();
- }
-
- //Remove any duplicate service ids and store the array of ids
- $services = array_unique($services);
-
- //Assign the impacted services and endpoints to their own arrays for us by the addDowntime method
- $downtimeInfo['Impacted_Services'] = $services;
+ list(
+ $siteLevelDetails,
+ $serviceWithEndpoints
+ ) = addParentServiceForEndpoints(
+ $serviceWithEndpoints,
+ $siteLevelDetails,
+ false,
+ $downtimeInfo['DOWNTIME']
+ );
+
+ $downtimeInfo['SITE_LEVEL_DETAILS'] = $siteLevelDetails;
+ $downtimeInfo['SERVICE_WITH_ENDPOINTS'] = $serviceWithEndpoints;
show_view("downtime/confirm_add_downtime.php", $downtimeInfo);
}
diff --git a/htdocs/web_portal/controllers/downtime/downtime_utils.php b/htdocs/web_portal/controllers/downtime/downtime_utils.php
new file mode 100644
index 000000000..f0905c4f6
--- /dev/null
+++ b/htdocs/web_portal/controllers/downtime/downtime_utils.php
@@ -0,0 +1,169 @@
+ $siteData) {
+ $siteDetails[$siteID]['services'] = [];
+
+ $newSite = \Factory::getSiteService()->getSite($siteID);
+ $siteDetails[$siteID]['siteName'] = $newSite->getShortName();
+
+ if ($hasMultipleTimezones) {
+ list(
+ $siteDetails[$siteID]['START_TIMESTAMP'],
+ $siteDetails[$siteID]['END_TIMESTAMP']
+ ) = setLocalTimeForSites($downtimeDetails, $siteID);
+ }
+
+ foreach (array_keys($siteData) as $serviceID) {
+ $servWithEndpoints[$siteID][$serviceID]['services'] = [];
+ $servWithEndpoints[$siteID][$serviceID]['services'][] = $serviceID;
+ // Ensuring that service IDs are unique for the selected sites.
+ $siteDetails[$siteID]['services'][] = $serviceID;
+ }
+ }
+
+ return [$siteDetails, $servWithEndpoints];
+}
+
+/**
+ * Converts UTC start and end timestamps to the local timezone
+ * of a specific site based on that site's timezone.
+ *
+ * @param mixed $downtimeDetails Downtime information.
+ * @param integer $siteID Site ID
+ */
+function setLocalTimeForSites($downtimeDetails, $siteID)
+{
+ $site = \Factory::getSiteService()->getSite($siteID);
+
+ $siteTimezone = $site->getTimeZoneId();
+
+ $startTimeAsString = $downtimeDetails['START_TIMESTAMP'];
+ $utcEndTime = $downtimeDetails['END_TIMESTAMP'];
+
+ $utcStartDateTime = DateTime::createFromFormat(
+ 'd/m/Y H:i',
+ $startTimeAsString,
+ new DateTimeZone('UTC')
+ );
+ $utcEndDateTime = DateTime::createFromFormat(
+ 'd/m/Y H:i',
+ $utcEndTime,
+ new DateTimeZone('UTC')
+ );
+
+ $targetSiteTimezone = new DateTimeZone($siteTimezone);
+ $utcOffset = $targetSiteTimezone->getOffset($utcStartDateTime);
+
+ // Calculate the equivalent time in the target timezone.
+ // Ref: https://www.php.net/manual/en/datetime.modify.php
+ $siteStartDateTime = $utcStartDateTime->modify("-$utcOffset seconds");
+ $siteEndDateTime = $utcEndDateTime->modify("-$utcOffset seconds");
+
+ return [
+ $siteStartDateTime->format('d/m/Y H:i'),
+ $siteEndDateTime->format('d/m/Y H:i')
+ ];
+}
+
+/**
+ * Unset a given variable, helper method to destroy the specified variables.
+ *
+ * @param mixed $downtimeObj Object to destroy specified variables.
+ * @param string $fromLocation Location from where the
+ * function is being called.
+ */
+function unsetVariables($downtimeObj, $fromLocation)
+{
+ if ($fromLocation == "add") {
+ unset($downtimeObj['SERVICE_WITH_ENDPOINTS']);
+ unset($downtimeObj['SINGLE_TIMEZONE']);
+ } else {
+ unset($downtimeObj['DOWNTIME']['EXISTINGID']);
+ unset($downtimeObj['isEdit']);
+ unset($downtimeObj['SERVICE_WITH_ENDPOINTS']);
+ unset($downtimeObj['SINGLE_TIMEZONE']);
+ }
+
+ return $downtimeObj;
+}
diff --git a/htdocs/web_portal/controllers/downtime/edit_downtime.php b/htdocs/web_portal/controllers/downtime/edit_downtime.php
index 9bf244428..3f74cb16f 100644
--- a/htdocs/web_portal/controllers/downtime/edit_downtime.php
+++ b/htdocs/web_portal/controllers/downtime/edit_downtime.php
@@ -21,6 +21,7 @@
require_once __DIR__ . '/../../../../lib/Gocdb_Services/Factory.php';
require_once __DIR__ . '/../../../../htdocs/web_portal/components/Get_User_Principle.php';
require_once __DIR__ . '/../utils.php';
+require_once __DIR__ . '/downtime_utils.php';
/**
* Controller for an edit downtime request
@@ -88,11 +89,18 @@ function submit(\User $user = null) {
if($confirmed == true){
//Downtime is confirmed, submit it
$downtimeInfo = json_decode($_POST['newValues'], TRUE);
-
+ $params = [];
$serv = \Factory::getDowntimeService();
$dt = $serv->getDowntime($downtimeInfo['DOWNTIME']['EXISTINGID']);
- unset($downtimeInfo['DOWNTIME']['EXISTINGID']);
- unset($downtimeInfo['isEdit']);
+ $downtimeInfo = unsetVariables($downtimeInfo, 'edit');
+
+ foreach ($downtimeInfo['SITE_LEVEL_DETAILS'] as $siteIDs) {
+ $downtimeInfo['Impacted_Services'] = $siteIDs['services'];
+ $downtimeInfo['Impacted_Endpoints'] = $siteIDs['endpoints'];
+ }
+
+ unset($downtimeInfo['SITE_LEVEL_DETAILS']);
+
$params['dt'] = $serv->editDowntime($dt, $downtimeInfo, $user);
show_view("downtime/edited_downtime.php", $params);
@@ -101,43 +109,30 @@ function submit(\User $user = null) {
$downtimeInfo = getDtDataFromWeb();
//Need to sort the impacted_ids into impacted services and impacted endpoints
- $impactedids = $downtimeInfo['IMPACTED_IDS'];
-
- $services=array();
- $endpoints=array();
-
- //For each impacted id sort between endpoints and services using the prepended letter
- foreach($impactedids as $id){
- if (strpos($id, 's') !== FALSE){
- //This is a service id
- $services[] = str_replace('s', '', $id); //trim off the identifying char before storing in array
- }else{
- //This is an endpoint id
- $endpoints[] = str_replace('e', '', $id); //trim off the identifying char before storing in array
- }
- }
-
- unset($downtimeInfo['IMPACTED_IDS']); //Delete the unsorted Ids from the downtime info
-
- $downtimeInfo['Impacted_Endpoints'] = $endpoints;
+ list(
+ $siteLevelDetails,
+ $serviceWithEndpoints
+ ) = endpointToServiceMapping($downtimeInfo['IMPACTED_IDS']);
+ // Delete the unsorted IDs from the downtime info
+ unset($downtimeInfo['IMPACTED_IDS']);
- $serv = \Factory::getServiceService();
-
- /** For endpoint put into downtime we want the parent service also. If a user has selected
- * endpoints but not the parent service here we will add the service to maintain the link beteween
- * a downtime having both the service and the endpoint.
- */
- foreach($downtimeInfo['Impacted_Endpoints'] as $endpointIds){
- $endpoint = $serv->getEndpoint($endpointIds);
- $services[] = $endpoint->getService()->getId();
+ if (!count($siteLevelDetails) > 1) {
+ $downtimeInfo['SINGLE_TIMEZONE'] = true;
}
- //Remove any duplicate service ids and store the array of ids
- $services = array_unique($services);
-
- //Assign the impacted services and endpoints to their own arrays for us by the addDowntime method
- $downtimeInfo['Impacted_Services'] = $services;
+ list(
+ $siteLevelDetails,
+ $serviceWithEndpoints
+ ) = addParentServiceForEndpoints(
+ $serviceWithEndpoints,
+ $siteLevelDetails,
+ false,
+ $downtimeInfo['DOWNTIME']
+ );
+
+ $downtimeInfo['SITE_LEVEL_DETAILS'] = $siteLevelDetails;
+ $downtimeInfo['SERVICE_WITH_ENDPOINTS'] = $serviceWithEndpoints;
//Pass the edit variable so the confirm_add view works as the confirm edit view.
$downtimeInfo['isEdit'] = true;
show_view("downtime/confirm_add_downtime.php", $downtimeInfo);
diff --git a/htdocs/web_portal/controllers/downtime/view_endpoint_tree.php b/htdocs/web_portal/controllers/downtime/view_endpoint_tree.php
index eb9f81946..c8451d787 100644
--- a/htdocs/web_portal/controllers/downtime/view_endpoint_tree.php
+++ b/htdocs/web_portal/controllers/downtime/view_endpoint_tree.php
@@ -19,19 +19,30 @@
* limitations under the License.
*
/*====================================================== */
+use Doctrine\Common\Collections\ArrayCollection;
+use Exception;
+
function getServiceandEndpointList() {
require_once __DIR__ . '/../utils.php';
require_once __DIR__ . '/../../../web_portal/components/Get_User_Principle.php';
+ $params = [];
$dn = Get_User_Principle();
$user = \Factory::getUserService()->getUserByPrinciple($dn);
$params['portalIsReadOnly'] = portalIsReadOnlyAndUserIsNotAdmin($user);
+ $siteIDs = $_REQUEST['site_id'];
- if (!isset($_REQUEST['site_id']) || !is_numeric($_REQUEST['site_id']) ){
- throw new Exception("An id must be specified");
+ if (empty($siteIDs)) {
+ throw new Exception("Please select at least one site.");
}
- $site = \Factory::getSiteService()->getSite($_REQUEST['site_id']);
- $services = $site->getServices();
+
+ $services = new ArrayCollection();
+
+ foreach ($siteIDs as $value) {
+ $site = \Factory::getSiteService()->getSite($value);
+ $services[$value] = $site->getServices();
+ }
+
$params['services'] = $services;
show_view("downtime/view_nested_endpoints_list.php", $params, null, true);
}
@@ -41,18 +52,26 @@ function editDowntimePopulateEndpointTree() {
require_once __DIR__ . '/../utils.php';
require_once __DIR__ . '/../../../web_portal/components/Get_User_Principle.php';
+ $params = [];
$dn = Get_User_Principle();
$user = \Factory::getUserService()->getUserByPrinciple($dn);
$params['portalIsReadOnly'] = portalIsReadOnlyAndUserIsNotAdmin($user);
+ $siteIDs = $_REQUEST['site_id'];
- if (!isset($_REQUEST['site_id']) || !is_numeric($_REQUEST['site_id']) ){
- throw new Exception("A site id must be specified");
+ if (empty($_REQUEST['site_id'])) {
+ throw new Exception("Please select at least one site.");
}
if (!isset($_REQUEST['dt_id']) || !is_numeric($_REQUEST['dt_id']) ){
throw new Exception("A downtime id must be specified");
}
- $site = \Factory::getSiteService()->getSite($_REQUEST['site_id']);
- $services = $site->getServices();
+
+ $services = new ArrayCollection();
+
+ foreach ($siteIDs as $value) {
+ $site = \Factory::getSiteService()->getSite($value);
+ $services[$value] = $site->getServices();
+ }
+
$params['services'] = $services;
$downtime = \Factory::getDowntimeService()->getDowntime($_REQUEST['dt_id']);
diff --git a/htdocs/web_portal/views/downtime/add_downtime.php b/htdocs/web_portal/views/downtime/add_downtime.php
index 35508c0d2..6435dd6ec 100644
--- a/htdocs/web_portal/views/downtime/add_downtime.php
+++ b/htdocs/web_portal/views/downtime/add_downtime.php
@@ -67,7 +67,13 @@
-
+
@@ -147,10 +153,15 @@
$size = sizeof($sites) + 2;
}
?>
-
';
+ ?>
+
- Severity:
- Description:
@@ -38,30 +53,38 @@
//echo date_format($timestamp, 'l jS \of F Y \a\t\: h:i A');
xecho($params['DOWNTIME']['END_TIMESTAMP']);
?>
- 1)){
- echo "- Affecting Services:";
- }else{
- echo "
- Affecting Service:";
- }
- ?>
-
+
+ $siteDetails) : ?>
getService($id);
- $safeHostName = xssafe($service->getHostname());
- echo "- " . $safeHostName . "
";
- }
+ $siteName = $params['SITE_LEVEL_DETAILS'][$siteID]['siteName'];
+
+ echo '- Site Name: ';
+ echo $siteName;
+ echo '
';
?>
-
-
- 1)){
- echo "- Affecting Endpoints:";
- }else{
- echo "
- Affecting Endpoint:";
- }
- ?>
+
+
+ -
+ Affecting Service and Endpoint(s):
+
+ $data) : ?>
+ getService($serviceID);
+ $safeHostName = xssafe($service->getHostname());
+ ?>
+
+
+ -
+ getServiceType()->getName() .
+ ') '
+ );
+ echo $safeHostName;
+ ?>
-
+
+
+
+
+
+
diff --git a/htdocs/web_portal/views/downtime/downtime_edit_view_nested_endpoints_list.php b/htdocs/web_portal/views/downtime/downtime_edit_view_nested_endpoints_list.php
index 5be329d0e..2727fbbd6 100644
--- a/htdocs/web_portal/views/downtime/downtime_edit_view_nested_endpoints_list.php
+++ b/htdocs/web_portal/views/downtime/downtime_edit_view_nested_endpoints_list.php
@@ -26,7 +26,8 @@ class="form-control" onclick=""
style="width:99%; margin-left:1%"
onChange="selectServicesEndpoint()" multiple>
$siteServiceList) {
+ foreach ($siteServiceList as $service) {
$count=0;
// Set the html 'SELECTED' attribute on the ");
@@ -52,10 +56,14 @@ class="form-control" onclick=""
$name = xssafe($endpoint->getName());
}
//Option styling doesn't work well cross browser so just use 4 spaces to indent the branch
- echo "";
+ echo "";
$count++;
}
}
+}
?>
diff --git a/htdocs/web_portal/views/downtime/edit_downtime.php b/htdocs/web_portal/views/downtime/edit_downtime.php
index 0f1fcd761..f6319caeb 100644
--- a/htdocs/web_portal/views/downtime/edit_downtime.php
+++ b/htdocs/web_portal/views/downtime/edit_downtime.php
@@ -154,10 +154,15 @@ class="glyphicon glyphicon-time">
$size = sizeof($sites) + 2;
}
?>
-
-
+
Select Affected Services+Endpoints (Ctrl+click to select)
$siteServiceList) {
+ foreach ($siteServiceList as $service) {
$count=0;
- echo "";
+
+ echo "";
+
foreach($service->getEndpointLocations() as $endpoint){
if($endpoint->getName() == ''){
$name = xssafe('myEndpoint');
@@ -17,10 +25,13 @@
$name = xssafe($endpoint->getName());
}
//Option styling doesn't work well cross browser so just use 4 spaces to indent the branch
- echo "";
+ echo "";
$count++;
}
}
+}
?>