'WS', 'USERREQDIR' => 'REQ', 'USERDATADIR' => 'DATA', // 'USERWORKINGDIR' =>'RES', 'USERTTDIR' => 'TT', 'USERJOBDIR' => 'JOBS'); class FilesMgr extends AmdaObjectMgr { private $fileName, $fileId, $theFile; public $xp; private $fileMgr = NULL; //used when a file format needs to use a specific manager private $sampling = -100.0, $maxSampling = -100.0; private $ncID = NULL; private $simuContentRootId; function __construct() { parent::__construct('Files.xml'); $this->contentRootId = 'myData-treeRootNode'; $this->contentRootTag = 'fileList'; $this->attributes = array('name' => '', 'start' => '', 'stop' => ''); $this->optionalAttributes = array(); $this->objTagName = 'file'; if (!file_exists($this->xmlName)) { $this->createDom(); $this->xp = new domxpath($this->contentDom); } } /* * Create Content Dom 'Files.xml' if it doesn't exist */ protected function createDom() { $rootElement = $this->contentDom->createElement('ws'); $typeElement = $this->contentDom->createElement($this->contentRootTag); $typeElement->setAttribute('xml:id', $this->contentRootId); $rootElement->appendChild($typeElement); $this->contentDom->appendChild($rootElement); // $typeElement = $this->contentDom->createElement($this->contentRootTag); // $rootElement->appendChild($typeElement); // $this->contentDom->appendChild($rootElement); $this->contentDom->save($this->xmlName); } /* * VOTable format processing done by an instance of VOTableMgr */ protected function getVotFileMgr() { if (!$this->fileMgr) { $this->fileMgr = new VOTableMgr(); $this->fileMgr->load($this->fileName); } return $this->fileMgr; } /* * CDF format processing */ protected function getCdfStartStop() { exec('cdfstartstopfromdata '.$this->fileName, $start_stop); return $start_stop[0]; } protected function getCdfVars() { exec('cdfinfo '.$this->fileName, $results); return $results; } protected function getCdfVarInfo($cdfVarId) { exec('cdfvarinfo '.$this->fileName.' '.$cdfVarId, $results); $tempArr = explode(' ', $results[0]); // data type switch ($tempArr[0]) { case "CDF_FLOAT" : case "CDF_REAL4" : $data_type = 'FLOAT'; break; case "CDF_INT2": case "CDF_UCHAR": case "CDF_UINT1" : $data_type = 'SHORT'; break; case "CDF_UINT2": case "CDF_INT4" : $data_type = 'INTEGER'; break; case "CDF_DOUBLE": case "CDF_REAL8": case "CDF_UINT4": $data_type = 'DOUBLE'; break; default : $data_type = 'FLOAT'; } // data dimensions & number of records $n_recs = $tempArr[2]; if ($tempArr[1] != 0) { $size = $tempArr[3]; //TODO 2D,3D,4D array no processing // if ($tempArr[1] > 1) } else { $size = 1; } return array('type' => $data_type, 'size' => $size, 'n_records' => $n_recs); } protected function getCdfSampling() { copy($this->fileName, "temp.cdf"); exec('cdfsamplingfromdata ', $results); unlink("temp.cdf"); return $results; } /* * CEF format processing */ protected function getCefStartStop() { exec("cefstartstop ".$this->fileName, $start_stop); return $start_stop[0]; } protected function getCefTimeInfo() { $timeinfo = exec("ceftimeinfo ".$this->fileName); return $timeinfo; } protected function getCefVars() { exec('cefinfo '.$this->fileName, $results); return $results; } protected function getCefVarInfo($cdfVarId) { exec('cefvarinfo '.$this->fileName." ".$cdfVarId, $results); $tempArr = explode(' ', $results[0]); // data type switch ($tempArr[0]) { case "CEF_FLOAT" : $data_type = 'FLOAT'; break; case "CEF_SHORT": $data_type = 'SHORT'; break; case "CEF_INT": $data_type = 'INTEGER'; break; case "CEF_DOUBLE": $data_type = 'DOUBLE'; break; default : $data_type = 'FLOAT'; } // data dimensions & number of records3 $n_recs = $tempArr[2]; if ($tempArr[1] != 0) { $size = $tempArr[3]; //TODO 2D,3D,4D array no processing // if ($tempArr[1] > 1) } else { $size = 1; } return array('type' => $data_type, 'size' => $size, 'n_records' => 'TBD'); } protected function getCefSampling() { exec('cefsampling '.$this->fileName, $results); return $results; } /* * netCDF format processing if needed */ protected function reformatNcTime() { exec('nctimestring2double '.$this->fileName, $results); return $results[0]; } protected function getNcTimeInfo() { exec('nctimeinfo '.$this->fileName, $result); return $result[0]; } protected function getNcVars(){ exec('getncvars '.$this->fileName, $result); if ($result[0] < 0) return $result[0]; $varsArr = explode("#",$result[0]); return $varsArr; } protected function getNcVarInfo($varId) { exec('ncvarinfo '.$this->fileName.' '.$this->param2dd($varId), $results); $tempArr = explode(' ', $results[0]); // data type switch ($tempArr[0]) { case "5": $data_type = 'FLOAT'; break; case "3": $data_type = 'SHORT'; break; case "4" : $data_type = 'INTEGER'; break; case "6": $data_type = 'DOUBLE'; break; default: $data_type = 'FLOAT'; } // data dimensions & number of records $n_recs = $tempArr[2]; if (count($tempArr) > 3) { $size = $tempArr[3]; //TODO 2D,3D,4D array no processing // if ($tempArr[1] > 1) } else { $size = 1; } return array('type' => $data_type, 'size' => $size, 'n_records' => $n_recs); } protected function param2dd($paramID) { $pairs = array("-" => "_", "%" => "_","\\" => "_","$" => "_",":" => "_","+" =>" _","-" => "_","#" => "_","@" => "_", "." => "_",">" => "_", "<" => "_"); return strtr($paramID, $pairs); } /* * ascii format processing */ protected function getTxtSampling() { $StartTime = null; if (!file_exists($this->fileName)) return -100; $i = 0; $handler = fopen($this->fileName, 'r'); if ($handler) { while (!feof($handler) && !$StartTime) { $oneLine = trim(fgets($handler)); $elems = explode(" ", preg_replace('/\s+/', ' ', $oneLine)); if ((strlen($elems[0]) < 16) || !($time = strtotime($elems[0]))) { $i++; continue; } $StartTime = $time; if (!(is_numeric($elems[1]))) return -10; $dt = $elems[1]; } } if (feof($handle)) return -10; $oneLine = trim(fgets($handler)); $elems = explode(" ",$oneLine); if (count($elems) < 2) return -10; // dT else Array if (!($time = strtotime($elems[0]))) return $dt; else return $time - $StartTime; } public function getTxtSamplings() { $StartTime = null; if (!file_exists($this->fileName)) return array(-100); $handler = fopen($this->fileName, 'r'); if ($handler) { $i = 0; while (!feof($handler) && !$StartTime) { $oneLine = trim(fgets($handler)); $elems = explode(" ", preg_replace('/\s+/', ' ', $oneLine)); if (strlen($elems[0]) < 16 || !($time = strtotime($elems[0]))) { $i++; continue; } $StartTime = $time; if (!(is_numeric($elems[1]))) return array(-10); $dt = $elems[1]; } } if (feof($handle)) return array(-10); $oneLine = trim(fgets($handler)); $elems = explode(" ",$oneLine); if (count($elems) < 2) return array (-1); // dT else Array if (!($time = strtotime($elems[0]))) return array($dt); else { $minSampling = +1.e31; $maxSampling = 0.0; while (!feof($handler)) { $oneLine = trim(fgets($handler)); $elems = explode(" ",$oneLine); if (count($elems) < 2) continue; $StartTime = $time; if (!($time = strtotime($elems[0]))) return array(-1); $deltaT[$time - $StartTime]++; } foreach ($deltaT as $key => $value) { if ($value < 5) continue; if ($key < $minSampling) $minSampling = $key; if ($key > $maxSampling) $maxSampling = $key; } return array($minSampling,$maxSampling); } } /* * Delete comments and convert time into double */ public function reformatTxt() { $StartTime = null; if (!file_exists($this->fileName)) return -100; $handler = fopen($this->fileName, 'r'); if ($handler) { $offset = ftell($handle); $i = 0; while (!$StartTime && !feof($handler)) { $oneLine = trim(fgets($handler)); $elems = explode(" ", preg_replace('/\s+/', ' ', $oneLine)); if (!($time = strtotime($elems[0]))) { $offset = ftell($handle); $i++; continue; } $StartTime = $time; $dt = $elems[1]; } } $newfile = fopen(USERDATADIR."temp", "w"); $oneLine = trim(fgets($handler)); $elems = explode(" " , $oneLine); // dT if (!($time = strtotime($elems[0]))) { $newtime = $StartTime; settype($dt, "float"); if ($oneLine != PHP_EOL && count($elems) > 0) fwrite($newfile, $newtime." ".$oneLine.PHP_EOL); $newtime += $dt; while (!feof($handler)) { $oneLine = trim(fgets($handler)); if ($oneLine != PHP_EOL && count($elems) > 0) fwrite($newfile, $newtime." ".$oneLine.PHP_EOL); $newtime += $dt; } } // Array else { fseek($handler, $offset); while (!feof($handler)) { $oneLine = trim(fgets($handler)); $elems = explode(" " ,$oneLine); // empty lines if (count($elems) < 2) continue; $newtime = strtotime($elems[0]); //TODO Error message if wrong time format...??? if (!$newtime) continue; unset($elems[0]); $newline = join($elems," "); fwrite($newfile,$newtime." ". $newline.PHP_EOL); } } fclose($newfile); rename(USERDATADIR."temp",$this->fileName); return $StartTime." ".$newtime; } /* * Convert time into ISO */ protected function reformatTime($timeFormat, $timeLength, $doy) { $formatLength = $timeLength == 'auto' ? strlen($timeFormat) + (strpos($timeFormat,"Y") !== false)*3 + (strpos($timeFormat,"y") !== false) + (strpos($timeFormat,"M") !== false)*2 + (strpos($timeFormat,"m") !== false) + (strpos($timeFormat,"d") !== false) + (strpos($timeFormat,"H") !== false) + (strpos($timeFormat,"i") !== false) + (strpos($timeFormat,"s") !== false) + (strpos($timeFormat,".u") !== false)*2 : $timeLength; if (strpos($timeFormat,".u") !== false) { $formatLength = $formatLength - 4; $timeFormat = substr($timeFormat, 0, strlen($timeFormat)-2); } if (strpos($timeFormat,".k") !== false) { $formatLength = $formatLength - 2; $timeFormat = substr($timeFormat, 0, strlen($timeFormat)-2); } $handle = fopen($this->fileName,'r'); if ($handle) { $newfile = fopen(USERDATADIR."temp", "w"); while (!feof($handle)) { if (($oneLine = fgets($handle)) !== false) { $line = $timeLength == 'auto' ? $line = trim(preg_replace('/\s+/', ' ', $oneLine)) : trim($oneLine); if (strlen($line) > $formatLength) { try { $date = DateTime::createFromFormat($timeFormat, trim(substr($line,0,$formatLength))); if (!$date) { if (strpos($line,'#') === 0) fwrite($newfile, $line.PHP_EOL); } else { // DOY starts from 1 if ($doy) { $date->modify('-1 day'); } $suffix = preg_replace('/\s+/', ' ',substr($line, $formatLength)); fwrite($newfile,$date->format('Y-m-d')."T".$date->format('H:i:s').$suffix.PHP_EOL); } } catch (Exception $e) { // fwrite($newfile,$line.PHP_EOL); } } else if (strpos($line,'#') === 0) fwrite($newfile,$line.PHP_EOL); } } } else { if (file_exists($this->fileName)) { fclose($handle); unlink($this->fileName); } return $false; } fclose($newfile); fclose($handle); rename(USERDATADIR."temp", $this->fileName); return true; } /* * Returns number of columns in text file to create data model fields in MyDataUI.js */ protected function getTxtColNumber($timeDouble) { if (!file_exists($this->fileName)) return -100; $handle = fopen($this->fileName,'r'); if ($handle) { $found = false; $i = 0; while (($line = trim(fgets($handle))) !== false && $i < 100) { $elems = explode(" ", preg_replace('/\s+/', ' ', $line)); $i++; if (count($elems) < 2 || strpos($elems[0], '#') === 0) continue; if (!$timeDouble) { if (strlen($elems[0]) >= 16 && ($time = strtotime($elems[0]))) { $found = true; break; } } else { $found = true; break; } } if (!feof($handle) && !$found) { fclose($handle); unlink($this->fileName); return -1; } } fclose($handle); if (!$found) { unlink($this->fileName); return 0; } return count($elems); } /* * new file tag in Files.xml */ protected function createSimuFile($format) { $newFile = $this->contentDom->createElement('file'); $newFile->setAttribute('xml:id', $this->fileId); $newFile->setAttribute('name', $this->fileId); $newFile->setAttribute('format', $format); $start_stop = explode(" ",$this->getVotFileMgr()->getStartStop()); $samplings = $this->getVotFileMgr()->getSamplings(); $minSamp = $samplings["minSampling"]; $maxSamp = $samplings["maxSampling"]; $desc = $this->getVotFileMgr()->getDescription(); $start = $start_stop[0]; $stop = $start_stop[1]; $newFile->setAttribute("start",$start); $newFile->setAttribute("stop",$stop); $newFile->setAttribute('minsampling',$minSamp); $newFile->setAttribute('maxsampling',$maxSamp); $newFile->setAttribute('uploaded', date('Y-m-d H:i:s')); // generic MASK without datas for simu params if ((strncmp($this->fileId, "impex___", 8) == 0) || (strncmp($this->fileId, "spase___", 8) == 0)) $newFile->setAttribute('mask', $this->getGenericMask()); $newFile->nodeValue = date('Y-m-d',$start)."T".date('H:i:s',$start)."-".date('Y-m-d',$stop)."T".date('H:i:s',$stop); if ($desc != '') $newFile->nodeValue .= (PHP_EOL.$desc); return $newFile; } protected function createFile($format) { $newFile = $this->contentDom->createElement('file'); $newFile->setAttribute('xml:id', $this->fileId); $newFile->setAttribute('name', $this->fileId); $newFile->setAttribute('format', $format); switch ($format){ case "cdf": $start_stop = explode(" ",$this->getCdfStartStop()); $result = $this->getCdfSampling(); //TODO process errors $minSamp = $result[count($result)-1]; //TODO if min & max $maxSamp = $minSamp; break; case "txt": $start_stop = explode(" ",$this->reformatTxt()); if ($start_stop[0] < 0) return $start_stop; $minSamp = $this->sampling; $maxSamp = $this->maxSampling; break; case "cef": // Test if 'standard' meta exist in CEF $cefMetaTest = $this->getCefStartStop(); if ($cefMetaTest != -1) { $cefStartStop = explode("/",$cefMetaTest); $start_stop[] = strtotime($cefStartStop[0]); $start_stop[] = strtotime($cefStartStop[1]); $result = $this->getCefSampling(); $minSamp = $result[count($result)-1]; } else { // no META data - so time processing $timeInfo = $this->getCefTimeInfo(); $timeInfoArr = explode(" ", $timeInfo); $start_stop[] = $timeInfoArr[0]; $start_stop[] = $timeInfoArr[1]; $minSamp = $timeInfoArr[2]; } //TODO if min & max $maxSamp = $minSamp; break; case "vot" : $start_stop = explode(" ",$this->getVotFileMgr()->getStartStop()); $samplings = $this->getVotFileMgr()->getSamplings(); $minSamp = $samplings["minSampling"]; $maxSamp = $samplings["maxSampling"]; $desc = $this->getVotFileMgr()->getDescription(); break; case "nc": $ncInfo = $this->getNcTimeInfo(); if ($ncInfo < 0) { unlink($this->fileName); return $ncInfo; } $ncInfoArr = explode("#",$ncInfo); $start_stop = explode(":",$ncInfoArr[0]); //TODO process errors $minSamp = $ncInfoArr[1]; //TODO if min & max $maxSamp = $minSamp; break; default: } $start = $start_stop[0]; $stop = $start_stop[1]; $newFile->setAttribute("start",$start); $newFile->setAttribute("stop",$stop); $newFile->setAttribute('minsampling',$minSamp); $newFile->setAttribute('maxsampling',$maxSamp); $newFile->setAttribute('uploaded', date('Y-m-d H:i:s')); // generic MASK without datas for simu params if ((strncmp($this->fileId, "impex___", 8) === 0) || (strncmp($this->fileId, "spase___", 8) === 0)) $newFile->setAttribute('mask', $this->getGenericMask()); else $newFile->setAttribute('mask', $this->fileId); $newFile->nodeValue = date('Y-m-d',$start)."T".date('H:i:s',$start)."-".date('Y-m-d',$stop)."T".date('H:i:s',$stop); if ($desc != '') $newFile->nodeValue .= (PHP_EOL.$desc); return $newFile; } protected function getGenericMask() { if (strncmp($this->fileId, "impex___", 8) == 0) { $prefix = "impex___"; $tmpFileName = str_replace ("impex___", "", $this->fileId); } elseif (strncmp($this->fileId, "spase___", 8) == 0) { $prefix = "spase___"; $tmpFileName = str_replace ("spase___", "", $this->fileId); } $tmpFileArray = explode( '.', $tmpFileName); $tmpParamArray = explode( '_', $tmpFileArray[0]); array_pop($tmpParamArray); array_pop($tmpParamArray); $tmpName = implode("_", $tmpParamArray); $mask = $prefix.$tmpName."_*.xml"; return $mask; } /* //TODO check how to upgrade this */ protected function getFormat() { $ext = pathinfo($this->fileName, PATHINFO_EXTENSION); if (PHP_VERSION_ID < 50300) { $finfo = new finfo(FILEINFO_MIME, MAGIC_FILE); $file_info = explode(";", $finfo->file($this->fileName)); } else { // PHP v >= 5.3 comes with its own magic file !!!! $finfo = finfo_open(FILEINFO_MIME); $file_info = explode(";",finfo_file($finfo, $this->fileName)); } if (strpos($file_info[0],"plain") !== false) { if (strpos($ext,"cef") !== false) return "cef"; return "txt"; } if (strpos($file_info[0],"application/x-gzip") !== false) { if (strpos($this->fileName,"cef.gz") !== false) return "cef"; } if (strpos($file_info[0],"application/xml") !== false) { //if ($this->getVotFileMgr()->isValidSchema()) //BRE : No schema validation for the moment due to some trouble with Topcat (it can create not valid VOTable) return "vot"; } // check binary at different machines - if it works..... if (strpos($file_info[0],"octet-stream") !== false) { if (strpos($ext,"cdf") !== false) return "cdf"; if (strpos($ext,"nc") !== false) return "nc"; } return "unknown"; } /* * PUBLIC FUNCTIONS */ public function getAsciiFile($name) { $this->fileName = USERDATADIR.$name; if (!file_exists(USERDATADIR.$name)) return array('success' => false, 'error' => 'No such file'); $handle = fopen($this->fileName, "r"); $fileToReturn = array(); $index = 0; $tempFileToReturn = array(); while (!feof($handle)) { $line = trim(fgets($handle)); $tempArr = explode(' ', preg_replace('/\s+/', ' ', $line)); if (count($tempArr) > 1) { for ($i = 0; $i < count($tempArr); $i++) { $name = $i === 0 ? 'Time' : 'n'.$i; //transform double time to ISO if ($name == 'Time') { $temp = $tempArr[0]; settype($temp, 'double'); $tempArr[0] = date('Y-m-d H:i:s', $temp); } $tempFileToReturn[$name] = $tempArr[$i]; } $fileToReturn[$index] = $tempFileToReturn; $index++; if ($index > MAX_FILE_INDEX_TO_SHOW) break; } } return $fileToReturn; } /* * Get info on parameter */ public function getParamInfo($obj){ $this->fileName = USERDATADIR.$obj->file; $varId = $obj->varName; $format = $obj->format; // at first info from Files.xml $file = $this->contentDom->getElementById($obj->file); if ($file) { if ($file->parentNode->tagName == 'folder') $mask = $file->parentNode->getAttribute('name'); else $mask = $file->getAttribute('mask'); $dom_info = array( 'name' => $varId, 'minsampling' => $file->getAttribute('minsampling'), 'maxsampling' => $file->getAttribute('maxsampling'), 'mask' => $mask); } else { if ($format == "nc"){ $status = $this->reformatNcTime(); if ($status <= 0) { unlink($this->fileName); return array('success' => false, 'error' => 'error '.$timeFormat.PHP_EOL.'Time Format problem'); } $ncInfo = $this->getNcTimeInfo(); $ncVars = $this->getNcVars(); if ($ncInfo < 0) { unlink($this->fileName); return $ncInfo; } $ncInfoArr = explode("#",$ncInfo); $start_stop = explode(":",$ncInfoArr[0]); //TODO process errors $minSamp = $ncInfoArr[1]; //TODO if min & max $maxSamp = $minSamp; $dom_info = array( 'name' => $varId, 'minsampling' => $minSamp, 'maxsampling' => $maxSamp, 'mask' => $obj->mask); } } switch ($format){ case "cdf": $info = $this->getCdfVarInfo($varId); break; case "txt": break; case "cef": $info = $this->getCefVarInfo($varId); break; case "nc": $info = $this->getNcVarInfo($varId); break; case "vot": $info = $this->getVotFileMgr()->getFieldInfoByID($varId); break; default: } return array('success' => true, 'info' => array_merge($dom_info,$info)); } public function deleteObject($obj) { $myBaseManager = new BaseManager(); $paramMgr = new DerivedParamMgr('myDataParam'); $xpd = new domxpath($paramMgr->contentDom); //File, not a folder if ($obj->leaf) { $this->fileName = USERDATADIR.$obj->id; if (file_exists($this->fileName)) unlink($this->fileName); $theFile = $this->contentDom->getElementById($obj->id); // Update data base $fileInBase = $myBaseManager->xp->query("//file[@name='".$obj->id."']"); if ($fileInBase->length > 0) { $viInfo = $myBaseManager->delFile($fileInBase->item(0)); $mask = $viInfo['mask']; $length = $viInfo['length']; $params = $xpd->query("//mydata[@mask='".$mask."']"); if ($params->length > 0) { // NO FILES in the mask; corresponding parameters are to be deleted if ($length == 0) { $paramsToDelete = array(); for ($i = $params->length; --$i >= 0; ) { $id = $params->item($i)->getAttribute('xml:id'); $paramMgr->deleteParameter($id); $paramMgr->deleteFromContent($params->item($i)); $paramsToDelete[] = $id; } } // update params description in Content Dom else { $vi = $myBaseManager->getVi($mask); $desc = $myBaseManager->getStartStop($vi); foreach ($params as $param) $param->setAttribute("desc",$desc); $paramMgr->saveContent(); } } } // WS/Files.xml if ($theFile) { if ($desc) $theFile->parentNode->setAttribute('info', $desc); $theFile->parentNode->removeChild($theFile); $this->contentDom->save($this->xmlName); } } // Folder else { $mask = $obj->id; $theMask = $this->contentDom->getElementById($obj->id); $files = $theMask->getElementsByTagName('file'); foreach ($files as $file) { $fileName = USERDATADIR.$file->getAttribute('name'); if (file_exists($fileName)) unlink($fileName); } $this->deleteFromContent($theMask); $myBaseManager->delVI($mask); $params = $xpd->query("//mydata[@mask='".$mask."']"); $paramsToDelete = array(); for ($i = $params->length; --$i >= 0; ) { $id = $params->item($i)->getAttribute('xml:id'); $paramMgr->deleteParameter($id); $paramMgr->deleteFromContent($params->item($i)); $paramsToDelete[] = $id; } } // No more files for myDataParams if ($paramsToDelete) return array('id' => $obj->id, 'params' => $paramsToDelete); // update info for myDataParams Start Stop were changed return array('id' => $obj->id, 'mask' => $mask, 'maskDesc' => $desc); } public function deleteSimuObject($obj) { $myBaseManager = new BaseManager(); $paramMgr = new DerivedParamMgr('mySimuParam'); $xpd = new domxpath($paramMgr->contentDom); if ($obj->leaf) { $this->fileName = USERDATADIR.$obj->id; if (file_exists($this->fileName)) unlink($this->fileName); $theFile = $this->contentDom->getElementById($obj->id); if ($theFile) { $theFile->parentNode->removeChild($theFile); $this->contentDom->save($this->xmlName); } // update base data $fileInBase = $myBaseManager->xp->query("//file[@name='".$obj->id."']"); if ($fileInBase->length > 0) { $mask = $myBaseManager->delFile($fileInBase->item(0)); $params = $xpd->query("//mydata[@mask='".$mask."']"); if ($params->length > 0) { // NO FILES in the mask; corresponding parameters are to be deleted if (strcmp($mask, "NONEMPTY") != 0) { $paramsToDelete = array(); for ($i = $params->length; --$i >= 0; ) { $id = $params->item($i)->getAttribute('xml:id'); $paramMgr->deleteParameter($id); $paramMgr->deleteFromContent($params->item($i)); $paramsToDelete[] = $id; } } // update params description in Content Dom else { $vi = $myBaseManager->getVi($mask); $desc = $myBaseManager->getStartStop($vi); foreach ($params as $param) $param->setAttribute("desc",$desc); $paramMgr->saveContent(); } } } } else { $mask = $obj->id; $theMask = $this->contentDom->getElementById($obj->id); $files = $theMask->getElementsByTagName('file'); foreach ($files as $file) { $fileName = USERDATADIR.$file->getAttribute('name'); if (file_exists($fileName)) unlink($fileName); } $this->deleteFromContent($theMask); $myBaseManager->delVI($mask); $params = $xpd->query("//mydata[@mask='".$mask."']"); $paramsToDelete = array(); for ($i = $params->length; --$i >= 0; ) { $id = $params->item($i)->getAttribute('xml:id'); $paramMgr->deleteParameter($id); $paramMgr->deleteFromContent($params->item($i)); $paramsToDelete[] = $id; } } if ($paramsToDelete) return array('id' => $obj->id, 'params' => $paramsToDelete); else return array('id' => $obj->id); } /* * recombine files in Files.xml according to new Mask */ public function addMask($fileMask, $type) { if ($this->contentDom ->getElementById($fileMask) != null) return false; $filesInRoot = $this->xp->query("/ws/fileList/file"); $newMask = $this->contentDom->createElement("folder"); $newMask->setAttribute('xml:id', $fileMask); $newMask->setAttribute('name', $fileMask); for ($i = $filesInRoot->length; --$i >= 0;) { $aFile = $filesInRoot->item($i); // mask corresponds to file name if ($this->fileMask($aFile->getAttribute("name"),$fileMask)) { $newMask->appendChild($aFile); } } $files = $newMask->getElementsByTagName("file"); if ($files->length == 0) return false; foreach ($files as $file) { $starts[] = $file->getAttribute("start"); $stops[] = $file->getAttribute("stop"); } $newMask->setAttribute('info',date('Y-m-d',min($starts))."T".date('H:i:s',min($starts))."-".date('Y-m-d',max($stops))."T".date('H:i:s',max($stops))); $fileList = $this->contentDom->getElementById($this->contentRootId); $fileList->appendChild($newMask); $this->contentDom->save($this->xmlName); return true; } /* * check correspondence FleName <=> Mask * returns true if Mask fits FileName */ public function fileMask($fileName, $maskName) { $mask = explode("*", $maskName); if (strpos($fileName, $mask[0]) !== 0) return false; if (count($mask) == 1) return true; for ($i = 1; $i < count($mask); $i++) if ($mask[$i] != null) if (strpos($fileName, $mask[$i]) === false) return false; return true; } /* * Delete Mask */ public function delMask($oldMask) { $mask = $this->contentDom->getElementById($oldMask); if ($mask != null && $mask->tagName == "folder") { $filesInMask = $mask->getElementsByTagName("file"); $fileList = $this->contentDom->getElementById($this->contentRootId); while ($filesInMask->length > 0) $fileList->appendChild($filesInMask->item(0)); $fileList->removeChild($mask); $this->contentDom->save($this->xmlName); return true; } return false; } /* * mask or file */ public function getObject($name) { $object = $this->contentDom->getElementById($name); if (is_object($object)) { // mask if ($object->tagName == 'folder') { $file = $object->getElementsByTagName('file'); if ($file->length > 0) return $this->getUploadedObject($file->item(0)->getAttribute('name')); else return array('success' => false, 'error' => 'Mask is empty'); } } else return array('success' => false, 'error' => 'No such mask in DOM'); // file return $this->getUploadedObject($name); } /* * Get generic info on uploaded file */ public function getUploadedObject($name) { $this->fileName = USERDATADIR.$name; $file = $this->contentDom->getElementById($name); if (!$file) return array('success' => false, 'error' => 'No such file in DOM'); $format = $file->getAttribute('format'); $minSamp = $file->getAttribute('minsampling'); $maxSamp = $file->getAttribute('maxsampling'); $mask = $file->parentNode->tagName == "folder" ? $file->parentNode->getAttribute("name") : null; $maskDesc = $mask ? $file->parentNode->getAttribute('info') : null; $desc = $file->nodeValue; $foundTime = true; switch ($format){ case "cdf": $vars = $this->getCdfVars(); break; case "txt": $vars = $this->getTxtColNumber(true); break; case "nc" : $vars = $this->getNcVars(); break; case "cef": $vars = $this->getCefVars(); break; case "vot" : $vars = $this->getVotFileMgr()->getFieldsInfo(); $foundTime = ($this->getVotFileMgr()->getTimeFieldIndex() > -1); break; default: } return array('success' => true, 'format' => $format, 'vars' => $vars, 'fileName' => $name, 'minsampling' => $minSamp, 'maxsampling' => $maxSamp, 'mask' => $mask, 'maskDesc' => $maskDesc, 'description' => $desc, 'foundTime' => $foundTime); } /* * The very first processing of newly uploaded file file * $formats = array('fileFormat', 'timeFormat', 'timeSampling', 'nonStandard', 'doy'); */ public function addFile($fileName, $formats) { $this->fileName = USERDATADIR.$fileName; $this->fileId = $fileName; $format = $this->getFormat(); if ($format === 'unknown'){ unlink($this->fileName); return array('success' => false, 'error' => 'Sorry, unknown format of '.$fileName); } if ($format == 'txt') { if ($formats["timeFormat"] == "user") { $res = $this->reformatTime($formats["nonStandard"], $formats["timeLength"], $formats["doy"]); if (!$res) { unlink($this->fileName); return array('success' => false, 'error' => 'can\'t reformat time'); } } // check if file is not empty $vars = $this->getTxtColNumber(false); if ($vars == -100) { return array('success' => false, 'error' => 'no such file'); } if ($vars == -1) { unlink($this->fileName); return array('success' => false, 'error' => 'while reading file'); } if ($vars === 0) { unlink($this->fileName); return array('success' => false, 'error' => 'file contains no data'); } if ($formats["timeSampling"] == "constant") { $this->sampling = $this->getTxtSampling(); $this->maxSampling = $this->sampling; } else { $samplings = $this->getTxtSamplings(); $this->sampling = $samplings[0]; $this->maxSampling = $samplings[1]; } if ($this->sampling <= 0) { unlink($this->fileName); if ($this->sampling == -10) { return array('success' => false, 'error' => 'Sorry, can\'t process'.$fileName.PHP_EOL.'. Check if there are non numeric chars in the data'); } return array('success' => false, 'error' => 'Sorry, can\'t process Time for '.$fileName.PHP_EOL.'. Check time format, start time (> 1970-01-01) or sampling time (>= 1s)'); } } if ($format == 'nc') { $status = $this->reformatNcTime(); if ($status <= 0) { unlink($this->fileName); return array('success' => false, 'error' => 'error '.$timeFormat.PHP_EOL.'Time Format problem'); } } //create new file tag with all attributes and add it to the content DOM $newFile = $this->createFile($format); if ($newFile < 0) { unlink($this->fileName); return array( 'success' => false, 'file' => $fileName); } $isMask = false; $masks = $this->contentDom->getElementsByTagName("folder"); foreach ($masks as $mask) { $folderMask = $mask->getAttribute("name"); if ($this->fileMask($fileName, $folderMask)) { $mask->appendChild($newFile); $files = $mask->getElementsByTagName("file"); foreach ($files as $file) { $starts[] = $file->getAttribute("start"); $stops[] = $file->getAttribute("stop"); } $mask->setAttribute("info", date('Y-m-d',min($starts))."T".date('H:i:s',min($starts))."-".date('Y-m-d',max($stops))."T".date('H:i:s',max($stops))); $isMask = true; break; } } // no corresponding masks => add to fileList if (!$isMask) { $filesList = $this->contentDom->getElementById($this->contentRootId); $filesList->appendChild($newFile); } $this->contentDom->save($this->xmlName); //if mask exists - add to data base $myBaseManager = new BaseManager(); $mask = $myBaseManager->addFile($fileName); if ($mask != null) { $startstop = $myBaseManager->getStartStop($myBaseManager->getVi($mask)); $myParamMgr = new DerivedParamMgr('myDataParam'); $myParamMgr->updateMydata($mask,$startstop); } return array( 'success' => true, 'file' => $fileName); } } ?>