1
|
<?php
|
2
|
// $Id: cdm_api.php 1012 2007-12-05 17:58:45Z a.kohlbecker $
|
3
|
|
4
|
/**
|
5
|
* @file
|
6
|
* Functions which are required or useful when accessing and processing CDM Data Store Webservices
|
7
|
*
|
8
|
* Naming conventions:
|
9
|
* ----------------------
|
10
|
*
|
11
|
* - all webservice access methods are prefixed with cdm_ws
|
12
|
*
|
13
|
*
|
14
|
* Copyright (C) 2007 EDIT
|
15
|
* European Distributed Institute of Taxonomy
|
16
|
* http://www.e-taxonomy.eu
|
17
|
*
|
18
|
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
19
|
* See LICENSE.TXT at the top of this package for the full license terms.
|
20
|
*/
|
21
|
require_once ('xml2json.php');
|
22
|
|
23
|
// Taxon Relationship Types
|
24
|
define('UUID_TAXONOMICALLY_INCLUDED_IN', 'd13fecdf-eb44-4dd7-9244-26679c05df1c');
|
25
|
define('UUID_MISAPPLIED_NAME_FOR', '1ed87175-59dd-437e-959e-0d71583d8417');
|
26
|
define('UUID_INVALID_DESIGNATION_FOR', '605b1d01-f2b1-4544-b2e0-6f08def3d6ed');
|
27
|
define('UUID_CONTRADICTION', 'a8f03491-2ad6-4fae-a04c-2a4c117a2e9b');
|
28
|
define('UUID_CONGRUENT_TO', '60974c98-64ab-4574-bb5c-c110f6db634d');
|
29
|
define('UUID_INCLUDES', '0501c385-cab1-4fbe-b945-fc747419bb13');
|
30
|
define('UUID_OVERLAPS', '2046a0fd-4fd6-45a1-b707-2b91547f3ec7');
|
31
|
define('UUID_EXCLUDES', '4535a63c-4a3f-4d69-9350-7bf02e2c23be');
|
32
|
define('UUID_DOES_NOT_EXCLUDE', '0e5099bb-87c0-400e-abdc-bcfed5b5eece');
|
33
|
define('UUID_DOES_NOT_OVERLAP', 'ecd2382b-3d94-4169-9dd2-2c4ea1d24605');
|
34
|
define('UUID_NOT_INCLUDED_IN', '89dffa4e-e004-4d42-b0d1-ae1827529e43');
|
35
|
define('UUID_NOT_CONGRUENT_TO', '6c16c33b-cfc5-4a00-92bd-a9f9e448f389');
|
36
|
|
37
|
// Synonym Relationship Types
|
38
|
define('UUID_SYNONYM_OF', '1afa5429-095a-48da-8877-836fa4fe709e');
|
39
|
define('UUID_PRO_PARTE_SYNONYM_OF', '130b752d-2eff-4a62-a132-104ed8d13e5e');
|
40
|
define('UUID_PARTIAL_SYNONYM_OF', '8b0d1d34-cc00-47cb-999d-b67f98d1af6e');
|
41
|
define('UUID_HOMOTYPIC_SYNONYM_OF', '294313a9-5617-4ed5-ae2d-c57599907cb2');
|
42
|
define('UUID_HETEROTYPIC_SYNONYM_OF', '4c1e2c59-ca55-41ac-9a82-676894976084');
|
43
|
|
44
|
|
45
|
/**
|
46
|
* Converts an array of TagedText items into a sequence of corresponding html tags whereas
|
47
|
* each item will provided with a class attribute which set to the key of the TaggedText item.
|
48
|
*
|
49
|
* @param array $taggedtxt
|
50
|
* @param String $tag
|
51
|
* @param String $glue the string by which the chained text tokens are concatenated together.
|
52
|
* Default is a blak character
|
53
|
* @return String of HTML
|
54
|
*/
|
55
|
function cdm_taggedtext2html(array &$taggedtxt, $tag = 'span', $glue = ' '){
|
56
|
$out = '';
|
57
|
foreach($taggedtxt as $tt){
|
58
|
$out .= (strlen($out) > 0 ? $glue : '').'<'.$tag.' class="'.$tt->tag.'">'.$tt->text.'</'.$tag.'>';
|
59
|
}
|
60
|
return $out;
|
61
|
}
|
62
|
|
63
|
/**
|
64
|
* Finds the text tagged with $tagname in an array of taggedText instances
|
65
|
*
|
66
|
* @param array $taggedtxt
|
67
|
* @param string $tagname
|
68
|
* @return the text mapped by $tagname or an empty string
|
69
|
*/
|
70
|
function cdm_taggedtext_value(array &$taggedtxt = array(), $tagname){
|
71
|
foreach($taggedtxt as $tagtxt){
|
72
|
if($tagtxt->tag == $tagname)
|
73
|
return $tagtxt->text;
|
74
|
}
|
75
|
return '';
|
76
|
}
|
77
|
|
78
|
/**
|
79
|
* Searches the appay of LocalisedTermTO instances for an entry mapped with the language
|
80
|
* specified as parameter $language if existing. If not the term mapped with the $defauklt_language
|
81
|
* is returend otherwise the first term in $localised_terms is returned or fale if
|
82
|
* $localised_terms is empty.
|
83
|
*
|
84
|
*
|
85
|
* @param array $localised_terms
|
86
|
* @param string $language
|
87
|
* @param string $default_language
|
88
|
* @return string
|
89
|
*/
|
90
|
function cdm_get_localised_term($localised_terms, $language, $default_language = 'en'){
|
91
|
|
92
|
$default_term = (count($localised_terms) > 0 ? $localised_terms[0]->term : '') ;
|
93
|
|
94
|
foreach($localised_terms as $lt){
|
95
|
if($lt->language == $language){
|
96
|
return $lt->term;
|
97
|
}
|
98
|
if($lt->language == $default_language){
|
99
|
$default_term = $lt->term;
|
100
|
}
|
101
|
}
|
102
|
|
103
|
return $default_term;
|
104
|
}
|
105
|
|
106
|
/**
|
107
|
* Enter description here...
|
108
|
*
|
109
|
* @param unknown_type $uuid
|
110
|
*/
|
111
|
function cdm_localized_term_is($uuid){
|
112
|
|
113
|
}
|
114
|
|
115
|
/**
|
116
|
* Produces a path to a static web service stub out of a cdm web service path.
|
117
|
* These stubs are object serialisations stored in files whereas the filename
|
118
|
* consists of the service name and of a
|
119
|
* encoded version of the request query parameters
|
120
|
*
|
121
|
* @param string $path
|
122
|
* @param string $fileextension
|
123
|
* @return string
|
124
|
*/
|
125
|
function cdm_encode_stub($path, $fileextension){
|
126
|
return variable_get('cdm_webservice_type', 'xml').'/'.str_replace('&',',', str_replace('?',';',$path)).'.'.$fileextension;
|
127
|
}
|
128
|
|
129
|
/**
|
130
|
* Decodes a path to a static web service stub to turn it into a path
|
131
|
* suitable for a cdm web service
|
132
|
*
|
133
|
* @param string $path
|
134
|
* @return string
|
135
|
*/
|
136
|
function cdm_decode_stub($path){
|
137
|
|
138
|
// remove fileextension
|
139
|
$path = substr_replace($path, '', strrpos($path, '.'));
|
140
|
|
141
|
return str_replace(',','&', str_replace(';','?',$path));
|
142
|
}
|
143
|
|
144
|
/**
|
145
|
* Enter description here...
|
146
|
*
|
147
|
* @param unknown_type $file
|
148
|
* @param unknown_type $parameters
|
149
|
* @return unknown
|
150
|
*/
|
151
|
function cdm_compose_url($file, $parameters = array()){
|
152
|
$pstr = '';
|
153
|
foreach($parameters as $key=>$value){
|
154
|
$pstr .= ( strlen($pstr) == 0 ? '?' : '&').$key.'='.urlencode($value);
|
155
|
}
|
156
|
$file .= $pstr;
|
157
|
|
158
|
if(variable_get('cdm_webservice_isStub', 0)){
|
159
|
$file = cdm_encode_stub($file, variable_get('cdm_webservice_type', 'json'));
|
160
|
}
|
161
|
|
162
|
$url = variable_get('cdm_webservice_url', '').$file;
|
163
|
return $url;
|
164
|
}
|
165
|
|
166
|
/**
|
167
|
* Return string content from a remote file
|
168
|
*
|
169
|
* @param string $url
|
170
|
* @return string
|
171
|
*
|
172
|
* @author Luiz Miguel Axcar (lmaxcar@yahoo.com.br)
|
173
|
*/
|
174
|
function _get_content_curl($url)
|
175
|
{
|
176
|
$ch = curl_init();
|
177
|
|
178
|
curl_setopt ($ch, CURLOPT_URL, $url);
|
179
|
curl_setopt ($ch, CURLOPT_HEADER, 0);
|
180
|
|
181
|
ob_start();
|
182
|
|
183
|
curl_exec ($ch);
|
184
|
if(curl_errno($ch)){
|
185
|
watchdog('CDM', curl_error($ch).' URL: '.$url, WATCHDOG_ERROR);
|
186
|
}
|
187
|
curl_close ($ch);
|
188
|
$string = ob_get_contents();
|
189
|
|
190
|
ob_end_clean();
|
191
|
|
192
|
return $string;
|
193
|
}
|
194
|
|
195
|
function _get_content_fsockopen($url){
|
196
|
//FIXME implement get_content_fsockopen($url);
|
197
|
}
|
198
|
|
199
|
function get_content($url){
|
200
|
|
201
|
/* FIXME: all requests must be sent with the correct request headers:
|
202
|
*
|
203
|
* - Accept: application/json, text/xml, ...
|
204
|
* - Accept-Language: en, de, ....
|
205
|
* - Accept-Encoding: UTF8
|
206
|
*
|
207
|
*/
|
208
|
if(function_exists('curl_init')){
|
209
|
|
210
|
// use the CURL lib if installed it is supposed to be 20x faster
|
211
|
return _get_content_curl($url);
|
212
|
} else {
|
213
|
return _get_content_fsockopen($url);
|
214
|
}
|
215
|
}
|
216
|
|
217
|
|
218
|
/**
|
219
|
* Implementation of hook_menu()
|
220
|
*/
|
221
|
function cdm_api_menu($may_cache) {
|
222
|
$items = array();
|
223
|
if ($may_cache) {
|
224
|
|
225
|
$items[] = array(
|
226
|
'path' => 'cdm_api/proxy',
|
227
|
'callback' => 'proxy_content',
|
228
|
'access' => true,
|
229
|
'type' => MENU_CALLBACK,
|
230
|
);
|
231
|
|
232
|
}
|
233
|
|
234
|
return $items;
|
235
|
}
|
236
|
|
237
|
|
238
|
/**
|
239
|
* Implementation of hook_requirements()
|
240
|
*/
|
241
|
function cdm_api_requirements() {
|
242
|
|
243
|
$requirements['cdm_api'] = array(
|
244
|
'title' => t('CDM API')
|
245
|
);
|
246
|
|
247
|
if( function_exists('curl_init') ){
|
248
|
$requirements['cdm_api']['description'] = ''; // description below title is not jet in use
|
249
|
$requirements['cdm_api']['value'] = 'CURL php extension is available.';
|
250
|
} else {
|
251
|
$requirements['cdm_api']['value'] = 'CURL php extension is missing.';
|
252
|
}
|
253
|
|
254
|
//FIXME: once _get_content_fsockopen is implemented change severity to REQUIREMENT_WARNING,
|
255
|
$requirements['cdm_api']['severity'] = (function_exists('curl_init') ? REQUIREMENT_OK : REQUIREMENT_ERROR);
|
256
|
|
257
|
return $requirements;
|
258
|
}
|
259
|
|
260
|
|
261
|
|
262
|
function proxy_content($url, $theme = null){
|
263
|
$data = get_content(urldecode($url));
|
264
|
|
265
|
if(!$theme){
|
266
|
print $data;
|
267
|
} else {
|
268
|
print theme($theme, cdm_load_obj($data));
|
269
|
}
|
270
|
}
|
271
|
|
272
|
function cdm_load_obj($datastr){
|
273
|
// if the webservice deilvers XML convert it into json
|
274
|
if(variable_get('cdm_webservice_type', 'xml') == 'xml'){
|
275
|
$datastr = xml2json::transformXmlStringToJson($datastr);
|
276
|
}
|
277
|
$json = new Services_JSON();
|
278
|
$obj = $json->decode($datastr);
|
279
|
return $obj->root;
|
280
|
}
|
281
|
|
282
|
/**
|
283
|
* Loads the XML or JSON response for the given url from the CDM Data Store Webservice.
|
284
|
* The XML is turned into a object which is returned. In case of an error a
|
285
|
* appropriate watchdog message is generated and the function returns false.
|
286
|
*
|
287
|
* @param String $url the relative url of the web service call.
|
288
|
* Relative means relative to the web service base url which is stored in cdm_webservice_url
|
289
|
* @return An object or false
|
290
|
*/
|
291
|
function cdm_ws_load($url){
|
292
|
|
293
|
$datastr = get_content($url);
|
294
|
|
295
|
if( !($obj = cdm_load_obj($datastr)) ){
|
296
|
$backtrace = debug_backtrace();
|
297
|
watchdog('CDM', 'cdm_ws_load() - '.$url.' failed to load', WATCHDOG_ERROR);
|
298
|
}
|
299
|
|
300
|
return $obj;
|
301
|
}
|
302
|
|
303
|
|
304
|
/* ------------------------------------------------------------------------- */
|
305
|
|
306
|
/**
|
307
|
* Enter description here...
|
308
|
*
|
309
|
* @return unknown
|
310
|
*/
|
311
|
function cdm_ws(){
|
312
|
$args = func_get_args();
|
313
|
$method = array_shift($args);
|
314
|
$url_function = 'cdm_ws_'.$method.'_url';
|
315
|
if(function_exists($url_function)){
|
316
|
$url = call_user_func_array($url_function, $args);
|
317
|
return cdm_ws_load($url);
|
318
|
}
|
319
|
watchdog("cdm-api", 'cdm_ws() - invalid web service method call: "'.$method.'" dues not exist.', WATCHDOG_ERROR);
|
320
|
return false;
|
321
|
|
322
|
}
|
323
|
|
324
|
// -------- whatis
|
325
|
|
326
|
function cdm_ws_whatis_url($uuid){
|
327
|
return cdm_compose_url("whatis", array('uuid'=>$uuid));
|
328
|
}
|
329
|
|
330
|
/**cdm_ws_whatis
|
331
|
* The whatis service returns the type
|
332
|
* i.e. DTO class name and simplename & cdm class name and simplename of the instance referenced by the $uuid parameter.
|
333
|
*
|
334
|
*
|
335
|
* @param unknown_type $uuid
|
336
|
* @return false if the cdm store contains no matching instance.
|
337
|
* An associative array with the following key-value pairs:
|
338
|
* - 'cdmName': name of the cdm class as returned by Class.getName(), e.g. eu.etaxonomy.cdm.model.taxon.Taxon
|
339
|
* - 'cdmSimpleName': simple name of the cdm class as returned by Class.getSimpleName(), e.g. Taxon
|
340
|
* - 'dtoName': name of the DTO class as returned by Class.getName(), e.g. eu.etaxonomy.cdm.dto.TaxonTO
|
341
|
* - 'dtoSimpleName': simple name of the TDO class as returned by Class.getSimpleName(), e.g. TaxonTO
|
342
|
*/
|
343
|
function cdm_ws_whatis($uuid){
|
344
|
$url = cdm_ws_whatis_url($uuid);
|
345
|
return cdm_ws_load($url);
|
346
|
}
|
347
|
|
348
|
// -------- get_name
|
349
|
|
350
|
function cdm_ws_get_name_url($uuid){
|
351
|
return cdm_compose_url("name", array('uuid'=>$uuid));
|
352
|
}
|
353
|
/**
|
354
|
* load a name from the CDM Webservice
|
355
|
*
|
356
|
* @param String $uuid
|
357
|
* @return a NameTO instance or false
|
358
|
*/
|
359
|
function cdm_ws_get_name($uuid){
|
360
|
$uri = cdm_ws_get_name_url($uuid);
|
361
|
$obj = cdm_ws_load($url);
|
362
|
return $obj;
|
363
|
|
364
|
}
|
365
|
|
366
|
// -------- name_list
|
367
|
function cdm_ws_name_list_url($beginsWith, $page, $onlyAccepted = false, $pagesize = 20){
|
368
|
//TODO: fully implement
|
369
|
return cdm_compose_url('namelist', array(
|
370
|
'beginswith' =>$beginsWith,
|
371
|
'page' =>$page,
|
372
|
)
|
373
|
);
|
374
|
}
|
375
|
|
376
|
/**
|
377
|
* load a list of names from the CDM Webservice
|
378
|
*
|
379
|
* cdm_ws_name_list($beginsWith, $page, $onlyAccepted, $_SESSION['cdm']['namelist_pagesize']);
|
380
|
*/
|
381
|
function cdm_ws_name_list($beginsWith, $page, $onlyAccepted = false, $pagesize = 20){
|
382
|
//TODO: fully implement
|
383
|
$url = cdm_ws_name_list_url($beginsWith, $page, $onlyAccepted = false, $pagesize = 20);
|
384
|
$obj = cdm_ws_load($url);
|
385
|
return $obj;
|
386
|
}
|
387
|
|
388
|
// -------- get_reference
|
389
|
function cdm_ws_get_reference_url($uuid){
|
390
|
return cdm_compose_url('reference', array('uuid'=>$uuid));
|
391
|
}
|
392
|
|
393
|
/**
|
394
|
* Enter description here...
|
395
|
*
|
396
|
* @param String $uuid of the requested reference
|
397
|
* @return unknown
|
398
|
*/
|
399
|
function cdm_ws_get_reference($uuid){
|
400
|
$url = cdm_ws_get_reference_url($uuid);
|
401
|
$obj = cdm_ws_load($url);
|
402
|
return $obj;
|
403
|
}
|
404
|
|
405
|
// -------- get_taxon
|
406
|
|
407
|
function cdm_ws_get_taxon_url($uuid){
|
408
|
return cdm_compose_url('taxon', array('uuid'=>$uuid));
|
409
|
}
|
410
|
|
411
|
/**
|
412
|
* Enter description here...
|
413
|
*
|
414
|
* @param String $taxon_uuid UUID of the requested Taxon
|
415
|
* @return a TaxonTO objetct
|
416
|
*/
|
417
|
function cdm_ws_get_taxon($taxon_uuid){
|
418
|
$url = cdm_ws_get_taxon_url($taxon_uuid);
|
419
|
return cdm_ws_load($url);
|
420
|
}
|
421
|
|
422
|
// -------- get_typedesignation
|
423
|
function cdm_ws_get_typedesignations_url($name_uuid){
|
424
|
return cdm_compose_url('type', array('uuid'=>$name_uuid));
|
425
|
}
|
426
|
|
427
|
function cdm_ws_get_typedesignations($name_uuid){
|
428
|
$url = cdm_ws_get_typedesignations_url($name_uuid);
|
429
|
return cdm_ws_load($url);
|
430
|
}
|
431
|
|
432
|
// -------- get_accepted
|
433
|
function cdm_ws_get_accepted_url($taxon_uuid){
|
434
|
return cdm_compose_url('accepted', array('uuid'=>$taxon_uuid));
|
435
|
}
|
436
|
|
437
|
function cdm_ws_get_accepted($taxon_uuid){
|
438
|
$url = cdm_ws_get_accepted_url($taxon_uuid);
|
439
|
return cdm_ws_load($url);
|
440
|
}
|
441
|
|
442
|
// -------- Taxon tree ws functions
|
443
|
|
444
|
/**
|
445
|
* treenode_parents returns an array of the parent TreeNodes in descending order.
|
446
|
* The TreeNode referenced by the parameter $taxon_uuid is included as last element
|
447
|
*
|
448
|
* @param String $taxon_uuid
|
449
|
* @return array
|
450
|
*/
|
451
|
function cdm_ws_get_treenode_parents_url($taxon_uuid){
|
452
|
return cdm_compose_url('treenode_parents', array('uuid'=>$taxon_uuid));
|
453
|
}
|
454
|
|
455
|
function cdm_ws_get_treenode_children_url($taxon_uuid = ''){
|
456
|
return cdm_compose_url('treenode_children', array('uuid'=>$taxon_uuid));
|
457
|
}
|