Project

General

Profile

Download (60.4 KB) Statistics
| Branch: | Tag: | Revision:
1 6657531f Andreas Kohlbecker
<?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 0c432a94 Andreas Kohlbecker
 * 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 6657531f Andreas Kohlbecker
 */
33
function theme_cdm_feature_name($variables) {
34
  $feature_name = $variables['feature_name'];
35 0c432a94 Andreas Kohlbecker
  return t($feature_name);
36 6657531f Andreas Kohlbecker
}
37
38
/**
39 28c5c87a Andreas Kohlbecker
 * Returns a set of feature blocks for a taxon profile from the $mergedFeatureNodes of a given $taxon.
40 6657531f Andreas Kohlbecker
 *
41 28c5c87a Andreas Kohlbecker
 * The taxon profile consists of drupal block elements, one for the description elements
42
 * of a specific feature. The structure is defined by specific FeatureTree.
43
 * The chosen FeatureTree is merged with the list of description elements prior to using this method.
44 6657531f Andreas Kohlbecker
 *
45
 * The merged nodes can be obtained by making use of the
46
 * function cdm_ws_descriptions_by_featuretree().
47
 *
48 37252893 Andreas Kohlbecker
 * @see cdm_ws_descriptions_by_featuretree()
49
 *
50 28c5c87a Andreas Kohlbecker
 * @param $mergedFeatureNodes
51 6657531f Andreas Kohlbecker
 *
52 28c5c87a Andreas Kohlbecker
 * @param $taxon
53
 *
54
 * @return array
55 9aff46e4 Andreas Kohlbecker
 *  A Drupal render array containing feature blocks and the table of content
56 28c5c87a Andreas Kohlbecker
 *
57
 * @ingroup compose
58 6657531f Andreas Kohlbecker
 */
59 28c5c87a Andreas Kohlbecker
function compose_cdm_feature_nodes($mergedFeatureNodes, $taxon) {
60 6657531f Andreas Kohlbecker
61 9aff46e4 Andreas Kohlbecker
  $block_list = array();
62 6657531f Andreas Kohlbecker
63
  RenderHints::pushToRenderStack('feature_nodes');
64 235fc94b Andreas Kohlbecker
65 6657531f Andreas Kohlbecker
  $gallery_settings = getGallerySettings(CDM_DATAPORTAL_DESCRIPTION_GALLERY_NAME);
66
67 28c5c87a Andreas Kohlbecker
  // Create a drupal block for each feature
68 6657531f Andreas Kohlbecker
  foreach ($mergedFeatureNodes as $node) {
69
70 28c5c87a Andreas Kohlbecker
    if ((isset($node->descriptionElements['#type']) ||
71
        has_feature_node_description_elements($node)) && $node->feature->uuid != UUID_IMAGE) { // skip empty or supressed features
72 6657531f Andreas Kohlbecker
73 28c5c87a Andreas Kohlbecker
      $feature_name = cdm_term_representation($node->feature, 'Unnamed Feature');
74 6657531f Andreas Kohlbecker
75 f19f47fa Andreas Kohlbecker
      $block = feature_block($feature_name, $node->feature);
76 6f5c7f2a Andreas Kohlbecker
      $block->content = array();
77 159cd9bb Andreas Kohlbecker
      $block_content_is_empty = TRUE;
78 6f5c7f2a Andreas Kohlbecker
      $block_content_weight = 0;
79 6657531f Andreas Kohlbecker
80 f19f47fa Andreas Kohlbecker
      /*
81
       * Content/DISTRIBUTION.
82
       */
83 6657531f Andreas Kohlbecker
84 28c5c87a Andreas Kohlbecker
      if ($node->feature->uuid == UUID_DISTRIBUTION) {
85
        $block = compose_feature_block_distribution($taxon, $node->descriptionElements, $node->feature);
86 159cd9bb Andreas Kohlbecker
        $block_content_is_empty = FALSE;
87 f19f47fa Andreas Kohlbecker
      }
88
      /*
89
       * Content/COMMON_NAME.
90
       */
91 6f5c7f2a Andreas Kohlbecker
      else if ($node->feature->uuid == UUID_COMMON_NAME) {
92 28c5c87a Andreas Kohlbecker
        $common_names_render_array = compose_cdm_common_names($node->descriptionElements, $node->feature);
93 6f5c7f2a Andreas Kohlbecker
        $block->content[] = $common_names_render_array;
94 9aff46e4 Andreas Kohlbecker
        $block_content_is_empty = FALSE;
95
      }
96
97
      else if ($node->feature->uuid == UUID_USE_RECORD) {
98
        $block_uses_content_html = theme('cdm_block_Uses', array('taxonUuid' => $taxon->uuid));
99
        $block->content[] = markup_to_render_array($block_uses_content_html);
100
        $block_content_is_empty = FALSE;
101 f19f47fa Andreas Kohlbecker
      }
102
103
      /*
104
       * Content/ALL OTHER FEATURES.
105
       */
106
      else {
107 28c5c87a Andreas Kohlbecker
108
        $media_list = array();
109
        $out_child_elements = '';
110
111 f19f47fa Andreas Kohlbecker
        if (isset($node->descriptionElements)) {
112
          $taxon_uuid = NULL;
113
          if(isset($taxon) ) {
114
            $taxon_uuid = $taxon->uuid;
115 6657531f Andreas Kohlbecker
          }
116 159cd9bb Andreas Kohlbecker
          $elements_render_array = compose_cdm_descriptionElements($node->descriptionElements, $node->feature, $taxon_uuid);
117
          $block_content_is_empty = empty($elements_render_array);
118
          $block->content[] = $elements_render_array;
119 f19f47fa Andreas Kohlbecker
        }
120 0c432a94 Andreas Kohlbecker
121 28c5c87a Andreas Kohlbecker
          // Content/ALL OTHER FEATURES/Subordinate Features
122
          // subordinate features are printed inline in one floating text,
123 6f5c7f2a Andreas Kohlbecker
          // it is expected hat subordinate features can "contain" TextData,
124 28c5c87a Andreas Kohlbecker
          // Qualitative- and Qualitative- DescriptioneElements
125
          if (isset($node->childNodes[0])) {
126 f19f47fa Andreas Kohlbecker
127
          // TODO support more than one level of children.
128 6f5c7f2a Andreas Kohlbecker
          // can this be solved by recursively calling this function?
129 f19f47fa Andreas Kohlbecker
          // @see http://dev.e-taxonomy.eu/trac/ticket/2393
130
          $text = '';
131
          foreach ($node->childNodes as $child) {
132
133
            if (isset($child->descriptionElements) && is_array($child->descriptionElements)) {
134
              foreach ($child->descriptionElements as $element) {
135 8db340ef Andreas Kohlbecker
136 6f5c7f2a Andreas Kohlbecker
                //TODO it woud be better if we could use compose_cdm_descriptionElements() directly instead of the below stuff
137
138 f19f47fa Andreas Kohlbecker
                if (is_array($element->media)) {
139
                  // Append media of supordinate elements to list of main
140
                  // feature.
141
                  $media_list = array_merge($media_list, $element->media);
142 6657531f Andreas Kohlbecker
                }
143 f19f47fa Andreas Kohlbecker
144
                switch ($element->class) {
145
                  case 'TextData':
146 6f5c7f2a Andreas Kohlbecker
                    // FIXME use theme_cdm_descriptionElementTextData()
147 f19f47fa Andreas Kohlbecker
                    $out_child_elements = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
148
                    $out_child_elements = str_replace($child->feature->titleCache, '<em>' . $child->feature->representation_L10n . '</em>', $out_child_elements);
149
                    break;
150
                  case 'CategoricalData':
151
                    $out_child_elements  = '<em>' . $child->feature->representation_L10n . '</em> '
152
                      . theme('cdm_descriptionElement_CategoricalData', array('element' => $element));
153
                    break;
154
                  case 'QuantitativeData':
155
                    $out_child_elements = '<em>' . $child->feature->representation_L10n . '</em> '
156
                      . theme('cdm_descriptionElement_QuantitativeData', array('element' => $element));
157
158
                }
159
160 6657531f Andreas Kohlbecker
              }
161 f19f47fa Andreas Kohlbecker
              $text .= " " . $out_child_elements;
162
              $out_child_elements = '';
163 6657531f Andreas Kohlbecker
            }
164
          }
165 159cd9bb Andreas Kohlbecker
          $block_content_is_empty = $block_content_is_empty && empty($text);
166 6f5c7f2a Andreas Kohlbecker
          $block->content[] = markup_to_render_array($text);
167 159cd9bb Andreas Kohlbecker
          $block_content_is_empty = $block_content_is_empty && empty($media_list);
168 6f5c7f2a Andreas Kohlbecker
          $block->content[] = compose_feature_media_gallery($node, $media_list, $gallery_settings);
169 28c5c87a Andreas Kohlbecker
170
171 6f5c7f2a Andreas Kohlbecker
          }
172
        /*
173
         * Footnotes for the feature block
174
         */
175
        $block->content[] = markup_to_render_array(theme('cdm_footnotes', array('footnoteListKey' => $node->feature->uuid)));
176
        $block->content[] = markup_to_render_array(theme('cdm_annotation_footnotes', array('footnoteListKey' => $node->feature->uuid)));
177 159cd9bb Andreas Kohlbecker
      } // END all other features
178 f19f47fa Andreas Kohlbecker
179 159cd9bb Andreas Kohlbecker
      if(!$block_content_is_empty){ // skip empty block content
180 9aff46e4 Andreas Kohlbecker
        $block_list[] = $block;
181 dd1c109a Andreas Kohlbecker
        cdm_toc_list_add_item(cdm_term_representation($node->feature), $node->feature->uuid);
182 159cd9bb Andreas Kohlbecker
      } // END: skip empty block content
183 28c5c87a Andreas Kohlbecker
    } // END: skip empty or supressed features
184
  } // END: creating a block per feature
185 9aff46e4 Andreas Kohlbecker
186
  drupal_alter('cdm_feature_node_blocks', $block_list, $taxon);
187
188 6657531f Andreas Kohlbecker
  RenderHints::popFromRenderStack();
189 28c5c87a Andreas Kohlbecker
190 9aff46e4 Andreas Kohlbecker
  return _block_get_renderable_array($block_list);
191 6657531f Andreas Kohlbecker
}
192
193 28c5c87a Andreas Kohlbecker
  /**
194
   * @param $node
195
   * @param $media_list
196
   * @param $gallery_settings
197
   * @return array
198
   */
199
  function compose_feature_media_gallery($node, $media_list, $gallery_settings) {
200
    if (isset($node->descriptionElements)) {
201
      $media_list = array_merge($media_list, cdm_dataportal_media_from_descriptionElements($node->descriptionElements));
202
    }
203
    $captionElements = array('title', 'rights');
204
    $gallery = '';
205
    if (isset($gallery_settings['cdm_dataportal_media_maxextend']) && isset($gallery_settings['cdm_dataportal_media_cols'])) {
206
      $gallery = theme('cdm_media_gallerie', array(
207
        'mediaList' => $media_list,
208
        'galleryName' => CDM_DATAPORTAL_DESCRIPTION_GALLERY_NAME . '_' . $node->feature->uuid,
209
        'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
210
        'cols' => $gallery_settings['cdm_dataportal_media_cols'],
211
        'captionElements' => $captionElements,
212
      ));
213 0c7d3099 Andreas Kohlbecker
      return markup_to_render_array($gallery);
214 28c5c87a Andreas Kohlbecker
    }
215 0c7d3099 Andreas Kohlbecker
    return markup_to_render_array($gallery);
216 28c5c87a Andreas Kohlbecker
  }
217
218
  /**
219
   * @param $taxon
220
   * @param $descriptionElements
221
   *   an associative array with two elements:
222
   *   - '#type': must be 'DTO'
223
   *   - 'DistributionInfoDTO': a CDM DistributionInfoDTO object as returned by the DistributionInfo web service
224
   * @param $feature
225
   *
226
   * @ingroup compose
227
   */
228
  function compose_feature_block_distribution($taxon, $descriptionElements, $feature) {
229
    $text_data_glue = '';
230
    $text_data_sortOutArray = FALSE;
231
    $text_data_enclosingTag = 'ul';
232
    $text_data_out_array = array();
233
234
    $distributionElements = NULL;
235
    $distribution_info_dto = NULL;
236
    $distribution_sortOutArray = FALSE;
237
238
    if (variable_get('distribution_sort', 'NO_SORT') != 'NO_SORT') {
239
      $distribution_glue = '';
240
      $distribution_enclosingTag = 'dl';
241
    } else {
242
      $distribution_glue = '';
243
      $distribution_enclosingTag = 'ul';
244
    }
245
246
    if (!isset($descriptionElements['#type']) || !$descriptionElements['#type'] == 'DTO') {
247
      // skip the DISTRIBUTION section if there is no DTO type element
248
      return array(); // FIXME is it ok to return an empty array?
249
    }
250 f19f47fa Andreas Kohlbecker
251 28c5c87a Andreas Kohlbecker
    $block = feature_block(
252
      cdm_term_representation($feature, 'Unnamed Feature'),
253
      $feature
254
    );
255
256 22f5e82d Andreas Kohlbecker
    // $$descriptionElements['TextData'] is added to to the feature node in merged_taxon_feature_tree()
257 28c5c87a Andreas Kohlbecker
    if (isset($descriptionElements['TextData'])) {
258
      // --- TextData
259
      foreach ($descriptionElements['TextData'] as $text_data_element) {
260
        $asListElement = FALSE;
261 159cd9bb Andreas Kohlbecker
        $text_data_render_array = compose_cdm_descriptionElementTextData($text_data_element, $asListElement, $text_data_element->feature->uuid);
262
        $repr = drupal_render($text_data_render_array);
263 f19f47fa Andreas Kohlbecker
264 159cd9bb Andreas Kohlbecker
        if (!array_search($repr, $text_data_out_array)) { // de-duplication !!
265 28c5c87a Andreas Kohlbecker
          $text_data_out_array[] = $repr;
266 c367b0ab Andreas Kohlbecker
          // TODO HINT: sorting in compose_cdm_feature_block_elements will
267 28c5c87a Andreas Kohlbecker
          // not work since this array contains html attributes with uuids
268 159cd9bb Andreas Kohlbecker
          // and what is about cases like the bibliography where
269
          // any content can be prefixed with some foot-note anchors?
270 28c5c87a Andreas Kohlbecker
          $text_data_sortOutArray = TRUE;
271
          $text_data_glue = '<br/> ';
272
          $text_data_enclosingTag = 'p';
273
        }
274
      }
275
    }
276
277
278
    if ($text_data_out_array && variable_get(DISTRIBUTION_TEXTDATA_DISPLAY_ON_TOP, 0)) {
279 6f5c7f2a Andreas Kohlbecker
      $block->content[] = compose_cdm_feature_block_elements(
280 c367b0ab Andreas Kohlbecker
        $text_data_out_array,
281
        $feature,
282
        $text_data_glue,
283
        $text_data_sortOutArray,
284
        $text_data_enclosingTag
285
      );
286 28c5c87a Andreas Kohlbecker
    }
287
288
    // --- Distribution map
289
    $distribution_map_query_parameters = NULL;
290
    if (isset($descriptionElements['DistributionInfoDTO'])) {
291
      $distribution_map_query_parameters = $descriptionElements['DistributionInfoDTO']->mapUriParams;
292
    }
293
    $map_render_element = compose_distribution_map($taxon, $distribution_map_query_parameters);
294 6f5c7f2a Andreas Kohlbecker
    $block->content[] = $map_render_element;
295 28c5c87a Andreas Kohlbecker
296
    // --- tree or list
297
    $dto_out_array = array();
298
    if (isset($descriptionElements['DistributionInfoDTO'])) {
299
      $distribution_info_dto = $descriptionElements['DistributionInfoDTO'];
300
301
      // --- tree
302
      if (is_object($distribution_info_dto->tree)) {
303
        $dto_out_array[] = theme('cdm_description_ordered_distributions', array('distribution_tree' => $distribution_info_dto->tree));
304
      }
305
306
      // --- sorted element list
307
      if (is_array($distribution_info_dto->elements) && count($distribution_info_dto->elements) > 0) {
308
        foreach ($distribution_info_dto->elements as $descriptionElement) {
309
          if (is_object($descriptionElement->area)) {
310
            $sortKey = $descriptionElement->area->representation_L10n;
311
            $distributionElements[$sortKey] = $descriptionElement;
312
          }
313
        }
314
        ksort($distributionElements);
315 44d445c0 Andreas Kohlbecker
        $distribution_element_render_array = compose_cdm_descriptionElement_Distribution($distributionElements);
316
        $dto_out_array[] = drupal_render($distribution_element_render_array);
317 28c5c87a Andreas Kohlbecker
318
      }
319
      //
320 6f5c7f2a Andreas Kohlbecker
      $block->content[] = compose_cdm_feature_block_elements(
321 c367b0ab Andreas Kohlbecker
        $dto_out_array,
322
        $feature,
323
        $distribution_glue,
324
        $distribution_sortOutArray,
325
        $distribution_enclosingTag
326
      );
327 28c5c87a Andreas Kohlbecker
    }
328
329
    // --- TextData at the bottom
330
    if ($text_data_out_array && !variable_get(DISTRIBUTION_TEXTDATA_DISPLAY_ON_TOP, 0)) {
331 6f5c7f2a Andreas Kohlbecker
      $block->content[] = compose_cdm_feature_block_elements(
332 c367b0ab Andreas Kohlbecker
        $text_data_out_array,
333
        $feature,
334
        $text_data_glue,
335
        $text_data_sortOutArray,
336
        $text_data_enclosingTag
337
      );
338 28c5c87a Andreas Kohlbecker
    }
339
340 6f5c7f2a Andreas Kohlbecker
    $block->content[] = markup_to_render_array(theme('cdm_footnotes', array('footnoteListKey' => UUID_DISTRIBUTION)));
341
    $block->content[] = markup_to_render_array(theme('cdm_annotation_footnotes', array('footnoteListKey' => UUID_DISTRIBUTION)));
342 28c5c87a Andreas Kohlbecker
343
    return $block;
344
  }
345
346
347
  /**
348 6657531f Andreas Kohlbecker
 * @todo Please document this function.
349
 * @see http://drupal.org/node/1354
350
 */
351
function theme_FeatureTree_hierarchy($variables) {
352
353
  $FeatureTreeUuid = $variables['FeatureTreeUuid'];
354
  if (!is_uuid($FeatureTreeUuid)) {
355
    return;
356
  }
357
358
  $out = '';
359
  $featureTree = cdm_ws_get(CDM_WS_FEATURETREE, array(
360
    $FeatureTreeUuid,
361
  ));
362
363
  if (isset($featureTree) && isset($featureTree->root)) {
364
    $out = '<ul class="' . $featureTree->class . '">';
365
    $out .= theme('FeatureTree_hierarchy_children', array('node' => $featureTree->root));
366
    $out .= '</ul>';
367
  }
368
  return $out;
369
}
370
371
/**
372
 * @todo Please document this function.
373
 * @see http://drupal.org/node/1354
374
 */
375
function theme_FeatureTree_hierarchy_children($variables) {
376
377
  $node = $variables['node'];
378
  $out = '';
379 fae36a2a Andreas Kohlbecker
  if (isset($node->childNodes)) {
380 6657531f Andreas Kohlbecker
381 fae36a2a Andreas Kohlbecker
    foreach ($node->childNodes as $childNode) {
382 6657531f Andreas Kohlbecker
      $out .= '<li>' . check_plain($childNode->feature->representation_L10n);
383 fae36a2a Andreas Kohlbecker
      if (isset($childNode->childNodes) && count($childNode->childNodes) > 0) {
384 6657531f Andreas Kohlbecker
        $out .= '<ul>' . theme('FeatureTree_hierarchy_children', array('node' => $childNode)) . '</ul>';
385
      }
386
      $out .= '</li>';
387
    }
388
  }
389
  return $out;
390
}
391
392
/**
393 c367b0ab Andreas Kohlbecker
 * Returns HTML for the texts in a description $elements.
394 6657531f Andreas Kohlbecker
 *
395 c367b0ab Andreas Kohlbecker
 * Joins the texts in $elements and encloses with a HTML tag.
396 6657531f Andreas Kohlbecker
 *
397 c367b0ab Andreas Kohlbecker
 * @param  $elements
398
 * @param  feature:
399
 *  The feature to which the elements given in $elements are belonging to.
400
 * @param  glue:
401
 *  Defaults to empty string.
402
 * @param $sort
403
 *   Boolean Whether to sort the $elements alphabetically, default is FALSE
404
 * @param  $enclosing_tag
405 6657531f Andreas Kohlbecker
 *
406 c367b0ab Andreas Kohlbecker
 * @ingroup compose
407 6657531f Andreas Kohlbecker
 */
408 c367b0ab Andreas Kohlbecker
function compose_cdm_feature_block_elements($elements, $feature, $glue = '', $sort = FALSE, $enclosing_tag = 'ul') {
409
410 22f5e82d Andreas Kohlbecker
  $feature_block_settings = get_feature_block_settings($feature->uuid);
411 c367b0ab Andreas Kohlbecker
  if($feature_block_settings['as_list']){
412
    $enclosing_tag = $feature_block_settings['as_list'];
413
  }
414 28c5c87a Andreas Kohlbecker
415 c367b0ab Andreas Kohlbecker
  $out = '<' . $enclosing_tag . ' class="feature-block-elements" id="' . $feature->representation_L10n . '">';
416 6657531f Andreas Kohlbecker
417 c367b0ab Andreas Kohlbecker
  if ($sort) {
418
    sort($elements);
419 6657531f Andreas Kohlbecker
  }
420
421 c367b0ab Andreas Kohlbecker
  //TODO it would be nice if any element would get "feature-block-element" as additional class attribute
422
  //     this will become possible once all $elemets are real Drupal render arrays
423 44d445c0 Andreas Kohlbecker
  $out .= join($glue, $elements) ;
424 6657531f Andreas Kohlbecker
425 c367b0ab Andreas Kohlbecker
  $out .= '</' . $enclosing_tag . '>';
426 6f5c7f2a Andreas Kohlbecker
  return markup_to_render_array($out);
427 6657531f Andreas Kohlbecker
}
428
429
430
/**
431 ac8bfc49 Andreas Kohlbecker
 * Theme function to render CDM DescriptionElements of the type CategoricalData.
432
 *
433
 * @param array $variables
434
 *   An associative array containing:
435
 *  - element: the CategoricalData element
436
 * @return a html representation of the given CategoricalData element
437
 *
438
 * @ingroup themeable
439 2ba0f3bd Andreas Kohlbecker
 */
440 6657531f Andreas Kohlbecker
function theme_cdm_descriptionElement_CategoricalData($variables) {
441
  $element = $variables['element'];
442 e9bc1326 Andreas Kohlbecker
443 6657531f Andreas Kohlbecker
  $state_data_strings = array();
444 acf3a2e7 Andreas Kohlbecker
  if (isset($element->stateData)) {
445
    foreach ($element->stateData as $stateData) {
446 3445600f Andreas Kohlbecker
447 e9bc1326 Andreas Kohlbecker
      $state  = NULL;
448 3445600f Andreas Kohlbecker
449 e9bc1326 Andreas Kohlbecker
      if(isset($stateData->state)){
450 6657531f Andreas Kohlbecker
        $state = cdm_term_representation($stateData->state);
451 e9bc1326 Andreas Kohlbecker
      }
452 6657531f Andreas Kohlbecker
453 e9bc1326 Andreas Kohlbecker
      if (isset($stateData->modifyingText_L10n)) {
454 3445600f Andreas Kohlbecker
        $state = ' ' . $stateData->modifyingText_L10n;
455 e9bc1326 Andreas Kohlbecker
      }
456 6657531f Andreas Kohlbecker
457 3445600f Andreas Kohlbecker
      $modifiers_strings = cdm_modifers_representations($stateData);
458 6657531f Andreas Kohlbecker
459 3445600f Andreas Kohlbecker
      $state_data_strings[] = $state . ($modifiers_strings ? ' ' . $modifiers_strings : '');
460
461 6657531f Andreas Kohlbecker
    }
462
  }
463 acf3a2e7 Andreas Kohlbecker
464
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
465
466 f19f47fa Andreas Kohlbecker
  $out = '<span class="' . html_class_attribute_ref($element) . '">' . implode(', ', $state_data_strings) . '</span>';
467 acf3a2e7 Andreas Kohlbecker
  return $out . $footnote_key_list_str;
468 6657531f Andreas Kohlbecker
}
469
470 ac8bfc49 Andreas Kohlbecker
/**
471
 * Theme function to render CDM DescriptionElements of the type QuantitativeData.
472
 *
473
 * @param array $variables
474
 *   An associative array containing:
475
 *  - element: the QuantitativeData element
476
 * @return a html representation of the given QuantitativeData element
477
 *
478
 * @ingroup themeable
479
 */
480 3445600f Andreas Kohlbecker
function theme_cdm_descriptionElement_QuantitativeData($variables) {
481
  /*
482
   * - statisticalValues
483
   *   - value
484
   *   - modifiers
485
   *   - type
486
   * - unit->representation_L10n
487
   * - modifyingText
488
   * - modifiers
489
   * - sources
490
   */
491
  $element = $variables['element'];
492
493
  $out = '';
494
495
  $type_representation = NULL;
496
  $modifiers_strings = array();
497
498
499
  if (isset($element->statisticalValues)) {
500
    $value_array = array();
501
    foreach ($element->statisticalValues as $val) {
502
      if (isset($val->value)) {
503
        $value_array[] = $val->value;
504
      }
505
    }
506
507
    $out .= implode($value_array, ', ');
508
  }
509
510 f19f47fa Andreas Kohlbecker
  if (isset($element->unit)) {
511
    $out .= ' '. cdm_term_representation($element->unit);
512 3445600f Andreas Kohlbecker
  }
513
514
  if (isset($element->statisticalValues->modifyingText_L10n)) {
515
    $out .=  ' ' . $element->statisticalValues->modifyingText_L10n;
516
  }
517 28c5c87a Andreas Kohlbecker
  $modifiers_strings = cdm_modifers_representations($element->statisticalValues);
518
  $out .= ($modifiers_strings ? ' ' . cdm_modifers_representations($element->statisticalValues) : '');
519 3445600f Andreas Kohlbecker
520 1f11e206 Andreas Kohlbecker
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
521 3445600f Andreas Kohlbecker
522 1f11e206 Andreas Kohlbecker
  return $out . $footnote_key_list_str;
523 3445600f Andreas Kohlbecker
524
}
525
526 2ba0f3bd Andreas Kohlbecker
/**
527
 * Theme function to render CDM DescriptionElements of the type IndividualsAssociations.
528
 *
529 ac8bfc49 Andreas Kohlbecker
 * @param array $variables
530
 *   An associative array containing:
531
 *  - element: the IndividualsAssociations element
532
 * @return html representation of the given IndividualsAssociations element
533
 *
534
 * @ingroup themeable
535 2ba0f3bd Andreas Kohlbecker
 */
536
function theme_cdm_descriptionElement_IndividualsAssociation($variables) {
537
538
  $element = $variables['element'];
539
540
  $out = '';
541
542
  $render_array = compose_cdm_specimenOrObservation($element->associatedSpecimenOrObservation);
543
544
  if (isset($element->description_L10n)) {
545
    $out .=  ' ' . $element->description_L10n;
546
  }
547
548
  $out .= drupal_render($render_array);
549 1f11e206 Andreas Kohlbecker
550
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
551
552
  return $out . $footnote_key_list_str;
553 2ba0f3bd Andreas Kohlbecker
554
555
}
556
557
/**
558
 * Theme function to render CDM DescriptionElements of the type TaxonInteraction.
559
 *
560 ac8bfc49 Andreas Kohlbecker
 * @param array $variables
561
 *   An associative array containing:
562
 *  - element: the TaxonInteraction element
563
 * @return html representation of the given TaxonInteraction element
564
 *
565
 * @ingroup themeable
566 2ba0f3bd Andreas Kohlbecker
 */
567
function theme_cdm_descriptionElement_TaxonInteraction($variables) {
568
569
  $element = $variables['element'];
570
571
  $out = '';
572
573
  if (isset($element->description_L10n)) {
574
    $out .=  ' ' . $element->description_L10n;
575
  }
576
577
  if(isset($element->taxon2)){
578
    $out = theme('cdm_taxonName',
579
        array(
580 5b3557f9 Andreas Kohlbecker
            'taxonName' => $element->taxon2->name,
581 05e1b851 Andreas Kohlbecker
            'nameLink' => url(path_to_taxon($element->taxon2->uuid))
582 2ba0f3bd Andreas Kohlbecker
        )
583
      );
584
  }
585
586 1f11e206 Andreas Kohlbecker
  $footnote_key_list_str = cdm_create_description_element_footnotes($element);
587
588
  return $out . $footnote_key_list_str;
589 2ba0f3bd Andreas Kohlbecker
590
591
}
592
593 6657531f Andreas Kohlbecker
/**
594 44d445c0 Andreas Kohlbecker
 * Composes a drupal render array for CDM TextData description elements.
595 6657531f Andreas Kohlbecker
 *
596 159cd9bb Andreas Kohlbecker
 * @param $element
597
 *    The CDM TextData description element which contains the textual  information.
598
 * @param $asListElement
599
 *    A boolean which determines whether the citations should
600 6657531f Andreas Kohlbecker
 *     be rendered as a list or not.
601 159cd9bb Andreas Kohlbecker
 *    TODO remove and replace $asListElement by $feature_block_settings['as_list']
602
 *  @param $feature_uuid
603 6657531f Andreas Kohlbecker
 *
604 159cd9bb Andreas Kohlbecker
 * @return array
605
 *   A drupal render array with the following elements being used:
606
 *    - #tag: either 'div', 'li', ...
607
 *    ⁻ #attributes: class attributes
608
 *    - #value_prefix: (optionally) contains footnote anchors
609
 *    - #value: contains the textual content
610
 *    - #value_suffix: (optionally) contains footnote keys
611
 *
612
 * @ingroup compose
613 6657531f Andreas Kohlbecker
 */
614 159cd9bb Andreas Kohlbecker
function compose_cdm_descriptionElementTextData($element, $asListElement, $feature_uuid) {
615 235fc94b Andreas Kohlbecker
616 6f5c7f2a Andreas Kohlbecker
  $footnote_list_key_suggestion = $feature_uuid;
617 22f5e82d Andreas Kohlbecker
618
  // FIXME $feature_block_settings should be passed as parameter!!!!!
619
  $feature_block_settings = get_feature_block_settings($feature_uuid);
620 f3a04cfa Andreas Kohlbecker
  $do_references_inline = $feature_block_settings['sources_as_content'];
621 22f5e82d Andreas Kohlbecker
622
  // FIXME remove this hack ---------------------------
623
  $default_theme = variable_get('theme_default', NULL);
624
  if($default_theme == 'garland_cichorieae' || $default_theme == 'cyprus'
625
    || $default_theme == 'flore_afrique_centrale' || $default_theme == 'flora_malesiana' || $default_theme == 'flore_gabon' ){
626
    $asListElement = $feature_block_settings['as_list'] == 'ul';
627
  }
628
  // --------------------------------------------------
629 235fc94b Andreas Kohlbecker
630 159cd9bb Andreas Kohlbecker
  $render_array = array(
631
    '#type' => 'html_tag',
632
    '#tag' => $asListElement ? 'li' : 'span',
633
    '#attributes' => array(
634
      'class' => 'DescriptionElement DescriptionElement-' . $element->class . '
635
      ' .  html_class_attribute_ref($element)
636
    ),
637
    '#value' => '',
638
    '#value_suffix' => NULL
639
  );
640
641 44d445c0 Andreas Kohlbecker
  $element_text = '';
642 6657531f Andreas Kohlbecker
  if (isset($element->multilanguageText_L10n->text)) {
643 44d445c0 Andreas Kohlbecker
    // TODO replacement of \n by <br> should be configurable
644
    $element_text = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
645 6657531f Andreas Kohlbecker
  }
646 28c5c87a Andreas Kohlbecker
647 44d445c0 Andreas Kohlbecker
  $annotations_and_sources = handle_annotations_and_sources($element, $do_references_inline, $feature_block_settings, $element_text, $footnote_list_key_suggestion);
648 b5854b72 Andreas Kohlbecker
649 44d445c0 Andreas Kohlbecker
  $names_used_in_source_markup = '';
650
  if (!empty($annotations_and_sources['names_used_in_source']) && empty($element_text)) {
651
    // $element_text ==  NULL  usually occurs only in the case of CITATIONS!!!
652
    $names_used_in_source_markup = join(', ', $annotations_and_sources['names_used_in_source']) . ': ';
653
  }
654 22f5e82d Andreas Kohlbecker
655 44d445c0 Andreas Kohlbecker
  $source_references_markup = '';
656
  if(!empty($annotations_and_sources['source_references'])){
657
    $source_references_markup = '<span class="sources">'. join(' ', $annotations_and_sources['source_references']) . '<span>';
658
  }
659 6657531f Andreas Kohlbecker
660 44d445c0 Andreas Kohlbecker
  $render_array['#value'] = $names_used_in_source_markup . $element_text . $source_references_markup;
661
  $render_array['#value-suffix'] = $annotations_and_sources['foot_note_keys'];
662 22f5e82d Andreas Kohlbecker
663 44d445c0 Andreas Kohlbecker
  return $render_array;
664
}
665 22f5e82d Andreas Kohlbecker
666 44d445c0 Andreas Kohlbecker
  /**
667
   * @param $element
668
   * @param $do_references_inline
669
   * @param $feature_block_settings
670
   * @param $element_text
671
   * @param $footnote_list_key_suggestion
672
   * @return array
673
   *   an associative array with the following elements:
674
   *   - foot_note_keys: all footnote keys as markup
675
   *   - source_references: an array of the source references citations
676
   *   - names used in source: an associative array of the names in source,
677
   *        the name in source string are deduplicated
678
   *        !!!NOTE!!!!: this field will most probably be removed soon (TODO)
679
   *
680
   * 
681
   */
682
  function handle_annotations_and_sources($element, $do_references_inline, $feature_block_settings, $element_text, $footnote_list_key_suggestion) {
683
    $annotations_and_sources = array(
684
      'foot_note_keys' => NULL,
685
      'source_references' => array(),
686
      'names_used_in_source' => array()
687 6f5c7f2a Andreas Kohlbecker
    );
688 6657531f Andreas Kohlbecker
689 44d445c0 Andreas Kohlbecker
    if ($do_references_inline) {
690
      foreach ($element->sources as $source) {
691 f3a04cfa Andreas Kohlbecker
692 44d445c0 Andreas Kohlbecker
        $referenceCitation = theme('cdm_OriginalSource',
693
          array(
694
            'source' => $source,
695
            'doLink' => $feature_block_settings['link_to_reference']
696
          )
697
        );
698 6657531f Andreas Kohlbecker
699 44d445c0 Andreas Kohlbecker
        if ($referenceCitation) {
700
          if (empty($element_text)) {
701
            $annotations_and_sources['source_references'][] = $referenceCitation;
702
          }
703
          else {
704
            $annotations_and_sources['source_references'][] = ' (' . $referenceCitation . ')';
705
          }
706
        }
707 6f5c7f2a Andreas Kohlbecker
708 44d445c0 Andreas Kohlbecker
        if (isset($source->nameUsedInSource->uuid) && isset($source->nameUsedInSource->titleCache)) {
709
          // it is a DescriptionElementSource
710
          if ($feature_block_settings['link_to_name_used_in_source']) {
711
            // using the titleCache as key to avoid duplicate entries
712
            $annotations_and_sources['names_used_in_source'][$source->nameUsedInSource->titleCache] = l(
713
              $source->nameUsedInSource->titleCache,
714
              path_to_name($source->nameUsedInSource->uuid),
715
              array(
716
                'attributes' => array(),
717
                'absolute' => TRUE,
718
                'html' => TRUE,
719
              ));
720
          }
721
          else {
722
            // using the titleCache as key to avoid duplicate entries
723
            $annotations_and_sources['names_used_in_source'][$source->nameUsedInSource->titleCache] = $source->nameUsedInSource->titleCache;
724
          }
725
        }
726
        else if (isset($source->originalNameString) && !empty($source->originalNameString)) {
727
          // the name used in source can not be expressed as valid taxon name,
728
          // so the editor has chosen to put the freetext name into ReferencedEntityBase.originalNameString
729
          // field
730
          // using the originalNameString as key to avoid duplicate entries
731
          $annotations_and_sources['names_used_in_source'][$source->originalNameString] = $source->originalNameString;
732
        }
733
      } // END of loop over sources
734
735
      // annotations footnotes separate.
736
      $annotations_and_sources['foot_note_keys'] = theme('cdm_annotations_as_footnotekeys',
737
        array(
738
          'cdmBase_list' => $element,
739
          'footnote_list_key' => $footnote_list_key_suggestion,
740
        )
741
      );
742
743
    } // END of references inline
744
745
    if (!$do_references_inline || $feature_block_settings['sources_as_content_to_bibliography']) {
746
      $annotations_and_sources['foot_note_keys'] = cdm_create_description_element_footnotes($element, ',', $footnote_list_key_suggestion);
747
      return $annotations_and_sources;
748 6f5c7f2a Andreas Kohlbecker
    }
749 44d445c0 Andreas Kohlbecker
    return $annotations_and_sources;
750 6657531f Andreas Kohlbecker
  }
751 092744e1 Andreas Kohlbecker
752 44d445c0 Andreas Kohlbecker
  /**
753 28c5c87a Andreas Kohlbecker
 * Composes block of common names for the given DescriptionElements $elements which must be of the feature CommonName
754
 *
755
 * @parameter $elements
756
 *  an array of CDM DescriptionElements either of type CommonName or TextData
757
 * @parameter $feature
758
 *  the common feature of all $elements, must be CommonName
759
 *
760
 * @return
761
 *   A drupal render array
762
 *
763
 * @ingroup compose
764 6657531f Andreas Kohlbecker
 */
765 6f5c7f2a Andreas Kohlbecker
function compose_cdm_common_names($elements, $feature, $weight = FALSE) {
766 28c5c87a Andreas Kohlbecker
767 6657531f Andreas Kohlbecker
  $common_name_out = '';
768 28c5c87a Andreas Kohlbecker
  $common_name_feature_elements = array();
769 6657531f Andreas Kohlbecker
  $textData_commonNames = array();
770
771 28c5c87a Andreas Kohlbecker
  $footnote_key_suggestion = 'common-names-feature-block';
772
773 6657531f Andreas Kohlbecker
  if (is_array($elements)) {
774
    foreach ($elements as $element) {
775 28c5c87a Andreas Kohlbecker
776 6657531f Andreas Kohlbecker
      if ($element->class == 'CommonTaxonName') {
777 20143e0d Andreas Kohlbecker
778
        // common name without a language or area, should not happen but is possible
779
        $language_area_key = '';
780 6657531f Andreas Kohlbecker
        if (isset($element->language->representation_L10n)) {
781 20143e0d Andreas Kohlbecker
          $language_area_key .= '<b>' . $element->language->representation_L10n . '</b>';
782 6657531f Andreas Kohlbecker
        }
783 20143e0d Andreas Kohlbecker
        if(isset($element->area->titleCache) && strlen($element->area->titleCache) > 0){
784
          $language_area_key .= ($language_area_key ? ' '  : '') . '(' . $element->area->titleCache . ')';
785 ae0a5060 Andreas Kohlbecker
        }
786 20143e0d Andreas Kohlbecker
787 ae0a5060 Andreas Kohlbecker
        if(isset($common_names[$language_area_key][$element->name])) {
788
          // same name already exists for language and areae combination, se we merge the description elements
789
          cdm_merge_description_elements($common_names[$language_area_key][$element->name], $element);
790
        } else{
791
          // otherwise add as new entry
792
          $common_names[$language_area_key][$element->name] = $element;
793 6657531f Andreas Kohlbecker
        }
794 20143e0d Andreas Kohlbecker
795 6657531f Andreas Kohlbecker
      }
796
      elseif ($element->class == 'TextData') {
797
        $textData_commonNames[] = $element;
798
      }
799
    }
800
  }
801
  // Handling common names.
802
  if (isset($common_names) && count($common_names) > 0) {
803
    // Sorting the array based on the key (language, + area if set).
804
    // Comment @WA there are common names without a language, so this sorting
805
    // can give strange results.
806
    ksort($common_names);
807
808 28c5c87a Andreas Kohlbecker
    // loop over set of elements per language area
809
    foreach ($common_names as $language_area_key => $elements) {
810 ae0a5060 Andreas Kohlbecker
      ksort($elements); // sort names alphabetically
811 28c5c87a Andreas Kohlbecker
      $per_language_area_out = array();
812
      // loop over set of individual elements
813 6657531f Andreas Kohlbecker
      foreach ($elements as $element) {
814
        if ($element->name) {
815 28c5c87a Andreas Kohlbecker
          $per_language_area_out[] = '<span class="' . html_class_attribute_ref($element) . '">'
816
          . $element->name . cdm_create_description_element_footnotes($element, ',', $footnote_key_suggestion) . '</span>';
817 6657531f Andreas Kohlbecker
        }
818 28c5c87a Andreas Kohlbecker
      } // End of loop over set of individual elements
819 c367b0ab Andreas Kohlbecker
      $common_name_feature_elements[] = ($language_area_key ? $language_area_key . ': ' : '' ) . join(', ', $per_language_area_out);
820 28c5c87a Andreas Kohlbecker
    } // End of loop over set of elements per language area
821
822
823 6f5c7f2a Andreas Kohlbecker
    $common_name_feature_elements_render_array = compose_cdm_feature_block_elements(
824
      $common_name_feature_elements,
825
      $feature,
826
      '; ',
827
      FALSE,
828
      'div'
829 c367b0ab Andreas Kohlbecker
      );
830 6f5c7f2a Andreas Kohlbecker
    $common_name_out .= $common_name_feature_elements_render_array['#markup'];
831 28c5c87a Andreas Kohlbecker
832 6657531f Andreas Kohlbecker
  }
833 28c5c87a Andreas Kohlbecker
834 6657531f Andreas Kohlbecker
  // Handling commons names as text data.
835 28c5c87a Andreas Kohlbecker
  $text_data_out = array();
836
837 6657531f Andreas Kohlbecker
  foreach ($textData_commonNames as $text_data_element) {
838 28c5c87a Andreas Kohlbecker
    /* footnotes are not handled correctly in theme_cdm_descriptionElementTextData,
839
       need to set 'common-names-feature-block' as $footnote_key_suggestion */
840
    RenderHints::setFootnoteListKey($footnote_key_suggestion);
841 159cd9bb Andreas Kohlbecker
    $text_data_render_array = compose_cdm_descriptionElementTextData($text_data_element, TRUE, $text_data_element->feature->uuid);
842
    $text_data_out[] = drupal_render($text_data_render_array);
843 6657531f Andreas Kohlbecker
  }
844
845 c367b0ab Andreas Kohlbecker
  $common_name_out_text_data = compose_cdm_feature_block_elements(
846
        $text_data_out,
847
        $feature
848 28c5c87a Andreas Kohlbecker
      );
849 6657531f Andreas Kohlbecker
850 28c5c87a Andreas Kohlbecker
851
  $footnotes = theme('cdm_footnotes', array('footnoteListKey' => $footnote_key_suggestion)); // FIXME is this needed at all?
852
  $footnotes .= theme('cdm_annotation_footnotes', array('footnoteListKey' => $footnote_key_suggestion));
853
854
  return  markup_to_render_array(
855
    '<div class="common_names_as_common_names">' . $common_name_out . '</div>'
856 6f5c7f2a Andreas Kohlbecker
    .'<div class="common_names_as_text_data">' . $common_name_out_text_data['#markup'] . '</div>'
857
    .$footnotes,
858
    $weight
859 28c5c87a Andreas Kohlbecker
  );
860 6657531f Andreas Kohlbecker
}
861
862
/**
863
 * Return HTML for a list of description elements.
864
 *
865
 * Usually these are of a specific feature type.
866
 *
867 6f5c7f2a Andreas Kohlbecker
 * @param $descriptionElements
868
 *   array of descriptionElements which belong to the same feature.
869
 *   These descriptions elements of a Description must be ordered by the chosen feature tree by
870
 *   calling the function _mergeFeatureTreeDescriptions().
871
 *   @see _mergeFeatureTreeDescriptions()
872 159cd9bb Andreas Kohlbecker
 *
873
 * @param  $feature_uuid
874
 *
875
 * @return
876
 *    A drupal render array for the $descriptionElements, may be an empty array if the textual content was empty.
877
 *    Footnote key or anchors are not considered to be textual content.
878 6657531f Andreas Kohlbecker
 *
879 6f5c7f2a Andreas Kohlbecker
 * @ingroup compose
880 6657531f Andreas Kohlbecker
 */
881 fa782b11 Andreas Kohlbecker
function compose_cdm_descriptionElements($descriptionElements, $feature) {
882 235fc94b Andreas Kohlbecker
883 159cd9bb Andreas Kohlbecker
  $render_array = array();
884
  $elements_out_array = array();
885 6f5c7f2a Andreas Kohlbecker
  $distribution_tree = null;
886 6657531f Andreas Kohlbecker
887 159cd9bb Andreas Kohlbecker
  /*
888
   * $feature_block_has_content will be set true if at least one of the
889
   * $descriptionElements contains some text which makes up some content
890
   * for the feature block. Footnote keys are not considered
891
   * to be content in this sense.
892
   */
893
  $feature_block_has_content = false;
894
895 6657531f Andreas Kohlbecker
  /*
896 092744e1 Andreas Kohlbecker
  $userDefined = mixed_variable_get(LAYOUT_SETTING_PREFIX . $feature_uuid, FEATURE_TREE_LAYOUT_DEFAULTS);
897 bfb2b81a Andreas Kohlbecker
  if(variable_get('distribution_sort',
898
      'NO_SORT') != 'NO_SORT'){
899
      $glue = '';
900
      $enclosingTag = 'dl';
901
      $entryEnclosingTag = NULL;
902
  } else if($userDefined &&
903
      $userDefined['enabled']){
904
    $glue = $userDefined['glue'];
905
    $enclosingTag =  $userDefined['enclosingTag'];
906
    $entryEnclosingTag = $userDefined['entryEnclosingTag'];
907
  } else { // TODO remove once  LAYOUT_SETTING_PREFIX-{uuid} setting are configured to work for all portals(selenium test still missing!!!)
908
    $glue = ''; $enclosingTag = 'ul';
909
    $entryEnclosingTag = NULL ;
910
  }
911 6657531f Andreas Kohlbecker
  */
912
913
  RenderHints::pushToRenderStack('cdm_descriptionElements');
914
915 2fc97419 Andreas Kohlbecker
  if (is_array($descriptionElements)) {
916 092744e1 Andreas Kohlbecker
    // --- normal description element arrays
917 6657531f Andreas Kohlbecker
    foreach ($descriptionElements as $descriptionElement) {
918
919
      // --- IMAGE_SOURCES --- //
920 092744e1 Andreas Kohlbecker
      if ($descriptionElement->feature->uuid == UUID_IMAGE_SOURCES) {
921 6657531f Andreas Kohlbecker
        $image_sources[] = $descriptionElement;
922
      }
923
      // --- USE TEXTDATA --- //
924
      elseif ($descriptionElement->feature->uuid == UUID_USE) {
925
        // Do nothing to avoid rendering.
926
      } else {
927
        /* decide based on the description element class
928 22f5e82d Andreas Kohlbecker
         *
929
         * Features handled here:
930
         * all except DISTRIBUTION, COMMON_NAME, USES, IMAGES,
931
         *
932 6657531f Andreas Kohlbecker
         *
933 f3a04cfa Andreas Kohlbecker
         * TODO provide api_hook as extension point for this?
934 6657531f Andreas Kohlbecker
         */
935 f3a04cfa Andreas Kohlbecker
        $feature_block_settings = get_feature_block_settings($descriptionElement->feature->uuid);
936
        $asListElement  = $feature_block_settings['as_list'] == 'ul';
937 6657531f Andreas Kohlbecker
        switch ($descriptionElement->class) {
938
          case 'TextData':
939 159cd9bb Andreas Kohlbecker
              $text_data_render_array = compose_cdm_descriptionElementTextData($descriptionElement, $asListElement, $descriptionElement->feature->uuid);
940
              $feature_block_has_content = $feature_block_has_content || !empty($text_data_render_array['#value']);
941
              $elements_out_array[] = drupal_render($text_data_render_array);
942 6657531f Andreas Kohlbecker
            break;
943
          case 'CategoricalData':
944 159cd9bb Andreas Kohlbecker
            $feature_block_has_content = true;
945
            $elements_out_array[] = theme('cdm_descriptionElement_CategoricalData', array('element' => $descriptionElement));
946 6657531f Andreas Kohlbecker
            break;
947 f19f47fa Andreas Kohlbecker
          case 'QuantitativeData':
948 159cd9bb Andreas Kohlbecker
            $feature_block_has_content = true;
949
            $elements_out_array[] = theme('cdm_descriptionElement_QuantitativeData', array('element' => $descriptionElement));
950 3445600f Andreas Kohlbecker
            break;
951 2ba0f3bd Andreas Kohlbecker
          case 'IndividualsAssociation':
952 159cd9bb Andreas Kohlbecker
            $feature_block_has_content = true;
953
            $elements_out_array[] = theme('cdm_descriptionElement_IndividualsAssociation', array('element' => $descriptionElement));
954 2ba0f3bd Andreas Kohlbecker
            break;
955
          case 'TaxonInteraction':
956 159cd9bb Andreas Kohlbecker
            $feature_block_has_content = true;
957
            $elements_out_array[] = theme('cdm_descriptionElement_TaxonInteraction', array('element' => $descriptionElement));
958 2ba0f3bd Andreas Kohlbecker
            break;
959 3445600f Andreas Kohlbecker
          case 'Uses':
960 29809fe3 Andreas Kohlbecker
          /* IGNORE Uses classes, these are handled completely in theme_cdm_UseDescription */
961 6657531f Andreas Kohlbecker
          break;
962
        default:
963 159cd9bb Andreas Kohlbecker
          $feature_block_has_content = true;
964
          $elements_out_array[] = '<li>No method for rendering unknown description class: ' . $descriptionElement->class . '</li>';
965 6657531f Andreas Kohlbecker
      }
966
    }
967 092744e1 Andreas Kohlbecker
    } // --- END loop over normal description element arrays
968 6657531f Andreas Kohlbecker
969 c367b0ab Andreas Kohlbecker
    // If feature = CITATION sort the list of sources.
970 092744e1 Andreas Kohlbecker
    // This is ONLY for FLORA MALESIANA and FLORE d'AFRIQUE CENTRALE.
971 c367b0ab Andreas Kohlbecker
    if ($descriptionElement->feature->uuid == UUID_CITATION) {
972 159cd9bb Andreas Kohlbecker
      sort($elements_out_array);
973 092744e1 Andreas Kohlbecker
    }
974 6657531f Andreas Kohlbecker
975 092744e1 Andreas Kohlbecker
    if (isset($image_sources)) {
976 159cd9bb Andreas Kohlbecker
      $elements_out_array[] = theme('cdm_description_element_image_source', array('image_sources' => $image_sources, 'asListElement' => TRUE));
977 092744e1 Andreas Kohlbecker
    }
978
  } // END normal description element arrays
979 6657531f Andreas Kohlbecker
980 159cd9bb Andreas Kohlbecker
  if($feature_block_has_content){
981
    $render_array = compose_cdm_feature_block_elements(
982
      $elements_out_array,
983
      $feature
984
    );
985
  }
986 6657531f Andreas Kohlbecker
987
  RenderHints::popFromRenderStack();
988 6f5c7f2a Andreas Kohlbecker
  return $render_array;
989 6657531f Andreas Kohlbecker
}
990
991
/**
992
 * @todo Please document this function.
993
 * @see http://drupal.org/node/1354
994
 */
995
function compare_image_sources($a, $b) {
996
  if ($a->multilanguageText_L10n->text == $b->multilanguageText_L10n->text) {
997
    return 0;
998
  }
999
  return ($a->multilanguageText_L10n->text < $b->multilanguageText_L10n->text) ? -1 : 1;
1000
}
1001
1002
/**
1003
 * @todo Please document this function.
1004
 * @see http://drupal.org/node/1354
1005
 */
1006
function theme_cdm_description_element_image_source($variables) {
1007
  $image_sources = $variables['image_sources'];
1008
  $asListElement = $variables['asListElement'];
1009
  $out = '';
1010
  $separator = ',';
1011
  RenderHints::pushToRenderStack('descriptionElementImageSource');
1012
  RenderHints::setFootnoteListKey(UUID_IMAGE_SOURCES);
1013
1014
  // Sorting the image sources.
1015
  usort($image_sources, "compare_image_sources");
1016
  // Generate the footnotes.
1017
  foreach ($image_sources as $image_source) {
1018
    $footNoteKeys = cdm_annotations_as_footnotekeys($image_source);
1019
    foreach ($image_source->sources as $source) {
1020
      if (_is_original_source_type($source)) {
1021 f19f47fa Andreas Kohlbecker
        $fn_key = FootnoteManager::addNewFootnote(original_source_footnote_list_key(), theme('cdm_OriginalSource', array(
1022 1b04a204 Andreas Kohlbecker
          'source' => $source,
1023 6657531f Andreas Kohlbecker
          'doLink' => FALSE,
1024
        )));
1025
        // Ensure uniqueness of the footnote keys.
1026
        cdm_add_footnote_to_array($footNoteKeys, $fn_key);
1027
      }
1028
    }
1029
    // Sort and render footnote keys.
1030 1f11e206 Andreas Kohlbecker
    $footnote_key_list_str = '';
1031 6657531f Andreas Kohlbecker
    asort($footNoteKeys);
1032
    foreach ($footNoteKeys as $footNoteKey) {
1033 1f11e206 Andreas Kohlbecker
      $footnote_key_list_str .= theme('cdm_footnote_key', array('footnoteKey' => $footNoteKey, 'separator' => ($footnote_key_list_str ? $separator : '')));
1034 6657531f Andreas Kohlbecker
    }
1035
    // Return value!
1036 1f11e206 Andreas Kohlbecker
    $out .= '<span class="descriptionElement descriptionElement-' . $image_source->uuid . '">' . $image_source->multilanguageText_L10n->text . $footnote_key_list_str . '; </span>';
1037 6657531f Andreas Kohlbecker
  }
1038
1039
  RenderHints::popFromRenderStack();
1040
  return $out;
1041
}
1042
1043
/**
1044 44d445c0 Andreas Kohlbecker
 * Composes the render array for a CDM Distribution element
1045
 *
1046
 * @param $descriptionElements
1047
 *   The CDM Distribution element
1048
 * @param $enclosingTag
1049
 *   The html tag to be use for the enclosing element
1050
 *
1051
 * @return array
1052
 *   A Drupal render array
1053
 *
1054
 * @ingroup compose
1055 6657531f Andreas Kohlbecker
 */
1056 44d445c0 Andreas Kohlbecker
function compose_cdm_descriptionElement_Distribution($descriptionElements, $enclosingTag = "span"){
1057 6657531f Andreas Kohlbecker
1058
  $out = '';
1059
  RenderHints::pushToRenderStack('descriptionElementDistribution');
1060
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
1061
1062
  foreach ($descriptionElements as $descriptionElement) {
1063 1f11e206 Andreas Kohlbecker
    $footnote_key_list_str = cdm_create_description_element_footnotes($descriptionElement);
1064 6657531f Andreas Kohlbecker
1065 1f11e206 Andreas Kohlbecker
    $out .= '<' . $enclosingTag . ' class="descriptionElement descriptionElement-' . $descriptionElement->uuid . '">'
1066
        . $descriptionElement->area->representation_L10n . $footnote_key_list_str
1067
        . ' </' . $enclosingTag . '>';
1068 6657531f Andreas Kohlbecker
  }
1069
1070
  RenderHints::popFromRenderStack();
1071 44d445c0 Andreas Kohlbecker
  return markup_to_render_array($out);
1072 6657531f Andreas Kohlbecker
}
1073
1074 1f11e206 Andreas Kohlbecker
1075 6657531f Andreas Kohlbecker
/**
1076
 * Compare two different footnotes objects.
1077
 *
1078
 * The comparison is based on the footnote key. The one which is
1079
 * displayed as footnote number.
1080
 *
1081
 * @param mixed $a
1082
 *   Footnote object $a.
1083
 * @param mixed $b
1084
 *   Footnote object $b.
1085
 */
1086
function footnotes_key_compare($a, $b) {
1087
  $res = 0;
1088
  if (empty($a) || empty($b)) {
1089
    return $res;
1090
  }
1091
  if ($a->keyStr < $b->keyStr) {
1092
    $res = -1;
1093
  }
1094
  elseif ($a->keyStr > $b->keyStr) {
1095
    $res = 1;
1096
  }
1097
  return $res;
1098
}
1099
1100
/**
1101
 * @todo Please document this function.
1102
 * @see http://drupal.org/node/1354
1103
 */
1104
function theme_cdm_description_ordered_distributions($variables) {
1105 bfb2b81a Andreas Kohlbecker
1106 092744e1 Andreas Kohlbecker
  $distribution_tree = $variables['distribution_tree'];
1107 bfb2b81a Andreas Kohlbecker
1108 6657531f Andreas Kohlbecker
  // Returning NULL if there are no description elements.
1109 092744e1 Andreas Kohlbecker
  if ($distribution_tree == null) {
1110 bfb2b81a Andreas Kohlbecker
    return NULL;
1111 6657531f Andreas Kohlbecker
  }
1112 bfb2b81a Andreas Kohlbecker
1113 6657531f Andreas Kohlbecker
  // Initialization of some variables.
1114
  $out = '';
1115
  $separator = ',';
1116
  RenderHints::pushToRenderStack('descriptionElementDistribution');
1117
  RenderHints::setFootnoteListKey(UUID_DISTRIBUTION);
1118 bfb2b81a Andreas Kohlbecker
1119 092744e1 Andreas Kohlbecker
  $ordered_areas = $distribution_tree;
1120 6657531f Andreas Kohlbecker
  if (isset($ordered_areas->rootElement->children)) {
1121
    $ordered_areas = $ordered_areas->rootElement->children;
1122
  }
1123
1124
  // Printing the distributions.
1125
  if (is_array($ordered_areas) && count($ordered_areas) > 0) {
1126
    foreach ($ordered_areas as $element_level1) {
1127
      // Level1.
1128 85b65ccc Andreas Kohlbecker
      $out .= '<dt>' . $element_level1->nodeId->representation_L10n . ':</dt> ';
1129 6657531f Andreas Kohlbecker
      $out .= '<dd>';
1130
1131
      // Level3.
1132
      foreach ($element_level1->children as $element_level3) {
1133 85b65ccc Andreas Kohlbecker
        $text_l3 = $element_level3->nodeId->representation_L10n;
1134 6657531f Andreas Kohlbecker
        $fnKeysLevel3Str = '';
1135
        $fnKeysLevel3 = cdm_annotations_as_footnotekeys($element_level3->data);
1136 85b65ccc Andreas Kohlbecker
        if (isset($element_level3->data[0])) {
1137
          foreach ($element_level3->data as $description_level3){
1138
            foreach ($description_level3->sources as $source) {
1139
              if (_is_original_source_type($source)) {
1140 bdd7d687 Andreas Kohlbecker
                $fn_key3 = FootnoteManager::addNewFootnote(
1141
                  original_source_footnote_list_key(),
1142
                  theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)
1143
                ));
1144 85b65ccc Andreas Kohlbecker
                cdm_add_footnote_to_array($fnKeysLevel3, $fn_key3);
1145
              }
1146
            }
1147 6657531f Andreas Kohlbecker
          }
1148
        }
1149
        // Level4.
1150
        $l4_regions = array();
1151
        foreach ($element_level3->children as $element_level4) {
1152 85b65ccc Andreas Kohlbecker
          if (isset($element_level4->data[0])) {
1153
            $text_l4 = $element_level4->nodeId->representation_L10n;
1154
            $l4_regions[$element_level3->nodeId->representation_L10n] = array();
1155 6657531f Andreas Kohlbecker
            $fnKeysLevel4Str = '';
1156 85b65ccc Andreas Kohlbecker
            foreach($element_level4->data as $description_level4) {
1157
              $fnKeysLevel4 = cdm_annotations_as_footnotekeys($description_level4);
1158
              foreach ($description_level4->sources as $source) {
1159
                if (_is_original_source_type($source)) {
1160
                  $fn_key4 = FootnoteManager::addNewFootnote(
1161 f19f47fa Andreas Kohlbecker
                      original_source_footnote_list_key(),
1162 85b65ccc Andreas Kohlbecker
                      theme('cdm_OriginalSource', array('source' => $source, 'doLink' => FALSE)));
1163
                  cdm_add_footnote_to_array($fnKeysLevel4, $fn_key4);
1164
                }
1165
              }
1166
              usort($fnKeysLevel4, "footnotes_key_compare");
1167
              if(!isset( $l4_regions[$text_l4])){
1168
                $l4_regions[$text_l4] = $fnKeysLevel4;
1169
              } else {
1170
                $l4_regions[$text_l4] = array_merge($l4_regions[$text_l4], $fnKeysLevel4);
1171 6657531f Andreas Kohlbecker
              }
1172
            }
1173
          }
1174
        }// Level4.
1175
        // Managing level3 and level4 for generating the right output.
1176
        usort($fnKeysLevel3, "footnotes_key_compare");
1177
        foreach ($fnKeysLevel3 as $key3) {
1178
          foreach ($l4_regions as $key4 => $value4) {
1179
            cdm_add_footnote_to_array($l4_regions[$key4], $key3);
1180
          }
1181
        }
1182 85b65ccc Andreas Kohlbecker
        if ($element_level3->numberOfChildren == 1 && $text_l3 == $element_level3->children[0]->nodeId->representation_L10n) {
1183 6657531f Andreas Kohlbecker
          // var_dump($element_level3->children[0]->data->area->representation_L10n);
1184
          $fnStr = '';
1185
          $region = array_pop($l4_regions);
1186
          foreach ($region as $key) {
1187
            $fnStr .= theme('cdm_footnote_key', array('footnoteKey' => $key, 'separator' => ($fnStr ? $separator : '')));
1188
          }
1189
          $out .= "$text_l3 $fnStr; ";
1190
          // Removing whitespaces when &fnStr is empty.
1191
          if (substr($out, -3) == ' ; ') {
1192
            $out = substr($out, 0, -3) . '; ';
1193
          }
1194 85b65ccc Andreas Kohlbecker
        } else {
1195 6657531f Andreas Kohlbecker
          $fnKeysLevel3Str = '';
1196
          foreach ($fnKeysLevel3 as $key) {
1197
            $fnKeysLevel3Str .= theme('cdm_footnote_key', array('footnoteKey' => $key, 'separator' => ($fnKeysLevel3Str ? $separator : '')));
1198
          }
1199
          $text_l4_aux = '';
1200
          foreach ($l4_regions as $key => $value) {
1201
            $fnKeysLevel4Str = '';
1202
            if (is_array($l4_regions[$key])) {
1203 85b65ccc Andreas Kohlbecker
              foreach ($l4_regions[$key] as $fnkey) {
1204 6657531f Andreas Kohlbecker
                $fnKeysLevel4Str .= theme('cdm_footnote_key', array('footnoteKey' => $fnkey, 'separator' => ($fnKeysLevel4Str ? $separator : '')));
1205
              }
1206
            }
1207
            // if ($key != $text_l3 || sizeof($l4_regions > 1)){
1208
            if ($key != $text_l3) {
1209
              $text_l4_aux .= "$key $fnKeysLevel4Str, ";
1210
            }
1211
          }
1212
          $text_l4_aux = substr($text_l4_aux, 0, -2);
1213
1214
          if (strlen($text_l4_aux) > 0) {
1215
            $out .= "$text_l3 $fnKeysLevel3Str ($text_l4_aux); ";
1216
          }
1217
          else {
1218
            $out .= "$text_l3 $fnKeysLevel3Str; ";
1219
          }
1220
        }
1221
      }// Level3.
1222
      $out = substr($out, 0, -2);
1223
      $out .= '.</dd>';
1224
    }// Level1.
1225
  }
1226
  RenderHints::popFromRenderStack();
1227
  return $out;
1228
}
1229 1b04a204 Andreas Kohlbecker
1230 6657531f Andreas Kohlbecker
/**
1231
 * Returns a list of a specific type of IdentificationKeys.
1232
 *
1233
 * The list can be restricteded by a taxon.
1234
 *
1235
 * @param string $type
1236
 *   The simple name of the cdm class implementing the interface
1237
 *   IdentificationKey, valid values are:
1238
 *   PolytomousKey, MediaKey, MultiAccessKey.
1239
 * @param string $taxonUuid
1240
 *   If given this parameter restrict the listed keys to those which have
1241
 *   the taxon identified be this uuid in scope.
1242
 *
1243
 * @return array
1244
 *   List with identification keys.
1245
 */
1246
function _list_IdentificationKeys($type, $taxonUuid = NULL, $pageSize = NULL, $pageNumber = NULL) {
1247
  if (!$type) {
1248
    drupal_set_message(t('Type parameter is missing'), 'error');
1249
    return;
1250
  }
1251
  $cdm_ws_pasepath = NULL;
1252
  switch ($type) {
1253
    case "PolytomousKey":
1254
      $cdm_ws_pasepath = CDM_WS_POLYTOMOUSKEY;
1255
      break;
1256
1257
    case "MediaKey":
1258
      $cdm_ws_pasepath = CDM_WS_MEDIAKEY;
1259
      break;
1260
1261
    case "MultiAccessKey":
1262
      $cdm_ws_pasepath = CDM_WS_MULTIACCESSKEY;
1263
      break;
1264
1265
  }
1266
1267
  if (!$cdm_ws_pasepath) {
1268
    drupal_set_message(t('Type parameter is not valid: ') . $type, 'error');
1269
  }
1270
1271
  $queryParameters = '';
1272
  if (is_numeric($pageSize)) {
1273
    $queryParameters = "pageSize=" . $pageSize;
1274
  }
1275
  else {
1276
    $queryParameters = "pageSize=0";
1277
  }
1278
1279
  if (is_numeric($pageNumber)) {
1280
    $queryParameters = "pageNumber=" . $pageNumber;
1281
  }
1282
  else {
1283
    $queryParameters = "pageNumber=0";
1284
  }
1285
  $queryParameters = NULL;
1286
  if ($taxonUuid) {
1287
    $queryParameters = "findByTaxonomicScope=$taxonUuid";
1288
  }
1289
  $pager = cdm_ws_get($cdm_ws_pasepath, NULL, $queryParameters);
1290
1291
  if (!$pager || $pager->count == 0) {
1292
    return array();
1293
  }
1294
  return $pager->records;
1295
}
1296
1297
/**
1298
 * @todo Please document this function.
1299
 * @see http://drupal.org/node/1354
1300
 */
1301
function theme_cdm_IdentificationKey($variables) {
1302
  $out = '';
1303
  $identificationKey = $variables['identificationKey'];
1304
  $doLinkToKeyPage = $variables['doLinkToKeyPage'];
1305
  $showIdentificationKeyTitle = $variables['showIdentificationKeyTitle'];
1306
  $parentRenderPath = RenderHints::getRenderPath();
1307
  RenderHints::pushToRenderStack("IdentificationKey");
1308
1309
  if ($showIdentificationKeyTitle) {
1310
    if ($doLinkToKeyPage) {
1311
      $out = l($identificationKey->titleCache, path_to_key($identificationKey->class, $identificationKey->uuid));
1312
    }
1313
    else {
1314
      $out = $identificationKey->titleCache;
1315
    }
1316
  }
1317
  if (isset($identificationKey->sources) && is_array($identificationKey->sources)) {
1318 c2486c6b Andreas Kohlbecker
    // order and display sources.
1319
    $sources = oder_sources($identificationKey->sources, TRUE);
1320 29809fe3 Andreas Kohlbecker
    $out .= '<div class="sources">';
1321 c2486c6b Andreas Kohlbecker
    $out .=  implode('', $sources);
1322 6657531f Andreas Kohlbecker
    $out .= '</div>';
1323
  }
1324
  // Display annotations.
1325
  $out .= theme('cdm_annotations', array('annotations' => cdm_ws_getAnnotationsFor($identificationKey), 'enclosingTag' => 'div'));
1326
  RenderHints::popFromRenderStack();
1327
  return $out;
1328
}
1329
1330
/**
1331
 * @todo Please document this function.
1332
 * @see http://drupal.org/node/1354
1333
 */
1334
function theme_cdm_polytomousKey($variables) {
1335
  $polytomousKey = $variables['polytomousKey'];
1336
1337
  // TODO settings needed.
1338
  // @see http://en.wikipedia.org/wiki/Single_access_key#Presentation_styles
1339
  // @see http://dev.e-taxonomy.eu/trac/ticket/2152
1340
  $keyStyle = "linkedStyle";
1341
1342
  RenderHints::pushToRenderStack("polytomousKey");
1343
  // Key nodes in linked style.
1344
  $out = '<table class="polytomousKey polytomousKey_' . $keyStyle . '">';
1345
  $out .= theme('cdm_polytomousKey_' . $keyStyle . '_subgraph', array('polytomousKeyNode' => $polytomousKey->root));
1346
  $out .= '</table>';
1347
  RenderHints::popFromRenderStack();
1348
  return $out;
1349
}
1350
1351
/**
1352
 * @todo Please document this function.
1353
 * @see http://drupal.org/node/1354
1354
 */
1355
function theme_cdm_polytomousKey_linkedStyle_subgraph($variables) {
1356
  $polytomousKeyNode = $variables['polytomousKeyNode'];
1357
  static $statementCountCharacter = '\'';
1358
  $out = "";
1359
1360
  if (is_array($polytomousKeyNode->children)) {
1361
    $childIndex = 0;
1362
1363
    // Render edges of the current node.
1364
    foreach ($polytomousKeyNode->children as &$child) {
1365
1366
      if (!isset($child->statement) && isset($child->taxon->uuid)) {
1367
        // Skip node with empty statements (see below for explanation: "Special
1368
        // case").
1369
        // this skipping here happens always in the next deeper level of iteration
1370
        // the check below is node on the level above
1371
        continue;
1372
      }
1373
1374
      /*
1375
       * Special case: Child nodes with empty statements but taxa as leaf are to
1376
       * treated as if all those taxa where direct children of the source node.
1377
       */
1378
      $islinkToManyTaxa = !isset($child->children[0]->statement) && isset($child->children[0]->taxon->uuid);
1379
      $islinkToTaxon = isset($child->taxon->uuid);
1380
      $islinkToSubKey = isset($child->subkey->uuid);
1381
      $islinkToOtherNode = isset($child->otherNode);
1382
      // Either NULL or 0.
1383
      $islinkToNode = $child->nodeNumber && !$islinkToManyTaxa && !$islinkToOtherNode;
1384 32dccd76 Andreas Kohlbecker
      $hasQuestion = !empty($polytomousKeyNode->question->label_l10n);
1385 6657531f Andreas Kohlbecker
      $hasFeature = isset($polytomousKeyNode->feature);
1386
1387
      // $indentEdge = $hasQuestion && $childIndex > 0;
1388
      // Question.
1389
      if ($hasQuestion && $childIndex == 0) {
1390
        // Place question, as extra table row.
1391
        $out .= '<tr class="question new_section">';
1392
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber) . "</td>";
1393
        $out .= '<td class="question">' . $polytomousKeyNode->question->label_l10n . '</td>';
1394
        $out .= '</tr>';
1395
      }
1396
1397
      $out .= '<tr class="childCount_' . $childIndex . (!$hasQuestion && $childIndex == 0 ? ' new_section' : '') . '">';
1398
1399
      if ($hasQuestion) {
1400
        $out .= '<td class="nodeNumber"></td>';
1401
      }
1402
      else {
1403
        $out .= '<td class="nodeNumber">' . uuid_anchor($polytomousKeyNode->uuid, $polytomousKeyNode->nodeNumber . str_pad("", $childIndex, $statementCountCharacter)) . "</td>";
1404
      }
1405
1406
      $out .= '<td ' . RenderHints::getHtmlElementID($child) . '  class="edge' . ($hasQuestion ? ' edge-indent' : '') . '">';
1407
1408
      // Feature.
1409
      if ($hasFeature) {
1410
        $out .= $polytomousKeyNode->feature->representation_L10n . ": ";
1411
      }
1412
1413
      // Statement.
1414
      $out .= $child->statement->label_l10n;
1415
1416
      // --- Links to nodes taxa and subkeys.
1417
      $out .= '<div class="nodeLink">';
1418
1419
      // Link to a PolytomousKeyNode.
1420
      if ($islinkToNode) {
1421
        $out .= '<div class="nodeLinkToNode">';
1422 1a2294c8 Andreas Kohlbecker
        if (isset($child->modifyingText)) {
1423 6657531f Andreas Kohlbecker
          $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $child->modifyingText));
1424
        }
1425
        $out .= l($child->nodeNumber, request_path(), array(
1426
          'attributes' => NULL,
1427
          'query' => NULL,
1428
          'fragment' => $child->uuid,
1429
        )) . '</div>';
1430
      }
1431
1432
      // Link to a PolytomousKeyNode.
1433
      if ($islinkToOtherNode) {
1434
        $out .= '<div class="nodeLinkToOtherNode">';
1435 1a2294c8 Andreas Kohlbecker
        if (isset($child->modifyingText)) {
1436 6657531f Andreas Kohlbecker
          $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $child->modifyingText));
1437
        }
1438
        $out .= l($child->otherNode->nodeNumber, $_REQUEST["q"], array(
1439
          'attributes' => NULL,
1440
          'query' => NULL,
1441
          'fragment' => $child->otherNode->uuid,
1442
        )) . '</div>';
1443
      }
1444
1445
      // Link to one or many taxa.
1446
      if ($islinkToTaxon || $islinkToManyTaxa) {
1447
1448
        if ($islinkToManyTaxa) {
1449
          $taxonChildren = $child->children;
1450
        }
1451
        else {
1452
          $taxonChildren = array(
1453
            $child,
1454
          );
1455
        }
1456
1457
        foreach ($taxonChildren as $taxonChild) {
1458
          // TODO many taxa $child->children->taxon.
1459
          $out .= '<div class="nodeLinkToTaxon">';
1460 1a2294c8 Andreas Kohlbecker
          if (isset($taxonChild->modifyingText)) {
1461 6657531f Andreas Kohlbecker
            $out .= theme('cdm_poytomousKeyNode_modifyingText', array('modifyingText' => $taxonChild->modifyingText));
1462
          }
1463
          $out .= theme("cdm_taxonName", array('taxonName' => $taxonChild->taxon->name, 'nameLink' => url(path_to_taxon($taxonChild->taxon->uuid))));
1464
          $out .= '</div>';
1465
        }
1466
1467
        // Link to a subkey.
1468
        if ($islinkToSubKey) {
1469
          $out .= '<div class="nodeLinkToSubkey">' . theme('cdm_IdentificationKey', array('identificationKey' => $child->subkey)) . '</div>';
1470
        }
1471
      }
1472
1473
      $out .= '</div>'; // End node link.
1474
      $out .= '</td>'; // End edge.
1475
      $out .= '</tr>';
1476
1477
      $childIndex++;
1478
    }
1479
1480
    // Recurse into child nodes.
1481
    foreach ($polytomousKeyNode->children as &$child) {
1482
      $out .= theme('cdm_polytomousKey_linkedStyle_subgraph', array('polytomousKeyNode' => $child));
1483
    }
1484
  }
1485
1486
  return $out;
1487
}
1488
1489
/**
1490
 * @todo Please document this function.
1491
 * @see http://drupal.org/node/1354
1492
 */
1493
function theme_cdm_poytomousKeyNode_modifyingText($variables) {
1494
  $out = '';
1495
  $modifyingText = $variables['modifyingText'];
1496
  if (is_object($modifyingText)) {
1497
    $i = 0;
1498
    foreach (get_object_vars($modifyingText) as $lang => $languageString) {
1499
      $out .= ($i++ > 0 ? ', ' : '') . '<span class="modifyingText">' . $languageString->text . '</span> ';
1500
    }
1501
  }
1502
  return $out;
1503
}
1504
1505
/**
1506
 * Returns HTML for a list of a specific type of IdentificationKeys.
1507
 *
1508
 * The list can be restricteded by a taxon.
1509
 *
1510
 * @param array $variables
1511
 *   An associative array containing:
1512
 *   - type: The simple name of the cdm class implementing the interface
1513
 *     IdentificationKey, valid values are:
1514
 *     PolytomousKey, MediaKey, MultiAccessKey
1515
 *   - taxonUuid: If given, this parameter restrict the listed keys to those
1516
 *     which have the taxon identified be this uuid in scope.
1517
 *
1518
 * @ingroup themeable
1519
 */
1520
function theme_cdm_list_IdentificationKeys($variables) {
1521
  $type = $variables['type'];
1522
  $taxonUuid = $variables['taxonUuid'];
1523
  $keyList = _list_IdentificationKeys($type, $taxonUuid);
1524
  if (!$keyList || count($keyList) == 0) {
1525
    return;
1526
  }
1527
1528
  RenderHints::pushToRenderStack('list_IdentificationKeys');
1529
  $out = '<ul>';
1530
  foreach ($keyList as $key) {
1531
    $out .= '<li>';
1532
    $out .= theme('cdm_IdentificationKey', array('identificationKey' => $key));
1533
    $out .= '</li>';
1534
  }
1535
  $out .= '</ul>';
1536
  $out .= theme("cdm_annotation_footnotes", array('footnoteListKey' => RenderHints::getRenderPath()));
1537
  RenderHints::popFromRenderStack();
1538
1539
  return $out;
1540
}
1541
1542
/**
1543
 * @todo Please document this function.
1544
 * @see http://drupal.org/node/1354
1545
 */
1546
function theme_cdm_block_IdentificationKeys($variables) {
1547
  $taxonUuid = $variables['taxonUuid'];
1548
  static $types = array(
1549
    "PolytomousKey" => "Polytomous",
1550
    "MediaKey" => "Media",
1551
    "MultiAccessKey" => "Multiaccess",
1552
  );
1553
  RenderHints::pushToRenderStack('block_IdentificationKeys');
1554
  $out = '';
1555
  foreach ($types as $type => $label) {
1556
    $keylist = theme('cdm_list_IdentificationKeys', array('type' => $type, 'taxonUuid' => $taxonUuid));
1557
    if (!$keylist) {
1558
      continue;
1559
    }
1560
    $out .= '<div class="' . $type . '">';
1561
    $out .= '<h3>' . t($label) . "</h3>";
1562
    $out .= $keylist;
1563
    $out .= '</div>';
1564
  }
1565
  RenderHints::popFromRenderStack();
1566
  return $out;
1567
}
1568
1569
/**
1570 ae0a5060 Andreas Kohlbecker
 * This theming function formats the use description and use record list for
1571
 * these descriptions.
1572
 *
1573 6657531f Andreas Kohlbecker
 * @see http://drupal.org/node/1354
1574
 */
1575
function theme_cdm_UseDescription($variables) {
1576
  $descriptions = $variables['description'];
1577
  $taxonUuid = $variables['taxonUuid'];
1578
  $out = '<div id="content"><ul id="Description" class ="description">';
1579
  if ($descriptions == NULL) {
1580
    return;
1581
  }
1582
  $descriptionSynonyms = '';
1583
  $descriptionOut = '';
1584
  $synonymOut = '';
1585
  $currentTaxon = cdm_ws_get(CDM_WS_PORTAL_TAXON, $taxonUuid);
1586
1587
  foreach ($descriptions as $description) {
1588 3daa3743 Andreas Kohlbecker
    $useSummary = '';
1589 6657531f Andreas Kohlbecker
    foreach ($description->elements as $element) {
1590
1591 3a5d0703 Andreas Kohlbecker
      if ($element->feature->uuid == UUID_USE && !(strlen($useSummary) > 0) && isset($element->multilanguageText_L10n)) {
1592 6657531f Andreas Kohlbecker
        $useSummary = $element->multilanguageText_L10n->text;
1593
      }
1594
    }
1595 3445600f Andreas Kohlbecker
    // uses will be ordered by source
1596 6657531f Andreas Kohlbecker
    foreach ($description->sources as $source) {
1597 3445600f Andreas Kohlbecker
      $is_about_current_taxon = FALSE;
1598 6657531f Andreas Kohlbecker
      $originalTaxonUsedInSource = NULL;
1599
      $originalTaxonPager = NULL;
1600
      if ($source->originalNameString) {
1601
        $request_params = array();
1602
        $request_params['query'] = $source->originalNameString;
1603
        $request_params['matchMode'] = "EXACT";
1604
        $originalTaxonPager = cdm_ws_get(CDM_WS_PORTAL_NAME_FINDBYNAME, NULL, queryString($request_params));
1605
        if ($originalTaxonPager->count > 0) {
1606
          $originalTaxonUsedInSource = $originalTaxonPager->records[0];
1607
        }
1608
        else {
1609
          $originalTaxonUsedInSource = $currentTaxon->name;
1610
        }
1611
      }
1612
      else {
1613
        $originalTaxonUsedInSource = $currentTaxon->name;
1614
      }
1615
1616 3445600f Andreas Kohlbecker
      $is_about_current_taxon = $currentTaxon->name->uuid == $originalTaxonUsedInSource->uuid;
1617 6657531f Andreas Kohlbecker
1618 3445600f Andreas Kohlbecker
      if (!$is_about_current_taxon) {
1619 6657531f Andreas Kohlbecker
        $descriptionOut .= '<li class="descriptionText DescriptionElement">';
1620
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1621
          'absolute' => TRUE,
1622
          'html' => TRUE,
1623
        ));
1624
        $descriptionOut .= $name_used_in_source_link_to_show_use . ': ';
1625
        $descriptionOut .= $useSummary;
1626
        foreach ($description->sources as $source) {
1627 1b04a204 Andreas Kohlbecker
          $descriptionOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1628 6657531f Andreas Kohlbecker
        }
1629
        $hasUseRecords = FALSE;
1630
        $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>';
1631
        foreach ($description->elements as $descriptionElement) {
1632
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1633
            $hasUseRecords = TRUE;
1634 3445600f Andreas Kohlbecker
            // FIXME localization hardcoded to English
1635 3a5d0703 Andreas Kohlbecker
            $useRecordTags = explode(';', $descriptionElement->modifyingText_l10n);
1636 6657531f Andreas Kohlbecker
            $descriptionUseRecordOut .= '<tr>';
1637
            $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>';
1638
            $descriptionUseRecordOut .= '</tr>';
1639
          }
1640
        }
1641
        $descriptionUseRecordOut .= '</table></div>';
1642
        if ($hasUseRecords) {
1643
          $descriptionOut .= $descriptionUseRecordOut . '</li>';
1644
        }
1645
      }
1646
      else {
1647 3445600f Andreas Kohlbecker
        // TODO +/- duplicate of above, unify this code
1648 6657531f Andreas Kohlbecker
        $synonymOut .= '<li class="descriptionText DescriptionElement">';
1649
        $name_used_in_source_link_to_show_use = l($source->originalNameString, path_to_name($originalTaxonUsedInSource->uuid), array(
1650
          'absolute' => TRUE,
1651
          'html' => TRUE,
1652
        ));
1653
1654
        $synonymOut .= $name_used_in_source_link_to_show_use . ': ';
1655
        $synonymOut .= $useSummary;
1656
        foreach ($description->sources as $source) {
1657 1b04a204 Andreas Kohlbecker
          $synonymOut .= " (" . theme('cdm_OriginalSource', array('source' => $source, 'doLink' => TRUE)) . ")";
1658 6657531f Andreas Kohlbecker
        }
1659
1660
        $hasUseRecords = FALSE;
1661
        $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>';
1662
        foreach ($description->elements as $descriptionElement) {
1663
          if ($descriptionElement->feature->uuid == UUID_USE_RECORD) {
1664
            $hasUseRecords = TRUE;
1665 3a5d0703 Andreas Kohlbecker
            $useRecordTags = explode(';', $descriptionElement->modifyingText_l10n);
1666 6657531f Andreas Kohlbecker
            $useRecordTableOut .= '<tr>';
1667
            $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>';
1668
            $useRecordTableOut .= '</tr>';
1669
          }
1670
        }
1671
        $useRecordTableOut .= '</table></div>';
1672
        if ($hasUseRecords) {
1673
          $synonymOut .= $useRecordTableOut . '</li>';
1674
        }
1675
      }
1676
1677
      // }
1678
    }
1679
  }
1680
  $out .= $descriptionOut . $synonymOut;
1681
  $out .= "</ul></div>";
1682
  return $out;
1683
}
1684
1685 db074558 Andreas Kohlbecker
1686 6657531f Andreas Kohlbecker
/**
1687 db074558 Andreas Kohlbecker
 * The theming function for a block of Uses Descriptions for a given taxon.
1688
 *
1689
 * The Uses block has been removed from the code but the according theme function
1690
 * is kept for compatibility reasons with existing code regarding palmweb.
1691
 *
1692 6657531f Andreas Kohlbecker
 */
1693
function theme_cdm_block_Uses($variables) {
1694
  $taxonUuid = $variables['taxonUuid'];
1695
  RenderHints::pushToRenderStack('block_Uses');
1696
1697
  if ($taxonUuid == NULL) {
1698
    return;
1699
  }
1700
  $out = '';
1701
  $markerTypes = array();
1702
  $markerTypes['markerTypes'] = UUID_MARKERTYPE_USE;
1703
  $useDescriptions = cdm_ws_get(CDM_WS_PORTAL_TAXON_DESCRIPTIONS, $taxonUuid, queryString($markerTypes));
1704
  if (!empty($useDescriptions)) {
1705 3445600f Andreas Kohlbecker
    // FIXME use theme_block instaed of hardcoding the block html here !!!!
1706 6657531f Andreas Kohlbecker
    $out .= '<div id="block-cdm_dataportal-feature-description" class="clear-block block block-cdm_dataportal-feature"><H2><a name="userecords"> </a> Uses </H2>';
1707
    $formatUseDescriptions = theme('cdm_UseDescription', array('description' => $useDescriptions, 'taxonUuid' => $taxonUuid));
1708
1709
    $out .= $formatUseDescriptions;
1710
    $out .= "</div>";
1711
  }
1712
1713
  return $out;
1714
}