Blame view

php/epntap.php 8.67 KB
8a0f1e9e   Nathanael Jourdane   Add autocompletio...
1
<?php
68664dca   Nathanael Jourdane   make epntap php f...
2

49401187   Nathanael Jourdane   epntap: Do not us...
3
include(realpath(dirname(__FILE__) . "/config.php"));
49401187   Nathanael Jourdane   epntap: Do not us...
4
5
include(CLASSPATH . "VOTableMgr.php");

8c2fa14d   Nathanael Jourdane   Update services g...
6
$action = preg_replace("/[^a-zA-Z]+/", "", filter_var($_GET['action'], FILTER_SANITIZE_STRING));
68664dca   Nathanael Jourdane   make epntap php f...
7
8
9

switch ($action) {
	case 'resolver':
50dd7220   Nathanael Jourdane   epntap.php works ...
10
		$response = resolver();
68664dca   Nathanael Jourdane   make epntap php f...
11
		break;
8c2fa14d   Nathanael Jourdane   Update services g...
12
	case 'getServices':
50dd7220   Nathanael Jourdane   epntap.php works ...
13
		$response = getServices();
68664dca   Nathanael Jourdane   make epntap php f...
14
		break;
8c2fa14d   Nathanael Jourdane   Update services g...
15
	case 'getNbResults':
a8a12768   Nathanael Jourdane   Create the grid m...
16
		$response = getNbResults();
8c2fa14d   Nathanael Jourdane   Update services g...
17
		break;
d6674d39   Nathanael Jourdane   Add error and inf...
18
	case 'getGranules':
50dd7220   Nathanael Jourdane   epntap.php works ...
19
		$response = getGranules();
68664dca   Nathanael Jourdane   make epntap php f...
20
		break;
d6674d39   Nathanael Jourdane   Add error and inf...
21
	default:
50dd7220   Nathanael Jourdane   epntap.php works ...
22
		$response = ['success' => false, 'msg' => 'Unknown action: ' . $action];
a8a12768   Nathanael Jourdane   Create the grid m...
23
		break;
8a0f1e9e   Nathanael Jourdane   Add autocompletio...
24
}
50dd7220   Nathanael Jourdane   epntap.php works ...
25
echo json_encode($response);
68664dca   Nathanael Jourdane   make epntap php f...
26

5454dd64   Nathanael Jourdane   Refactoring epnta...
27
28
29
30
31
32
33
34
function getParam($paramName, $default=null) {
	if(array_key_exists($paramName, $_GET)) {
		return filter_var($_GET[$paramName], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
	} else {
		return $default;
	}
}

8c2fa14d   Nathanael Jourdane   Update services g...
35
36
function resolver() {
	$input = filter_var($_GET['input'], FILTER_SANITIZE_URL);
68664dca   Nathanael Jourdane   make epntap php f...
37
	$resolver_url = "http://voparis-registry.obspm.fr/ssodnet/1/autocomplete?q=%22$input%22";
68664dca   Nathanael Jourdane   make epntap php f...
38

50dd7220   Nathanael Jourdane   epntap.php works ...
39
40
41
42
43
44
45
	$response = ['success' => true, 'metaData' => ['root' => 'data', 'messageProperty' => 'msg']];
	try {
		$content = file_get_contents($resolver_url);
	} catch (Exception $e) {
		error_log('Resolver access error: ' . $e);
		$response['success'] = false;
		$response['msg'] = "Resolver unreachable on $resolver_url.";
49401187   Nathanael Jourdane   epntap: Do not us...
46
	}
50dd7220   Nathanael Jourdane   epntap.php works ...
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
	try {
		$result = json_decode($content, 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);
		}
		$response['data'] = $targets;
	} catch (Exception $e) {
		error_log('Resolver type error: ' . $e);
		$response['success'] = false;
		$response['msg'] = 'The resolver returned a bad result.';
	}
	return $response;
}

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);
	$data = $votMgr->parseStream();
	$error = $votMgr->getVotableError();

	$response = ['query' => $query, 'metaData' => ['root' => 'data', 'messageProperty' => 'msg']];
	if($error) {
		$response['success'] = false;
		$response['msg'] = $error;
	} else {
		$response['success'] = true;
		$response['data'] = $data;
	}
	return $response;
49401187   Nathanael Jourdane   epntap: Do not us...
82
83
84
85
86
87
}

/* 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'];
a8a12768   Nathanael Jourdane   Create the grid m...
88
	$query = "SELECT DISTINCT " . implode(', ', $columns) . " FROM rr.resource
49401187   Nathanael Jourdane   epntap: Do not us...
89
90
91
			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";
50dd7220   Nathanael Jourdane   epntap.php works ...
92
93
94
95
96
97
98
99
100
101
102
103

	$regNumber = 0;
	for(; $regNumber<count($registriesURL) ; $regNumber++) {
		$response = request($registriesURL[$regNumber], $query);
		if($response['success']) {
			// Add several other parameters and remove AMDA
			for($j=0 ; $j<count($response['data']) ; $j++) {
				$response['data'][$j]['id'] = generateServiceId($response['data'][$j]);
				$response['data'][$j]['nb_results'] = -1;
				$response['data'][$j]['info'] = 'Please make a query.';
				if($response['data'][$j]['id'] == 'cdpp/amda/amdadb') {
					array_splice($response['data'], $j, 1);
1813a0ba   Nathanael Jourdane   Remove AMDA to th...
104
105
					$j-=1;
				}
49401187   Nathanael Jourdane   epntap: Do not us...
106
			}
50dd7220   Nathanael Jourdane   epntap.php works ...
107
108
			if(isset($lastErrorMesage)) {
				$response['msg'] = $lastErrorMesage;
173951f6   Nathanael Jourdane   Display the getSe...
109
			}
50dd7220   Nathanael Jourdane   epntap.php works ...
110
111
112
			break;
		} else {
			$lastErrorMesage = 'Last tried registry (' . $registriesURL[$regNumber] . ') returned this error: ' . $response['msg'] . '.';
49401187   Nathanael Jourdane   epntap: Do not us...
113
		}
68664dca   Nathanael Jourdane   make epntap php f...
114
	}
50dd7220   Nathanael Jourdane   epntap.php works ...
115
116
117
118
	if(!$response['success']) {
		$response['msg'] = 'Can not access any of these registries: ' . implode(', ', $registriesURL) . ', last error message is ' . $lastErrorMesage;
	}
	return $response;
68664dca   Nathanael Jourdane   make epntap php f...
119
120
}

8c2fa14d   Nathanael Jourdane   Update services g...
121
function getNbResults() {
a5475297   Nathanael Jourdane   use a hash for me...
122
123
	$query = "SELECT COUNT(*) AS nb_rows FROM " . getParam('tableName') . createFilter(getParam('targetName'), getParam('productTypes'), getParam('timeMin'), getParam('timeMax'));
	$response = request(getParam('url'), $query);
50dd7220   Nathanael Jourdane   epntap.php works ...
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
	if($response['success']) {
		$response['success'] = false;
		$response['msg'] = 'The service returned a bad value, can not get the number of results.';
		if(count($response['data']) < 1) {
			error_log('getNbResults error: Too few returned raws.');
		} else if(count($response['data']) > 1) {
			error_log('getNbResults error: Too many returned raws.');
		} else if(!array_key_exists(0, $response['data'])) {
			error_log('getNbResults error: cant find raw item 0');
		} else if(is_null($response['data'][0])) {
			error_log('getNbResults error: The returned raw is null.');
		} else if(!array_key_exists("nb_rows", $response['data'][0])) {
			error_log('getNbResults error: cant find nb_rows.');
		} else if(!is_numeric($response['data'][0]['nb_rows'])) {
			error_log('getNbResults error: The returned value is not a number.');
		} else {
			$response['success'] = true;
			$response['data'] = (int)($response['data'][0]['nb_rows']);
			$response['msg'] = 'The service returned ' . ($response['data'] == 0 ? 'no' : $response['data']) . ' result' . ($response['data'] > 1 ? 's' : '') . ' for the given query.';
		}
8c2fa14d   Nathanael Jourdane   Update services g...
144
	}
50dd7220   Nathanael Jourdane   epntap.php works ...
145
	return $response;
49401187   Nathanael Jourdane   epntap: Do not us...
146
147
}

d6674d39   Nathanael Jourdane   Add error and inf...
148
function getGranules() {
a5475297   Nathanael Jourdane   use a hash for me...
149
150
151
	$sort = is_null(getParam('sort')) ? '' : "ORDER BY " . getParam('sort') . " " . getParam('dir');
	$filter = createFilter(getParam('targetName'), getParam('productTypes'), getParam('timeMin'), getParam('timeMax'));
	$query = "SELECT TOP " . getParam('limit') . " * FROM " . getParam('tableName') . " $filter $sort OFFSET " . getParam('start');
a8a12768   Nathanael Jourdane   Create the grid m...
152
	// error_log('getGranules query: ' . $query);
a5475297   Nathanael Jourdane   use a hash for me...
153
	$response = request(getParam('url'), $query);
50dd7220   Nathanael Jourdane   epntap.php works ...
154
	if($response['success']) {
f82d19f1   Nathanael Jourdane   Display granules ...
155
156
157
158
159
		$visibleColumns = ['granule_gid', 'obs_id', 'dataproduct_type', 'time_min', 'time_max', 'instrument_name', 'processing_level', 'access_estsize', 'thumbnail_url', 'access_url']; // rest are hidden
		$names = ['granule_gid' => 'GID', 'dataproduct_type' => 'Type', 'processing_level' => 'Proc. lvl', 'access_estsize' => 'Size', 'access_url' => 'URL']; // default: pretty printed key name
		$renderers = ['dataproduct_type' => 'type', 'time_min' => 'date', 'time_max' => 'date', 'processing_level' => 'proc_lvl',
			'access_estsize' => 'size', 'thumbnail_url' => 'img', 'access_url' => 'link', 'access_format' => 'format']; // default: text
		$widths = ['obs_id' => 75, 'time_min' => 75, 'time_max' => 75, 'instrument_name' => 75, 'processing_level' => 60]; // default: 50
50dd7220   Nathanael Jourdane   epntap.php works ...
160
161
162
163

		$fields = array();
		$columns = array();
		foreach($response['data'][0] as $key => $value) {
50dd7220   Nathanael Jourdane   epntap.php works ...
164
165
166
167
			$fields[] = ['name' => $key, 'type' => 'string'];
			$columns[] = [
				'dataIndex' => $key,
				'text' => array_key_exists($key, $names) ? $names[$key] : ucfirst(str_replace('_', ' ', $key)),
f82d19f1   Nathanael Jourdane   Display granules ...
168
				'width' => array_key_exists($key, $widths) ? $widths[$key] : 50,
50dd7220   Nathanael Jourdane   epntap.php works ...
169
				'hidden' => !in_array($key, $visibleColumns),
a5475297   Nathanael Jourdane   use a hash for me...
170
171
				'filterable' => true,
				// 'filter' => ['type' => 'list', 'options' => ['Image', 'Map']],
465b7a40   Nathanael Jourdane   Escape quotes in ...
172
				'renderer' => 'granule.' . (array_key_exists($key, $renderers) ? $renderers[$key] : 'text')
50dd7220   Nathanael Jourdane   epntap.php works ...
173
174
			];
		}
a8a12768   Nathanael Jourdane   Create the grid m...
175

a5475297   Nathanael Jourdane   use a hash for me...
176
		$response['total'] = (int)getParam('nbRes');
50dd7220   Nathanael Jourdane   epntap.php works ...
177
178
		$response['metaData']['fields'] = $fields;
		$response['metaData']['columns'] = $columns;
a5475297   Nathanael Jourdane   use a hash for me...
179
		$response['metaData']['metaHash'] = md5(serialize($response['metaData']));
50dd7220   Nathanael Jourdane   epntap.php works ...
180
181
	}
	return $response;
d6674d39   Nathanael Jourdane   Add error and inf...
182
183
}

8c2fa14d   Nathanael Jourdane   Update services g...
184
185
// ----- utils -----

8c2fa14d   Nathanael Jourdane   Update services g...
186
187
188
189
190
191
192
193
194
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) {
e4785141   Nathanael Jourdane   Fix date filter i...
195
		array_push($filter, "time_max >= " . dateToJD($timeMin));
8c2fa14d   Nathanael Jourdane   Update services g...
196
197
	}
	if($timeMax) {
e4785141   Nathanael Jourdane   Fix date filter i...
198
		array_push($filter, "time_min <= " . dateToJD($timeMax));
8c2fa14d   Nathanael Jourdane   Update services g...
199
200
201
202
203
204
205
206
207
208
209
210
211
	}
	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);
}
8a0f1e9e   Nathanael Jourdane   Add autocompletio...
212
?>