Project

General

Profile

Download (57 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 a set of feature blocks for a taxon profile from the $mergedFeatureNodes of a given $taxon.
41
 *
42
 * The taxon profile consists of drupal block elements, one for the description elements
43
 * of a specific feature. The structure is defined by specific FeatureTree.
44
 * The chosen FeatureTree is merged with the list of description 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 $mergedFeatureNodes
52
 *
53
 * @param $taxon
54
 *
55
 * @return array
56
 *  A Drupal render array
57
 *
58
 * @ingroup compose
59
 */
60
function compose_cdm_feature_nodes($mergedFeatureNodes, $taxon) {
61

    
62
  $out = '';
63

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

    
66
  $gallery_settings = getGallerySettings(CDM_DATAPORTAL_DESCRIPTION_GALLERY_NAME);
67

    
68
  // Create a drupal block for each feature
69
  foreach ($mergedFeatureNodes as $node) {
70

    
71
    if ((isset($node->descriptionElements['#type']) ||
72
        has_feature_node_description_elements($node)) && $node->feature->uuid != UUID_IMAGE) { // skip empty or supressed features
73

    
74
      $feature_name = cdm_term_representation($node->feature, 'Unnamed Feature');
75

    
76
      $block = feature_block($feature_name, $node->feature);
77

    
78
      /*
79
       * Content/DISTRIBUTION.
80
       */
81

    
82
      if ($node->feature->uuid == UUID_DISTRIBUTION) {
83
        $block = compose_feature_block_distribution($taxon, $node->descriptionElements, $node->feature);
84

    
85
      }
86
      /*
87
       * Content/COMMON_NAME.
88
       */
89
      elseif ($node->feature->uuid == UUID_COMMON_NAME) {
90
        $common_names_render_array = compose_cdm_common_names($node->descriptionElements, $node->feature);
91
        $block->content .= drupal_render($common_names_render_array);
92
      }
93

    
94
      /*
95
       * Content/ALL OTHER FEATURES.
96
       */
97
      else {
98

    
99
        $media_list = array();
100
        $out_child_elements = '';
101

    
102
        if (isset($node->descriptionElements)) {
103
          $taxon_uuid = NULL;
104
          if(isset($taxon) ) {
105
            $taxon_uuid = $taxon->uuid;
106
          }
107
          $block->content .= theme('cdm_descriptionElements', array(
108
            'descriptionElements' => $node->descriptionElements,
109
            'feature' => $node->feature,
110
            'taxon_uuid' => $taxon_uuid,
111
          ));
112
        }
113

    
114
          // Content/ALL OTHER FEATURES/Subordinate Features
115
          // subordinate features are printed inline in one floating text,
116
          // it is expected hat supordinate features can "contain" TextData,
117
          // Qualitative- and Qualitative- DescriptioneElements
118
          if (isset($node->childNodes[0])) {
119

    
120
          // TODO support more than one level of children.
121
          // can this be solved by resursively calling this very function?
122
          // @see http://dev.e-taxonomy.eu/trac/ticket/2393
123
          $text = '';
124
          foreach ($node->childNodes as $child) {
125

    
126
            if (isset($child->descriptionElements) && is_array($child->descriptionElements)) {
127
              foreach ($child->descriptionElements as $element) {
128

    
129
                if (is_array($element->media)) {
130
                  // Append media of supordinate elements to list of main
131
                  // feature.
132
                  $media_list = array_merge($media_list, $element->media);
133
                }
134

    
135
                switch ($element->class) {
136
                  case 'TextData':
137
                    // TODO use theme_cdm_descriptionElementTextData()
138
                    $out_child_elements = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
139
                    $out_child_elements = str_replace($child->feature->titleCache, '<em>' . $child->feature->representation_L10n . '</em>', $out_child_elements);
140
                    break;
141
                  case 'CategoricalData':
142
                    $out_child_elements  = '<em>' . $child->feature->representation_L10n . '</em> '
143
                      . theme('cdm_descriptionElement_CategoricalData', array('element' => $element));
144
                    break;
145
                  case 'QuantitativeData':
146
                    $out_child_elements = '<em>' . $child->feature->representation_L10n . '</em> '
147
                      . theme('cdm_descriptionElement_QuantitativeData', array('element' => $element));
148

    
149
                }
150

    
151
              }
152
              $text .= " " . $out_child_elements;
153
              $out_child_elements = '';
154
            }
155
          }
156
          $block->content .= $text;
157
          $block->content .=  compose_feature_media_gallery($node, $media_list, $gallery_settings);
158

    
159

    
160
          /*
161
           * Footnotes for the feature block
162
           */
163
          $block->content .= theme('cdm_footnotes', array('footnoteListKey' => $node->feature->uuid));
164
          $block->content .= theme('cdm_annotation_footnotes', array('footnoteListKey' => $node->feature->uuid));
165
        }
166
      }
167

    
168

    
169
      $out .= theme('block',
170
        array(
171
          'elements' => array(
172
            '#block' => $block,
173
            '#children' => $block->content,
174
          )
175
        )
176
      );
177
    } // END: skip empty or supressed features
178
  } // END: creating a block per feature
179
  RenderHints::popFromRenderStack();
180

    
181
  return markup_to_render_array($out);
182
}
183

    
184
  /**
185
   * @param $node
186
   * @param $media_list
187
   * @param $gallery_settings
188
   * @return array
189
   */
190
  function compose_feature_media_gallery($node, $media_list, $gallery_settings) {
191
    if (isset($node->descriptionElements)) {
192
      $media_list = array_merge($media_list, cdm_dataportal_media_from_descriptionElements($node->descriptionElements));
193
    }
194
    $captionElements = array('title', 'rights');
195
    $gallery = '';
196
    if (isset($gallery_settings['cdm_dataportal_media_maxextend']) && isset($gallery_settings['cdm_dataportal_media_cols'])) {
197
      $gallery = theme('cdm_media_gallerie', array(
198
        'mediaList' => $media_list,
199
        'galleryName' => CDM_DATAPORTAL_DESCRIPTION_GALLERY_NAME . '_' . $node->feature->uuid,
200
        'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
201
        'cols' => $gallery_settings['cdm_dataportal_media_cols'],
202
        'captionElements' => $captionElements,
203
      ));
204
      return array($media_list, $gallery);
205
    }
206
    return array($media_list, $gallery);
207
  }
208

    
209
  /**
210
   * @param $taxon
211
   * @param $descriptionElements
212
   *   an associative array with two elements:
213
   *   - '#type': must be 'DTO'
214
   *   - 'DistributionInfoDTO': a CDM DistributionInfoDTO object as returned by the DistributionInfo web service
215
   * @param $feature
216
   *
217
   * @ingroup compose
218
   */
219
  function compose_feature_block_distribution($taxon, $descriptionElements, $feature) {
220
    $text_data_glue = '';
221
    $text_data_sortOutArray = FALSE;
222
    $text_data_enclosingTag = 'ul';
223
    $text_data_out_array = array();
224

    
225
    $distributionElements = NULL;
226
    $distribution_info_dto = NULL;
227
    $distribution_sortOutArray = FALSE;
228

    
229
    if (variable_get('distribution_sort', 'NO_SORT') != 'NO_SORT') {
230
      $distribution_glue = '';
231
      $distribution_enclosingTag = 'dl';
232
    } else {
233
      $distribution_glue = '';
234
      $distribution_enclosingTag = 'ul';
235
    }
236

    
237
    if (!isset($descriptionElements['#type']) || !$descriptionElements['#type'] == 'DTO') {
238
      // skip the DISTRIBUTION section if there is no DTO type element
239
      return array(); // FIXME is it ok to return an empty array?
240
    }
241

    
242
    $block = feature_block(
243
      cdm_term_representation($feature, 'Unnamed Feature'),
244
      $feature
245
    );
246

    
247
    // ======== FIXME is this being used at all? seems to make no sense!!!
248
    if (isset($descriptionElements['TextData'])) {
249
      // --- TextData
250
      foreach ($descriptionElements['TextData'] as $text_data_element) {
251
        $asListElement = FALSE;
252
        $repr = theme('cdm_descriptionElementTextData', array(
253
          'element' => $text_data_element,
254
          'asListElement' => $asListElement,
255
          'feature_uuid' => $text_data_element->feature->uuid,
256
        ));
257

    
258
        if (!array_search($repr, $text_data_out_array)) {
259
          $text_data_out_array[] = $repr;
260
          // TODO HINT: sorting in theme_cdm_feature_block_elements will
261
          // not work since this array contains html attributes with uuids
262
          // !!!!
263
          $text_data_sortOutArray = TRUE;
264
          $text_data_glue = '<br/> ';
265
          $text_data_enclosingTag = 'p';
266
        }
267
      }
268
    }
269

    
270

    
271
    if ($text_data_out_array && variable_get(DISTRIBUTION_TEXTDATA_DISPLAY_ON_TOP, 0)) {
272
      $block->content .= theme('cdm_feature_block_elements', array(
273
        'elementArray' => $text_data_out_array,
274
        'feature' => $feature,
275
        'glue' => $text_data_glue,
276
        'sortArray' => $text_data_sortOutArray,
277
        'enclosingHtml' => $text_data_enclosingTag,
278
      ));
279
    }
280

    
281
    // --- Distribution map
282
    $distribution_map_query_parameters = NULL;
283
    if (isset($descriptionElements['DistributionInfoDTO'])) {
284
      $distribution_map_query_parameters = $descriptionElements['DistributionInfoDTO']->mapUriParams;
285
    }
286
    $map_render_element = compose_distribution_map($taxon, $distribution_map_query_parameters);
287
    $block->content .= $map_render_element['#markup'];
288

    
289
    // --- tree or list
290
    $dto_out_array = array();
291
    if (isset($descriptionElements['DistributionInfoDTO'])) {
292
      $distribution_info_dto = $descriptionElements['DistributionInfoDTO'];
293

    
294
      // --- tree
295
      if (is_object($distribution_info_dto->tree)) {
296
        $dto_out_array[] = theme('cdm_description_ordered_distributions', array('distribution_tree' => $distribution_info_dto->tree));
297
      }
298

    
299
      // --- sorted element list
300
      if (is_array($distribution_info_dto->elements) && count($distribution_info_dto->elements) > 0) {
301
        foreach ($distribution_info_dto->elements as $descriptionElement) {
302
          if (is_object($descriptionElement->area)) {
303
            $sortKey = $descriptionElement->area->representation_L10n;
304
            $distributionElements[$sortKey] = $descriptionElement;
305
          }
306
        }
307
        ksort($distributionElements);
308
        $dto_out_array[] = theme('cdm_descriptionElement_Distribution', array(
309
          'descriptionElements' => $distributionElements,
310
        ));
311

    
312
      }
313
      //
314
      $block->content .= theme('cdm_feature_block_elements', array(
315
        'elementArray' => $dto_out_array,
316
        'feature' => $feature,
317
        'glue' => $distribution_glue,
318
        'sortArray' => $distribution_sortOutArray,
319
        'enclosingHtml' => $distribution_enclosingTag,
320
      ));
321
    }
322

    
323
    // --- TextData at the bottom
324
    if ($text_data_out_array && !variable_get(DISTRIBUTION_TEXTDATA_DISPLAY_ON_TOP, 0)) {
325
      $block->content .= theme('cdm_feature_block_elements', array(
326
        'elementArray' => $text_data_out_array,
327
        'feature' => $feature,
328
        'glue' => $text_data_glue,
329
        'sortArray' => $text_data_sortOutArray,
330
        'enclosingHtml' => $text_data_enclosingTag,
331
      ));
332
    }
333

    
334
    $block->content .= theme('cdm_footnotes', array('footnoteListKey' => UUID_DISTRIBUTION));
335
    $block->content .= theme('cdm_annotation_footnotes', array('footnoteListKey' => UUID_DISTRIBUTION));
336

    
337
    return $block;
338
  }
339

    
340

    
341
  /**
342
 * @todo Please document this function.
343
 * @see http://drupal.org/node/1354
344
 */
345
function theme_FeatureTree_hierarchy($variables) {
346

    
347
  $FeatureTreeUuid = $variables['FeatureTreeUuid'];
348
  if (!is_uuid($FeatureTreeUuid)) {
349
    return;
350
  }
351

    
352
  $out = '';
353
  $featureTree = cdm_ws_get(CDM_WS_FEATURETREE, array(
354
    $FeatureTreeUuid,
355
  ));
356

    
357
  if (isset($featureTree) && isset($featureTree->root)) {
358
    $out = '<ul class="' . $featureTree->class . '">';
359
    $out .= theme('FeatureTree_hierarchy_children', array('node' => $featureTree->root));
360
    $out .= '</ul>';
361
  }
362
  return $out;
363
}
364

    
365
/**
366
 * @todo Please document this function.
367
 * @see http://drupal.org/node/1354
368
 */
369
function theme_FeatureTree_hierarchy_children($variables) {
370

    
371
  $node = $variables['node'];
372
  $out = '';
373
  if (isset($node->childNodes)) {
374

    
375
    foreach ($node->childNodes as $childNode) {
376
      $out .= '<li>' . check_plain($childNode->feature->representation_L10n);
377
      if (isset($childNode->childNodes) && count($childNode->childNodes) > 0) {
378
        $out .= '<ul>' . theme('FeatureTree_hierarchy_children', array('node' => $childNode)) . '</ul>';
379
      }
380
      $out .= '</li>';
381
    }
382
  }
383
  return $out;
384
}
385

    
386
/**
387
 * Returns HTML for the texts in a description $elementArray.
388
 *
389
 * Joins the texts in $elementArray and encloses with a HTML tag.
390
 *
391
 * @param array $variables
392
 *   An associative array containing:
393
 *   - elementArray
394
 *   - feature: The feature to which the elements given in $elementArray are
395
 *     belonging to.
396
 *   - glue: Defaults to empty string.
397
 *   - sortArray: Whether to sort the $elementArray alphabetically.
398
 *   - enclosingHtml
399
 *
400
 * @ingroup themeable
401
 */
402
function theme_cdm_feature_block_elements($variables) {
403
  $elementArray = $variables['elementArray'];
404
  $feature = $variables['feature'];
405
  $glue = $variables['glue'];
406
  $sortArray = $variables['sortArray'];
407
  $enclosingHtml = $variables['enclosingHtml'];
408

    
409
  $out = '<' . $enclosingHtml . ' class="feature-block-elements" id="' . $feature->representation_L10n . '">';
410

    
411
  if ($sortArray) {
412
    sort($elementArray);
413
  }
414

    
415
  $out .= '<span class="feature-block-element">' . join($elementArray, '<span class="feature-block-element">' . $glue . '</span>') . '</span>';
416

    
417
  $out .= '</' . $enclosingHtml . '>';
418
  return $out;
419
}
420

    
421

    
422
/**
423
 * Theme function to render CDM DescriptionElements of the type CategoricalData.
424
 *
425
 * @param array $variables
426
 *   An associative array containing:
427
 *  - element: the CategoricalData element
428
 * @return a html representation of the given CategoricalData element
429
 *
430
 * @ingroup themeable
431
 */
432
function theme_cdm_descriptionElement_CategoricalData($variables) {
433
  $element = $variables['element'];
434

    
435
  $state_data_strings = array();
436
  if (isset($element->stateData)) {
437
    foreach ($element->stateData as $stateData) {
438

    
439
      $state  = NULL;
440

    
441
      if(isset($stateData->state)){
442
        $state = cdm_term_representation($stateData->state);
443
      }
444

    
445
      if (isset($stateData->modifyingText_L10n)) {
446
        $state = ' ' . $stateData->modifyingText_L10n;
447
      }
448

    
449
      $modifiers_strings = cdm_modifers_representations($stateData);
450

    
451
      $state_data_strings[] = $state . ($modifiers_strings ? ' ' . $modifiers_strings : '');
452

    
453
    }
454
  }
455

    
456
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
457

    
458
  $out = '<span class="' . html_class_attribute_ref($element) . '">' . implode(', ', $state_data_strings) . '</span>';
459
  return $out . $footnote_key_list_str;
460
}
461

    
462
/**
463
 * Theme function to render CDM DescriptionElements of the type QuantitativeData.
464
 *
465
 * @param array $variables
466
 *   An associative array containing:
467
 *  - element: the QuantitativeData element
468
 * @return a html representation of the given QuantitativeData element
469
 *
470
 * @ingroup themeable
471
 */
472
function theme_cdm_descriptionElement_QuantitativeData($variables) {
473
  /*
474
   * - statisticalValues
475
   *   - value
476
   *   - modifiers
477
   *   - type
478
   * - unit->representation_L10n
479
   * - modifyingText
480
   * - modifiers
481
   * - sources
482
   */
483
  $element = $variables['element'];
484

    
485
  $out = '';
486

    
487
  $type_representation = NULL;
488
  $modifiers_strings = array();
489

    
490

    
491
  if (isset($element->statisticalValues)) {
492
    $value_array = array();
493
    foreach ($element->statisticalValues as $val) {
494
      if (isset($val->value)) {
495
        $value_array[] = $val->value;
496
      }
497
    }
498

    
499
    $out .= implode($value_array, ', ');
500
  }
501

    
502
  if (isset($element->unit)) {
503
    $out .= ' '. cdm_term_representation($element->unit);
504
  }
505

    
506
  if (isset($element->statisticalValues->modifyingText_L10n)) {
507
    $out .=  ' ' . $element->statisticalValues->modifyingText_L10n;
508
  }
509
  $modifiers_strings = cdm_modifers_representations($element->statisticalValues);
510
  $out .= ($modifiers_strings ? ' ' . cdm_modifers_representations($element->statisticalValues) : '');
511

    
512
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
513

    
514
  return $out . $footnote_key_list_str;
515

    
516
}
517

    
518
/**
519
 * Theme function to render CDM DescriptionElements of the type IndividualsAssociations.
520
 *
521
 * @param array $variables
522
 *   An associative array containing:
523
 *  - element: the IndividualsAssociations element
524
 * @return html representation of the given IndividualsAssociations element
525
 *
526
 * @ingroup themeable
527
 */
528
function theme_cdm_descriptionElement_IndividualsAssociation($variables) {
529

    
530
  $element = $variables['element'];
531

    
532
  $out = '';
533

    
534
  $render_array = compose_cdm_specimenOrObservation($element->associatedSpecimenOrObservation);
535

    
536
  if (isset($element->description_L10n)) {
537
    $out .=  ' ' . $element->description_L10n;
538
  }
539

    
540
  $out .= drupal_render($render_array);
541

    
542
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
543

    
544
  return $out . $footnote_key_list_str;
545

    
546

    
547
}
548

    
549
/**
550
 * Theme function to render CDM DescriptionElements of the type TaxonInteraction.
551
 *
552
 * @param array $variables
553
 *   An associative array containing:
554
 *  - element: the TaxonInteraction element
555
 * @return html representation of the given TaxonInteraction element
556
 *
557
 * @ingroup themeable
558
 */
559
function theme_cdm_descriptionElement_TaxonInteraction($variables) {
560

    
561
  $element = $variables['element'];
562

    
563
  $out = '';
564

    
565
  if (isset($element->description_L10n)) {
566
    $out .=  ' ' . $element->description_L10n;
567
  }
568

    
569
  if(isset($element->taxon2)){
570
    $out = theme('cdm_taxonName',
571
        array(
572
            'taxonName' => $element->taxon2->name,
573
            'nameLink' => url(path_to_taxon($element->taxon2->uuid))
574
        )
575
      );
576
  }
577

    
578
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
579

    
580
  return $out . $footnote_key_list_str;
581

    
582

    
583
}
584

    
585
/**
586
 * Returns HTML for citations textdata elements.
587
 *
588
 * TODO: assign a new name to the function? Because it is used for the citations
589
 * textdata elements and not for all text data description elements.
590
 *
591
 * @param array $variables
592
 *   An associative array containing:
593
 *   - element: The description element which contains the text information.
594
 *   - asListElement: A boolean which determines whether the citations should
595
 *     be rendered as a list or not.
596
 *   - feature_uuid
597
 *
598
 * @ingroup themeable
599
 */
600
function theme_cdm_descriptionElementTextData($variables) {
601

    
602
  $element = $variables['element'];
603
  $asListElement = $variables['asListElement'];
604
  $feature_uuid = $variables['feature_uuid'];
605

    
606
  $description = '';
607
  if (isset($element->multilanguageText_L10n->text)) {
608
    $description = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
609
  }
610
  $sourceRefs = '';
611
  $out = '';
612

    
613
  if (isset($element->sources) && is_array($element->sources) && count($element->sources) > 0) {
614
    foreach ($element->sources as $source) {
615
      $referenceCitation = theme('cdm_OriginalSource', array('source' => $source));
616
      if ($description && strlen($description) > 0 && $referenceCitation) {
617
        $sourceRefs .= ' (' . $referenceCitation . ')';
618
      }
619
      elseif ($referenceCitation) {
620
        $sourceRefs = $referenceCitation;
621
      }
622

    
623
      if (strlen($sourceRefs) > 0) {
624
        $sourceRefs = '<span class="sources">' . $sourceRefs . '</span>';
625
      }
626
      $name_used_in_source_link_to_show = '';
627
      // Do a link to name page.
628
      if (isset($source->nameUsedInSource->uuid) && isset($source->nameUsedInSource->titleCache)) {
629
        $name_used_in_source_link_to_show = l($source->nameUsedInSource->titleCache, path_to_name($source->nameUsedInSource->uuid), array(
630
          'attributes' => array(),
631
          'absolute' => TRUE,
632
          'html' => TRUE,
633
        ));
634
      }
635
      // Show a text without link.
636
      elseif (isset($source->nameUsedInSource->originalNameString) && strlen($source->nameUsedInSource->originalNameString) > 0) {
637
        $name_used_in_source_link_to_show = $source->nameUsedInSource->originalNameString;
638
      }
639

    
640
      if ($asListElement) {
641

    
642
       $out = '<li class="descriptionText DescriptionElement">';
643
        // Adding ":" if necessary.
644
        if (!empty($name_used_in_source_link_to_show)) {
645
          if ( (!empty($description)|| !empty($sourceRefs)) && $feature_uuid != UUID_CHROMOSOMES_NUMBERS) {
646
            $out .= $name_used_in_source_link_to_show . ': ';
647
          } else {
648
            $out .= $name_used_in_source_link_to_show . ' ';
649
          }
650
        }
651
        $out .= $description . $sourceRefs . theme(
652
            'cdm_annotations_as_footnotekeys',
653
            array('cdmBase_list' => $element,
654
              'footnote_list_key' => $feature_uuid)) . '</li>';
655
      }
656
      else {
657
        if ($name_used_in_source_link_to_show) {
658
          $name_used_in_source_link_to_show = ' (name in source: ' . $name_used_in_source_link_to_show . ')';
659
        }
660

    
661
        $out = '<span class="DescriptionElement DescriptionElement-' . $element->class . '">' . $description . $sourceRefs . $name_used_in_source_link_to_show . '</span>';
662
      }
663
    }
664
  }
665
  else {
666
    // If no sources, print the description.
667
    $out = $description;
668
  }
669

    
670
  // FIXME This will create footnotes for annotations and sources, sources are already rendered though
671
  // FIXME the footnoes are not shown in the page
672
  // FIXME RenderHints::getFootnoteListKey() ate not set here
673
  // to many problems, so the below line is diabled for now
674
  //$footnote_key_list_str = cdm_create_description_element_footnotes($element);
675
  // $out .= $footnote_key_list_str;
676

    
677
  return $out;
678
}
679

    
680
/**
681
 * Composes block of common names for the given DescriptionElements $elements which must be of the feature CommonName
682
 *
683
 * @parameter $elements
684
 *  an array of CDM DescriptionElements either of type CommonName or TextData
685
 * @parameter $feature
686
 *  the common feature of all $elements, must be CommonName
687
 *
688
 * @return
689
 *   A drupal render array
690
 *
691
 * @ingroup compose
692
 */
693
function compose_cdm_common_names($elements, $feature) {
694

    
695
  $common_name_out = '';
696
  $common_name_feature_elements = array();
697
  $textData_commonNames = array();
698

    
699
  $footnote_key_suggestion = 'common-names-feature-block';
700

    
701
  if (is_array($elements)) {
702
    foreach ($elements as $element) {
703

    
704
      if ($element->class == 'CommonTaxonName') {
705

    
706
        // common name without a language or area, should not happen but is possible
707
        $language_area_key = '';
708
        if (isset($element->language->representation_L10n)) {
709
          $language_area_key .= '<b>' . $element->language->representation_L10n . '</b>';
710
        }
711
        if(isset($element->area->titleCache) && strlen($element->area->titleCache) > 0){
712
          $language_area_key .= ($language_area_key ? ' '  : '') . '(' . $element->area->titleCache . ')';
713
        }
714

    
715
        if(isset($common_names[$language_area_key][$element->name])) {
716
          // same name already exists for language and areae combination, se we merge the description elements
717
          cdm_merge_description_elements($common_names[$language_area_key][$element->name], $element);
718
        } else{
719
          // otherwise add as new entry
720
          $common_names[$language_area_key][$element->name] = $element;
721
        }
722

    
723
      }
724
      elseif ($element->class == 'TextData') {
725
        $textData_commonNames[] = $element;
726
      }
727
    }
728
  }
729
  // Handling common names.
730
  if (isset($common_names) && count($common_names) > 0) {
731
    // Sorting the array based on the key (language, + area if set).
732
    // Comment @WA there are common names without a language, so this sorting
733
    // can give strange results.
734
    ksort($common_names);
735

    
736
    // loop over set of elements per language area
737
    foreach ($common_names as $language_area_key => $elements) {
738
      ksort($elements); // sort names alphabetically
739
      $per_language_area_out = array();
740
      // loop over set of individual elements
741
      foreach ($elements as $element) {
742
        if ($element->name) {
743
          $per_language_area_out[] = '<span class="' . html_class_attribute_ref($element) . '">'
744
          . $element->name . cdm_create_description_element_footnotes($element, ',', $footnote_key_suggestion) . '</span>';
745
        }
746
      } // End of loop over set of individual elements
747
      $common_name_feature_elements[] = ($language_area_key ? $language_area_key . ': ' : '' ) . join(',', $per_language_area_out);
748
    } // End of loop over set of elements per language area
749

    
750

    
751
    $common_name_out .= theme('cdm_feature_block_elements',
752
      array(
753
        'elementArray' => $common_name_feature_elements,
754
        'feature' => $feature,
755
        'glue' => ';',
756
        'sortArray' => FALSE,
757
        'enclosingHtml' => 'div',
758
      )
759
    );
760

    
761

    
762
  }
763

    
764
  // Handling commons names as text data.
765
  $text_data_out = array();
766

    
767
  foreach ($textData_commonNames as $text_data_element) {
768
    /* footnotes are not handled correctly in theme_cdm_descriptionElementTextData,
769
       need to set 'common-names-feature-block' as $footnote_key_suggestion */
770
    RenderHints::setFootnoteListKey($footnote_key_suggestion);
771
    $text_data_out[] = theme('cdm_descriptionElementTextData', array(
772
      'element' => $text_data_element,
773
      'asListElement' => TRUE,
774
      'feature_uuid' => $text_data_element->feature->uuid,
775
    ));
776
  }
777

    
778
  $common_name_out_text_data = theme(
779
        'cdm_feature_block_elements',
780
        array(
781
          'elementArray' => $text_data_out,
782
          'feature' => $feature
783
        )
784
      );
785

    
786

    
787
  $footnotes = theme('cdm_footnotes', array('footnoteListKey' => $footnote_key_suggestion)); // FIXME is this needed at all?
788
  $footnotes .= theme('cdm_annotation_footnotes', array('footnoteListKey' => $footnote_key_suggestion));
789

    
790
  return  markup_to_render_array(
791
    '<div class="common_names_as_common_names">' . $common_name_out . '</div>'
792
    .'<div class="common_names_as_text_data">' . $common_name_out_text_data . '</div>'
793
    .$footnotes
794
  );
795
}
796

    
797
/**
798
 * Return HTML for a list of description elements.
799
 *
800
 * Usually these are of a specific feature type.
801
 *
802
 * @param array $variables
803
 *   An associative array containing:
804
 *   - array of descriptionElements which belong to the same feature.
805
 *     These descriptions elements of a Description must be ordered by the chosen feature tree by
806
 *     calling the function _mergeFeatureTreeDescriptions().
807
 *     @see _mergeFeatureTreeDescriptions()
808
 *   - featureUuid: currently unused, according code disabled
809
 *   - taxon_uuid: only used for ordered distributions (will be removed!)
810
 *
811
 * @ingroup themeable
812
 */
813
function theme_cdm_descriptionElements($variables) {
814

    
815
  $descriptionElements = $variables['descriptionElements'];
816
  $feature = $variables['feature'];
817
  $taxon_uuid = $variables['taxon_uuid'];
818
  $outArray = array();
819

    
820
  /*
821
  $userDefined = mixed_variable_get(LAYOUT_SETTING_PREFIX . $feature_uuid, FEATURE_TREE_LAYOUT_DEFAULTS);
822
  if(variable_get('distribution_sort',
823
      'NO_SORT') != 'NO_SORT'){
824
      $glue = '';
825
      $enclosingTag = 'dl';
826
      $entryEnclosingTag = NULL;
827
  } else if($userDefined &&
828
      $userDefined['enabled']){
829
    $glue = $userDefined['glue'];
830
    $enclosingTag =  $userDefined['enclosingTag'];
831
    $entryEnclosingTag = $userDefined['entryEnclosingTag'];
832
  } else { // TODO remove once  LAYOUT_SETTING_PREFIX-{uuid} setting are configured to work for all portals(selenium test still missing!!!)
833
    $glue = ''; $enclosingTag = 'ul';
834
    $entryEnclosingTag = NULL ;
835
  }
836
  */
837

    
838

    
839
  if (variable_get('distribution_sort', 'NO_SORT') != 'NO_SORT') {
840
    $glue = '';
841
    $enclosingTag = 'dl';
842
  }
843
  else {
844
    $glue = '';
845
    $enclosingTag = 'ul';
846
  }
847

    
848
  $sortOutArray = FALSE;
849
  $distributionElements = array();
850
  $distribution_tree = null;
851

    
852
  RenderHints::pushToRenderStack('cdm_descriptionElements');
853

    
854
  if (is_array($descriptionElements)) {
855
    // --- normal description element arrays
856
    foreach ($descriptionElements as $descriptionElement) {
857

    
858
      // --- IMAGE_SOURCES --- //
859
      if ($descriptionElement->feature->uuid == UUID_IMAGE_SOURCES) {
860
        $image_sources[] = $descriptionElement;
861
      }
862
      // --- USE TEXTDATA --- //
863
      elseif ($descriptionElement->feature->uuid == UUID_USE) {
864
        // Do nothing to avoid rendering.
865
      } else {
866
        /* decide based on the description element class
867
         *
868
         * TODO provide api_hook as extension point for this
869
         */
870
        switch ($descriptionElement->class) {
871
          case 'TextData':
872
            $asListElement = TRUE;
873
            $outArray[] = theme('cdm_descriptionElementTextData', array(
874
              'element' => $descriptionElement,
875
              'asListElement' => $asListElement,
876
              'feature_uuid' => $descriptionElement->feature->uuid,
877
            ));
878
            break;
879
          case 'CategoricalData':
880
            $outArray[] = theme('cdm_descriptionElement_CategoricalData', array('element' => $descriptionElement));
881
            break;
882
          case 'QuantitativeData':
883
            $outArray[] = theme('cdm_descriptionElement_QuantitativeData', array('element' => $descriptionElement));
884
            break;
885
          case 'IndividualsAssociation':
886
            $outArray[] = theme('cdm_descriptionElement_IndividualsAssociation', array('element' => $descriptionElement));
887
            break;
888
          case 'TaxonInteraction':
889
            $outArray[] = theme('cdm_descriptionElement_TaxonInteraction', array('element' => $descriptionElement));
890
            break;
891
          case 'Uses':
892
          /* IGNORE Uses classes, these are handled completely in theme_cdm_UseDescription */
893
          break;
894
        default:
895
        $outArray[] = '<li>No method for rendering unknown description class: ' . $descriptionElement->class . '</li>';
896
      }
897
    }
898
    } // --- END loop over normal description element arrays
899

    
900
    // If feature = NAME USAGE sort the list of sources.
901
    // This is ONLY for FLORA MALESIANA and FLORE d'AFRIQUE CENTRALE.
902
    if ($descriptionElement->feature->uuid == UUID_NAME_USAGE) {
903
      sort($outArray);
904
    }
905

    
906
    if (isset($image_sources)) {
907
      $outArray[] = theme('cdm_description_element_image_source', array('image_sources' => $image_sources, 'asListElement' => TRUE));
908
    }
909
  } // END normal description element arrays
910

    
911

    
912
  $out = theme('cdm_feature_block_elements', array(
913
    'elementArray' => $outArray,
914
    'feature' => $feature,
915
    'glue' => $glue,
916
    'sortArray' => $sortOutArray,
917
    'enclosingHtml' => $enclosingTag,
918
  ));
919

    
920
  RenderHints::popFromRenderStack();
921
  return $out;
922
}
923

    
924
/**
925
 * @todo Please document this function.
926
 * @see http://drupal.org/node/1354
927
 */
928
function compare_image_sources($a, $b) {
929
  if ($a->multilanguageText_L10n->text == $b->multilanguageText_L10n->text) {
930
    return 0;
931
  }
932
  return ($a->multilanguageText_L10n->text < $b->multilanguageText_L10n->text) ? -1 : 1;
933
}
934

    
935
/**
936
 * @todo Please document this function.
937
 * @see http://drupal.org/node/1354
938
 */
939
function theme_cdm_description_element_image_source($variables) {
940
  $image_sources = $variables['image_sources'];
941
  $asListElement = $variables['asListElement'];
942
  $out = '';
943
  $separator = ',';
944
  RenderHints::pushToRenderStack('descriptionElementImageSource');
945
  RenderHints::setFootnoteListKey(UUID_IMAGE_SOURCES);
946

    
947
  // Sorting the image sources.
948
  usort($image_sources, "compare_image_sources");
949
  // Generate the footnotes.
950
  foreach ($image_sources as $image_source) {
951
    $footNoteKeys = cdm_annotations_as_footnotekeys($image_source);
952
    foreach ($image_source->sources as $source) {
953
      if (_is_original_source_type($source)) {
954
        $fn_key = FootnoteManager::addNewFootnote(original_source_footnote_list_key(), theme('cdm_OriginalSource', array(
955
          'source' => $source,
956
          'doLink' => FALSE,
957
        )));
958
        // Ensure uniqueness of the footnote keys.
959
        cdm_add_footnote_to_array($footNoteKeys, $fn_key);
960
      }
961
    }
962
    // Sort and render footnote keys.
963
    $footnote_key_list_str = '';
964
    asort($footNoteKeys);
965
    foreach ($footNoteKeys as $footNoteKey) {
966
      $footnote_key_list_str .= theme('cdm_footnote_key', array('footnoteKey' => $footNoteKey, 'separator' => ($footnote_key_list_str ? $separator : '')));
967
    }
968
    // Return value!
969
    $out .= '<span class="descriptionElement descriptionElement-' . $image_source->uuid . '">' . $image_source->multilanguageText_L10n->text . $footnote_key_list_str . '; </span>';
970
  }
971

    
972
  RenderHints::popFromRenderStack();
973
  return $out;
974
}
975

    
976
/**
977
 * @todo Please document this function.
978
 * @see http://drupal.org/node/1354
979
 */
980
function theme_cdm_descriptionElement_Distribution($variables) {
981
  $descriptionElements = $variables['descriptionElements'];
982
  $enclosingTag = $variables['enclosingTag'];
983
  if (!$enclosingTag) {
984
    $enclosingTag = "span";
985
  }
986

    
987
  $out = '';
988
  RenderHints::pushToRenderStack('descriptionElementDistribution');
989
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
990

    
991
  foreach ($descriptionElements as $descriptionElement) {
992

    
993
    $footnote_key_list_str = cdm_create_description_element_footnotes($descriptionElement);
994

    
995
    $out .= '<' . $enclosingTag . ' class="descriptionElement descriptionElement-' . $descriptionElement->uuid . '">'
996
        . $descriptionElement->area->representation_L10n . $footnote_key_list_str
997
        . ' </' . $enclosingTag . '>';
998
  }
999

    
1000
  RenderHints::popFromRenderStack();
1001
  return $out;
1002
}
1003

    
1004

    
1005
/**
1006
 * Compare two different footnotes objects.
1007
 *
1008
 * The comparison is based on the footnote key. The one which is
1009
 * displayed as footnote number.
1010
 *
1011
 * @param mixed $a
1012
 *   Footnote object $a.
1013
 * @param mixed $b
1014
 *   Footnote object $b.
1015
 */
1016
function footnotes_key_compare($a, $b) {
1017
  $res = 0;
1018
  if (empty($a) || empty($b)) {
1019
    return $res;
1020
  }
1021
  if ($a->keyStr < $b->keyStr) {
1022
    $res = -1;
1023
  }
1024
  elseif ($a->keyStr > $b->keyStr) {
1025
    $res = 1;
1026
  }
1027
  return $res;
1028
}
1029

    
1030
/**
1031
 * @todo Please document this function.
1032
 * @see http://drupal.org/node/1354
1033
 */
1034
function theme_cdm_description_ordered_distributions($variables) {
1035

    
1036
  $distribution_tree = $variables['distribution_tree'];
1037

    
1038
  // Returning NULL if there are no description elements.
1039
  if ($distribution_tree == null) {
1040
    return NULL;
1041
  }
1042

    
1043
  // Initialization of some variables.
1044
  $out = '';
1045
  $separator = ',';
1046
  RenderHints::pushToRenderStack('descriptionElementDistribution');
1047
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
1048

    
1049
  $ordered_areas = $distribution_tree;
1050
  if (isset($ordered_areas->rootElement->children)) {
1051
    $ordered_areas = $ordered_areas->rootElement->children;
1052
  }
1053

    
1054
  // Printing the distributions.
1055
  if (is_array($ordered_areas) && count($ordered_areas) > 0) {
1056
    foreach ($ordered_areas as $element_level1) {
1057
      // Level1.
1058
      $out .= '<dt>' . $element_level1->nodeId->representation_L10n . ':</dt> ';
1059
      $out .= '<dd>';
1060

    
1061
      // Level3.
1062
      foreach ($element_level1->children as $element_level3) {
1063
        $text_l3 = $element_level3->nodeId->representation_L10n;
1064
        $fnKeysLevel3Str = '';
1065
        $fnKeysLevel3 = cdm_annotations_as_footnotekeys($element_level3->data);
1066
        if (isset($element_level3->data[0])) {
1067
          foreach ($element_level3->data as $description_level3){
1068
            foreach ($description_level3->sources as $source) {
1069
              if (_is_original_source_type($source)) {
1070
                $fn_key3 = FootnoteManager::addNewFootnote(
1071
                  original_source_footnote_list_key(),
1072
                  theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)
1073
                ));
1074
                cdm_add_footnote_to_array($fnKeysLevel3, $fn_key3);
1075
              }
1076
            }
1077
          }
1078
        }
1079
        // Level4.
1080
        $l4_regions = array();
1081
        foreach ($element_level3->children as $element_level4) {
1082
          if (isset($element_level4->data[0])) {
1083
            $text_l4 = $element_level4->nodeId->representation_L10n;
1084
            $l4_regions[$element_level3->nodeId->representation_L10n] = array();
1085
            $fnKeysLevel4Str = '';
1086
            foreach($element_level4->data as $description_level4) {
1087
              $fnKeysLevel4 = cdm_annotations_as_footnotekeys($description_level4);
1088
              foreach ($description_level4->sources as $source) {
1089
                if (_is_original_source_type($source)) {
1090
                  $fn_key4 = FootnoteManager::addNewFootnote(
1091
                      original_source_footnote_list_key(),
1092
                      theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)));
1093
                  cdm_add_footnote_to_array($fnKeysLevel4, $fn_key4);
1094
                }
1095
              }
1096
              usort($fnKeysLevel4, "footnotes_key_compare");
1097
              if(!isset( $l4_regions[$text_l4])){
1098
                $l4_regions[$text_l4] = $fnKeysLevel4;
1099
              } else {
1100
                $l4_regions[$text_l4] = array_merge($l4_regions[$text_l4], $fnKeysLevel4);
1101
              }
1102
            }
1103
          }
1104
        }// Level4.
1105
        // Managing level3 and level4 for generating the right output.
1106
        usort($fnKeysLevel3, "footnotes_key_compare");
1107
        foreach ($fnKeysLevel3 as $key3) {
1108
          foreach ($l4_regions as $key4 => $value4) {
1109
            cdm_add_footnote_to_array($l4_regions[$key4], $key3);
1110
          }
1111
        }
1112
        if ($element_level3->numberOfChildren == 1 && $text_l3 == $element_level3->children[0]->nodeId->representation_L10n) {
1113
          // var_dump($element_level3->children[0]->data->area->representation_L10n);
1114
          $fnStr = '';
1115
          $region = array_pop($l4_regions);
1116
          foreach ($region as $key) {
1117
            $fnStr .= theme('cdm_footnote_key', array('footnoteKey' => $key, 'separator' => ($fnStr ? $separator : '')));
1118
          }
1119
          $out .= "$text_l3 $fnStr; ";
1120
          // Removing whitespaces when &fnStr is empty.
1121
          if (substr($out, -3) == ' ; ') {
1122
            $out = substr($out, 0, -3) . '; ';
1123
          }
1124
        } else {
1125
          $fnKeysLevel3Str = '';
1126
          foreach ($fnKeysLevel3 as $key) {
1127
            $fnKeysLevel3Str .= theme('cdm_footnote_key', array('footnoteKey' => $key, 'separator' => ($fnKeysLevel3Str ? $separator : '')));
1128
          }
1129
          $text_l4_aux = '';
1130
          foreach ($l4_regions as $key => $value) {
1131
            $fnKeysLevel4Str = '';
1132
            if (is_array($l4_regions[$key])) {
1133
              foreach ($l4_regions[$key] as $fnkey) {
1134
                $fnKeysLevel4Str .= theme('cdm_footnote_key', array('footnoteKey' => $fnkey, 'separator' => ($fnKeysLevel4Str ? $separator : '')));
1135
              }
1136
            }
1137
            // if ($key != $text_l3 || sizeof($l4_regions > 1)){
1138
            if ($key != $text_l3) {
1139
              $text_l4_aux .= "$key $fnKeysLevel4Str, ";
1140
            }
1141
          }
1142
          $text_l4_aux = substr($text_l4_aux, 0, -2);
1143

    
1144
          if (strlen($text_l4_aux) > 0) {
1145
            $out .= "$text_l3 $fnKeysLevel3Str ($text_l4_aux); ";
1146
          }
1147
          else {
1148
            $out .= "$text_l3 $fnKeysLevel3Str; ";
1149
          }
1150
        }
1151
      }// Level3.
1152
      $out = substr($out, 0, -2);
1153
      $out .= '.</dd>';
1154
    }// Level1.
1155
  }
1156
  RenderHints::popFromRenderStack();
1157
  return $out;
1158
}
1159

    
1160

    
1161
/*
1162
function theme_cdm_descriptionElement_Distribution($descriptionElements){ $out
1163
  = ''; $separator = ',';
1164
  RenderHints::pushToRenderStack('descriptionElementDistribution');
1165
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
1166
  foreach($descriptionElements as $descriptionElement){ // annotations as
1167
  footnotes $annotationFootnoteKeys = theme('cdm_annotations_as_footnotekeys',
1168
  $descriptionElement); // source references as footnotes
1169
  $sourcesFootnoteKeyList = ''; foreach($descriptionElement->sources as
1170
  $source){ if(_is_original_source_type($source)){ $_fkey =
1171
  FootnoteManager::addNewFootnote(UUID_DISTRIBUTION,
1172
  theme('cdm_OriginalSource', $source, FALSE));
1173
  $sourcesFootnoteKeyList .= theme('cdm_footnote_key', $_fkey,
1174
  UUID_DISTRIBUTION, ($sourcesFootnoteKeyList ? $separator : '')); } }
1175
  if($annotationFootnoteKeys && $sourcesFootnoteKeyList){
1176
  $annotationFootnoteKeys .= $separator; } $out .=
1177
  $descriptionElement->area->representation_L10n . $annotationFootnoteKeys .
1178
  $sourcesFootnoteKeyList . ' '; } $out = substr($out, 0,
1179
  strlen($out)-strlen($separator) ); RenderHints::popFromRenderStack(); return
1180
  $out; }
1181
*/
1182

    
1183
/**
1184
 * Returns a list of a specific type of IdentificationKeys.
1185
 *
1186
 * The list can be restricteded by a taxon.
1187
 *
1188
 * @param string $type
1189
 *   The simple name of the cdm class implementing the interface
1190
 *   IdentificationKey, valid values are:
1191
 *   PolytomousKey, MediaKey, MultiAccessKey.
1192
 * @param string $taxonUuid
1193
 *   If given this parameter restrict the listed keys to those which have
1194
 *   the taxon identified be this uuid in scope.
1195
 *
1196
 * @return array
1197
 *   List with identification keys.
1198
 */
1199
function _list_IdentificationKeys($type, $taxonUuid = NULL, $pageSize = NULL, $pageNumber = NULL) {
1200
  if (!$type) {
1201
    drupal_set_message(t('Type parameter is missing'), 'error');
1202
    return;
1203
  }
1204
  $cdm_ws_pasepath = NULL;
1205
  switch ($type) {
1206
    case "PolytomousKey":
1207
      $cdm_ws_pasepath = CDM_WS_POLYTOMOUSKEY;
1208
      break;
1209

    
1210
    case "MediaKey":
1211
      $cdm_ws_pasepath = CDM_WS_MEDIAKEY;
1212
      break;
1213

    
1214
    case "MultiAccessKey":
1215
      $cdm_ws_pasepath = CDM_WS_MULTIACCESSKEY;
1216
      break;
1217

    
1218
  }
1219

    
1220
  if (!$cdm_ws_pasepath) {
1221
    drupal_set_message(t('Type parameter is not valid: ') . $type, 'error');
1222
  }
1223

    
1224
  $queryParameters = '';
1225
  if (is_numeric($pageSize)) {
1226
    $queryParameters = "pageSize=" . $pageSize;
1227
  }
1228
  else {
1229
    $queryParameters = "pageSize=0";
1230
  }
1231

    
1232
  if (is_numeric($pageNumber)) {
1233
    $queryParameters = "pageNumber=" . $pageNumber;
1234
  }
1235
  else {
1236
    $queryParameters = "pageNumber=0";
1237
  }
1238
  $queryParameters = NULL;
1239
  if ($taxonUuid) {
1240
    $queryParameters = "findByTaxonomicScope=$taxonUuid";
1241
  }
1242
  $pager = cdm_ws_get($cdm_ws_pasepath, NULL, $queryParameters);
1243

    
1244
  if (!$pager || $pager->count == 0) {
1245
    return array();
1246
  }
1247
  return $pager->records;
1248
}
1249

    
1250
/**
1251
 * @todo Please document this function.
1252
 * @see http://drupal.org/node/1354
1253
 */
1254
function theme_cdm_IdentificationKey($variables) {
1255
  $out = '';
1256
  $identificationKey = $variables['identificationKey'];
1257
  $doLinkToKeyPage = $variables['doLinkToKeyPage'];
1258
  $showIdentificationKeyTitle = $variables['showIdentificationKeyTitle'];
1259
  $parentRenderPath = RenderHints::getRenderPath();
1260
  RenderHints::pushToRenderStack("IdentificationKey");
1261

    
1262
  if ($showIdentificationKeyTitle) {
1263
    if ($doLinkToKeyPage) {
1264
      $out = l($identificationKey->titleCache, path_to_key($identificationKey->class, $identificationKey->uuid));
1265
    }
1266
    else {
1267
      $out = $identificationKey->titleCache;
1268
    }
1269
  }
1270
  if (isset($identificationKey->sources) && is_array($identificationKey->sources)) {
1271
    // order and display sources.
1272
    $sources = oder_sources($identificationKey->sources, TRUE);
1273
    $out .= '<div class="sources">';
1274
    $out .=  implode('', $sources);
1275
    $out .= '</div>';
1276
  }
1277
  // Display annotations.
1278
  $out .= theme('cdm_annotations', array('annotations' => cdm_ws_getAnnotationsFor($identificationKey), 'enclosingTag' => 'div'));
1279
  RenderHints::popFromRenderStack();
1280
  return $out;
1281
}
1282

    
1283
/**
1284
 * @todo Please document this function.
1285
 * @see http://drupal.org/node/1354
1286
 */
1287
function theme_cdm_polytomousKey($variables) {
1288
  $polytomousKey = $variables['polytomousKey'];
1289

    
1290
  // TODO settings needed.
1291
  // @see http://en.wikipedia.org/wiki/Single_access_key#Presentation_styles
1292
  // @see http://dev.e-taxonomy.eu/trac/ticket/2152
1293
  $keyStyle = "linkedStyle";
1294

    
1295
  RenderHints::pushToRenderStack("polytomousKey");
1296
  // Key nodes in linked style.
1297
  $out = '<table class="polytomousKey polytomousKey_' . $keyStyle . '">';
1298
  $out .= theme('cdm_polytomousKey_' . $keyStyle . '_subgraph', array('polytomousKeyNode' => $polytomousKey->root));
1299
  $out .= '</table>';
1300
  RenderHints::popFromRenderStack();
1301
  return $out;
1302
}
1303

    
1304
/**
1305
 * @todo Please document this function.
1306
 * @see http://drupal.org/node/1354
1307
 */
1308
function theme_cdm_polytomousKey_linkedStyle_subgraph($variables) {
1309
  $polytomousKeyNode = $variables['polytomousKeyNode'];
1310
  static $statementCountCharacter = '\'';
1311
  $out = "";
1312

    
1313
  if (is_array($polytomousKeyNode->children)) {
1314
    $childIndex = 0;
1315

    
1316
    // Render edges of the current node.
1317
    foreach ($polytomousKeyNode->children as &$child) {
1318

    
1319
      if (!isset($child->statement) && isset($child->taxon->uuid)) {
1320
        // Skip node with empty statements (see below for explanation: "Special
1321
        // case").
1322
        // this skipping here happens always in the next deeper level of iteration
1323
        // the check below is node on the level above
1324
        continue;
1325
      }
1326

    
1327
      /*
1328
       * Special case: Child nodes with empty statements but taxa as leaf are to
1329
       * treated as if all those taxa where direct children of the source node.
1330
       */
1331
      $islinkToManyTaxa = !isset($child->children[0]->statement) && isset($child->children[0]->taxon->uuid);
1332
      $islinkToTaxon = isset($child->taxon->uuid);
1333
      $islinkToSubKey = isset($child->subkey->uuid);
1334
      $islinkToOtherNode = isset($child->otherNode);
1335
      // Either NULL or 0.
1336
      $islinkToNode = $child->nodeNumber && !$islinkToManyTaxa && !$islinkToOtherNode;
1337
      $hasQuestion = !empty($polytomousKeyNode->question->label_l10n);
1338
      $hasFeature = isset($polytomousKeyNode->feature);
1339

    
1340
      // $indentEdge = $hasQuestion && $childIndex > 0;
1341
      // Question.
1342
      if ($hasQuestion && $childIndex == 0) {
1343
        // Place question, as extra table row.
1344
        $out .= '<tr class="question new_section">';
1345
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber) . "</td>";
1346
        $out .= '<td class="question">' . $polytomousKeyNode->question->label_l10n . '</td>';
1347
        $out .= '</tr>';
1348
      }
1349

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

    
1352
      if ($hasQuestion) {
1353
        $out .= '<td class="nodeNumber"></td>';
1354
      }
1355
      else {
1356
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber . str_pad("", $childIndex, $statementCountCharacter)) . "</td>";
1357
      }
1358

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

    
1361
      // Feature.
1362
      if ($hasFeature) {
1363
        $out .= $polytomousKeyNode->feature->representation_L10n . ": ";
1364
      }
1365

    
1366
      // Statement.
1367
      $out .= $child->statement->label_l10n;
1368

    
1369
      // --- Links to nodes taxa and subkeys.
1370
      $out .= '<div class="nodeLink">';
1371

    
1372
      // Link to a PolytomousKeyNode.
1373
      if ($islinkToNode) {
1374
        $out .= '<div class="nodeLinkToNode">';
1375
        if (isset($child->modifyingText)) {
1376
          $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $child->modifyingText));
1377
        }
1378
        $out .= l($child->nodeNumber, request_path(), array(
1379
          'attributes' => NULL,
1380
          'query' => NULL,
1381
          'fragment' => $child->uuid,
1382
        )) . '</div>';
1383
      }
1384

    
1385
      // Link to a PolytomousKeyNode.
1386
      if ($islinkToOtherNode) {
1387
        $out .= '<div class="nodeLinkToOtherNode">';
1388
        if (isset($child->modifyingText)) {
1389
          $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $child->modifyingText));
1390
        }
1391
        $out .= l($child->otherNode->nodeNumber, $_REQUEST["q"], array(
1392
          'attributes' => NULL,
1393
          'query' => NULL,
1394
          'fragment' => $child->otherNode->uuid,
1395
        )) . '</div>';
1396
      }
1397

    
1398
      // Link to one or many taxa.
1399
      if ($islinkToTaxon || $islinkToManyTaxa) {
1400

    
1401
        if ($islinkToManyTaxa) {
1402
          $taxonChildren = $child->children;
1403
        }
1404
        else {
1405
          $taxonChildren = array(
1406
            $child,
1407
          );
1408
        }
1409

    
1410
        foreach ($taxonChildren as $taxonChild) {
1411
          // TODO many taxa $child->children->taxon.
1412
          $out .= '<div class="nodeLinkToTaxon">';
1413
          if (isset($taxonChild->modifyingText)) {
1414
            $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $taxonChild->modifyingText));
1415
          }
1416
          $out .= theme("cdm_taxonName", array('taxonName' => $taxonChild->taxon->name, 'nameLink' => url(path_to_taxon($taxonChild->taxon->uuid))));
1417
          $out .= '</div>';
1418
        }
1419

    
1420
        // Link to a subkey.
1421
        if ($islinkToSubKey) {
1422
          $out .= '<div class="nodeLinkToSubkey">' . theme('cdm_IdentificationKey', array('identificationKey' => $child->subkey)) . '</div>';
1423
        }
1424
      }
1425

    
1426
      $out .= '</div>'; // End node link.
1427
      $out .= '</td>'; // End edge.
1428
      $out .= '</tr>';
1429

    
1430
      $childIndex++;
1431
    }
1432

    
1433
    // Recurse into child nodes.
1434
    foreach ($polytomousKeyNode->children as &$child) {
1435
      $out .= theme('cdm_polytomousKey_linkedStyle_subgraph', array('polytomousKeyNode' => $child));
1436
    }
1437
  }
1438

    
1439
  return $out;
1440
}
1441

    
1442
/**
1443
 * @todo Please document this function.
1444
 * @see http://drupal.org/node/1354
1445
 */
1446
function theme_cdm_poytomousKeyNode_modifyingText($variables) {
1447
  $out = '';
1448
  $modifyingText = $variables['modifyingText'];
1449
  if (is_object($modifyingText)) {
1450
    $i = 0;
1451
    foreach (get_object_vars($modifyingText) as $lang => $languageString) {
1452
      $out .= ($i++ > 0 ? ', ' : '') . '<span class="modifyingText">' . $languageString->text . '</span> ';
1453
    }
1454
  }
1455
  return $out;
1456
}
1457

    
1458
/**
1459
 * Returns HTML for a list of a specific type of IdentificationKeys.
1460
 *
1461
 * The list can be restricteded by a taxon.
1462
 *
1463
 * @param array $variables
1464
 *   An associative array containing:
1465
 *   - type: The simple name of the cdm class implementing the interface
1466
 *     IdentificationKey, valid values are:
1467
 *     PolytomousKey, MediaKey, MultiAccessKey
1468
 *   - taxonUuid: If given, this parameter restrict the listed keys to those
1469
 *     which have the taxon identified be this uuid in scope.
1470
 *
1471
 * @ingroup themeable
1472
 */
1473
function theme_cdm_list_IdentificationKeys($variables) {
1474
  $type = $variables['type'];
1475
  $taxonUuid = $variables['taxonUuid'];
1476
  $keyList = _list_IdentificationKeys($type, $taxonUuid);
1477
  if (!$keyList || count($keyList) == 0) {
1478
    return;
1479
  }
1480

    
1481
  RenderHints::pushToRenderStack('list_IdentificationKeys');
1482
  $out = '<ul>';
1483
  foreach ($keyList as $key) {
1484
    $out .= '<li>';
1485
    $out .= theme('cdm_IdentificationKey', array('identificationKey' => $key));
1486
    $out .= '</li>';
1487
  }
1488
  $out .= '</ul>';
1489
  $out .= theme("cdm_annotation_footnotes", array('footnoteListKey' => RenderHints::getRenderPath()));
1490
  RenderHints::popFromRenderStack();
1491

    
1492
  return $out;
1493
}
1494

    
1495
/**
1496
 * @todo Please document this function.
1497
 * @see http://drupal.org/node/1354
1498
 */
1499
function theme_cdm_block_IdentificationKeys($variables) {
1500
  $taxonUuid = $variables['taxonUuid'];
1501
  static $types = array(
1502
    "PolytomousKey" => "Polytomous",
1503
    "MediaKey" => "Media",
1504
    "MultiAccessKey" => "Multiaccess",
1505
  );
1506
  RenderHints::pushToRenderStack('block_IdentificationKeys');
1507
  $out = '';
1508
  foreach ($types as $type => $label) {
1509
    $keylist = theme('cdm_list_IdentificationKeys', array('type' => $type, 'taxonUuid' => $taxonUuid));
1510
    if (!$keylist) {
1511
      continue;
1512
    }
1513
    $out .= '<div class="' . $type . '">';
1514
    $out .= '<h3>' . t($label) . "</h3>";
1515
    $out .= $keylist;
1516
    $out .= '</div>';
1517
  }
1518
  RenderHints::popFromRenderStack();
1519
  return $out;
1520
}
1521

    
1522
/**
1523
 * This theming function formats the use description and use record list for
1524
 * these descriptions.
1525
 *
1526
 * @see http://drupal.org/node/1354
1527
 */
1528
function theme_cdm_UseDescription($variables) {
1529
  $descriptions = $variables['description'];
1530
  $taxonUuid = $variables['taxonUuid'];
1531
  $out = '<div id="content"><ul id="Description" class ="description">';
1532
  if ($descriptions == NULL) {
1533
    return;
1534
  }
1535
  $descriptionSynonyms = '';
1536
  $descriptionOut = '';
1537
  $synonymOut = '';
1538
  $currentTaxon = cdm_ws_get(CDM_WS_PORTAL_TAXON, $taxonUuid);
1539

    
1540
  foreach ($descriptions as $description) {
1541
    $useSummary = '';
1542
    foreach ($description->elements as $element) {
1543

    
1544
      if ($element->feature->uuid == UUID_USE && !(strlen($useSummary) > 0) && isset($element->multilanguageText_L10n)) {
1545
        $useSummary = $element->multilanguageText_L10n->text;
1546
      }
1547
    }
1548
    // uses will be ordered by source
1549
    foreach ($description->sources as $source) {
1550
      $is_about_current_taxon = FALSE;
1551
      $originalTaxonUsedInSource = NULL;
1552
      $originalTaxonPager = NULL;
1553
      if ($source->originalNameString) {
1554
        $request_params = array();
1555
        $request_params['query'] = $source->originalNameString;
1556
        $request_params['matchMode'] = "EXACT";
1557
        $originalTaxonPager = cdm_ws_get(CDM_WS_PORTAL_NAME_FINDBYNAME, NULL, queryString($request_params));
1558
        if ($originalTaxonPager->count > 0) {
1559
          $originalTaxonUsedInSource = $originalTaxonPager->records[0];
1560
        }
1561
        else {
1562
          $originalTaxonUsedInSource = $currentTaxon->name;
1563
        }
1564
      }
1565
      else {
1566
        $originalTaxonUsedInSource = $currentTaxon->name;
1567
      }
1568

    
1569
      $is_about_current_taxon = $currentTaxon->name->uuid == $originalTaxonUsedInSource->uuid;
1570

    
1571
      if (!$is_about_current_taxon) {
1572
        $descriptionOut .= '<li class="descriptionText DescriptionElement">';
1573
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1574
          'absolute' => TRUE,
1575
          'html' => TRUE,
1576
        ));
1577
        $descriptionOut .= $name_used_in_source_link_to_show_use . ': ';
1578
        $descriptionOut .= $useSummary;
1579
        foreach ($description->sources as $source) {
1580
          $descriptionOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1581
        }
1582
        $hasUseRecords = FALSE;
1583
        $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>';
1584
        foreach ($description->elements as $descriptionElement) {
1585
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1586
            $hasUseRecords = TRUE;
1587
            // FIXME localization hardcoded to English
1588
            $useRecordTags = explode(';', $descriptionElement->modifyingText_l10n);
1589
            $descriptionUseRecordOut .= '<tr>';
1590
            $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>';
1591
            $descriptionUseRecordOut .= '</tr>';
1592
          }
1593
        }
1594
        $descriptionUseRecordOut .= '</table></div>';
1595
        if ($hasUseRecords) {
1596
          $descriptionOut .= $descriptionUseRecordOut . '</li>';
1597
        }
1598
      }
1599
      else {
1600
        // TODO +/- duplicate of above, unify this code
1601
        $synonymOut .= '<li class="descriptionText DescriptionElement">';
1602
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1603
          'absolute' => TRUE,
1604
          'html' => TRUE,
1605
        ));
1606

    
1607
        $synonymOut .= $name_used_in_source_link_to_show_use . ': ';
1608
        $synonymOut .= $useSummary;
1609
        foreach ($description->sources as $source) {
1610
          $synonymOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1611
        }
1612

    
1613
        $hasUseRecords = FALSE;
1614
        $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>';
1615
        foreach ($description->elements as $descriptionElement) {
1616
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1617
            $hasUseRecords = TRUE;
1618
            $useRecordTags = explode(';', $descriptionElement->modifyingText_l10n);
1619
            $useRecordTableOut .= '<tr>';
1620
            $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>';
1621
            $useRecordTableOut .= '</tr>';
1622
          }
1623
        }
1624
        $useRecordTableOut .= '</table></div>';
1625
        if ($hasUseRecords) {
1626
          $synonymOut .= $useRecordTableOut . '</li>';
1627
        }
1628
      }
1629

    
1630
      // }
1631
    }
1632
  }
1633
  $out .= $descriptionOut . $synonymOut;
1634
  $out .= "</ul></div>";
1635
  return $out;
1636
}
1637

    
1638

    
1639
/**
1640
 * The theming function for a block of Uses Descriptions for a given taxon.
1641
 *
1642
 * The Uses block has been removed from the code but the according theme function
1643
 * is kept for compatibility reasons with existing code regarding palmweb.
1644
 *
1645
 */
1646
function theme_cdm_block_Uses($variables) {
1647
  $taxonUuid = $variables['taxonUuid'];
1648
  RenderHints::pushToRenderStack('block_Uses');
1649

    
1650
  if ($taxonUuid == NULL) {
1651
    return;
1652
  }
1653
  $out = '';
1654
  $markerTypes = array();
1655
  $markerTypes['markerTypes'] = UUID_MARKERTYPE_USE;
1656
  $useDescriptions = cdm_ws_get(CDM_WS_PORTAL_TAXON_DESCRIPTIONS, $taxonUuid, queryString($markerTypes));
1657
  if (!empty($useDescriptions)) {
1658
    // FIXME use theme_block instaed of hardcoding the block html here !!!!
1659
    $out .= '<div id="block-cdm_dataportal-feature-description" class="clear-block block block-cdm_dataportal-feature"><H2><a name="userecords"> </a> Uses </H2>';
1660
    $formatUseDescriptions = theme('cdm_UseDescription', array('description' => $useDescriptions, 'taxonUuid' => $taxonUuid));
1661

    
1662
    $out .= $formatUseDescriptions;
1663
    $out .= "</div>";
1664
  }
1665

    
1666
  return $out;
1667
}
(3-3/10)