Project

General

Profile

Download (57.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * Description theming functions.
5
 *
6
 * @copyright
7
 *   (C) 2007-2012 EDIT
8
 *   European Distributed Institute of Taxonomy
9
 *   http://www.e-taxonomy.eu
10
 *
11
 *   The contents of this module are subject to the Mozilla
12
 *   Public License Version 1.1.
13
 * @see http://www.mozilla.org/MPL/MPL-1.1.html
14
 */
15

    
16
/**
17
 * @todo Please document this function.
18
 * @see http://drupal.org/node/1354
19
 */
20
function theme_cdm_feature_nodesTOC($variables) {
21
  $featureNodes = $variables['featureNodes'];
22
  $out = '';
23
  $out .= '<ul>';
24

    
25
  foreach ($featureNodes as $node) {
26

    
27
    if (hasFeatureNodeDescriptionElements($node)) {
28

    
29
      $featureRepresentation = isset($node->feature->representation_L10n) ? $node->feature->representation_L10n : 'Feature';
30
      // HACK to implement images for taxa, should be removed.
31
      if ($node->feature->uuid != UUID_IMAGE) {
32
        $out .= '<li>' . l(t(theme('cdm_feature_name', array('feature_name' => $featureRepresentation))), $_GET['q'], array(
33
         'attributes' => array('class' => array('toc')), 'fragment' => generalizeString($featureRepresentation))) . '</li>';
34
      }
35
    }
36
  }
37

    
38
  $out .= '</ul>';
39
  return $out;
40
}
41

    
42
/**
43
 * Theme function to alter the feature representation.
44
 *
45
 * It is highly qeutionalbe if this function should be completely removed.
46
 * If a feature needs a different representation this should be edited directly
47
 * in the cdm data but it shoud not be tweeked like this in the portal.
48
 *
49
 * Used in:
50
 *  - theme_cdm_feature_nodesTOC()
51
 *  - theme_cdm_feature_nodes()
52
 *  - theme_cdm_media_mime_application()
53
 *  - theme_cdm_media_mime_text()
54
 *
55
 * TODO delete this function? (a.kohlbecker feb 2013)
56
 *
57
 */
58
function theme_cdm_feature_name($variables) {
59
  $feature_name = $variables['feature_name'];
60
  // TODO replace by using translations ?
61
  return t($feature_name);
62
}
63

    
64
/**
65
 * Returns HTML for a taxon profile from the $mergedFeatureNodes of a given $taxon.
66
 *
67
 * The taxon profile consists of description elements which are ordered by the
68
 * structure defined by specific FeatureTree. The chosen FeatureTree is merged
69
 * with the list of desctiprion elements prior to using this method.
70
 *
71
 * The merged nodes can be obtained by making use of the
72
 * function cdm_ws_descriptions_by_featuretree().
73
 *
74
 * @see cdm_ws_descriptions_by_featuretree()
75
 *
76
 * @param array $variables
77
 *   An associative array containing:
78
 *   - mergedFeatureNodes
79
 *   -taxon
80
 *
81
 * @ingroup themeable
82
 */
83
function theme_cdm_feature_nodes($variables) {
84

    
85
  $mergedFeatureNodes = $variables['mergedFeatureNodes'];
86
  $taxon = $variables['taxon'];
87
  $out = '';
88

    
89
  RenderHints::pushToRenderStack('feature_nodes');
90

    
91
  $gallery_settings = getGallerySettings(CDM_DATAPORTAL_DESCRIPTION_GALLERY_NAME);
92

    
93
  // Creating an array to place the description elements in.
94
  foreach ($mergedFeatureNodes as $node) {
95

    
96
    if (hasFeatureNodeDescriptionElements($node)) {
97

    
98
      $featureRepresentation = isset($node->feature->representation_L10n) ? $node->feature->representation_L10n : 'Feature';
99
      $block = new stdclass(); // Empty object.
100
      $block->module = 'cdm_dataportal';
101
      $media_list = array();
102

    
103
      if (true || $node->feature->uuid != UUID_IMAGE) {
104

    
105
        $block->delta = generalizeString($featureRepresentation);
106
        $block->subject = '<span class="' . html_class_atttibute_ref($node->feature) . '">' . theme('cdm_feature_name', array('feature_name' => $featureRepresentation)) . '</span>';
107
        $block->module = "cdm_dataportal-feature";
108
        $block->content = '';
109

    
110
        /*
111
         * Content/DISTRIBUTION.
112
         */
113
        if ($node->feature->uuid == UUID_DISTRIBUTION) {
114

    
115
          $node->descriptionElements = cdm_description_elements_prefer_computed($node->descriptionElements);
116

    
117
          if (variable_get(DISTRIBUTION_TEXTDATA_DISPLAY_ON_TOP, 0)) {
118
            $distributionTextDataList = array();
119
            $distributionElementsList = array();
120

    
121
            foreach ($node->descriptionElements as $descriptionElement) {
122
              if ($descriptionElement->class == "TextData") {
123
                $distributionTextDataList[] = $descriptionElement;
124
              }
125
              else {
126
                $distributionElementsList[] = $descriptionElement;
127
              }
128
            }
129

    
130

    
131
            if (count($distributionTextDataList) > 0) {
132
              $node->descriptionElements = $distributionElementsList;
133
              $block->content .= theme('cdm_descriptionElements', array(
134
                'descriptionElements' => $distributionTextDataList,
135
                'featureUuid' => $node->feature->uuid,
136
                'taxon_uuid' => $taxon->uuid,
137
              ));
138
            }
139
          }
140

    
141
          // Display cdm distribution map TODO this is a HACK to a proper
142
          // generic implementation?
143
          $map_render_element = compose_distribution_map($taxon);
144
          $block->content .= $map_render_element['#markup'];
145
          $block->content .= theme('cdm_descriptionElements', array(
146
            'descriptionElements' => $node->descriptionElements,
147
            'featureUuid' => $node->feature->uuid,
148
            'taxon_uuid' => $taxon->uuid,
149
          ));
150

    
151
        }
152

    
153
        /*
154
         * Content/COMMON_NAME.
155
         */
156
        elseif ($node->feature->uuid == UUID_COMMON_NAME) {
157
          // TODO why is theme_cdm_descriptionElement_CommonTaxonName not
158
          // beeing used???
159
         $block->content .= theme('cdm_common_names', array('elements' => $node->descriptionElements));
160
          /*
161
          }else if($node->feature->uuid == UUID_IMAGE_SOURCES) {
162
          $block->content .= theme('cdm_image_sources',
163
          $node->descriptionElements);
164
          */
165
        }
166

    
167
        /*
168
         * Content/ALL OTHER FEATURES.
169
         */
170
        else {
171
          if (isset($node->descriptionElements)) {
172
            $taxon_uuid = NULL;
173
            if(isset($taxon) ) {
174
              $taxon_uuid = $taxon->uuid;
175
            }
176
            $block->content .= theme('cdm_descriptionElements', array(
177
              'descriptionElements' => $node->descriptionElements,
178
              'featureUuid' => $node->feature->uuid,
179
              'taxon_uuid' => $taxon_uuid,
180
            ));
181
          }
182

    
183
//           Content/ALL OTHER FEATURES/Subordinate Features
184
//           subordinate features are printed inline in one floating text,
185
//           it is expected hat supordinate features can "contain" TextData,
186
//           Qualitative- and Qualitative- DescriptioneElements
187
          if (isset($node->children[0])) {
188

    
189
            // TODO support more than one level of children.
190
            // can this be solved by resursively calling this very function?
191
            // @see http://dev.e-taxonomy.eu/trac/ticket/2393
192
            $text = '';
193
            foreach ($node->children as $child) {
194

    
195
              if (isset($child->descriptionElements) && is_array($child->descriptionElements)) {
196
                foreach ($child->descriptionElements as $element) {
197

    
198
                  if (is_array($element->media)) {
199
                    // Append media of supordinate elements to list of main
200
                    // feature.
201
                    $media_list = array_merge($media_list, $element->media);
202
                  }
203

    
204
                  switch ($element->class) {
205
                    case 'TextData':
206
                      // TODO use theme_cdm_descriptionElementTextData()
207
                      $out_child_elements = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
208
                      $out_child_elements = str_replace($child->feature->titleCache, '<em>' . $child->feature->representation_L10n . '</em>', $out_child_elements);
209
                      break;
210
                    case 'CategoricalData':
211
                      $out_child_elements  = '<em>' . $child->feature->representation_L10n . '</em> '
212
                        . theme('cdm_descriptionElement_CategoricalData', array('element' => $element));
213
                      break;
214
                    case 'QuantitativeData':
215
                      $out_child_elements = '<em>' . $child->feature->representation_L10n . '</em> '
216
                        . theme('cdm_descriptionElement_QuantitativeData', array('element' => $element));
217

    
218
                  }
219

    
220
                }
221
                $text .= " " . $out_child_elements;
222
                $out_child_elements = '';
223
              }
224
            }
225
            $block->content .= $text;
226
          }
227
        }
228

    
229
        /*
230
         * Media/ALL FEATURES.
231
         */
232
        if (isset($node->descriptionElements)) {
233
          $media_list = array_merge($media_list, cdm_dataportal_media_from_descriptionElements($node->descriptionElements));
234
        }
235
        $captionElements = array('title', 'rights');
236
        $gallery = '';
237
        if (isset($gallery_settings['cdm_dataportal_media_maxextend']) && isset($gallery_settings['cdm_dataportal_media_cols'])) {
238
          $gallery = theme('cdm_media_gallerie', array(
239
            'mediaList' => $media_list,
240
            'galleryName' => CDM_DATAPORTAL_DESCRIPTION_GALLERY_NAME . '_' . $node->feature->uuid,
241
            'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
242
            'cols' => $gallery_settings['cdm_dataportal_media_cols'],
243
            'captionElements' => $captionElements,
244
          ));
245
        }
246
        $block->content .= $gallery;
247
        $block->content .= theme('cdm_footnotes', array('footnoteListKey' => $node->feature->uuid));
248
        $block->content .= theme('cdm_annotation_footnotes', array('footnoteListKey' => $node->feature->uuid));
249

    
250
        // Add anchor to subject.
251
        $block->subject = '<a name="' . $block->delta . '"></a>' . $block->subject;
252

    
253
        // In D6: $out .= theme('block', $block);
254
        // Comment @WA @TODO check if need to set a region, and which one.
255
        $block->region = FALSE;
256
        $out .= theme('block', array('elements' => array(
257
          '#block' => $block,
258
          '#children' => $block->content,
259
        )));
260
      }
261
    }
262
  }
263
  RenderHints::popFromRenderStack();
264
  return $out;
265
}
266

    
267
/**
268
 * @todo Please document this function.
269
 * @see http://drupal.org/node/1354
270
 */
271
function theme_FeatureTree_hierarchy($variables) {
272

    
273
  $FeatureTreeUuid = $variables['FeatureTreeUuid'];
274
  if (!is_uuid($FeatureTreeUuid)) {
275
    return;
276
  }
277

    
278
  $out = '';
279
  $featureTree = cdm_ws_get(CDM_WS_FEATURETREE, array(
280
    $FeatureTreeUuid,
281
  ));
282

    
283
  if (isset($featureTree) && isset($featureTree->root)) {
284
    $out = '<ul class="' . $featureTree->class . '">';
285
    $out .= theme('FeatureTree_hierarchy_children', array('node' => $featureTree->root));
286
    $out .= '</ul>';
287
  }
288
  return $out;
289
}
290

    
291
/**
292
 * @todo Please document this function.
293
 * @see http://drupal.org/node/1354
294
 */
295
function theme_FeatureTree_hierarchy_children($variables) {
296

    
297
  $node = $variables['node'];
298
  $out = '';
299
  if (isset($node->children)) {
300

    
301
    foreach ($node->children as $childNode) {
302
      $out .= '<li>' . check_plain($childNode->feature->representation_L10n);
303
      if (isset($childNode->children) && count($childNode->children) > 0) {
304
        $out .= '<ul>' . theme('FeatureTree_hierarchy_children', array('node' => $childNode)) . '</ul>';
305
      }
306
      $out .= '</li>';
307
    }
308
  }
309
  return $out;
310
}
311

    
312
/**
313
 * Returns HTML for the texts in a description $elementArray.
314
 *
315
 * Joins the texts in $elementArray and encloses with a HTML tag.
316
 *
317
 * @param array $variables
318
 *   An associative array containing:
319
 *   - elementArray
320
 *   - feature: The feature to which the elements given in $elementArray are
321
 *     belonging to.
322
 *   - glue: Defaults to empty string.
323
 *   - sortArray: Whether to sort the $elementArray alphabetically.
324
 *   - enclosingHtml
325
 *
326
 * @ingroup themeable
327
 */
328
function theme_cdm_descriptionElementArray($variables) {
329
  $elementArray = $variables['elementArray'];
330

    
331
  $feature = $variables['feature'];
332
  $glue = $variables['glue'];
333
  $sortArray = $variables['sortArray'];
334
  $enclosingHtml = $variables['enclosingHtml'];
335
  $out = '<' . $enclosingHtml . ' class="description" id="' . $feature->representation_L10n . '">';
336

    
337
  if ($sortArray) {
338
    sort($elementArray);
339
  }
340

    
341
  $out .= join($elementArray, $glue);
342

    
343
  $out .= '</' . $enclosingHtml . '>';
344
  return $out;
345
}
346

    
347
/**
348
 * @todo Please document this function.
349
 * @see http://drupal.org/node/1354
350
 */
351
function theme_cdm_descriptionElement_CommonTaxonName($variables) {
352
  $element = $variables['element'];
353
  $out = '<span class="' . html_class_atttibute_ref($element) . '">' . $element->language->representation_L10n . ' (' . $element->area->titleCache . '): ' . $element->name . '</span>';
354
  return $out;
355
}
356

    
357
/**
358
* @todo Please document this function.
359
* @see http://drupal.org/node/1354
360
*/
361
function theme_cdm_descriptionElement_CategoricalData($variables) {
362
  $element = $variables['element'];
363

    
364
  $state_data_strings = array();
365
  if (isset($element->states)) {
366
    foreach ($element->states as $stateData) {
367

    
368
      $state  = NULL;
369

    
370
      if(isset($stateData->state)){
371
        $state = cdm_term_representation($stateData->state);
372
      }
373

    
374
      if (isset($stateData->modifyingText_L10n)) {
375
        $state = ' ' . $stateData->modifyingText_L10n;
376
      }
377

    
378
      $modifiers_strings = cdm_modifers_representations($stateData);
379

    
380
      $state_data_strings[] = $state . ($modifiers_strings ? ' ' . $modifiers_strings : '');
381

    
382
      // FIXME render sources
383

    
384
    }
385
  }
386
  $out = '<span class="' . html_class_atttibute_ref($element) . '">' . implode(', ', $state_data_strings) . '</span>';
387
  return $out;
388
}
389

    
390
function theme_cdm_descriptionElement_QuantitativeData($variables) {
391
  /*
392
   * - statisticalValues
393
   *   - value
394
   *   - modifiers
395
   *   - type
396
   * - unit->representation_L10n
397
   * - modifyingText
398
   * - modifiers
399
   * - sources
400
   */
401
  $element = $variables['element'];
402

    
403
  $out = '';
404

    
405
  $type_representation = NULL;
406
  $modifiers_strings = array();
407

    
408

    
409
  if (isset($element->statisticalValues)) {
410
    $value_array = array();
411
    foreach ($element->statisticalValues as $val) {
412
      if (isset($val->value)) {
413
        $value_array[] = $val->value;
414
      }
415
    }
416

    
417
    $out .= implode($value_array, ', ');
418
  }
419

    
420
  if (isset($element->unit)) {
421
    $out .= ' '. cdm_term_representation($element->unit);
422
  }
423

    
424
  if (isset($element->statisticalValues->modifyingText_L10n)) {
425
    $out .=  ' ' . $element->statisticalValues->modifyingText_L10n;
426
  }
427
  $modifers_string = cdm_modifers_representations($element->statisticalValues);
428
  $out .= ($modifers_string ? ' ' . cdm_modifers_representations($element->statisticalValues) : '');
429

    
430
  // FIXME render sources
431

    
432
  return $out;
433

    
434
}
435

    
436
/**
437
 * Returns HTML for citations textdata elements.
438
 *
439
 * TODO: assign a new name to the function? Because it is used for the citations
440
 * textdata elements and not for all text data description elements.
441
 *
442
 * @param array $variables
443
 *   An associative array containing:
444
 *   - element: The description element which contains the text information.
445
 *   - asListElement: A boolean which determines whether the citations should
446
 *     be rendered as a list or not.
447
 *   - feature_uuid
448
 *
449
 * @ingroup themeable
450
 */
451
function theme_cdm_descriptionElementTextData($variables) {
452

    
453
  $element = $variables['element'];
454
  $asListElement = $variables['asListElement'];
455
  $feature_uuid = $variables['feature_uuid'];
456

    
457
  $description = '';
458
  if (isset($element->multilanguageText_L10n->text)) {
459
    $description = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
460
  }
461
  $sourceRefs = '';
462
  $result = array();
463
  $out = '';
464
  $res_author = '';
465
  $res_date = '';
466
  if (isset($element->sources) && is_array($element->sources) && count($element->sources) > 0) {
467
    foreach ($element->sources as $source) {
468
      $referenceCitation = theme('cdm_OriginalSource', array('source' => $source));
469
      if ($description && strlen($description) > 0 && $referenceCitation) {
470
        $sourceRefs .= ' (' . $referenceCitation . ')';
471
      }
472
      elseif ($referenceCitation) {
473
        $sourceRefs = $referenceCitation;
474
      }
475

    
476
      if (strlen($sourceRefs) > 0) {
477
        $sourceRefs = '<span class="sources">' . $sourceRefs . '</span>';
478
      }
479
      $name_used_in_source_link_to_show = '';
480
      // Do a link to name page.
481
      if (isset($source->nameUsedInSource->uuid) && isset($source->nameUsedInSource->titleCache)) {
482
        $name_used_in_source_link_to_show = l($source->nameUsedInSource->titleCache, path_to_name($source->nameUsedInSource->uuid), array(
483
          'attributes' => array(),
484
          'absolute' => TRUE,
485
          'html' => TRUE,
486
        ));
487
      }
488
      // Show a text without link.
489
      elseif (isset($source->nameUsedInSource->originalNameString) && strlen($source->nameUsedInSource->originalNameString) > 0) {
490
        $name_used_in_source_link_to_show = $source->nameUsedInSource->originalNameString;
491
      }
492

    
493
      if ($asListElement) {
494

    
495
       $out = '<li class="descriptionText DescriptionElement">';
496
        // Adding ":" if necessary.
497
        if (!empty($name_used_in_source_link_to_show)) {
498
          if ( (!empty($description)|| !empty($sourceRefs)) && $feature_uuid != UUID_CHROMOSOMES_NUMBERS) {
499
            $out .= $name_used_in_source_link_to_show . ': ';
500
          } else {
501
            $out .= $name_used_in_source_link_to_show . ' ';
502
          }
503
        }
504
        $out .= $description . $sourceRefs . theme('cdm_annotations_as_footnotekeys', array('cdmBase_list' => $element, 'footnote_list_key' => $feature_uuid)) . '</li>';
505
      }
506
      else {
507
        if ($name_used_in_source_link_to_show) {
508
          $name_used_in_source_link_to_show = ' (name in source: ' . $name_used_in_source_link_to_show . ')';
509
        }
510

    
511
        $out = '<span class="DescriptionElement DescriptionElement-' . $element->class . '">' . $description . $sourceRefs . $name_used_in_source_link_to_show . '</span>';
512
      }
513
    }
514
  }
515
  else {
516
    // If no sources, print the description.
517
    $out = $description;
518
  }
519
  return $out;
520
}
521

    
522
/**
523
 * @todo Please document this function.
524
 * @see http://drupal.org/node/1354
525
 */
526
function theme_cdm_common_names($variables) {
527
  $elements = $variables['elements'];
528
  $text_data_out = '';
529
  $common_name_out = '';
530
  $separator = ',';
531
  $textData_commonNames = array();
532

    
533
  if (is_array($elements)) {
534
    foreach ($elements as $element) {
535
      if ($element->class == 'CommonTaxonName') {
536

    
537
        // common name without a language or area, should not happen but is possible
538
        $language_area_key = '';
539
        if (isset($element->language->representation_L10n)) {
540
          $language_area_key .= '<b>' . $element->language->representation_L10n . '</b>';
541
        }
542
        if(isset($element->area->titleCache) && strlen($element->area->titleCache) > 0){
543
          $language_area_key .= ($language_area_key ? ' '  : '') . '(' . $element->area->titleCache . ')';
544
        }
545

    
546
        if(isset($common_names[$language_area_key][$element->name])) {
547
          // same name already exists for language and areae combination, se we merge the description elements
548
          cdm_merge_description_elements($common_names[$language_area_key][$element->name], $element);
549
        } else{
550
          // otherwise add as new entry
551
          $common_names[$language_area_key][$element->name] = $element;
552
        }
553

    
554
      }
555
      elseif ($element->class == 'TextData') {
556
        $textData_commonNames[] = $element;
557
      }
558
    }
559
  }
560
  // Handling common names.
561
  if (isset($common_names) && count($common_names) > 0) {
562
    // Sorting the array based on the key (language, + area if set).
563
    // Comment @WA there are common names without a language, so this sorting
564
    // can give strange results.
565
    ksort($common_names);
566

    
567
    // Creating the output to be render by Drupal.
568
    foreach ($common_names as $key => $elements) {
569
      ksort($elements); // sort names alphabetically
570
      $rendered_element_list = '';
571
      foreach ($elements as $element) {
572
        $sourcesFootnoteKeyList = '';
573
        // Adding footnotes sources.
574
        foreach ($element->sources as $source) {
575
          if (_is_original_source_type($source)) {
576
            $_fkey = FootnoteManager::addNewFootnote(UUID_COMMON_NAME, theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)));
577
            $sourcesFootnoteKeyList .= theme('cdm_footnote_key', array('footnoteKey' => $_fkey, 'separator' => ($sourcesFootnoteKeyList ? $separator : '')));
578
          }
579
        }
580
        if ($element->name) {
581
          $rendered_element_list .= '<span class="' . html_class_atttibute_ref($element) . '">' . (strlen($rendered_element_list) > 0 ? ', ' : '') . $element->name . $sourcesFootnoteKeyList . '</span>';
582
        }
583
      }
584
      if ($key) {
585
        $common_name_out .= (strlen($common_name_out) > 0 ? '; ' : '') . $key . ': ' . $rendered_element_list;
586
      }
587
      else {
588
        $common_name_out .= (strlen($common_name_out) > 0 ? '; ' : '') . $rendered_element_list;
589
      }
590
    }
591
  }
592
  // Handling commons names as text data.
593
  foreach ($textData_commonNames as $text_data_element) {
594
    $text_data_out .= theme('cdm_descriptionElementTextData', array(
595
      'element' => $text_data_element,
596
      'asListElement' => TRUE,
597
      'feature_uuid' => $text_data_element->feature->uuid,
598
    ));
599
  }
600

    
601
  $common_name_out = "<div class=common_names_as_common_names> $common_name_out </div>";
602
  $out_array[] = $text_data_out;
603
  $common_name_out_text_data = '<div class=common_names_as_text_data>' . theme('cdm_descriptionElementArray', array('elementArray' => $out_array, 'feature' => $element->feature)) . '</div>';
604

    
605
  return $common_name_out . $common_name_out_text_data;
606
  /*
607
  return $common_name_out . theme('cdm_descriptionElementArray', $out_array,
608
  $element->feature);
609
  return "<div class=common_names> $common_name_out
610
  $common_name_out_text_data";
611
  */
612
}
613

    
614
/**
615
 * Return HTML for a list of description elements.
616
 *
617
 * Usually these are of a specific feature type.
618
 *
619
 * @param array $variables
620
 *   An associative array containing:
621
 *   - array of descriptionElements which belong to the same feature.
622
 *     These descriptions elements of a Description must be ordered by the chosen feature tree by
623
 *     calling the function _mergeFeatureTreeDescriptions().
624
 *     @see _mergeFeatureTreeDescriptions()
625
 *   - featureUuid: currently unused, accoding code disabled
626
 *   - taxon_uuid: only used for ordered dditributions (will be removed!)
627
 *
628
 * @ingroup themeable
629
 */
630
function theme_cdm_descriptionElements($variables) {
631

    
632
  $descriptionElements = $variables['descriptionElements'];
633
  $featureUuid = $variables['featureUuid'];
634
  $taxon_uuid = $variables['taxon_uuid'];
635
  $outArray = array();
636

    
637
  /*
638
  $userDefined = mixed_variable_get(LAYOUT_SETTING_PREFIX . $featureUuid, FEATURE_TREE_LAYOUT_DEFAULTS);
639
  if(variable_get('distribution_sort',
640
      'NO_SORT') != 'NO_SORT'){
641
      $glue = '';
642
      $enclosingTag = 'dl';
643
      $entryEnclosingTag = NULL;
644
  } else if($userDefined &&
645
      $userDefined['enabled']){
646
    $glue = $userDefined['glue'];
647
    $enclosingTag =  $userDefined['enclosingTag'];
648
    $entryEnclosingTag = $userDefined['entryEnclosingTag'];
649
  } else { // TODO remove once  LAYOUT_SETTING_PREFIX-{uuid} setting are configured to work for all portals(selenium test still missing!!!)
650
    $glue = ''; $enclosingTag = 'ul';
651
    $entryEnclosingTag = NULL ;
652
  }
653
  */
654

    
655

    
656
  if (variable_get('distribution_sort', 'NO_SORT') != 'NO_SORT') {
657
    $glue = '';
658
    $enclosingTag = 'dl';
659
  }
660
  else {
661
    $glue = '';
662
    $enclosingTag = 'ul';
663
  }
664

    
665
  $sortOutArray = FALSE;
666
  $distributionElements = array();
667

    
668
  RenderHints::pushToRenderStack('cdm_descriptionElements');
669

    
670
  // Avoiding warning box in drupal for flora malesiana.
671
  if (is_array($descriptionElements)) {
672
    foreach ($descriptionElements as $descriptionElement) {
673

    
674
      // --- DISTRIBUTION ---- //
675
      if ($descriptionElement->feature->uuid == UUID_DISTRIBUTION) {
676
        if ($descriptionElement->class == 'Distribution' && is_object($descriptionElement->area)) {
677
          $sortKey = $descriptionElement->area->representation_L10n;
678
          $distributionElements[$sortKey] = $descriptionElement;
679
        }
680
        elseif ($descriptionElement->class == 'TextData') {
681
          $asListElement = FALSE;
682
          $repr = theme('cdm_descriptionElementTextData', array(
683
            'element' => $descriptionElement,
684
            'asListElement' => $asListElement,
685
            'feature_uuid' => $descriptionElement->feature->uuid,
686
          ));
687

    
688
          if (!array_search($repr, $outArray)) {
689
            $outArray[] = $repr;
690
            // TODO HINT: sorting in theme_cdm_descriptionElementArray will
691
            // not work since this array contains html attributes with uuids
692
            // !!!!
693
            $sortOutArray = TRUE;
694
            $glue = '<br/> ';
695
            $enclosingTag = 'p';
696
          }
697
        }
698
      }
699

    
700
      // --- IMAGE_SOURCES --- //
701
      elseif ($descriptionElement->feature->uuid == UUID_IMAGE_SOURCES) {
702
        $image_sources[] = $descriptionElement;
703
      }
704
      // --- USE TEXTDATA --- //
705
      elseif ($descriptionElement->feature->uuid == UUID_USE) {
706
        // Do nothing to avoid rendering.
707
      } else {
708
        /* decide based on the description element class
709
         *
710
         * TODO provide api_hook as extension point for this
711
         */
712
        switch ($descriptionElement->class) {
713
          case 'TextData':
714
            $asListElement = TRUE;
715
            $outArray[] = theme('cdm_descriptionElementTextData', array(
716
              'element' => $descriptionElement,
717
              'asListElement' => $asListElement,
718
              'feature_uuid' => $descriptionElement->feature->uuid,
719
            ));
720
            break;
721
          case 'CommonTaxonName':
722
            $outArray[] = theme('cdm_descriptionElement_CommonTaxonName', array('element' => $descriptionElement));
723
          break;
724
          case 'CategoricalData':
725
            $outArray[] = theme('cdm_descriptionElement_CategoricalData', array('element' => $descriptionElement));
726
            break;
727
          case 'QuantitativeData':
728
            $outArray[] = theme('cdm_descriptionElement_QuantitativeData', array('element' => $descriptionElement));
729
            break;
730
          case 'Uses':
731
          /* IGNORE Uses classes, these are handled completely in theme_cdm_UseDescription */
732
          break;
733
        default:
734
        $outArray[] = '<li>No method for rendering unknown description class: ' . $descriptionElement->class . '</li>';
735
      }
736
    }
737
    }
738
  }
739

    
740
  // If feature = NAME USAGE sort the list of sources.
741
  // This is ONLY for FLORA MALESIANA and FLORE d'AFRIQUE CENTRALE.
742
  if ($descriptionElement->feature->uuid == UUID_NAME_USAGE) {
743
    sort($outArray);
744
  }
745

    
746
  if (isset($image_sources)) {
747
    $outArray[] = theme('cdm_description_element_image_source', array('image_sources' => $image_sources, 'asListElement' => TRUE));
748
  }
749

    
750
  if (variable_get('distribution_sort', 'NO_SORT') != 'NO_SORT') {
751
    $outArray[] = theme('cdm_description_ordered_distributions', array('taxon_uuid' => $taxon_uuid, 'descriptionElements' => $distributionElements));
752
  }
753
  else {
754
    ksort($distributionElements);
755
    // TODO , $entryEnclosingTag);
756
    $outArray[] = theme('cdm_descriptionElementDistribution', array(
757
      'descriptionElements' => $distributionElements,
758
    ));
759
  }
760

    
761
  // Take the feature of the last $descriptionElement.
762
  $feature = $descriptionElement->feature;
763

    
764
  $out = theme('cdm_descriptionElementArray', array(
765
    'elementArray' => $outArray,
766
    'feature' => $feature,
767
    'glue' => $glue,
768
    'sortArray' => $sortOutArray,
769
    'enclosingHtml' => $enclosingTag,
770
  ));
771

    
772
  RenderHints::popFromRenderStack();
773
  return $out;
774
}
775

    
776
/**
777
 * @todo Please document this function.
778
 * @see http://drupal.org/node/1354
779
 */
780
function compare_image_sources($a, $b) {
781
  if ($a->multilanguageText_L10n->text == $b->multilanguageText_L10n->text) {
782
    return 0;
783
  }
784
  return ($a->multilanguageText_L10n->text < $b->multilanguageText_L10n->text) ? -1 : 1;
785
}
786

    
787
/**
788
 * @todo Please document this function.
789
 * @see http://drupal.org/node/1354
790
 */
791
function theme_cdm_description_element_image_source($variables) {
792
  $image_sources = $variables['image_sources'];
793
  $asListElement = $variables['asListElement'];
794
  $out = '';
795
  $separator = ',';
796
  RenderHints::pushToRenderStack('descriptionElementImageSource');
797
  RenderHints::setFootnoteListKey(UUID_IMAGE_SOURCES);
798

    
799
  // Sorting the image sources.
800
  usort($image_sources, "compare_image_sources");
801
  // Generate the footnotes.
802
  foreach ($image_sources as $image_source) {
803
    $footNoteKeys = cdm_annotations_as_footnotekeys($image_source);
804
    foreach ($image_source->sources as $source) {
805
      if (_is_original_source_type($source)) {
806
        $fn_key = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), theme('cdm_OriginalSource', array(
807
          'source' => $source,
808
          'doLink' => FALSE,
809
        )));
810
        // Ensure uniqueness of the footnote keys.
811
        cdm_add_footnote_to_array($footNoteKeys, $fn_key);
812
      }
813
    }
814
    // Sort and render footnote keys.
815
    $footnoteKeyListStr = '';
816
    asort($footNoteKeys);
817
    foreach ($footNoteKeys as $footNoteKey) {
818
      $footnoteKeyListStr .= theme('cdm_footnote_key', array('footnoteKey' => $footNoteKey, 'separator' => ($footnoteKeyListStr ? $separator : '')));
819
    }
820
    // Return value!
821
    $out .= '<span class="descriptionElement descriptionElement-' . $image_source->uuid . '">' . $image_source->multilanguageText_L10n->text . $footnoteKeyListStr . '; </span>';
822
  }
823

    
824
  RenderHints::popFromRenderStack();
825
  return $out;
826
}
827

    
828
/**
829
 * @todo Please document this function.
830
 * @see http://drupal.org/node/1354
831
 */
832
function theme_cdm_descriptionElementDistribution($variables) {
833
  $descriptionElements = $variables['descriptionElements'];
834
  $enclosingTag = $variables['enclosingTag'];
835
  if (!$enclosingTag) {
836
    $enclosingTag = "span";
837
  }
838

    
839
  $out = '';
840
  $separator = ',';
841
  RenderHints::pushToRenderStack('descriptionElementDistribution');
842
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
843

    
844
  foreach ($descriptionElements as $descriptionElement) {
845

    
846
    // Annotations as footnotes.
847
    $footNoteKeys = cdm_annotations_as_footnotekeys($descriptionElement);
848
    // Source references as footnotes.
849
    foreach ($descriptionElement->sources as $source) {
850
      if (_is_original_source_type($source)) {
851
        $fn_key = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), theme('cdm_OriginalSource', array(
852
          'source' => $source,
853
          'doLink' => FALSE,
854
        )));
855
        // Ensure uniqueness of the footnote keys.
856
        cdm_add_footnote_to_array($footNoteKeys, $fn_key);
857
      }
858
    }
859
    // Sort and render footnote keys.
860
    $footnoteKeyListStr = '';
861
    asort($footNoteKeys);
862
    foreach ($footNoteKeys as $footNoteKey) {
863
      $footnoteKeyListStr .= theme('cdm_footnote_key', array('footnoteKey' => $footNoteKey, 'separator' => ($footnoteKeyListStr ? $separator : '')));
864
    }
865

    
866
    $out .= '<' . $enclosingTag . ' class="descriptionElement descriptionElement-' . $descriptionElement->uuid . '">' . $descriptionElement->area->representation_L10n . $footnoteKeyListStr . ' </' . $enclosingTag . '>';
867
  }
868

    
869
  RenderHints::popFromRenderStack();
870
  return $out;
871
}
872

    
873
/**
874
 * Compare two different footnotes objects.
875
 *
876
 * The comparison is based on the footnote key. The one which is
877
 * displayed as footnote number.
878
 *
879
 * @param mixed $a
880
 *   Footnote object $a.
881
 * @param mixed $b
882
 *   Footnote object $b.
883
 */
884
function footnotes_key_compare($a, $b) {
885
  $res = 0;
886
  if (empty($a) || empty($b)) {
887
    return $res;
888
  }
889
  if ($a->keyStr < $b->keyStr) {
890
    $res = -1;
891
  }
892
  elseif ($a->keyStr > $b->keyStr) {
893
    $res = 1;
894
  }
895
  return $res;
896
}
897

    
898
/**
899
 * @todo Please document this function.
900
 * @see http://drupal.org/node/1354
901
 */
902
function theme_cdm_description_ordered_distributions($variables) {
903

    
904
  $taxon_uuid = $variables['taxon_uuid'];
905
  $descriptionElements = $variables['descriptionElements'];
906

    
907
  // Returning NULL if there are no description elements.
908
  if ($taxon_uuid == null || $descriptionElements == NULL) {
909
    return NULL;
910
  }
911

    
912
  // Initialization of some variables.
913
  $out = '';
914
  $separator = ',';
915
  RenderHints::pushToRenderStack('descriptionElementDistribution');
916
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
917

    
918
  // Getting all the taxon description for a given taxon.
919
  $markerTypesEmpty = array();
920
  // $markerTypesEmpty['markerTypes'] = 'af9860ff-08f5-4b4d-863c-49ae96985115';
921
  $markerTypesEmpty['markerTypes'] = '';
922
  $queryString = $markerTypesEmpty['markerTypes'] ? queryString($markerTypesEmpty) : '';
923

    
924
  $taxonDescriptions = cdm_ws_get(CDM_WS_PORTAL_TAXON_DESCRIPTIONS, $taxon_uuid, $queryString);
925
  foreach ($taxonDescriptions as $description) {
926
    $descriptions_uuids[] = $description->uuid;
927
  }
928

    
929
  // Getting the sortered distributions (omitting level ??).
930
  $request_params = array();
931
  $request_params['omitLevels'] = UUID_NAMEDAREALEVEL_TDWGLEVEL_2;
932
  $ordered_areas = cdm_ws_get(CDM_WS_PORTAL_DESCRIPTION_DISTRIBUTION_TREE, join(',', $descriptions_uuids), queryString($request_params));
933
  if (isset($ordered_areas->rootElement->children)) {
934
    $ordered_areas = $ordered_areas->rootElement->children;
935
  }
936

    
937
  // Printing the distributions.
938
  if (is_array($ordered_areas) && count($ordered_areas) > 0) {
939
    foreach ($ordered_areas as $element_level1) {
940
      // Level1.
941
      if ($element_level1->data) {
942
        $out .= '<dt>' . $element_level1->data->area->representation_L10n . ':</dt> ';
943
      }
944
      $out .= '<dd>';
945

    
946
      // Level3.
947
      foreach ($element_level1->children as $element_level3) {
948
        if ($element_level3->data) {
949
          $text_l3 = $element_level3->data->area->representation_L10n;
950
        }
951
        $fnKeysLevel3Str = '';
952
        $fnKeysLevel3 = cdm_annotations_as_footnotekeys($element_level3->data);
953
        foreach ($element_level3->data->sources as $source) {
954
          if (_is_original_source_type($source)) {
955
            $fn_key3 = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)));
956
            cdm_add_footnote_to_array($fnKeysLevel3, $fn_key3);
957
          }
958
        }
959
        // Level4.
960
        $l4_regions = array();
961
        foreach ($element_level3->children as $element_level4) {
962
          if ($element_level4->data) {
963
            $text_l4 = $element_level4->data->area->representation_L10n;
964
            $l4_regions[$element_level3->data->area->representation_L10n] = '';
965
            $fnKeysLevel4Str = '';
966
            $fnKeysLevel4 = cdm_annotations_as_footnotekeys($element_level4->data);
967
            foreach ($element_level4->data->sources as $source) {
968
              if (_is_original_source_type($source)) {
969
                $fn_key4 = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)));
970
                cdm_add_footnote_to_array($fnKeysLevel4, $fn_key4);
971
              }
972
            }
973
            usort($fnKeysLevel4, "footnotes_key_compare");
974
            $l4_regions[$text_l4] = $fnKeysLevel4;
975
          }
976
        }// Level4.
977
        // Managing level3 and level4 for generating the right output.
978
        usort($fnKeysLevel3, "footnotes_key_compare");
979
        foreach ($fnKeysLevel3 as $key3) {
980
          foreach ($l4_regions as $key4 => $value4) {
981
            cdm_add_footnote_to_array($l4_regions[$key4], $key3);
982
          }
983
        }
984
        if ($element_level3->numberOfChildren == 1 && $text_l3 == $element_level3->children[0]->data->area->representation_L10n) {
985
          // var_dump($element_level3->children[0]->data->area->representation_L10n);
986
          $fnStr = '';
987
          $region = array_pop($l4_regions);
988
          foreach ($region as $key) {
989
            $fnStr .= theme('cdm_footnote_key', array('footnoteKey' => $key, 'separator' => ($fnStr ? $separator : '')));
990
          }
991
          $out .= "$text_l3 $fnStr; ";
992
          // Removing whitespaces when &fnStr is empty.
993
          if (substr($out, -3) == ' ; ') {
994
            $out = substr($out, 0, -3) . '; ';
995
          }
996
        }
997
        else {
998
          $fnKeysLevel3Str = '';
999
          foreach ($fnKeysLevel3 as $key) {
1000
            $fnKeysLevel3Str .= theme('cdm_footnote_key', array('footnoteKey' => $key, 'separator' => ($fnKeysLevel3Str ? $separator : '')));
1001
          }
1002
          $text_l4_aux = '';
1003
          foreach ($l4_regions as $key => $value) {
1004
            $fnKeysLevel4Str = '';
1005
            if (is_array($l4_regions[$key])) {
1006
              foreach ($l4_regions[$key] as $fnkey) {// Warning why?
1007
                $fnKeysLevel4Str .= theme('cdm_footnote_key', array('footnoteKey' => $fnkey, 'separator' => ($fnKeysLevel4Str ? $separator : '')));
1008
              }
1009
            }
1010
            // if ($key != $text_l3 || sizeof($l4_regions > 1)){
1011
            if ($key != $text_l3) {
1012
              $text_l4_aux .= "$key $fnKeysLevel4Str, ";
1013
            }
1014
          }
1015
          $text_l4_aux = substr($text_l4_aux, 0, -2);
1016

    
1017
          if (strlen($text_l4_aux) > 0) {
1018
            $out .= "$text_l3 $fnKeysLevel3Str ($text_l4_aux); ";
1019
          }
1020
          else {
1021
            $out .= "$text_l3 $fnKeysLevel3Str; ";
1022
          }
1023
        }
1024
      }// Level3.
1025
      $out = substr($out, 0, -2);
1026
      $out .= '.</dd>';
1027
    }// Level1.
1028
  }
1029
  RenderHints::popFromRenderStack();
1030
  return $out;
1031
}
1032

    
1033

    
1034
/*
1035
function theme_cdm_descriptionElementDistribution($descriptionElements){ $out
1036
  = ''; $separator = ',';
1037
  RenderHints::pushToRenderStack('descriptionElementDistribution');
1038
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
1039
  foreach($descriptionElements as $descriptionElement){ // annotations as
1040
  footnotes $annotationFootnoteKeys = theme('cdm_annotations_as_footnotekeys',
1041
  $descriptionElement); // source references as footnotes
1042
  $sourcesFootnoteKeyList = ''; foreach($descriptionElement->sources as
1043
  $source){ if(_is_original_source_type($source)){ $_fkey =
1044
  FootnoteManager::addNewFootnote(UUID_DISTRIBUTION,
1045
  theme('cdm_OriginalSource', $source, FALSE));
1046
  $sourcesFootnoteKeyList .= theme('cdm_footnote_key', $_fkey,
1047
  UUID_DISTRIBUTION, ($sourcesFootnoteKeyList ? $separator : '')); } }
1048
  if($annotationFootnoteKeys && $sourcesFootnoteKeyList){
1049
  $annotationFootnoteKeys .= $separator; } $out .=
1050
  $descriptionElement->area->representation_L10n . $annotationFootnoteKeys .
1051
  $sourcesFootnoteKeyList . ' '; } $out = substr($out, 0,
1052
  strlen($out)-strlen($separator) ); RenderHints::popFromRenderStack(); return
1053
  $out; }
1054
*/
1055

    
1056
/**
1057
 * Composes the render array for a distribution map of the given taxon.
1058
 *
1059
 * The distribution map can either be a plain image or a dynamic open layers map
1060
 * depending on the settings.
1061
 *
1062
 * compose_hook() implementation
1063
 *
1064
 * @param $taxon
1065
 *   The CDM Taxon instance to create the distribution map for.
1066
 * @return array
1067
 *    A drupal render array
1068
 *
1069
 * Similar compose function compose_map()
1070
 *
1071
 * @ingroup compose
1072
 */
1073
function compose_distribution_map($taxon) {
1074

    
1075
  $out = '';
1076
  $settings = get_edit_map_service_settings();
1077

    
1078
  $fontStyles = array(
1079
    0 => "plane",
1080
    1 => "italic",
1081
  );
1082

    
1083
  // Query cdm server for map service uri parameters.
1084
  $map_data_parameters = cdm_ws_get(CDM_WS_GEOSERVICE_DISTRIBUTIONMAP, $taxon->uuid);
1085
  $out .= "<!-- map_data_parameters:" . print_r($map_data_parameters, TRUE) . " -->";
1086
  $query_string = $map_data_parameters->String;
1087
  if (!$query_string) {
1088
    // The $query_string is empty if there are no distribution areas defined.
1089
    return;
1090
  }
1091

    
1092
  // Some cleaning of the URI paramters, TODO is this still needed?
1093
  $query_string = str_replace('%3A', ":", $query_string);
1094

    
1095
  /* ------ choose the display mode, either openlayers or static image ------ */
1096

    
1097
  $map_settings = get_array_variable_merged(CDM_MAP_DISTRIBUTION, CDM_MAP_DISTRIBUTION_DEFAULT);
1098

    
1099
  if ($map_settings['map_type'] == 1) {
1100

    
1101
    /* =========== display distributions using the openlayers map viewer =========== */
1102

    
1103
    $legendFormatQueryStr = "format=image" . urlencode('/') . "png"
1104
         . "&TRANSPARENT=TRUE"
1105
         . "&WIDTH=" . $map_settings['legend']['icon_width']
1106
         . "&HEIGHT=" . $map_settings['legend']['icon_height']
1107
           // TODO why is the layer=topp:tdwg_level_4 parameter needed at all here??
1108
           // AK: i think the tdwg_level_4 is used as place holder and will be replaced later on
1109
           // => search for "tdwg_level_4" in the code
1110
         . "&layer=topp" . urlencode(':') . "tdwg_level_4"
1111
         . "&LEGEND_OPTIONS=forceLabels" . urlencode(':') . "on"
1112
             . ";fontStyle" . urlencode(':') . $fontStyles[$map_settings['legend']['font_style']]
1113
             . ";fontSize" . urlencode(':') .  $map_settings['legend']['font_size']
1114
         . "&SLD=";
1115

    
1116
    $out .= get_openlayers_map(
1117
        $map_settings['width'],
1118
        $map_settings['height'],
1119
        $map_settings['bbox'],
1120
        NULL,
1121
        $query_string,
1122
        $legendFormatQueryStr,
1123
        $map_settings['caption']
1124
     );
1125
  }
1126
  else {
1127
    $legendFormatQueryStr = '';
1128
    $out = get_image_map(
1129
        $map_settings['width'],
1130
        $map_settings['height'],
1131
        $map_settings['bbox'],
1132
        NULL,
1133
        $query_string,
1134
        $legendFormatQueryStr,
1135
        $map_settings['caption']
1136
    );
1137
  }
1138
  return markup_to_render_array($out);
1139
}
1140

    
1141
/**
1142
 * Returns a list of a specific type of IdentificationKeys.
1143
 *
1144
 * The list can be restricteded by a taxon.
1145
 *
1146
 * @param string $type
1147
 *   The simple name of the cdm class implementing the interface
1148
 *   IdentificationKey, valid values are:
1149
 *   PolytomousKey, MediaKey, MultiAccessKey.
1150
 * @param string $taxonUuid
1151
 *   If given this parameter restrict the listed keys to those which have
1152
 *   the taxon identified be this uuid in scope.
1153
 *
1154
 * @return array
1155
 *   List with identification keys.
1156
 */
1157
function _list_IdentificationKeys($type, $taxonUuid = NULL, $pageSize = NULL, $pageNumber = NULL) {
1158
  if (!$type) {
1159
    drupal_set_message(t('Type parameter is missing'), 'error');
1160
    return;
1161
  }
1162
  $cdm_ws_pasepath = NULL;
1163
  switch ($type) {
1164
    case "PolytomousKey":
1165
      $cdm_ws_pasepath = CDM_WS_POLYTOMOUSKEY;
1166
      break;
1167

    
1168
    case "MediaKey":
1169
      $cdm_ws_pasepath = CDM_WS_MEDIAKEY;
1170
      break;
1171

    
1172
    case "MultiAccessKey":
1173
      $cdm_ws_pasepath = CDM_WS_MULTIACCESSKEY;
1174
      break;
1175

    
1176
  }
1177

    
1178
  if (!$cdm_ws_pasepath) {
1179
    drupal_set_message(t('Type parameter is not valid: ') . $type, 'error');
1180
  }
1181

    
1182
  $queryParameters = '';
1183
  if (is_numeric($pageSize)) {
1184
    $queryParameters = "pageSize=" . $pageSize;
1185
  }
1186
  else {
1187
    $queryParameters = "pageSize=0";
1188
  }
1189

    
1190
  if (is_numeric($pageNumber)) {
1191
    $queryParameters = "pageNumber=" . $pageNumber;
1192
  }
1193
  else {
1194
    $queryParameters = "pageNumber=0";
1195
  }
1196
  $queryParameters = NULL;
1197
  if ($taxonUuid) {
1198
    $queryParameters = "findByTaxonomicScope=$taxonUuid";
1199
  }
1200
  $pager = cdm_ws_get($cdm_ws_pasepath, NULL, $queryParameters);
1201

    
1202
  if (!$pager || $pager->count == 0) {
1203
    return array();
1204
  }
1205
  return $pager->records;
1206
}
1207

    
1208
/**
1209
 * @todo Please document this function.
1210
 * @see http://drupal.org/node/1354
1211
 */
1212
function theme_cdm_IdentificationKey($variables) {
1213
  $out = '';
1214
  $identificationKey = $variables['identificationKey'];
1215
  $doLinkToKeyPage = $variables['doLinkToKeyPage'];
1216
  $showIdentificationKeyTitle = $variables['showIdentificationKeyTitle'];
1217
  $parentRenderPath = RenderHints::getRenderPath();
1218
  RenderHints::pushToRenderStack("IdentificationKey");
1219

    
1220
  if ($showIdentificationKeyTitle) {
1221
    if ($doLinkToKeyPage) {
1222
      $out = l($identificationKey->titleCache, path_to_key($identificationKey->class, $identificationKey->uuid));
1223
    }
1224
    else {
1225
      $out = $identificationKey->titleCache;
1226
    }
1227
  }
1228
  if (isset($identificationKey->sources) && is_array($identificationKey->sources)) {
1229
    // order and display sources.
1230
    $sources = oder_sources($identificationKey->sources, TRUE);
1231
    $out .= '<div class="sources">';
1232
    $out .=  implode('', $sources);
1233
    $out .= '</div>';
1234
  }
1235
  // Display annotations.
1236
  $out .= theme('cdm_annotations', array('annotations' => cdm_ws_getAnnotationsFor($identificationKey), 'enclosingTag' => 'div'));
1237
  RenderHints::popFromRenderStack();
1238
  return $out;
1239
}
1240

    
1241
/**
1242
 * @todo Please document this function.
1243
 * @see http://drupal.org/node/1354
1244
 */
1245
function theme_cdm_polytomousKey($variables) {
1246
  $polytomousKey = $variables['polytomousKey'];
1247

    
1248
  // TODO settings needed.
1249
  // @see http://en.wikipedia.org/wiki/Single_access_key#Presentation_styles
1250
  // @see http://dev.e-taxonomy.eu/trac/ticket/2152
1251
  $keyStyle = "linkedStyle";
1252

    
1253
  RenderHints::pushToRenderStack("polytomousKey");
1254
  // Key nodes in linked style.
1255
  $out = '<table class="polytomousKey polytomousKey_' . $keyStyle . '">';
1256
  $out .= theme('cdm_polytomousKey_' . $keyStyle . '_subgraph', array('polytomousKeyNode' => $polytomousKey->root));
1257
  $out .= '</table>';
1258
  RenderHints::popFromRenderStack();
1259
  return $out;
1260
}
1261

    
1262
/**
1263
 * @todo Please document this function.
1264
 * @see http://drupal.org/node/1354
1265
 */
1266
function theme_cdm_polytomousKey_linkedStyle_subgraph($variables) {
1267
  $polytomousKeyNode = $variables['polytomousKeyNode'];
1268
  static $statementCountCharacter = '\'';
1269
  $out = "";
1270

    
1271
  if (is_array($polytomousKeyNode->children)) {
1272
    $childIndex = 0;
1273

    
1274
    // Render edges of the current node.
1275
    foreach ($polytomousKeyNode->children as &$child) {
1276

    
1277
      if (!isset($child->statement) && isset($child->taxon->uuid)) {
1278
        // Skip node with empty statements (see below for explanation: "Special
1279
        // case").
1280
        // this skipping here happens always in the next deeper level of iteration
1281
        // the check below is node on the level above
1282
        continue;
1283
      }
1284

    
1285
      /*
1286
       * Special case: Child nodes with empty statements but taxa as leaf are to
1287
       * treated as if all those taxa where direct children of the source node.
1288
       */
1289
      $islinkToManyTaxa = !isset($child->children[0]->statement) && isset($child->children[0]->taxon->uuid);
1290
      $islinkToTaxon = isset($child->taxon->uuid);
1291
      $islinkToSubKey = isset($child->subkey->uuid);
1292
      $islinkToOtherNode = isset($child->otherNode);
1293
      // Either NULL or 0.
1294
      $islinkToNode = $child->nodeNumber && !$islinkToManyTaxa && !$islinkToOtherNode;
1295
      $hasQuestion = !empty($polytomousKeyNode->question->label_l10n);
1296
      $hasFeature = isset($polytomousKeyNode->feature);
1297

    
1298
      // $indentEdge = $hasQuestion && $childIndex > 0;
1299
      // Question.
1300
      if ($hasQuestion && $childIndex == 0) {
1301
        // Place question, as extra table row.
1302
        $out .= '<tr class="question new_section">';
1303
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber) . "</td>";
1304
        $out .= '<td class="question">' . $polytomousKeyNode->question->label_l10n . '</td>';
1305
        $out .= '</tr>';
1306
      }
1307

    
1308
      $out .= '<tr class="childCount_' . $childIndex . (!$hasQuestion && $childIndex == 0 ? ' new_section' : '') . '">';
1309

    
1310
      if ($hasQuestion) {
1311
        $out .= '<td class="nodeNumber"></td>';
1312
      }
1313
      else {
1314
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber . str_pad("", $childIndex, $statementCountCharacter)) . "</td>";
1315
      }
1316

    
1317
      $out .= '<td ' . RenderHints::getHtmlElementID($child) . '  class="edge' . ($hasQuestion ? ' edge-indent' : '') . '">';
1318

    
1319
      // Feature.
1320
      if ($hasFeature) {
1321
        $out .= $polytomousKeyNode->feature->representation_L10n . ": ";
1322
      }
1323

    
1324
      // Statement.
1325
      $out .= $child->statement->label_l10n;
1326

    
1327
      // --- Links to nodes taxa and subkeys.
1328
      $out .= '<div class="nodeLink">';
1329

    
1330
      // Link to a PolytomousKeyNode.
1331
      if ($islinkToNode) {
1332
        $out .= '<div class="nodeLinkToNode">';
1333
        if (is_object($child->modifyingText)) {
1334
          $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $child->modifyingText));
1335
        }
1336
        $out .= l($child->nodeNumber, request_path(), array(
1337
          'attributes' => NULL,
1338
          'query' => NULL,
1339
          'fragment' => $child->uuid,
1340
        )) . '</div>';
1341
      }
1342

    
1343
      // Link to a PolytomousKeyNode.
1344
      if ($islinkToOtherNode) {
1345
        $out .= '<div class="nodeLinkToOtherNode">';
1346
        if (is_object($child->modifyingText)) {
1347
          $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $child->modifyingText));
1348
        }
1349
        $out .= l($child->otherNode->nodeNumber, $_REQUEST["q"], array(
1350
          'attributes' => NULL,
1351
          'query' => NULL,
1352
          'fragment' => $child->otherNode->uuid,
1353
        )) . '</div>';
1354
      }
1355

    
1356
      // Link to one or many taxa.
1357
      if ($islinkToTaxon || $islinkToManyTaxa) {
1358

    
1359
        if ($islinkToManyTaxa) {
1360
          $taxonChildren = $child->children;
1361
        }
1362
        else {
1363
          $taxonChildren = array(
1364
            $child,
1365
          );
1366
        }
1367

    
1368
        foreach ($taxonChildren as $taxonChild) {
1369
          // TODO many taxa $child->children->taxon.
1370
          $out .= '<div class="nodeLinkToTaxon">';
1371
          if (is_object($taxonChild->modifyingText)) {
1372
            $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $taxonChild->modifyingText));
1373
          }
1374
          $out .= theme("cdm_taxonName", array('taxonName' => $taxonChild->taxon->name, 'nameLink' => url(path_to_taxon($taxonChild->taxon->uuid))));
1375
          $out .= '</div>';
1376
        }
1377

    
1378
        // Link to a subkey.
1379
        if ($islinkToSubKey) {
1380
          $out .= '<div class="nodeLinkToSubkey">' . theme('cdm_IdentificationKey', array('identificationKey' => $child->subkey)) . '</div>';
1381
        }
1382
      }
1383

    
1384
      $out .= '</div>'; // End node link.
1385
      $out .= '</td>'; // End edge.
1386
      $out .= '</tr>';
1387

    
1388
      $childIndex++;
1389
    }
1390

    
1391
    // Recurse into child nodes.
1392
    foreach ($polytomousKeyNode->children as &$child) {
1393
      $out .= theme('cdm_polytomousKey_linkedStyle_subgraph', array('polytomousKeyNode' => $child));
1394
    }
1395
  }
1396

    
1397
  return $out;
1398
}
1399

    
1400
/**
1401
 * @todo Please document this function.
1402
 * @see http://drupal.org/node/1354
1403
 */
1404
function theme_cdm_poytomousKeyNode_modifyingText($variables) {
1405
  $out = '';
1406
  $modifyingText = $variables['modifyingText'];
1407
  if (is_object($modifyingText)) {
1408
    $i = 0;
1409
    foreach (get_object_vars($modifyingText) as $lang => $languageString) {
1410
      $out .= ($i++ > 0 ? ', ' : '') . '<span class="modifyingText">' . $languageString->text . '</span> ';
1411
    }
1412
  }
1413
  return $out;
1414
}
1415

    
1416
/**
1417
 * Returns HTML for a list of a specific type of IdentificationKeys.
1418
 *
1419
 * The list can be restricteded by a taxon.
1420
 *
1421
 * @param array $variables
1422
 *   An associative array containing:
1423
 *   - type: The simple name of the cdm class implementing the interface
1424
 *     IdentificationKey, valid values are:
1425
 *     PolytomousKey, MediaKey, MultiAccessKey
1426
 *   - taxonUuid: If given, this parameter restrict the listed keys to those
1427
 *     which have the taxon identified be this uuid in scope.
1428
 *
1429
 * @ingroup themeable
1430
 */
1431
function theme_cdm_list_IdentificationKeys($variables) {
1432
  $type = $variables['type'];
1433
  $taxonUuid = $variables['taxonUuid'];
1434
  $keyList = _list_IdentificationKeys($type, $taxonUuid);
1435
  if (!$keyList || count($keyList) == 0) {
1436
    return;
1437
  }
1438

    
1439
  RenderHints::pushToRenderStack('list_IdentificationKeys');
1440
  $out = '<ul>';
1441
  foreach ($keyList as $key) {
1442
    $out .= '<li>';
1443
    $out .= theme('cdm_IdentificationKey', array('identificationKey' => $key));
1444
    $out .= '</li>';
1445
  }
1446
  $out .= '</ul>';
1447
  $out .= theme("cdm_annotation_footnotes", array('footnoteListKey' => RenderHints::getRenderPath()));
1448
  RenderHints::popFromRenderStack();
1449

    
1450
  return $out;
1451
}
1452

    
1453
/**
1454
 * @todo Please document this function.
1455
 * @see http://drupal.org/node/1354
1456
 */
1457
function theme_cdm_block_IdentificationKeys($variables) {
1458
  $taxonUuid = $variables['taxonUuid'];
1459
  static $types = array(
1460
    "PolytomousKey" => "Polytomous",
1461
    "MediaKey" => "Media",
1462
    "MultiAccessKey" => "Multiaccess",
1463
  );
1464
  RenderHints::pushToRenderStack('block_IdentificationKeys');
1465
  $out = '';
1466
  foreach ($types as $type => $label) {
1467
    $keylist = theme('cdm_list_IdentificationKeys', array('type' => $type, 'taxonUuid' => $taxonUuid));
1468
    if (!$keylist) {
1469
      continue;
1470
    }
1471
    $out .= '<div class="' . $type . '">';
1472
    $out .= '<h3>' . t($label) . "</h3>";
1473
    $out .= $keylist;
1474
    $out .= '</div>';
1475
  }
1476
  RenderHints::popFromRenderStack();
1477
  return $out;
1478
}
1479

    
1480
/**
1481
 * This theming function formats the use description and use record list for
1482
 * these descriptions.
1483
 *
1484
 * @see http://drupal.org/node/1354
1485
 */
1486
function theme_cdm_UseDescription($variables) {
1487
  $descriptions = $variables['description'];
1488
  $taxonUuid = $variables['taxonUuid'];
1489
  $out = '<div id="content"><ul id="Description" class ="description">';
1490
  if ($descriptions == NULL) {
1491
    return;
1492
  }
1493
  $descriptionSynonyms = '';
1494
  $descriptionOut = '';
1495
  $synonymOut = '';
1496
  $currentTaxon = cdm_ws_get(CDM_WS_PORTAL_TAXON, $taxonUuid);
1497

    
1498
  foreach ($descriptions as $description) {
1499
    $useSummary = '';
1500
    foreach ($description->elements as $element) {
1501

    
1502
      if ($element->feature->uuid == UUID_USE && !(strlen($useSummary) > 0)) {
1503
        $useSummary = $element->multilanguageText_L10n->text;
1504
      }
1505
    }
1506
    // uses will be ordered by source
1507
    foreach ($description->sources as $source) {
1508
      $is_about_current_taxon = FALSE;
1509
      $originalTaxonUsedInSource = NULL;
1510
      $originalTaxonPager = NULL;
1511
      if ($source->originalNameString) {
1512
        $request_params = array();
1513
        $request_params['query'] = $source->originalNameString;
1514
        $request_params['matchMode'] = "EXACT";
1515
        $originalTaxonPager = cdm_ws_get(CDM_WS_PORTAL_NAME_FINDBYNAME, NULL, queryString($request_params));
1516
        if ($originalTaxonPager->count > 0) {
1517
          $originalTaxonUsedInSource = $originalTaxonPager->records[0];
1518
        }
1519
        else {
1520
          $originalTaxonUsedInSource = $currentTaxon->name;
1521
        }
1522
      }
1523
      else {
1524
        $originalTaxonUsedInSource = $currentTaxon->name;
1525
      }
1526

    
1527
      $is_about_current_taxon = $currentTaxon->name->uuid == $originalTaxonUsedInSource->uuid;
1528

    
1529
      if (!$is_about_current_taxon) {
1530
        $descriptionOut .= '<li class="descriptionText DescriptionElement">';
1531
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1532
          'absolute' => TRUE,
1533
          'html' => TRUE,
1534
        ));
1535
        $descriptionOut .= $name_used_in_source_link_to_show_use . ': ';
1536
        $descriptionOut .= $useSummary;
1537
        foreach ($description->sources as $source) {
1538
          $descriptionOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1539
        }
1540
        $hasUseRecords = FALSE;
1541
        $descriptionUseRecordOut = '<div id=useRecords><table><th>Use Category</th><th>Use Sub Category</th><th>Plant Part</th><th>Human Group</th><th>Ethnic Group</th><th>Country</th>';
1542
        foreach ($description->elements as $descriptionElement) {
1543
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1544
            $hasUseRecords = TRUE;
1545
            // FIXME localization hardcoded to English
1546
            $useRecordTags = explode(';', $descriptionElement->modifyingText->English->text);
1547
            $descriptionUseRecordOut .= '<tr>';
1548
            $descriptionUseRecordOut .= '<td>' . $useRecordTags[0] . '</td>' . '<td>' . $useRecordTags[1] . '</td>' . '<td>' . $useRecordTags[3] . '</td>' . '<td>' . $useRecordTags[4] . '</td>' . '<td>' . $useRecordTags[5] . '</td>' . '<td>' . $useRecordTags[2] . '</td>';
1549
            $descriptionUseRecordOut .= '</tr>';
1550
          }
1551
        }
1552
        $descriptionUseRecordOut .= '</table></div>';
1553
        if ($hasUseRecords) {
1554
          $descriptionOut .= $descriptionUseRecordOut . '</li>';
1555
        }
1556
      }
1557
      else {
1558
        // TODO +/- duplicate of above, unify this code
1559
        $synonymOut .= '<li class="descriptionText DescriptionElement">';
1560
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1561
          'absolute' => TRUE,
1562
          'html' => TRUE,
1563
        ));
1564

    
1565
        $synonymOut .= $name_used_in_source_link_to_show_use . ': ';
1566
        $synonymOut .= $useSummary;
1567
        foreach ($description->sources as $source) {
1568
          $synonymOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1569
        }
1570

    
1571
        $hasUseRecords = FALSE;
1572
        $useRecordTableOut = '<div id=useRecords><table><th>Use Category</th><th>Use Sub Category</th><th>Plant Part</th><th>Human Group</th><th>Ethnic Group</th><th>Country</th>';
1573
        foreach ($description->elements as $descriptionElement) {
1574
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1575
            $hasUseRecords = TRUE;
1576
            $useRecordTags = explode(';', $descriptionElement->modifyingText->English->text);
1577
            $useRecordTableOut .= '<tr>';
1578
            $useRecordTableOut .= '<td>' . $useRecordTags[0] . '</td>' . '<td>' . $useRecordTags[1] . '</td>' . '<td>' . $useRecordTags[3] . '</td>' . '<td>' . $useRecordTags[4] . '</td>' . '<td>' . $useRecordTags[5] . '</td>' . '<td>' . $useRecordTags[2] . '</td>';
1579
            $useRecordTableOut .= '</tr>';
1580
          }
1581
        }
1582
        $useRecordTableOut .= '</table></div>';
1583
        if ($hasUseRecords) {
1584
          $synonymOut .= $useRecordTableOut . '</li>';
1585
        }
1586
      }
1587

    
1588
      // }
1589
    }
1590
  }
1591
  $out .= $descriptionOut . $synonymOut;
1592
  $out .= "</ul></div>";
1593
  return $out;
1594
}
1595

    
1596
// The Uses theming function here will handle the display of the
1597
// Uses Descriptions.
1598
// Comment @WA: $pageSize is not used.
1599
// function theme_cdm_block_Uses ($taxonUuid = NULL, $pageSize = NULL {
1600
/**
1601
 * @todo Please document this function.
1602
 * @see http://drupal.org/node/1354
1603
 */
1604
function theme_cdm_block_Uses($variables) {
1605
  $taxonUuid = $variables['taxonUuid'];
1606
  RenderHints::pushToRenderStack('block_Uses');
1607

    
1608
  if ($taxonUuid == NULL) {
1609
    return;
1610
  }
1611
  $out = '';
1612
  $markerTypes = array();
1613
  $markerTypes['markerTypes'] = UUID_MARKERTYPE_USE;
1614
  $useDescriptions = cdm_ws_get(CDM_WS_PORTAL_TAXON_DESCRIPTIONS, $taxonUuid, queryString($markerTypes));
1615
  if (!empty($useDescriptions)) {
1616
    // FIXME use theme_block instaed of hardcoding the block html here !!!!
1617
    $out .= '<div id="block-cdm_dataportal-feature-description" class="clear-block block block-cdm_dataportal-feature"><H2><a name="userecords"> </a> Uses </H2>';
1618
    $formatUseDescriptions = theme('cdm_UseDescription', array('description' => $useDescriptions, 'taxonUuid' => $taxonUuid));
1619

    
1620
    $out .= $formatUseDescriptions;
1621
    $out .= "</div>";
1622
  }
1623

    
1624
  return $out;
1625
}
(3-3/10)