epntap.php 6.89 KB
<?php

include(realpath(dirname(__FILE__) . "/config.php"));
// include(CLASSPATH . "EpnTapMgr.php");
include(CLASSPATH . "VOTableMgr.php");

$action = preg_replace("/[^a-zA-Z]+/", "", filter_var($_GET['action'], FILTER_SANITIZE_STRING));

switch ($action) {
	case 'resolver':
		$response = json_encode(resolver());
		break;
	case 'getServices':
		$response = json_encode(getServices());
		break;
	case 'getNbResults':
		$response = getNbResults();
		break;
	case 'getGranules':
		$response = json_encode(getGranules());
		break;
	default:
		$response = 'unknown action';
		break;
}
// error_log('epntap response: ' . $response);
echo $response;

function resolver() {
	$input = filter_var($_GET['input'], FILTER_SANITIZE_URL);
	$resolver_url = "http://voparis-registry.obspm.fr/ssodnet/1/autocomplete?q=%22$input%22";
	$result = json_decode(file_get_contents($resolver_url), true);

	$targets = array();
	foreach($result['hits'] as $e) {
		$aliases = '<li>' . join('</li><li>', $e['aliases']) . '</li>';
		$target = array('name' => $e['name'], 'type' => $e['type'], 'parent' => $e['parent'], 'aliases' => $aliases);
		array_push($targets, $target);
	}
	return $targets;
}

/* Return the list of available services by querying some usual registries. */
function getServices() {
	$registriesURL = ["http://registry.euro-vo.org/regtap/tap", "http://dc.zah.uni-heidelberg.de/tap", "http://gavo.aip.de/tap", "http://reg.g-vo.org/tap"];
	$columns = ['short_name', 'res_title', 'ivoid', 'access_url', 'table_name', 'content_type', 'creator_seq', 'content_level', 'reference_url', 'created', 'updated'];
	$query = "SELECT DISTINCT " . implode(', ', $columns) . " FROM rr.resource
			NATURAL JOIN rr.res_schema NATURAL JOIN rr.res_table NATURAL JOIN rr.interface NATURAL JOIN rr.res_detail NATURAL JOIN rr.capability
			WHERE standard_id='ivo://ivoa.net/std/tap' AND intf_type='vs:paramhttp' AND detail_xpath='/capability/dataModel/@ivo-id'
			AND 1=ivo_nocasematch(detail_value, 'ivo://vopdc.obspm/std/EpnCore%') AND table_name LIKE '%.epn_core' ORDER BY short_name, table_name";
	// error_log('getServices query: ' . $query);

	for($i=0; $i<count($registriesURL); $i++) {
		$services = request($registriesURL[$i], $query);
		if(! array_key_exists("error", $services)) {
			for($j=0; $j<count($services); $j++) {
				$services[$j]['id'] = generateServiceId($services[$j]);
				$services[$j]['nb_results'] = -1;
				$services[$j]['info'] = 'Please make a query first.';
				if($services[$j]['id'] == 'cdpp/amda/amdadb') {
					array_splice($services, $j, 1);
					$j-=1;
				}
			}
			return $services;
		} else {
			error_log('getServices error: ' . $services['error']);
			if($i === count($registriesURL)-1) {
				error_log("Can not access any of these registries : " . implode(', ', $registriesURL) . ", check the internet connexion.");
				return;
			}
		}
	}
}

function getNbResults() {
	$url = filter_var($_GET['url'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$tableName = filter_var($_GET['tableName'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$targetName = filter_var($_GET['targetName'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$productTypes = filter_var($_GET['productTypes'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$timeMin = filter_var($_GET['timeMin'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$timeMax = filter_var($_GET['timeMax'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);

	$query = "SELECT COUNT(*) AS nb_rows FROM $tableName" . createFilter($targetName, $productTypes, $timeMin, $timeMax);
	// error_log('getNbResults query: ' . $query);
	$result = request($url, $query);
	if(count($result) < 1) {
		return 'Too few returned raws.';
	} else if(count($result) > 1) {
		return 'Too many returned raws.';
	} else if(!array_key_exists(0, $result)) {
		return 'cant find raw item 0';
	} else if(is_null($result[0])) {
		return 'The returned raw is null.';
	} else if(!array_key_exists("nb_rows", $result[0])) {
		return 'cant find nb_rows.';
	} else if(!is_numeric($result[0]['nb_rows'])) {
		return 'The returned value is not a number.';
	} else {
		return (int)($result[0]['nb_rows']);
	}
}

function getGranules() {
	// error_log('getGranules GET: ' . json_encode($_GET));
	$url = filter_var($_GET['url'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$tableName = filter_var($_GET['tableName'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$targetName = filter_var($_GET['targetName'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$productTypes = filter_var($_GET['productTypes'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$timeMin = filter_var($_GET['timeMin'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$timeMax = filter_var($_GET['timeMax'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$start = filter_var($_GET['start'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$limit = filter_var($_GET['limit'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	$nbRes = filter_var($_GET['nbRes'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);

	$filter = createFilter($targetName, $productTypes, $timeMin, $timeMax);
	$query = "SELECT TOP $limit * FROM $tableName $filter OFFSET $start";
	// error_log('getGranules query: ' . $query);
	$rows = request($url, $query);

	$fields = array();
	$columns = array();
	foreach($rows[0] as $key => $value) {
		$fields[] = ['name' => $key, 'type' => 'string'];
		$columns[] = ['text' => ucfirst(str_replace('_', ' ', $key)), 'dataIndex' => $key];
	}

	$metadata = ['fields' => $fields, 'columns' => $columns, 'root' => 'data'];
	return ['data' => $rows, 'total' => $nbRes, 'metaData' => $metadata];
}

// ----- utils -----

function request($access_url, $query) {
	$votMgr = new VOTableMgr;
	$params = 'FORMAT=votable&LANG=ADQL&REQUEST=doQuery';
	$url = $access_url . '/sync?' . $params . '&QUERY=' . urlencode(preg_replace('/\s+/', ' ', $query)); // remove also multiple whitespaces

	$votMgr->load($url);
	$result = $votMgr->parseStream();
	return $votMgr->getVotableError() ? array('error' => $votMgr->getVotableError()) : $result;
}

function createFilter($targetName, $productTypes, $timeMin, $timeMax) {
	$filter = array();
	if($targetName) {
		array_push($filter, "target_name = '$targetName'");
	}
	if($productTypes) {
		array_push($filter, "dataproduct_type IN ('" . join("', '", explode(';', $productTypes)) . "')");
	}
	if($timeMin) {
		array_push($filter, "time_min >= " . dateToJD($timeMin));
	}
	if($timeMax) {
		array_push($filter, "time_max <= " . dateToJD($timeMax));
	}
	return (count($filter) > 0 ? ' WHERE ' . join(' AND ', $filter) : '');
}

/* Generate a unique service identifier from the service ivoid and the table name. */
function generateServiceId($service) {
	return str_replace(['ivo://', '.epn_core'], '', $service['ivoid'] . '/' . $service['table_name']);
}

function dateToJD($gregorian_date) {
	list($day, $month, $year, $hours, $minutes, $seconds) = preg_split('/[\s\/:]+/', $gregorian_date);
	return GregorianToJD($month, $day, $year) + $hours/24 + $minutes/(24*60) + $seconds/(24*60*60);
}
?>