Project

General

Profile

Download (56.3 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
/**
18
 * Theme function to alter the feature representation.
19
 *
20
 * It is highly qeutionalbe if this function should be completely removed.
21
 * If a feature needs a different representation this should be edited directly
22
 * in the cdm data but it shoud not be tweeked like this in the portal.
23
 *
24
 * Used in:
25
 *  - theme_cdm_feature_nodesTOC()
26
 *  - theme_cdm_feature_nodes()
27
 *  - theme_cdm_media_mime_application()
28
 *  - theme_cdm_media_mime_text()
29
 *
30
 * TODO delete this function? (a.kohlbecker feb 2013)
31
 *
32
 */
33
function theme_cdm_feature_name($variables) {
34
  $feature_name = $variables['feature_name'];
35
  // TODO replace by using translations ?
36
  return t($feature_name);
37
}
38

    
39
/**
40
 * Returns HTML for a taxon profile from the $mergedFeatureNodes of a given $taxon.
41
 *
42
 * The taxon profile consists of description elements which are ordered by the
43
 * structure defined by specific FeatureTree. The chosen FeatureTree is merged
44
 * with the list of desctiprion elements prior to using this method.
45
 *
46
 * The merged nodes can be obtained by making use of the
47
 * function cdm_ws_descriptions_by_featuretree().
48
 *
49
 * @see cdm_ws_descriptions_by_featuretree()
50
 *
51
 * @param array $variables
52
 *   An associative array containing:
53
 *   - mergedFeatureNodes
54
 *   -taxon
55
 *
56
 * @ingroup themeable
57
 */
58
function theme_cdm_feature_nodes($variables) {
59

    
60
  $mergedFeatureNodes = $variables['mergedFeatureNodes'];
61
  $taxon = $variables['taxon'];
62
  $out = '';
63

    
64
  RenderHints::pushToRenderStack('feature_nodes');
65

    
66
  $gallery_settings = getGallerySettings(CDM_DATAPORTAL_DESCRIPTION_GALLERY_NAME);
67

    
68
  // Creating an array to place the description elements in.
69
  foreach ($mergedFeatureNodes as $node) {
70

    
71
    if (hasFeatureNodeDescriptionElements($node)) {
72

    
73
      $featureRepresentation = isset($node->feature->representation_L10n) ? $node->feature->representation_L10n : 'Feature';
74
      $block = new stdclass(); // Empty object.
75
      $block->module = 'cdm_dataportal';
76
      $media_list = array();
77

    
78
      if (true || $node->feature->uuid != UUID_IMAGE) {
79

    
80
        $block->delta = generalizeString($featureRepresentation);
81
        $block->subject = '<span class="' . html_class_atttibute_ref($node->feature) . '">' . theme('cdm_feature_name', array('feature_name' => $featureRepresentation)) . '</span>';
82
        $block->module = "cdm_dataportal-feature";
83
        $block->content = '';
84

    
85
        /*
86
         * Content/DISTRIBUTION.
87
         */
88
        if ($node->feature->uuid == UUID_DISTRIBUTION) {
89

    
90
          $node->descriptionElements = cdm_description_elements_prefer_computed($node->descriptionElements);
91

    
92
          if (variable_get(DISTRIBUTION_TEXTDATA_DISPLAY_ON_TOP, 0)) {
93
            $distributionTextDataList = array();
94
            $distributionElementsList = array();
95

    
96
            foreach ($node->descriptionElements as $descriptionElement) {
97
              if ($descriptionElement->class == "TextData") {
98
                $distributionTextDataList[] = $descriptionElement;
99
              }
100
              else {
101
                $distributionElementsList[] = $descriptionElement;
102
              }
103
            }
104

    
105

    
106
            if (count($distributionTextDataList) > 0) {
107
              $node->descriptionElements = $distributionElementsList;
108
              $block->content .= theme('cdm_descriptionElements', array(
109
                'descriptionElements' => $distributionTextDataList,
110
                'featureUuid' => $node->feature->uuid,
111
                'taxon_uuid' => $taxon->uuid,
112
              ));
113
            }
114
          }
115

    
116
          // Display cdm distribution map TODO this is a HACK to a proper
117
          // generic implementation?
118
          $map_render_element = compose_distribution_map($taxon);
119
          $block->content .= $map_render_element['#markup'];
120
          $block->content .= theme('cdm_descriptionElements', array(
121
            'descriptionElements' => $node->descriptionElements,
122
            'featureUuid' => $node->feature->uuid,
123
            'taxon_uuid' => $taxon->uuid,
124
          ));
125

    
126
        }
127

    
128
        /*
129
         * Content/COMMON_NAME.
130
         */
131
        elseif ($node->feature->uuid == UUID_COMMON_NAME) {
132
          // TODO why is theme_cdm_descriptionElement_CommonTaxonName not
133
          // beeing used???
134
         $block->content .= theme('cdm_common_names', array('elements' => $node->descriptionElements));
135
          /*
136
          }else if($node->feature->uuid == UUID_IMAGE_SOURCES) {
137
          $block->content .= theme('cdm_image_sources',
138
          $node->descriptionElements);
139
          */
140
        }
141

    
142
        /*
143
         * Content/ALL OTHER FEATURES.
144
         */
145
        else {
146
          if (isset($node->descriptionElements)) {
147
            $taxon_uuid = NULL;
148
            if(isset($taxon) ) {
149
              $taxon_uuid = $taxon->uuid;
150
            }
151
            $block->content .= theme('cdm_descriptionElements', array(
152
              'descriptionElements' => $node->descriptionElements,
153
              'featureUuid' => $node->feature->uuid,
154
              'taxon_uuid' => $taxon_uuid,
155
            ));
156
          }
157

    
158
//           Content/ALL OTHER FEATURES/Subordinate Features
159
//           subordinate features are printed inline in one floating text,
160
//           it is expected hat supordinate features can "contain" TextData,
161
//           Qualitative- and Qualitative- DescriptioneElements
162
          if (isset($node->children[0])) {
163

    
164
            // TODO support more than one level of children.
165
            // can this be solved by resursively calling this very function?
166
            // @see http://dev.e-taxonomy.eu/trac/ticket/2393
167
            $text = '';
168
            foreach ($node->children as $child) {
169

    
170
              if (isset($child->descriptionElements) && is_array($child->descriptionElements)) {
171
                foreach ($child->descriptionElements as $element) {
172

    
173
                  if (is_array($element->media)) {
174
                    // Append media of supordinate elements to list of main
175
                    // feature.
176
                    $media_list = array_merge($media_list, $element->media);
177
                  }
178

    
179
                  switch ($element->class) {
180
                    case 'TextData':
181
                      // TODO use theme_cdm_descriptionElementTextData()
182
                      $out_child_elements = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
183
                      $out_child_elements = str_replace($child->feature->titleCache, '<em>' . $child->feature->representation_L10n . '</em>', $out_child_elements);
184
                      break;
185
                    case 'CategoricalData':
186
                      $out_child_elements  = '<em>' . $child->feature->representation_L10n . '</em> '
187
                        . theme('cdm_descriptionElement_CategoricalData', array('element' => $element));
188
                      break;
189
                    case 'QuantitativeData':
190
                      $out_child_elements = '<em>' . $child->feature->representation_L10n . '</em> '
191
                        . theme('cdm_descriptionElement_QuantitativeData', array('element' => $element));
192

    
193
                  }
194

    
195
                }
196
                $text .= " " . $out_child_elements;
197
                $out_child_elements = '';
198
              }
199
            }
200
            $block->content .= $text;
201
          }
202
        }
203

    
204
        /*
205
         * Media/ALL FEATURES.
206
         */
207
        if (isset($node->descriptionElements)) {
208
          $media_list = array_merge($media_list, cdm_dataportal_media_from_descriptionElements($node->descriptionElements));
209
        }
210
        $captionElements = array('title', 'rights');
211
        $gallery = '';
212
        if (isset($gallery_settings['cdm_dataportal_media_maxextend']) && isset($gallery_settings['cdm_dataportal_media_cols'])) {
213
          $gallery = theme('cdm_media_gallerie', array(
214
            'mediaList' => $media_list,
215
            'galleryName' => CDM_DATAPORTAL_DESCRIPTION_GALLERY_NAME . '_' . $node->feature->uuid,
216
            'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
217
            'cols' => $gallery_settings['cdm_dataportal_media_cols'],
218
            'captionElements' => $captionElements,
219
          ));
220
        }
221
        $block->content .= $gallery;
222
        $block->content .= theme('cdm_footnotes', array('footnoteListKey' => $node->feature->uuid));
223
        $block->content .= theme('cdm_annotation_footnotes', array('footnoteListKey' => $node->feature->uuid));
224

    
225
        // Add anchor to subject.
226
        $block->subject = '<a name="' . $block->delta . '"></a>' . $block->subject;
227

    
228
        // In D6: $out .= theme('block', $block);
229
        // Comment @WA @TODO check if need to set a region, and which one.
230
        $block->region = FALSE;
231
        $out .= theme('block', array('elements' => array(
232
          '#block' => $block,
233
          '#children' => $block->content,
234
        )));
235
      }
236
    }
237
  }
238
  RenderHints::popFromRenderStack();
239
  return $out;
240
}
241

    
242
/**
243
 * @todo Please document this function.
244
 * @see http://drupal.org/node/1354
245
 */
246
function theme_FeatureTree_hierarchy($variables) {
247

    
248
  $FeatureTreeUuid = $variables['FeatureTreeUuid'];
249
  if (!is_uuid($FeatureTreeUuid)) {
250
    return;
251
  }
252

    
253
  $out = '';
254
  $featureTree = cdm_ws_get(CDM_WS_FEATURETREE, array(
255
    $FeatureTreeUuid,
256
  ));
257

    
258
  if (isset($featureTree) && isset($featureTree->root)) {
259
    $out = '<ul class="' . $featureTree->class . '">';
260
    $out .= theme('FeatureTree_hierarchy_children', array('node' => $featureTree->root));
261
    $out .= '</ul>';
262
  }
263
  return $out;
264
}
265

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

    
272
  $node = $variables['node'];
273
  $out = '';
274
  if (isset($node->children)) {
275

    
276
    foreach ($node->children as $childNode) {
277
      $out .= '<li>' . check_plain($childNode->feature->representation_L10n);
278
      if (isset($childNode->children) && count($childNode->children) > 0) {
279
        $out .= '<ul>' . theme('FeatureTree_hierarchy_children', array('node' => $childNode)) . '</ul>';
280
      }
281
      $out .= '</li>';
282
    }
283
  }
284
  return $out;
285
}
286

    
287
/**
288
 * Returns HTML for the texts in a description $elementArray.
289
 *
290
 * Joins the texts in $elementArray and encloses with a HTML tag.
291
 *
292
 * @param array $variables
293
 *   An associative array containing:
294
 *   - elementArray
295
 *   - feature: The feature to which the elements given in $elementArray are
296
 *     belonging to.
297
 *   - glue: Defaults to empty string.
298
 *   - sortArray: Whether to sort the $elementArray alphabetically.
299
 *   - enclosingHtml
300
 *
301
 * @ingroup themeable
302
 */
303
function theme_cdm_descriptionElementArray($variables) {
304
  $elementArray = $variables['elementArray'];
305

    
306
  $feature = $variables['feature'];
307
  $glue = $variables['glue'];
308
  $sortArray = $variables['sortArray'];
309
  $enclosingHtml = $variables['enclosingHtml'];
310
  $out = '<' . $enclosingHtml . ' class="description" id="' . $feature->representation_L10n . '">';
311

    
312
  if ($sortArray) {
313
    sort($elementArray);
314
  }
315

    
316
  $out .= join($elementArray, $glue);
317

    
318
  $out .= '</' . $enclosingHtml . '>';
319
  return $out;
320
}
321

    
322
/**
323
 * @todo Please document this function.
324
 * @see http://drupal.org/node/1354
325
 */
326
function theme_cdm_descriptionElement_CommonTaxonName($variables) {
327
  $element = $variables['element'];
328
  $out = '<span class="' . html_class_atttibute_ref($element) . '">' . $element->language->representation_L10n . ' (' . $element->area->titleCache . '): ' . $element->name . '</span>';
329
  return $out;
330
}
331

    
332
/**
333
* @todo Please document this function.
334
* @see http://drupal.org/node/1354
335
*/
336
function theme_cdm_descriptionElement_CategoricalData($variables) {
337
  $element = $variables['element'];
338

    
339
  $state_data_strings = array();
340
  if (isset($element->states)) {
341
    foreach ($element->states as $stateData) {
342

    
343
      $state  = NULL;
344

    
345
      if(isset($stateData->state)){
346
        $state = cdm_term_representation($stateData->state);
347
      }
348

    
349
      if (isset($stateData->modifyingText_L10n)) {
350
        $state = ' ' . $stateData->modifyingText_L10n;
351
      }
352

    
353
      $modifiers_strings = cdm_modifers_representations($stateData);
354

    
355
      $state_data_strings[] = $state . ($modifiers_strings ? ' ' . $modifiers_strings : '');
356

    
357
      // FIXME render sources
358

    
359
    }
360
  }
361
  $out = '<span class="' . html_class_atttibute_ref($element) . '">' . implode(', ', $state_data_strings) . '</span>';
362
  return $out;
363
}
364

    
365
function theme_cdm_descriptionElement_QuantitativeData($variables) {
366
  /*
367
   * - statisticalValues
368
   *   - value
369
   *   - modifiers
370
   *   - type
371
   * - unit->representation_L10n
372
   * - modifyingText
373
   * - modifiers
374
   * - sources
375
   */
376
  $element = $variables['element'];
377

    
378
  $out = '';
379

    
380
  $type_representation = NULL;
381
  $modifiers_strings = array();
382

    
383

    
384
  if (isset($element->statisticalValues)) {
385
    $value_array = array();
386
    foreach ($element->statisticalValues as $val) {
387
      if (isset($val->value)) {
388
        $value_array[] = $val->value;
389
      }
390
    }
391

    
392
    $out .= implode($value_array, ', ');
393
  }
394

    
395
  if (isset($element->unit)) {
396
    $out .= ' '. cdm_term_representation($element->unit);
397
  }
398

    
399
  if (isset($element->statisticalValues->modifyingText_L10n)) {
400
    $out .=  ' ' . $element->statisticalValues->modifyingText_L10n;
401
  }
402
  $modifers_string = cdm_modifers_representations($element->statisticalValues);
403
  $out .= ($modifers_string ? ' ' . cdm_modifers_representations($element->statisticalValues) : '');
404

    
405
  // FIXME render sources
406

    
407
  return $out;
408

    
409
}
410

    
411
/**
412
 * Returns HTML for citations textdata elements.
413
 *
414
 * TODO: assign a new name to the function? Because it is used for the citations
415
 * textdata elements and not for all text data description elements.
416
 *
417
 * @param array $variables
418
 *   An associative array containing:
419
 *   - element: The description element which contains the text information.
420
 *   - asListElement: A boolean which determines whether the citations should
421
 *     be rendered as a list or not.
422
 *   - feature_uuid
423
 *
424
 * @ingroup themeable
425
 */
426
function theme_cdm_descriptionElementTextData($variables) {
427

    
428
  $element = $variables['element'];
429
  $asListElement = $variables['asListElement'];
430
  $feature_uuid = $variables['feature_uuid'];
431

    
432
  $description = '';
433
  if (isset($element->multilanguageText_L10n->text)) {
434
    $description = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
435
  }
436
  $sourceRefs = '';
437
  $result = array();
438
  $out = '';
439
  $res_author = '';
440
  $res_date = '';
441
  if (isset($element->sources) && is_array($element->sources) && count($element->sources) > 0) {
442
    foreach ($element->sources as $source) {
443
      $referenceCitation = theme('cdm_OriginalSource', array('source' => $source));
444
      if ($description && strlen($description) > 0 && $referenceCitation) {
445
        $sourceRefs .= ' (' . $referenceCitation . ')';
446
      }
447
      elseif ($referenceCitation) {
448
        $sourceRefs = $referenceCitation;
449
      }
450

    
451
      if (strlen($sourceRefs) > 0) {
452
        $sourceRefs = '<span class="sources">' . $sourceRefs . '</span>';
453
      }
454
      $name_used_in_source_link_to_show = '';
455
      // Do a link to name page.
456
      if (isset($source->nameUsedInSource->uuid) && isset($source->nameUsedInSource->titleCache)) {
457
        $name_used_in_source_link_to_show = l($source->nameUsedInSource->titleCache, path_to_name($source->nameUsedInSource->uuid), array(
458
          'attributes' => array(),
459
          'absolute' => TRUE,
460
          'html' => TRUE,
461
        ));
462
      }
463
      // Show a text without link.
464
      elseif (isset($source->nameUsedInSource->originalNameString) && strlen($source->nameUsedInSource->originalNameString) > 0) {
465
        $name_used_in_source_link_to_show = $source->nameUsedInSource->originalNameString;
466
      }
467

    
468
      if ($asListElement) {
469

    
470
       $out = '<li class="descriptionText DescriptionElement">';
471
        // Adding ":" if necessary.
472
        if (!empty($name_used_in_source_link_to_show)) {
473
          if ( (!empty($description)|| !empty($sourceRefs)) && $feature_uuid != UUID_CHROMOSOMES_NUMBERS) {
474
            $out .= $name_used_in_source_link_to_show . ': ';
475
          } else {
476
            $out .= $name_used_in_source_link_to_show . ' ';
477
          }
478
        }
479
        $out .= $description . $sourceRefs . theme('cdm_annotations_as_footnotekeys', array('cdmBase_list' => $element, 'footnote_list_key' => $feature_uuid)) . '</li>';
480
      }
481
      else {
482
        if ($name_used_in_source_link_to_show) {
483
          $name_used_in_source_link_to_show = ' (name in source: ' . $name_used_in_source_link_to_show . ')';
484
        }
485

    
486
        $out = '<span class="DescriptionElement DescriptionElement-' . $element->class . '">' . $description . $sourceRefs . $name_used_in_source_link_to_show . '</span>';
487
      }
488
    }
489
  }
490
  else {
491
    // If no sources, print the description.
492
    $out = $description;
493
  }
494
  return $out;
495
}
496

    
497
/**
498
 * @todo Please document this function.
499
 * @see http://drupal.org/node/1354
500
 */
501
function theme_cdm_common_names($variables) {
502
  $elements = $variables['elements'];
503
  $text_data_out = '';
504
  $common_name_out = '';
505
  $separator = ',';
506
  $textData_commonNames = array();
507

    
508
  if (is_array($elements)) {
509
    foreach ($elements as $element) {
510
      if ($element->class == 'CommonTaxonName') {
511

    
512
        // common name without a language or area, should not happen but is possible
513
        $language_area_key = '';
514
        if (isset($element->language->representation_L10n)) {
515
          $language_area_key .= '<b>' . $element->language->representation_L10n . '</b>';
516
        }
517
        if(isset($element->area->titleCache) && strlen($element->area->titleCache) > 0){
518
          $language_area_key .= ($language_area_key ? ' '  : '') . '(' . $element->area->titleCache . ')';
519
        }
520

    
521
        if(isset($common_names[$language_area_key][$element->name])) {
522
          // same name already exists for language and areae combination, se we merge the description elements
523
          cdm_merge_description_elements($common_names[$language_area_key][$element->name], $element);
524
        } else{
525
          // otherwise add as new entry
526
          $common_names[$language_area_key][$element->name] = $element;
527
        }
528

    
529
      }
530
      elseif ($element->class == 'TextData') {
531
        $textData_commonNames[] = $element;
532
      }
533
    }
534
  }
535
  // Handling common names.
536
  if (isset($common_names) && count($common_names) > 0) {
537
    // Sorting the array based on the key (language, + area if set).
538
    // Comment @WA there are common names without a language, so this sorting
539
    // can give strange results.
540
    ksort($common_names);
541

    
542
    // Creating the output to be render by Drupal.
543
    foreach ($common_names as $key => $elements) {
544
      ksort($elements); // sort names alphabetically
545
      $rendered_element_list = '';
546
      foreach ($elements as $element) {
547
        $sourcesFootnoteKeyList = '';
548
        // Adding footnotes sources.
549
        foreach ($element->sources as $source) {
550
          if (_is_original_source_type($source)) {
551
            $_fkey = FootnoteManager::addNewFootnote(UUID_COMMON_NAME, theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)));
552
            $sourcesFootnoteKeyList .= theme('cdm_footnote_key', array('footnoteKey' => $_fkey, 'separator' => ($sourcesFootnoteKeyList ? $separator : '')));
553
          }
554
        }
555
        if ($element->name) {
556
          $rendered_element_list .= '<span class="' . html_class_atttibute_ref($element) . '">' . (strlen($rendered_element_list) > 0 ? ', ' : '') . $element->name . $sourcesFootnoteKeyList . '</span>';
557
        }
558
      }
559
      if ($key) {
560
        $common_name_out .= (strlen($common_name_out) > 0 ? '; ' : '') . $key . ': ' . $rendered_element_list;
561
      }
562
      else {
563
        $common_name_out .= (strlen($common_name_out) > 0 ? '; ' : '') . $rendered_element_list;
564
      }
565
    }
566
  }
567
  // Handling commons names as text data.
568
  foreach ($textData_commonNames as $text_data_element) {
569
    $text_data_out .= theme('cdm_descriptionElementTextData', array(
570
      'element' => $text_data_element,
571
      'asListElement' => TRUE,
572
      'feature_uuid' => $text_data_element->feature->uuid,
573
    ));
574
  }
575

    
576
  $common_name_out = "<div class=common_names_as_common_names> $common_name_out </div>";
577
  $out_array[] = $text_data_out;
578
  $common_name_out_text_data = '<div class=common_names_as_text_data>' . theme('cdm_descriptionElementArray', array('elementArray' => $out_array, 'feature' => $element->feature)) . '</div>';
579

    
580
  return $common_name_out . $common_name_out_text_data;
581
  /*
582
  return $common_name_out . theme('cdm_descriptionElementArray', $out_array,
583
  $element->feature);
584
  return "<div class=common_names> $common_name_out
585
  $common_name_out_text_data";
586
  */
587
}
588

    
589
/**
590
 * Return HTML for a list of description elements.
591
 *
592
 * Usually these are of a specific feature type.
593
 *
594
 * @param array $variables
595
 *   An associative array containing:
596
 *   - array of descriptionElements which belong to the same feature.
597
 *     These descriptions elements of a Description must be ordered by the chosen feature tree by
598
 *     calling the function _mergeFeatureTreeDescriptions().
599
 *     @see _mergeFeatureTreeDescriptions()
600
 *   - featureUuid: currently unused, accoding code disabled
601
 *   - taxon_uuid: only used for ordered dditributions (will be removed!)
602
 *
603
 * @ingroup themeable
604
 */
605
function theme_cdm_descriptionElements($variables) {
606

    
607
  $descriptionElements = $variables['descriptionElements'];
608
  $featureUuid = $variables['featureUuid'];
609
  $taxon_uuid = $variables['taxon_uuid'];
610
  $outArray = array();
611

    
612
  /*
613
  $userDefined = mixed_variable_get(LAYOUT_SETTING_PREFIX . $featureUuid, FEATURE_TREE_LAYOUT_DEFAULTS);
614
  if(variable_get('distribution_sort',
615
      'NO_SORT') != 'NO_SORT'){
616
      $glue = '';
617
      $enclosingTag = 'dl';
618
      $entryEnclosingTag = NULL;
619
  } else if($userDefined &&
620
      $userDefined['enabled']){
621
    $glue = $userDefined['glue'];
622
    $enclosingTag =  $userDefined['enclosingTag'];
623
    $entryEnclosingTag = $userDefined['entryEnclosingTag'];
624
  } else { // TODO remove once  LAYOUT_SETTING_PREFIX-{uuid} setting are configured to work for all portals(selenium test still missing!!!)
625
    $glue = ''; $enclosingTag = 'ul';
626
    $entryEnclosingTag = NULL ;
627
  }
628
  */
629

    
630

    
631
  if (variable_get('distribution_sort', 'NO_SORT') != 'NO_SORT') {
632
    $glue = '';
633
    $enclosingTag = 'dl';
634
  }
635
  else {
636
    $glue = '';
637
    $enclosingTag = 'ul';
638
  }
639

    
640
  $sortOutArray = FALSE;
641
  $distributionElements = array();
642

    
643
  RenderHints::pushToRenderStack('cdm_descriptionElements');
644

    
645
  // Avoiding warning box in drupal for flora malesiana.
646
  if (is_array($descriptionElements)) {
647
    foreach ($descriptionElements as $descriptionElement) {
648

    
649
      // --- DISTRIBUTION ---- //
650
      if ($descriptionElement->feature->uuid == UUID_DISTRIBUTION) {
651
        if ($descriptionElement->class == 'Distribution' && is_object($descriptionElement->area)) {
652
          $sortKey = $descriptionElement->area->representation_L10n;
653
          $distributionElements[$sortKey] = $descriptionElement;
654
        }
655
        elseif ($descriptionElement->class == 'TextData') {
656
          $asListElement = FALSE;
657
          $repr = theme('cdm_descriptionElementTextData', array(
658
            'element' => $descriptionElement,
659
            'asListElement' => $asListElement,
660
            'feature_uuid' => $descriptionElement->feature->uuid,
661
          ));
662

    
663
          if (!array_search($repr, $outArray)) {
664
            $outArray[] = $repr;
665
            // TODO HINT: sorting in theme_cdm_descriptionElementArray will
666
            // not work since this array contains html attributes with uuids
667
            // !!!!
668
            $sortOutArray = TRUE;
669
            $glue = '<br/> ';
670
            $enclosingTag = 'p';
671
          }
672
        }
673
      }
674

    
675
      // --- IMAGE_SOURCES --- //
676
      elseif ($descriptionElement->feature->uuid == UUID_IMAGE_SOURCES) {
677
        $image_sources[] = $descriptionElement;
678
      }
679
      // --- USE TEXTDATA --- //
680
      elseif ($descriptionElement->feature->uuid == UUID_USE) {
681
        // Do nothing to avoid rendering.
682
      } else {
683
        /* decide based on the description element class
684
         *
685
         * TODO provide api_hook as extension point for this
686
         */
687
        switch ($descriptionElement->class) {
688
          case 'TextData':
689
            $asListElement = TRUE;
690
            $outArray[] = theme('cdm_descriptionElementTextData', array(
691
              'element' => $descriptionElement,
692
              'asListElement' => $asListElement,
693
              'feature_uuid' => $descriptionElement->feature->uuid,
694
            ));
695
            break;
696
          case 'CommonTaxonName':
697
            $outArray[] = theme('cdm_descriptionElement_CommonTaxonName', array('element' => $descriptionElement));
698
          break;
699
          case 'CategoricalData':
700
            $outArray[] = theme('cdm_descriptionElement_CategoricalData', array('element' => $descriptionElement));
701
            break;
702
          case 'QuantitativeData':
703
            $outArray[] = theme('cdm_descriptionElement_QuantitativeData', array('element' => $descriptionElement));
704
            break;
705
          case 'Uses':
706
          /* IGNORE Uses classes, these are handled completely in theme_cdm_UseDescription */
707
          break;
708
        default:
709
        $outArray[] = '<li>No method for rendering unknown description class: ' . $descriptionElement->class . '</li>';
710
      }
711
    }
712
    }
713
  }
714

    
715
  // If feature = NAME USAGE sort the list of sources.
716
  // This is ONLY for FLORA MALESIANA and FLORE d'AFRIQUE CENTRALE.
717
  if ($descriptionElement->feature->uuid == UUID_NAME_USAGE) {
718
    sort($outArray);
719
  }
720

    
721
  if (isset($image_sources)) {
722
    $outArray[] = theme('cdm_description_element_image_source', array('image_sources' => $image_sources, 'asListElement' => TRUE));
723
  }
724

    
725
  if (variable_get('distribution_sort', 'NO_SORT') != 'NO_SORT') {
726
    $outArray[] = theme('cdm_description_ordered_distributions', array('taxon_uuid' => $taxon_uuid, 'descriptionElements' => $distributionElements));
727
  }
728
  else {
729
    ksort($distributionElements);
730
    // TODO , $entryEnclosingTag);
731
    $outArray[] = theme('cdm_descriptionElementDistribution', array(
732
      'descriptionElements' => $distributionElements,
733
    ));
734
  }
735

    
736
  // Take the feature of the last $descriptionElement.
737
  $feature = $descriptionElement->feature;
738

    
739
  $out = theme('cdm_descriptionElementArray', array(
740
    'elementArray' => $outArray,
741
    'feature' => $feature,
742
    'glue' => $glue,
743
    'sortArray' => $sortOutArray,
744
    'enclosingHtml' => $enclosingTag,
745
  ));
746

    
747
  RenderHints::popFromRenderStack();
748
  return $out;
749
}
750

    
751
/**
752
 * @todo Please document this function.
753
 * @see http://drupal.org/node/1354
754
 */
755
function compare_image_sources($a, $b) {
756
  if ($a->multilanguageText_L10n->text == $b->multilanguageText_L10n->text) {
757
    return 0;
758
  }
759
  return ($a->multilanguageText_L10n->text < $b->multilanguageText_L10n->text) ? -1 : 1;
760
}
761

    
762
/**
763
 * @todo Please document this function.
764
 * @see http://drupal.org/node/1354
765
 */
766
function theme_cdm_description_element_image_source($variables) {
767
  $image_sources = $variables['image_sources'];
768
  $asListElement = $variables['asListElement'];
769
  $out = '';
770
  $separator = ',';
771
  RenderHints::pushToRenderStack('descriptionElementImageSource');
772
  RenderHints::setFootnoteListKey(UUID_IMAGE_SOURCES);
773

    
774
  // Sorting the image sources.
775
  usort($image_sources, "compare_image_sources");
776
  // Generate the footnotes.
777
  foreach ($image_sources as $image_source) {
778
    $footNoteKeys = cdm_annotations_as_footnotekeys($image_source);
779
    foreach ($image_source->sources as $source) {
780
      if (_is_original_source_type($source)) {
781
        $fn_key = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), theme('cdm_OriginalSource', array(
782
          'source' => $source,
783
          'doLink' => FALSE,
784
        )));
785
        // Ensure uniqueness of the footnote keys.
786
        cdm_add_footnote_to_array($footNoteKeys, $fn_key);
787
      }
788
    }
789
    // Sort and render footnote keys.
790
    $footnoteKeyListStr = '';
791
    asort($footNoteKeys);
792
    foreach ($footNoteKeys as $footNoteKey) {
793
      $footnoteKeyListStr .= theme('cdm_footnote_key', array('footnoteKey' => $footNoteKey, 'separator' => ($footnoteKeyListStr ? $separator : '')));
794
    }
795
    // Return value!
796
    $out .= '<span class="descriptionElement descriptionElement-' . $image_source->uuid . '">' . $image_source->multilanguageText_L10n->text . $footnoteKeyListStr . '; </span>';
797
  }
798

    
799
  RenderHints::popFromRenderStack();
800
  return $out;
801
}
802

    
803
/**
804
 * @todo Please document this function.
805
 * @see http://drupal.org/node/1354
806
 */
807
function theme_cdm_descriptionElementDistribution($variables) {
808
  $descriptionElements = $variables['descriptionElements'];
809
  $enclosingTag = $variables['enclosingTag'];
810
  if (!$enclosingTag) {
811
    $enclosingTag = "span";
812
  }
813

    
814
  $out = '';
815
  $separator = ',';
816
  RenderHints::pushToRenderStack('descriptionElementDistribution');
817
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
818

    
819
  foreach ($descriptionElements as $descriptionElement) {
820

    
821
    // Annotations as footnotes.
822
    $footNoteKeys = cdm_annotations_as_footnotekeys($descriptionElement);
823
    // Source references as footnotes.
824
    foreach ($descriptionElement->sources as $source) {
825
      if (_is_original_source_type($source)) {
826
        $fn_key = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), theme('cdm_OriginalSource', array(
827
          'source' => $source,
828
          'doLink' => FALSE,
829
        )));
830
        // Ensure uniqueness of the footnote keys.
831
        cdm_add_footnote_to_array($footNoteKeys, $fn_key);
832
      }
833
    }
834
    // Sort and render footnote keys.
835
    $footnoteKeyListStr = '';
836
    asort($footNoteKeys);
837
    foreach ($footNoteKeys as $footNoteKey) {
838
      $footnoteKeyListStr .= theme('cdm_footnote_key', array('footnoteKey' => $footNoteKey, 'separator' => ($footnoteKeyListStr ? $separator : '')));
839
    }
840

    
841
    $out .= '<' . $enclosingTag . ' class="descriptionElement descriptionElement-' . $descriptionElement->uuid . '">' . $descriptionElement->area->representation_L10n . $footnoteKeyListStr . ' </' . $enclosingTag . '>';
842
  }
843

    
844
  RenderHints::popFromRenderStack();
845
  return $out;
846
}
847

    
848
/**
849
 * Compare two different footnotes objects.
850
 *
851
 * The comparison is based on the footnote key. The one which is
852
 * displayed as footnote number.
853
 *
854
 * @param mixed $a
855
 *   Footnote object $a.
856
 * @param mixed $b
857
 *   Footnote object $b.
858
 */
859
function footnotes_key_compare($a, $b) {
860
  $res = 0;
861
  if (empty($a) || empty($b)) {
862
    return $res;
863
  }
864
  if ($a->keyStr < $b->keyStr) {
865
    $res = -1;
866
  }
867
  elseif ($a->keyStr > $b->keyStr) {
868
    $res = 1;
869
  }
870
  return $res;
871
}
872

    
873
/**
874
 * @todo Please document this function.
875
 * @see http://drupal.org/node/1354
876
 */
877
function theme_cdm_description_ordered_distributions($variables) {
878

    
879
  $taxon_uuid = $variables['taxon_uuid'];
880
  $descriptionElements = $variables['descriptionElements'];
881

    
882
  // Returning NULL if there are no description elements.
883
  if ($taxon_uuid == null || $descriptionElements == NULL) {
884
    return NULL;
885
  }
886

    
887
  // Initialization of some variables.
888
  $out = '';
889
  $separator = ',';
890
  RenderHints::pushToRenderStack('descriptionElementDistribution');
891
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
892

    
893
  // Getting all the taxon description for a given taxon.
894
  $markerTypesEmpty = array();
895
  // $markerTypesEmpty['markerTypes'] = 'af9860ff-08f5-4b4d-863c-49ae96985115';
896
  $markerTypesEmpty['markerTypes'] = '';
897
  $queryString = $markerTypesEmpty['markerTypes'] ? queryString($markerTypesEmpty) : '';
898

    
899
  $taxonDescriptions = cdm_ws_get(CDM_WS_PORTAL_TAXON_DESCRIPTIONS, $taxon_uuid, $queryString);
900
  foreach ($taxonDescriptions as $description) {
901
    $descriptions_uuids[] = $description->uuid;
902
  }
903

    
904
  // Getting the sortered distributions (omitting level ??).
905
  $request_params = array();
906
  $request_params['omitLevels'] = UUID_NAMEDAREALEVEL_TDWGLEVEL_2;
907
  $ordered_areas = cdm_ws_get(CDM_WS_PORTAL_DESCRIPTION_DISTRIBUTION_TREE, join(',', $descriptions_uuids), queryString($request_params));
908
  if (isset($ordered_areas->rootElement->children)) {
909
    $ordered_areas = $ordered_areas->rootElement->children;
910
  }
911

    
912
  // Printing the distributions.
913
  if (is_array($ordered_areas) && count($ordered_areas) > 0) {
914
    foreach ($ordered_areas as $element_level1) {
915
      // Level1.
916
      if ($element_level1->data) {
917
        $out .= '<dt>' . $element_level1->data->area->representation_L10n . ':</dt> ';
918
      }
919
      $out .= '<dd>';
920

    
921
      // Level3.
922
      foreach ($element_level1->children as $element_level3) {
923
        if ($element_level3->data) {
924
          $text_l3 = $element_level3->data->area->representation_L10n;
925
        }
926
        $fnKeysLevel3Str = '';
927
        $fnKeysLevel3 = cdm_annotations_as_footnotekeys($element_level3->data);
928
        foreach ($element_level3->data->sources as $source) {
929
          if (_is_original_source_type($source)) {
930
            $fn_key3 = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)));
931
            cdm_add_footnote_to_array($fnKeysLevel3, $fn_key3);
932
          }
933
        }
934
        // Level4.
935
        $l4_regions = array();
936
        foreach ($element_level3->children as $element_level4) {
937
          if ($element_level4->data) {
938
            $text_l4 = $element_level4->data->area->representation_L10n;
939
            $l4_regions[$element_level3->data->area->representation_L10n] = '';
940
            $fnKeysLevel4Str = '';
941
            $fnKeysLevel4 = cdm_annotations_as_footnotekeys($element_level4->data);
942
            foreach ($element_level4->data->sources as $source) {
943
              if (_is_original_source_type($source)) {
944
                $fn_key4 = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)));
945
                cdm_add_footnote_to_array($fnKeysLevel4, $fn_key4);
946
              }
947
            }
948
            usort($fnKeysLevel4, "footnotes_key_compare");
949
            $l4_regions[$text_l4] = $fnKeysLevel4;
950
          }
951
        }// Level4.
952
        // Managing level3 and level4 for generating the right output.
953
        usort($fnKeysLevel3, "footnotes_key_compare");
954
        foreach ($fnKeysLevel3 as $key3) {
955
          foreach ($l4_regions as $key4 => $value4) {
956
            cdm_add_footnote_to_array($l4_regions[$key4], $key3);
957
          }
958
        }
959
        if ($element_level3->numberOfChildren == 1 && $text_l3 == $element_level3->children[0]->data->area->representation_L10n) {
960
          // var_dump($element_level3->children[0]->data->area->representation_L10n);
961
          $fnStr = '';
962
          $region = array_pop($l4_regions);
963
          foreach ($region as $key) {
964
            $fnStr .= theme('cdm_footnote_key', array('footnoteKey' => $key, 'separator' => ($fnStr ? $separator : '')));
965
          }
966
          $out .= "$text_l3 $fnStr; ";
967
          // Removing whitespaces when &fnStr is empty.
968
          if (substr($out, -3) == ' ; ') {
969
            $out = substr($out, 0, -3) . '; ';
970
          }
971
        }
972
        else {
973
          $fnKeysLevel3Str = '';
974
          foreach ($fnKeysLevel3 as $key) {
975
            $fnKeysLevel3Str .= theme('cdm_footnote_key', array('footnoteKey' => $key, 'separator' => ($fnKeysLevel3Str ? $separator : '')));
976
          }
977
          $text_l4_aux = '';
978
          foreach ($l4_regions as $key => $value) {
979
            $fnKeysLevel4Str = '';
980
            if (is_array($l4_regions[$key])) {
981
              foreach ($l4_regions[$key] as $fnkey) {// Warning why?
982
                $fnKeysLevel4Str .= theme('cdm_footnote_key', array('footnoteKey' => $fnkey, 'separator' => ($fnKeysLevel4Str ? $separator : '')));
983
              }
984
            }
985
            // if ($key != $text_l3 || sizeof($l4_regions > 1)){
986
            if ($key != $text_l3) {
987
              $text_l4_aux .= "$key $fnKeysLevel4Str, ";
988
            }
989
          }
990
          $text_l4_aux = substr($text_l4_aux, 0, -2);
991

    
992
          if (strlen($text_l4_aux) > 0) {
993
            $out .= "$text_l3 $fnKeysLevel3Str ($text_l4_aux); ";
994
          }
995
          else {
996
            $out .= "$text_l3 $fnKeysLevel3Str; ";
997
          }
998
        }
999
      }// Level3.
1000
      $out = substr($out, 0, -2);
1001
      $out .= '.</dd>';
1002
    }// Level1.
1003
  }
1004
  RenderHints::popFromRenderStack();
1005
  return $out;
1006
}
1007

    
1008

    
1009
/*
1010
function theme_cdm_descriptionElementDistribution($descriptionElements){ $out
1011
  = ''; $separator = ',';
1012
  RenderHints::pushToRenderStack('descriptionElementDistribution');
1013
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
1014
  foreach($descriptionElements as $descriptionElement){ // annotations as
1015
  footnotes $annotationFootnoteKeys = theme('cdm_annotations_as_footnotekeys',
1016
  $descriptionElement); // source references as footnotes
1017
  $sourcesFootnoteKeyList = ''; foreach($descriptionElement->sources as
1018
  $source){ if(_is_original_source_type($source)){ $_fkey =
1019
  FootnoteManager::addNewFootnote(UUID_DISTRIBUTION,
1020
  theme('cdm_OriginalSource', $source, FALSE));
1021
  $sourcesFootnoteKeyList .= theme('cdm_footnote_key', $_fkey,
1022
  UUID_DISTRIBUTION, ($sourcesFootnoteKeyList ? $separator : '')); } }
1023
  if($annotationFootnoteKeys && $sourcesFootnoteKeyList){
1024
  $annotationFootnoteKeys .= $separator; } $out .=
1025
  $descriptionElement->area->representation_L10n . $annotationFootnoteKeys .
1026
  $sourcesFootnoteKeyList . ' '; } $out = substr($out, 0,
1027
  strlen($out)-strlen($separator) ); RenderHints::popFromRenderStack(); return
1028
  $out; }
1029
*/
1030

    
1031
/**
1032
 * Composes the render array for a distribution map of the given taxon.
1033
 *
1034
 * The distribution map can either be a plain image or a dynamic open layers map
1035
 * depending on the settings.
1036
 *
1037
 * compose_hook() implementation
1038
 *
1039
 * @param $taxon
1040
 *   The CDM Taxon instance to create the distribution map for.
1041
 * @return array
1042
 *    A drupal render array
1043
 *
1044
 * Similar compose function compose_map()
1045
 *
1046
 * @ingroup compose
1047
 */
1048
function compose_distribution_map($taxon) {
1049

    
1050
  $out = '';
1051
  $settings = get_edit_map_service_settings();
1052

    
1053
  $fontStyles = array(
1054
    0 => "plane",
1055
    1 => "italic",
1056
  );
1057

    
1058
  // Query cdm server for map service uri parameters.
1059
  $query_string = cdm_ws_get(CDM_WS_GEOSERVICE_DISTRIBUTIONMAP, $taxon->uuid);
1060
  $query_string = $query_string->String;
1061
  $out .= "<!-- map_data_parameters:" . print_r($query_string, TRUE) . " -->";
1062
  if (!$query_string) {
1063
    // The $query_string is empty if there are no distribution areas defined.
1064
    return;
1065
  }
1066

    
1067
  /* ------ choose the display mode, either openlayers or static image ------ */
1068

    
1069
  $map_settings = get_array_variable_merged(CDM_MAP_DISTRIBUTION, CDM_MAP_DISTRIBUTION_DEFAULT);
1070

    
1071
  if ($map_settings['map_type'] == 1) {
1072

    
1073
    /* =========== display distributions using the openlayers map viewer =========== */
1074

    
1075
    $legendFormatQueryStr = "format=image" . urlencode('/') . "png"
1076
         . "&TRANSPARENT=TRUE"
1077
         . "&WIDTH=" . $map_settings['legend']['icon_width']
1078
         . "&HEIGHT=" . $map_settings['legend']['icon_height']
1079
           // TODO why is the layer=topp:tdwg_level_4 parameter needed at all here??
1080
           // AK: i think the tdwg_level_4 is used as place holder and will be replaced later on
1081
           // => search for "tdwg_level_4" in the code
1082
         . "&layer=topp" . urlencode(':') . "tdwg_level_4"
1083
         . "&LEGEND_OPTIONS=forceLabels" . urlencode(':') . "on"
1084
             . ";fontStyle" . urlencode(':') . $fontStyles[$map_settings['legend']['font_style']]
1085
             . ";fontSize" . urlencode(':') .  $map_settings['legend']['font_size']
1086
         . "&SLD=";
1087

    
1088
    $out .= get_openlayers_map(
1089
        $map_settings['width'],
1090
        $map_settings['height'],
1091
        $map_settings['bbox'],
1092
        NULL,
1093
        $query_string,
1094
        $legendFormatQueryStr,
1095
        $map_settings['caption']
1096
     );
1097
  }
1098
  else {
1099
    $legendFormatQueryStr = '';
1100
    $out = get_image_map(
1101
        $map_settings['width'],
1102
        $map_settings['height'],
1103
        $map_settings['bbox'],
1104
        NULL,
1105
        $query_string,
1106
        $legendFormatQueryStr,
1107
        $map_settings['caption']
1108
    );
1109
  }
1110
  return markup_to_render_array($out);
1111
}
1112

    
1113
/**
1114
 * Returns a list of a specific type of IdentificationKeys.
1115
 *
1116
 * The list can be restricteded by a taxon.
1117
 *
1118
 * @param string $type
1119
 *   The simple name of the cdm class implementing the interface
1120
 *   IdentificationKey, valid values are:
1121
 *   PolytomousKey, MediaKey, MultiAccessKey.
1122
 * @param string $taxonUuid
1123
 *   If given this parameter restrict the listed keys to those which have
1124
 *   the taxon identified be this uuid in scope.
1125
 *
1126
 * @return array
1127
 *   List with identification keys.
1128
 */
1129
function _list_IdentificationKeys($type, $taxonUuid = NULL, $pageSize = NULL, $pageNumber = NULL) {
1130
  if (!$type) {
1131
    drupal_set_message(t('Type parameter is missing'), 'error');
1132
    return;
1133
  }
1134
  $cdm_ws_pasepath = NULL;
1135
  switch ($type) {
1136
    case "PolytomousKey":
1137
      $cdm_ws_pasepath = CDM_WS_POLYTOMOUSKEY;
1138
      break;
1139

    
1140
    case "MediaKey":
1141
      $cdm_ws_pasepath = CDM_WS_MEDIAKEY;
1142
      break;
1143

    
1144
    case "MultiAccessKey":
1145
      $cdm_ws_pasepath = CDM_WS_MULTIACCESSKEY;
1146
      break;
1147

    
1148
  }
1149

    
1150
  if (!$cdm_ws_pasepath) {
1151
    drupal_set_message(t('Type parameter is not valid: ') . $type, 'error');
1152
  }
1153

    
1154
  $queryParameters = '';
1155
  if (is_numeric($pageSize)) {
1156
    $queryParameters = "pageSize=" . $pageSize;
1157
  }
1158
  else {
1159
    $queryParameters = "pageSize=0";
1160
  }
1161

    
1162
  if (is_numeric($pageNumber)) {
1163
    $queryParameters = "pageNumber=" . $pageNumber;
1164
  }
1165
  else {
1166
    $queryParameters = "pageNumber=0";
1167
  }
1168
  $queryParameters = NULL;
1169
  if ($taxonUuid) {
1170
    $queryParameters = "findByTaxonomicScope=$taxonUuid";
1171
  }
1172
  $pager = cdm_ws_get($cdm_ws_pasepath, NULL, $queryParameters);
1173

    
1174
  if (!$pager || $pager->count == 0) {
1175
    return array();
1176
  }
1177
  return $pager->records;
1178
}
1179

    
1180
/**
1181
 * @todo Please document this function.
1182
 * @see http://drupal.org/node/1354
1183
 */
1184
function theme_cdm_IdentificationKey($variables) {
1185
  $out = '';
1186
  $identificationKey = $variables['identificationKey'];
1187
  $doLinkToKeyPage = $variables['doLinkToKeyPage'];
1188
  $showIdentificationKeyTitle = $variables['showIdentificationKeyTitle'];
1189
  $parentRenderPath = RenderHints::getRenderPath();
1190
  RenderHints::pushToRenderStack("IdentificationKey");
1191

    
1192
  if ($showIdentificationKeyTitle) {
1193
    if ($doLinkToKeyPage) {
1194
      $out = l($identificationKey->titleCache, path_to_key($identificationKey->class, $identificationKey->uuid));
1195
    }
1196
    else {
1197
      $out = $identificationKey->titleCache;
1198
    }
1199
  }
1200
  if (isset($identificationKey->sources) && is_array($identificationKey->sources)) {
1201
    // order and display sources.
1202
    $sources = oder_sources($identificationKey->sources, TRUE);
1203
    $out .= '<div class="sources">';
1204
    $out .=  implode('', $sources);
1205
    $out .= '</div>';
1206
  }
1207
  // Display annotations.
1208
  $out .= theme('cdm_annotations', array('annotations' => cdm_ws_getAnnotationsFor($identificationKey), 'enclosingTag' => 'div'));
1209
  RenderHints::popFromRenderStack();
1210
  return $out;
1211
}
1212

    
1213
/**
1214
 * @todo Please document this function.
1215
 * @see http://drupal.org/node/1354
1216
 */
1217
function theme_cdm_polytomousKey($variables) {
1218
  $polytomousKey = $variables['polytomousKey'];
1219

    
1220
  // TODO settings needed.
1221
  // @see http://en.wikipedia.org/wiki/Single_access_key#Presentation_styles
1222
  // @see http://dev.e-taxonomy.eu/trac/ticket/2152
1223
  $keyStyle = "linkedStyle";
1224

    
1225
  RenderHints::pushToRenderStack("polytomousKey");
1226
  // Key nodes in linked style.
1227
  $out = '<table class="polytomousKey polytomousKey_' . $keyStyle . '">';
1228
  $out .= theme('cdm_polytomousKey_' . $keyStyle . '_subgraph', array('polytomousKeyNode' => $polytomousKey->root));
1229
  $out .= '</table>';
1230
  RenderHints::popFromRenderStack();
1231
  return $out;
1232
}
1233

    
1234
/**
1235
 * @todo Please document this function.
1236
 * @see http://drupal.org/node/1354
1237
 */
1238
function theme_cdm_polytomousKey_linkedStyle_subgraph($variables) {
1239
  $polytomousKeyNode = $variables['polytomousKeyNode'];
1240
  static $statementCountCharacter = '\'';
1241
  $out = "";
1242

    
1243
  if (is_array($polytomousKeyNode->children)) {
1244
    $childIndex = 0;
1245

    
1246
    // Render edges of the current node.
1247
    foreach ($polytomousKeyNode->children as &$child) {
1248

    
1249
      if (!isset($child->statement) && isset($child->taxon->uuid)) {
1250
        // Skip node with empty statements (see below for explanation: "Special
1251
        // case").
1252
        // this skipping here happens always in the next deeper level of iteration
1253
        // the check below is node on the level above
1254
        continue;
1255
      }
1256

    
1257
      /*
1258
       * Special case: Child nodes with empty statements but taxa as leaf are to
1259
       * treated as if all those taxa where direct children of the source node.
1260
       */
1261
      $islinkToManyTaxa = !isset($child->children[0]->statement) && isset($child->children[0]->taxon->uuid);
1262
      $islinkToTaxon = isset($child->taxon->uuid);
1263
      $islinkToSubKey = isset($child->subkey->uuid);
1264
      $islinkToOtherNode = isset($child->otherNode);
1265
      // Either NULL or 0.
1266
      $islinkToNode = $child->nodeNumber && !$islinkToManyTaxa && !$islinkToOtherNode;
1267
      $hasQuestion = !empty($polytomousKeyNode->question->label_l10n);
1268
      $hasFeature = isset($polytomousKeyNode->feature);
1269

    
1270
      // $indentEdge = $hasQuestion && $childIndex > 0;
1271
      // Question.
1272
      if ($hasQuestion && $childIndex == 0) {
1273
        // Place question, as extra table row.
1274
        $out .= '<tr class="question new_section">';
1275
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber) . "</td>";
1276
        $out .= '<td class="question">' . $polytomousKeyNode->question->label_l10n . '</td>';
1277
        $out .= '</tr>';
1278
      }
1279

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

    
1282
      if ($hasQuestion) {
1283
        $out .= '<td class="nodeNumber"></td>';
1284
      }
1285
      else {
1286
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber . str_pad("", $childIndex, $statementCountCharacter)) . "</td>";
1287
      }
1288

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

    
1291
      // Feature.
1292
      if ($hasFeature) {
1293
        $out .= $polytomousKeyNode->feature->representation_L10n . ": ";
1294
      }
1295

    
1296
      // Statement.
1297
      $out .= $child->statement->label_l10n;
1298

    
1299
      // --- Links to nodes taxa and subkeys.
1300
      $out .= '<div class="nodeLink">';
1301

    
1302
      // Link to a PolytomousKeyNode.
1303
      if ($islinkToNode) {
1304
        $out .= '<div class="nodeLinkToNode">';
1305
        if (is_object($child->modifyingText)) {
1306
          $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $child->modifyingText));
1307
        }
1308
        $out .= l($child->nodeNumber, request_path(), array(
1309
          'attributes' => NULL,
1310
          'query' => NULL,
1311
          'fragment' => $child->uuid,
1312
        )) . '</div>';
1313
      }
1314

    
1315
      // Link to a PolytomousKeyNode.
1316
      if ($islinkToOtherNode) {
1317
        $out .= '<div class="nodeLinkToOtherNode">';
1318
        if (is_object($child->modifyingText)) {
1319
          $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $child->modifyingText));
1320
        }
1321
        $out .= l($child->otherNode->nodeNumber, $_REQUEST["q"], array(
1322
          'attributes' => NULL,
1323
          'query' => NULL,
1324
          'fragment' => $child->otherNode->uuid,
1325
        )) . '</div>';
1326
      }
1327

    
1328
      // Link to one or many taxa.
1329
      if ($islinkToTaxon || $islinkToManyTaxa) {
1330

    
1331
        if ($islinkToManyTaxa) {
1332
          $taxonChildren = $child->children;
1333
        }
1334
        else {
1335
          $taxonChildren = array(
1336
            $child,
1337
          );
1338
        }
1339

    
1340
        foreach ($taxonChildren as $taxonChild) {
1341
          // TODO many taxa $child->children->taxon.
1342
          $out .= '<div class="nodeLinkToTaxon">';
1343
          if (is_object($taxonChild->modifyingText)) {
1344
            $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $taxonChild->modifyingText));
1345
          }
1346
          $out .= theme("cdm_taxonName", array('taxonName' => $taxonChild->taxon->name, 'nameLink' => url(path_to_taxon($taxonChild->taxon->uuid))));
1347
          $out .= '</div>';
1348
        }
1349

    
1350
        // Link to a subkey.
1351
        if ($islinkToSubKey) {
1352
          $out .= '<div class="nodeLinkToSubkey">' . theme('cdm_IdentificationKey', array('identificationKey' => $child->subkey)) . '</div>';
1353
        }
1354
      }
1355

    
1356
      $out .= '</div>'; // End node link.
1357
      $out .= '</td>'; // End edge.
1358
      $out .= '</tr>';
1359

    
1360
      $childIndex++;
1361
    }
1362

    
1363
    // Recurse into child nodes.
1364
    foreach ($polytomousKeyNode->children as &$child) {
1365
      $out .= theme('cdm_polytomousKey_linkedStyle_subgraph', array('polytomousKeyNode' => $child));
1366
    }
1367
  }
1368

    
1369
  return $out;
1370
}
1371

    
1372
/**
1373
 * @todo Please document this function.
1374
 * @see http://drupal.org/node/1354
1375
 */
1376
function theme_cdm_poytomousKeyNode_modifyingText($variables) {
1377
  $out = '';
1378
  $modifyingText = $variables['modifyingText'];
1379
  if (is_object($modifyingText)) {
1380
    $i = 0;
1381
    foreach (get_object_vars($modifyingText) as $lang => $languageString) {
1382
      $out .= ($i++ > 0 ? ', ' : '') . '<span class="modifyingText">' . $languageString->text . '</span> ';
1383
    }
1384
  }
1385
  return $out;
1386
}
1387

    
1388
/**
1389
 * Returns HTML for a list of a specific type of IdentificationKeys.
1390
 *
1391
 * The list can be restricteded by a taxon.
1392
 *
1393
 * @param array $variables
1394
 *   An associative array containing:
1395
 *   - type: The simple name of the cdm class implementing the interface
1396
 *     IdentificationKey, valid values are:
1397
 *     PolytomousKey, MediaKey, MultiAccessKey
1398
 *   - taxonUuid: If given, this parameter restrict the listed keys to those
1399
 *     which have the taxon identified be this uuid in scope.
1400
 *
1401
 * @ingroup themeable
1402
 */
1403
function theme_cdm_list_IdentificationKeys($variables) {
1404
  $type = $variables['type'];
1405
  $taxonUuid = $variables['taxonUuid'];
1406
  $keyList = _list_IdentificationKeys($type, $taxonUuid);
1407
  if (!$keyList || count($keyList) == 0) {
1408
    return;
1409
  }
1410

    
1411
  RenderHints::pushToRenderStack('list_IdentificationKeys');
1412
  $out = '<ul>';
1413
  foreach ($keyList as $key) {
1414
    $out .= '<li>';
1415
    $out .= theme('cdm_IdentificationKey', array('identificationKey' => $key));
1416
    $out .= '</li>';
1417
  }
1418
  $out .= '</ul>';
1419
  $out .= theme("cdm_annotation_footnotes", array('footnoteListKey' => RenderHints::getRenderPath()));
1420
  RenderHints::popFromRenderStack();
1421

    
1422
  return $out;
1423
}
1424

    
1425
/**
1426
 * @todo Please document this function.
1427
 * @see http://drupal.org/node/1354
1428
 */
1429
function theme_cdm_block_IdentificationKeys($variables) {
1430
  $taxonUuid = $variables['taxonUuid'];
1431
  static $types = array(
1432
    "PolytomousKey" => "Polytomous",
1433
    "MediaKey" => "Media",
1434
    "MultiAccessKey" => "Multiaccess",
1435
  );
1436
  RenderHints::pushToRenderStack('block_IdentificationKeys');
1437
  $out = '';
1438
  foreach ($types as $type => $label) {
1439
    $keylist = theme('cdm_list_IdentificationKeys', array('type' => $type, 'taxonUuid' => $taxonUuid));
1440
    if (!$keylist) {
1441
      continue;
1442
    }
1443
    $out .= '<div class="' . $type . '">';
1444
    $out .= '<h3>' . t($label) . "</h3>";
1445
    $out .= $keylist;
1446
    $out .= '</div>';
1447
  }
1448
  RenderHints::popFromRenderStack();
1449
  return $out;
1450
}
1451

    
1452
/**
1453
 * This theming function formats the use description and use record list for
1454
 * these descriptions.
1455
 *
1456
 * @see http://drupal.org/node/1354
1457
 */
1458
function theme_cdm_UseDescription($variables) {
1459
  $descriptions = $variables['description'];
1460
  $taxonUuid = $variables['taxonUuid'];
1461
  $out = '<div id="content"><ul id="Description" class ="description">';
1462
  if ($descriptions == NULL) {
1463
    return;
1464
  }
1465
  $descriptionSynonyms = '';
1466
  $descriptionOut = '';
1467
  $synonymOut = '';
1468
  $currentTaxon = cdm_ws_get(CDM_WS_PORTAL_TAXON, $taxonUuid);
1469

    
1470
  foreach ($descriptions as $description) {
1471
    $useSummary = '';
1472
    foreach ($description->elements as $element) {
1473

    
1474
      if ($element->feature->uuid == UUID_USE && !(strlen($useSummary) > 0)) {
1475
        $useSummary = $element->multilanguageText_L10n->text;
1476
      }
1477
    }
1478
    // uses will be ordered by source
1479
    foreach ($description->sources as $source) {
1480
      $is_about_current_taxon = FALSE;
1481
      $originalTaxonUsedInSource = NULL;
1482
      $originalTaxonPager = NULL;
1483
      if ($source->originalNameString) {
1484
        $request_params = array();
1485
        $request_params['query'] = $source->originalNameString;
1486
        $request_params['matchMode'] = "EXACT";
1487
        $originalTaxonPager = cdm_ws_get(CDM_WS_PORTAL_NAME_FINDBYNAME, NULL, queryString($request_params));
1488
        if ($originalTaxonPager->count > 0) {
1489
          $originalTaxonUsedInSource = $originalTaxonPager->records[0];
1490
        }
1491
        else {
1492
          $originalTaxonUsedInSource = $currentTaxon->name;
1493
        }
1494
      }
1495
      else {
1496
        $originalTaxonUsedInSource = $currentTaxon->name;
1497
      }
1498

    
1499
      $is_about_current_taxon = $currentTaxon->name->uuid == $originalTaxonUsedInSource->uuid;
1500

    
1501
      if (!$is_about_current_taxon) {
1502
        $descriptionOut .= '<li class="descriptionText DescriptionElement">';
1503
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1504
          'absolute' => TRUE,
1505
          'html' => TRUE,
1506
        ));
1507
        $descriptionOut .= $name_used_in_source_link_to_show_use . ': ';
1508
        $descriptionOut .= $useSummary;
1509
        foreach ($description->sources as $source) {
1510
          $descriptionOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1511
        }
1512
        $hasUseRecords = FALSE;
1513
        $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>';
1514
        foreach ($description->elements as $descriptionElement) {
1515
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1516
            $hasUseRecords = TRUE;
1517
            // FIXME localization hardcoded to English
1518
            $useRecordTags = explode(';', $descriptionElement->modifyingText->English->text);
1519
            $descriptionUseRecordOut .= '<tr>';
1520
            $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>';
1521
            $descriptionUseRecordOut .= '</tr>';
1522
          }
1523
        }
1524
        $descriptionUseRecordOut .= '</table></div>';
1525
        if ($hasUseRecords) {
1526
          $descriptionOut .= $descriptionUseRecordOut . '</li>';
1527
        }
1528
      }
1529
      else {
1530
        // TODO +/- duplicate of above, unify this code
1531
        $synonymOut .= '<li class="descriptionText DescriptionElement">';
1532
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1533
          'absolute' => TRUE,
1534
          'html' => TRUE,
1535
        ));
1536

    
1537
        $synonymOut .= $name_used_in_source_link_to_show_use . ': ';
1538
        $synonymOut .= $useSummary;
1539
        foreach ($description->sources as $source) {
1540
          $synonymOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1541
        }
1542

    
1543
        $hasUseRecords = FALSE;
1544
        $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>';
1545
        foreach ($description->elements as $descriptionElement) {
1546
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1547
            $hasUseRecords = TRUE;
1548
            $useRecordTags = explode(';', $descriptionElement->modifyingText->English->text);
1549
            $useRecordTableOut .= '<tr>';
1550
            $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>';
1551
            $useRecordTableOut .= '</tr>';
1552
          }
1553
        }
1554
        $useRecordTableOut .= '</table></div>';
1555
        if ($hasUseRecords) {
1556
          $synonymOut .= $useRecordTableOut . '</li>';
1557
        }
1558
      }
1559

    
1560
      // }
1561
    }
1562
  }
1563
  $out .= $descriptionOut . $synonymOut;
1564
  $out .= "</ul></div>";
1565
  return $out;
1566
}
1567

    
1568
// The Uses theming function here will handle the display of the
1569
// Uses Descriptions.
1570
// Comment @WA: $pageSize is not used.
1571
// function theme_cdm_block_Uses ($taxonUuid = NULL, $pageSize = NULL {
1572
/**
1573
 * @todo Please document this function.
1574
 * @see http://drupal.org/node/1354
1575
 */
1576
function theme_cdm_block_Uses($variables) {
1577
  $taxonUuid = $variables['taxonUuid'];
1578
  RenderHints::pushToRenderStack('block_Uses');
1579

    
1580
  if ($taxonUuid == NULL) {
1581
    return;
1582
  }
1583
  $out = '';
1584
  $markerTypes = array();
1585
  $markerTypes['markerTypes'] = UUID_MARKERTYPE_USE;
1586
  $useDescriptions = cdm_ws_get(CDM_WS_PORTAL_TAXON_DESCRIPTIONS, $taxonUuid, queryString($markerTypes));
1587
  if (!empty($useDescriptions)) {
1588
    // FIXME use theme_block instaed of hardcoding the block html here !!!!
1589
    $out .= '<div id="block-cdm_dataportal-feature-description" class="clear-block block block-cdm_dataportal-feature"><H2><a name="userecords"> </a> Uses </H2>';
1590
    $formatUseDescriptions = theme('cdm_UseDescription', array('description' => $useDescriptions, 'taxonUuid' => $taxonUuid));
1591

    
1592
    $out .= $formatUseDescriptions;
1593
    $out .= "</div>";
1594
  }
1595

    
1596
  return $out;
1597
}
(3-3/10)