Project

General

Profile

Download (29.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
// $Id$
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
require_once ('xml2json.php');
19
require_once ('commons.php');
20
require_once ('uuids.php');
21

    
22
define(DEFAULT_TAXONTREE_RANKLIMIT, '');//TODO Genus UUID
23

    
24

    
25
/**
26
 * Implementation of hook_requirements()
27
 */
28
function cdm_api_requirements() {
29

    
30
  $requirements['cdm_api'] = array(
31
    'title' => t('CDM API')
32
  );
33

    
34
  if( function_exists('curl_init') ){
35
    $requirements['cdm_api']['description'] = ''; // description below title is not jet in use
36
    $requirements['cdm_api']['value'] =  'CURL php extension is available.';
37
  } else {
38
    $requirements['cdm_api']['value'] =  'CURL php extension is missing.';
39
  }
40
 
41
  //FIXME: once _get_content_fsockopen is implemented change  severity to  REQUIREMENT_WARNING,
42
  $requirements['cdm_api']['severity'] =  (function_exists('curl_init') ? REQUIREMENT_OK : REQUIREMENT_ERROR);
43
  
44
  return $requirements;
45
}
46

    
47

    
48
/**
49
 * Implementation of hook_menu()
50
 */
51
function cdm_api_menu($may_cache) {
52
  $items = array();
53
  if ($may_cache) {
54
    $items[] = array(
55
      // usage: url('cdm_api/proxy/'.urlencode($content_url)."/$theme");
56
      'path' => 'cdm_api/proxy',
57
      'callback' => 'proxy_content',
58
      'access' => true,
59
      'type' => MENU_CALLBACK,
60
    );
61
    
62
    $items[] = array(
63
      // usage: url('cdm_api/proxy/'.urlencode($content_url)."/$theme");
64
      'path' => 'cdm_api/setvalue/session',
65
      'callback' => 'setvalue_session',
66
      'access' => true,
67
      'type' => MENU_CALLBACK,
68
    );
69
    
70
  }
71
  
72
  return $items;
73
}
74

    
75
/**
76
 * Configures the settings forfm for the CDM-API module.
77
 *
78
 * @return Array Drupal settings form
79
 */
80
function cdm_api_settings_form(){
81
  
82
  $form['cdm_webservice'] = array(
83
      '#type' => 'fieldset',
84
      '#title' => t('CDM Web Service'),
85
      '#collapsible' => FALSE,
86
      '#collapsed' => FALSE,
87
  );
88

    
89
  $form['cdm_webservice']['cdm_webservice_url'] =  array(
90
    '#type' => 'textfield',
91
    '#title'         => t('CDM Web Service URL'),
92
    '#description'   => t('The URL of CDM Webservice which delivers the data to be published.'),
93
    '#default_value' => variable_get('cdm_webservice_url', NULL),
94
  );
95
  
96
  $form['cdm_webservice']['taxontree_ranklimit'] =  array(
97
    '#type'          => 'select',
98
    '#title'         => t('Rank of highest displayed taxon'),
99
    '#default_value' => variable_get('taxontree_ranklimit', DEFAULT_TAXONTREE_RANKLIMIT_UUID),
100
    '#options'       => cdm_rankVocabulary_as_option(),
101
    '#description'   => t('The rank of the highest displayed taxon in the taxontree.'),
102
  );
103
  
104
  /*
105
  $form['cdm_webservice']['cdm_webservice_isStub'] =  array(
106
    '#type' => 'checkbox',
107
    '#title'         => t('Use Web Service Stub'),
108
    '#default_value' => variable_get('cdm_webservice_isStub', 1),
109
    '#description'   => t('Use a static web service stub. Only for development. For further information please refer to the ')
110
  .l('ws_stub/README.txt', 'http://dev.e-taxonomy.eu/svn/trunk/drupal/modules/cdm_dataportal/cdm/ws_stub/README.txt', array('target'=>'_blank')),
111
  );
112
  
113

    
114
  $form['cdm_webservice']['cdm_webservice_type'] =  array(
115
    '#type'          => 'select',
116
    '#title'         => t('Web Service Type'),
117
    '#default_value' => variable_get('cdm_webservice_type', 'json'),
118
    '#options'       => array(
119
            'xml'  => t('XML'),
120
            'json' => t('JSON'),
121
        ),
122
    '#description'   => t('The response data type of the web service.'),
123
  );
124
  */
125

    
126
  $form['cdm_webservice']['cdm_webservice_cache'] =  array(
127
    '#type' => 'checkbox',
128
    '#title'         => t('Enable Caching'),
129
    '#default_value' => variable_get('cdm_webservice_cache', 1),
130
    '#description'   => t('Enable caching of webservice responses on simple requests, '
131
      .'that is requests which only have one parameter generally a UUID or a concatenation of UUIDs')
132
  );
133
  
134
  $form['cdm_webservice']['proxy'] = array(
135
      '#type' => 'fieldset',
136
      '#title' => t('Proxy'),
137
      '#collapsible' => TRUE,
138
      '#collapsed' => TRUE
139
  );
140
  
141
  $form['cdm_webservice']['proxy']['cdm_webservice_proxy_url'] =  array(
142
    '#type' => 'textfield',
143
    '#title'         => t('Proxy URL'),
144
    '#description'   => t('If this proxy url is set the cdm api tries
145
    to connect the web service over the given proxy server.
146
    Otherwise proxy usage is deactivated.'),
147
    '#default_value' => variable_get('cdm_webservice_proxy_url', false),
148
  );
149
  
150
  $form['cdm_webservice']['proxy']['cdm_webservice_proxy_port'] =  array(
151
    '#type' => 'textfield',
152
    '#title'         => t('Proxy Port'),
153
    '#default_value' => variable_get('cdm_webservice_proxy_port', '80'),
154
  );
155
  
156
  $form['cdm_webservice']['proxy']['cdm_webservice_proxy_usr'] =  array(
157
    '#type' => 'textfield',
158
    '#title'         => t('Login'),
159
    '#default_value' => variable_get('cdm_webservice_proxy_usr', false),
160
  );
161
  
162
  $form['cdm_webservice']['proxy']['cdm_webservice_proxy_pwd'] =  array(
163
    '#type' => 'textfield',
164
    '#title'         => t('Password'),
165
    '#default_value' => variable_get('cdm_webservice_proxy_pwd', false),
166
  );
167
  
168
  $form['cdm_webservice']['cdm_webservice_debug'] =  array(
169
    '#type' => 'checkbox',
170
    '#title'         => t('Debug CDM Web Service'),
171
    '#default_value' => variable_get('cdm_webservice_debug', 1),
172
    '#description'   => t('Enable CDM Web Service debugging messages. Only visible for administrators!')
173
  );
174
    
175
  return $form;
176
}
177

    
178
/**
179
 * Implementation of hook_cron().
180
 *
181
 * Expire outdated cache entries
182
 */
183
function cdm_api_cron() {
184
  cache_clear_all(NULL, 'cache_cdm_ws');
185
}
186

    
187

    
188
// ----------------------------------------------------------- //
189

    
190

    
191
/**
192
 * Converts an array of TagedText items into a sequence of corresponding html tags whereas
193
 * each item will provided with a class attribute which set to the key of the TaggedText item.
194
 *
195
 * @param array $taggedtxt
196
 * @param String $tag
197
 * @param String $glue the string by which the chained text tokens are concatenated together.
198
 *       Default is a blank character
199
 * @return String of HTML
200
 */
201
function cdm_taggedtext2html(array &$taggedtxt, $tag = 'span', $glue = ' ', $skiptags = array()){
202
   $out = '';
203
   $i = 0;
204
   foreach($taggedtxt as $tt){
205
     if(!in_array($tt->type, $skiptags) && strlen($tt->text) > 0){
206
      $out .= (strlen($out) > 0 && ++$i < count($taggedtxt)? $glue : '').'<'.$tag.' class="'.$tt->type.'">'.t($tt->text).'</'.$tag.'>';
207
     }
208
   }
209
   return $out;
210
}
211

    
212
/**
213
 * Finds the text tagged with $$tag_type in an array of taggedText instances
214
 *
215
 * @param array $taggedtxt
216
 * @param string $tag_type
217
 * @return the text mapped by $tag_type or an empty string
218
 */
219
function cdm_taggedtext_value(array &$taggedtxt = array(), $tag_type){
220
  foreach($taggedtxt as $tagtxt){
221
    if($tagtxt->type == $tag_type)
222
    return $tagtxt->text;
223
  }
224
  return '';
225
}
226

    
227
/**
228
 * media Array [4]
229
 *   representations Array [3]
230
 *       mimeType  image/jpeg
231
 *       representationParts Array [1]
232
 *           duration  0
233
 *           heigth  0
234
 *           size  0
235
 *           uri http://wp5.e-taxonomy.eu/dataportal/cichorieae/media/protolog/jpeg/Acanthocephalus_p1.jpg
236
 *           uuid  15c687f1-f79d-4b79-992f-7ba0f55e610b
237
 *           width 0
238
 *       suffix  jpg
239
 *       uuid  930b7d51-e7b6-4350-b21e-8124b14fe29b
240
 *   title
241
 *   uuid  17e514f1-7a8e-4daa-87ea-8f13f8742cf9
242
 *
243
 * @param unknown_type $media
244
 * @param array $mimeTypes
245
 * @param unknown_type $width
246
 * @param unknown_type $height
247
 * @return unknown
248
 */
249
function cdm_preferred_media_representations($media, array $mimeTypes, $width = 400, $height = 300){
250
    /**
251

    
252
     *
253
     */
254
  $prefRepr = array();
255
  if(!isset($media->representations[0])){
256
    return $prefRepr;
257
  }
258
  
259
  while(count($mimeTypes) > 0){
260
    // getRepresentationByMimeType
261
    $mimeType = array_shift($mimeTypes);
262
    foreach($media->representations as $representation){
263
      if($representation->mimeType == $mimeType){
264
        // preffered mimetype found -> erase all remaining mimetypes to end loop
265
        $mimeTypes = array();
266
        $dwa = 0;
267
        // look for part with the best matching size
268
        foreach($representation->parts as $part){
269
          $dw = $part->width * $part->height - $height * $width;
270
          if($dw < 0){
271
            $dw *= -1;
272
          }
273
          $dwa+= $dw;
274
        }
275
        $dwa = (count($representation->parts)>0) ? $dwa / count($representation->parts) : 0;
276
        $prefRepr[$dwa.'_'.$mimeTypeKey] = $representation;
277
      }
278
    }
279
  }
280
  // sort
281
  krsort($prefRepr);
282
  // return
283
  return $prefRepr;
284
}
285

    
286
/**
287
 * expects an ISO 8601 time representations of a org.joda.time.Partial 
288
 * of the form yyyy-MM-dd and returns the year as String. 
289
 * In case the year is unknown (= ????) null is returned.
290
 *
291
 * @param ISO 8601 time representations of a org.joda.time.Partial 
292
 * @return String 
293
 */
294
function partialToYear($partial){
295
  if(is_string($partial)){
296
    $year = substr($partial, 0, 4);  
297
    if($year != '??'){
298
      return $year;
299
    } 
300
  }
301
  return; 
302
}
303
/**
304
 * expects an ISO 8601 time representations of a org.joda.time.Partial 
305
 * of the form yyyy-MM-dd and returns the month as String.
306
 * In case the month is unknown (= ???) null is returned.
307
 *
308
 * @param ISO 8601 time representations of a org.joda.time.Partial 
309
 * @return String 
310
 */
311
function partialToMonth($partial){
312
  if(is_string($partial)){
313
    $month = substr($partial, 5, 2);
314
    if($month != '??'){
315
      return $month;
316
    }
317
  }
318
  return; 
319
}
320
/**
321
 * expects an ISO 8601 time representations of a org.joda.time.Partial 
322
 * of the form yyyy-MM-dd and returns the day as String.
323
 * In case the day is unknown (= ???) null is returned.
324
 *
325
 * @param ISO 8601 time representations of a org.joda.time.Partial 
326
 * @return String 
327
 */
328
function partialToDay($partial){
329
  if(is_string($partial)){
330
    $day = substr($partial, 7, 2);
331
    if($day != '??'){
332
      return $day;
333
    }
334
  }
335
  return;
336
}
337

    
338
/**
339
 * 
340
 * @param $uri_pattern
341
 * @param $pathParameters an array of path elements, or a single element
342
 * @param $query  A query string to append to the URL.
343
 * @return unknown_type
344
 */
345
function cdm_compose_url($uri_pattern, $pathParameters = array(), $query = NULL ){
346
  
347
  $request_params = '';
348
  $path_params = '';
349
  
350
  /* (1) 
351
   * substitute all place holders ($0, $1, ..) in the 
352
   * $uri_pattern by the according element of the $pathParameters array
353
   */
354
  static $helperArray = array();
355
  if($pathParameters && !is_array($pathParameters)){
356
    $helperArray[0] = $pathParameters;
357
    $pathParameters = $helperArray;
358
  }
359
  
360
  $i = 0;
361
  while(strpos($uri_pattern, "$".$i) !== FALSE){
362
    if(count($pathParameters) <= $i){
363
      drupal_set_message('cdm_compose_url(): missing pathParameters', 'debug');
364
    }
365
    $uri_pattern = str_replace("$".$i, rawurlencode($pathParameters[$i]), $uri_pattern);
366
    ++$i;      
367
  }
368
    
369
  /* (2)
370
   * Append all remaining element of the $pathParameters array as path elements
371
   */
372
  if(count($pathParameters) > $i){
373
    // strip trailing slashes
374
    if(strrchr($uri_pattern, '/') == strlen($uri_pattern)){ 
375
      $uri_pattern = substr($uri_pattern, 0, strlen($uri_pattern) - 1); 
376
    }
377
    while(count($pathParameters) > $i){
378
      $uri_pattern .= '/' . $pathParameters[$i];
379
      ++$i;
380
    }
381
  }
382
  
383
  /* (3)
384
   * Append the query string supplied by $query
385
   */
386
  if (isset($query)) {
387
    $uri_pattern .= (strpos($uri_pattern, '?') !== FALSE ? '&' : '?') . $query;
388
  }
389
  
390
  $path = $ws_name.$uri_pattern;
391
  
392
  $uri = variable_get('cdm_webservice_url', '').$path;
393
  return $uri;
394
}
395

    
396

    
397
function proxy_content($uri, $theme = null){
398
  
399
  $args = func_get_args();
400
  
401
  $uriEncoded = array_shift($args);
402
  $uri = urldecode($uriEncoded);
403
  $theme = array_shift($args);
404
  
405
  $request_method = strtoupper($_SERVER["REQUEST_METHOD"]);
406
  
407
  if($request_method == "POST"){
408
    
409
    $parameters = $_POST;
410
    
411
    $post_data = array();
412
    foreach ($parameters as $k=>$v)
413
    {
414
        $post_data[] = "$k=".utf8_encode($v);
415
    }
416
    $post_data = implode(',', $post_data);
417
    
418
    // testing
419
    $data = cdm_http_request($uri, "POST", $post_data);
420
    print $data;
421
    
422
  }else if(strpos($theme, '/') > 0){ // must be a mimetype
423
    header('Content-Type: '.$theme);
424
    $data = _http_request_binary($uri);
425
    print $data;
426
    exit;
427
  } else {
428
    // in all other cases perform a simple get request
429
    //TODO reconsider caching logic in this function
430
    if(!$theme){
431
      // print out JSON, the cache cannot be used since it contains objects
432
      $data = cdm_http_request($uri);
433
      print $data;
434
      exit;
435
    } else {
436
      $obj = cdm_ws_get($uri, null, null, null, TRUE);
437
      array_unshift($args, $theme, $obj);
438
      print call_user_func_array('theme', $args);
439
    }
440
  }
441
}
442

    
443
function setvalue_session(){
444
 
445
  if(strlen(arg(3)) > 0){
446
    $keys = explode('|', arg(3));
447
  }
448
  $val = arg(4);
449
  
450
  // prevent from malicous tags  
451
  $val = strip_tags($val);
452
  
453
  $var = &$_SESSION;
454
  $i = 0;
455
  foreach($keys as $key){
456
    $hasMoreKeys = ++$i < count($var);
457
    if($hasMoreKeys && (!isset($var[$key]) || !is_array($var[$key]))){
458
      $var[$key] = array();
459
    }
460
    $var = &$var[$key];
461
  }
462
  $var = $val;
463
}
464

    
465
function uri_uriByProxy($uri, $theme = false){
466
  // usage: url('cdm_api/proxy/'.urlencode($content_url)."/$theme");)
467
  return url('cdm_api/proxy/'.urlencode($uri).($theme?"/$theme":''));
468
}
469

    
470
/**
471
 * Enter description here...
472
 *
473
 * @param String $resourceURI
474
 * @param pageSize
475
 *            the maximum number of entities returned per page (can be null
476
 *            to return all entities in a single page)
477
 * @param pageNumber
478
 *            the number of the page to be returned, the first page has the
479
 *            pageNumber = 1
480
 * @return unknown
481
 */
482
function cdm_ws_page($resourceURI, $pageSize, $pageNumber){
483
  return cdm_ws_get($resourceURI, null, queryString(array("page" => $pageNumber, 'pageSize'=>$pageSize)));
484
}
485

    
486
function cdm_ws_taxonomy_find($uuid, $rank = null, $viewUuid = null){
487
 return cdm_ws_get(CDM_WS_TAXONOMY, null, queryString(array("uuid" => $uuid, 'rank'=>$rank)));
488
}
489

    
490
/**
491
 * Enter description here...
492
 *
493
 * @param unknown_type $secUuid
494
 * @param unknown_type $path
495
 * @return unknown
496
 */
497
function cdm_ws_taxonomy($path = null){
498
 return cdm_ws_get(cdm_ws_taxonomy_compose_resourcePath($path));
499
}
500

    
501
function cdm_ws_taxonomy_compose_resourcePath($path = null){
502
  $viewrank =  _cdm_taxonomy_compose_viewrank();
503
  return CDM_WS_TAXONOMY . '/' . ($viewrank ? $viewrank : '' ) . ($path ? '/' . $path : '') ;
504
}
505

    
506
/**
507
 * Enter description here...
508
 *
509
 * @param UUID $secUuid
510
 * @param String $path
511
 * @return unknown
512
 */
513
function cdm_ws_taxonomy_pathFromRoot($path){
514
 $viewrank =  _cdm_taxonomy_compose_viewrank();
515
 return cdm_ws_get(CDM_WS_TAXONOMY .  ($viewrank ? '/' .$viewrank : '' )  . '/' . $path . '/path' );
516
}
517

    
518
/**
519
 * Enter description here...
520
 *
521
 * @param UUID $viewUuid
522
 * @param String $rank
523
 * @return unknown
524
 */
525
function _cdm_taxonomy_compose_viewrank(){
526
  $viewUuid = variable_get('cdm_taxonomictree_uuid', false);
527
  if(!$viewUuid){
528
    return;
529
  }
530
  $rank = variable_get('taxontree_ranklimit', DEFAULT_TAXONTREE_RANKLIMIT);
531
  return $viewUuid . (empty($rank) ? '' : ','.$rank);
532
}
533

    
534

    
535
function cdm_rankVocabulary_as_option(){
536
  global $rankVocabularyOptions;
537
  if(!$rankVocabularyOptions){
538
    $vocab = cdm_ws_get(CDM_WS_TERMVOCABULARY, UUID_RANK);
539
    $rankVocabularyOptions = array();
540
    foreach($vocab->terms as $term){
541
      $rankVocabularyOptions[$term->uuid] = t($term->representation_L10n);
542
    }
543
    array_reverse($rankVocabularyOptions);
544
  }
545
  return $rankVocabularyOptions;
546
}
547

    
548

    
549
function cdm_ws_descriptions_by_featuretree($featureTree, $descriptions, $isDescriptionsSeparated = false){
550
  
551
  if(!$featureTree){
552
    drupal_set_message('cdm_ws_descriptions_by_featuretree() - No feature supplied', 'error');
553
    return false;
554
  }
555
  
556
  $mergedTrees = array(); 
557
  
558
  if($isDescriptionsSeparated){
559
    // merge any description into a sparate feature tree
560
    foreach($descriptions as $desc){
561
      $mergedNodes = _mergeFeatureTreeDesciptions($featureTree->root->children, $desc->elements);
562
      
563
      $mergedTree = clone $featureTree;
564
      $mergedTree->root->children = $mergedNodes;
565
      $mergedTrees[] = $mergedTree;
566
    }
567
  } else {
568
    // combine all descripions into one feature tree
569
    foreach($descriptions as $desc){
570
      $mergedNodes = _mergeFeatureTreeDesciptions($featureTree->root->children, $desc->elements);
571
      $featureTree->root->children = $mergedNodes;
572
    }
573
    $mergedTrees[] = $featureTree;
574
  }
575
  
576
 return $mergedTrees;
577
}
578

    
579
function _mergeFeatureTreeDesciptions($featureNodes, $descriptionElements){
580
  
581
  foreach($featureNodes as &$node){
582
    
583
    // append corresponding elements to an additional node field: $node->descriptionElements 
584
    foreach($descriptionElements as $element){
585
      if($element->feature->uuid == $node->feature->uuid){
586
        if(!isset($node->descriptionElements)){
587
          $node->descriptionElements = array();
588
        }
589
        $node->descriptionElements[] = $element;
590
      }
591
    }
592
    
593
    // recurse into node children
594
    if(is_array($node->children)){
595
      foreach($node->children as $nodes){
596
        $mergedChildNodes = _mergeFeatureTreeDesciptions($nodes, $descriptionElements);
597
        $node->children = $mergedChildNodes;
598
      }
599
    }
600
    
601
  }
602
  return $featureNodes;
603
}
604

    
605

    
606
/**
607
 * Loads the XML or JSON response for the given url from the CDM Data Store Webservice.
608
 * The XML is turned into a object which is returned.
609
 *
610
 * @param String $uri the relative url of the web service call.
611
 *        Relative means relative to the web service base url which is stored in cdm_webservice_url
612
 * @param $is_multi_parameter_query parameter to indicate that the URI has queryparameters and should not be cached
613
 * @return An object or false
614
 */
615

    
616

    
617
/**
618
 * Send a HTTP GET request to the RESTService and deserializes 
619
 * and returns the response as object
620
 * 
621
 * @param $uri
622
 * @param $pathParameters
623
 * @param $query
624
 * @param $method the HTTP method to use, valuid values are "GET" or "POST";
625
 * @param $absoluteURI
626
 * @return unknown_type
627
 */
628
function cdm_ws_get($uri, $pathParameters = array(), $query = null, $method="GET", $absoluteURI = false){
629
   
630
  // transform the given uri path or patthern into a proper webservice uri
631
  if(!$absoluteURI){
632
    $uri = cdm_compose_url($uri, $pathParameters, $query);
633
  }
634
  
635
  $do_cache = variable_get('cdm_webservice_cache', 1); //strpos($uri, "?") !== FALSE; // if the url has a query parameter sting
636
  // only cache cdm webservice URIs
637
  $do_cache = $do_cache && str_beginsWith($uri, variable_get('cdm_webservice_url', '#EMPTY#'));
638
  $cache_entry = false;
639
   
640
  if($do_cache){
641
    // try to get object from cache
642
    $cache_entry = cache_get($uri, 'cache_cdm_ws');
643
  }
644
  
645
  if(!$cache_entry){
646
    // load fresh data from webservice
647
    $time_get_start = microtime(true);
648
    // request data from webservice JSON or XML
649
    $datastr = cdm_http_request($uri, $method);
650
    $time_get = microtime(true) - $time_get_start;
651

    
652
    
653
    $time_parse_start = microtime(true);
654
    // parse data and create object
655
    $obj = cdm_load_obj($datastr);
656

    
657
    $time_parse = microtime(true) - $time_parse_start;
658
    if(variable_get('cdm_webservice_debug', 1) && user_access('administer')){
659
      $success_msg = $obj || $datastr == "[]" ? 'valid':'invalid'; 
660
      _add_debugMessage($uri, $time_get, $time_parse, strlen($datastr), $success_msg);
661
    }
662
    if($obj && $do_cache) {
663
      // store fresh data in cache
664
      cache_set($uri, 'cache_cdm_ws', serialize($obj), CACHE_TEMPORARY);
665
    }
666
  } else {
667
    $obj = unserialize($cache_entry->data);
668
    if(variable_get('cdm_webservice_debug', 1) && user_access('administer')){
669
      _add_status_message_toggler();
670
      drupal_set_message('Using cache for: '.$uri, 'debug');
671
    }
672
  }
673
  return $obj;
674
}
675

    
676
function _add_debugMessage($uri, $time_get, $time_parse, $datasize, $success_msg){
677
  
678
  static $cummulated_time_parse;
679
  static $cummulated_time_get;
680
  _add_status_message_toggler();
681
  
682
  $cummulated_time_get += $time_get;
683
  $cummulated_time_parse += $time_parse;
684
 
685
  $message = '<span class="uri">'.$uri.'</span><br />';
686
  $message .= '[fetched in: '.sprintf('%3.3f', $time_get).'s('.sprintf('%3.3f', $cummulated_time_get).'s); ';
687
  $message .= 'parsed in '.sprintf('%3.3f', $time_parse).' s('.sprintf('%3.3f', $cummulated_time_parse).'s); ';
688
  $message .= 'size:'.sprintf('%3.1f', ($datasize / 1024)).' kb of '.$success_msg.' data: ';
689
  $message .= '<a href="'.$uri.'.xml" target="data" class="'.$success_msg.'">xml</a>,';
690
  $message .= '<a href="'.$uri.'.json" target="data" class="'.$success_msg.'">json</a>';
691
  $message .= '] ';
692
  
693
  drupal_set_message($message, 'debug');
694

    
695
}
696

    
697

    
698
function cdm_load_obj($datastr){
699
     
700
  // if the web service delivers XML convert it into json
701
  if(variable_get('cdm_webservice_type', 'xml') == 'xml'){
702
    $datastr = xml2json::transformXmlStringToJson($datastr);
703
  }
704
  
705
  $obj = json_decode($datastr);
706
  
707
  
708
  if(!(is_object($obj) || is_array($obj)) ){
709
    ob_start();
710
    var_dump($obj);
711
    $obj_dump = ob_get_contents();
712
    ob_clean();
713
    return false;
714
  }
715

    
716
  return $obj;
717
}
718

    
719
/**
720
 * 
721
 * @param $uri
722
 * @param $method the HTTP method to use, valuid values are "GET" or "POST"; efaults to "GET" even if null, 
723
 *        false or any invalid value is supplied.
724
 * @param $parameters
725
 * @param $header
726
 * @return unknown_type
727
 */
728
function cdm_http_request($uri, $method="GET", $parameters = array(), $header = false){
729
  global $locale;  // drupal variable containing the current locale i.e. language
730
  static $header;
731
  
732
  if($method != "GET" && $method != "POST"){
733
    $method  = "GET";
734
  }
735
  
736
  if(!$header){
737
    $header = array();
738
    $header[] = 'Accept: '.(variable_get('cdm_webservice_type', 'json') == 'json' ? 'application/json' : 'text/xml');
739
    $header[] = 'Accept-Language: '.$locale;
740
    $header[] = 'Accept-Charset: UTF-8';
741
  }
742
  
743
  if(function_exists('curl_init')){
744

    
745
    // use the CURL lib if installed it is supposed to be 20x faster
746
    return _http_request_using_curl($uri, $header, $method, $parameters);
747
  } else {
748
    return _http_request_using_fsockopen($uri, $header, $method, $parameters);
749
  }
750
}
751

    
752
function _http_request_using_fsockopen($uri, $header = array(), $method = "GET"){
753
  //FIXME implement get_content_fsockopen($uri);
754
   watchdog('CDM_API', '_http_request_fsockopen - UNIMPLEMENTED', WATCHDOG_ERROR);
755
   return false;
756
}
757

    
758

    
759
/**
760
 * Return string content from a remote file
761
 *
762
 * @param string $uri
763
 * @return string
764
 *
765
 * @author Luiz Miguel Axcar (lmaxcar@yahoo.com.br)
766
*/
767
function _http_request_using_curl($uri, $header = array(), $method = "GET", $parameters = array())
768
{
769
    $ch = curl_init();
770

    
771
    curl_setopt ($ch, CURLOPT_URL, $uri);
772
    // set proxy settings
773
    if(variable_get('cdm_webservice_proxy_url', false)){
774
      curl_setopt($ch, CURLOPT_PROXY, variable_get('cdm_webservice_proxy_url', ''));
775
      curl_setopt($ch, CURLOPT_PROXYPORT, variable_get('cdm_webservice_proxy_port', '80'));
776
      if(variable_get('cdm_webservice_proxy_usr', false)){
777
        curl_setopt ($ch, CURLOPT_PROXYUSERPWD, variable_get('cdm_webservice_proxy_usr', '').':'.variable_get('cdm_webservice_proxy_pwd', ''));
778
      }
779
    }
780
    // set headers
781
    curl_setopt ($ch, CURLOPT_HTTPHEADER, $header);
782
    // set method if not default
783
    if($method != "GET"){
784
      if($method == "POST"){
785
        
786
        curl_setopt ($ch, CURLOPT_POST, 1);
787
        curl_setopt ($ch, CURLOPT_POSTFIELDS, $parameters);
788
        
789
      }else{
790
        // other obscure http methods get passed to curl directly
791
        // TODO generic parameter/body handling
792
        curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, $method);
793
      }
794
    }
795
    
796
    ob_start();
797
    curl_exec ($ch);
798
    if(curl_errno($ch)){
799
      watchdog('CDM_API', '_http_request_curl() - '.curl_error($ch).'; REQUEST-METHOD:'.$method.' URL: '.substr($uri.' ', 0, 150), WATCHDOG_ERROR);
800
        if(variable_get('cdm_webservice_debug', 1)  && user_access('administer') ){
801
          drupal_set_message('_http_request_curl() - '.curl_error($ch).'; REQUEST-METHOD:'.$method.' URL: '.substr($uri.' ', 0, 150), 'error');
802
        }
803
    }
804
    curl_close ($ch);
805
    $string = ob_get_contents();
806
    ob_end_clean();
807
 
808
    return $string;
809
}
810

    
811
function cdm_api_secref_cache_prefetch(&$secUuids){
812
  global $secref_cache;
813
  if(!is_array($secref_cache)){
814
    $secref_cache = array();
815
  }
816
  $uniqueUuids = array_unique($secUuids);
817
  $i = 0;
818
  $param = '';
819
  while($i++ < count($uniqueUuids)){
820
    $param .= $secUuids[$i].',';
821
    if(strlen($param) + 37 > 2000){
822
     _cdm_api_secref_cache_add($param);
823
      $param = '';
824
    }
825
  }
826
  if($param){
827
     _cdm_api_secref_cache_add($param);
828
  }
829
}
830

    
831
function cdm_api_secref_cache_get($secUuid){
832
  global $secref_cache;
833
  if(!is_array($secref_cache)){
834
    $secref_cache = array();
835
  }
836
  if(!array_key_exists($secUuid, $secref_cache)){
837
    _cdm_api_secref_cache_add($secUuid);
838
  }
839
  return $secref_cache[$secUuid];
840
}
841

    
842
function cdm_api_secref_cache_clear(){
843
  global $secref_cache;
844
  $secref_cache = array();
845
}
846

    
847
function _cdm_api_secref_cache_add($secUuidsStr){
848
  global $secref_cache;
849
  $ref = cdm_ws_get(CDM_WS_REFERENCE, $secUuidsStr);
850
  // batch fetching not jet reimplemented thus:
851
  /*$assocRefSTOs = array();
852
  if($refSTOs) {
853
    foreach($refSTOs as $ref){
854
      $assocRefSTOs[$ref->uuid] = $ref;
855
    }
856
    $secref_cache = array_merge($secref_cache, $assocRefSTOs);
857
  }*/
858
  $secref_cache[$ref->uuid] = $ref;
859
}
860

    
861
function queryString($elements) {
862
  $query = '';
863
  foreach($elements as $key=>$value){
864
    if(is_array($value)){
865
      foreach($value as $v){
866
        $query .= (strlen($query) > 0 ? '&' : '').$key.'='.urlencode($v);
867
      }
868
    } else{
869
      $query .= (strlen($query) > 0 ? '&' : '').$key.'='.urlencode($value);      
870
    }
871
  }
872
  return $query;
873
}
874

    
875
/**
876
 * implementation of the magic method __clone to allow deep cloning of objects and arrays
877
 */
878
function __clone(){
879
    foreach($this as $name => $value){
880
        if(gettype($value)=='object' || gettype($value)=='array'){
881
            $this->$name= clone($this->$name);
882
        }
883
    }
884
} 
885

    
886
/**
887
 * Make a complete deep copy of an array replacing
888
 * references with deep copies until a certain depth is reached
889
 * ($maxdepth) whereupon references are copied as-is...
890
 * [From http://us3.php.net/manual/en/ref.array.php]
891
 * @param $array
892
 * @param $copy
893
 * @param $maxdepth
894
 * @param $depth
895
 * @return unknown_type
896
 */
897
function array_deep_copy (&$array, &$copy, $maxdepth=50, $depth=0) {
898
    if($depth > $maxdepth) { $copy = $array; return; }
899
    if(!is_array($copy)) $copy = array();
900
    foreach($array as $k => &$v) {
901
        if(is_array($v)) {        array_deep_copy($v,$copy[$k],$maxdepth,++$depth);
902
        } else {
903
            $copy[$k] = $v;
904
        }
905
    }
906
}
907

    
908
/**
909
 * Implementation of theme_status_messages($display = NULL) 
910
 * @see includes/theme.inc
911
 * 
912
 * @param $display
913
 * @return unknown_type
914
 */
915
function _add_status_message_toggler() {
916
  static $isAdded;
917
  if(!$isAdded){
918
    
919
    drupal_add_js(
920
          '$(document).ready(function(){
921
          
922
            $(\'.messages.debug\').before( \'<h6 class="messages_toggler debug">Debug Messages (klick to toggle)</h6>\' );
923
            $(\'.messages_toggler\').click(function(){
924
              $(this).next().slideToggle(\'fast\');
925
                return false;
926
            }).next().hide();
927
            
928
          });'
929
          , 'inline');
930
    $isAdded = TRUE;      
931
  }
932
}
933

    
934
define('CDM_WS_MEDIA', 'portal/media');
935

    
936
define('CDM_WS_NAME', 'name');
937

    
938
define('CDM_WS_NAME_TYPEDESIGNATIONS', 'name/$0/typeDesignations');
939

    
940
define('CDM_WS_TAXON_NAMETYPEDESIGNATIONS', 'portal/taxon/$0/nameTypeDesignations');
941

    
942
define('CDM_WS_TAXON_DESCRIPTIONS', 'portal/taxon/$0/descriptions');
943

    
944
define('CDM_WS_NAME_DESCRIPTIONS', 'portal/name/$0/descriptions');
945

    
946
define('CDM_WS_REFERENCE', 'reference');
947

    
948
define('CDM_WS_NOMENCLATURAL_REFERENCE_CITATION', 'reference/$0/nomenclaturalCitation/$1');
949

    
950
define('CDM_WS_FIND_TAXA', 'portal/taxon/find');
951

    
952
define('CDM_WS_TAXON', 'portal/taxon');
953

    
954
/**
955
 * @parameters $0 : the taxon uuid
956
 * 
957
 * @returns 
958
 */
959
define('CDM_WS_TAXON_SYNONYMY', 'portal/taxon/$0/synonymy');
960

    
961
define('CDM_WS_TAXON_RELATIONS', 'portal/taxon/$0/taxonRelationships');
962

    
963
define('CDM_WS_TAXON_NAMERELATIONS', 'portal/taxon/$0/nameRelationships');
964

    
965

    
966
/**
967
 * @parameters $0 : the taxon uuid
968
 * 
969
 * @returns the taxon which is the accepted synonym for the taxon given as
970
 * parameter taxonUuid. If the taxon specified by taxonUuid is itself the
971
 * accepted taxon, this one will be returned.
972
 */
973
define('CDM_WS_TAXON_ACCEPTED', 'portal/taxon/$0/accepted');
974

    
975
define('CDM_WS_TAXON_MEDIA', 'portal/taxon/$0/media/$1/$2');
976

    
977
/**
978
 *
979
 * Gets the root nodes of the taxonomic concept tree for the concept
980
 * reference specified by the secUuid parameter.
981
 *
982
 * stub: treenode_root
983
 */
984
define('CDM_WS_TAXONOMY', 'portal/taxontree');
985

    
986
define('CDM_WS_TERMVOCABULARY', 'term/$0');
987

    
988
define('CDM_WS_TERM_COMPARE', 'term/$0/compareTo/$1');
989

    
990
define('CDM_WS_TDWG_LEVEL', 'term/tdwg/$0');
991

    
992
/**
993
 * returns FeatureTrees that are stored in this community store
994
 *
995
 */
996
define('CDM_WS_FEATURETREE', 'featuretree/$0');
997

    
998
define('CDM_WS_FEATURETREES', 'featuretree');
999

    
1000
define('CDM_WS_GEOSERVICE_DISTRIBUTIONMAP', 'geo/map/distribution/$0');
(4-4/8)