Project

General

Profile

Download (58.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
 * 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
    // $$descriptionElements['TextData'] is added to to the feature node in merged_taxon_feature_tree()
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 compose_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 .= compose_cdm_feature_block_elements(
273
        $text_data_out_array,
274
        $feature,
275
        $text_data_glue,
276
        $text_data_sortOutArray,
277
        $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 .= compose_cdm_feature_block_elements(
315
        $dto_out_array,
316
        $feature,
317
        $distribution_glue,
318
        $distribution_sortOutArray,
319
        $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 .= compose_cdm_feature_block_elements(
326
        $text_data_out_array,
327
        $feature,
328
        $text_data_glue,
329
        $text_data_sortOutArray,
330
        $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 $elements.
388
 *
389
 * Joins the texts in $elements and encloses with a HTML tag.
390
 *
391
 * @param  $elements
392
 * @param  feature:
393
 *  The feature to which the elements given in $elements are belonging to.
394
 * @param  glue:
395
 *  Defaults to empty string.
396
 * @param $sort
397
 *   Boolean Whether to sort the $elements alphabetically, default is FALSE
398
 * @param  $enclosing_tag
399
 *
400
 * @ingroup compose
401
 */
402
function compose_cdm_feature_block_elements($elements, $feature, $glue = '', $sort = FALSE, $enclosing_tag = 'ul') {
403

    
404
  $feature_block_settings = get_feature_block_settings($feature->uuid);
405
  if($feature_block_settings['as_list']){
406
    $enclosing_tag = $feature_block_settings['as_list'];
407
  }
408

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

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

    
415
  //TODO it would be nice if any element would get "feature-block-element" as additional class attribute
416
  //     this will become possible once all $elemets are real Drupal render arrays
417
  $out .= join($elements, $glue) ;
418

    
419
  $out .= '</' . $enclosing_tag . '>';
420
  return $out;
421
}
422

    
423

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

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

    
441
      $state  = NULL;
442

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

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

    
451
      $modifiers_strings = cdm_modifers_representations($stateData);
452

    
453
      $state_data_strings[] = $state . ($modifiers_strings ? ' ' . $modifiers_strings : '');
454

    
455
    }
456
  }
457

    
458
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
459

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

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

    
487
  $out = '';
488

    
489
  $type_representation = NULL;
490
  $modifiers_strings = array();
491

    
492

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

    
501
    $out .= implode($value_array, ', ');
502
  }
503

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

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

    
514
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
515

    
516
  return $out . $footnote_key_list_str;
517

    
518
}
519

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

    
532
  $element = $variables['element'];
533

    
534
  $out = '';
535

    
536
  $render_array = compose_cdm_specimenOrObservation($element->associatedSpecimenOrObservation);
537

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

    
542
  $out .= drupal_render($render_array);
543

    
544
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
545

    
546
  return $out . $footnote_key_list_str;
547

    
548

    
549
}
550

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

    
563
  $element = $variables['element'];
564

    
565
  $out = '';
566

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

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

    
580
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
581

    
582
  return $out . $footnote_key_list_str;
583

    
584

    
585
}
586

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

    
604
  $element = $variables['element'];
605
  $feature_uuid = $variables['feature_uuid'];
606
  $asListElement = $variables['asListElement']; // TODo remove and replace by $feature_block_settings['as_list']
607

    
608
  $sourceRefs = '';
609
  $out = '';
610

    
611
  // FIXME $feature_block_settings should be passed as parameter!!!!!
612
  $feature_block_settings = get_feature_block_settings($feature_uuid);
613

    
614
  // FIXME remove this hack ---------------------------
615
  $default_theme = variable_get('theme_default', NULL);
616
  if($default_theme == 'garland_cichorieae' || $default_theme == 'cyprus'
617
    || $default_theme == 'flore_afrique_centrale' || $default_theme == 'flora_malesiana' || $default_theme == 'flore_gabon' ){
618
    $asListElement = $feature_block_settings['as_list'] == 'ul';
619
  }
620

    
621
  // --------------------------------------------------
622

    
623
  $description = '';
624
  if (isset($element->multilanguageText_L10n->text)) {
625
    $description = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
626
  }
627

    
628
  // annotations footnotes.
629
  $annotation_fkeys = theme('cdm_annotations_as_footnotekeys',
630
    array(
631
      'cdmBase_list' => $element,
632
      'footnote_list_key' => $feature_uuid,
633
    )
634
  );
635

    
636
  // original sources
637
  if (isset($element->sources) && is_array($element->sources) && count($element->sources) > 0) {
638
    foreach ($element->sources as $source) {
639

    
640
      // ---------------------------------------------------------------------------
641
      // CUSTOM CODE (2) from cichorieae theme,
642
      // use nomref web service to combine reference with microreference, other way to combine these?
643
      // is this a general case for all features? >>> DISCUSS with Andreas M. FIXME
644
      if ($feature_uuid == UUID_CITATION) {
645
        $referenceCitation = cdm_ws_get(
646
          CDM_WS_NOMENCLATURAL_REFERENCE_CITATION,
647
          array($source->citation->uuid),
648
          "microReference=" . urlencode($source->citationMicroReference
649
          ));
650
        $referenceCitation = $referenceCitation->String;
651

    
652
      // END CUSTOM CODE (2)
653
      // ---------------------------------------------------------------------------
654
      } else {
655
        $referenceCitation = theme('cdm_OriginalSource', array('source' => $source));
656
      }
657

    
658
      if ($description && strlen($description) > 0 && $referenceCitation) {
659
        $sourceRefs .= ' (' . $referenceCitation . ')';
660
      }
661
      elseif ($referenceCitation) {
662
        $sourceRefs = $referenceCitation;
663
      }
664

    
665
      if (strlen($sourceRefs) > 0) {
666
        $sourceRefs = '<span class="sources">' . $sourceRefs . '</span>';
667
      }
668

    
669
      // link the nameUsedInSource to the according name page
670
      $name_used_in_source_link_to_show = '';
671
      // Do a link to name page.
672
      if (isset($source->nameUsedInSource->uuid) && isset($source->nameUsedInSource->titleCache)) {
673
        // it is a DescriptionElementSource
674
        if($feature_block_settings['link_to_name_used_in_source']){
675
          $name_used_in_source_link_to_show = l(
676
            $source->nameUsedInSource->titleCache,
677
            path_to_name($source->nameUsedInSource->uuid),
678
            array(
679
            'attributes' => array(),
680
            'absolute' => TRUE,
681
            'html' => TRUE,
682
          ));
683

    
684
        } else {
685
          $name_used_in_source_link_to_show = $source->nameUsedInSource->titleCache;
686
        }
687
      }
688
      else if (isset($source->nameUsedInSource->originalNameString) && strlen($source->nameUsedInSource->originalNameString) > 0) {
689
        // TODO does this make sense? is $source->nameUsedInSource->originalNameString different from $source->nameUsedInSource->titleCache ?
690
        // it is NOT a DescriptionElementSource
691
        // Show a text without link.
692
        $name_used_in_source_link_to_show = $source->nameUsedInSource->originalNameString;
693
      }
694

    
695
      // final composition of the TextData element
696
      // FIXME this should move below after the end if (isset($element->sources) {...} and will replace the else
697
      if ($asListElement) {
698

    
699
       $out = '<li class="descriptionText DescriptionElement">';
700
        // Adding ":" if necessary.
701
        if (!empty($name_used_in_source_link_to_show)) {
702
          if ( (!empty($description)|| !empty($sourceRefs)) && $feature_uuid != UUID_CHROMOSOMES_NUMBERS) {
703
            $out .= $name_used_in_source_link_to_show . ': ';
704
          } else {
705
            $out .= $name_used_in_source_link_to_show . ' ';
706
          }
707
        }
708
        $out .= $description . $sourceRefs . $annotation_fkeys . '</li>';
709
      }
710
      else {
711
        if ($name_used_in_source_link_to_show) {
712
          $name_used_in_source_link_to_show = ' (name in source: ' . $name_used_in_source_link_to_show . ')';
713
        }
714

    
715
        $out = '<span class="DescriptionElement DescriptionElement-'. $element->class . '
716
        ' .  html_class_attribute_ref($element)  . '">'
717
          . $description . $sourceRefs . $name_used_in_source_link_to_show . $annotation_fkeys . '</span>';
718
      }
719
    }
720
  } // END of if (isset($element->sources)
721

    
722
  else {
723
    // If no sources, print the description.
724
    $out = '<span class="' . html_class_attribute_ref($element) . '"> '
725
      . $description . $annotation_fkeys . '</span>';
726
  }
727

    
728
  return $out;
729
}
730

    
731
/**
732
 * Composes block of common names for the given DescriptionElements $elements which must be of the feature CommonName
733
 *
734
 * @parameter $elements
735
 *  an array of CDM DescriptionElements either of type CommonName or TextData
736
 * @parameter $feature
737
 *  the common feature of all $elements, must be CommonName
738
 *
739
 * @return
740
 *   A drupal render array
741
 *
742
 * @ingroup compose
743
 */
744
function compose_cdm_common_names($elements, $feature) {
745

    
746
  $common_name_out = '';
747
  $common_name_feature_elements = array();
748
  $textData_commonNames = array();
749

    
750
  $footnote_key_suggestion = 'common-names-feature-block';
751

    
752
  if (is_array($elements)) {
753
    foreach ($elements as $element) {
754

    
755
      if ($element->class == 'CommonTaxonName') {
756

    
757
        // common name without a language or area, should not happen but is possible
758
        $language_area_key = '';
759
        if (isset($element->language->representation_L10n)) {
760
          $language_area_key .= '<b>' . $element->language->representation_L10n . '</b>';
761
        }
762
        if(isset($element->area->titleCache) && strlen($element->area->titleCache) > 0){
763
          $language_area_key .= ($language_area_key ? ' '  : '') . '(' . $element->area->titleCache . ')';
764
        }
765

    
766
        if(isset($common_names[$language_area_key][$element->name])) {
767
          // same name already exists for language and areae combination, se we merge the description elements
768
          cdm_merge_description_elements($common_names[$language_area_key][$element->name], $element);
769
        } else{
770
          // otherwise add as new entry
771
          $common_names[$language_area_key][$element->name] = $element;
772
        }
773

    
774
      }
775
      elseif ($element->class == 'TextData') {
776
        $textData_commonNames[] = $element;
777
      }
778
    }
779
  }
780
  // Handling common names.
781
  if (isset($common_names) && count($common_names) > 0) {
782
    // Sorting the array based on the key (language, + area if set).
783
    // Comment @WA there are common names without a language, so this sorting
784
    // can give strange results.
785
    ksort($common_names);
786

    
787
    // loop over set of elements per language area
788
    foreach ($common_names as $language_area_key => $elements) {
789
      ksort($elements); // sort names alphabetically
790
      $per_language_area_out = array();
791
      // loop over set of individual elements
792
      foreach ($elements as $element) {
793
        if ($element->name) {
794
          $per_language_area_out[] = '<span class="' . html_class_attribute_ref($element) . '">'
795
          . $element->name . cdm_create_description_element_footnotes($element, ',', $footnote_key_suggestion) . '</span>';
796
        }
797
      } // End of loop over set of individual elements
798
      $common_name_feature_elements[] = ($language_area_key ? $language_area_key . ': ' : '' ) . join(', ', $per_language_area_out);
799
    } // End of loop over set of elements per language area
800

    
801

    
802
    $common_name_out .= compose_cdm_feature_block_elements(
803
        $common_name_feature_elements,
804
        $feature,
805
        '; ',
806
        FALSE,
807
        'div'
808
      );
809

    
810

    
811
  }
812

    
813
  // Handling commons names as text data.
814
  $text_data_out = array();
815

    
816
  foreach ($textData_commonNames as $text_data_element) {
817
    /* footnotes are not handled correctly in theme_cdm_descriptionElementTextData,
818
       need to set 'common-names-feature-block' as $footnote_key_suggestion */
819
    RenderHints::setFootnoteListKey($footnote_key_suggestion);
820
    $text_data_out[] = theme('cdm_descriptionElementTextData', array(
821
      'element' => $text_data_element,
822
      'asListElement' => TRUE,
823
      'feature_uuid' => $text_data_element->feature->uuid,
824
    ));
825
  }
826

    
827
  $common_name_out_text_data = compose_cdm_feature_block_elements(
828
        $text_data_out,
829
        $feature
830
      );
831

    
832

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

    
836
  return  markup_to_render_array(
837
    '<div class="common_names_as_common_names">' . $common_name_out . '</div>'
838
    .'<div class="common_names_as_text_data">' . $common_name_out_text_data . '</div>'
839
    .$footnotes
840
  );
841
}
842

    
843
/**
844
 * Return HTML for a list of description elements.
845
 *
846
 * Usually these are of a specific feature type.
847
 *
848
 * @param array $variables
849
 *   An associative array containing:
850
 *   - array of descriptionElements which belong to the same feature.
851
 *     These descriptions elements of a Description must be ordered by the chosen feature tree by
852
 *     calling the function _mergeFeatureTreeDescriptions().
853
 *     @see _mergeFeatureTreeDescriptions()
854
 *   - featureUuid: currently unused, according code disabled
855
 *   - taxon_uuid: only used for ordered distributions (will be removed!)
856
 *
857
 * @ingroup themeable
858
 */
859
function theme_cdm_descriptionElements($variables) {
860

    
861
  $descriptionElements = $variables['descriptionElements'];
862
  $feature = $variables['feature'];
863
  $taxon_uuid = $variables['taxon_uuid'];
864
  $outArray = array();
865

    
866
  /*
867
  $userDefined = mixed_variable_get(LAYOUT_SETTING_PREFIX . $feature_uuid, FEATURE_TREE_LAYOUT_DEFAULTS);
868
  if(variable_get('distribution_sort',
869
      'NO_SORT') != 'NO_SORT'){
870
      $glue = '';
871
      $enclosingTag = 'dl';
872
      $entryEnclosingTag = NULL;
873
  } else if($userDefined &&
874
      $userDefined['enabled']){
875
    $glue = $userDefined['glue'];
876
    $enclosingTag =  $userDefined['enclosingTag'];
877
    $entryEnclosingTag = $userDefined['entryEnclosingTag'];
878
  } else { // TODO remove once  LAYOUT_SETTING_PREFIX-{uuid} setting are configured to work for all portals(selenium test still missing!!!)
879
    $glue = ''; $enclosingTag = 'ul';
880
    $entryEnclosingTag = NULL ;
881
  }
882
  */
883

    
884
  $sortOutArray = FALSE;
885
  $distributionElements = array();
886
  $distribution_tree = null;
887

    
888
  RenderHints::pushToRenderStack('cdm_descriptionElements');
889

    
890
  if (is_array($descriptionElements)) {
891
    // --- normal description element arrays
892
    foreach ($descriptionElements as $descriptionElement) {
893

    
894
      // --- IMAGE_SOURCES --- //
895
      if ($descriptionElement->feature->uuid == UUID_IMAGE_SOURCES) {
896
        $image_sources[] = $descriptionElement;
897
      }
898
      // --- USE TEXTDATA --- //
899
      elseif ($descriptionElement->feature->uuid == UUID_USE) {
900
        // Do nothing to avoid rendering.
901
      } else {
902
        /* decide based on the description element class
903
         *
904
         * Features handled here:
905
         * all except DISTRIBUTION, COMMON_NAME, USES, IMAGES,
906
         *
907
         *
908
         * TODO provide api_hook as extension point for this
909
         */
910
        switch ($descriptionElement->class) {
911
          case 'TextData':
912
            $asListElement = TRUE;
913
            $outArray[] = theme('cdm_descriptionElementTextData', array(
914
              'element' => $descriptionElement,
915
              'asListElement' => $asListElement,
916
              'feature_uuid' => $descriptionElement->feature->uuid,
917
            ));
918
            break;
919
          case 'CategoricalData':
920
            $outArray[] = theme('cdm_descriptionElement_CategoricalData', array('element' => $descriptionElement));
921
            break;
922
          case 'QuantitativeData':
923
            $outArray[] = theme('cdm_descriptionElement_QuantitativeData', array('element' => $descriptionElement));
924
            break;
925
          case 'IndividualsAssociation':
926
            $outArray[] = theme('cdm_descriptionElement_IndividualsAssociation', array('element' => $descriptionElement));
927
            break;
928
          case 'TaxonInteraction':
929
            $outArray[] = theme('cdm_descriptionElement_TaxonInteraction', array('element' => $descriptionElement));
930
            break;
931
          case 'Uses':
932
          /* IGNORE Uses classes, these are handled completely in theme_cdm_UseDescription */
933
          break;
934
        default:
935
        $outArray[] = '<li>No method for rendering unknown description class: ' . $descriptionElement->class . '</li>';
936
      }
937
    }
938
    } // --- END loop over normal description element arrays
939

    
940
    // If feature = CITATION sort the list of sources.
941
    // This is ONLY for FLORA MALESIANA and FLORE d'AFRIQUE CENTRALE.
942
    if ($descriptionElement->feature->uuid == UUID_CITATION) {
943
      sort($outArray);
944
    }
945

    
946
    if (isset($image_sources)) {
947
      $outArray[] = theme('cdm_description_element_image_source', array('image_sources' => $image_sources, 'asListElement' => TRUE));
948
    }
949
  } // END normal description element arrays
950

    
951
  $out = compose_cdm_feature_block_elements(
952
    $outArray,
953
    $feature
954
  );
955

    
956
  RenderHints::popFromRenderStack();
957
  return $out;
958
}
959

    
960
/**
961
 * @todo Please document this function.
962
 * @see http://drupal.org/node/1354
963
 */
964
function compare_image_sources($a, $b) {
965
  if ($a->multilanguageText_L10n->text == $b->multilanguageText_L10n->text) {
966
    return 0;
967
  }
968
  return ($a->multilanguageText_L10n->text < $b->multilanguageText_L10n->text) ? -1 : 1;
969
}
970

    
971
/**
972
 * @todo Please document this function.
973
 * @see http://drupal.org/node/1354
974
 */
975
function theme_cdm_description_element_image_source($variables) {
976
  $image_sources = $variables['image_sources'];
977
  $asListElement = $variables['asListElement'];
978
  $out = '';
979
  $separator = ',';
980
  RenderHints::pushToRenderStack('descriptionElementImageSource');
981
  RenderHints::setFootnoteListKey(UUID_IMAGE_SOURCES);
982

    
983
  // Sorting the image sources.
984
  usort($image_sources, "compare_image_sources");
985
  // Generate the footnotes.
986
  foreach ($image_sources as $image_source) {
987
    $footNoteKeys = cdm_annotations_as_footnotekeys($image_source);
988
    foreach ($image_source->sources as $source) {
989
      if (_is_original_source_type($source)) {
990
        $fn_key = FootnoteManager::addNewFootnote(original_source_footnote_list_key(), theme('cdm_OriginalSource', array(
991
          'source' => $source,
992
          'doLink' => FALSE,
993
        )));
994
        // Ensure uniqueness of the footnote keys.
995
        cdm_add_footnote_to_array($footNoteKeys, $fn_key);
996
      }
997
    }
998
    // Sort and render footnote keys.
999
    $footnote_key_list_str = '';
1000
    asort($footNoteKeys);
1001
    foreach ($footNoteKeys as $footNoteKey) {
1002
      $footnote_key_list_str .= theme('cdm_footnote_key', array('footnoteKey' => $footNoteKey, 'separator' => ($footnote_key_list_str ? $separator : '')));
1003
    }
1004
    // Return value!
1005
    $out .= '<span class="descriptionElement descriptionElement-' . $image_source->uuid . '">' . $image_source->multilanguageText_L10n->text . $footnote_key_list_str . '; </span>';
1006
  }
1007

    
1008
  RenderHints::popFromRenderStack();
1009
  return $out;
1010
}
1011

    
1012
/**
1013
 * @todo Please document this function.
1014
 * @see http://drupal.org/node/1354
1015
 */
1016
function theme_cdm_descriptionElement_Distribution($variables) {
1017
  $descriptionElements = $variables['descriptionElements'];
1018
  $enclosingTag = $variables['enclosingTag'];
1019
  if (!$enclosingTag) {
1020
    $enclosingTag = "span";
1021
  }
1022

    
1023
  $out = '';
1024
  RenderHints::pushToRenderStack('descriptionElementDistribution');
1025
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
1026

    
1027
  foreach ($descriptionElements as $descriptionElement) {
1028

    
1029
    $footnote_key_list_str = cdm_create_description_element_footnotes($descriptionElement);
1030

    
1031
    $out .= '<' . $enclosingTag . ' class="descriptionElement descriptionElement-' . $descriptionElement->uuid . '">'
1032
        . $descriptionElement->area->representation_L10n . $footnote_key_list_str
1033
        . ' </' . $enclosingTag . '>';
1034
  }
1035

    
1036
  RenderHints::popFromRenderStack();
1037
  return $out;
1038
}
1039

    
1040

    
1041
/**
1042
 * Compare two different footnotes objects.
1043
 *
1044
 * The comparison is based on the footnote key. The one which is
1045
 * displayed as footnote number.
1046
 *
1047
 * @param mixed $a
1048
 *   Footnote object $a.
1049
 * @param mixed $b
1050
 *   Footnote object $b.
1051
 */
1052
function footnotes_key_compare($a, $b) {
1053
  $res = 0;
1054
  if (empty($a) || empty($b)) {
1055
    return $res;
1056
  }
1057
  if ($a->keyStr < $b->keyStr) {
1058
    $res = -1;
1059
  }
1060
  elseif ($a->keyStr > $b->keyStr) {
1061
    $res = 1;
1062
  }
1063
  return $res;
1064
}
1065

    
1066
/**
1067
 * @todo Please document this function.
1068
 * @see http://drupal.org/node/1354
1069
 */
1070
function theme_cdm_description_ordered_distributions($variables) {
1071

    
1072
  $distribution_tree = $variables['distribution_tree'];
1073

    
1074
  // Returning NULL if there are no description elements.
1075
  if ($distribution_tree == null) {
1076
    return NULL;
1077
  }
1078

    
1079
  // Initialization of some variables.
1080
  $out = '';
1081
  $separator = ',';
1082
  RenderHints::pushToRenderStack('descriptionElementDistribution');
1083
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
1084

    
1085
  $ordered_areas = $distribution_tree;
1086
  if (isset($ordered_areas->rootElement->children)) {
1087
    $ordered_areas = $ordered_areas->rootElement->children;
1088
  }
1089

    
1090
  // Printing the distributions.
1091
  if (is_array($ordered_areas) && count($ordered_areas) > 0) {
1092
    foreach ($ordered_areas as $element_level1) {
1093
      // Level1.
1094
      $out .= '<dt>' . $element_level1->nodeId->representation_L10n . ':</dt> ';
1095
      $out .= '<dd>';
1096

    
1097
      // Level3.
1098
      foreach ($element_level1->children as $element_level3) {
1099
        $text_l3 = $element_level3->nodeId->representation_L10n;
1100
        $fnKeysLevel3Str = '';
1101
        $fnKeysLevel3 = cdm_annotations_as_footnotekeys($element_level3->data);
1102
        if (isset($element_level3->data[0])) {
1103
          foreach ($element_level3->data as $description_level3){
1104
            foreach ($description_level3->sources as $source) {
1105
              if (_is_original_source_type($source)) {
1106
                $fn_key3 = FootnoteManager::addNewFootnote(
1107
                  original_source_footnote_list_key(),
1108
                  theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)
1109
                ));
1110
                cdm_add_footnote_to_array($fnKeysLevel3, $fn_key3);
1111
              }
1112
            }
1113
          }
1114
        }
1115
        // Level4.
1116
        $l4_regions = array();
1117
        foreach ($element_level3->children as $element_level4) {
1118
          if (isset($element_level4->data[0])) {
1119
            $text_l4 = $element_level4->nodeId->representation_L10n;
1120
            $l4_regions[$element_level3->nodeId->representation_L10n] = array();
1121
            $fnKeysLevel4Str = '';
1122
            foreach($element_level4->data as $description_level4) {
1123
              $fnKeysLevel4 = cdm_annotations_as_footnotekeys($description_level4);
1124
              foreach ($description_level4->sources as $source) {
1125
                if (_is_original_source_type($source)) {
1126
                  $fn_key4 = FootnoteManager::addNewFootnote(
1127
                      original_source_footnote_list_key(),
1128
                      theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)));
1129
                  cdm_add_footnote_to_array($fnKeysLevel4, $fn_key4);
1130
                }
1131
              }
1132
              usort($fnKeysLevel4, "footnotes_key_compare");
1133
              if(!isset( $l4_regions[$text_l4])){
1134
                $l4_regions[$text_l4] = $fnKeysLevel4;
1135
              } else {
1136
                $l4_regions[$text_l4] = array_merge($l4_regions[$text_l4], $fnKeysLevel4);
1137
              }
1138
            }
1139
          }
1140
        }// Level4.
1141
        // Managing level3 and level4 for generating the right output.
1142
        usort($fnKeysLevel3, "footnotes_key_compare");
1143
        foreach ($fnKeysLevel3 as $key3) {
1144
          foreach ($l4_regions as $key4 => $value4) {
1145
            cdm_add_footnote_to_array($l4_regions[$key4], $key3);
1146
          }
1147
        }
1148
        if ($element_level3->numberOfChildren == 1 && $text_l3 == $element_level3->children[0]->nodeId->representation_L10n) {
1149
          // var_dump($element_level3->children[0]->data->area->representation_L10n);
1150
          $fnStr = '';
1151
          $region = array_pop($l4_regions);
1152
          foreach ($region as $key) {
1153
            $fnStr .= theme('cdm_footnote_key', array('footnoteKey' => $key, 'separator' => ($fnStr ? $separator : '')));
1154
          }
1155
          $out .= "$text_l3 $fnStr; ";
1156
          // Removing whitespaces when &fnStr is empty.
1157
          if (substr($out, -3) == ' ; ') {
1158
            $out = substr($out, 0, -3) . '; ';
1159
          }
1160
        } else {
1161
          $fnKeysLevel3Str = '';
1162
          foreach ($fnKeysLevel3 as $key) {
1163
            $fnKeysLevel3Str .= theme('cdm_footnote_key', array('footnoteKey' => $key, 'separator' => ($fnKeysLevel3Str ? $separator : '')));
1164
          }
1165
          $text_l4_aux = '';
1166
          foreach ($l4_regions as $key => $value) {
1167
            $fnKeysLevel4Str = '';
1168
            if (is_array($l4_regions[$key])) {
1169
              foreach ($l4_regions[$key] as $fnkey) {
1170
                $fnKeysLevel4Str .= theme('cdm_footnote_key', array('footnoteKey' => $fnkey, 'separator' => ($fnKeysLevel4Str ? $separator : '')));
1171
              }
1172
            }
1173
            // if ($key != $text_l3 || sizeof($l4_regions > 1)){
1174
            if ($key != $text_l3) {
1175
              $text_l4_aux .= "$key $fnKeysLevel4Str, ";
1176
            }
1177
          }
1178
          $text_l4_aux = substr($text_l4_aux, 0, -2);
1179

    
1180
          if (strlen($text_l4_aux) > 0) {
1181
            $out .= "$text_l3 $fnKeysLevel3Str ($text_l4_aux); ";
1182
          }
1183
          else {
1184
            $out .= "$text_l3 $fnKeysLevel3Str; ";
1185
          }
1186
        }
1187
      }// Level3.
1188
      $out = substr($out, 0, -2);
1189
      $out .= '.</dd>';
1190
    }// Level1.
1191
  }
1192
  RenderHints::popFromRenderStack();
1193
  return $out;
1194
}
1195

    
1196

    
1197
/*
1198
function theme_cdm_descriptionElement_Distribution($descriptionElements){ $out
1199
  = ''; $separator = ',';
1200
  RenderHints::pushToRenderStack('descriptionElementDistribution');
1201
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
1202
  foreach($descriptionElements as $descriptionElement){ // annotations as
1203
  footnotes $annotationFootnoteKeys = theme('cdm_annotations_as_footnotekeys',
1204
  $descriptionElement); // source references as footnotes
1205
  $sourcesFootnoteKeyList = ''; foreach($descriptionElement->sources as
1206
  $source){ if(_is_original_source_type($source)){ $_fkey =
1207
  FootnoteManager::addNewFootnote(UUID_DISTRIBUTION,
1208
  theme('cdm_OriginalSource', $source, FALSE));
1209
  $sourcesFootnoteKeyList .= theme('cdm_footnote_key', $_fkey,
1210
  UUID_DISTRIBUTION, ($sourcesFootnoteKeyList ? $separator : '')); } }
1211
  if($annotationFootnoteKeys && $sourcesFootnoteKeyList){
1212
  $annotationFootnoteKeys .= $separator; } $out .=
1213
  $descriptionElement->area->representation_L10n . $annotationFootnoteKeys .
1214
  $sourcesFootnoteKeyList . ' '; } $out = substr($out, 0,
1215
  strlen($out)-strlen($separator) ); RenderHints::popFromRenderStack(); return
1216
  $out; }
1217
*/
1218

    
1219
/**
1220
 * Returns a list of a specific type of IdentificationKeys.
1221
 *
1222
 * The list can be restricteded by a taxon.
1223
 *
1224
 * @param string $type
1225
 *   The simple name of the cdm class implementing the interface
1226
 *   IdentificationKey, valid values are:
1227
 *   PolytomousKey, MediaKey, MultiAccessKey.
1228
 * @param string $taxonUuid
1229
 *   If given this parameter restrict the listed keys to those which have
1230
 *   the taxon identified be this uuid in scope.
1231
 *
1232
 * @return array
1233
 *   List with identification keys.
1234
 */
1235
function _list_IdentificationKeys($type, $taxonUuid = NULL, $pageSize = NULL, $pageNumber = NULL) {
1236
  if (!$type) {
1237
    drupal_set_message(t('Type parameter is missing'), 'error');
1238
    return;
1239
  }
1240
  $cdm_ws_pasepath = NULL;
1241
  switch ($type) {
1242
    case "PolytomousKey":
1243
      $cdm_ws_pasepath = CDM_WS_POLYTOMOUSKEY;
1244
      break;
1245

    
1246
    case "MediaKey":
1247
      $cdm_ws_pasepath = CDM_WS_MEDIAKEY;
1248
      break;
1249

    
1250
    case "MultiAccessKey":
1251
      $cdm_ws_pasepath = CDM_WS_MULTIACCESSKEY;
1252
      break;
1253

    
1254
  }
1255

    
1256
  if (!$cdm_ws_pasepath) {
1257
    drupal_set_message(t('Type parameter is not valid: ') . $type, 'error');
1258
  }
1259

    
1260
  $queryParameters = '';
1261
  if (is_numeric($pageSize)) {
1262
    $queryParameters = "pageSize=" . $pageSize;
1263
  }
1264
  else {
1265
    $queryParameters = "pageSize=0";
1266
  }
1267

    
1268
  if (is_numeric($pageNumber)) {
1269
    $queryParameters = "pageNumber=" . $pageNumber;
1270
  }
1271
  else {
1272
    $queryParameters = "pageNumber=0";
1273
  }
1274
  $queryParameters = NULL;
1275
  if ($taxonUuid) {
1276
    $queryParameters = "findByTaxonomicScope=$taxonUuid";
1277
  }
1278
  $pager = cdm_ws_get($cdm_ws_pasepath, NULL, $queryParameters);
1279

    
1280
  if (!$pager || $pager->count == 0) {
1281
    return array();
1282
  }
1283
  return $pager->records;
1284
}
1285

    
1286
/**
1287
 * @todo Please document this function.
1288
 * @see http://drupal.org/node/1354
1289
 */
1290
function theme_cdm_IdentificationKey($variables) {
1291
  $out = '';
1292
  $identificationKey = $variables['identificationKey'];
1293
  $doLinkToKeyPage = $variables['doLinkToKeyPage'];
1294
  $showIdentificationKeyTitle = $variables['showIdentificationKeyTitle'];
1295
  $parentRenderPath = RenderHints::getRenderPath();
1296
  RenderHints::pushToRenderStack("IdentificationKey");
1297

    
1298
  if ($showIdentificationKeyTitle) {
1299
    if ($doLinkToKeyPage) {
1300
      $out = l($identificationKey->titleCache, path_to_key($identificationKey->class, $identificationKey->uuid));
1301
    }
1302
    else {
1303
      $out = $identificationKey->titleCache;
1304
    }
1305
  }
1306
  if (isset($identificationKey->sources) && is_array($identificationKey->sources)) {
1307
    // order and display sources.
1308
    $sources = oder_sources($identificationKey->sources, TRUE);
1309
    $out .= '<div class="sources">';
1310
    $out .=  implode('', $sources);
1311
    $out .= '</div>';
1312
  }
1313
  // Display annotations.
1314
  $out .= theme('cdm_annotations', array('annotations' => cdm_ws_getAnnotationsFor($identificationKey), 'enclosingTag' => 'div'));
1315
  RenderHints::popFromRenderStack();
1316
  return $out;
1317
}
1318

    
1319
/**
1320
 * @todo Please document this function.
1321
 * @see http://drupal.org/node/1354
1322
 */
1323
function theme_cdm_polytomousKey($variables) {
1324
  $polytomousKey = $variables['polytomousKey'];
1325

    
1326
  // TODO settings needed.
1327
  // @see http://en.wikipedia.org/wiki/Single_access_key#Presentation_styles
1328
  // @see http://dev.e-taxonomy.eu/trac/ticket/2152
1329
  $keyStyle = "linkedStyle";
1330

    
1331
  RenderHints::pushToRenderStack("polytomousKey");
1332
  // Key nodes in linked style.
1333
  $out = '<table class="polytomousKey polytomousKey_' . $keyStyle . '">';
1334
  $out .= theme('cdm_polytomousKey_' . $keyStyle . '_subgraph', array('polytomousKeyNode' => $polytomousKey->root));
1335
  $out .= '</table>';
1336
  RenderHints::popFromRenderStack();
1337
  return $out;
1338
}
1339

    
1340
/**
1341
 * @todo Please document this function.
1342
 * @see http://drupal.org/node/1354
1343
 */
1344
function theme_cdm_polytomousKey_linkedStyle_subgraph($variables) {
1345
  $polytomousKeyNode = $variables['polytomousKeyNode'];
1346
  static $statementCountCharacter = '\'';
1347
  $out = "";
1348

    
1349
  if (is_array($polytomousKeyNode->children)) {
1350
    $childIndex = 0;
1351

    
1352
    // Render edges of the current node.
1353
    foreach ($polytomousKeyNode->children as &$child) {
1354

    
1355
      if (!isset($child->statement) && isset($child->taxon->uuid)) {
1356
        // Skip node with empty statements (see below for explanation: "Special
1357
        // case").
1358
        // this skipping here happens always in the next deeper level of iteration
1359
        // the check below is node on the level above
1360
        continue;
1361
      }
1362

    
1363
      /*
1364
       * Special case: Child nodes with empty statements but taxa as leaf are to
1365
       * treated as if all those taxa where direct children of the source node.
1366
       */
1367
      $islinkToManyTaxa = !isset($child->children[0]->statement) && isset($child->children[0]->taxon->uuid);
1368
      $islinkToTaxon = isset($child->taxon->uuid);
1369
      $islinkToSubKey = isset($child->subkey->uuid);
1370
      $islinkToOtherNode = isset($child->otherNode);
1371
      // Either NULL or 0.
1372
      $islinkToNode = $child->nodeNumber && !$islinkToManyTaxa && !$islinkToOtherNode;
1373
      $hasQuestion = !empty($polytomousKeyNode->question->label_l10n);
1374
      $hasFeature = isset($polytomousKeyNode->feature);
1375

    
1376
      // $indentEdge = $hasQuestion && $childIndex > 0;
1377
      // Question.
1378
      if ($hasQuestion && $childIndex == 0) {
1379
        // Place question, as extra table row.
1380
        $out .= '<tr class="question new_section">';
1381
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber) . "</td>";
1382
        $out .= '<td class="question">' . $polytomousKeyNode->question->label_l10n . '</td>';
1383
        $out .= '</tr>';
1384
      }
1385

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

    
1388
      if ($hasQuestion) {
1389
        $out .= '<td class="nodeNumber"></td>';
1390
      }
1391
      else {
1392
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber . str_pad("", $childIndex, $statementCountCharacter)) . "</td>";
1393
      }
1394

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

    
1397
      // Feature.
1398
      if ($hasFeature) {
1399
        $out .= $polytomousKeyNode->feature->representation_L10n . ": ";
1400
      }
1401

    
1402
      // Statement.
1403
      $out .= $child->statement->label_l10n;
1404

    
1405
      // --- Links to nodes taxa and subkeys.
1406
      $out .= '<div class="nodeLink">';
1407

    
1408
      // Link to a PolytomousKeyNode.
1409
      if ($islinkToNode) {
1410
        $out .= '<div class="nodeLinkToNode">';
1411
        if (isset($child->modifyingText)) {
1412
          $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $child->modifyingText));
1413
        }
1414
        $out .= l($child->nodeNumber, request_path(), array(
1415
          'attributes' => NULL,
1416
          'query' => NULL,
1417
          'fragment' => $child->uuid,
1418
        )) . '</div>';
1419
      }
1420

    
1421
      // Link to a PolytomousKeyNode.
1422
      if ($islinkToOtherNode) {
1423
        $out .= '<div class="nodeLinkToOtherNode">';
1424
        if (isset($child->modifyingText)) {
1425
          $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $child->modifyingText));
1426
        }
1427
        $out .= l($child->otherNode->nodeNumber, $_REQUEST["q"], array(
1428
          'attributes' => NULL,
1429
          'query' => NULL,
1430
          'fragment' => $child->otherNode->uuid,
1431
        )) . '</div>';
1432
      }
1433

    
1434
      // Link to one or many taxa.
1435
      if ($islinkToTaxon || $islinkToManyTaxa) {
1436

    
1437
        if ($islinkToManyTaxa) {
1438
          $taxonChildren = $child->children;
1439
        }
1440
        else {
1441
          $taxonChildren = array(
1442
            $child,
1443
          );
1444
        }
1445

    
1446
        foreach ($taxonChildren as $taxonChild) {
1447
          // TODO many taxa $child->children->taxon.
1448
          $out .= '<div class="nodeLinkToTaxon">';
1449
          if (isset($taxonChild->modifyingText)) {
1450
            $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $taxonChild->modifyingText));
1451
          }
1452
          $out .= theme("cdm_taxonName", array('taxonName' => $taxonChild->taxon->name, 'nameLink' => url(path_to_taxon($taxonChild->taxon->uuid))));
1453
          $out .= '</div>';
1454
        }
1455

    
1456
        // Link to a subkey.
1457
        if ($islinkToSubKey) {
1458
          $out .= '<div class="nodeLinkToSubkey">' . theme('cdm_IdentificationKey', array('identificationKey' => $child->subkey)) . '</div>';
1459
        }
1460
      }
1461

    
1462
      $out .= '</div>'; // End node link.
1463
      $out .= '</td>'; // End edge.
1464
      $out .= '</tr>';
1465

    
1466
      $childIndex++;
1467
    }
1468

    
1469
    // Recurse into child nodes.
1470
    foreach ($polytomousKeyNode->children as &$child) {
1471
      $out .= theme('cdm_polytomousKey_linkedStyle_subgraph', array('polytomousKeyNode' => $child));
1472
    }
1473
  }
1474

    
1475
  return $out;
1476
}
1477

    
1478
/**
1479
 * @todo Please document this function.
1480
 * @see http://drupal.org/node/1354
1481
 */
1482
function theme_cdm_poytomousKeyNode_modifyingText($variables) {
1483
  $out = '';
1484
  $modifyingText = $variables['modifyingText'];
1485
  if (is_object($modifyingText)) {
1486
    $i = 0;
1487
    foreach (get_object_vars($modifyingText) as $lang => $languageString) {
1488
      $out .= ($i++ > 0 ? ', ' : '') . '<span class="modifyingText">' . $languageString->text . '</span> ';
1489
    }
1490
  }
1491
  return $out;
1492
}
1493

    
1494
/**
1495
 * Returns HTML for a list of a specific type of IdentificationKeys.
1496
 *
1497
 * The list can be restricteded by a taxon.
1498
 *
1499
 * @param array $variables
1500
 *   An associative array containing:
1501
 *   - type: The simple name of the cdm class implementing the interface
1502
 *     IdentificationKey, valid values are:
1503
 *     PolytomousKey, MediaKey, MultiAccessKey
1504
 *   - taxonUuid: If given, this parameter restrict the listed keys to those
1505
 *     which have the taxon identified be this uuid in scope.
1506
 *
1507
 * @ingroup themeable
1508
 */
1509
function theme_cdm_list_IdentificationKeys($variables) {
1510
  $type = $variables['type'];
1511
  $taxonUuid = $variables['taxonUuid'];
1512
  $keyList = _list_IdentificationKeys($type, $taxonUuid);
1513
  if (!$keyList || count($keyList) == 0) {
1514
    return;
1515
  }
1516

    
1517
  RenderHints::pushToRenderStack('list_IdentificationKeys');
1518
  $out = '<ul>';
1519
  foreach ($keyList as $key) {
1520
    $out .= '<li>';
1521
    $out .= theme('cdm_IdentificationKey', array('identificationKey' => $key));
1522
    $out .= '</li>';
1523
  }
1524
  $out .= '</ul>';
1525
  $out .= theme("cdm_annotation_footnotes", array('footnoteListKey' => RenderHints::getRenderPath()));
1526
  RenderHints::popFromRenderStack();
1527

    
1528
  return $out;
1529
}
1530

    
1531
/**
1532
 * @todo Please document this function.
1533
 * @see http://drupal.org/node/1354
1534
 */
1535
function theme_cdm_block_IdentificationKeys($variables) {
1536
  $taxonUuid = $variables['taxonUuid'];
1537
  static $types = array(
1538
    "PolytomousKey" => "Polytomous",
1539
    "MediaKey" => "Media",
1540
    "MultiAccessKey" => "Multiaccess",
1541
  );
1542
  RenderHints::pushToRenderStack('block_IdentificationKeys');
1543
  $out = '';
1544
  foreach ($types as $type => $label) {
1545
    $keylist = theme('cdm_list_IdentificationKeys', array('type' => $type, 'taxonUuid' => $taxonUuid));
1546
    if (!$keylist) {
1547
      continue;
1548
    }
1549
    $out .= '<div class="' . $type . '">';
1550
    $out .= '<h3>' . t($label) . "</h3>";
1551
    $out .= $keylist;
1552
    $out .= '</div>';
1553
  }
1554
  RenderHints::popFromRenderStack();
1555
  return $out;
1556
}
1557

    
1558
/**
1559
 * This theming function formats the use description and use record list for
1560
 * these descriptions.
1561
 *
1562
 * @see http://drupal.org/node/1354
1563
 */
1564
function theme_cdm_UseDescription($variables) {
1565
  $descriptions = $variables['description'];
1566
  $taxonUuid = $variables['taxonUuid'];
1567
  $out = '<div id="content"><ul id="Description" class ="description">';
1568
  if ($descriptions == NULL) {
1569
    return;
1570
  }
1571
  $descriptionSynonyms = '';
1572
  $descriptionOut = '';
1573
  $synonymOut = '';
1574
  $currentTaxon = cdm_ws_get(CDM_WS_PORTAL_TAXON, $taxonUuid);
1575

    
1576
  foreach ($descriptions as $description) {
1577
    $useSummary = '';
1578
    foreach ($description->elements as $element) {
1579

    
1580
      if ($element->feature->uuid == UUID_USE && !(strlen($useSummary) > 0) && isset($element->multilanguageText_L10n)) {
1581
        $useSummary = $element->multilanguageText_L10n->text;
1582
      }
1583
    }
1584
    // uses will be ordered by source
1585
    foreach ($description->sources as $source) {
1586
      $is_about_current_taxon = FALSE;
1587
      $originalTaxonUsedInSource = NULL;
1588
      $originalTaxonPager = NULL;
1589
      if ($source->originalNameString) {
1590
        $request_params = array();
1591
        $request_params['query'] = $source->originalNameString;
1592
        $request_params['matchMode'] = "EXACT";
1593
        $originalTaxonPager = cdm_ws_get(CDM_WS_PORTAL_NAME_FINDBYNAME, NULL, queryString($request_params));
1594
        if ($originalTaxonPager->count > 0) {
1595
          $originalTaxonUsedInSource = $originalTaxonPager->records[0];
1596
        }
1597
        else {
1598
          $originalTaxonUsedInSource = $currentTaxon->name;
1599
        }
1600
      }
1601
      else {
1602
        $originalTaxonUsedInSource = $currentTaxon->name;
1603
      }
1604

    
1605
      $is_about_current_taxon = $currentTaxon->name->uuid == $originalTaxonUsedInSource->uuid;
1606

    
1607
      if (!$is_about_current_taxon) {
1608
        $descriptionOut .= '<li class="descriptionText DescriptionElement">';
1609
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1610
          'absolute' => TRUE,
1611
          'html' => TRUE,
1612
        ));
1613
        $descriptionOut .= $name_used_in_source_link_to_show_use . ': ';
1614
        $descriptionOut .= $useSummary;
1615
        foreach ($description->sources as $source) {
1616
          $descriptionOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1617
        }
1618
        $hasUseRecords = FALSE;
1619
        $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>';
1620
        foreach ($description->elements as $descriptionElement) {
1621
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1622
            $hasUseRecords = TRUE;
1623
            // FIXME localization hardcoded to English
1624
            $useRecordTags = explode(';', $descriptionElement->modifyingText_l10n);
1625
            $descriptionUseRecordOut .= '<tr>';
1626
            $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>';
1627
            $descriptionUseRecordOut .= '</tr>';
1628
          }
1629
        }
1630
        $descriptionUseRecordOut .= '</table></div>';
1631
        if ($hasUseRecords) {
1632
          $descriptionOut .= $descriptionUseRecordOut . '</li>';
1633
        }
1634
      }
1635
      else {
1636
        // TODO +/- duplicate of above, unify this code
1637
        $synonymOut .= '<li class="descriptionText DescriptionElement">';
1638
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1639
          'absolute' => TRUE,
1640
          'html' => TRUE,
1641
        ));
1642

    
1643
        $synonymOut .= $name_used_in_source_link_to_show_use . ': ';
1644
        $synonymOut .= $useSummary;
1645
        foreach ($description->sources as $source) {
1646
          $synonymOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1647
        }
1648

    
1649
        $hasUseRecords = FALSE;
1650
        $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>';
1651
        foreach ($description->elements as $descriptionElement) {
1652
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1653
            $hasUseRecords = TRUE;
1654
            $useRecordTags = explode(';', $descriptionElement->modifyingText_l10n);
1655
            $useRecordTableOut .= '<tr>';
1656
            $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>';
1657
            $useRecordTableOut .= '</tr>';
1658
          }
1659
        }
1660
        $useRecordTableOut .= '</table></div>';
1661
        if ($hasUseRecords) {
1662
          $synonymOut .= $useRecordTableOut . '</li>';
1663
        }
1664
      }
1665

    
1666
      // }
1667
    }
1668
  }
1669
  $out .= $descriptionOut . $synonymOut;
1670
  $out .= "</ul></div>";
1671
  return $out;
1672
}
1673

    
1674

    
1675
/**
1676
 * The theming function for a block of Uses Descriptions for a given taxon.
1677
 *
1678
 * The Uses block has been removed from the code but the according theme function
1679
 * is kept for compatibility reasons with existing code regarding palmweb.
1680
 *
1681
 */
1682
function theme_cdm_block_Uses($variables) {
1683
  $taxonUuid = $variables['taxonUuid'];
1684
  RenderHints::pushToRenderStack('block_Uses');
1685

    
1686
  if ($taxonUuid == NULL) {
1687
    return;
1688
  }
1689
  $out = '';
1690
  $markerTypes = array();
1691
  $markerTypes['markerTypes'] = UUID_MARKERTYPE_USE;
1692
  $useDescriptions = cdm_ws_get(CDM_WS_PORTAL_TAXON_DESCRIPTIONS, $taxonUuid, queryString($markerTypes));
1693
  if (!empty($useDescriptions)) {
1694
    // FIXME use theme_block instaed of hardcoding the block html here !!!!
1695
    $out .= '<div id="block-cdm_dataportal-feature-description" class="clear-block block block-cdm_dataportal-feature"><H2><a name="userecords"> </a> Uses </H2>';
1696
    $formatUseDescriptions = theme('cdm_UseDescription', array('description' => $useDescriptions, 'taxonUuid' => $taxonUuid));
1697

    
1698
    $out .= $formatUseDescriptions;
1699
    $out .= "</div>";
1700
  }
1701

    
1702
  return $out;
1703
}
(3-3/10)