Blame view

php/classes/VOTableMgr.php 16.3 KB
16035364   Benjamin Renard   First commit
1
2
3
<?php
/**
 * @class VOTableMgr
f534c4a8   Nathanael Jourdane   Make the VOTable ...
4
 * @version $Id: VOTableMgr.php 2916 2015-05-19 13:08:33Z elena $
16035364   Benjamin Renard   First commit
5
6
 */

8e8f453c   Nathanael Jourdane   VOTable parser: r...
7
8
//set DEBUG_MODE to TRUE to have some log information
define("DEBUG_MODE", FALSE);
16035364   Benjamin Renard   First commit
9
10

class VOTableMgr {
5de62950   Nathanael Jourdane   Improve the VOTab...
11
12
13
14
	private $xml, $xp;
	private $logVotable; // The log file.
	private $stream; // The stream in the VOTable
	private $c; // Current character position on the stream
e581690d   Nathanael Jourdane   Fix VOtable conve...
15
	private $is_little_endian;
b97c59e9   Nathanael Jourdane   Provide to the us...
16
	private $votable_error = false;
5de62950   Nathanael Jourdane   Improve the VOTab...
17

f534c4a8   Nathanael Jourdane   Make the VOTable ...
18
	function load($fileName) {
8e8f453c   Nathanael Jourdane   VOTable parser: r...
19
		// error_log("Loading " . $fileName);
e581690d   Nathanael Jourdane   Fix VOtable conve...
20
		$this->is_little_endian = array_values(unpack('L1L', pack('V', 1)))[0] == 1;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
21
22

		// see http://php.net/manual/en/domdocument.load.php#91384
b97c59e9   Nathanael Jourdane   Provide to the us...
23
24
25
26
		$options = array(
			'http' => array(
				'method' => 'GET',
				'timeout' => '5',
8e8f453c   Nathanael Jourdane   VOTable parser: r...
27
28
29
				'user_agent' => 'PHP libxml agent',
				// If the query is wrong, epn-tap service returns an HTTP error code 400, along with xml containing some usefull informations.
				'ignore_errors' => true
b97c59e9   Nathanael Jourdane   Provide to the us...
30
			)
f534c4a8   Nathanael Jourdane   Make the VOTable ...
31
		);
b97c59e9   Nathanael Jourdane   Provide to the us...
32
		$context = stream_context_create($options);
f534c4a8   Nathanael Jourdane   Make the VOTable ...
33
		libxml_set_streams_context($context);
f534c4a8   Nathanael Jourdane   Make the VOTable ...
34
		$this->xml = new DomDocument();
5de62950   Nathanael Jourdane   Improve the VOTab...
35

8e8f453c   Nathanael Jourdane   VOTable parser: r...
36
		try {
8d5016bc   Nathanael Jourdane   bugFix: do not us...
37
			$load_res = $this->xml->load($fileName);
8e8f453c   Nathanael Jourdane   VOTable parser: r...
38
39
		} catch (Exception $e) {
			$this->votable_error = $e->message;
5de62950   Nathanael Jourdane   Improve the VOTab...
40
			return false;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
41
42
43
		}

		$this->checkIDAttribute();
f534c4a8   Nathanael Jourdane   Make the VOTable ...
44
45
46
47
48

		$rootNamespace = $this->xml->lookupNamespaceUri($this->xml->namespaceURI);
		$this->xp = new domxpath($this->xml);
		$this->xp->registerNameSpace('x', $rootNamespace);

f534c4a8   Nathanael Jourdane   Make the VOTable ...
49
50
51
		return true;
	}

b97c59e9   Nathanael Jourdane   Provide to the us...
52
53
54
55
56
57
	function getVotableError() {
		return $this->votable_error;
	}

	function isValidSchema() {
		if ($this->votable_error != false) {
b97c59e9   Nathanael Jourdane   Provide to the us...
58
59
60
61
62
			return false;
		}

		if (!$this->xml) {
			$this->votable_error = "The returned file is not XML.";
b97c59e9   Nathanael Jourdane   Provide to the us...
63
64
			return false;
		}
5de62950   Nathanael Jourdane   Improve the VOTab...
65
66
67
68

		$infos = $this->xp->query($this->queryResourceInfo());
		foreach($infos as $info) {
			if($info->getAttribute('value') == 'ERROR') {
b97c59e9   Nathanael Jourdane   Provide to the us...
69
				$this->votable_error = $info->textContent;
b97c59e9   Nathanael Jourdane   Provide to the us...
70
				return false;
5de62950   Nathanael Jourdane   Improve the VOTab...
71
72
73
74
			}
		}

		//ToDo - BRE - add validation!!
b97c59e9   Nathanael Jourdane   Provide to the us...
75
		return true;
5de62950   Nathanael Jourdane   Improve the VOTab...
76
77
78
79
80

		 if (DEBUG_MODE)
			 libxml_use_internal_errors(true);

		 $vers = $this->getVersion();
5de62950   Nathanael Jourdane   Improve the VOTab...
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
		 $result = FALSE;

		 switch ($vers)
		 {
		 	 case '1.2' :
		 	 	 $result = $this->xml->schemaValidate(XMLPATH.'VOTable-1.2.xsd');
		 	 case '1.0' :
		 	 	 $result = $this->xml->schemaValidate(XMLPATH.'VOTable-1.0.xsd');
		 	 default :
		 		 $result = $this->xml->schemaValidate(XMLPATH.'VOTable-1.1.xsd');
		 }

		 if (DEBUG_MODE)
		 {
			 $errors = libxml_get_errors();

			 foreach ($errors as $error)
			 {
			 	 $msg = '';

				switch ($error->level)
				{
					case LIBXML_ERR_WARNING:
						$msg .= ("WARNING ".$error->code.": ");
						break;
					case LIBXML_ERR_ERROR:
						$msg .= ("ERROR ".$error->code.": ");
						break;
					case LIBXML_ERR_FATAL:
						$msg .= ("FATAL ".$error->code.": ");
						break;
				}
				$msg .= ($error->message." - In line : ".$error->line." - Of file : ".$error->file."\n");
8e8f453c   Nathanael Jourdane   VOTable parser: r...
114
				error_log($msg);
5de62950   Nathanael Jourdane   Improve the VOTab...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
			 }

			 libxml_use_internal_errors(false);
		 }

		return $result;
	}

	protected function queryResource()
	{
		 return "//x:RESOURCE";
	}

	protected function queryResourceInfo()
	{
		return $this->queryResource()."/x:INFO";
	}

	protected function queryTable()
	{
		 return $this->queryResource()."/x:TABLE";
	}

	protected function queryDescription()
	{
		 return $this->queryTable()."/x:DESCRIPTION";
	}

	protected function queryFields()
	{
		 return $this->queryTable()."/x:FIELD";
	}

	protected function queryField($field_id)
	{
		 return $this->queryFields()."[@ID='".$field_id."']";
	}

	protected function queryFieldByName($field_id)
	{
		 return $this->queryFields()."[@name='".$field_id."']";
	}
	protected function queryFieldDescription($field_id)
	{
		 return $this->queryField($field_id)."/x:DESCRIPTION";
	}

	protected function queryData()
	{
		 return $this->queryTable()."/x:DATA";
	}

	protected function queryTableData()
	{
		 return $this->queryData()."/x:TABLEDATA";
	}

	protected function queryTR()
	{
		 return $this->queryTableData()."/x:TR";
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
176
177
178
179
180
181
182
183
184
185

	protected function queryBinaryData() {
		return $this->queryData()."/x:BINARY";
	}

	protected function queryStream() {
		return $this->queryBinaryData()."/x:STREAM";
	}


5de62950   Nathanael Jourdane   Improve the VOTab...
186
187
188
189
190
	public function getVersion()
	{
		 if (!$this->xml)
		 		return '';
		 $root = $this->xml->documentElement;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
191

5de62950   Nathanael Jourdane   Improve the VOTab...
192
193
		 return $root->getAttribute('version');
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
194

5de62950   Nathanael Jourdane   Improve the VOTab...
195
196
197
198
	public function getDescription()
	{
		 if (!$this->xp)
			 return '';
f534c4a8   Nathanael Jourdane   Make the VOTable ...
199

5de62950   Nathanael Jourdane   Improve the VOTab...
200
		 $desc = $this->xp->query($this->queryDescription());
f534c4a8   Nathanael Jourdane   Make the VOTable ...
201

5de62950   Nathanael Jourdane   Improve the VOTab...
202
203
		 if ($desc->length < 1)
			 return '';
f534c4a8   Nathanael Jourdane   Make the VOTable ...
204

5de62950   Nathanael Jourdane   Improve the VOTab...
205
206
207
		 return $desc->item(0)->nodeValue;
	}

e581690d   Nathanael Jourdane   Fix VOtable conve...
208
209
210
211
212
213
214
215
	private function get_row_size($field_node) {
		$datatype = $field_node->getAttribute("datatype");

		if($datatype == 'boolean') {
			return 1;
		}

		switch($datatype) {
5de62950   Nathanael Jourdane   Improve the VOTab...
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
			case 'unsignedByte':
			case 'char':
				$block_size = 1;
				break;
			case 'unicodeChar':
			case 'short':
				$block_size = 2;
				break;
			case 'int':
			case 'float':
				$block_size = 4;
				break;
			case 'long':
			case 'double':
			case 'float_complex':
				$block_size = 8;
				break;
			case 'double_complex':
e581690d   Nathanael Jourdane   Fix VOtable conve...
234
				$block_size = 16;
5de62950   Nathanael Jourdane   Improve the VOTab...
235
236
237
238
			default:
				$block_size = 0;
				break;
		}
5de62950   Nathanael Jourdane   Improve the VOTab...
239

5de62950   Nathanael Jourdane   Improve the VOTab...
240
241
242
		if($field_node->getAttribute("arraysize") == NULL) {
			$array_size = $block_size;
		} else if("*" == $field_node->getAttribute("arraysize")) {
5de62950   Nathanael Jourdane   Improve the VOTab...
243
			$array_size = unpack("Ns", substr($this->stream, $this->c, 4))["s"] * $block_size;
5de62950   Nathanael Jourdane   Improve the VOTab...
244
245
246
247
248
249
			$this->c+=4;
		} else {
			$array_size = (int)($field_node->getAttribute("arraysize")) * $block_size;
		}
		return $array_size;
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
250
251

	/** Get the VOTable stream content.*/
5de62950   Nathanael Jourdane   Improve the VOTab...
252
	public function parseStream() {
b97c59e9   Nathanael Jourdane   Provide to the us...
253
		if (! $this->isValidSchema()) {
8d5016bc   Nathanael Jourdane   bugFix: do not us...
254
			error_log('There is an error on the VOTable: ' . $this->votable_error);
b97c59e9   Nathanael Jourdane   Provide to the us...
255
			return null;
b97c59e9   Nathanael Jourdane   Provide to the us...
256
		}
5de62950   Nathanael Jourdane   Improve the VOTab...
257
258
		$data = Array();
		$fields = $this->xp->query($this->queryFields());
8d5016bc   Nathanael Jourdane   bugFix: do not us...
259
		$resource = $this->xp->query($this->queryResource());
5de62950   Nathanael Jourdane   Improve the VOTab...
260
261
262
263
264
		$nb_columns = $fields->length;
		$row = Array();
		$n_value = 0; // index of current value
		$this->c = 0; // initialize cursor position.
		$query_stream = $this->xp->query($this->queryStream())->item(0);
b97c59e9   Nathanael Jourdane   Provide to the us...
265
266
		if($query_stream == NULL) {
			$this->votable_error = "There is no STREAM node in the VOTable file.";
8d5016bc   Nathanael Jourdane   bugFix: do not us...
267
			return null;
b97c59e9   Nathanael Jourdane   Provide to the us...
268
		}
5de62950   Nathanael Jourdane   Improve the VOTab...
269
		$this->stream = base64_decode($query_stream->textContent);
5de62950   Nathanael Jourdane   Improve the VOTab...
270
		$stream_len = strlen($this->stream);
b97c59e9   Nathanael Jourdane   Provide to the us...
271
272
		if($stream_len == 0) {
			$this->votable_error = "There is no result for this query.";
8d5016bc   Nathanael Jourdane   bugFix: do not us...
273
			return null;
b97c59e9   Nathanael Jourdane   Provide to the us...
274
		}
5de62950   Nathanael Jourdane   Improve the VOTab...
275
276
277
278
		while($this->c < strlen($this->stream)) {
			$col_id = $n_value % $nb_columns;
			$field_node = $fields[$col_id];

5de62950   Nathanael Jourdane   Improve the VOTab...
279
280
281
282
283
284
			if($col_id == 0) {
				$row = Array();
			}
			$row[$field_node->getAttribute("ID")] = $this->process_datablock($field_node);
			if($col_id == $nb_columns-1) {
				array_push($data, $row);
f534c4a8   Nathanael Jourdane   Make the VOTable ...
285
			}
5de62950   Nathanael Jourdane   Improve the VOTab...
286
			$n_value+=1;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
287
		}
5de62950   Nathanael Jourdane   Improve the VOTab...
288
289
		return $data;
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
290

e581690d   Nathanael Jourdane   Fix VOtable conve...
291
292
293
294
295
	private function JDTodate($jd) {
		list($month, $day, $year) = split('/', JDToGregorian($jd));
		return "$day/$month/$year";
	}

5de62950   Nathanael Jourdane   Improve the VOTab...
296
297
298
	private function process_datablock($field_node) {
		$data_type = $field_node->getAttribute("datatype");
		$row_size = $this->get_row_size($field_node);
e581690d   Nathanael Jourdane   Fix VOtable conve...
299
300
		$substr = substr($this->stream, $this->c, $row_size);

5de62950   Nathanael Jourdane   Improve the VOTab...
301
302
303
		switch ($data_type) {
			case 'boolean':
			case 'unsignedByte':
e581690d   Nathanael Jourdane   Fix VOtable conve...
304
305
				$b = $substr;
				$res = $b == "T" || $b == "t" || $b == "1";
5de62950   Nathanael Jourdane   Improve the VOTab...
306
307
				break;
			case 'char':
e461c01f   Nathanael Jourdane   Improve VOTable p...
308
				$res = $row_size!=0 ? utf8_encode($substr) : NULL;
5de62950   Nathanael Jourdane   Improve the VOTab...
309
			case 'unicodeChar':
e461c01f   Nathanael Jourdane   Improve VOTable p...
310
				$res = $row_size!=0 ? utf8_encode(str_replace("\0", "", $substr)) : NULL;
5de62950   Nathanael Jourdane   Improve the VOTab...
311
312
				break;
			case 'short':
e581690d   Nathanael Jourdane   Fix VOtable conve...
313
				$res = unpack("ss", $substr)["s"];
5de62950   Nathanael Jourdane   Improve the VOTab...
314
315
				break;
			case 'int':
e581690d   Nathanael Jourdane   Fix VOtable conve...
316
				$res = unpack("Ns", $substr)["s"];
5de62950   Nathanael Jourdane   Improve the VOTab...
317
318
				break;
			case 'long':
e581690d   Nathanael Jourdane   Fix VOtable conve...
319
				$res = unpack("Js", $substr)["s"];  // /!\ J -> PHP 5.6 only
5de62950   Nathanael Jourdane   Improve the VOTab...
320
321
				break;
			case 'float':
e581690d   Nathanael Jourdane   Fix VOtable conve...
322
323
324
325
326
327
				$res = unpack("fs", $substr)["s"];

				// If machine is little endian:
				if($this->is_little_endian) {
					$res = unpack('f1f', strrev(pack('f', $res)))["f"];
				}
5de62950   Nathanael Jourdane   Improve the VOTab...
328
329
				break;
			case 'double':
e581690d   Nathanael Jourdane   Fix VOtable conve...
330
331
332
333
334
335
				$res = unpack("ds", $substr)["s"];

				// If machine is little endian:
				if($this->is_little_endian) {
					$res = unpack('d1d', strrev(pack('d', $res)))["d"];
				}
5de62950   Nathanael Jourdane   Improve the VOTab...
336
337
338
				break;
			default:
				$res = NULL;
8e8f453c   Nathanael Jourdane   VOTable parser: r...
339
				error_log("Unknown character: $data_type");
5de62950   Nathanael Jourdane   Improve the VOTab...
340
341
342
				break;
		}
		$this->c+=$row_size;
8d5016bc   Nathanael Jourdane   bugFix: do not us...
343
		return (string)$res;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
344
345
	}

f534c4a8   Nathanael Jourdane   Make the VOTable ...
346

5de62950   Nathanael Jourdane   Improve the VOTab...
347
348
349
350
	public function getFirstTR()
	{
		 if (!$this->xp)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
351

5de62950   Nathanael Jourdane   Improve the VOTab...
352
		 /*$trs = $this->xp->query($this->queryTR());
f534c4a8   Nathanael Jourdane   Make the VOTable ...
353

5de62950   Nathanael Jourdane   Improve the VOTab...
354
355
		 if ($trs->length < 1)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
356

5de62950   Nathanael Jourdane   Improve the VOTab...
357
		 return $trs->item(0);*/
f534c4a8   Nathanael Jourdane   Make the VOTable ...
358

5de62950   Nathanael Jourdane   Improve the VOTab...
359
360
361
		$tabledatas = $this->xp->query($this->queryTableData());
		 if ($tabledatas->length < 1)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
362

5de62950   Nathanael Jourdane   Improve the VOTab...
363
		 $tabledata = $tabledatas->item(0);
f534c4a8   Nathanael Jourdane   Make the VOTable ...
364

5de62950   Nathanael Jourdane   Improve the VOTab...
365
		 $node = $tabledata->firstChild;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
366

5de62950   Nathanael Jourdane   Improve the VOTab...
367
368
		 while($node && ($node->nodeType != 1) && ($node->nodeName != "TR"))
			$node = $node->nextSibling;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
369

5de62950   Nathanael Jourdane   Improve the VOTab...
370
371
372
373
374
375
376
		return $node;
	}

	public function getNextTR($tr)
	{
		 if (!$this->xp)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
377

5de62950   Nathanael Jourdane   Improve the VOTab...
378
379
		while($tr->nextSibling && ($tr->nextSibling->nodeType != 1) && ($node->nodeName != "TR"))
			$tr = $tr->nextSibling;
16035364   Benjamin Renard   First commit
380
				return $tr->nextSibling;
5de62950   Nathanael Jourdane   Improve the VOTab...
381
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
382

5de62950   Nathanael Jourdane   Improve the VOTab...
383
384
385
386
	public function getTDValueByFieldIndex($tr,$field_index)
	{
		 if (!$this->xp)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
387

5de62950   Nathanael Jourdane   Improve the VOTab...
388
		 $tds = $tr->getElementsByTagName("TD");
f534c4a8   Nathanael Jourdane   Make the VOTable ...
389

5de62950   Nathanael Jourdane   Improve the VOTab...
390
391
		 if (($tds->length < 1) || ($field_index >= $tds->length))
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
392

5de62950   Nathanael Jourdane   Improve the VOTab...
393
394
		 return $tds->item($field_index)->nodeValue;
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
395

5de62950   Nathanael Jourdane   Improve the VOTab...
396
397
398
399
	protected function isTimeField($field)
	{
		if (!$this->xp)
			 return FALSE;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
400

5de62950   Nathanael Jourdane   Improve the VOTab...
401
402
		 return (($field->getAttribute("ucd") == "time.epoch") && ($field->getAttribute("xtype") == "dateTime"));
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
403

5de62950   Nathanael Jourdane   Improve the VOTab...
404
405
406
407
	public function getTimeFieldIndex()
	{
		 if (!$this->xp)
			 return -1;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
408

5de62950   Nathanael Jourdane   Improve the VOTab...
409
		 $fields = $this->xp->query($this->queryFields());
f534c4a8   Nathanael Jourdane   Make the VOTable ...
410

5de62950   Nathanael Jourdane   Improve the VOTab...
411
412
		 if ($fields->length < 1)
			 return -1;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
413

5de62950   Nathanael Jourdane   Improve the VOTab...
414
415
416
		 for ($i = 0; $i < $fields->length; $i++)
			 if ($this->isTimeField($fields->item($i)))
				 return $i;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
417

5de62950   Nathanael Jourdane   Improve the VOTab...
418
419
		 return -1;
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
420

5de62950   Nathanael Jourdane   Improve the VOTab...
421
422
423
424
	protected function getFieldByID($field_id)
	{
		 if (!$this->xp)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
425

5de62950   Nathanael Jourdane   Improve the VOTab...
426
		 $fields = $this->xp->query($this->queryFields());
f534c4a8   Nathanael Jourdane   Make the VOTable ...
427

5de62950   Nathanael Jourdane   Improve the VOTab...
428
429
		 if ($fields->length < 1)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
430

5de62950   Nathanael Jourdane   Improve the VOTab...
431
432
433
		 foreach ($fields as $field)
			 if ($field->getAttribute("ID") == $field_id)
				 return $field;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
434

5de62950   Nathanael Jourdane   Improve the VOTab...
435
436
		 return NULL;
	}
16035364   Benjamin Renard   First commit
437

5de62950   Nathanael Jourdane   Improve the VOTab...
438
439
440
441
		protected function getFieldByName($field_id)
	{
		 if (!$this->xp)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
442

5de62950   Nathanael Jourdane   Improve the VOTab...
443
		 $fields = $this->xp->query($this->queryFieldByName($field_id));
f534c4a8   Nathanael Jourdane   Make the VOTable ...
444

5de62950   Nathanael Jourdane   Improve the VOTab...
445
446
		 if ($fields->length < 1)
			 return NULL;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
447

5de62950   Nathanael Jourdane   Improve the VOTab...
448
449
450
		 foreach ($fields as $field)
			 if ($field->getAttribute("name") == $field_id)
				 return $field;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
451

5de62950   Nathanael Jourdane   Improve the VOTab...
452
453
		 return NULL;
	}
16035364   Benjamin Renard   First commit
454

5de62950   Nathanael Jourdane   Improve the VOTab...
455
	protected function checkIDAttribute(){
16035364   Benjamin Renard   First commit
456

5de62950   Nathanael Jourdane   Improve the VOTab...
457
458
459
			$fields = $this->xml->getElementsByTagName('FIELD');
			$i = 0;
			foreach ($fields as $field){
16035364   Benjamin Renard   First commit
460
461
	$i++;
	if (!$field->hasAttribute("ID")){
5de62950   Nathanael Jourdane   Improve the VOTab...
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
			$field->setAttribute("ID", "col".$i);
	}
			}
			$this->xml->saveXML();

	}

	public function getFieldIndexByID($field_id)
	{
		 if (!$this->xp)
			 return -1;

		 $fields = $this->xp->query($this->queryFields());

		 if ($fields->length < 1)
			 return -1;

		 for ($i = 0; $i < $fields->length; $i++)
			 if ($fields->item($i)->getAttribute("ID") == $field_id)
				 return $i;

		 return -1;
	}

	public function getStartStop()
	{
		 if (!$this->xp)
			 return '0 0';

		$timeIndex = $this->getTimeFieldIndex();
		if ($timeIndex < 0)
			return '0 0';

		$tr = $this->getFirstTR();

		if (!$tr)
			return '0 0';

		$start = $this->getTDValueByFieldIndex($tr,$timeIndex);

		$stop = $start;
		while ($tr)
		{
			$stop = $this->getTDValueByFieldIndex($tr,$timeIndex);
			$tr = $this->getNextTR($tr);
		}

		if (!$start)
			$start = 0;
		else
			$start = strtotime($start);

		if (!$stop)
			$stop = 0;
		else
			$stop = strtotime($stop);

		return $start." ".$stop;
	}

	public function getFieldInfoByID($field_id)
	{
	 if (!$this->xp)
			 return array("id"		=> $field_id,
										"error" => "No file loaded");

								 $field = $this->getFieldByID($field_id);

		 if (!$field)
			$field = $this->getFieldByName($field_id);

		 if (!$field)
			 return array("id"		=> $field_id,
										"error" => "This field doesn't exist");
		 return $this->getFieldInfo($field);
	}


	public function getFieldInfo($field)
	{
		if (!$this->xp)
			return array("id"		=> $field_id,
			"error" => "No file loaded");
		$description = '';
		$desc = $field->getElementsByTagName("DESCRIPTION");
		if ($desc->length >= 1)
			$description = $desc->item(0)->nodeValue;

		$size = $field->getAttribute("arraysize");
		if ($size == '')
			$size = 1;
		else
			$size = intval($size);

		switch ($field->getAttribute("datatype"))
		{
			 case "short" :
			 	 $type = "SHORT";
			 	 break;
			 case "int" :
			 	 $type = "INTEGER";
			 	 break;
			 case "long"	 :
			 case "double" :
				 $type = "DOUBLE";
				 break;
			 default :
					$type = "FLOAT";
		}
16035364   Benjamin Renard   First commit
571
	if (!$field->getAttribute("ID"))
5de62950   Nathanael Jourdane   Improve the VOTab...
572
		$id = "col".$n;
16035364   Benjamin Renard   First commit
573
	else $id = $field->getAttribute("ID");
f534c4a8   Nathanael Jourdane   Make the VOTable ...
574

5de62950   Nathanael Jourdane   Improve the VOTab...
575
576
577
578
579
580
581
582
583
		 return array("id"		 => $field->getAttribute("ID"),
								 "type"				=> $type,
								 "name"				=> $field->getAttribute("name"),
								 "ucd"				 => $field->getAttribute("ucd"),
								 "unit"				=> $field->getAttribute("unit"),
								 "size"				=> $size,
								 "description" => $description
								);
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
584

5de62950   Nathanael Jourdane   Improve the VOTab...
585
586
587
588
	public function getFieldsInfo()
	{
	 	 if (!$this->xp)
			 return array("error" => "No file loaded");
f534c4a8   Nathanael Jourdane   Make the VOTable ...
589

5de62950   Nathanael Jourdane   Improve the VOTab...
590
		$fields_info = array();
f534c4a8   Nathanael Jourdane   Make the VOTable ...
591

5de62950   Nathanael Jourdane   Improve the VOTab...
592
		 $fields = $this->xp->query($this->queryFields());
f534c4a8   Nathanael Jourdane   Make the VOTable ...
593

5de62950   Nathanael Jourdane   Improve the VOTab...
594
595
		 if ($fields->length < 1)
			 return $fields_info;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
596

5de62950   Nathanael Jourdane   Improve the VOTab...
597
598
599
600
		foreach ($fields as $field)
		{
		 	if ($this->isTimeField($field))
				continue;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
601

5de62950   Nathanael Jourdane   Improve the VOTab...
602
603
			array_push($fields_info,$this->getFieldInfo($field));
		}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
604

5de62950   Nathanael Jourdane   Improve the VOTab...
605
606
		return $fields_info;
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
607

5de62950   Nathanael Jourdane   Improve the VOTab...
608
609
610
611
612
	public function getSamplings()
	{
		 if (!$this->xp)
			 return array("minSampling" => 0,
									 "maxSampling" => 0);
f534c4a8   Nathanael Jourdane   Make the VOTable ...
613

5de62950   Nathanael Jourdane   Improve the VOTab...
614
615
616
617
		 $timeIndex = $this->getTimeFieldIndex();
		if ($timeIndex < 0)
			return array("minSampling" => 0,
									 "maxSampling" => 0);
16035364   Benjamin Renard   First commit
618

5de62950   Nathanael Jourdane   Improve the VOTab...
619
		$tr = $this->getFirstTR();
16035364   Benjamin Renard   First commit
620

5de62950   Nathanael Jourdane   Improve the VOTab...
621
622
623
		if (!$tr)
			return array("minSampling" => 0,
									 "maxSampling" => 0);
f534c4a8   Nathanael Jourdane   Make the VOTable ...
624

5de62950   Nathanael Jourdane   Improve the VOTab...
625
626
627
628
629
630
631
632
633
634
635
636
		$prevTime = 0;
		while ($tr)
		{
			$time = $this->getTDValueByFieldIndex($tr,$timeIndex);

			if ($time)
			{
				$time = strtotime($time);
				if (($prevTime > 0) && ($time-$prevTime > 0))
					$deltaT[$time-$prevTime]++;
				$prevTime = $time;
			}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
637

5de62950   Nathanael Jourdane   Improve the VOTab...
638
639
			$tr = $this->getNextTR($tr);
		}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
640

5de62950   Nathanael Jourdane   Improve the VOTab...
641
642
		$minSampling = +1.e31;
		$maxSampling = 0.0;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
643

5de62950   Nathanael Jourdane   Improve the VOTab...
644
645
		foreach ($deltaT as $key => $value)
		{
f534c4a8   Nathanael Jourdane   Make the VOTable ...
646

5de62950   Nathanael Jourdane   Improve the VOTab...
647
648
		 if ($value/count($deltaT) < 0.10)
				continue;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
649

5de62950   Nathanael Jourdane   Improve the VOTab...
650
651
652
			if ($key < $minSampling) $minSampling = $key;
			if ($key > $maxSampling) $maxSampling = $key;
		}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
653

5de62950   Nathanael Jourdane   Improve the VOTab...
654
655
656
		return array("minSampling" => $minSampling,
								 "maxSampling" => $maxSampling);
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
657

5de62950   Nathanael Jourdane   Improve the VOTab...
658
	public function args2vector($file, $paramID){
16035364   Benjamin Renard   First commit
659

5de62950   Nathanael Jourdane   Improve the VOTab...
660
	$argsArr = explode('_', $paramID);
16035364   Benjamin Renard   First commit
661

5de62950   Nathanael Jourdane   Improve the VOTab...
662
663
664
665
666
667
668
	$dom = new DOMDocument();
	$dom->load($file);
	$fields = $dom->getElementsByTagName('FIELD');
	$table = $dom->getElementsByTagName('TABLE')->item(0);
	$i=0;
	foreach ($fields as $field){
			if ($field->getAttribute('name') == $argsArr[0]){
16035364   Benjamin Renard   First commit
669
	$unit = $field->getAttribute('unit');
5de62950   Nathanael Jourdane   Improve the VOTab...
670
671
	$ucd	= $field->getAttribute('ucd');
	$datatype	= $field->getAttribute('datatype');
16035364   Benjamin Renard   First commit
672
	$firstTD = $i;
5de62950   Nathanael Jourdane   Improve the VOTab...
673
674
675
676
677
678
679
680
681
682
		}
		$i++;
	}
	if ($firstTD > 0){
		$table->removeChild($fields->item($firstTD + 2));
		$table->removeChild($fields->item($firstTD + 1));
		$table->removeChild($fields->item($firstTD));

		$i = 0;
		foreach ($fields as $field){
16035364   Benjamin Renard   First commit
683
	$i++;
f534c4a8   Nathanael Jourdane   Make the VOTable ...
684
	if (strpos($field->getAttribute('ID'),'col') !== FALSE){
5de62950   Nathanael Jourdane   Improve the VOTab...
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
			$field->setAttribute('ID', 'col'.$i);
			$dom->saveXML();
	}
		}

		$group = $dom->createElement('GROUP');
		$group->appendChild(new DOMAttr('ID', 'info_'.$paramID));
		$table->appendChild($group);

		$param = $dom->createElement('PARAM');
		$param->appendChild(new DOMAttr('ID', 'components_'.$paramID));
		$param->appendChild(new DOMAttr('name', 'components_'.$paramID));
		$param->appendChild(new DOMAttr('datatype', 'char'));
		$param->appendChild(new DOMAttr('arraysize', '*'));
		$param->appendChild(new DOMAttr('value', $argsArr[0].' '.$argsArr[1].' '.$argsArr[2] ));
		$group->appendChild($param);

		$new_field = $dom->createElement('FIELD');
		$new_field->appendChild(new DOMAttr('ID', $paramID));
		$new_field->appendChild(new DOMAttr('name', $paramID));
		$new_field->appendChild(new DOMAttr('datatype', $datatype));
		$new_field->appendChild(new DOMAttr('arraysize', '3'));
		$new_field->appendChild(new DOMAttr('unit', $unit));
		$new_field->appendChild(new DOMAttr('ucd', $ucd));
		$new_field->appendChild(new DOMAttr('ref', 'info_'.$paramID));
		$table->appendChild($new_field);

		$trs = $dom->getElementsByTagName('TR');
		foreach($trs as $tr){
			$tds = $tr->getElementsByTagName('TD');
			$value = trim($tds->item($firstTD)->nodeValue).' '.trim($tds->item($firstTD + 1)->nodeValue).' '.trim($tds->item($firstTD + 2)->nodeValue);
			$toRemote	= $tds->item($firstTD);
			$tr->removeChild($toRemote);
			 $toRemote = $tds->item($firstTD);
			$tr->removeChild($toRemote);
			 $toRemote = $tds->item($firstTD);
			$tr->removeChild($toRemote);

			$td = $dom->createElement('TD', $value);
			$tr->appendChild($td);
		}

		$dom->save($file);
		}
	}
f534c4a8   Nathanael Jourdane   Make the VOTable ...
730

16035364   Benjamin Renard   First commit
731
732
733
734
}



f534c4a8   Nathanael Jourdane   Make the VOTable ...
735
?>