requestTime = date('Ymd',time()); if (!isset($data)) { $this->userID = WSConfigClass::getAnonymousUserName(); return array('success' => true); } if(is_object($data)){ $vars = get_object_vars($data); $this->isSoap = true; } else { $vars = $data; } if (isset($vars['userID'])){ $this->userID = $vars['userID']; IHMConfigClass::setUserName($this->userID); } else { $this->userID = WSConfigClass::getAnonymousUserName(); } $this->sessionID = $this->userID; if (isset($vars['password'])) $this->userPWD = $vars['password']; else $this->userPWD = WSConfigClass::getAnonymousUserPwd(); return array('success' => true, 'vars' => $vars); } private function initUserMgr($setPathOnly = false) { $wsUserMgr = new WSUserMgr(); $wsUserMgr->initWS($this->userID, $this->userPWD, $this->sessionID, $setPathOnly, $this->isSoap); $this->IPclient = $wsUserMgr->getIPClient(); return array('success' => true); } private function throwError($errorType, $msg) { if ($this->isSoap) throw new SoapFault($errorType, $msg); else exit(json_encode(array("error" => $msg))); } private function isGetPlotRequest($name){ return (substr($name,0,7) == 'getplot'); } private function xsl2vot($inputName, $outputName) { // Load Time table $xml = new DomDocument("1.0"); if (!@$xml->load($inputName)) $this->throwError("wokrspaceError", "Cannot load time table $inputName for ".$this->userID); // Load XSL file $xsl = new DomDocument("1.0"); if (!@$xsl->load(WSConfigClass::getXslDir()."xml2vot.xsl")) $this->throwError("systemError", "Cannot load xsl file"); // Import XSL and write output file in vot format $xslt = new XSLTProcessor(); $xslt->importStylesheet($xsl); $vot = new DomDocument("1.0"); if (!@$vot->loadXML($xslt->transformToXML($xml))) $this->throwError("systemError", "Cannot convert time table to VOtable"); if (!$vot->save(WSConfigClass::getWsResultDir().$outputName)) $this->throwError("systemError", "Cannot save time table to result dir"); } private function getDatasetInfo($id) { $dataSetXml = WSConfigClass::getDataSetInfoDir().$id.".xml"; if (!file_exists($dataSetXml)) $this->throwError("systemError", "Cannot find info file for dataset ".$id); $dataSetDom = new DomDocument("1.0"); if (!@$dataSetDom->load($dataSetXml)) $this->throwError("systemError", "Cannot load info file for dataset ".$id); return $dataSetDom; } /* * get user TimeTables list; Shared for anonymous user ('impex') */ private function getTimeTablesCatalogsList($object) { $this->initUserMgr(); $dom = new DOMDocument("1.0"); if ($this->userID == WSConfigClass::getAnonymousUserName()) { $sharedObjMgr = new SharedObjectsMgr(); if (!@$dom->load($sharedObjMgr->getTreeFilePath())) $this->throwError("workspaceError", "Workspace Error : Cannot load Shared TimeTable list"); $tagName = $object == "timetables" ? "timeTableList" : "catalogList"; } else { if (!@$dom->load(USERWSDIR.'Tt.xml')) $this->throwError("workspaceError", "Workspace Error : Cannot load TimeTable list for ".$this->userID); $tagName = $object == "timetables" ? "timetabList" : "catalogList"; } $timetabNode = $dom->getElementsByTagName($tagName); if ($timetabNode->length < 1){ $this->throwError("workspaceWarning", "Workspace Warning : No $object"); } $outDOM = new DOMDocument("1.0"); $outDOM->formatOutput = TRUE; $outDOM->preserveWhiteSpace = FALSE; $newNode = $outDOM->importNode($timetabNode->item(0),TRUE); $outDOM->appendChild($newNode); $ttListResult = $object.'_'.$this->userID.'_'.$this->requestTime.'.xml'; if (!$outDOM->save(WSConfigClass::getWsResultDir().$ttListResult)) $this->throwError("workspaceError", "Workspace Error : problem while saving $object list file"); return WSConfigClass::getUrl().$ttListResult; } /* * Get corresponding orbit parameter ID */ private function getOrbitParameter($orbitRequest) { if (!file_exists(WSConfigClass::getOrbitsXml())) $this->throwError('systemError', "No AMDA system orbits file"); $orbitsXml = new DomDocument(); if (!@$orbitsXml->load(WSConfigClass::getOrbitsXml())) $this->throwError('systemError', "Cannot load AMDA system orbits file"); $spacecraft = strtolower($orbitRequest['spacecraft']); $spacecraft = str_replace('-', '', $spacecraft); $xpath = new DOMXpath($orbitsXml); $path = '//orbites[@mission="'.$spacecraft.'" and @coordinate_system="'.$orbitRequest['coordinateSystem'].'" and @units="'.$orbitRequest['units'].'" ] '; $orbits = $xpath->query($path); foreach ($orbits as $orbit) { $datasetID = strtr($orbit->getAttribute('dataset'),"_","-"); $dataSetDom = $this->getDatasetInfo($datasetID); $paramStart = strtotime($dataSetDom->getElementsByTagName('global_start')->item(0)->nodeValue); $paramStop = strtotime($dataSetDom->getElementsByTagName('global_stop')->item(0)->nodeValue); if(($paramStart <= strtotime($orbitRequest['startTime']) && (strtotime($orbitRequest['stopTime'])) <= $paramStop)) { return array('success' => true, 'parameterID' => $orbit->getAttribute('xml:id') ); } } $this->throwError('systemError', "Cannot find orbit data for ".$orbitRequest['spacecraft']." for ".$orbitRequest['startTime']."-".$orbitRequest['stopTime']." in ".$orbitRequest['units']." ".$orbitRequest['coordinateSystem']."($paramStart - $paramStop)"); } private function doDownloadRequest($interval, $paramList, $formatInfo, $file_info) { if (!isset($this->paramLoader)) $this->paramLoader = new IHMUserParamManagerClass(); //Build parameter list $params = array(); //TODO template arguments to implement ? foreach ($paramList['params'] as $paramId) { $param = new stdClass; if (preg_match("#^ws_#",$paramId)) { $res = $this->paramLoader->getDerivedParameterNameFromId($paramId); if (!$res["success"]) { $this->throwError("serverError", "Not available derived parameter $paramId"); } $param->paramid = "ws_".$res['name']; } else if (preg_match("#^wsd_#",$paramId)) { $res = $this->paramLoader->getUploadedParameterNameFromId($paramId); if (!$res["success"]){ $this->throwError("serverError", "Not available parameter $paramId"); } $param->paramid = "wsd_".$res['name']; } else { $param->paramid = $paramId; } $params[] = $param; } $ref_sampling_param = isset($interval['ref_sampling_param']) ? $interval['ref_sampling_param'] : NULL; $obj = (object)array( "sampling" => $interval['sampling'], "startDate" => $interval['startTime'], "stopDate" => $interval['stopTime'], "list" => $params, "fileformat" => $formatInfo['format'], "timeformat" => $formatInfo['timeFormat'], "compression" => $formatInfo['gzip'], "ref_sampling_param" => $ref_sampling_param, "file_info" => $file_info, ); if (!isset($this->requestManager)) $this->requestManager = new RequestManagerClass(); try { $downloadResult = $this->requestManager->runWSRequest($this->userID, $this->IPclient, FunctionTypeEnumClass::PARAMS, $this->service, $obj); } catch (Exception $e) { $this->throwError("executionError", "Exception detected : ".$e->getMessage()); } if (!$downloadResult['success']) { $this->throwError("serverError", $downloadResult['message']); } if($downloadResult['status'] == 'in_progress') { return ['success' => true, 'status' => 'in progress', 'id' => $downloadResult['id']]; } elseif ($downloadResult['status'] == 'done') { $this->deleteProcess($downloadResult['id']); return array('success' => true, 'status' => 'done', 'dataFileURLs' => WSConfigClass::getUrl().$downloadResult['result'], 'exectime' => $downloadResult['exectime']); } else { return ['success' => false, 'message' => 'Unknown status ' . $downloadResult['status']]; } } /* * delete process after execution : * delete temporary files/folders ( JOBS/process_xxxx, RES/DDxxx ); * delete job node in processManager.xml */ private function deleteProcess($id) { $obj = (object)array('id' => $id); if (!isset($this->requestManager)) $this->requestManager = new RequestManagerClass(); try { $downloadResult = $this->requestManager->runWSRequest($this->userID, $this->IPclient, FunctionTypeEnumClass::PROCESSDELETE, null, $obj); } catch (Exception $e) { $this->throwError("deleteProcessError", $e->getMessage()); } } private function excludePrivateNodes($locParamSrc, $locParamDst) { $locParamSrcDom = new DomDocument("1.0"); $locParamSrcDom->preserveWhiteSpace = FALSE; /// Important !!! otherwise removeChild() leaves empty text nodes if (!@$locParamSrcDom->load($locParamSrc)) $this->throwError("getObsDataTree", "Cannot load Amda Local DataBase Parameters description file".$this->userID); $xp = new domxpath($locParamSrcDom); $restricted = $xp->query("//*[@group]"); foreach ($restricted as $node) { $parentNode = $node->parentNode; $parentNode->removeChild($node); if (!$parentNode->hasChildNodes()) { if ($parentNode->parentNode){ $parentParentNode = $parentNode->parentNode; $parentParentNode->removeChild($parentNode); } } } if (!$locParamSrcDom->save(WSConfigClass::getWsResultDir().$locParamDst)) $this->throwError('workspaceError', 'Cannot save Amda Local DataBase Parameters description file'.$this->userID); } private function checkInputTime($startTime, $stopTime) { if ($stopTime <= $startTime ) $this->throwError("requestError", "Requested time interval should be greater than 0"); } /************************** WEB SERVICES **************************************/ /* * generate AUTH token for access to REST services */ public function getNewToken() { // generate token from timeStamp and some salt $newToken = md5(1321 * (int)( time() / WSConfigClass::$timeLimitQuery)); return array('success' => true, 'token' => $newToken); } /* * public data only : anonymous user (impex) */ public function getObsDataTree() { $res = $this->init(); $this->initUserMgr(); $locParamSrc = USERWSDIR.'LocalParams.xml'; $locParamDst = substr(strtolower(__FUNCTION__),3).'_'.$this->userID.'_'.$this->requestTime.'_AmdaLocalDataBaseParameters.xml'; // if (!copy($locParamSrc,WSConfigClass::getWsResultDir().$locParamDst)) // $this->throwError('workspaceError', 'No Amda Local DataBase Parameters description file'); $this->excludePrivateNodes($locParamSrc,$locParamDst); return array('success' => true,'WorkSpace' => array("LocalDataBaseParameters" => WSConfigClass::getUrl().$locParamDst)); } /* * get Parameter List for given user */ public function getParameterList($data) { $res = $this->init($data); $this->initUserMgr(); $vars = $res['vars']; $locParamSrc = USERWSDIR.'LocalParams.xml'; $wsParamSrc = USERWSDIR.'WsParams.xml'; $locParamDst = substr(strtolower(__FUNCTION__),3).'_'.$this->userID.'_'.$this->requestTime.'_AmdaLocalDataBaseParameters.xml'; $wsParamDst = substr(strtolower(__FUNCTION__),3).'_'.$this->userID.'_'.$this->requestTime.'_UserDefinedParameters.xml'; // if (!copy($locParamSrc, WSConfigClass::getWsResultDir().$locParamDst)) // $this->throwError('workspaceError', 'No Amda Local DataBase Parameters description file for '.$this->userID); $this->excludePrivateNodes($locParamSrc,$locParamDst); if (($this->userID == WSConfigClass::getAnonymousUserName()) || !copy($wsParamSrc, WSConfigClass::getWsResultDir().$wsParamDst)) return array('success' => true,'ParameterList' => array("LocalDataBaseParameters" => WSConfigClass::getUrl().$locParamDst)); return array('success' => true,'ParameterList' => array("UserDefinedParameters" => WSConfigClass::getUrl().$wsParamDst, "LocalDataBaseParameters" => WSConfigClass::getUrl().$locParamDst)); } /* * getParameter */ public function getParameter($data) { $res = $this->init($data); if (!$res['success']){ $this->throwError("requestError", "Cannot parse request"); } $this->initUserMgr(); $vars = $res['vars']; if (empty($vars["startTime"])) { $this->throwError("requestError", "Missing startTime definition"); } if (empty($vars["stopTime"])) { $this->throwError("requestError", "Missing stopTime definition"); } if (is_numeric($vars["startTime"])) { $this->checkInputTime($vars["startTime"],$vars["stopTime"]); $vars["startTime"] = date("Y-m-d\TH:i:s", $vars["startTime"]); $vars["stopTime"] = date("Y-m-d\TH:i:s", $vars["stopTime"]); } else { $this->checkInputTime(strtotime($vars["startTime"]),strtotime($vars["stopTime"])); } if (empty($vars["timeFormat"])) { $timeFormat = "ISO8601"; } else { $timeFormat = $vars["timeFormat"]; } $sampling = !empty($vars["sampling"]) ? $vars["sampling"] : NULL; $ref_sampling_param = NULL; $file_info = ""; if (empty($vars["parameterID"])) { $this->throwError("requestError", "Missing parameterID definition"); } $paramId = array(); if (strpos($vars["parameterID"], ',')) { $paramId = explode(',', $vars["parameterID"]); if (!isset($sampling)) { $ref_sampling_param = trim($paramId[0]); } foreach ($paramId as &$id) { $id = trim($id); if (!empty($file_info)) { $file_info .= "-"; } $file_info .= $id; } } else { array_push($paramId, $vars["parameterID"]); $file_info = $vars["parameterID"]; } if (empty($vars["gzip"])) $gzip = 0; else $gzip = ($vars["gzip"] == 1); $outputFormat = !empty($vars["outputFormat"]) ? $vars["outputFormat"] : 'ASCII'; $this->service = strtolower(__FUNCTION__); $res = $this->doDownloadRequest( array("startTime" => $vars["startTime"], "stopTime" => $vars["stopTime"], "sampling" => $sampling, "ref_sampling_param" => $ref_sampling_param), array("params" => $paramId), array("format" => $outputFormat, "timeFormat"=> $timeFormat, "gzip"=>$gzip), $file_info); if ($res['success']) return $res; $this->throwError("serverError", $res['message']); } /* * get user Catalogs list; Shared for anonymous user (impex) */ public function getCatalogsList($data) { $this->init($data); return array('success' => true, 'CatalogsList' => $this->getTimeTablesCatalogsList('catalogs')); } /* * get user TimeTables list; Shared for anonymous user (impex) */ public function getTimeTablesList($data) { $this->init($data); return array('success' => true, 'TimeTablesList' => $this->getTimeTablesCatalogsList('timetables')); } public function isAlive() { return true; } /* * get Dataset */ public function getDataset($data) { $res = $this->init($data); if (!$res['success']){ $this->throwError("requestError", "Cannot parse request"); } $this->initUserMgr(); $vars = $res['vars']; if (is_numeric($vars["startTime"])) { $this->checkInputTime($vars["startTime"],$vars["stopTime"]); $vars["startTime"] = date("Y-m-d\TH:i:s", $vars["startTime"]); $vars["stopTime"] = date("Y-m-d\TH:i:s", $vars["stopTime"]); } else { $this->checkInputTime(strtotime($vars["startTime"]),strtotime($vars["stopTime"])); } if (empty($vars["timeFormat"])) { $timeFormat = "ISO8601"; } else { $timeFormat = $vars["timeFormat"]; } if (empty($vars['datasetID'])) { $this->throwError("requestError", "Missing datasetID definition"); } $datasetId = $vars['datasetID']; $dataSetDom = $this->getDatasetInfo($datasetId); $params = $dataSetDom->getElementsByTagName("parameter"); if ($params->length == 0) $this->throwError("systemError", "Cannot find parameter list for dataset ".$datasetId); $paramId = array(); foreach ($params as $p) $paramId[] = $p->nodeValue; if (empty($vars["sampling"])) { $sampling = NULL; $ref_sampling_param = $paramId[0]; } else { $sampling = $vars["sampling"]; $ref_sampling_param = NULL; } if (empty($vars["gzip"])) $gzip = 0; else $gzip = ($vars["gzip"] == 1); $outputFormat = !empty($vars["outputFormat"]) ? $vars["outputFormat"] : 'ASCII'; $this->service = strtolower(__FUNCTION__); $res = $this->doDownloadRequest( array("startTime" => $vars["startTime"], "stopTime" => $vars["stopTime"], "sampling" => $sampling, "ref_sampling_param" => $ref_sampling_param), array("params" => $paramId), array("format" => $outputFormat, "timeFormat"=> $timeFormat, "gzip"=>$gzip), $datasetId); if ($res['success']) return $res; $this->throwError("serverError", $res['message']); } /* * get status for jobs in batch */ public function getStatus($data) { $result = $this->init($data); $id = $result['vars']['id']; if (!isset($this->requestManager)) $this->requestManager = new RequestManagerClass(); try { $res = $this->requestManager->runWSRequest('nobody', 'nobody', FunctionTypeEnumClass::PROCESSGETINFO, null, $id); } catch (Exception $e) { $this->throwError("executionError", "Exception detected : ".$e->getMessage()); } if (!$res['success']) { $this->throwError("processError","Cannot retrieve process $id info"); } if ($res['status'] == 'in_progress') { return array('success' => true, 'status' => 'in progress'); } if ($res['error']) { $this->throwError("processError","Process $id error code"); } $this->deleteProcess($res['id']); $resultTag = $this->isGetPlotRequest($res['result']) ? 'plotURL' : 'dataFileURLs'; return array('success' => true, 'status' => $res['status'], $resultTag => WSConfigClass::getUrl().$res['result']); } /* * TODO Can be done by TTCONVERT function of AMDA_Kernel - more hard !!! * TODO Think about this if merge/union will be also done by AMDA_Kernel * * get Time Table : shared for anonymous user (impex) ; user' for user */ public function getTimeTable($data) { $res = $this->init($data); if (!$res['success']){ $this->throwError("requestError", "Cannot parse request"); } $ttID = $res['vars']['ttID']; $format = !empty($res['vars']['outputFormat']) ? $res['vars']['outputFormat'] : 'VOTable'; return $this->getTimeTableCatalog('timeTable', $ttID, $format); } /* * TODO Can be done by TTCONVERT function of AMDA_Kernel - more hard !!! * TODO Think about this if merge/union will be also done by AMDA_Kernel * * get Time Table : shared for anonymous user (impex) ; user' for user */ public function getCatalog($data) { $res = $this->init($data); if (!$res['success']){ $this->throwError("requestError", "Cannot parse request"); } $catID = $res['vars']['catID']; $format = !empty($res['vars']['outputFormat']) ? $res['vars']['outputFormat'] : 'VOTable'; return $this->getTimeTableCatalog('catalog', $catID, $format); } /* * TODO Can be done by TTCONVERT function of AMDA_Kernel - more hard !!! * TODO Think about this if merge/union will be also done by AMDA_Kernel * * get Time Table : shared for anonymous user (impex) ; user' for user */ private function getTimeTableCatalog($type, $id, $format) { $this->initUserMgr(); if ($this->userID == WSConfigClass::getAnonymousUserName()) { $sharedObjMgr = new SharedObjectsMgr(); $objSrc = $sharedObjMgr->getDataFilePath($type, $id); } else $objSrc = USERTTDIR.$id.'.xml'; if (!file_exists($objSrc)) { $this->throwError("workspaceError", "No such object ".$id." for user ".$this->userID); } $prefix = ($type == 'catalog') ? 'catalog' : 'timetable'; $extension = (strtolower($format) == 'votable') ? "xml" : "txt"; $objDst = $prefix."_".$this->userID."_".$this->requestTime."_$id.$extension"; if (!isset($this->requestManager)) $this->requestManager = new RequestManagerClass(); try { $obj = array( 'inputFile' => $objSrc, 'outputFormat' => $format, 'outputFileName' => $objDst, ); $res = $this->requestManager->runWSRequest($this->userID, $this->IPclient, FunctionTypeEnumClass::TTCONVERT, $this->service, $obj); } catch (Exception $e) { return array('success' => false, 'message' => 'Exception detected : '.$e->getMessage()); } $resKey = ($type == 'catalog') ? 'catFileURL' : 'ttFileURL'; return array('success' => true, $resKey => WSConfigClass::getUrl().$objDst); } /* * get Orbits */ public function getOrbites($data) { $res = $this->init($data); if (!$res['success']){ $this->throwError("requestError", "Cannot parse request"); } $this->initUserMgr(); $vars = $res['vars']; if (is_numeric($vars["startTime"])) { $this->checkInputTime($vars["startTime"],$vars["stopTime"]); $vars["startTime"] = date("Y-m-d\TH:i:s", $vars["startTime"]); $vars["stopTime"] = date("Y-m-d\TH:i:s", $vars["stopTime"]); } else { $this->checkInputTime(strtotime($vars["startTime"]),strtotime($vars["stopTime"])); } if (empty($vars["timeFormat"])) { $timeFormat = "ISO8601"; } else { $timeFormat = $vars["timeFormat"]; } if (empty($vars["spacecraft"])) { $this->throwError("requestError", "Missing spacecraft definition"); } $spacecraft = $vars["spacecraft"]; if (empty($vars["coordinateSystem"])) { $this->throwError("requestError", "Missing coordinateSystem definition"); } $coordinateSystem = $vars["coordinateSystem"]; if (empty($vars["units"])) $units = "km"; else $units = $vars["units"]; $orbitRequest = array("startTime" => $vars["startTime"], "stopTime" => $vars["stopTime"], "spacecraft" => $spacecraft, "coordinateSystem" => $coordinateSystem, "units" => $units ); $orbitParam = $this->getOrbitParameter($orbitRequest); $paramId = array(); array_push($paramId, $orbitParam['parameterID']); if (empty($vars["gzip"])) $gzip = 0; else $gzip = ($vars["gzip"] == 1); $sampling = !empty($vars["sampling"]) ? $vars["sampling"] : NULL; $outputFormat = !empty($vars["outputFormat"]) ? $vars["outputFormat"] : 'ASCII'; $this->service = strtolower(__FUNCTION__); $res = $this->doDownloadRequest( array("startTime" => $vars["startTime"], "stopTime" => $vars["stopTime"], "sampling" => $sampling), array("params" => $paramId), array("format" => $outputFormat, "timeFormat"=> $timeFormat, "gzip"=>$gzip), $orbitParam['parameterID']); if ($res['success']) return $res; $this->throwError("serverError",$res['message']); } /* * getPlot : predefined; by mission */ public function getPlot($data) { $res = $this->init($data); if (!$res['success']){ $this->throwError("requestError", "Cannot parse request"); } $this->initUserMgr(); $vars = $res['vars']; $mission = $vars["missionID"]; if (is_numeric($vars["startTime"])) { $this->checkInputTime($vars["startTime"],$vars["stopTime"]); $vars["startTime"] = date("Y-m-d\TH:i:s", $vars["startTime"]); $vars["stopTime"] = date("Y-m-d\TH:i:s", $vars["stopTime"]); } else { $this->checkInputTime(strtotime($vars["startTime"]),strtotime($vars["stopTime"])); } $resultFilePrefix = strtolower(__FUNCTION__)."_".$mission."_".date("YmdHms",strtotime($vars["startTime"]))."_".date("YmdHms",strtotime($vars["stopTime"])); if ($this->userID != WSConfigClass::getAnonymousUserName()) $resultFilePrefix .= "_".$this->userID; $dom = new DomDocument("1.0"); if (!@$dom->load(WSConfigClass::getXslDir()."AmdaPlots.xml")) $this->throwError("systemError", "Cannot load predefined plot definition"); ; $missionTag = $dom->getElementById($mission); $params = $missionTag->getElementsByTagName('param'); $paramsList = array(); foreach ($params as $param) $paramsList[] = $param->getAttribute('name'); $requestObject = (Object) array( "nodeType" => "request", "file-format" => "PNG", "result-file" => $resultFilePrefix, "timesrc" => "Interval", "startDate" => $vars["startTime"], "stopDate" => $vars["stopTime"], "parameters" => array() ); foreach ($paramsList as $paramToPlot) { $paramObject = (Object) array( "paramid" => $paramToPlot ); $requestObject->{"parameters"}[] = $paramObject; } $this->service = strtolower(__FUNCTION__); if (!isset($this->requestManager)) $this->requestManager = new RequestManagerClass(); try { $plotResult = $this->requestManager->runWSRequest($this->userID, $this->IPclient, FunctionTypeEnumClass::PARAMS, $this->service, $requestObject); } catch (Exception $e) { $this->throwError("plotError", "Exeption detected : ".$e->getMessage()); } if (!$plotResult['success']) { $this->throwError("serverError", $plotResult['message']); } if($plotResult['status'] == 'in_progress') { return ['success' => true, 'status' => 'in progress', 'id' => $plotResult['id']]; } elseif ($plotResult['status'] == 'done') { $this->deleteProcess($plotResult['id']); return array('success' => true, 'status' => 'done', 'plotFileURL' => WSConfigClass::getUrl().$plotResult['result']); } else { return ['success' => false, 'message' => 'Unknown status ' . $plotResult['status']]; } } } ?>