Project

General

Profile

Download (57.5 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
 * @param unknown $feature_nodes
19
 * @return multitype:multitype:Ambigous <An, string>
20
 */
21
function cdm_feature_node_toc_items($feature_nodes) {
22
  $items = array();
23

    
24
  // FIXME !!!!!!!!!!!!!!!!
25
  // implement api hook to allow adding additional toc items for other modules,
26
  // implement palmweb module to preserve funcion of palmweb_2_cdm_feature_nodesTOC()
27
  //
28

    
29
  // we better cache here since drupal_get_query_parameters has no internal static cache variable
30
  $http_request_params = drupal_get_query_parameters();
31

    
32
  foreach ($feature_nodes as $node) {
33

    
34
    if (hasFeatureNodeDescriptionElements($node)) {
35

    
36
      $featureRepresentation = isset($node->feature->representation_L10n) ? $node->feature->representation_L10n : 'Feature';
37
      //TODO HACK to implement images for taxa, should be removed.
38
      if ($node->feature->uuid != UUID_IMAGE) {
39
        $items[] = array(
40
          l(
41
              theme('cdm_feature_name', array('feature_name' => $featureRepresentation)),
42
              $_GET['q'],
43
              array(
44
                  'attributes' => array('class' => array('toc')),
45
                  'fragment' => generalizeString($featureRepresentation),
46
                  'query' => $http_request_params
47
              )
48
           )
49
        );
50
      }
51
    }
52
  }
53

    
54
  return $items;
55
}
56

    
57
/**
58
 * Theme function to alter the feature representation.
59
 *
60
 * It is highly qeutionalbe if this function should be completely removed.
61
 * If a feature needs a different representation this should be edited directly
62
 * in the cdm data but it shoud not be tweeked like this in the portal.
63
 *
64
 * Used in:
65
 *  - theme_cdm_feature_nodesTOC()
66
 *  - theme_cdm_feature_nodes()
67
 *  - theme_cdm_media_mime_application()
68
 *  - theme_cdm_media_mime_text()
69
 *
70
 * TODO delete this function? (a.kohlbecker feb 2013)
71
 *
72
 */
73
function theme_cdm_feature_name($variables) {
74
  $feature_name = $variables['feature_name'];
75
  // TODO replace by using translations ?
76
  return t($feature_name);
77
}
78

    
79
/**
80
 * Returns HTML for a taxon profile from the $mergedFeatureNodes of a given $taxon.
81
 *
82
 * The taxon profile consists of description elements which are ordered by the
83
 * structure defined by specific FeatureTree. The chosen FeatureTree is merged
84
 * with the list of desctiprion elements prior to using this method.
85
 *
86
 * The merged nodes can be obtained by making use of the
87
 * function cdm_ws_descriptions_by_featuretree().
88
 *
89
 * @see cdm_ws_descriptions_by_featuretree()
90
 *
91
 * @param array $variables
92
 *   An associative array containing:
93
 *   - mergedFeatureNodes
94
 *   -taxon
95
 *
96
 * @ingroup themeable
97
 */
98
function theme_cdm_feature_nodes($variables) {
99

    
100
  $mergedFeatureNodes = $variables['mergedFeatureNodes'];
101
  $taxon = $variables['taxon'];
102
  $out = '';
103

    
104
  RenderHints::pushToRenderStack('feature_nodes');
105

    
106
  $gallery_settings = getGallerySettings(CDM_DATAPORTAL_DESCRIPTION_GALLERY_NAME);
107

    
108
  // Creating an array to place the description elements in.
109
  foreach ($mergedFeatureNodes as $node) {
110

    
111
    if (hasFeatureNodeDescriptionElements($node)) {
112

    
113
      $featureRepresentation = isset($node->feature->representation_L10n) ? $node->feature->representation_L10n : 'Feature';
114
      $block = new stdclass(); // Empty object.
115
      $block->module = 'cdm_dataportal';
116
      $media_list = array();
117

    
118
      if (true || $node->feature->uuid != UUID_IMAGE) {
119

    
120
        $block->delta = generalizeString($featureRepresentation);
121
        $block->subject = '<span class="' . html_class_atttibute_ref($node->feature) . '">' . theme('cdm_feature_name', array('feature_name' => $featureRepresentation)) . '</span>';
122
        $block->module = "cdm_dataportal-feature";
123
        $block->content = '';
124

    
125
        /*
126
         * Content/DISTRIBUTION.
127
         */
128
        if ($node->feature->uuid == UUID_DISTRIBUTION) {
129

    
130
          $node->descriptionElements = cdm_description_elements_prefer_computed($node->descriptionElements);
131

    
132
          if (variable_get(DISTRIBUTION_TEXTDATA_DISPLAY_ON_TOP, 0)) {
133
            $distributionTextDataList = array();
134
            $distributionElementsList = array();
135

    
136
            foreach ($node->descriptionElements as $descriptionElement) {
137
              if ($descriptionElement->class == "TextData") {
138
                $distributionTextDataList[] = $descriptionElement;
139
              }
140
              else {
141
                $distributionElementsList[] = $descriptionElement;
142
              }
143
            }
144

    
145

    
146
            if (count($distributionTextDataList) > 0) {
147
              $node->descriptionElements = $distributionElementsList;
148
              $block->content .= theme('cdm_descriptionElements', array(
149
                'descriptionElements' => $distributionTextDataList,
150
                'featureUuid' => $node->feature->uuid,
151
                'taxon_uuid' => $taxon->uuid,
152
              ));
153
            }
154
          }
155

    
156
          // Display cdm distribution map TODO this is a HACK to a proper
157
          // generic implementation?
158
          $map_render_element = compose_distribution_map($taxon);
159
          $block->content .= $map_render_element['#markup'];
160
          $block->content .= theme('cdm_descriptionElements', array(
161
            'descriptionElements' => $node->descriptionElements,
162
            'featureUuid' => $node->feature->uuid,
163
            'taxon_uuid' => $taxon->uuid,
164
          ));
165

    
166
        }
167

    
168
        /*
169
         * Content/COMMON_NAME.
170
         */
171
        elseif ($node->feature->uuid == UUID_COMMON_NAME) {
172
          // TODO why is theme_cdm_descriptionElement_CommonTaxonName not
173
          // beeing used???
174
         $block->content .= theme('cdm_common_names', array('elements' => $node->descriptionElements));
175
          /*
176
          }else if($node->feature->uuid == UUID_IMAGE_SOURCES) {
177
          $block->content .= theme('cdm_image_sources',
178
          $node->descriptionElements);
179
          */
180
        }
181

    
182
        /*
183
         * Content/ALL OTHER FEATURES.
184
         */
185
        else {
186
          if (isset($node->descriptionElements)) {
187
            $taxon_uuid = NULL;
188
            if(isset($taxon) ) {
189
              $taxon_uuid = $taxon->uuid;
190
            }
191
            $block->content .= theme('cdm_descriptionElements', array(
192
              'descriptionElements' => $node->descriptionElements,
193
              'featureUuid' => $node->feature->uuid,
194
              'taxon_uuid' => $taxon_uuid,
195
            ));
196
          }
197

    
198
//           Content/ALL OTHER FEATURES/Subordinate Features
199
//           subordinate features are printed inline in one floating text,
200
//           it is expected hat supordinate features can "contain" TextData,
201
//           Qualitative- and Qualitative- DescriptioneElements
202
          if (isset($node->children[0])) {
203

    
204
            // TODO support more than one level of children.
205
            // can this be solved by resursively calling this very function?
206
            // @see http://dev.e-taxonomy.eu/trac/ticket/2393
207
            $text = '';
208
            foreach ($node->children as $child) {
209

    
210
              if (isset($child->descriptionElements) && is_array($child->descriptionElements)) {
211
                foreach ($child->descriptionElements as $element) {
212

    
213
                  if (is_array($element->media)) {
214
                    // Append media of supordinate elements to list of main
215
                    // feature.
216
                    $media_list = array_merge($media_list, $element->media);
217
                  }
218

    
219
                  switch ($element->class) {
220
                    case 'TextData':
221
                      // TODO use theme_cdm_descriptionElementTextData()
222
                      $out_child_elements = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
223
                      $out_child_elements = str_replace($child->feature->titleCache, '<em>' . $child->feature->representation_L10n . '</em>', $out_child_elements);
224
                      break;
225
                    case 'CategoricalData':
226
                      $out_child_elements  = '<em>' . $child->feature->representation_L10n . '</em> '
227
                        . theme('cdm_descriptionElement_CategoricalData', array('element' => $element));
228
                      break;
229
                    case 'QuantitativeData':
230
                      $out_child_elements = '<em>' . $child->feature->representation_L10n . '</em> '
231
                        . theme('cdm_descriptionElement_QuantitativeData', array('element' => $element));
232

    
233
                  }
234

    
235
                }
236
                $text .= " " . $out_child_elements;
237
                $out_child_elements = '';
238
              }
239
            }
240
            $block->content .= $text;
241
          }
242
        }
243

    
244
        /*
245
         * Media/ALL FEATURES.
246
         */
247
        if (isset($node->descriptionElements)) {
248
          $media_list = array_merge($media_list, cdm_dataportal_media_from_descriptionElements($node->descriptionElements));
249
        }
250
        $captionElements = array('title', 'rights');
251
        $gallery = '';
252
        if (isset($gallery_settings['cdm_dataportal_media_maxextend']) && isset($gallery_settings['cdm_dataportal_media_cols'])) {
253
          $gallery = theme('cdm_media_gallerie', array(
254
            'mediaList' => $media_list,
255
            'galleryName' => CDM_DATAPORTAL_DESCRIPTION_GALLERY_NAME . '_' . $node->feature->uuid,
256
            'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
257
            'cols' => $gallery_settings['cdm_dataportal_media_cols'],
258
            'captionElements' => $captionElements,
259
          ));
260
        }
261
        $block->content .= $gallery;
262
        $block->content .= theme('cdm_footnotes', array('footnoteListKey' => $node->feature->uuid));
263
        $block->content .= theme('cdm_annotation_footnotes', array('footnoteListKey' => $node->feature->uuid));
264

    
265
        // Add anchor to subject.
266
        $block->subject = '<a name="' . $block->delta . '"></a>' . $block->subject;
267

    
268
        // In D6: $out .= theme('block', $block);
269
        // Comment @WA @TODO check if need to set a region, and which one.
270
        $block->region = FALSE;
271
        $out .= theme('block', array('elements' => array(
272
          '#block' => $block,
273
          '#children' => $block->content,
274
        )));
275
      }
276
    }
277
  }
278
  RenderHints::popFromRenderStack();
279
  return $out;
280
}
281

    
282
/**
283
 * @todo Please document this function.
284
 * @see http://drupal.org/node/1354
285
 */
286
function theme_FeatureTree_hierarchy($variables) {
287

    
288
  $FeatureTreeUuid = $variables['FeatureTreeUuid'];
289
  if (!is_uuid($FeatureTreeUuid)) {
290
    return;
291
  }
292

    
293
  $out = '';
294
  $featureTree = cdm_ws_get(CDM_WS_FEATURETREE, array(
295
    $FeatureTreeUuid,
296
  ));
297

    
298
  if (isset($featureTree) && isset($featureTree->root)) {
299
    $out = '<ul class="' . $featureTree->class . '">';
300
    $out .= theme('FeatureTree_hierarchy_children', array('node' => $featureTree->root));
301
    $out .= '</ul>';
302
  }
303
  return $out;
304
}
305

    
306
/**
307
 * @todo Please document this function.
308
 * @see http://drupal.org/node/1354
309
 */
310
function theme_FeatureTree_hierarchy_children($variables) {
311

    
312
  $node = $variables['node'];
313
  $out = '';
314
  if (isset($node->children)) {
315

    
316
    foreach ($node->children as $childNode) {
317
      $out .= '<li>' . check_plain($childNode->feature->representation_L10n);
318
      if (isset($childNode->children) && count($childNode->children) > 0) {
319
        $out .= '<ul>' . theme('FeatureTree_hierarchy_children', array('node' => $childNode)) . '</ul>';
320
      }
321
      $out .= '</li>';
322
    }
323
  }
324
  return $out;
325
}
326

    
327
/**
328
 * Returns HTML for the texts in a description $elementArray.
329
 *
330
 * Joins the texts in $elementArray and encloses with a HTML tag.
331
 *
332
 * @param array $variables
333
 *   An associative array containing:
334
 *   - elementArray
335
 *   - feature: The feature to which the elements given in $elementArray are
336
 *     belonging to.
337
 *   - glue: Defaults to empty string.
338
 *   - sortArray: Whether to sort the $elementArray alphabetically.
339
 *   - enclosingHtml
340
 *
341
 * @ingroup themeable
342
 */
343
function theme_cdm_descriptionElementArray($variables) {
344
  $elementArray = $variables['elementArray'];
345

    
346
  $feature = $variables['feature'];
347
  $glue = $variables['glue'];
348
  $sortArray = $variables['sortArray'];
349
  $enclosingHtml = $variables['enclosingHtml'];
350
  $out = '<' . $enclosingHtml . ' class="description" id="' . $feature->representation_L10n . '">';
351

    
352
  if ($sortArray) {
353
    sort($elementArray);
354
  }
355

    
356
  $out .= join($elementArray, $glue);
357

    
358
  $out .= '</' . $enclosingHtml . '>';
359
  return $out;
360
}
361

    
362
/**
363
 * @todo Please document this function.
364
 * @see http://drupal.org/node/1354
365
 */
366
function theme_cdm_descriptionElement_CommonTaxonName($variables) {
367
  $element = $variables['element'];
368
  $out = '<span class="' . html_class_atttibute_ref($element) . '">' . $element->language->representation_L10n . ' (' . $element->area->titleCache . '): ' . $element->name . '</span>';
369
  return $out;
370
}
371

    
372
/**
373
* @todo Please document this function.
374
* @see http://drupal.org/node/1354
375
*/
376
function theme_cdm_descriptionElement_CategoricalData($variables) {
377
  $element = $variables['element'];
378

    
379
  $state_data_strings = array();
380
  if (isset($element->states)) {
381
    foreach ($element->states as $stateData) {
382

    
383
      $state  = NULL;
384

    
385
      if(isset($stateData->state)){
386
        $state = cdm_term_representation($stateData->state);
387
      }
388

    
389
      if (isset($stateData->modifyingText_L10n)) {
390
        $state = ' ' . $stateData->modifyingText_L10n;
391
      }
392

    
393
      $modifiers_strings = cdm_modifers_representations($stateData);
394

    
395
      $state_data_strings[] = $state . ($modifiers_strings ? ' ' . $modifiers_strings : '');
396

    
397
      // FIXME render sources
398

    
399
    }
400
  }
401
  $out = '<span class="' . html_class_atttibute_ref($element) . '">' . implode(', ', $state_data_strings) . '</span>';
402
  return $out;
403
}
404

    
405
function theme_cdm_descriptionElement_QuantitativeData($variables) {
406
  /*
407
   * - statisticalValues
408
   *   - value
409
   *   - modifiers
410
   *   - type
411
   * - unit->representation_L10n
412
   * - modifyingText
413
   * - modifiers
414
   * - sources
415
   */
416
  $element = $variables['element'];
417

    
418
  $out = '';
419

    
420
  $type_representation = NULL;
421
  $modifiers_strings = array();
422

    
423

    
424
  if (isset($element->statisticalValues)) {
425
    $value_array = array();
426
    foreach ($element->statisticalValues as $val) {
427
      if (isset($val->value)) {
428
        $value_array[] = $val->value;
429
      }
430
    }
431

    
432
    $out .= implode($value_array, ', ');
433
  }
434

    
435
  if (isset($element->unit)) {
436
    $out .= ' '. cdm_term_representation($element->unit);
437
  }
438

    
439
  if (isset($element->statisticalValues->modifyingText_L10n)) {
440
    $out .=  ' ' . $element->statisticalValues->modifyingText_L10n;
441
  }
442
  $modifers_string = cdm_modifers_representations($element->statisticalValues);
443
  $out .= ($modifers_string ? ' ' . cdm_modifers_representations($element->statisticalValues) : '');
444

    
445
  // FIXME render sources
446

    
447
  return $out;
448

    
449
}
450

    
451
/**
452
 * Returns HTML for citations textdata elements.
453
 *
454
 * TODO: assign a new name to the function? Because it is used for the citations
455
 * textdata elements and not for all text data description elements.
456
 *
457
 * @param array $variables
458
 *   An associative array containing:
459
 *   - element: The description element which contains the text information.
460
 *   - asListElement: A boolean which determines whether the citations should
461
 *     be rendered as a list or not.
462
 *   - feature_uuid
463
 *
464
 * @ingroup themeable
465
 */
466
function theme_cdm_descriptionElementTextData($variables) {
467

    
468
  $element = $variables['element'];
469
  $asListElement = $variables['asListElement'];
470
  $feature_uuid = $variables['feature_uuid'];
471

    
472
  $description = '';
473
  if (isset($element->multilanguageText_L10n->text)) {
474
    $description = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
475
  }
476
  $sourceRefs = '';
477
  $result = array();
478
  $out = '';
479
  $res_author = '';
480
  $res_date = '';
481
  if (isset($element->sources) && is_array($element->sources) && count($element->sources) > 0) {
482
    foreach ($element->sources as $source) {
483
      $referenceCitation = theme('cdm_OriginalSource', array('source' => $source));
484
      if ($description && strlen($description) > 0 && $referenceCitation) {
485
        $sourceRefs .= ' (' . $referenceCitation . ')';
486
      }
487
      elseif ($referenceCitation) {
488
        $sourceRefs = $referenceCitation;
489
      }
490

    
491
      if (strlen($sourceRefs) > 0) {
492
        $sourceRefs = '<span class="sources">' . $sourceRefs . '</span>';
493
      }
494
      $name_used_in_source_link_to_show = '';
495
      // Do a link to name page.
496
      if (isset($source->nameUsedInSource->uuid) && isset($source->nameUsedInSource->titleCache)) {
497
        $name_used_in_source_link_to_show = l($source->nameUsedInSource->titleCache, path_to_name($source->nameUsedInSource->uuid), array(
498
          'attributes' => array(),
499
          'absolute' => TRUE,
500
          'html' => TRUE,
501
        ));
502
      }
503
      // Show a text without link.
504
      elseif (isset($source->nameUsedInSource->originalNameString) && strlen($source->nameUsedInSource->originalNameString) > 0) {
505
        $name_used_in_source_link_to_show = $source->nameUsedInSource->originalNameString;
506
      }
507

    
508
      if ($asListElement) {
509

    
510
       $out = '<li class="descriptionText DescriptionElement">';
511
        // Adding ":" if necessary.
512
        if (!empty($name_used_in_source_link_to_show)) {
513
          if ( (!empty($description)|| !empty($sourceRefs)) && $feature_uuid != UUID_CHROMOSOMES_NUMBERS) {
514
            $out .= $name_used_in_source_link_to_show . ': ';
515
          } else {
516
            $out .= $name_used_in_source_link_to_show . ' ';
517
          }
518
        }
519
        $out .= $description . $sourceRefs . theme('cdm_annotations_as_footnotekeys', array('cdmBase_list' => $element, 'footnote_list_key' => $feature_uuid)) . '</li>';
520
      }
521
      else {
522
        if ($name_used_in_source_link_to_show) {
523
          $name_used_in_source_link_to_show = ' (name in source: ' . $name_used_in_source_link_to_show . ')';
524
        }
525

    
526
        $out = '<span class="DescriptionElement DescriptionElement-' . $element->class . '">' . $description . $sourceRefs . $name_used_in_source_link_to_show . '</span>';
527
      }
528
    }
529
  }
530
  else {
531
    // If no sources, print the description.
532
    $out = $description;
533
  }
534
  return $out;
535
}
536

    
537
/**
538
 * @todo Please document this function.
539
 * @see http://drupal.org/node/1354
540
 */
541
function theme_cdm_common_names($variables) {
542
  $elements = $variables['elements'];
543
  $text_data_out = '';
544
  $common_name_out = '';
545
  $separator = ',';
546
  $textData_commonNames = array();
547

    
548
  if (is_array($elements)) {
549
    foreach ($elements as $element) {
550
      if ($element->class == 'CommonTaxonName') {
551

    
552
        // common name without a language or area, should not happen but is possible
553
        $language_area_key = '';
554
        if (isset($element->language->representation_L10n)) {
555
          $language_area_key .= '<b>' . $element->language->representation_L10n . '</b>';
556
        }
557
        if(isset($element->area->titleCache) && strlen($element->area->titleCache) > 0){
558
          $language_area_key .= ($language_area_key ? ' '  : '') . '(' . $element->area->titleCache . ')';
559
        }
560

    
561
        if(isset($common_names[$language_area_key][$element->name])) {
562
          // same name already exists for language and areae combination, se we merge the description elements
563
          cdm_merge_description_elements($common_names[$language_area_key][$element->name], $element);
564
        } else{
565
          // otherwise add as new entry
566
          $common_names[$language_area_key][$element->name] = $element;
567
        }
568

    
569
      }
570
      elseif ($element->class == 'TextData') {
571
        $textData_commonNames[] = $element;
572
      }
573
    }
574
  }
575
  // Handling common names.
576
  if (isset($common_names) && count($common_names) > 0) {
577
    // Sorting the array based on the key (language, + area if set).
578
    // Comment @WA there are common names without a language, so this sorting
579
    // can give strange results.
580
    ksort($common_names);
581

    
582
    // Creating the output to be render by Drupal.
583
    foreach ($common_names as $key => $elements) {
584
      ksort($elements); // sort names alphabetically
585
      $rendered_element_list = '';
586
      foreach ($elements as $element) {
587
        $sourcesFootnoteKeyList = '';
588
        // Adding footnotes sources.
589
        foreach ($element->sources as $source) {
590
          if (_is_original_source_type($source)) {
591
            $_fkey = FootnoteManager::addNewFootnote(UUID_COMMON_NAME, theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)));
592
            $sourcesFootnoteKeyList .= theme('cdm_footnote_key', array('footnoteKey' => $_fkey, 'separator' => ($sourcesFootnoteKeyList ? $separator : '')));
593
          }
594
        }
595
        if ($element->name) {
596
          $rendered_element_list .= '<span class="' . html_class_atttibute_ref($element) . '">' . (strlen($rendered_element_list) > 0 ? ', ' : '') . $element->name . $sourcesFootnoteKeyList . '</span>';
597
        }
598
      }
599
      if ($key) {
600
        $common_name_out .= (strlen($common_name_out) > 0 ? '; ' : '') . $key . ': ' . $rendered_element_list;
601
      }
602
      else {
603
        $common_name_out .= (strlen($common_name_out) > 0 ? '; ' : '') . $rendered_element_list;
604
      }
605
    }
606
  }
607
  // Handling commons names as text data.
608
  foreach ($textData_commonNames as $text_data_element) {
609
    $text_data_out .= theme('cdm_descriptionElementTextData', array(
610
      'element' => $text_data_element,
611
      'asListElement' => TRUE,
612
      'feature_uuid' => $text_data_element->feature->uuid,
613
    ));
614
  }
615

    
616
  $common_name_out = "<div class=common_names_as_common_names> $common_name_out </div>";
617
  $out_array[] = $text_data_out;
618
  $common_name_out_text_data = '<div class=common_names_as_text_data>' . theme('cdm_descriptionElementArray', array('elementArray' => $out_array, 'feature' => $element->feature)) . '</div>';
619

    
620
  return $common_name_out . $common_name_out_text_data;
621
  /*
622
  return $common_name_out . theme('cdm_descriptionElementArray', $out_array,
623
  $element->feature);
624
  return "<div class=common_names> $common_name_out
625
  $common_name_out_text_data";
626
  */
627
}
628

    
629
/**
630
 * Return HTML for a list of description elements.
631
 *
632
 * Usually these are of a specific feature type.
633
 *
634
 * @param array $variables
635
 *   An associative array containing:
636
 *   - array of descriptionElements which belong to the same feature.
637
 *     These descriptions elements of a Description must be ordered by the chosen feature tree by
638
 *     calling the function _mergeFeatureTreeDescriptions().
639
 *     @see _mergeFeatureTreeDescriptions()
640
 *   - featureUuid: currently unused, accoding code disabled
641
 *   - taxon_uuid: only used for ordered dditributions (will be removed!)
642
 *
643
 * @ingroup themeable
644
 */
645
function theme_cdm_descriptionElements($variables) {
646

    
647
  $descriptionElements = $variables['descriptionElements'];
648
  $featureUuid = $variables['featureUuid'];
649
  $taxon_uuid = $variables['taxon_uuid'];
650
  $outArray = array();
651

    
652
  /*
653
  $userDefined = mixed_variable_get(LAYOUT_SETTING_PREFIX . $featureUuid, FEATURE_TREE_LAYOUT_DEFAULTS);
654
  if(variable_get('distribution_sort',
655
      'NO_SORT') != 'NO_SORT'){
656
      $glue = '';
657
      $enclosingTag = 'dl';
658
      $entryEnclosingTag = NULL;
659
  } else if($userDefined &&
660
      $userDefined['enabled']){
661
    $glue = $userDefined['glue'];
662
    $enclosingTag =  $userDefined['enclosingTag'];
663
    $entryEnclosingTag = $userDefined['entryEnclosingTag'];
664
  } else { // TODO remove once  LAYOUT_SETTING_PREFIX-{uuid} setting are configured to work for all portals(selenium test still missing!!!)
665
    $glue = ''; $enclosingTag = 'ul';
666
    $entryEnclosingTag = NULL ;
667
  }
668
  */
669

    
670

    
671
  if (variable_get('distribution_sort', 'NO_SORT') != 'NO_SORT') {
672
    $glue = '';
673
    $enclosingTag = 'dl';
674
  }
675
  else {
676
    $glue = '';
677
    $enclosingTag = 'ul';
678
  }
679

    
680
  $sortOutArray = FALSE;
681
  $distributionElements = array();
682

    
683
  RenderHints::pushToRenderStack('cdm_descriptionElements');
684

    
685
  // Avoiding warning box in drupal for flora malesiana.
686
  if (is_array($descriptionElements)) {
687
    foreach ($descriptionElements as $descriptionElement) {
688

    
689
      // --- DISTRIBUTION ---- //
690
      if ($descriptionElement->feature->uuid == UUID_DISTRIBUTION) {
691
        if ($descriptionElement->class == 'Distribution' && is_object($descriptionElement->area)) {
692
          $sortKey = $descriptionElement->area->representation_L10n;
693
          $distributionElements[$sortKey] = $descriptionElement;
694
        }
695
        elseif ($descriptionElement->class == 'TextData') {
696
          $asListElement = FALSE;
697
          $repr = theme('cdm_descriptionElementTextData', array(
698
            'element' => $descriptionElement,
699
            'asListElement' => $asListElement,
700
            'feature_uuid' => $descriptionElement->feature->uuid,
701
          ));
702

    
703
          if (!array_search($repr, $outArray)) {
704
            $outArray[] = $repr;
705
            // TODO HINT: sorting in theme_cdm_descriptionElementArray will
706
            // not work since this array contains html attributes with uuids
707
            // !!!!
708
            $sortOutArray = TRUE;
709
            $glue = '<br/> ';
710
            $enclosingTag = 'p';
711
          }
712
        }
713
      }
714

    
715
      // --- IMAGE_SOURCES --- //
716
      elseif ($descriptionElement->feature->uuid == UUID_IMAGE_SOURCES) {
717
        $image_sources[] = $descriptionElement;
718
      }
719
      // --- USE TEXTDATA --- //
720
      elseif ($descriptionElement->feature->uuid == UUID_USE) {
721
        // Do nothing to avoid rendering.
722
      } else {
723
        /* decide based on the description element class
724
         *
725
         * TODO provide api_hook as extension point for this
726
         */
727
        switch ($descriptionElement->class) {
728
          case 'TextData':
729
            $asListElement = TRUE;
730
            $outArray[] = theme('cdm_descriptionElementTextData', array(
731
              'element' => $descriptionElement,
732
              'asListElement' => $asListElement,
733
              'feature_uuid' => $descriptionElement->feature->uuid,
734
            ));
735
            break;
736
          case 'CommonTaxonName':
737
            $outArray[] = theme('cdm_descriptionElement_CommonTaxonName', array('element' => $descriptionElement));
738
          break;
739
          case 'CategoricalData':
740
            $outArray[] = theme('cdm_descriptionElement_CategoricalData', array('element' => $descriptionElement));
741
            break;
742
          case 'QuantitativeData':
743
            $outArray[] = theme('cdm_descriptionElement_QuantitativeData', array('element' => $descriptionElement));
744
            break;
745
          case 'Uses':
746
          /* IGNORE Uses classes, these are handled completely in theme_cdm_UseDescription */
747
          break;
748
        default:
749
        $outArray[] = '<li>No method for rendering unknown description class: ' . $descriptionElement->class . '</li>';
750
      }
751
    }
752
    }
753
  }
754

    
755
  // If feature = NAME USAGE sort the list of sources.
756
  // This is ONLY for FLORA MALESIANA and FLORE d'AFRIQUE CENTRALE.
757
  if ($descriptionElement->feature->uuid == UUID_NAME_USAGE) {
758
    sort($outArray);
759
  }
760

    
761
  if (isset($image_sources)) {
762
    $outArray[] = theme('cdm_description_element_image_source', array('image_sources' => $image_sources, 'asListElement' => TRUE));
763
  }
764

    
765
  if (variable_get('distribution_sort', 'NO_SORT') != 'NO_SORT') {
766
    $outArray[] = theme('cdm_description_ordered_distributions', array('taxon_uuid' => $taxon_uuid, 'descriptionElements' => $distributionElements));
767
  }
768
  else {
769
    ksort($distributionElements);
770
    // TODO , $entryEnclosingTag);
771
    $outArray[] = theme('cdm_descriptionElementDistribution', array(
772
      'descriptionElements' => $distributionElements,
773
    ));
774
  }
775

    
776
  // Take the feature of the last $descriptionElement.
777
  $feature = $descriptionElement->feature;
778

    
779
  $out = theme('cdm_descriptionElementArray', array(
780
    'elementArray' => $outArray,
781
    'feature' => $feature,
782
    'glue' => $glue,
783
    'sortArray' => $sortOutArray,
784
    'enclosingHtml' => $enclosingTag,
785
  ));
786

    
787
  RenderHints::popFromRenderStack();
788
  return $out;
789
}
790

    
791
/**
792
 * @todo Please document this function.
793
 * @see http://drupal.org/node/1354
794
 */
795
function compare_image_sources($a, $b) {
796
  if ($a->multilanguageText_L10n->text == $b->multilanguageText_L10n->text) {
797
    return 0;
798
  }
799
  return ($a->multilanguageText_L10n->text < $b->multilanguageText_L10n->text) ? -1 : 1;
800
}
801

    
802
/**
803
 * @todo Please document this function.
804
 * @see http://drupal.org/node/1354
805
 */
806
function theme_cdm_description_element_image_source($variables) {
807
  $image_sources = $variables['image_sources'];
808
  $asListElement = $variables['asListElement'];
809
  $out = '';
810
  $separator = ',';
811
  RenderHints::pushToRenderStack('descriptionElementImageSource');
812
  RenderHints::setFootnoteListKey(UUID_IMAGE_SOURCES);
813

    
814
  // Sorting the image sources.
815
  usort($image_sources, "compare_image_sources");
816
  // Generate the footnotes.
817
  foreach ($image_sources as $image_source) {
818
    $footNoteKeys = cdm_annotations_as_footnotekeys($image_source);
819
    foreach ($image_source->sources as $source) {
820
      if (_is_original_source_type($source)) {
821
        $fn_key = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), theme('cdm_OriginalSource', array(
822
          'source' => $source,
823
          'doLink' => FALSE,
824
        )));
825
        // Ensure uniqueness of the footnote keys.
826
        cdm_add_footnote_to_array($footNoteKeys, $fn_key);
827
      }
828
    }
829
    // Sort and render footnote keys.
830
    $footnoteKeyListStr = '';
831
    asort($footNoteKeys);
832
    foreach ($footNoteKeys as $footNoteKey) {
833
      $footnoteKeyListStr .= theme('cdm_footnote_key', array('footnoteKey' => $footNoteKey, 'separator' => ($footnoteKeyListStr ? $separator : '')));
834
    }
835
    // Return value!
836
    $out .= '<span class="descriptionElement descriptionElement-' . $image_source->uuid . '">' . $image_source->multilanguageText_L10n->text . $footnoteKeyListStr . '; </span>';
837
  }
838

    
839
  RenderHints::popFromRenderStack();
840
  return $out;
841
}
842

    
843
/**
844
 * @todo Please document this function.
845
 * @see http://drupal.org/node/1354
846
 */
847
function theme_cdm_descriptionElementDistribution($variables) {
848
  $descriptionElements = $variables['descriptionElements'];
849
  $enclosingTag = $variables['enclosingTag'];
850
  if (!$enclosingTag) {
851
    $enclosingTag = "span";
852
  }
853

    
854
  $out = '';
855
  $separator = ',';
856
  RenderHints::pushToRenderStack('descriptionElementDistribution');
857
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
858

    
859
  foreach ($descriptionElements as $descriptionElement) {
860

    
861
    // Annotations as footnotes.
862
    $footNoteKeys = cdm_annotations_as_footnotekeys($descriptionElement);
863
    // Source references as footnotes.
864
    foreach ($descriptionElement->sources as $source) {
865
      if (_is_original_source_type($source)) {
866
        $fn_key = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), theme('cdm_OriginalSource', array(
867
          'source' => $source,
868
          'doLink' => FALSE,
869
        )));
870
        // Ensure uniqueness of the footnote keys.
871
        cdm_add_footnote_to_array($footNoteKeys, $fn_key);
872
      }
873
    }
874
    // Sort and render footnote keys.
875
    $footnoteKeyListStr = '';
876
    asort($footNoteKeys);
877
    foreach ($footNoteKeys as $footNoteKey) {
878
      $footnoteKeyListStr .= theme('cdm_footnote_key', array('footnoteKey' => $footNoteKey, 'separator' => ($footnoteKeyListStr ? $separator : '')));
879
    }
880

    
881
    $out .= '<' . $enclosingTag . ' class="descriptionElement descriptionElement-' . $descriptionElement->uuid . '">' . $descriptionElement->area->representation_L10n . $footnoteKeyListStr . ' </' . $enclosingTag . '>';
882
  }
883

    
884
  RenderHints::popFromRenderStack();
885
  return $out;
886
}
887

    
888
/**
889
 * Compare two different footnotes objects.
890
 *
891
 * The comparison is based on the footnote key. The one which is
892
 * displayed as footnote number.
893
 *
894
 * @param mixed $a
895
 *   Footnote object $a.
896
 * @param mixed $b
897
 *   Footnote object $b.
898
 */
899
function footnotes_key_compare($a, $b) {
900
  $res = 0;
901
  if (empty($a) || empty($b)) {
902
    return $res;
903
  }
904
  if ($a->keyStr < $b->keyStr) {
905
    $res = -1;
906
  }
907
  elseif ($a->keyStr > $b->keyStr) {
908
    $res = 1;
909
  }
910
  return $res;
911
}
912

    
913
/**
914
 * @todo Please document this function.
915
 * @see http://drupal.org/node/1354
916
 */
917
function theme_cdm_description_ordered_distributions($variables) {
918

    
919
  $taxon_uuid = $variables['taxon_uuid'];
920
  $descriptionElements = $variables['descriptionElements'];
921

    
922
  // Returning NULL if there are no description elements.
923
  if ($taxon_uuid == null || $descriptionElements == NULL) {
924
    return NULL;
925
  }
926

    
927
  // Initialization of some variables.
928
  $out = '';
929
  $separator = ',';
930
  RenderHints::pushToRenderStack('descriptionElementDistribution');
931
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
932

    
933
  // Getting all the taxon description for a given taxon.
934
  $markerTypesEmpty = array();
935
  // $markerTypesEmpty['markerTypes'] = 'af9860ff-08f5-4b4d-863c-49ae96985115';
936
  $markerTypesEmpty['markerTypes'] = '';
937
  $queryString = $markerTypesEmpty['markerTypes'] ? queryString($markerTypesEmpty) : '';
938

    
939
  $taxonDescriptions = cdm_ws_get(CDM_WS_PORTAL_TAXON_DESCRIPTIONS, $taxon_uuid, $queryString);
940
  foreach ($taxonDescriptions as $description) {
941
    $descriptions_uuids[] = $description->uuid;
942
  }
943

    
944
  // Getting the sortered distributions (omitting level ??).
945
  $request_params = array();
946
  $request_params['omitLevels'] = UUID_NAMEDAREALEVEL_TDWGLEVEL_2;
947
  $ordered_areas = cdm_ws_get(CDM_WS_PORTAL_DESCRIPTION_DISTRIBUTION_TREE, join(',', $descriptions_uuids), queryString($request_params));
948
  if (isset($ordered_areas->rootElement->children)) {
949
    $ordered_areas = $ordered_areas->rootElement->children;
950
  }
951

    
952
  // Printing the distributions.
953
  if (is_array($ordered_areas) && count($ordered_areas) > 0) {
954
    foreach ($ordered_areas as $element_level1) {
955
      // Level1.
956
      if ($element_level1->data) {
957
        $out .= '<dt>' . $element_level1->data->area->representation_L10n . ':</dt> ';
958
      }
959
      $out .= '<dd>';
960

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

    
1032
          if (strlen($text_l4_aux) > 0) {
1033
            $out .= "$text_l3 $fnKeysLevel3Str ($text_l4_aux); ";
1034
          }
1035
          else {
1036
            $out .= "$text_l3 $fnKeysLevel3Str; ";
1037
          }
1038
        }
1039
      }// Level3.
1040
      $out = substr($out, 0, -2);
1041
      $out .= '.</dd>';
1042
    }// Level1.
1043
  }
1044
  RenderHints::popFromRenderStack();
1045
  return $out;
1046
}
1047

    
1048

    
1049
/*
1050
function theme_cdm_descriptionElementDistribution($descriptionElements){ $out
1051
  = ''; $separator = ',';
1052
  RenderHints::pushToRenderStack('descriptionElementDistribution');
1053
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
1054
  foreach($descriptionElements as $descriptionElement){ // annotations as
1055
  footnotes $annotationFootnoteKeys = theme('cdm_annotations_as_footnotekeys',
1056
  $descriptionElement); // source references as footnotes
1057
  $sourcesFootnoteKeyList = ''; foreach($descriptionElement->sources as
1058
  $source){ if(_is_original_source_type($source)){ $_fkey =
1059
  FootnoteManager::addNewFootnote(UUID_DISTRIBUTION,
1060
  theme('cdm_OriginalSource', $source, FALSE));
1061
  $sourcesFootnoteKeyList .= theme('cdm_footnote_key', $_fkey,
1062
  UUID_DISTRIBUTION, ($sourcesFootnoteKeyList ? $separator : '')); } }
1063
  if($annotationFootnoteKeys && $sourcesFootnoteKeyList){
1064
  $annotationFootnoteKeys .= $separator; } $out .=
1065
  $descriptionElement->area->representation_L10n . $annotationFootnoteKeys .
1066
  $sourcesFootnoteKeyList . ' '; } $out = substr($out, 0,
1067
  strlen($out)-strlen($separator) ); RenderHints::popFromRenderStack(); return
1068
  $out; }
1069
*/
1070

    
1071
/**
1072
 * Composes the render array for a distribution map of the given taxon.
1073
 *
1074
 * The distribution map can either be a plain image or a dynamic open layers map
1075
 * depending on the settings.
1076
 *
1077
 * compose_hook() implementation
1078
 *
1079
 * @param $taxon
1080
 *   The CDM Taxon instance to create the distribution map for.
1081
 * @return array
1082
 *    A drupal render array
1083
 *
1084
 * Similar compose function compose_map()
1085
 *
1086
 * @ingroup compose
1087
 */
1088
function compose_distribution_map($taxon) {
1089

    
1090
  $out = '';
1091
  $settings = get_edit_map_service_settings();
1092

    
1093
  $fontStyles = array(
1094
    0 => "plane",
1095
    1 => "italic",
1096
  );
1097

    
1098
  // Query cdm server for map service uri parameters.
1099
  $query_string = cdm_ws_get(CDM_WS_GEOSERVICE_DISTRIBUTIONMAP, $taxon->uuid);
1100
  $query_string = $query_string->String;
1101
  $out .= "<!-- map_data_parameters:" . print_r($query_string, TRUE) . " -->";
1102
  if (!$query_string) {
1103
    // The $query_string is empty if there are no distribution areas defined.
1104
    return;
1105
  }
1106

    
1107
  /* ------ choose the display mode, either openlayers or static image ------ */
1108

    
1109
  $map_settings = get_array_variable_merged(CDM_MAP_DISTRIBUTION, CDM_MAP_DISTRIBUTION_DEFAULT);
1110

    
1111
  if ($map_settings['map_type'] == 1) {
1112

    
1113
    /* =========== display distributions using the openlayers map viewer =========== */
1114

    
1115
    $legendFormatQueryStr = "format=image" . urlencode('/') . "png"
1116
         . "&TRANSPARENT=TRUE"
1117
         . "&WIDTH=" . $map_settings['legend']['icon_width']
1118
         . "&HEIGHT=" . $map_settings['legend']['icon_height']
1119
           // TODO why is the layer=topp:tdwg_level_4 parameter needed at all here??
1120
           // AK: i think the tdwg_level_4 is used as place holder and will be replaced later on
1121
           // => search for "tdwg_level_4" in the code
1122
         . "&layer=topp" . urlencode(':') . "tdwg_level_4"
1123
         . "&LEGEND_OPTIONS=forceLabels" . urlencode(':') . "on"
1124
             . ";fontStyle" . urlencode(':') . $fontStyles[$map_settings['legend']['font_style']]
1125
             . ";fontSize" . urlencode(':') .  $map_settings['legend']['font_size']
1126
         . "&SLD=";
1127

    
1128
    $out .= get_openlayers_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
  else {
1139
    $legendFormatQueryStr = '';
1140
    $out = get_image_map(
1141
        $map_settings['width'],
1142
        $map_settings['height'],
1143
        $map_settings['bbox'],
1144
        NULL,
1145
        $query_string,
1146
        $legendFormatQueryStr,
1147
        $map_settings['caption']
1148
    );
1149
  }
1150
  return markup_to_render_array($out);
1151
}
1152

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

    
1180
    case "MediaKey":
1181
      $cdm_ws_pasepath = CDM_WS_MEDIAKEY;
1182
      break;
1183

    
1184
    case "MultiAccessKey":
1185
      $cdm_ws_pasepath = CDM_WS_MULTIACCESSKEY;
1186
      break;
1187

    
1188
  }
1189

    
1190
  if (!$cdm_ws_pasepath) {
1191
    drupal_set_message(t('Type parameter is not valid: ') . $type, 'error');
1192
  }
1193

    
1194
  $queryParameters = '';
1195
  if (is_numeric($pageSize)) {
1196
    $queryParameters = "pageSize=" . $pageSize;
1197
  }
1198
  else {
1199
    $queryParameters = "pageSize=0";
1200
  }
1201

    
1202
  if (is_numeric($pageNumber)) {
1203
    $queryParameters = "pageNumber=" . $pageNumber;
1204
  }
1205
  else {
1206
    $queryParameters = "pageNumber=0";
1207
  }
1208
  $queryParameters = NULL;
1209
  if ($taxonUuid) {
1210
    $queryParameters = "findByTaxonomicScope=$taxonUuid";
1211
  }
1212
  $pager = cdm_ws_get($cdm_ws_pasepath, NULL, $queryParameters);
1213

    
1214
  if (!$pager || $pager->count == 0) {
1215
    return array();
1216
  }
1217
  return $pager->records;
1218
}
1219

    
1220
/**
1221
 * @todo Please document this function.
1222
 * @see http://drupal.org/node/1354
1223
 */
1224
function theme_cdm_IdentificationKey($variables) {
1225
  $out = '';
1226
  $identificationKey = $variables['identificationKey'];
1227
  $doLinkToKeyPage = $variables['doLinkToKeyPage'];
1228
  $showIdentificationKeyTitle = $variables['showIdentificationKeyTitle'];
1229
  $parentRenderPath = RenderHints::getRenderPath();
1230
  RenderHints::pushToRenderStack("IdentificationKey");
1231

    
1232
  if ($showIdentificationKeyTitle) {
1233
    if ($doLinkToKeyPage) {
1234
      $out = l($identificationKey->titleCache, path_to_key($identificationKey->class, $identificationKey->uuid));
1235
    }
1236
    else {
1237
      $out = $identificationKey->titleCache;
1238
    }
1239
  }
1240
  if (isset($identificationKey->sources) && is_array($identificationKey->sources)) {
1241
    // order and display sources.
1242
    $sources = oder_sources($identificationKey->sources, TRUE);
1243
    $out .= '<div class="sources">';
1244
    $out .=  implode('', $sources);
1245
    $out .= '</div>';
1246
  }
1247
  // Display annotations.
1248
  $out .= theme('cdm_annotations', array('annotations' => cdm_ws_getAnnotationsFor($identificationKey), 'enclosingTag' => 'div'));
1249
  RenderHints::popFromRenderStack();
1250
  return $out;
1251
}
1252

    
1253
/**
1254
 * @todo Please document this function.
1255
 * @see http://drupal.org/node/1354
1256
 */
1257
function theme_cdm_polytomousKey($variables) {
1258
  $polytomousKey = $variables['polytomousKey'];
1259

    
1260
  // TODO settings needed.
1261
  // @see http://en.wikipedia.org/wiki/Single_access_key#Presentation_styles
1262
  // @see http://dev.e-taxonomy.eu/trac/ticket/2152
1263
  $keyStyle = "linkedStyle";
1264

    
1265
  RenderHints::pushToRenderStack("polytomousKey");
1266
  // Key nodes in linked style.
1267
  $out = '<table class="polytomousKey polytomousKey_' . $keyStyle . '">';
1268
  $out .= theme('cdm_polytomousKey_' . $keyStyle . '_subgraph', array('polytomousKeyNode' => $polytomousKey->root));
1269
  $out .= '</table>';
1270
  RenderHints::popFromRenderStack();
1271
  return $out;
1272
}
1273

    
1274
/**
1275
 * @todo Please document this function.
1276
 * @see http://drupal.org/node/1354
1277
 */
1278
function theme_cdm_polytomousKey_linkedStyle_subgraph($variables) {
1279
  $polytomousKeyNode = $variables['polytomousKeyNode'];
1280
  static $statementCountCharacter = '\'';
1281
  $out = "";
1282

    
1283
  if (is_array($polytomousKeyNode->children)) {
1284
    $childIndex = 0;
1285

    
1286
    // Render edges of the current node.
1287
    foreach ($polytomousKeyNode->children as &$child) {
1288

    
1289
      if (!isset($child->statement) && isset($child->taxon->uuid)) {
1290
        // Skip node with empty statements (see below for explanation: "Special
1291
        // case").
1292
        // this skipping here happens always in the next deeper level of iteration
1293
        // the check below is node on the level above
1294
        continue;
1295
      }
1296

    
1297
      /*
1298
       * Special case: Child nodes with empty statements but taxa as leaf are to
1299
       * treated as if all those taxa where direct children of the source node.
1300
       */
1301
      $islinkToManyTaxa = !isset($child->children[0]->statement) && isset($child->children[0]->taxon->uuid);
1302
      $islinkToTaxon = isset($child->taxon->uuid);
1303
      $islinkToSubKey = isset($child->subkey->uuid);
1304
      $islinkToOtherNode = isset($child->otherNode);
1305
      // Either NULL or 0.
1306
      $islinkToNode = $child->nodeNumber && !$islinkToManyTaxa && !$islinkToOtherNode;
1307
      $hasQuestion = !empty($polytomousKeyNode->question->label_l10n);
1308
      $hasFeature = isset($polytomousKeyNode->feature);
1309

    
1310
      // $indentEdge = $hasQuestion && $childIndex > 0;
1311
      // Question.
1312
      if ($hasQuestion && $childIndex == 0) {
1313
        // Place question, as extra table row.
1314
        $out .= '<tr class="question new_section">';
1315
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber) . "</td>";
1316
        $out .= '<td class="question">' . $polytomousKeyNode->question->label_l10n . '</td>';
1317
        $out .= '</tr>';
1318
      }
1319

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

    
1322
      if ($hasQuestion) {
1323
        $out .= '<td class="nodeNumber"></td>';
1324
      }
1325
      else {
1326
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber . str_pad("", $childIndex, $statementCountCharacter)) . "</td>";
1327
      }
1328

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

    
1331
      // Feature.
1332
      if ($hasFeature) {
1333
        $out .= $polytomousKeyNode->feature->representation_L10n . ": ";
1334
      }
1335

    
1336
      // Statement.
1337
      $out .= $child->statement->label_l10n;
1338

    
1339
      // --- Links to nodes taxa and subkeys.
1340
      $out .= '<div class="nodeLink">';
1341

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

    
1355
      // Link to a PolytomousKeyNode.
1356
      if ($islinkToOtherNode) {
1357
        $out .= '<div class="nodeLinkToOtherNode">';
1358
        if (is_object($child->modifyingText)) {
1359
          $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $child->modifyingText));
1360
        }
1361
        $out .= l($child->otherNode->nodeNumber, $_REQUEST["q"], array(
1362
          'attributes' => NULL,
1363
          'query' => NULL,
1364
          'fragment' => $child->otherNode->uuid,
1365
        )) . '</div>';
1366
      }
1367

    
1368
      // Link to one or many taxa.
1369
      if ($islinkToTaxon || $islinkToManyTaxa) {
1370

    
1371
        if ($islinkToManyTaxa) {
1372
          $taxonChildren = $child->children;
1373
        }
1374
        else {
1375
          $taxonChildren = array(
1376
            $child,
1377
          );
1378
        }
1379

    
1380
        foreach ($taxonChildren as $taxonChild) {
1381
          // TODO many taxa $child->children->taxon.
1382
          $out .= '<div class="nodeLinkToTaxon">';
1383
          if (is_object($taxonChild->modifyingText)) {
1384
            $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $taxonChild->modifyingText));
1385
          }
1386
          $out .= theme("cdm_taxonName", array('taxonName' => $taxonChild->taxon->name, 'nameLink' => url(path_to_taxon($taxonChild->taxon->uuid))));
1387
          $out .= '</div>';
1388
        }
1389

    
1390
        // Link to a subkey.
1391
        if ($islinkToSubKey) {
1392
          $out .= '<div class="nodeLinkToSubkey">' . theme('cdm_IdentificationKey', array('identificationKey' => $child->subkey)) . '</div>';
1393
        }
1394
      }
1395

    
1396
      $out .= '</div>'; // End node link.
1397
      $out .= '</td>'; // End edge.
1398
      $out .= '</tr>';
1399

    
1400
      $childIndex++;
1401
    }
1402

    
1403
    // Recurse into child nodes.
1404
    foreach ($polytomousKeyNode->children as &$child) {
1405
      $out .= theme('cdm_polytomousKey_linkedStyle_subgraph', array('polytomousKeyNode' => $child));
1406
    }
1407
  }
1408

    
1409
  return $out;
1410
}
1411

    
1412
/**
1413
 * @todo Please document this function.
1414
 * @see http://drupal.org/node/1354
1415
 */
1416
function theme_cdm_poytomousKeyNode_modifyingText($variables) {
1417
  $out = '';
1418
  $modifyingText = $variables['modifyingText'];
1419
  if (is_object($modifyingText)) {
1420
    $i = 0;
1421
    foreach (get_object_vars($modifyingText) as $lang => $languageString) {
1422
      $out .= ($i++ > 0 ? ', ' : '') . '<span class="modifyingText">' . $languageString->text . '</span> ';
1423
    }
1424
  }
1425
  return $out;
1426
}
1427

    
1428
/**
1429
 * Returns HTML for a list of a specific type of IdentificationKeys.
1430
 *
1431
 * The list can be restricteded by a taxon.
1432
 *
1433
 * @param array $variables
1434
 *   An associative array containing:
1435
 *   - type: The simple name of the cdm class implementing the interface
1436
 *     IdentificationKey, valid values are:
1437
 *     PolytomousKey, MediaKey, MultiAccessKey
1438
 *   - taxonUuid: If given, this parameter restrict the listed keys to those
1439
 *     which have the taxon identified be this uuid in scope.
1440
 *
1441
 * @ingroup themeable
1442
 */
1443
function theme_cdm_list_IdentificationKeys($variables) {
1444
  $type = $variables['type'];
1445
  $taxonUuid = $variables['taxonUuid'];
1446
  $keyList = _list_IdentificationKeys($type, $taxonUuid);
1447
  if (!$keyList || count($keyList) == 0) {
1448
    return;
1449
  }
1450

    
1451
  RenderHints::pushToRenderStack('list_IdentificationKeys');
1452
  $out = '<ul>';
1453
  foreach ($keyList as $key) {
1454
    $out .= '<li>';
1455
    $out .= theme('cdm_IdentificationKey', array('identificationKey' => $key));
1456
    $out .= '</li>';
1457
  }
1458
  $out .= '</ul>';
1459
  $out .= theme("cdm_annotation_footnotes", array('footnoteListKey' => RenderHints::getRenderPath()));
1460
  RenderHints::popFromRenderStack();
1461

    
1462
  return $out;
1463
}
1464

    
1465
/**
1466
 * @todo Please document this function.
1467
 * @see http://drupal.org/node/1354
1468
 */
1469
function theme_cdm_block_IdentificationKeys($variables) {
1470
  $taxonUuid = $variables['taxonUuid'];
1471
  static $types = array(
1472
    "PolytomousKey" => "Polytomous",
1473
    "MediaKey" => "Media",
1474
    "MultiAccessKey" => "Multiaccess",
1475
  );
1476
  RenderHints::pushToRenderStack('block_IdentificationKeys');
1477
  $out = '';
1478
  foreach ($types as $type => $label) {
1479
    $keylist = theme('cdm_list_IdentificationKeys', array('type' => $type, 'taxonUuid' => $taxonUuid));
1480
    if (!$keylist) {
1481
      continue;
1482
    }
1483
    $out .= '<div class="' . $type . '">';
1484
    $out .= '<h3>' . t($label) . "</h3>";
1485
    $out .= $keylist;
1486
    $out .= '</div>';
1487
  }
1488
  RenderHints::popFromRenderStack();
1489
  return $out;
1490
}
1491

    
1492
/**
1493
 * This theming function formats the use description and use record list for
1494
 * these descriptions.
1495
 *
1496
 * @see http://drupal.org/node/1354
1497
 */
1498
function theme_cdm_UseDescription($variables) {
1499
  $descriptions = $variables['description'];
1500
  $taxonUuid = $variables['taxonUuid'];
1501
  $out = '<div id="content"><ul id="Description" class ="description">';
1502
  if ($descriptions == NULL) {
1503
    return;
1504
  }
1505
  $descriptionSynonyms = '';
1506
  $descriptionOut = '';
1507
  $synonymOut = '';
1508
  $currentTaxon = cdm_ws_get(CDM_WS_PORTAL_TAXON, $taxonUuid);
1509

    
1510
  foreach ($descriptions as $description) {
1511
    $useSummary = '';
1512
    foreach ($description->elements as $element) {
1513

    
1514
      if ($element->feature->uuid == UUID_USE && !(strlen($useSummary) > 0)) {
1515
        $useSummary = $element->multilanguageText_L10n->text;
1516
      }
1517
    }
1518
    // uses will be ordered by source
1519
    foreach ($description->sources as $source) {
1520
      $is_about_current_taxon = FALSE;
1521
      $originalTaxonUsedInSource = NULL;
1522
      $originalTaxonPager = NULL;
1523
      if ($source->originalNameString) {
1524
        $request_params = array();
1525
        $request_params['query'] = $source->originalNameString;
1526
        $request_params['matchMode'] = "EXACT";
1527
        $originalTaxonPager = cdm_ws_get(CDM_WS_PORTAL_NAME_FINDBYNAME, NULL, queryString($request_params));
1528
        if ($originalTaxonPager->count > 0) {
1529
          $originalTaxonUsedInSource = $originalTaxonPager->records[0];
1530
        }
1531
        else {
1532
          $originalTaxonUsedInSource = $currentTaxon->name;
1533
        }
1534
      }
1535
      else {
1536
        $originalTaxonUsedInSource = $currentTaxon->name;
1537
      }
1538

    
1539
      $is_about_current_taxon = $currentTaxon->name->uuid == $originalTaxonUsedInSource->uuid;
1540

    
1541
      if (!$is_about_current_taxon) {
1542
        $descriptionOut .= '<li class="descriptionText DescriptionElement">';
1543
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1544
          'absolute' => TRUE,
1545
          'html' => TRUE,
1546
        ));
1547
        $descriptionOut .= $name_used_in_source_link_to_show_use . ': ';
1548
        $descriptionOut .= $useSummary;
1549
        foreach ($description->sources as $source) {
1550
          $descriptionOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1551
        }
1552
        $hasUseRecords = FALSE;
1553
        $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>';
1554
        foreach ($description->elements as $descriptionElement) {
1555
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1556
            $hasUseRecords = TRUE;
1557
            // FIXME localization hardcoded to English
1558
            $useRecordTags = explode(';', $descriptionElement->modifyingText->English->text);
1559
            $descriptionUseRecordOut .= '<tr>';
1560
            $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>';
1561
            $descriptionUseRecordOut .= '</tr>';
1562
          }
1563
        }
1564
        $descriptionUseRecordOut .= '</table></div>';
1565
        if ($hasUseRecords) {
1566
          $descriptionOut .= $descriptionUseRecordOut . '</li>';
1567
        }
1568
      }
1569
      else {
1570
        // TODO +/- duplicate of above, unify this code
1571
        $synonymOut .= '<li class="descriptionText DescriptionElement">';
1572
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1573
          'absolute' => TRUE,
1574
          'html' => TRUE,
1575
        ));
1576

    
1577
        $synonymOut .= $name_used_in_source_link_to_show_use . ': ';
1578
        $synonymOut .= $useSummary;
1579
        foreach ($description->sources as $source) {
1580
          $synonymOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1581
        }
1582

    
1583
        $hasUseRecords = FALSE;
1584
        $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>';
1585
        foreach ($description->elements as $descriptionElement) {
1586
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1587
            $hasUseRecords = TRUE;
1588
            $useRecordTags = explode(';', $descriptionElement->modifyingText->English->text);
1589
            $useRecordTableOut .= '<tr>';
1590
            $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>';
1591
            $useRecordTableOut .= '</tr>';
1592
          }
1593
        }
1594
        $useRecordTableOut .= '</table></div>';
1595
        if ($hasUseRecords) {
1596
          $synonymOut .= $useRecordTableOut . '</li>';
1597
        }
1598
      }
1599

    
1600
      // }
1601
    }
1602
  }
1603
  $out .= $descriptionOut . $synonymOut;
1604
  $out .= "</ul></div>";
1605
  return $out;
1606
}
1607

    
1608
// The Uses theming function here will handle the display of the
1609
// Uses Descriptions.
1610
// Comment @WA: $pageSize is not used.
1611
// function theme_cdm_block_Uses ($taxonUuid = NULL, $pageSize = NULL {
1612
/**
1613
 * @todo Please document this function.
1614
 * @see http://drupal.org/node/1354
1615
 */
1616
function theme_cdm_block_Uses($variables) {
1617
  $taxonUuid = $variables['taxonUuid'];
1618
  RenderHints::pushToRenderStack('block_Uses');
1619

    
1620
  if ($taxonUuid == NULL) {
1621
    return;
1622
  }
1623
  $out = '';
1624
  $markerTypes = array();
1625
  $markerTypes['markerTypes'] = UUID_MARKERTYPE_USE;
1626
  $useDescriptions = cdm_ws_get(CDM_WS_PORTAL_TAXON_DESCRIPTIONS, $taxonUuid, queryString($markerTypes));
1627
  if (!empty($useDescriptions)) {
1628
    // FIXME use theme_block instaed of hardcoding the block html here !!!!
1629
    $out .= '<div id="block-cdm_dataportal-feature-description" class="clear-block block block-cdm_dataportal-feature"><H2><a name="userecords"> </a> Uses </H2>';
1630
    $formatUseDescriptions = theme('cdm_UseDescription', array('description' => $useDescriptions, 'taxonUuid' => $taxonUuid));
1631

    
1632
    $out .= $formatUseDescriptions;
1633
    $out .= "</div>";
1634
  }
1635

    
1636
  return $out;
1637
}
(3-3/10)