Skip to content
77 changes: 41 additions & 36 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,54 +72,58 @@ 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.
*/
$params = [];
$downtimeInfo = json_decode($_POST['newValues'], TRUE);
$serv = \Factory::getDowntimeService();
$downtimeInfo = unsetVariables($downtimeInfo, 'add');

foreach (
$downtimeInfo['SERVICE_WITH_ENDPOINTS'] as $siteID => $serviceIDs
) {
$serviceIDList = [];
$endpointIDList = [];

foreach ($serviceIDs as $serviceID => $endpointsInfo) {
$serviceIDList[] = $serviceID;
$endpointIDList = array_merge(
$endpointIDList,
$endpointsInfo['endpointIDs']
);
}

$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'];
$downtimeInfo['Impacted_Services'] = $serviceIDList;
$downtimeInfo['Impacted_Endpoints'] = $endpointIDList;

$services=array();
$endpoints=array();
$siteDetails = \Factory::getSiteService()->getSite($siteID);
$siteName = $siteDetails->getShortName();

//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
}
$params['submittedDowntimes'][$siteName] =
$serv->addDowntime($downtimeInfo, $user);
}

unset($downtimeInfo['IMPACTED_IDS']); //Delete the unsorted Ids from the downtime info

$downtimeInfo['Impacted_Endpoints'] = $endpoints;
show_view("downtime/added_downtime.php", $params);
}else{
//Show user confirmation screen with their input
$downtimeInfo = getDtDataFromWeb();

$downtimeInfo['SERVICE_WITH_ENDPOINTS'] = endpointToServiceMapping(
$downtimeInfo['IMPACTED_IDS']
);

$serv = \Factory::getServiceService();
/**
* Delete the `IMPACTED_IDS` from the `downtimeInfo` as we
* extracted the details we need in `endpointToServiceMapping`.
*/
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($downtimeInfo['SERVICE_WITH_ENDPOINTS']) === 1) {
$downtimeInfo['SELECTED_SINGLE_SITE'] = 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;

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

/*_____________________________________________________________________________
*=============================================================================
* File: downtime_utils.php
* Description: Helper functions which can be re-used while adding
* or editing a downtime.
*
* License information
*
* Copyright 2023 STFC
* 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';

/**
* Sorts the impacted IDs into impacted services and impacted endpoints.
*
* @param array $impactedIDs An array of `impactedIDs` which user has selected.
*
* @return array `serviceWithEndpoints` An array with
* 'SiteID->serviceID->EndpointID(s)' details.
*/
function endpointToServiceMapping($impactedIDs)
{
$serviceWithEndpoints = [];

/**
* For each impacted ID, sort between endpoints and services
* using the prepended letter.
*/
foreach ($impactedIDs as $impactedID) {
$indexPosition = 0;

list($siteID, $serviceID, $idType) = explode(':', $impactedID);
/**
* `idType` => It will have either `s` followed by service ID or
* `e` followed by endpoint ID.
*/
$trimmedID = str_replace(['s', 'e'], '', $idType);

if (strpos($idType, 's') === $indexPosition) {
continue;
}

// Using '+' to ensure we have an integer value after type coercion.
$serviceWithEndpoints[$siteID][$serviceID]['endpointIDs'][] =
+$trimmedID;
}

return $serviceWithEndpoints;
}

/**
* 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 == "edit") {
unset($downtimeObj['DOWNTIME']['EXISTINGID']);
unset($downtimeObj['isEdit']);
}

unset($downtimeObj['SELECTED_SINGLE_SITE']);

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,31 @@ 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['SERVICE_WITH_ENDPOINTS'] as $serviceIDs
) {
$serviceIDList = [];
$endpointIDList = [];

foreach ($serviceIDs as $serviceID => $endpointsInfo) {
$serviceIDList[] = $serviceID;
$endpointIDList = array_merge(
$endpointIDList,
$endpointsInfo['endpointIDs']
);
}

$downtimeInfo['Impacted_Services'] = $serviceIDList;
$downtimeInfo['Impacted_Endpoints'] = $endpointIDList;
}

unset($downtimeInfo['SERVICE_WITH_ENDPOINTS']);

$params['dt'] = $serv->editDowntime($dt, $downtimeInfo, $user);

show_view("downtime/edited_downtime.php", $params);
Expand All @@ -101,43 +122,17 @@ 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['SERVICE_WITH_ENDPOINTS'] = 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($downtimeInfo['SERVICE_WITH_ENDPOINTS']) === 1) {
$downtimeInfo['SELECTED_SINGLE_SITE'] = 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;
//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
44 changes: 34 additions & 10 deletions htdocs/web_portal/controllers/downtime/view_endpoint_tree.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,34 @@
* 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();
$params['services'] = $services;

$siteIdWithServices = new ArrayCollection();

foreach ($siteIDs as $siteID) {
// Using '+' to ensure we have integer value after type coercion.
$siteID = +$siteID;
$site = \Factory::getSiteService()->getSite($siteID);
$siteIdWithServices[$siteID] = $site->getServices();
}

$params['siteIdWithServices'] = $siteIdWithServices;

show_view("downtime/view_nested_endpoints_list.php", $params, null, true);
}

Expand All @@ -41,19 +55,29 @@ 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();
$params['services'] = $services;

$siteIdWithServices = new ArrayCollection();

foreach ($siteIDs as $siteID) {
// Using '+' to ensure we have integer value after type coercion.
$siteID = +$siteID;
$site = \Factory::getSiteService()->getSite($siteID);
$siteIdWithServices[$siteID] = $site->getServices();
}

$params['siteIdWithServices'] = $siteIdWithServices;

$downtime = \Factory::getDowntimeService()->getDowntime($_REQUEST['dt_id']);
$params['downtime'] = $downtime;
Expand Down
Loading