Project

General

Profile

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

    
16
/**
17
 *
18
 * @param unknown $feature_nodes
19
 * @return multitype:multitype:Ambigous <An, string>
20
 */
21
function cdm_feature_node_toc_items($feature_nodes) {
22
  $items = array();
23

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

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

    
32
  foreach ($feature_nodes as $node) {
33

    
34
    if (hasFeatureNodeDescriptionElements($node)) {
35

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

    
54
  $items = module_invoke_all('cdm_feature_node_toc_items_alter', $items);
55

    
56
  return $items;
57
}
58

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

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

    
102
  $mergedFeatureNodes = $variables['mergedFeatureNodes'];
103
  $taxon = $variables['taxon'];
104
  $out = '';
105

    
106
  RenderHints::pushToRenderStack('feature_nodes');
107

    
108
  $gallery_settings = getGallerySettings(CDM_DATAPORTAL_DESCRIPTION_GALLERY_NAME);
109

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

    
113
    if (hasFeatureNodeDescriptionElements($node)) {
114

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

    
120
      if (true || $node->feature->uuid != UUID_IMAGE) {
121

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

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

    
132
          $node->descriptionElements = cdm_description_elements_prefer_computed($node->descriptionElements);
133

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

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

    
147

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

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

    
168
        }
169

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

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

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

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

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

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

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

    
235
                  }
236

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

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

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

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

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

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

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

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

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

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

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

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

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

    
354
  if ($sortArray) {
355
    sort($elementArray);
356
  }
357

    
358
  $out .= join($elementArray, $glue);
359

    
360
  $out .= '</' . $enclosingHtml . '>';
361
  return $out;
362
}
363

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

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

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

    
385
      $state  = NULL;
386

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

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

    
395
      $modifiers_strings = cdm_modifers_representations($stateData);
396

    
397
      $state_data_strings[] = $state . ($modifiers_strings ? ' ' . $modifiers_strings : '');
398

    
399
      // FIXME render sources
400

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

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

    
420
  $out = '';
421

    
422
  $type_representation = NULL;
423
  $modifiers_strings = array();
424

    
425

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

    
434
    $out .= implode($value_array, ', ');
435
  }
436

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

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

    
447
  // FIXME render sources
448

    
449
  return $out;
450

    
451
}
452

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

    
470
  $element = $variables['element'];
471
  $asListElement = $variables['asListElement'];
472
  $feature_uuid = $variables['feature_uuid'];
473

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

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

    
510
      if ($asListElement) {
511

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

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

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

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

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

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

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

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

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

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

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

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

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

    
672

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

    
682
  $sortOutArray = FALSE;
683
  $distributionElements = array();
684

    
685
  RenderHints::pushToRenderStack('cdm_descriptionElements');
686

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

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

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

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

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

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

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

    
778
  // Take the feature of the last $descriptionElement.
779
  $feature = $descriptionElement->feature;
780

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

    
789
  RenderHints::popFromRenderStack();
790
  return $out;
791
}
792

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

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

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

    
841
  RenderHints::popFromRenderStack();
842
  return $out;
843
}
844

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

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

    
861
  foreach ($descriptionElements as $descriptionElement) {
862

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

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

    
886
  RenderHints::popFromRenderStack();
887
  return $out;
888
}
889

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

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

    
921
  $taxon_uuid = $variables['taxon_uuid'];
922
  $descriptionElements = $variables['descriptionElements'];
923

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

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

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

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

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

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

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

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

    
1050

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

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

    
1092
  $out = '';
1093
  $settings = get_edit_map_service_settings();
1094

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

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

    
1109
  /* ------ choose the display mode, either openlayers or static image ------ */
1110

    
1111
  $map_settings = get_array_variable_merged(CDM_MAP_DISTRIBUTION, CDM_MAP_DISTRIBUTION_DEFAULT);
1112

    
1113
  if ($map_settings['map_type'] == 1) {
1114

    
1115
    /* =========== display distributions using the openlayers map viewer =========== */
1116

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

    
1130
    $out .= get_openlayers_map(
1131
        $map_settings['width'],
1132
        $map_settings['height'],
1133
        $map_settings['bbox'],
1134
        NULL,
1135
        $query_string,
1136
        $legendFormatQueryStr,
1137
        $map_settings['caption']
1138
     );
1139
  }
1140
  else {
1141
    $legendFormatQueryStr = '';
1142
    $out = get_image_map(
1143
        $map_settings['width'],
1144
        $map_settings['height'],
1145
        $map_settings['bbox'],
1146
        NULL,
1147
        $query_string,
1148
        $legendFormatQueryStr,
1149
        $map_settings['caption']
1150
    );
1151
  }
1152
  return markup_to_render_array($out);
1153
}
1154

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

    
1182
    case "MediaKey":
1183
      $cdm_ws_pasepath = CDM_WS_MEDIAKEY;
1184
      break;
1185

    
1186
    case "MultiAccessKey":
1187
      $cdm_ws_pasepath = CDM_WS_MULTIACCESSKEY;
1188
      break;
1189

    
1190
  }
1191

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

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

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

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

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

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

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

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

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

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

    
1285
  if (is_array($polytomousKeyNode->children)) {
1286
    $childIndex = 0;
1287

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

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

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

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

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

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

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

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

    
1338
      // Statement.
1339
      $out .= $child->statement->label_l10n;
1340

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

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

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

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

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

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

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

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

    
1402
      $childIndex++;
1403
    }
1404

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

    
1411
  return $out;
1412
}
1413

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

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

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

    
1464
  return $out;
1465
}
1466

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

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

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

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

    
1541
      $is_about_current_taxon = $currentTaxon->name->uuid == $originalTaxonUsedInSource->uuid;
1542

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

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

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

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

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

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

    
1634
    $out .= $formatUseDescriptions;
1635
    $out .= "</div>";
1636
  }
1637

    
1638
  return $out;
1639
}
(3-3/10)