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
62 changes: 28 additions & 34 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,46 @@ 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'];

$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
list($siteLevelDetails, $serviceWithEndpoints) =
endpointToServiceMapping($downtimeInfo['IMPACTED_IDS']);

$downtimeInfo['Impacted_Endpoints'] = $endpoints;
// 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_SITE'] = true;
}

//Remove any duplicate service ids and store the array of ids
$services = array_unique($services);
list($siteLevelDetails, $serviceWithEndpoints) =
addParentServiceForEndpoints(
$serviceWithEndpoints,
$siteLevelDetails
);

//Assign the impacted services and endpoints to their own arrays for us by the addDowntime method
$downtimeInfo['Impacted_Services'] = $services;
$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
120 changes: 120 additions & 0 deletions htdocs/web_portal/controllers/downtime/downtime_utils.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?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) {
/**
* `$siteNumber` => It's about Site ID
* `$parentService` => It's about service ID endpoint belongs too
* `idType` => It's about to differentiate
* the endpoint vs service selection.
*/
list($siteNumber, $parentService, $idType) = explode(':', $id);

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

Choose a reason for hiding this comment

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

I'd go for something like:

Suggested change
foreach ($impactedIDs as $id) {
/**
* `$siteNumber` => It's about Site ID
* `$parentService` => It's about service ID endpoint belongs too
* `idType` => It's about to differentiate
* the endpoint vs service selection.
*/
list($siteNumber, $parentService, $idType) = explode(':', $id);
$type = strpos($idType, 's') !== false ? 'services' : 'endpoints';
foreach ($impactedIDs as $id) {
list($siteId, $parentServiceId, $idType) = explode(':', $id);
// put typical input for $idType here.
$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).
*
* @return array An array containing `$siteDetails` and `servWithEndpoints`.
*/
function addParentServiceForEndpoints(
$servWithEndpoints,
$siteDetails
) {
foreach ($servWithEndpoints as $siteID => $siteData) {
$siteDetails[$siteID]['services'] = [];

$newSite = \Factory::getSiteService()->getSite($siteID);
$siteDetails[$siteID]['siteName'] = $newSite->getShortName();

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];
}

/**
* 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_SITE']);
} else {
unset($downtimeObj['DOWNTIME']['EXISTINGID']);
unset($downtimeObj['isEdit']);
unset($downtimeObj['SERVICE_WITH_ENDPOINTS']);
unset($downtimeObj['SINGLE_SITE']);
}

return $downtimeObj;
}
59 changes: 24 additions & 35 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,24 @@ 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']);

$serv = \Factory::getServiceService();
// Delete the unsorted IDs from the downtime info
unset($downtimeInfo['IMPACTED_IDS']);

/** 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_SITE'] = true;
}

//Remove any duplicate service ids and store the array of ids
$services = array_unique($services);
list($siteLevelDetails, $serviceWithEndpoints) =
addParentServiceForEndpoints(
$serviceWithEndpoints,
$siteLevelDetails
);

//Assign the impacted services and endpoints to their own arrays for us by the addDowntime method
$downtimeInfo['Impacted_Services'] = $services;
$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
35 changes: 27 additions & 8 deletions htdocs/web_portal/controllers/downtime/view_endpoint_tree.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Copy link
Member

Choose a reason for hiding this comment

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

is this change equivalent to the old functionality? what if a non numeric string is passed in via site_id?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would say Not an equivalent. We are now passing an array of Number. So I don't think it would be an issue.

Copy link
Member

Choose a reason for hiding this comment

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

when you loop through the siteIDs later, can you add an is_numeric check?

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);
}
Expand All @@ -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']);
Expand Down
Loading