Project

General

Profile

Download (59.3 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
// $Id$
3

    
4
/*
5
 * @file
6
 * cdm_dataportal
7
 *
8
 * Copyright (C) 2007 EDIT
9
 * European Distributed Institute of Taxonomy
10
 * http://www.e-taxonomy.eu
11
 *
12
 * The contents of this file are subject to the Mozilla Public License Version 1.1
13
 * See http://www.mozilla.org/MPL/MPL-1.1.html for the full license terms.
14
 */
15

    
16
require_once('node_types.php');
17
require_once('settings.php');
18
require_once('help.php');
19

    
20
require_once('theme/cdm_dataportal.common.theme');
21
require_once('theme/cdm_dataportal.descriptions.theme');
22
require_once('theme/cdm_dataportal.media.theme');
23
require_once('theme/cdm_dataportal.occurrence.theme');
24
require_once('theme/cdm_dataportal.page.theme');
25
require_once('theme/cdm_dataportal.taxon.theme');
26
require_once('theme/cdm_dataportal.name.theme');
27
require_once('theme/cdm_dataportal.references.theme');
28

    
29
require_once('classes/footnotemanager.php');
30
require_once('classes/footnote.php');
31
require_once('classes/footnotekey.php');
32
require_once('classes/renderhints.php');
33

    
34
function _add_js_progressbar(){
35
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/jquery.progressbar/js/jquery.progressbar.js');
36
}
37

    
38
function _add_js_treeselector(){
39
  //drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/treeselector.js');
40
  drupal_add_js("
41
    if (Drupal.jsEnabled) {
42
      $(document).ready(function() {
43
          $('#cdm-taxonomictree-selector-form #edit-val').change(function () {
44
              $('#cdm-taxonomictree-selector-form').submit();
45
          });
46

    
47
      });
48
    }", 'inline');
49
}
50

    
51
function _add_js_openlayers_map(){
52

    
53
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/OpenLayers/OpenLayers.js', 'core', 'header');
54
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/openlayers_map.js');
55

    
56
  $gmap_api_key = variable_get('gmap_api_key', 'ABQIAAAAFho6eHAcUOTHLmH9IYHAeBRi_j0U6kJrkFvY4-OX2XYmEAa76BTsyMmEq-tn6nFNtD2UdEGvfhvoCQ');
57

    
58
  $baseLayers = variable_get('baselayers', array());
59
  if(!is_array($baseLayers) || count($baseLayers) == 0){
60
    $baseLayers = array('metacarta_vmap0' => 'Metacarta Vmap0', 'PREFERRED' => 'metacarta_vmap0');
61
  }
62
  $layerNames = '';
63
  foreach($baseLayers as $layerName => $layerLabel){
64
    if($layerName == 'PREFERRED'){
65
      $preferredLayer = $baseLayers['PREFERRED'];
66
    } else {
67
      $layerNames .= ($layerNames ? ', ': '') . "'$layerName'";
68
    }
69
  }
70

    
71
  if( isset($baseLayers['gmap']) || isset($baseLayers['gsat']) || isset($baseLayers['ghyb']) ){
72
    drupal_set_html_head('<script src=http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key='.$gmap_api_key.'" type="text/javascript"></script>');
73
    drupal_set_html_head('<script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1" type="text/javascript"></script>');
74
  }
75

    
76
  drupal_add_js("
77
        if (Drupal.jsEnabled) {
78
          $(document).ready(function() {
79
              $('#openlayers_map').cdm_openlayers_map('"
80
              .getEDITMapServiceURI()."', {
81
                legendPosition: 3,
82
                displayWidth: '" . variable_get('cdm_dataportal_geoservice_display_width', false) . "',
83
                boundingBox: '" . variable_get('cdm_dataportal_geoservice_bounding_box', false) . "',
84
                distributionOpacity: '" . variable_get('cdm_dataportal_geoservice_distributionOpacity', '0.5') . "',
85
                legendOpacity: '" . variable_get('cdm_dataportal_geoservice_legendOpacity', '0.5') . "',
86
                showLayerSwitcher: " . (variable_get('cdm_dataportal_geoservice_showLayerSwitcher', TRUE) ? 'true':'false') . ",
87
                baseLayerNames: [".$layerNames."],
88
                defaultBaseLayerName: '".$preferredLayer."',
89
            });
90
          });
91
        }", 'inline');
92

    
93
}
94

    
95
/**
96
 *
97
 * Enter description here ...
98
 * @param unknown_type $width
99
 * @param unknown_type $occurrenceQuery
100
 * @param unknown_type $distributionQuery
101
 * @param unknown_type $legendFormatQuery
102
 * @param unknown_type $map_caption
103
 */
104
function get_image_map($width,  $bounding_box=false, $occurrenceQuery = false, $distributionQuery = false, $legendFormatQuery = false, $map_caption = false ){
105

    
106
  $server = getEDITMapServiceURI();
107

    
108
  if(!$server){
109
    //warning message
110
    drupal_set_message('No \'Geoservice Access Point\' has been set so far. '
111
    . 'Please configure the variable \'Geoservice Access Point\' here '
112
    . l('CDM Dataportal Settings', 'admin/settings/cdm_dataportal/geo'), 'warning');
113
    //message to render
114
    return "<p>No geoservice specified</p>";
115
  }
116

    
117
  // additional query parameters as set in the data portal admin section
118
  $labels_on = variable_get('cdm_dataportal_geoservice_labels_on', 0);
119

    
120
  $query_string .= '&image=true&recalculate=false&legend=1&ms=' . $width
121
    . ($bounding_box ? '&bbox=' .  $bounding_box : '')
122
    . ($labels_on ? '&label=' .  $labels_on : '');
123

    
124
  if($map_caption){
125
    $query_string .= '&mlp=3&mc_s=Georgia,15,blue&mc=' . $map_caption;
126
  }
127

    
128
  // either occurrence or distribution - combined maps will be possible in future
129
  if ($occurrenceQuery){
130

    
131
    $map_service_script_name = "points.php";
132

    
133
    //fix $occurrenceQuery
134
    $occurrenceQuery = str_replace("&image=false", "", $occurrenceQuery);
135
    //$occurrenceQuery .= '&l=v%3Aatbi%2Ce_w_0';
136
    $occurrenceQuery .= '&l=v:e_w_0';
137

    
138
    $query_string .= "&" .$occurrenceQuery;
139

    
140
  } else if($distributionQuery){
141

    
142
    $query_string .= "&" .$distributionQuery;
143

    
144
    $map_service_script_name = "areas.php";
145

    
146
    // apply Plain Image map settings
147
    if (getEDITMapServiceVersionNumber() >= 1.1){
148
      /*
149
       * example : title=a:Naturalized++non-invasive
150
      * &ad=cyprusdivs:bdcode:a:5&as=a:ff9900,,0.1,&l=tdwg4
151
      * &ms=500&bbox=32,34,35,36&img=true&legend=1&mlp=3
152
      * &mc_s=Georgia,15,blue&mc=&recalculate=false
153
      *
154
      * http://edit.br.fgov.be/edit_wp5/v1/rest_gen.php?
155
      * l=background_gis:b,cyprusdivs&ad=cyprusdivs%3Abdcode%3Aa%3A8%2C4
156
      * &as=a%3A339966%2C%2C0.1%2C|b:0000ff,,
157
      * &bbox=32%2C34%2C35%2C36&img=true&legend=1&mc=&mc_s=Georgia%2C15%2Cblue
158
      * &mlp=3&ms=500&recalculate=false&title=a%3Aindigenous
159
      */
160

    
161
      $map_service_script_name = "rest_gen.php";
162

    
163
      $bgcolor_areaStyleId= "y";
164
      $baselayer_areaStyleId= "z";
165
      $bgcolor_layer='';
166
      $additional_area_styles = array();
167

    
168
      // background color:
169
      if(variable_get('map_bg_color', '')){
170
        $bgcolor_layer = "background_gis:".$bgcolor_areaStyleId;
171
        $additional_area_styles[] = $bgcolor_areaStyleId . ":" . variable_get('map_bg_color', '') . ",,";
172
      }
173

    
174
      //TODO HACK to replace the default base layer which currently is tdwg4 !!!
175
      if(strpos($query_string, "?l=") !== FALSE){
176
        $layer_param_token = "?l=";
177
      } else {
178
        $layer_param_token = "&l=";
179
      }
180
      if(strpos($query_string, "?as=") !== FALSE){
181
        $areystyle_param_token = "?as=";
182
      } else {
183
        $areystyle_param_token = "&as=";
184
      }
185

    
186
      if(variable_get('map_base_layer', '')){
187
        $query_string = str_replace($layer_param_token."tdwg4", "$layer_param_token".variable_get('map_base_layer', ''). ":" . $baselayer_areaStyleId, $query_string);
188
      } else {
189
        $query_string = str_replace($layer_param_token."tdwg4", $layer_param_token."tdwg4:".$baselayer_areaStyleId . ",", $query_string);
190
      }
191

    
192
      if($bgcolor_layer){
193
        $query_string = str_replace($layer_param_token, $layer_param_token . $bgcolor_layer . ",", $query_string);
194
      }
195

    
196
      if(variable_get('map_base_layer_style', '')){
197
        $additional_area_styles[] = $baselayer_areaStyleId . ":" . variable_get('map_base_layer_style', '');
198
      }
199

    
200
      foreach ($additional_area_styles as $as) {
201
        $query_string = str_replace($areystyle_param_token, $areystyle_param_token . $as . "|", $query_string);
202
      }
203

    
204
    }
205
  } // end of if($distributionQuery)
206

    
207
  $mapUri = url("$server/$map_service_script_name?$query_string");
208
  $out = '<img class="distribution_map" src="' . $mapUri . '" alt="Map" />';
209
  // showing map caption
210
  if($map_caption){
211
    $out .= '<div class="distribution_map_caption">' . $map_caption . '</div>' . '<br />'; //FIXME: replace <br> by according css style
212
    $out .= '</div>';
213
  }
214

    
215
  return $out;
216

    
217

    
218
}
219

    
220
/**
221
 *
222
 * Enter description here ...
223
 * @param unknown_type $width
224
 * @param unknown_type $occurrenceQuery
225
 * @param unknown_type $distributionQuery
226
 * @param unknown_type $legendFormatQuery
227
 * @param unknown_type $map_caption
228
 */
229
function get_openlayers_map($width, $bounding_box=false, $occurrenceQuery = false, $distributionQuery = false, $legendFormatQuery = false, $map_caption = false ){
230

    
231
  _add_js_openlayers_map();
232

    
233
  $out = '<div id="openlayers">';
234
  $out .= '<div id="openlayers_map" class="smallmap"';
235
  $out .= ' style="width: ' . $width . 'px; height:'.( $width / 2).'px"';
236

    
237
  // additional query parameters as set in the data portal admin section
238
  $labels_on = variable_get('cdm_dataportal_geoservice_labels_on', 0);
239

    
240
  $openlayers_map_query_string .= '&img=false&ms=' . $width
241
    . ($bounding_box ? '&bbox=' .  $bounding_box : '')
242
    . ($labels_on ? '&label=' .  $labels_on : '');
243

    
244
  if($occurrenceQuery){
245
    //fix $occurrenceQuery
246
    $occurrenceQuery .= '&bbox=-180,-90,180,90';
247
    $occurrenceQuery .= '&l=v%3Aatbi%2Ce_w_0';
248
    //$occurrenceQuery .= '&l=v:e_w_0';
249
    $occurrenceQuery .= '&legend=0'; //TODO add to cdm service?
250

    
251
    $out .= ' occurrenceQuery="' . $occurrenceQuery . '&' . $openlayers_map_query_string . '"';
252
  }
253

    
254
  if($distributionQuery){
255
    $out .= ' distributionQuery="' . $distributionQuery . '&' . $openlayers_map_query_string . '"';
256
  }
257

    
258
  if($legendFormatQuery){
259
    $out .= ' legendFormatQuery="'.$legendFormatQuery.'"';
260
  }
261

    
262
  $out .= '></div></div>';
263

    
264
  // showing map caption
265
  if($map_caption){
266
    $out .= '<div class="distribution_map_caption">' . $map_caption . '</div>' . '<br />'; //FIXME: replace <br> by according css style
267
    $out .= '</div>';
268
  }
269
  return $out;
270
}
271

    
272
/* ====================== hook implementations ====================== */
273

    
274

    
275
/**
276
 * Implementation of hook_perm()
277
 *
278
 * Valid permissions for this module
279
 * @return array An array of valid permissions for the portfolio module
280
 */
281
function cdm_dataportal_perm() {
282
  return array(
283
      'administer cdm_dataportal',
284
      'cdm_dataportal view notes',
285
  //TODO which else permission are required? -> check the WP6 requirements document
286
  );
287
}
288

    
289

    
290
/**
291
 * Implementation of hook_menu()
292
 */
293
function cdm_dataportal_menu($may_cache) {
294
  $items = array();
295

    
296
  cdm_dataportal_menu_admin($may_cache, $items);
297
  cdm_dataportal_menu_help($may_cache, $items);
298

    
299
  if ($may_cache) {
300

    
301
   $items[] = array(
302
      'path' => 'cdm_dataportal/names',
303
      'callback' => 'cdm_dataportal_view_names',
304
      'access' => true,
305
      'type' => MENU_CALLBACK,
306
    );
307
    // optional callback arguments: page
308

    
309
    $items[] = array(
310
      'path' => 'cdm_dataportal/taxon',
311
      'callback' => 'cdm_dataportal_taxon_page_view',
312
      'access' => true,
313
      'type' => MENU_CALLBACK,
314
    // expected callback arguments: uuid
315
    );
316

    
317
    $items[] = array(
318
      'path' => 'cdm_dataportal/name',
319
      'callback' => 'cdm_dataportal_name_page_view',
320
      'access' => true,
321
      'type' => MENU_CALLBACK,
322
    // expected callback arguments: uuid
323
    );
324

    
325
    $items[] = array(
326
      'path' => 'cdm_dataportal/reference',
327
      'callback' => 'cdm_dataportal_view_reference',
328
      'access' => true,
329
      'type' => MENU_CALLBACK,
330
    // expected callback arguments: uuid
331
    );
332

    
333
    $items[] = array(
334
      'path' => 'cdm_dataportal/reference/list',
335
      'callback' => 'cdm_dataportal_view_reference_list',
336
      'access' => true,
337
      'type' => MENU_CALLBACK,
338
    // expected callback arguments: uuid
339
    );
340

    
341
    $items[] = array(
342
      'path' => 'cdm_dataportal/media',
343
      'callback' => 'cdm_dataportal_view_media',
344
      'access' => true,
345
      'type' => MENU_CALLBACK,
346
    // expected callback arguments: uuid, mediarepresentation_uuid, part_uuid or part#
347
    );
348

    
349
    $items[] = array(
350
      'path' => 'cdm_dataportal/polytomousKey',
351
      'callback' => 'cdm_dataportal_view_polytomousKey',
352
      'access' => true,
353
      'type' => MENU_CALLBACK,
354
    // expected callback arguments: polytomousKey->uuid
355
    );
356

    
357
    $items[] = array(
358
      'path' => 'cdm_dataportal/search',
359
      'callback' => 'cdm_dataportal_view_search_advanced',
360
      'access' => true,
361
      'type' => MENU_CALLBACK,
362
    );
363

    
364
    $items[] = array(
365
      'path' => 'cdm_dataportal/search/taxon',
366
      'callback' => 'cdm_dataportal_view_search_taxon',
367
      'access' => true,
368
      'type' => MENU_CALLBACK,
369
    );
370

    
371
    $items[] = array(
372
      'path' => 'cdm/xml2json',
373
      'callback' => 'cdm_view_xml2json',
374
      'access' => true,
375
      'type' => MENU_CALLBACK,
376
    );
377

    
378
  }elseif (arg(0)=='user' && ($uid=arg(1)) && is_numeric($uid)) {
379
    //user configuration of cdm_dataportal
380
    $items[] = array('path' => 'user/'.$uid.'/cdm_dataportal',
381
        'title' => t('cdm_dataportal'),
382
        'access' => TRUE,
383
        'callback' => 'drupal_get_form',
384
        'callback arguments' => array('cdm_dataportal_user_form'),
385
        'type' => MENU_LOCAL_TASK,
386
        'weight' => 10,
387
      );
388
  } else {
389
    // may not cache
390
    // --- local tasks for Taxon
391
    $items[] = array(
392
      'path' => 'cdm_dataportal/name/'.arg(2),
393
    //'callback' => 'cdm_dataportal_view_name',
394
      'callback' => 'cdm_dataportal_name_page_view',
395
      'callback arguments' => array(arg(2), arg(3), arg(4)),
396
      'access' => true,
397
      'type' => MENU_CALLBACK,
398
    );
399

    
400
    if(variable_get('cdm_dataportal_taxonpage_tabs', 1)) {
401

    
402
      $items[] = array(
403
      'path' => 'cdm_dataportal/taxon/'.arg(2),
404
      'title' => theme('cdm_taxonpage_tab', 'General'),
405
      'callback' => 'cdm_dataportal_taxon_page_view',
406
      'access' => true,
407
      'type' => MENU_CALLBACK,
408
      'weight' => 1,
409
      'callback arguments' => array(arg(2), "description")
410
      // expected callback arguments: name_uuid
411
      );
412

    
413
      $items[] = array(
414
      'path' => 'cdm_dataportal/taxon/'.arg(2).'/all',
415
      'title' => theme('cdm_taxonpage_tab', 'General'),
416
      'callback' => 'cdm_dataportal_taxon_page_view',
417
      'access' => true,
418
      'type' => MENU_CALLBACK,
419
      'weight' => 2,
420
      'callback arguments' => array(arg(2), "all")
421
      // expected callback arguments: name_uuid
422
      );
423

    
424
      $items[] = array(
425
      'path' => 'cdm_dataportal/taxon/'.arg(2).'/description',
426
      'title' => theme('cdm_taxonpage_tab', 'General'),
427
      'callback' => 'cdm_dataportal_taxon_page_view',
428
      'access' => true,
429
      'type' => MENU_DEFAULT_LOCAL_TASK,
430
      'weight' => 2,
431
      'callback arguments' => array(arg(2), "description")
432
      // expected callback arguments: name_uuid
433
      );
434

    
435
      $items[] = array(
436
      'path' => 'cdm_dataportal/taxon/'.arg(2).'/synonymy',
437
      'title' => theme('cdm_taxonpage_tab', 'Synonymy'),
438
      'callback' => 'cdm_dataportal_taxon_page_view',
439
      'access' => true,
440
      'type' => MENU_LOCAL_TASK,
441
      'weight' => 4,
442
      'callback arguments' => array(arg(2), "synonymy", arg(4))
443
      // expected callback arguments: name_uuid
444
      );
445
      $items[] = array(
446
      'path' => 'cdm_dataportal/taxon/'.arg(2).'/images',
447
      'title' => theme('cdm_taxonpage_tab', 'Images'),
448
      'callback' => 'cdm_dataportal_taxon_page_view',
449
      'access' => true,
450
      'type' => MENU_LOCAL_TASK,
451
      'weight' => 5,
452
      'callback arguments' => array(arg(2), "images")
453
      // expected callback arguments: name_uuid
454
      );
455

    
456
     $items[] = array(
457
     'path' => 'cdm_dataportal/taxon/'.arg(2).'/specimens',
458
     'title' => theme('cdm_taxonpage_tab', 'Specimens'),
459
     'callback' => 'cdm_dataportal_taxon_page_view',
460
     'access' => true,
461
     'type' => MENU_LOCAL_TASK,
462
     'weight' => 6,
463
     'callback arguments' => array(arg(2), "specimens")
464
     // expected callback arguments: name_uuid
465
     );
466

    
467
     $items[] = array(
468
     'path' => 'cdm_dataportal/taxon/'.arg(2).'/keys',
469
     'title' => theme('cdm_taxonpage_tab', 'Keys'),
470
     'callback' => 'cdm_dataportal_taxon_page_view',
471
     'access' => true,
472
     'type' => MENU_LOCAL_TASK,
473
     'weight' => 6,
474
     'callback arguments' => array(arg(2), "keys")
475
     // expected callback arguments: name_uuid
476
     );
477
    }
478
  }
479

    
480
  drupal_add_css(drupal_get_path('module', 'cdm_dataportal').'/cdm_dataportal.css');
481
  //drupal_add_css(drupal_get_path('module', 'cdm_dataportal').'/cdm_dataportal_print.css', 'print');
482
  drupal_add_css(drupal_get_path('module', 'cdm_dataportal').'/cdm_dataportal_screen.css', 'screen');
483

    
484
  return $items;
485

    
486
}
487
/**
488
 * The function generate form for own user cdm dataportal configurations
489
 */
490
function cdm_dataportal_user_form() {
491

    
492
  global $user;
493
    $checkbox_value = 'cdm_dataportal_' .$user->uid . '_default_tab_active';
494

    
495
  $form['check'] = array
496
    (
497
    '#type'            => 'checkbox',
498
    '#title'         => t('Activate user default configuration'),
499
    '#default_value'   => variable_get($checkbox_value, 0),
500
    '#description' => t('Check this if you want configure your own default tab from the below menu.')
501
    );
502

    
503
  $form['cdm_dataportal_user_form'] =  array(
504
      '#type'          => 'select',
505
      '#title'         => t('Default tab to display'),
506
      '#default_value' => get_default_taxon_tab(true),
507
      '#options'       => unserialize(CDM_DATAPORTAL_DEFAULT_TAXON_TAB),
508
      '#description'   => t('<p>Select the default tab to display when visiting a taxon page. Only available if Tabbed Taxon Page is enable.</p>
509
              <strong>Note:</strong> After performing a search and clicking in any synonym, the taxon tab
510
              to be renderized will be the synonymy of the accepted taxon and not the above selected tab.'),
511
  );
512

    
513
  $form['submit'] = array(
514
    '#type' => 'submit',
515
    '#value' => t('Submit')
516
  );
517

    
518
  return $form;
519
}
520

    
521
/**
522
 * The function submit the user cdm dataportal configurations
523
 * @param unknown_type $form
524
 * @param unknown_type $form_values
525
 */
526
function cdm_dataportal_user_form_submit($form, $form_values) {
527
  global $user;
528
  $msg_type = 'status';
529
  $username = $user->name;
530
  $variable_to_use = 'cdm_dataportal_' .$user->uid . '_default_tab';
531

    
532
  //if is the right user the variables are setted
533
  if (arg(0)=='user' && ($uid=arg(1)) && is_numeric($uid) && $user->uid==$uid){
534
    $variable = unserialize(CDM_DATAPORTAL_DEFAULT_TAXON_TAB);
535
    variable_set($variable_to_use . '_active', $form_values['check']);
536
    variable_set($variable_to_use, $form_values['cdm_dataportal_user_form']);
537
    if ($form_values['check']){
538
      drupal_set_message('The user default tab will be used for the next taxon site visit.');
539
      drupal_set_message('The user default tab have been changed to: '
540
            . $variable[variable_get($variable_to_use, 0)]
541
            . ' for the user ' . $username, $msg_type);
542
    }else{
543
      drupal_set_message('The user default tab wont be used for the next taxon site, check the box if you want to use the user default configuration.');
544
    }
545
  //problem with the user id => variables wont be saved
546
  }else{
547
    $msg_type = 'warning';
548
    drupal_set_message('Default tab have not been saved due to user id problems', $msg_type);
549
  }
550
}
551

    
552
/**
553
 * Implementation of hook_block()
554
 *
555
 * Provides the following blocks:
556
 *  0: list of links useful during development
557
 *
558
 * @param String $op
559
 * @param int $delta
560
 */
561
function cdm_dataportal_block($op='list', $delta=0) {
562
  // listing of blocks, such as on the admin/block page
563
  if ($op == "list") {
564
    //$block[0]["info"] = t("CDM DataPortal DevLinks");
565
    //		$block[1]["info"] = t("CDM DataPortal Credits");
566
    $block[2]["info"] = t("CDM Search Taxa");
567
    //$block[3]["info"] = t("CDM Filters");
568
    $block[4]["info"] = t("CDM Dataportal Print");
569
    $block["keys"]["info"] = t("CDM identification keys");
570
    return $block;
571
  }
572
  else if ($op == 'view') {
573
    switch($delta){
574
      //			case 1:
575
      //				$block['subject'] = t('Credits');
576
      //				$block['content'] = theme('cdm_credits');
577
      //				return $block;
578
      case 2:
579
        $block['subject'] = t('Search taxa');
580
        $block['content'] = drupal_get_form('cdm_dataportal_search_taxon_form');
581
        if (variable_get('cdm_dataportal_show_advanced_search', 1)){
582
            $block['content'] .= '<div>'.l('Advanced Search', '/cdm_dataportal/search').'</div>';
583
        }
584
        return $block;
585
      case 4:
586
        $block['subject'] = t('<none>');
587
        $block['content'] = theme('cdm_print_button');;
588
        return $block;
589
      case "keys":
590
        $block['subject'] = t('Identification Keys');
591
        $block['content'] = theme('cdm_block_IdentificationKeys');
592
        return $block;
593
    }
594
  }
595
}
596

    
597

    
598

    
599
/*
600
 function cdm_dataportal_session_clear($cdm_ws_uri_update = false){
601
 $_SESSION['cdm'] = null;
602
 if(is_string($cdm_ws_uri_update)){
603
 $_SESSION['cdm'] = array('ws_uri'=>$cdm_ws_uri_update);
604
 }
605
 }
606

    
607
 function cdm_dataportal_session_validate(){
608

    
609
 if(!isset($_SESSION['cdm']['ws_uri'])){
610
 $_SESSION['cdm'] = array('ws_uri'=>variable_get('cdm_webservice_url', false));
611
 } else if($_SESSION['cdm']['ws_uri'] != variable_get('cdm_webservice_url', false)){
612
 cdm_dataportal_session_clear(variable_get('cdm_webservice_url', false));
613
 }
614
 }
615
 */
616

    
617
function cdm_dataportal_search_taxon_form($advancedForm = false){
618

    
619
  $preset_query = (isset($_SESSION['cdm']['search']['query']) ? $_SESSION['cdm']['search']['query'] : '');
620
  $preset_doTaxa = (isset($_SESSION['cdm']['search']['doTaxa']) ? 1 : 0);
621
  $preset_doSynonyms = (isset($_SESSION['cdm']['search']['doSynonyms']) ? 1 : 0);
622
  $preset_doTaxaByCommonNames = (isset($_SESSION['cdm']['search']['doTaxaByCommonNames']) ? 1 : 0);
623
  $tdwg_level_select =  (isset($_SESSION['cdm']['search']['tdwg_level_select']) ? $_SESSION['cdm']['search']['tdwg_level_select'] : 2);
624
  $selected_areas =  (isset($_SESSION['cdm']['search']['area']) ? $_SESSION['cdm']['search']['area'] : false);
625

    
626
  $url = 'cdm_dataportal/search/taxon';
627
  $form['#method'] = 'get';
628
  $form['#process'] = array('cdm_dataportal_search_process' => array());
629
  $form['#action'] = url($url, NULL, NULL, true);
630

    
631
  $form['query'] = array(
632
    '#delta' => 0,
633
    '#type' => 'textfield',
634
    '#size' => 20,
635
    '#attributes' => array('title' => t('Enter the name or part of a name you wish to search for. The asterisk  character * can always be used as wildcard')),
636
    '#value' => $preset_query,
637
  );
638

    
639
  $form['search'] = array(
640
      '#delta' => 1,
641
      '#tree' => true,
642
  //'#type' => $advancedForm ? 'fieldset': 'hidden',
643
      '#title' => t('Options')
644
  );
645

    
646
  $form['search']['tree'] = array(
647
    '#delta' => -1,
648
    '#type' => 'hidden',
649
    '#value' => get_taxonomictree_uuid_selected()
650
  );
651

    
652

    
653
  // clean URL get forms breaks if we don't give it a 'q'.
654
  if (!(bool)variable_get('clean_url', '0')) {
655
    $form['search']['q'] = array(
656
      '#delta' => -1,
657
      '#type' => 'hidden',
658
      '#value' => $url,
659
      '#name' => 'q',
660
    );
661
  }
662

    
663
  $form['search']['pageSize'] = array(
664
      '#delta' => -1,
665
      '#type' => 'hidden',
666
      '#value' => variable_get('cdm_dataportal_search_items_on_page', 25)
667
  );
668

    
669
  $form['search']['pageNumber'] = array(
670
      '#delta' => -1,
671
      '#type' => 'hidden',
672
      '#value' => 0
673
  );
674

    
675
  if($advancedForm){
676
    // general search parameters
677
    $form['search']['doTaxa'] = array(
678
      '#delta' => 2,
679
      '#type' => 'checkbox',
680
      '#title' => t('Search for accepted taxa'),
681
      '#value' => $preset_doTaxa
682
    );
683
    $form['search']['doSynonyms'] = array(
684
      '#delta' => 3,
685
      '#type' => 'checkbox',
686
      '#title' => t('Search for synonyms'),
687
      '#value' => $preset_doSynonyms
688
    );
689
    $form['search']['doTaxaByCommonNames'] = array(
690
      '#delta' => 4,
691
      '#type' => 'checkbox',
692
      '#title' => t('Search for common names'),
693
      '#value' => $preset_doTaxaByCommonNames
694
    );
695

    
696
    // Geographic Range
697
    $form['search']['geographic_range'] = array(
698
      '#type' => 'fieldset',
699
      '#delta' => 5,
700
      '#tree' => true,
701
      '#title' => t('Geographic range'),
702
    );
703

    
704
    $form['search']['geographic_range']['tdwg_level_select'] = array(
705
    '#type' => 'radios',
706
    '#title' => t('Select a TDWG distribution level and code'),
707
    '#default_value' => $tdwg_level_select,
708
    '#options' => array(
709
    t('TDWG level-1, i.e. a continent'),
710
    t('TDWG level-2'),
711
    t('TDWG level-3, i.e. a country'),
712
    t('TDWG level-4')
713
    )
714
    );
715
    $tdwg[1] = cdm_ws_get(CDM_WS_TDWG_LEVEL, '1');
716
    $tdwg[2] = cdm_ws_get(CDM_WS_TDWG_LEVEL, '2');
717
    $tdwg[3] = cdm_ws_get(CDM_WS_TDWG_LEVEL, '3');
718
    $tdwg[4] = cdm_ws_get(CDM_WS_TDWG_LEVEL, '4');
719

    
720
    $tdwg_js = '';
721
    foreach($tdwg as $key=>$tdwg_level){
722
      $tdwgOptions = array();
723
      $tdwgOptionsSelected = array();
724
      foreach($tdwg_level as $area){
725
        $representation = $area->representations[0];
726
        $tdwgOptions[$representation->abbreviatedLabel] = $area->representation_L10n;
727
        if(is_array($selected_areas) && in_array($representation->abbreviatedLabel, $selected_areas)){
728
          $tdwgOptionsSelected[] = $representation->abbreviatedLabel; //$area->uuid;
729
        }
730
      }
731
      asort($tdwgOptions);
732
      $form['search']['geographic_range']['tdwg_level_'.$key] = array(
733
        '#type' => 'select',
734
        '#title'         => t('TDWG level').' '.$key,
735
        '#default_value' => $tdwgOptionsSelected,
736
        '#multiple' => TRUE,
737
        '#options' => $tdwgOptions
738
      );
739
      $tdwg_js .= "$('#edit-search-geographic-range-tdwg-level-$key').parent()".($tdwg_level_select + 1 == $key ?  '.show()' : '.hide()'). ";\n";
740
    }
741

    
742
    drupal_add_js(
743
    "$(document).ready(function(){
744

    
745
      $(\"input[@name='search[geographic_range][tdwg_level_select]']\").change(
746
        function(event){
747
          var selectId = $(\"input[@name='search[geographic_range][tdwg_level_select]']:checked\").val();
748
          var i;
749
          for(i = 0; i < 4; i++){
750
            if(selectId == i){
751
              $('#edit-search-geographic-range-tdwg-level-' + (i + 1) ).parent().fadeIn('slow');
752
              $('#edit-search-geographic-range-tdwg-level-' + (i + 1)).children().removeAttr('selected');
753
            } else {
754
              $('#edit-search-geographic-range-tdwg-level-' + (i + 1)).parent().fadeOut('slow');
755
              $('#edit-search-geographic-range-tdwg-level-' + (i + 1)).children().removeAttr('selected');
756
            }
757
          }
758
        }
759
      );
760

    
761
      $tdwg_js
762
    });",
763
    'inline');
764

    
765
  } else {
766
    $form['search']['doTaxa'] = array(
767
        '#delta' => -2,
768
        '#type' => 'hidden',
769
        '#value' => 1
770
    );
771
    $form['search']['doSynonyms'] = array(
772
        '#delta' => -3,
773
        '#type' => 'hidden',
774
        '#value' => 1
775
    );
776
    $form['search']['doTaxaByCommonNames'] = array(
777
        '#delta' => -4,
778
        '#type' => 'hidden',
779
        '#value' => 0
780
    );
781
  }
782

    
783
  $form['submit'] = array(
784
    '#delta' => 9,
785
    '#type' => 'submit',
786
    '#name' => '',
787
    '#value' => t('Search')
788
  );
789

    
790
  return $form;
791
}
792

    
793
function cdm_dataportal_search_taxon_form_advanced(){
794
  return cdm_dataportal_search_taxon_form(true);
795
}
796

    
797
function cdm_taxonomictree_selector(){
798
  _add_js_treeselector();
799

    
800
  $out = drupal_get_form('cdm_taxonomictree_selector_form');
801

    
802
  return $out;
803
}
804

    
805

    
806
function cdm_taxonomictree_selector_form(){
807

    
808
  $url = url('cdm_api/setvalue/session', null);
809
  $form['#action'] = $url;
810

    
811
  $form['var'] = array(
812
        '#delta' => -3,
813
        '#type' => 'hidden',
814
        '#value' => '[cdm][taxonomictree_uuid]'
815
        );
816

    
817
        $form['destination'] = array(
818
     '#delta' => -3,
819
     '#type' => 'hidden',
820
     '#value' => substr(drupal_get_destination(), strlen('destination='))
821
        );
822

    
823
        $form['val'] = array(
824
      '#type' => 'select',
825
      '#title'         => t('Available classifications'),
826
      '#default_value' => get_taxonomictree_uuid_selected(),
827
      '#options' => cdm_get_taxontrees_as_options()
828
        );
829

    
830
        return $form;
831

    
832
}
833

    
834
/**
835
 * Implementation #process method call, see form_builder()
836
 * <p>
837
 * Removes Drupal internal form elements from query
838
 * @param $form
839
 * @return unknown_type
840
 */
841
function cdm_dataportal_search_process($form) {
842
  unset($form['form_id']);
843
  unset($form['form_token']);
844
  return $form;
845
}
846

    
847
/**
848
 * Filters $_REQUEST by a list of valid request  parameters and also sets defaults if required.
849
 * returns the processed request parameters submitted by the search form.
850
 */
851
function cdm_dataportal_search_form_request(){
852

    
853

    
854
  $form_params = array();
855
  array_deep_copy($_REQUEST['search'], $form_params);
856
  $form_params['query'] =  trim($_REQUEST['query']);
857

    
858
  // split of  geographic range
859
  if(isset($_REQUEST['search']['geographic_range'])){
860
    $geographicRange = $_REQUEST['search']['geographic_range'];
861
    // remove
862
    unset($form_params['geographic_range']);
863
  }
864

    
865
  // add geographic range
866
  if($geographicRange){
867
    $form_params['tdwg_level_select'] = $geographicRange['tdwg_level_select'];
868
    for($i = 1; $i < 5; $i++){
869
      if(isset($geographicRange['tdwg_level_'.$i])){
870
        $form_params['area'] = $geographicRange['tdwg_level_'.$i];
871
      }
872
    }
873
  }
874

    
875
  // store in session
876
  $_SESSION['cdm']['search'] = $form_params;
877

    
878
  return $form_params;
879
}
880

    
881

    
882
/* UNREACHABLE since action of form directly links to view
883
 function cdm_dataportal_search_taxon_form_submit($form_id, $form_values) {
884

    
885
 $_SESSION['cdm']['search'] = $form_values;
886
 //return '/cdm_dataportal/search/taxon/'.$form_values['queryString'].'/'.($form_values['vernacular']?'1':'0').'/'.$form_values['language'];
887
 return '/cdm_dataportal/search/taxon/'.$form_values['queryString'].'/'.($form_values['onlyAccepted']?'1':'0');
888
 //$paramstr = compose_url_prameterstr($form_values);
889
 //return url('/cdm_dataportal/search/taxon/', $paramstr);
890
 }
891
 */
892
/* ====================== menu callback functions ====================== */
893

    
894

    
895

    
896
function cdm_dataportal_form_alter($form_id, &$form) {
897

    
898
  static $comment_node_disabled =  0;
899
  static $comment_node_read_only =  1;
900
  static $comment_node_read_write =  2;
901

    
902

    
903
  if ($form_id == 'node_type_form'
904
  && isset($form['identity']['type'])
905
  && array_key_exists($form['#node_type']->type, cdm_get_nodetypes())
906
  ) {
907
    $form['workflow']['comment'] = array(
908
      '#type' => 'radios',
909
      '#title' => t('Default comment setting'),
910
      '#default_value' => variable_get('comment_'. $form['#node_type']->type, $comment_node_disabled),
911
      '#options' => array(t('Disabled'), t('Read only'), t('Read/Write')),
912
      '#description' => t('Users with the <em>administer comments</em> permission will be able to override this setting.'),
913
    );
914
  }
915
}
916

    
917

    
918

    
919
function cdm_dataportal_create_gallery_settings_form($form_name, $form_tittle, $collapsed, $form_description = ''){
920
//TODO move into settings.php
921
  $form[$form_name] = array(
922
    '#type' => 'fieldset',
923
    '#title' => t($form_tittle),
924
    '#collapsible' => TRUE,
925
    '#collapsed' => $collapsed,
926
    '#tree' => true,
927
  '#description' => t($form_description),
928
  );
929

    
930
  $default_values = unserialize(CDM_DATAPORTAL_GALLERY_SETTINGS);
931
  $gallery_settings = variable_get($form_name, $default_values);
932
  //$test = variable_get('cdm_dataportal_search_items_on_page', CDM_DATAPORTAL_SEARCH_ITEMS_ON_PAGE);
933

    
934
  if($form_name == CDM_DATAPORTAL_SEARCH_GALLERY_NAME){
935
    /* TODO: why cdm_dataportal_search_items_on_page does not save the value on $test???
936
     $form[$form_name]['cdm_dataportal_search_items_on_page'] = array(
937
     '#type' => 'textfield',
938
     '#title' => t('Search Page Size'),
939
     '#default_value' => $test,
940
     '#description' => t('Number of Names to display per page in search results.')
941
     );
942
     */
943
    $form[$form_name]['cdm_dataportal_show_taxon_thumbnails'] = array(
944
      '#type' => 'checkbox',
945
      '#title' => t('Show media thumbnails for accepted taxa'),
946
      '#default_value' => $gallery_settings['cdm_dataportal_show_taxon_thumbnails'],
947
    );
948

    
949
    $form[$form_name]['cdm_dataportal_show_synonym_thumbnails'] = array(
950
      '#type' => 'checkbox',
951
      '#title' => t('Show media thumbnails for synonyms'),
952
      '#default_value' => $gallery_settings['cdm_dataportal_show_synonym_thumbnails'],
953
      '#description' => t('')
954
    );
955
  }
956

    
957
  //$showCaption = variable_get('cdm_dataportal_findtaxa_show_thumbnail_captions', 0);
958
  $form[$form_name]['cdm_dataportal_show_thumbnail_captions'] = array(
959
    '#type' => 'checkbox',
960
    '#title' => t('Show captions under thumbnails'),
961
    '#default_value' => $gallery_settings['cdm_dataportal_show_thumbnail_captions'],
962
    '#description' => t('')
963
  );
964

    
965
  $form[$form_name]['cdm_dataportal_media_maxextend'] = array(
966
    '#type' => 'textfield',
967
    '#title' => t('Thumbnail size'),
968
    '#default_value' => $gallery_settings['cdm_dataportal_media_maxextend'],
969
    '#description' => t('Select the size of each individual thumbnail.')
970
  );
971

    
972
  if($form_name != CDM_DATAPORTAL_MEDIA_GALLERY_NAME){
973
     $form[$form_name]['cdm_dataportal_media_cols'] = array(
974
        '#type' => 'textfield',
975
        '#title' => t('Number of columns'),
976
        '#default_value' => $gallery_settings['cdm_dataportal_media_cols'],
977
        '#description' => t('Group the thumbnails in columns: select how many columns should the gallery display.')
978
     );
979
  }
980

    
981
  if($form_name == CDM_DATAPORTAL_SEARCH_GALLERY_NAME){
982
    $form[$form_name]['cdm_dataportal_media_maxRows'] = array(
983
      '#type' => 'textfield',
984
      '#title' => t('Maximum number of rows'),
985
      '#default_value' => $gallery_settings['cdm_dataportal_media_maxRows'],
986
      '#description' => t('You can group the thumbnails in rows, select in how many rows should be the thumbnails grouped.<br>
987
                           <b>Note:</b> If you want an unlimited number of rows please set to 0')
988
    );
989
  }
990

    
991
  return $form;
992
}
993

    
994

    
995
/**
996
 * Displays a list of the known taxonomic names. Long lists are split up into multiple pages
997
 *
998
 * TODO: parameters are still preliminar
999
 * @param String $page page number to diplay defaults to page 1
1000
 * @param boolean $hide_unaccepted whether to hide nams which are not accepted by the current view
1001
 */
1002
function cdm_dataportal_view_names($beginsWith = 'A', $page = 1, $onlyAccepted = false ){
1003

    
1004
  $request_params  = array(
1005
    'q' => $beginsWith,
1006
  //'sec' = '',
1007
  //'higherTaxa' => getFiters(),
1008
  // 'matchAnywhere' => false, // default is false
1009
    'page' => $page,
1010
    'onlyAccepted' => $onlyAccepted,
1011
    'pagesize' => 20  /*$_SESSION['cdm']['namelist_pagesize'] */);
1012

    
1013
  $taxonPager = cdm_ws_find(CDM_WS_PORTAL_TAXON_FIND, $request_params);
1014
  /*
1015
   * FIXME the filter for accepted names will be a form element, thus this widget
1016
   * should be generated via form api preferably as block
1017
   */
1018
  //$out  = theme('cdm_dataportal_widget_filter_accepted', $onlyAccepted);
1019
  //$out .= theme('cdm_dataportal_widget_names_list', $names, $page);
1020
  $out .= theme('cdm_listof_taxa', $taxonPager);
1021
  return $out;
1022
}
1023

    
1024
function cdm_dataportal_view_reference($uuid, $arg2 = null){
1025
  $reference = cdm_ws_get(CDM_WS_REFERENCE, $uuid);
1026
  return theme('cdm_reference_page', $reference);
1027
}
1028

    
1029
function cdm_dataportal_view_reference_list($pageNumber){
1030
  $referencePager = cdm_ws_page(CDM_WS_REFERENCE, variable_get('cdm_dataportal_search_items_on_page', CDM_DATAPORTAL_SEARCH_ITEMS_ON_PAGE), $pageNumber);
1031
  return theme('cdm_reference_pager', $referencePager, 'cdm_dataportal/reference/list/');
1032
}
1033

    
1034
function cdm_dataportal_view_media($mediaUuid, $mediarepresentation_uuid = false, $part = 0){
1035
  $media = cdm_ws_get(CDM_WS_PORTAL_MEDIA, $mediaUuid);
1036
  return theme('cdm_media_page', $media, $mediarepresentation_uuid, $part);
1037
}
1038

    
1039
function _load_taxonBase(&$taxonBase){
1040
  if(isset($taxonBase->uuid)){
1041
      $taxonBase->name = cdm_ws_get(CDM_WS_TAXON, array($taxonBase->uuid, "name"));
1042
      $taxonBase->name->taggedName = cdm_ws_get(CDM_WS_NAME, array($taxonBase->name->uuid, "taggedName"));
1043
      $taxonBase->name->nomenclaturalReference = cdm_ws_get(CDM_WS_NAME, array($taxonBase->name->uuid, "nomenclaturalReference"));
1044
    }
1045
}
1046

    
1047
/**
1048
 * similar to the variable_get() function of Drupal, except of thst this function
1049
 * is able to handle arrays correctly. This function is especially useful
1050
 * when dealing with collections of setting form elemens (#tree = true)
1051
 *
1052
 * @param String $variableKey
1053
 * @param String $defaultValueString a sting as for example derived from a CONSTANT
1054
 * @return mixed, usually an array
1055
 */
1056
function mixed_variable_get($variableKey, $defaultValueString){
1057
    $systemDefaults = unserialize($defaultValueString);
1058
    $storedSettings = variable_get($variableKey, array());
1059
    if(is_array($storedSettings)){
1060
      $settings =  array_merge($systemDefaults, $storedSettings);
1061
    } else {
1062
      $settings = $systemDefaults;
1063
    }
1064
    return $settings;
1065
}
1066

    
1067
/**
1068
 * Loads the subgraph of the given PolytomousKeyNode recursively from the cdm REST service.
1069
 * @param PolytomousKeyNode $polytomousKeyNode passed by reference
1070
 * @return nothing
1071
 */
1072
function _load_polytomousKeySubGraph(&$polytomousKeyNode){
1073

    
1074
  if(!$polytomousKeyNode){
1075
    return;
1076
  }
1077
  if($polytomousKeyNode->class != "PolytomousKeyNode"){
1078
    drupal_set_message("_load_polytomousKeySubGraph() invalid type given.", "error");
1079
    return;
1080
  }
1081
  if(!is_uuid($polytomousKeyNode->uuid)){
1082
    drupal_set_message("_load_polytomousKeySubGraph() invalid type given.", "error");
1083
    return;
1084
  }
1085

    
1086
  $polytomousKeyNode = cdm_ws_get(CDM_WS_POLYTOMOUSKEY_NODE, $polytomousKeyNode->uuid);
1087

    
1088
  if(!$polytomousKeyNode){
1089
    //drupal_set_message("_load_polytomousKeyChildNodes() : could not load polytomousKeyNode", "error");
1090
    return;
1091
  }
1092

    
1093
  // load children
1094
  foreach($polytomousKeyNode->children as &$childNode){
1095
    _load_polytomousKeySubGraph($childNode);
1096
  }
1097

    
1098
  // load subkey
1099
  $polytomousKeyNode->subkey = cdm_ws_get(CDM_WS_POLYTOMOUSKEY_NODE, array($polytomousKeyNode->uuid, "subkey"));
1100

    
1101
  // load taxon
1102
  $polytomousKeyNode->taxon = cdm_ws_get(CDM_WS_POLYTOMOUSKEY_NODE, array($polytomousKeyNode->uuid, "taxon"));
1103
  _load_taxonBase($polytomousKeyNode->taxon);
1104
  return;
1105
}
1106

    
1107
function cdm_dataportal_view_polytomousKey($polytomousKeyUuid){
1108
  $polytomousKey = cdm_ws_get(CDM_WS_POLYTOMOUSKEY, $polytomousKeyUuid);
1109

    
1110
  $sourcePager = cdm_ws_get(CDM_WS_POLYTOMOUSKEY, array($polytomousKeyUuid, "sources"));
1111
  if(is_array($sourcePager->records)){
1112
    $polytomousKey->sources =  $sourcePager->records;
1113
    //$polytomousKey->sources->citation = cdm_ws_get(CDM_WS_POLYTOMOUSKEY, array($polytomousKeyUuid, "sources"));
1114
  }
1115

    
1116
  $annotationPager = cdm_ws_get(CDM_WS_POLYTOMOUSKEY, array($polytomousKeyUuid, "annotations"));
1117
  if(is_array($annotationPager->records)){
1118
    $polytomousKey->annotations = $annotationPager->records;
1119
  }
1120

    
1121
  _load_polytomousKeySubGraph($polytomousKey->root);
1122
  return theme('cdm_polytomousKey_page', $polytomousKey);
1123
}
1124

    
1125
/**
1126
 * The taxon page gives detailed information on a taxon, it shows:
1127
 *  - Taxon name
1128
 *  - Full list of synonyms homotypic synonyms on top, followed by the
1129
 *    heterotypic and finally followed by misapplied names.
1130
 *    The list is ordered historically.
1131
 *  - All description associated with the taxon.
1132
 *
1133
 * @param $uuid
1134
 * @param $chapter name of the part to display,
1135
 *         valid values are: 'description', 'images', 'synonymy', 'specimens', 'all'
1136
 * @return unknown_type
1137
 */
1138
function cdm_dataportal_taxon_page_view($uuid, $chapter = 'all', $synonym_uuid = null){
1139
  // display the page for the taxon defined by $uuid
1140
  set_last_taxon_page_tab(arg(3));
1141
  $taxonpage = cdm_dataportal_taxon_view($uuid, $chapter, $synonym_uuid);
1142
  return cdm_node_show(NODETYPE_TAXON, $uuid, $taxonpage->title , $taxonpage->content);
1143
}
1144

    
1145
/**
1146
 * @param $uuid
1147
 * @param $chapter name of the part to display,
1148
 *         valid values are: 'description', 'images', 'synonymy', 'all'
1149
 * @return unknown_type
1150
 */
1151
function cdm_dataportal_taxon_view($uuid, $chapter = 'all', $synonym_uuid = null){
1152
  $taxon = cdm_ws_get(CDM_WS_PORTAL_TAXON, $uuid);
1153
  if(!$taxon){
1154
    drupal_set_title(t('Taxon does not exist'));
1155
    return false;
1156
  }
1157

    
1158
  $taxonpage->title = theme('cdm_taxon_page_title', $taxon, $uuid, $synonym_uuid);
1159

    
1160
  // check if the taxon id contained in the currently selected tree
1161
  $taxon_in_current_tree = taxon_in_current_tree($uuid);
1162
  $taxon_nodes = cdm_ws_get(CDM_WS_PORTAL_TAXON_TAXONNODES, $uuid);
1163
  if(!$taxon_in_current_tree){
1164
    if(count($taxon_nodes) == 0){
1165
      drupal_set_message('This concept of the taxon '.theme('cdm_taxonName', $taxon->name).' is not contained any classification.'
1166
      ,'warning');
1167
    } else {
1168
      $trees = '';
1169
      foreach($taxon_nodes as $node){
1170
        $trees .= ($trees?', ':'').'<strong>'.$node->classification->titleCache.'</strong>';
1171

    
1172
      }
1173
      drupal_set_message('This concept of the taxon '.theme('cdm_taxonName', $taxon->name).' is not contained in the currently chosen classification, but in '
1174
      .(count($taxon_nodes) > 1? ' one of these: ' : ' this one: ') . $trees
1175
      , 'warning');
1176
    }
1177
  }
1178

    
1179
  // render the taxon page
1180
  $taxonpage->content = theme('cdm_taxon_page', $taxon, $chapter);
1181

    
1182
  return $taxonpage;
1183
}
1184

    
1185
/**
1186
 * The function returns a name page as a drupal node ready to be renderized by drupal.
1187
 * The node page show the taxon name title and the list of taxon related with such taxon
1188
 * name on the tree already in used.
1189
 * @param $taxon_name_uuid A taxon name uuid
1190
 * @return The formatted name page as node
1191
 */
1192
function cdm_dataportal_name_page_view($taxon_name_uuid, $taxon_to_hide_uuid, $synonym_uuid = null){
1193
  $taxonname_page = cdm_dataportal_name_view($taxon_name_uuid, $taxon_to_hide_uuid, $synonym_uuid);
1194
  return cdm_node_show(NODETYPE_NAME, $taxon_name_uuid, $taxonname_page->title , $taxonname_page->content);
1195
}
1196

    
1197
/**
1198
 * The function genates a object ready to be transformated to a node
1199
 * in order to show as a drupal node
1200
 * @param $taxon_name_uuid
1201
 * @return the object with the page content and title
1202
 */
1203
function cdm_dataportal_name_view($taxon_name_uuid, $taxon_to_hide_uuid, $synonym_uuid = null){
1204
  //getting the full taxonname object from the server
1205
  $taxon_name = cdm_ws_get(CDM_WS_NAME, array($taxon_name_uuid));
1206
  if(!$taxon_name){
1207
    drupal_set_title(t('Taxon name does not exist'));
1208
    return false;
1209
  }
1210
  //searching for all the taxa connected with the taxon name on the tree in used
1211
  $name_cache = cdm_ws_get(CDM_WS_NAME_NAMECAHE, array($taxon_name_uuid));
1212
  $request_params = array();
1213
  $request_params['query'] = $name_cache;
1214
  $request_params['tree'] = get_taxonomictree_uuid_selected();
1215
  $request_params['doTaxa'] = 1;
1216
  $request_params['doSynonyms'] = 1;
1217
  $request_params['doTaxaByCommonNames'] = 0;
1218
  $request_params['matchMode'] = "EXACT";
1219
  $taxon_pager = cdm_ws_get(CDM_WS_PORTAL_TAXON_FIND, null, queryString($request_params));
1220

    
1221
  //removing the name where we come from and
1222
  foreach($taxon_pager->records as $k=>&$taxon){
1223
    if($taxon->uuid == $taxon_to_hide_uuid){
1224
      unset($taxon_pager->records[$k]);
1225
    }
1226
  }
1227
  //show the taxa list or go to the singular taxon
1228
  if (sizeof($taxon_pager->records) == 1){ //sigle taxon case
1229
    reset($taxon_pager->records);
1230
    $singleTaxon = $taxon_pager->records[0];
1231
    if($singleTaxon->class != "Taxon"){
1232
      // it is a Synonym -> look for the accepted
1233
      $taxon = cdm_ws_get(CDM_WS_PORTAL_TAXON_ACCEPTED, array($singleTaxon->uuid, get_taxonomictree_uuid_selected()));
1234
      if($synonym_uuid){
1235
        drupal_goto('cdm_dataportal/taxon/' . $taxon[0]->uuid . '/synonymy', 'highlite=' . $synonym_uuid);
1236
      }else {
1237
        drupal_goto('cdm_dataportal/taxon/' . $taxon[0]->uuid . '/synonymy', 'highlite=' . $singleTaxon->uuid);
1238
      }
1239
    }else{
1240
      // it is an accepted taxon
1241
      if($synonym_uuid){
1242
        drupal_goto('cdm_dataportal/taxon/' . $singleTaxon->uuid . '/synonymy', 'highlite=' . $synonym_uuid);
1243
      }else{
1244
        drupal_goto('cdm_dataportal/taxon/' . $singleTaxon->uuid);
1245
      }
1246
    }
1247
  }else{ //more than one taxa case
1248
    $taxon_name_page->title = theme('cdm_name_page_title', $taxon_name);
1249
    if($taxon_pager->records){
1250
      $taxon_name_page->content = theme_cdm_list_of_taxa($taxon_pager->records, false);
1251
    }else{
1252
      $taxon_name_page->content = 'This name has no taxa';
1253
    }
1254
    return $taxon_name_page;
1255
  }
1256
}
1257

    
1258
function cdm_dataportal_view_search_advanced(){
1259

    
1260
  drupal_set_title(t('Advanced search'));
1261

    
1262
  $searchForm = cdm_dataportal_search_taxon_form(true);
1263

    
1264
  return drupal_get_form('cdm_dataportal_search_taxon_form_advanced');
1265

    
1266
}
1267

    
1268
/**
1269
 *
1270
 * future extensions to meet palmweb mockup requirements:
1271
 *  - habitat
1272
 *  - uses
1273
 *  - conservation status
1274
 *  - locality / tdwg region
1275
 */
1276
function cdm_dataportal_view_search_taxon(){
1277

    
1278
  $_SESSION['cdm']['last_search'] = $_SERVER['REQUEST_URI'];
1279

    
1280
  $request_params = cdm_dataportal_search_form_request();
1281
  $taxonPager = cdm_ws_get(CDM_WS_PORTAL_TAXON_FIND, null, queryString($request_params));
1282

    
1283
  $search_params = $_REQUEST;
1284
  unset($search_params['q']);
1285
  return theme('cdm_search_results', $taxonPager, 'cdm_dataportal/search/taxon', $search_params);
1286
}
1287

    
1288

    
1289
function cdm_view_xml2json(){
1290
  $file = arg(2);
1291
  $datastr = get_content(variable_get('cdm_webservice_url', '').$file);
1292
  return  xml2json::transformXmlStringToJson($datastr);
1293
}
1294

    
1295
/* ====================== other functions ====================== */
1296

    
1297

    
1298
/**
1299
 * Enter description here...
1300
 *
1301
 * @param String $uuid the UUID of the taxon
1302
 * @return the URL
1303
 */
1304
function path_to_taxon($uuid, $no_tab = false){
1305
  $tab = get_default_taxon_tab();
1306
  $values = unserialize(CDM_DATAPORTAL_DEFAULT_TAXON_TAB);
1307

    
1308
  if(!$uuid) return false;
1309

    
1310
  if (!$tab){
1311
    return 'cdm_dataportal/taxon/'.$uuid;
1312
  }else if(get_last_taxon_page_tab() &&  $tab == $values[CDM_DATAPORTAL_LAST_VISITED_TAB_ARRAY_INDEX]){
1313
    return 'cdm_dataportal/taxon/'.$uuid . '/' . get_last_taxon_page_tab();
1314
  } else {
1315
    return 'cdm_dataportal/taxon/'.$uuid . '/' . strtolower($tab);
1316
  }
1317
}
1318

    
1319
function path_to_key($keyType, $keyUuid){
1320
  if(!$keyUuid || !$keyType) return false;
1321
  $keyType{0} = strtolower($keyType{0});
1322
  return "cdm_dataportal/".$keyType."/$keyUuid";
1323
}
1324

    
1325
function path_to_reference($uuid){
1326
  if(!$uuid) return false;
1327
  return 'cdm_dataportal/reference/'.$uuid;
1328
}
1329

    
1330
function path_to_name($name_uuid){
1331
  $res = false;
1332
  if($name_uuid){
1333
   $res = 'cdm_dataportal/name/'.$name_uuid;
1334
  }
1335
  return $res;
1336
}
1337

    
1338
function path_to_media($uuid, $representaion_uuid = false, $partId = false){
1339
  if(!$uuid) return false;
1340
  $out = 'cdm_dataportal/media/'.$uuid;
1341
  if($representaion_uuid){
1342
    $out .= '/'.$representaion_uuid;
1343
    if($partId !== false){
1344
      $out .= '/'.$partId;
1345
    }
1346
  }
1347
  return $out;
1348
}
1349

    
1350
/**
1351
 * Compares thisRank with thatRank.
1352
 * Returns a negative integer, zero, or a positive integer
1353
 * as the of thisRank is higher than, equal to, or lower than thatRank.
1354
 * e.g:
1355
 * <ul>
1356
 * <li>rank_compare({species_uuid}, {genus_uuid}) = -1</li>
1357
 * <li>rank_compare({genus_uuid}, {genus_uuid}) = 0</li>
1358
 * <li>rank_compare({genus_uuid}, {tribus_uuid}) = 1</li>
1359
 * </ul>
1360
 * <p>
1361
 * This compare logic of the underlying webservice is the
1362
 * <b>inverse logic</b> of the the one implemented in
1363
 * java.lang.Comparable#compareTo(java.lang.Object)
1364
 * @param $thisRankUuid
1365
 * @param $thatRankUuid
1366
 * @return  a negative integer, zero, or a positive integer
1367
 * as the thisRank is lower than, equal to, or higher than thatRank
1368
 */
1369
function rank_compare($thisRankUuid, $thatRankUuid){
1370
  $result = cdm_ws_get(CDM_WS_TERM_COMPARE, array($thisRankUuid, $thatRankUuid));
1371
  return $result->Integer;
1372
}
1373

    
1374
/**
1375
 * Composes an HTML element class attribute value composed of
1376
 * the shortname of the cdm class and the uuid of the entity.
1377
 * This class attribute should be used whereever an cdm-entity is rendered.
1378
 *
1379
 * These according class selectors in css must be escaped, eg:
1380
 *    .cdm\:TextData
1381
 *
1382
 * @param $cdmEntity
1383
 */
1384
function html_class_atttibute_ref($cdmEntity){
1385

    
1386
  if(is_cdm_entity($cdmEntity)) {
1387
    return "cdm:".$cdmEntity->class." uuid:".$cdmEntity->uuid;
1388
  }
1389
}
1390

    
1391
function theme_cdm_uri_to_synonym($synonymUuid, $acceptedUuid, $pagePart = null){
1392
  $acceptedPath = path_to_taxon($acceptedUuid, true);
1393
  return url($acceptedPath.($pagePart ? '/'.$pagePart : ''), 'highlite='.$synonymUuid.'&acceptedFor='.$synonymUuid, $synonymUuid);
1394
}
1395

    
1396
/**
1397
 * Preprocess the taggedName to normalize newly introduced tagtypes like hybridSign, separator, .. more?
1398
 *
1399
 * @param unknown_type $taggedTextList
1400
 */
1401
function normalize_TaggedName(&$taggedTextList){
1402

    
1403
    if(is_array($taggedTextList)) {
1404

    
1405
      // first pass: rename
1406
      for($i = 0; $i < count($taggedTextList); $i++){
1407

    
1408
        if($taggedTextList[$i]->type == "hybridSign"){
1409
          $taggedTextList[$i]->type = "name";
1410
        }
1411

    
1412
      }
1413

    
1414
      // second pass: resolve separators
1415
      $taggedNameListNew = array();
1416
      for($i = 0; $i < count($taggedTextList); $i++){
1417

    
1418
        if($i + 1 < count($taggedTextList) && $taggedTextList[$i + 1]->type == "separator" ) {
1419

    
1420
          if($taggedTextList[$i]->type == $taggedTextList[$i + 2]->type){
1421
            $taggedName = $taggedTextList[$i];
1422
            $taggedName->text = $taggedName->text . $taggedTextList[$i + 1]->text . $taggedTextList[$i + 2]->text;
1423
            $taggedNameListNew[] = $taggedName;
1424
            ++$i;
1425
            ++$i;
1426
          }
1427
        } else {
1428
          $taggedNameListNew[] = $taggedTextList[$i];
1429
        }
1430
	  }
1431
	   $taggedTextList = $taggedNameListNew;
1432
    }
1433
}
1434

    
1435
/**
1436
 * Creates a short taxonname by using the taggename field of NameSTO or NameTO instances.
1437
 * If the taggename if empty the fullname will be returned.
1438
 *
1439
 * @param unknown_type $Name or TreeNode
1440
 * @return string
1441
 */
1442
function cdm_dataportal_shortname_of($name){
1443
  $nameStr = '';
1444

    
1445
  normalize_TaggedName($name->taggedTitle);
1446

    
1447
  // get all tagged text tokens of the scientific name
1448
  foreach($name->taggedTitle as $tagtxt){
1449
    if($tagtxt->type == 'name' || $tagtxt->type == 'rank'){
1450
      $nameStr .= ($nameStr ? ' ' : '').$tagtxt->text;
1451
    }
1452
  }
1453
  $nameStr = trim($nameStr);
1454
  if($nameStr){
1455
    // do not return short names for these
1456
    //if (stristr(strtolower($nameStr), 'incertae sedis') !== FALSE ||
1457
    //	stristr(strtolower($nameStr), 'nomina excludenda') !== FALSE) {
1458
    if ($name->unplaced || $name->excluded){
1459
      return $nameStr;
1460
    }
1461
    if($pos = stripos($nameStr, ' ')){
1462
      return substr($nameStr, 0, 1).'. '.substr($nameStr, $pos);
1463
    } else {
1464
      return $nameStr;
1465
    }
1466
  } else {
1467
    return $name->titleCache;
1468
  }
1469
}
1470

    
1471

    
1472
/**
1473
 * Check if a taxon is accepted by the current taxonomic tree
1474
 *
1475
 * @param Taxon $taxon
1476
 * @return true if $taxon is accepted, false otherwise
1477
 */
1478

    
1479
function _cdm_dataportal_acceptedByCurrentView($taxon){
1480

    
1481
  $defaultTreeUuid = get_taxonomictree_uuid_selected();
1482
  if($taxon->class == "Taxon" && isset($taxon->taxonNodes)){
1483
    foreach($taxon->taxonNodes as $node){
1484
      if($node->classification == $defaultTreeUuid) {
1485
        return true;
1486
      }
1487
    }
1488
  }
1489
  return false;
1490
}
1491

    
1492
/**@Deprecated
1493
 *
1494
 */
1495
function compose_url_prameterstr($parameters = array(), $parentPropertyName = false){
1496
  $pstr = '';
1497
  foreach($parameters as $key=>$value){
1498
    if(is_array($value)){
1499

    
1500
    } else {
1501
      $pstr .= ($pstr ? '&' :'').$key.'='.urlencode($value);
1502
    }
1503
  }
1504
  return $pstr;
1505
}
1506

    
1507
/**
1508
 * workaround for missing original source type, idNamespace is always set in these cases
1509
 * @param unknown_type $source
1510
 * @return unknown_type
1511
 */
1512
function _is_original_source_type($source){
1513
  return !$source->idNamespace && strlen($source->idNamespace) == 0;
1514
}
1515

    
1516
function _is_invers_taxonRelationship($taxonRelationship, $focusedTaxon){
1517
  return $taxonRelationship->fromTaxon->uuid == $focusedTaxon->uuid;
1518
}
1519

    
1520

    
1521

    
1522
/**
1523
 * The function read the metadata info such title or artist of a media file. The
1524
 * function tries at first to get all the info from the file metadata and if it is
1525
 * not avaible look at the media file info stored at the database.
1526
 * @param $media The media file
1527
 * @return array The array with the avilable specified metadata info.
1528
 * TODO rename to read_media_metadata() and move to *.module
1529
 */
1530
function cdm_read_media_metadata($media){
1531

    
1532
  $metadata_caption = array('title' => '',           //media_metadata and media
1533
                              'artist' => '',          //media_metadata and media
1534
                              'rights',                //media_metadata and media
1535
                              'location',              //media_metadata
1536
                              'filename' => '',        //media
1537
                              'mediacreated' => '',    //media
1538
                              'description' => '');    //media
1539

    
1540
  //getting the media metadata
1541
  $media_metadata = cdm_ws_get(CDM_WS_MEDIA_METADATA, array($media->uuid));
1542
  $media_metadata_aux = (array) $media_metadata;
1543

    
1544
  //filename
1545
  if(isset($media->representations[0]->parts[0]->uri)){
1546
    $fileUri = $media->representations[0]->parts[0]->uri;
1547
    $filename = substr($fileUri, strrpos($fileUri, "/")+1);
1548
    $metadata_caption['filename'] = $filename;
1549
  }
1550
  else{
1551
      $metadata_caption['filename'] = '';
1552
  }
1553

    
1554
  //title
1555
  if ($media_metadata->ObjectName) {
1556
    $metadata_caption['title'] = $media_metadata->ObjectName;
1557
  } else if ($media_metadata_aux['Object Name']){
1558
    $metadata_caption['title'] = $media_metadata_aux['Object Name'];
1559
  } else if ($media->title_L10n){
1560
    $metadata_caption['title'] = $media->title_L10n;
1561
  } else if ($media->titleCache){
1562
    $metadata_caption['title'] = $media->titleCache;
1563
  }
1564

    
1565
  // append description to title
1566
  if ($media->description_L10n) {
1567
    $metadata_caption['title'] .= '<span class="media-description">' . $media->description_L10n . '<span>';
1568
  }
1569

    
1570
  //artist
1571
  if ($media_metadata->Artist){
1572
   $metadata_caption['artist'] = ($media_metadata->Artist ? ''.$media_metadata->Artist : '');
1573
  }
1574
  elseif ($media->artist->titleCache){
1575
   $metadata_caption['artist'] = $media->artist->titleCache;
1576
  }
1577

    
1578
  //copyright
1579
  $metadata_caption['rights'] = array('copyright' => array('agentNames' => array()),
1580
                                      'license' => array('agentNames' => array(), 'types' => array(), 'abbreviatedTexts' => array(), 'uris' => array()));
1581
  if ($media_metadata->Copyright)
1582
  $metadata_caption['rights']['copyright']['agentNames'][] = $media_metadata->Copyright;
1583
  elseif ($media->rights){
1584
    foreach($media->rights as $right){
1585
      switch($right->term->uuid){
1586
        case UUID_RIGHTS_LICENCE:
1587
          $metadata_caption['rights']['license']['agentNames'][] = ($right->agent ? ''.$right->agent->firstname.' '.$right->agent->lastname : '');
1588
          $metadata_caption['rights']['license']['types'][] = ($right->representation_L10n ? ''.$right->representation_L10n : '');
1589
          $metadata_caption['rights']['license']['abbreviatedTexts'][] = ($right->abbreviatedText ? ''.$right->abbreviatedText : '');
1590
          $metadata_caption['rights']['license']['uris'][] = ($right->uri ? ''.$right->uri : '');
1591
          break;
1592
        case UUID_RIGHTS_COPYRIGHT:
1593
          $metadata_caption['rights']['copyright']['agentNames'][] = $right->agent->firstname . ' ' . $right->agent->lastname;
1594
          break;
1595
      }
1596
    }
1597
  } else {
1598
    $metadata_caption['rights']['agentNames'][] = '';
1599
  }
1600

    
1601
  //filling the description (though there is no description in the db???)
1602
  //$metadata_caption['description'] = $media->description_L10n;
1603

    
1604
  //location
1605
  $metadata_caption['location'] = array();
1606
  $metadata_caption['location']['sublocation'] = $media_metadata->Sublocation;
1607
  $metadata_caption['location']['city'] = $media_metadata->City;
1608
  $metadata_caption['location']['province'] = $media_metadata->Province;
1609
  $metadata_caption['location']['country'] = $media_metadata->Country;
1610

    
1611
  /*
1612
   //creation date
1613
   if($media_metadata["Modify Date"])
1614
   $metadata_caption['mediacreated'] = $media_metadata["Modify Date"];
1615
   else
1616
   $metadata_caption['mediacreated'] = $media->created;
1617
   */
1618
  //returned value
1619
  return $metadata_caption;
1620
}
1621

    
1622
/**
1623
 * This function collects all the media from a list of description elements
1624
 * and return them as an Array.
1625
 *
1626
 * @param $descriptionElementes The description elements
1627
 * @return Array The output with all the media
1628
 */
1629
function cdm_dataportal_media_from_descriptionElements($descriptionElements){
1630
  //variables
1631
  $outArrayOfMedia = array(); //return value
1632
  //implementation
1633
  if(is_array($descriptionElements)){//avoiding warning box in drupal for flora malesiana
1634
    foreach($descriptionElements as $descriptionElement){
1635
      if(is_array($descriptionElement->media)){
1636
        foreach($descriptionElement->media as $media){
1637
          if(is_object($media)){
1638
            $outArrayOfMedia[] = $media;
1639
          }
1640
        }
1641
      }
1642
    }
1643
  }
1644
  return $outArrayOfMedia;
1645
}
1646

    
1647
function cdm_annotations_as_footnotekeys($cdmBase, $footnote_list_key = null){
1648
  $footNoteKeys = array();
1649
  //is argument cdmBase an array?
1650
  if (!is_array($cdmBase)){
1651
    $cdmBase_array = array();
1652
    $cdmBase_array[] = $cdmBase;
1653
  }else{
1654
    $cdmBase_array = $cdmBase;
1655
  }
1656
  //getting the key for the footnotemanager
1657
  if( $footnote_list_key ){
1658
    $footnoteListKey = $footnote_list_key;
1659
  }else{
1660
    $footnoteListKey = RenderHints::getFootnoteListKey() . '-annotations';
1661
  }
1662
  //adding the footnotes keys
1663
  foreach($cdmBase_array as $cdmBase_element){
1664
    $annotations = cdm_ws_getAnnotationsFor($cdmBase_element, variable_get('annotations_types_as_footnotes', unserialize(ANNOTATIONS_TYPES_AS_FOOTNOTES_DEFAULT)));
1665
    if(is_array($annotations)){
1666
      foreach($annotations as $annotation){
1667
          $footNoteKeys[] = FootnoteManager::addNewFootnote($footnoteListKey, $annotation->text);
1668
      }
1669
    }
1670
  }
1671
  return $footNoteKeys;
1672
}
1673

    
1674
function cdm_dynabox($label, $content_url, $theme, $link_alt_text, $enclosingtags = array('li', 'ul')){
1675

    
1676
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/cdm_dynabox.js');
1677

    
1678
  $cdm_proxy_url = url('cdm_api/proxy/'.urlencode($content_url)."/$theme");
1679
  $out .= '<'. $enclosingtags[0]. ' class="dynabox"><a href="'.$content_url.'" class="label" alt="'.t($link_alt_text).'">'.$label.'</a>';
1680
  $out .= '<'. $enclosingtags[1]. ' class="dynabox_content" title="'.$cdm_proxy_url.'"><'. $enclosingtags[0]. '><img class="loading" src="'.drupal_get_path('module', 'cdm_dataportal').'/images/loading_circle_grey_16.gif" style="display:none;"></'. $enclosingtags[0]. '></'. $enclosingtags[1]. '>';
1681
  $out .= '</'. $enclosingtags[0]. '>';
1682
  return $out;
1683
}
1684

    
1685
/**
1686
 * returns true if the given $featureNode or any of its subordinate nodes contains
1687
 * at least one non empty TextData or at leas one DescriptionElement of an other type.
1688
 *
1689
 * @param unknown_type $featureNode A heature node as produced by the function _mergeFeatureTreeDescriptions()
1690
 */
1691
function hasFeatureNodeDescriptionElements($featureNode) {
1692

    
1693
  if(is_array($featureNode->descriptionElements) && count($featureNode->descriptionElements) > 0) {
1694
    foreach ($featureNode->descriptionElements as $descriptionElement) {
1695
      if($descriptionElement->class != "TextData" || $descriptionElement->multilanguageText_L10n->text){
1696
        return true;
1697
      }
1698
    }
1699
  } else if(is_array($featureNode->children)) {
1700
    foreach ($featureNode->children as $child) {
1701
      if(hasFeatureNodeDescriptionElements($child)){
1702
        return true;
1703
      }
1704
    }
1705
  }
1706
  return false;
1707
}
1708

    
(6-6/12)