Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

cdm-dataportal / modules / cdm_dataportal / includes / taxon.inc @ 763b610c

History | View | Annotate | Download (20.8 KB)

1
<?php
2

    
3
/**
4
 * @file
5
 * Functions for dealing with CDM entities from the package model.taxon
6
 *
7
 * @copyright
8
 *   (C) 2007-2016 EDIT
9
 *   European Distributed Institute of Taxonomy
10
 *   http://www.e-taxonomy.eu
11
 *
12
 *   The contents of this module are subject to the Mozilla
13
 *   Public License Version 1.1.
14
 * @see http://www.mozilla.org/MPL/MPL-1.1.html
15
 *
16
 * @author
17
 *   - Andreas Kohlbecker <a.kohlbecker@BGBM.org>
18
 */
19

    
20
/**
21
 * @defgroup compose Compose functions
22
 * @{
23
 * Functions which are composing Drupal render arrays
24
 *
25
 * The cdm_dataportal module needs to compose rather complex render arrays from
26
 * the data returned by the CDM REST service. The compose functions are
27
 * responsible for creating the render arrays.
28
 *
29
 * All these functions are also implementations of the compose_hook()
30
 * which is used in the proxy_content() function.
31
 * @}
32
 */
33

    
34

    
35
/**
36
 * Returns HTML for misapplied names and invalid designations.
37
 *
38
 * Both relation types are currently treated the same!
39
 *
40
 * @param taxonRelationships
41
 * @param focusedTaxon
42
 *
43
 * @return string
44
 *    the rendered html
45
 */
46
function cdm_taxonRelationships($taxonRelationships, $focusedTaxon){
47

    
48
  static $NULL_AUTHORTEAM = 'NULL_AUTHORTEAM';
49

    
50
  if (!$taxonRelationships) {
51
    return null;
52
  }
53

    
54
  RenderHints::pushToRenderStack('taxon_relationships');
55
  $footnoteListKey = 'taxon_relationships';
56
  RenderHints::setFootnoteListKey($footnoteListKey);
57

    
58
  $misapplied = array();
59
  $joinedAuthorTeams = array();
60

    
61
  $taxon_relationship_types = variable_get(CDM_TAXON_RELATIONSHIP_TYPES, unserialize(CDM_TAXON_RELATIONSHIP_TYPES_DEFAULT));
62

    
63
  // Aggregate misapplied names having the same fullname:
64
  //  - deduplicate misapplied names, so that the same name it not shown multiple times in case it
65
  //    the duplicates only have different sensu references/author teams (see #5647)
66
  //  - show the author team as sec reference
67
  //  - show the according reference as footnote to this author team
68
  //  - if the sec reference has no author team it should show instead the title cache
69
  //
70
  // Example:
71
  // "Xenoxylum foobar" sensu Grumbach¹; sensu Lem²
72
  //    1. Novel marsian species, Grumbach, 2022
73
  //    2. Flora solaris, Lem, 2019
74
  foreach ($taxonRelationships as $taxonRelation) {
75

    
76
    if (in_array($taxonRelation->type->uuid, $taxon_relationship_types)) {
77

    
78
      if ($taxonRelation->type->uuid == UUID_MISAPPLIED_NAME_FOR || $taxonRelation->type->uuid == UUID_INVALID_DESIGNATION_FOR) {
79

    
80
        RenderHints::pushToRenderStack('misapplied_name_for'); // TODO the render path string should in future come from $taxonRelation->type->...
81

    
82
        $name = $taxonRelation->fromTaxon->name->titleCache;
83

    
84
        $sensu_citation_footnote_str = null;
85

    
86
        if(isset($taxonRelation->fromTaxon->sec)) {
87
          $sensu_citation_footnote_str = theme('cdm_reference', array('reference' => $taxonRelation->fromTaxon->sec));
88
          $authorteam = cdm_ws_get(CDM_WS_REFERENCE_AUTHORTEAM, $taxonRelation->fromTaxon->sec->uuid);
89

    
90
          if(isset($authorteam->titleCache)){
91
            $authorteam_str = $authorteam->titleCache;
92
            if($taxonRelation->fromTaxon->sec->titleCache == $authorteam->titleCache){
93
              // no need for a footnote in case the reference only consists of the author team
94
              $sensu_citation_footnote_str = '';
95
            }
96
          } else {
97
            $authorteam_str = $sensu_citation_footnote_str;
98
            // no need for a footnote in case in case it is used as replacement for missing author teams
99
            $sensu_citation_footnote_str = '';
100
          }
101
        } else {
102
          // taxa not always are have a sec reference (e.g. doubtful taxa)
103
          // use the NULL_AUTHORTEAM in this case
104
          $authorteam_str = $NULL_AUTHORTEAM;
105
        }
106

    
107
        if (!isset($misapplied[$name])) {
108
          // Render the first name found as representative for all others.
109
          $misapplied[$name]['out'] = cdm_related_taxon($taxonRelation->fromTaxon, UUID_MISAPPLIED_NAME_FOR);
110
        }
111
        else {
112
          // We need to add the anchors for all of the other misapplied names not
113
          // being rendered explicitly.
114
          $misapplied[$name]['out'] = uuid_anchor($taxonRelation->fromTaxon->uuid, $misapplied[$name]['out']);
115
        }
116

    
117
        // Collect all authors for this fullname.
118
        if (isset($authorteam_str) && $authorteam_str != $NULL_AUTHORTEAM) {
119
          // prepare entry for the footnote key of the sensu citation footnote
120
          $misapplied[$name]['authorteam'][$authorteam_str] = '';
121
          // map sensu citation footnote to the authorteam string
122
          $joinedAuthorTeams[$authorteam_str] = $sensu_citation_footnote_str;
123

    
124
        }
125

    
126
      }
127
      else {
128
        RenderHints::pushToRenderStack('other_taxon_relationship');
129
        // All relationsship types but misapplied_name_for
130
        // invalid_designation_for.
131
        $taxon_relationships_lines[] = cdm_taxonRelationship($taxonRelation, TRUE, _is_invers_taxonRelationship($taxonRelation, $focusedTaxon));
132
      }
133

    
134
      RenderHints::popFromRenderStack();
135
    }
136
  }
137

    
138
  // Sort the joinedAuthorTeams and create footnotes and footnotekeys.
139
  ksort($joinedAuthorTeams);
140
  $author_team_cnt = 0;
141
  foreach ($joinedAuthorTeams as $authorteam_str => $sensu_citation) {
142
    $footnoteKey = '';
143
    if(!empty($sensu_citation)) {
144
      $footnoteKey = FootnoteManager::addNewFootnote($footnoteListKey, 'sensu ' . $sensu_citation);
145
      $footnoteKey = theme('cdm_footnote_key', array('footnoteKey' => $footnoteKey));
146
    }
147
    $sensu = '';
148
    if($authorteam_str != $NULL_AUTHORTEAM){
149
      $sensu = ++$author_team_cnt == 0 ? '' : 'sensu ' . $authorteam_str;
150
    }
151
    $joinedAuthorTeams[$authorteam_str] = '<span class="sensu">' . $sensu . $footnoteKey .'</span>';
152
  }
153

    
154
  // ---- Generate output ---- //
155

    
156
  $out = '<div class="taxon-relationships">';
157
  if (is_array($misapplied) && count($misapplied) > 0) {
158
    $out .= '<ul class="misapplied">';
159
    foreach ($misapplied as $misapplied_name) {
160

    
161
      $out .= '<li class="synonym"><span class="misapplied">' . $misapplied_name['out'] . ' </span>';
162

    
163
      if (isset($misapplied_name['authorteam'])) {
164
        // Fill authors with the renderedFootnoteKey and sorting 'em.
165
        foreach ($misapplied_name['authorteam'] as $authorteam_str => &$renderedFootnoteKey) {
166
          $renderedFootnoteKey = $joinedAuthorTeams[$authorteam_str];
167
        }
168
        ksort($misapplied_name['authorteam']);
169
        $out .= join('; ', $misapplied_name['authorteam']);
170
      }
171
      $out .= '</li>';
172
    }
173
    $out .= '</ul>';
174
  }
175

    
176
  if (isset($taxon_relationships_lines) && is_array($taxon_relationships_lines) && count($taxon_relationships_lines) > 0) {
177
    $out .= '<ul class="taxonRelationships">';
178
    foreach ($taxon_relationships_lines as $taxon_relationship_line) {
179
      $out .= '<li class="synonym">' . $taxon_relationship_line . '</li>';
180
    }
181
    $out .= '</ul>';
182
  }
183

    
184
  $footnotes = theme('cdm_footnotes', array('footnoteListKey' => $footnoteListKey, 'enclosingTag' => 'li'));
185
  $footnotes .= theme('cdm_annotation_footnotes', array('footnoteListKey' => $footnoteListKey, 'enclosingTag' => 'li'));
186

    
187
// AK: why splitting footnotes at the sensu string ??? this is weired and hacky
188
//     TODO remove below dead code
189
//   $tr_footnotes_exploded = explode('sensu', $tr_footnotes);
190
//   $tr_footnotes_aux = '';
191
//   foreach ($tr_footnotes_exploded as $element) {
192
//     $tr_footnotes_aux .= $element;
193
//   }
194

    
195
  $out .= '<ul class="footnotes">' . $footnotes . '</ul>';
196

    
197
  $out .= '</div>';
198

    
199
  RenderHints::popFromRenderStack();
200
  return $out;
201
}
202

    
203

    
204
/**
205
 * Renders a representation of the given taxon relationship.
206
 *
207
 * According name relationships are also being rendered.
208
 *
209
 * @param $taxonRelationship
210
 * @param boolean $doLinkTaxon
211
 *     whether to create a link to the related taxon
212
 * @param boolean $inverse
213
 *     whether the $taxonRelationship should be treaded as invers relation
214
 *
215
 * @return void|string
216
 */
217
function cdm_taxonRelationship($taxonRelationship, $doLinkTaxon = FALSE, $inverse = FALSE) {
218

    
219
  // Validate object.
220
  if (!(isset($taxonRelationship->toTaxon) && isset($taxonRelationship->fromTaxon) && isset($taxonRelationship->type))) {
221
    return null;
222
  }
223

    
224
  $taxonRelationType = $taxonRelationship->type;
225

    
226
  if ($inverse) {
227
    $toTaxon = $taxonRelationship->fromTaxon;
228
    $relsign = $taxonRelationType->inverseRepresentation_L10n_abbreviatedLabel;
229
    $reltype_representation = $taxonRelationType->inverseRepresentation_L10n;
230
  }
231
  else {
232
    $toTaxon = $taxonRelationship->toTaxon;
233
    $relsign = $taxonRelationType->representation_L10n_abbreviatedLabel;
234
    $reltype_representation = $taxonRelationType->representation_L10n;
235
  }
236

    
237
  return cdm_related_taxon($toTaxon, NULL, $relsign, $reltype_representation, $taxonRelationship->doubtful, $doLinkTaxon);
238
}
239

    
240
/**
241
 * Renders a representation of the given taxon relationship.
242
 *
243
 * According name relationships are also being rendered.
244
 *
245
 * @param $taxon
246
 *  The CDM TaxonBase entity
247
 * @param $reltype_uuid
248
 *  The UUID of the TaxonRelationshipType
249
 * @param $relsign
250
 *  Optional. Can be  used to override the internal decision strategy on finding a suitable icon for the relationship
251
 * @param $reltype_representation
252
 *   Optional: Defines the value for the title attribute of the html element enclosing the relsign
253
 * @param $doubtful
254
 *   TODO
255
 * @param $doLinkTaxon
256
 *   The taxon will be rendered as clickable link when true.
257
 *
258
 * @return string
259
 *   Markup for the taxon relationship.
260
 */
261
function cdm_related_taxon($taxon, $reltype_uuid = NULL, $relsign = NULL, $reltype_representation = NULL, $doubtful=false, $doLinkTaxon = FALSE) {
262
  static $relsign_homo = '≡';
263
  static $relsign_hetero = '=';
264
  static $relsign_invalid = '&ndash;';
265
  static $nom_status_invalid_type_uuids =  array(
266
    UUID_NOMENCLATURALSTATUS_TYPE_INVALID,
267
    UUID_NOMENCLATURALSTATUS_TYPE_NUDUM,
268
    UUID_NOMENCLATURALSTATUS_TYPE_COMBINATIONINVALID,
269
    UUID_NOMENCLATURALSTATUS_TYPE_PROVISIONAL
270
  );
271

    
272
  // 'taxonRelationships';
273
  $footnoteListKey = NULL;
274

    
275
  $skip_tags = array();
276

    
277
  $is_invalid = false;
278

    
279
  if (!$relsign) {
280

    
281
    switch ($reltype_uuid) {
282
      case UUID_HETEROTYPIC_SYNONYM_OF:
283
      case UUID_SYNONYM_OF:
284
        $relsign = $relsign_hetero;
285
        break;
286

    
287
      case UUID_HOMOTYPIC_SYNONYM_OF:
288
        $relsign = $relsign_homo;
289
        break;
290

    
291
      case UUID_MISAPPLIED_NAME_FOR:
292
      case UUID_INVALID_DESIGNATION_FOR:
293
        $skip_tags[] = 'authors';
294
        $is_invalid = true;
295
        $relsign = $relsign_invalid;
296

    
297
        break;
298

    
299
      default:
300
        $relsign = $relsign_invalid;
301
    }
302

    
303
  }
304

    
305
  if($doubtful) {
306
    $relsign = '?' . $relsign;
307
  }
308

    
309
  /*
310
  Names with status invalid or nudum are to be displayed with the
311
  $relsign_invalid, these names appear at the end of all names in their
312
  homotypic group (ordered correctly by the java cdm_lib).
313
  */
314
  if (isset($taxon->name->status) && is_array($taxon->name->status)) {
315
    foreach ($taxon->name->status as $status) {
316
      if (in_array($status->type->uuid , $nom_status_invalid_type_uuids)) {
317
        $relsign = $relsign_invalid;
318
        break;
319
      }
320
    }
321
  }
322

    
323
  // Now rendering starts ..
324
  RenderHints::pushToRenderStack('related_taxon');
325

    
326
  if (isset($taxon->name->nomenclaturalReference)) {
327
    $referenceUri = url(path_to_reference($taxon->name->nomenclaturalReference->uuid));
328
  }
329
  $taxonUri = '';
330
  if ($doLinkTaxon) {
331
    $taxonUri = url(path_to_taxon($taxon->uuid, "synonymy"));
332
  }
333
  // Printing the taxonName and the handling the special case of annotations.
334
  if (!isset($referenceUri)) {
335
    $referenceUri = FALSE;
336
  }
337
  $out_taxon_part = render_taxon_or_name($taxon, $taxonUri, $referenceUri, TRUE, FALSE, $skip_tags, $is_invalid);
338
  $taxon_footnotes = theme('cdm_annotations_as_footnotekeys',
339
    array('cdmBase_list' => array(
340
      $taxon->name,
341
      $taxon,
342
    ),
343
      'footnote_list_key' => $footnoteListKey)
344
  );
345

    
346
  $homonyms = cdm_name_relationships_of($taxon);
347

    
348
  $out = '<span class="relation_sign" title="' . $reltype_representation . '">' . $relsign . '</span>'
349
    . $out_taxon_part . $taxon_footnotes . ' '  . $homonyms;
350

    
351
  $out = uuid_anchor($taxon->uuid, $out);
352

    
353
  RenderHints::popFromRenderStack();
354

    
355
  return $out;
356
}
357

    
358

    
359
/**
360
 * Creates markup for a taxon which is the accepted of another one
361
 *
362
 * @param $accepted_for_uuid
363
 *   The uuid of the accepted taxon
364
 */
365
function cdm_accepted_for($accepted_for_uuid) {
366

    
367
  if(!is_uuid($accepted_for_uuid)){
368
    return '';
369
  }
370

    
371
  RenderHints::pushToRenderStack('acceptedFor');
372
  $out = '';
373

    
374
  $synonym = cdm_ws_get(CDM_WS_PORTAL_TAXON, $accepted_for_uuid);
375
  if ($synonym) {
376
    $out .= '<span class="acceptedFor">';
377
    $out .= t('is accepted for ');
378
    if (isset($synonym->name->nomenclaturalReference)) {
379
      $referenceUri = url(path_to_reference($synonym->name->nomenclaturalReference->uuid));
380
    }
381
    $out .= render_taxon_or_name($synonym->name, NULL, $referenceUri);
382
    $out .= theme('cdm_annotations_as_footnotekeys', array('cdmBase_list' => $synonym));
383
    $out .= '</span>';
384
  }
385
  RenderHints::popFromRenderStack();
386
  return $out;
387
}
388

    
389
/**
390
 * Compose function for a list of taxa.
391
 *
392
 * This function is for example used to display search results or the taxa for a taxon name in the name page.
393
 *
394
 * @param $taxon_list array
395
 *   The list of CDM Taxon entities. e.g. The records array as contained in a pager object.
396
 * @param $freetext_search_results array
397
 * @param $show_classification boolean
398
 *
399
 * @ingroup compose
400
 *
401
 */
402
function compose_list_of_taxa($taxon_list, $freetext_search_results = array(), $show_classification = false) {
403

    
404
  $unclassified_snippet = '<span class="unclassified">' . t('unclassified') . '</span>';
405

    
406
  RenderHints::pushToRenderStack('list_of_taxa');
407

    
408
  $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SEARCH_GALLERY_NAME);
409

    
410
  $showMedia_taxa = $gallery_settings['cdm_dataportal_show_taxon_thumbnails'];
411
  $showMedia_synonyms = $gallery_settings['cdm_dataportal_show_synonym_thumbnails'];
412
  $searched_in_classification = cdm_dataportal_searched_in_classification();
413
  $searched_in_classification_uuid = null;
414
  if(isset($searched_in_classification->uuid)){
415
    $searched_in_classification_uuid = $searched_in_classification->uuid;
416
  }
417

    
418
  // .. Well, for sure not as performant as before, but better than nothing.
419
  $synonym_uuids = array();
420
  $misappied_uuids = array();
421
  foreach ($taxon_list as $taxon) {
422
    if ($taxon->class == "Synonym") {
423
      if (!array_key_exists($taxon->uuid, $synonym_uuids)) {
424
        $synonym_uuids[$taxon->uuid] = $taxon->uuid;
425
      }
426
    }
427
    elseif (!_cdm_dataportal_acceptedByCurrentView($taxon)) {
428
      // Assuming that it is a misappied name, will be further examined below.
429
      $misappied_uuids[$taxon->uuid] = $taxon->uuid;
430
    }
431
  }
432

    
433
  // Batch service not jet implemented:
434
  // $table_of_accepted = cdm_ws_property(CDM_WS_PORTAL_TAXON_ACCEPTED,
435
  // join(',', $synonym_uuids));
436
  // thus ...
437
  $table_of_accepted = array();
438

    
439
  foreach ($synonym_uuids as $relatedUuid) {
440
    $table_of_accepted[$relatedUuid] = cdm_ws_get(CDM_WS_PORTAL_TAXON_ACCEPTED, array(
441
      $relatedUuid,
442
      $searched_in_classification_uuid,
443
    ));
444
  }
445

    
446
  foreach ($misappied_uuids as $relatedUuid) {
447
    $taxonRelations = cdm_ws_get(CDM_WS_PORTAL_TAXON_RELATIONS, array(
448
      $relatedUuid,
449
    ));
450
    foreach ($taxonRelations as $relation) {
451
      if ($relation->type->uuid == UUID_MISAPPLIED_NAME_FOR && _cdm_dataportal_acceptedByCurrentView($relation->toTaxon)) {
452
        $table_of_accepted[$relatedUuid][] = $relation->toTaxon;
453
      }
454
    }
455
  }
456

    
457
  $out = '<ul class="cdm_names" style="background-image: none;">';
458
  $itemCnt = -1;
459
  foreach ($taxon_list as $taxon) {
460
    $itemCnt++;
461
    if (isset($table_of_accepted[$taxon->uuid])) {
462
      // Its a synonym or misapplied name.
463
      $is_synonym = isset($synonym_uuids[$taxon->uuid]); //TODO better use the $taxon->class attribute?
464
      $taxon_type = $is_synonym ? "Synonym" : "misapplied-name";
465

    
466
      $acceptedTaxa = $table_of_accepted[$taxon->uuid];
467

    
468
      if (count($acceptedTaxa) == 1) {
469

    
470
        $acceptedTaxon = $acceptedTaxa[0];
471
        $taxonUri = uri_to_synonym($taxon->uuid, $acceptedTaxon->uuid);
472
        $referenceUri = '';
473
        if (isset($acceptedTaxon->name->nomenclaturalReference)) {
474
          $referenceUri = url(path_to_reference($acceptedTaxon->name->nomenclaturalReference->uuid));
475
        }
476
        $taxon_or_name = $is_synonym ? $taxon->name : $taxon;
477
        // $taxon_or_name this is a trick to suppress the sec reference for sysnonyms
478
        // supplying the name will cause render_taxon_or_name() to not show the sec reference
479
        $out .= '<li class="' . $taxon_type . '">' . render_taxon_or_name($taxon_or_name, $taxonUri, $referenceUri);
480
        if ($show_classification) {
481
          $classifications = get_classifications_for_taxon($taxon);
482
          $classification_titles = array();
483
          foreach ($classifications as $classification) {
484
            if (isset($classification->titleCache)) {
485
              $classification_titles[] = $classification->titleCache;
486
            }
487
          }
488
          if(count($classification_titles) == 0){
489
            $classification_titles[] = $unclassified_snippet;
490
          }
491
          $out .= ' : <span class="classifications">' . implode(', ', $classification_titles) . '</span>';
492
        }
493
        $out .= theme('cdm_annotations_as_footnotekeys', array('cdmBase_list' => $taxon));
494
        if ($showMedia_synonyms) {
495
          $out .= theme('cdm_taxon_list_thumbnails', array('taxon' => $acceptedTaxon));
496
        }
497
      }
498
      else {
499

    
500
        // TODO avoid using Ajax in the cdm_dynabox .... why?
501
        // TODO add media.
502
        $out .= cdm_dynabox(
503
          $taxon->uuid,
504
          render_taxon_or_name($taxon->name, NULL, NULL, FALSE),
505
          cdm_compose_url(CDM_WS_PORTAL_TAXON_ACCEPTED,
506
            array(
507
              $taxon->uuid,
508
              $searched_in_classification_uuid
509
            )
510
          ),
511
          'cdm_list_of_taxa',
512
          'show accepted taxa of this ' . $taxon_type,
513
          array('li', 'ul'),
514
          array('class' => array($taxon_type))
515
        );
516
      }
517
    }
518
    else {
519
      // Its a Taxon.
520
      $taxonUri = url(path_to_taxon($taxon->uuid));
521
      $referenceUri = '';
522
      if (isset($taxon->name->nomenclaturalReference)) {
523
        $referenceUri = url(path_to_reference($taxon->name->nomenclaturalReference->uuid));
524
      }
525
      $out .= '<li class="Taxon">' . render_taxon_or_name($taxon, $taxonUri, $referenceUri);
526
      if ($show_classification) {
527
        $classifications = get_classifications_for_taxon($taxon);
528
        $classification_titles = array();
529
        foreach ($classifications as $classification) {
530
          if (isset($classification->titleCache)) {
531
            $classification_titles[] = $classification->titleCache;
532
          }
533
        }
534
        if(count($classification_titles) == 0){
535
          $classification_titles[] = $unclassified_snippet;
536
        }
537
        $out .= ' : <span class="classifications">' . implode(', ', $classification_titles) . '</span>';
538
      }
539
      $out .= theme('cdm_annotations_as_footnotekeys', array('cdmBase_list' => $taxon));
540

    
541
      if ($showMedia_taxa) {
542
        $out .= theme('cdm_taxon_list_thumbnails', array('taxon' => $taxon));
543
      }
544
    }
545

    
546
    /*
547
     * the score field will be empty in case of MultiTermQueries like
548
     * WildcardQueries, since these are  constant score by default
549
     * since Lucene 2.9
550
     */
551
    if(isset($freetext_search_results[$itemCnt]) && $freetext_search_results[$itemCnt]->score && $freetext_search_results[$itemCnt]->maxScore){
552
      $percentage =  ( $freetext_search_results[$itemCnt]->score / $freetext_search_results[$itemCnt]->maxScore ) * 100;
553
      $out .= '<div class="score-bar"><div class="score-bar-indicator" style="width:' . $percentage .'% "></div></div>';
554
      $out .= '<div class="score-bar-value">' . number_format($percentage, 2) .'%</div>';
555
    }
556

    
557
    // Render highlighted fragments, these are made available by free text
558
    // searches.
559
    if (isset($freetext_search_results[$itemCnt]->fieldHighlightMap)) {
560
      $field_fragments = (array) $freetext_search_results[$itemCnt]->fieldHighlightMap;
561
      if (count($field_fragments) > 0) {
562
        $fragments_out = '';
563
        foreach ($field_fragments as $fieldName => $fragments) {
564
          $fragments_out .= '... <span class="' . $fieldName. '">' . filter_xss(join(" ... ", $fragments), array('b') ) . '</span>';
565
        }
566
        $out .= '<div class="fragment_highlight">' . $fragments_out . ' ...</div>';
567
      }
568
    }
569

    
570
    $out .= '</li>';
571
  }
572

    
573
  $out .= '</ul>';
574
  RenderHints::popFromRenderStack();
575

    
576
  return markup_to_render_array($out); // TODO create render array of all list items in function
577
}
578

    
579

    
580
function compose_taxonomic_children($taxon_uuid){
581

    
582
  $render_array = array();
583
  
584
  if($taxon_uuid) {
585
    $children = cdm_ws_get(CDM_WS_PORTAL_TAXONOMY_CHILDNODES_OF_TAXON, array(
586
      get_current_classification_uuid(),
587
      $taxon_uuid
588
      ));
589
    if($children){
590
      $taxonomic_children = theme('cdm_taxontree', array('tree' => $children));
591
      $render_array = markup_to_render_array($taxonomic_children);
592
    }
593
  }
594
  return $render_array;
595
}
596

    
Add picture from clipboard (Maximum size: 40 MB)