Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GT-187] Add feature selecting multiple sites #475

Open
wants to merge 10 commits into
base: dev
Choose a base branch
from
70 changes: 35 additions & 35 deletions htdocs/web_portal/controllers/downtime/add_downtime.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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');
gregcorbett marked this conversation as resolved.
Show resolved Hide resolved
$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);
}
gregcorbett marked this conversation as resolved.
Show resolved Hide resolved

$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;
gregcorbett marked this conversation as resolved.
Show resolved Hide resolved
}

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,
gregcorbett marked this conversation as resolved.
Show resolved Hide resolved
$downtimeInfo['DOWNTIME']
);
gregcorbett marked this conversation as resolved.
Show resolved Hide resolved

$downtimeInfo['SITE_LEVEL_DETAILS'] = $siteLevelDetails;
$downtimeInfo['SERVICE_WITH_ENDPOINTS'] = $serviceWithEndpoints;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is SERVICE_WITH_ENDPOINTS roughly the same as the previous Impacted_Services here? if so, what does SITE_LEVEL_DETAILS add?

Copy link
Contributor Author

@Sae126V Sae126V Sep 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is SERVICE_WITH_ENDPOINTS roughly the same as the previous Impacted_Services here?
No, SERVICE_WITH_ENDPOINTS will have each service with endpoints. Whereas Impacted_Services will have all service INFO.

I have used one object(SERVICE_WITH_ENDPOINTS ) for Viewing and extract the other to submit(Just in case if user goes back to and not submitting).

In a single loop. I constructed two objects one for viewing and the other for submitting purpose.


show_view("downtime/confirm_add_downtime.php", $downtimeInfo);
}
Expand Down
169 changes: 169 additions & 0 deletions htdocs/web_portal/controllers/downtime/downtime_utils.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<?php

/*_____________________________________________________________________________
*=============================================================================
* File: downtime_utils.php
* Author: GOCDB DEV TEAM, STFC.
gregcorbett marked this conversation as resolved.
Show resolved Hide resolved
* Description: Helper functions which can be re-used while adding
* or editing a downtime.
*
* License information
*
* Copyright 2013 STFC
gregcorbett marked this conversation as resolved.
Show resolved Hide resolved
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
/*====================================================== */
require_once __DIR__ . '/../../../../lib/Gocdb_Services/Factory.php';

use DateTime;
use DateTimeZone;

/**
* Sorts the impacted IDs into impacted services and impacted endpoints.
*
* @param array $impactedIDs An array of `impactedIDs` which user has selected.
*
* @return array An array containing
* `$siteLevelDetails` and `serviceWithEndpoints`.
*/
function endpointToServiceMapping($impactedIDs)
{
$siteLevelDetails = [];
$serviceWithEndpoints = [];

/**
* For each impacted ID,
* sort between endpoints and services using the prepended letter.
Sae126V marked this conversation as resolved.
Show resolved Hide resolved
*/
foreach ($impactedIDs as $id) {
list($siteNumber, $parentService, $idType) = explode(':', $id);

$type = strpos($idType, 's') !== false ? 'services' : 'endpoints';
$id = str_replace(['s', 'e'], '', $idType);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add some comments here explaining the desired behaviour?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added


$siteLevelDetails[$siteNumber][$type][] = $id;
$serviceWithEndpoints[$siteNumber][$parentService][$type][] = $id;
}

return [$siteLevelDetails, $serviceWithEndpoints];
}

/**
* If a user has selected endpoints but not the parent service here
* we will add the service to maintain the link between a downtime
* having both the service and the endpoint.
*
* @param array $servWithEndpoints Used for displaying affected service
* with endpoint(s).
* @param array $siteDetails Each site ID will have a `services` that
* stores all affected service ID(s) and an
* `endpoints` that stores all affected
* endpoint ID(s).
* @param bool $hasMultipleTimezones If the user selects multiple sites in
* the web portal along with the option
* "site timezone" it will be true;
* otherwise, it will be false.
* @param mixed $downtimeDetails Downtime information.
*
* @return array An array containing `$siteDetails` and `servWithEndpoints`.
*/
function addParentServiceForEndpoints(
$servWithEndpoints,
$siteDetails,
$hasMultipleTimezones,
$downtimeDetails
) {
foreach ($servWithEndpoints as $siteID => $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;
}
67 changes: 31 additions & 36 deletions htdocs/web_portal/controllers/downtime/edit_downtime.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
Loading