Project

General

Profile

Download (18.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * Taxon 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
 * Returns HTML for misapplied names and invalid designations.
18
 *
19
 * Both relation types are currently treated the same!
20
 *
21
 * @param array $variables
22
 *   An associative array containing:
23
 *   - taxonRelationships
24
 *   - focusedTaxon
25
 *
26
 * @ingroup themeable
27
 *
28
 * @return string
29
 *    the rendered html
30
 */
31
function theme_cdm_taxonRelationships($variables) {
32
  $taxonRelationships = $variables['taxonRelationships'];
33
  $focusedTaxon = $variables['focusedTaxon'];
34
  if (!$taxonRelationships) {
35
    return null;
36
  }
37

    
38
  RenderHints::pushToRenderStack('taxonRelationships');
39
  $footnoteListKey = 'taxonRelationships';
40
  RenderHints::setFootnoteListKey($footnoteListKey);
41

    
42
  $misapplied = array();
43
  $joinedAuthorTeams = array();
44

    
45
  $taxon_relationship_types = variable_get(CDM_TAXON_RELATIONSHIP_TYPES, unserialize(CDM_TAXON_RELATIONSHIP_TYPES_DEFAULT));
46

    
47
  // Aggregate misapplied names having the same fullname:
48
  foreach ($taxonRelationships as $taxonRelation) {
49

    
50
    if (in_array($taxonRelation->type->uuid, $taxon_relationship_types)) {
51

    
52
      if ($taxonRelation->type->uuid == UUID_MISAPPLIED_NAME_FOR || $taxonRelation->type->uuid == UUID_INVALID_DESIGNATION_FOR) {
53

    
54
        $name = $taxonRelation->fromTaxon->name->titleCache;
55

    
56
        $authorteam = cdm_ws_get(CDM_WS_REFERENCE_AUTHORTEAM, $taxonRelation->fromTaxon->sec->uuid);
57
        $authorteam = $authorteam->titleCache;
58

    
59
        if (!isset($misapplied[$name])) {
60
          // Render the first name found as representative for all others.
61
          $misapplied[$name]['out'] = cdm_related_taxon($taxonRelation->fromTaxon, UUID_MISAPPLIED_NAME_FOR);
62
        }
63
        else {
64
          // We need to add the anchors for all of the other mispplied names not
65
          // being rendered explicitly.
66
          $misapplied[$name]['out'] = uuid_anchor($taxonRelation->fromTaxon->uuid, $misapplied[$name]['out']);
67
        }
68

    
69
        // Collect all authors for this fullname.
70
        if (isset($authorteam)) {
71
          $misapplied[$name]['authorteam'][$authorteam] = '';
72
          $joinedAuthorTeams[$authorteam] = 'sensu ' . theme('cdm_reference', array('reference' => $taxonRelation->fromTaxon->sec));
73
        }
74
      }
75
      else {
76
        // All relationsship types but misapplied_name_for
77
        // invalid_designation_for.
78
        $taxon_relationships_lines[] = cdm_taxonRelationship($taxonRelation, TRUE, _is_invers_taxonRelationship($taxonRelation, $focusedTaxon));
79
      }
80
    }
81
  }
82

    
83
  // Sort the joinedAuthorTeams and create footnotes and footnotekeys.
84
  ksort($joinedAuthorTeams);
85
  foreach ($joinedAuthorTeams as $authorteam => $sensuCitation) {
86
    $footnoteKey = FootnoteManager::addNewFootnote($footnoteListKey, $sensuCitation);
87
    $joinedAuthorTeams[$authorteam] = '<span class="sensu">sensu '
88
      . $authorteam
89
      . theme('cdm_footnote_key', array('footnoteKey' => $footnoteKey))
90
      . '</span>';
91
  }
92

    
93
  // ---- Generate output ---- //
94

    
95
  $out = '<div class="taxon-relationships">';
96
  if (is_array($misapplied) && count($misapplied) > 0) {
97
    $out .= '<ul class="misapplied">';
98
    foreach ($misapplied as $misapplied_name) {
99

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

    
102
      if (isset($misapplied_name['authorteam'])) {
103
        // Fill authors with the renderedFootnoteKey and sorting 'em.
104
        foreach ($misapplied_name['authorteam'] as $authorteam => &$renderedFootnoteKey) {
105
          $renderedFootnoteKey = $joinedAuthorTeams[$authorteam];
106
        }
107
        ksort($misapplied_name['authorteam']);
108
        $out .= join('; ', $misapplied_name['authorteam']);
109
      }
110
      $out .= '</li>';
111
    }
112
    $out .= '</ul>';
113
  }
114

    
115
  if (isset($taxon_relationships_lines) && is_array($taxon_relationships_lines) && count($taxon_relationships_lines) > 0) {
116
    $out .= '<ul class="taxonRelationships">';
117
    foreach ($taxon_relationships_lines as $taxon_relationship_line) {
118
      $out .= '<li class="synonym">' . $taxon_relationship_line . '</li>';
119
    }
120
    $out .= '</ul>';
121
  }
122

    
123
  $footnotes = theme('cdm_footnotes', array('footnoteListKey' => $footnoteListKey, 'enclosingTag' => 'li'));
124
  $footnotes .= theme('cdm_annotation_footnotes', array('footnoteListKey' => $footnoteListKey, 'enclosingTag' => 'li'));
125

    
126
// AK: why splitting footnotes at the sennsu string ??? this is weired and hacky
127
//     TODO remove below dead code
128
//   $tr_footnotes_exploded = explode('sensu', $tr_footnotes);
129
//   $tr_footnotes_aux = '';
130
//   foreach ($tr_footnotes_exploded as $element) {
131
//     $tr_footnotes_aux .= $element;
132
//   }
133

    
134
  $out .= '<ul class="footnotes">' . $footnotes . '</ul>';
135

    
136
  $out .= '</div>';
137

    
138
  RenderHints::popFromRenderStack();
139
  return $out;
140
}
141

    
142
/**
143
 * @todo Please document this function.
144
 * @see http://drupal.org/node/1354
145
 */
146
function theme_cdm_acceptedFor($variables) {
147
  $accepted_for_uuid = $variables['acceptedFor'];
148

    
149
  if(!is_uuid($accepted_for_uuid)){
150
    return '';
151
  }
152

    
153
  RenderHints::pushToRenderStack('acceptedFor');
154
  $out = '';
155

    
156
  $synonym = cdm_ws_get(CDM_WS_PORTAL_TAXON, $accepted_for_uuid);
157
  if ($synonym) {
158
    $out .= '<span class="acceptedFor">';
159
    $out .= t('is accepted for ');
160
    if (isset($synonym->name->nomenclaturalReference)) {
161
      $referenceUri = url(path_to_reference($synonym->name->nomenclaturalReference->uuid));
162
    }
163
    $out .= render_taxon_or_name($synonym->name, NULL, $referenceUri);
164
    $out .= theme('cdm_annotations_as_footnotekeys', array('cdmBase_list' => $synonym));
165
    $out .= '</span>';
166
  }
167
  RenderHints::popFromRenderStack();
168
  return $out;
169
}
170

    
171
/**
172
 * @todo document this function.
173
 */
174
function theme_cdm_list_of_taxa($variables) {
175

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

    
178
  $records = $variables['records'];
179
  $freetextSearchResults = $variables['freetextSearchResults'];
180
  $show_classification = $variables['show_classification'];
181

    
182
  RenderHints::pushToRenderStack('list_of_taxa');
183

    
184
  $form_name = 'search_gallery';
185
  // $default_values = unserialize(CDM_DATAPORTAL_GALLERY_SETTINGS);
186
  // $gallery_settings = variable_get($form_name, $default_values);
187
  $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SEARCH_GALLERY_NAME);
188

    
189
  $showMedia_taxa = $gallery_settings['cdm_dataportal_show_taxon_thumbnails'];
190
  $showMedia_synonyms = $gallery_settings['cdm_dataportal_show_synonym_thumbnails'];
191
  // $showMedia_taxa =
192
  // variable_get('cdm_dataportal_findtaxa_show_taxon_thumbnails', 1);
193
  // $showMedia_synonyms =
194
  // variable_get('cdm_dataportal_findtaxa_show_synonym_thumbnails', 0);
195
  $searched_in_classification = cdm_dataportal_searched_in_classification();
196
  $searched_in_classification_uuid = null;
197
  if(isset($searched_in_classification->uuid)){
198
    $searched_in_classification_uuid = $searched_in_classification->uuid;
199
  }
200

    
201
  // .. Well, for sure not as performant as before, but better than nothing.
202
  $synonym_uuids = array();
203
  $misappied_uuids = array();
204
  foreach ($records as $taxon) {
205
    if ($taxon->class == "Synonym") {
206
      if (!array_key_exists($taxon->uuid, $synonym_uuids)) {
207
        $synonym_uuids[$taxon->uuid] = $taxon->uuid;
208
      }
209
    }
210
    elseif (!_cdm_dataportal_acceptedByCurrentView($taxon)) {
211
      // Assuming that it is a misappied name, will be further examined below.
212
      $misappied_uuids[$taxon->uuid] = $taxon->uuid;
213
    }
214
  }
215

    
216
  // Batch service not jet implemented:
217
  // $table_of_accepted = cdm_ws_property(CDM_WS_PORTAL_TAXON_ACCEPTED,
218
  // join(',', $synonym_uuids));
219
  // thus ...
220
  $table_of_accepted = array();
221

    
222
  foreach ($synonym_uuids as $relatedUuid) {
223
    $table_of_accepted[$relatedUuid] = cdm_ws_get(CDM_WS_PORTAL_TAXON_ACCEPTED, array(
224
      $relatedUuid,
225
      $searched_in_classification_uuid,
226
    ));
227
  }
228

    
229
  foreach ($misappied_uuids as $relatedUuid) {
230
    $taxonRelations = cdm_ws_get(CDM_WS_PORTAL_TAXON_RELATIONS, array(
231
      $relatedUuid,
232
    ));
233
    foreach ($taxonRelations as $relation) {
234
      if ($relation->type->uuid == UUID_MISAPPLIED_NAME_FOR && _cdm_dataportal_acceptedByCurrentView($relation->toTaxon)) {
235
        $table_of_accepted[$relatedUuid][] = $relation->toTaxon;
236
      }
237
    }
238
  }
239

    
240
  $out = '<ul class="cdm_names" style="background-image: none;">';
241
  $itemCnt = -1;
242
  foreach ($records as $taxon) {
243
    $itemCnt++;
244
    if (isset($table_of_accepted[$taxon->uuid])) {
245
      // Its a synonym or misapplied name.
246
      $is_synonym = isset($synonym_uuids[$taxon->uuid]); //TODO better use the $taxon->class attribute?
247
      $taxon_type = $is_synonym ? "Synonym" : "misapplied-name";
248

    
249
      $acceptedTaxa = $table_of_accepted[$taxon->uuid];
250

    
251
      if (count($acceptedTaxa) == 1) {
252

    
253
        $acceptedTaxon = $acceptedTaxa[0];
254
        $taxonUri = uri_to_synonym($taxon->uuid, $acceptedTaxon->uuid, 'synonymy');
255
        $referenceUri = '';
256
        if (isset($acceptedTaxon->name->nomenclaturalReference)) {
257
          $referenceUri = url(path_to_reference($acceptedTaxon->name->nomenclaturalReference->uuid));
258
        }
259
        $taxon_or_name = $is_synonym ? $taxon->name : $taxon;
260
        // $taxon_or_name this is a trick to suppress the sec reference for sysnonyms
261
        // supplying the name will cause render_taxon_or_name() to not show the sec reference
262
        $out .= '<li class="' . $taxon_type . '">' . render_taxon_or_name($taxon_or_name, $taxonUri, $referenceUri);
263
        if ($show_classification) {
264
          $classifications = get_classifications_for_taxon($taxon);
265
          $classification_titles = array();
266
          foreach ($classifications as $classification) {
267
            if (isset($classification->titleCache)) {
268
              $classification_titles[] = $classification->titleCache;
269
            }
270
          }
271
          if(count($classification_titles) == 0){
272
            $classification_titles[] = $unclassified_snippet;
273
          }
274
          $out .= ' : <span class="classifications">' . implode(', ', $classification_titles) . '</span>';
275
        }
276
        $out .= theme('cdm_annotations_as_footnotekeys', array('cdmBase_list' => $taxon));
277
        if ($showMedia_synonyms) {
278
          $out .= theme('cdm_taxon_list_thumbnails', array('taxon' => $acceptedTaxon));
279
        }
280
      }
281
      else {
282

    
283
        // TODO avoid using Ajax in the cdm_dynabox .... why?
284
        // TODO add media.
285
        $out .= cdm_dynabox(
286
          $taxon->uuid,
287
          render_taxon_or_name($taxon->name, NULL, NULL, FALSE),
288
          cdm_compose_url(CDM_WS_PORTAL_TAXON_ACCEPTED,
289
            array(
290
              $taxon->uuid,
291
              $searched_in_classification_uuid
292
            )
293
          ),
294
          'cdm_list_of_taxa',
295
          'show accepted taxa of this ' . $taxon_type,
296
          array('li', 'ul'),
297
          array('class' => array($taxon_type))
298
         );
299
      }
300
    }
301
    else {
302
      // Its a Taxon.
303
      $taxonUri = url(path_to_taxon($taxon->uuid));
304
      $referenceUri = '';
305
      if (isset($taxon->name->nomenclaturalReference)) {
306
        $referenceUri = url(path_to_reference($taxon->name->nomenclaturalReference->uuid));
307
      }
308
      $out .= '<li class="Taxon">' . render_taxon_or_name($taxon, $taxonUri, $referenceUri);
309
      if ($show_classification) {
310
        $classifications = get_classifications_for_taxon($taxon);
311
        $classification_titles = array();
312
        foreach ($classifications as $classification) {
313
          if (isset($classification->titleCache)) {
314
            $classification_titles[] = $classification->titleCache;
315
          }
316
        }
317
        if(count($classification_titles) == 0){
318
          $classification_titles[] = $unclassified_snippet;
319
        }
320
        $out .= ' : <span class="classifications">' . implode(', ', $classification_titles) . '</span>';
321
      }
322
      $out .= theme('cdm_annotations_as_footnotekeys', array('cdmBase_list' => $taxon));
323

    
324
      if ($showMedia_taxa) {
325
        $out .= theme('cdm_taxon_list_thumbnails', array('taxon' => $taxon));
326
      }
327
    }
328

    
329
    /*
330
     * the score field will be empty in case of MultiTermQueries like
331
     * WildcardQueries, since these are  constant score by default
332
     * since Lucene 2.9
333
     */
334
    if(isset($freetextSearchResults[$itemCnt]) && $freetextSearchResults[$itemCnt]->score && $freetextSearchResults[$itemCnt]->maxScore){
335
      $percentage =  ( $freetextSearchResults[$itemCnt]->score / $freetextSearchResults[$itemCnt]->maxScore ) * 100;
336
      $out .= '<div class="score-bar"><div class="score-bar-indicator" style="width:' . $percentage .'% "></div></div>';
337
      $out .= '<div class="score-bar-value">' . number_format($percentage, 2) .'%</div>';
338
    }
339

    
340
    // Render highlighted fragments, these are made available by free text
341
    // searches.
342
    if (isset($freetextSearchResults[$itemCnt]->fieldHighlightMap)) {
343
      $field_fragments = (array) $freetextSearchResults[$itemCnt]->fieldHighlightMap;
344
      if (count($field_fragments) > 0) {
345
        $fragments_out = '';
346
        foreach ($field_fragments as $fieldName => $fragments) {
347
          $fragments_out .= '... <span class="' . $fieldName. '">' . filter_xss(join(" ... ", $fragments), array('b') ) . '</span>';
348
        }
349
        $out .= '<div class="fragment_highlight">' . $fragments_out . ' ...</div>';
350
      }
351
    }
352

    
353
    $out .= '</li>';
354
  }
355

    
356
  $out .= '</ul>';
357
  RenderHints::popFromRenderStack();
358

    
359
  return $out;
360
}
361

    
362
/**
363
 * Renders a representation of the given taxon relationship.
364
 *
365
 * According name relationships are also being rendered.
366
 *
367
 * @param unknown_type $taxonRelationship
368
 * @param boolean $doLinkTaxon
369
 *     whether to create a link to the related taxon
370
 * @param boolean $inverse
371
 *     whether the $taxonRelationship should be treaded as invers relation
372
 *
373
 * @return void|string
374
 */
375
function cdm_taxonRelationship($taxonRelationship, $doLinkTaxon = FALSE, $inverse = FALSE) {
376

    
377
  // Validate object.
378
  if (!(isset($taxonRelationship->toTaxon) && isset($taxonRelationship->fromTaxon) && isset($taxonRelationship->type))) {
379
    return null;
380
  }
381

    
382
  $taxonRelationType = $taxonRelationship->type;
383

    
384
  if ($inverse) {
385
    $toTaxon = $taxonRelationship->fromTaxon;
386
    $relsign = $taxonRelationType->inverseRepresentation_L10n_abbreviatedLabel;
387
    $reltype_representation = $taxonRelationType->inverseRepresentation_L10n;
388
  }
389
  else {
390
    $toTaxon = $taxonRelationship->toTaxon;
391
    $relsign = $taxonRelationType->representation_L10n_abbreviatedLabel;
392
    $reltype_representation = $taxonRelationType->representation_L10n;
393
  }
394

    
395
  return cdm_related_taxon($toTaxon, NULL, $relsign, $reltype_representation, $taxonRelationship->doubtful, $doLinkTaxon);
396
}
397

    
398
/**
399
 * Renders a representation of the given taxon relationship.
400
 *
401
 * According name relationships are also being rendered.
402
 *
403
 * @param $taxon
404
 *  The CDM TaxonBase entity
405
 * @param $reltype_uuid
406
 *  The UUID of the TaxonRelationshipType
407
 * @param $relsign
408
 *  Optional. Can be  used to override the internal decision strategy on finding a suitable icon for the relationship
409
 * @param $reltype_representation
410
 *   Optional: Defines the value for the title attribute of the html element enclosing the relsign
411
 * @param $doubtful
412
 *   TODO
413
 * @param $doLinkTaxon
414
 *   The taxon will be rendered as clickable link when true.
415
 *
416
 * @return string
417
 *   Markup for the taxon relationship.
418
 */
419
function cdm_related_taxon($taxon, $reltype_uuid = NULL, $relsign = NULL, $reltype_representation = NULL, $doubtful=false, $doLinkTaxon = FALSE) {
420
  static $relsign_homo = '≡';
421
  static $relsign_hetero = '=';
422
  static $relsign_invalid = '&ndash;';
423
  static $nom_status_invalid_type_uuids =  array(
424
      UUID_NOMENCLATURALSTATUS_TYPE_INVALID,
425
      UUID_NOMENCLATURALSTATUS_TYPE_NUDUM,
426
      UUID_NOMENCLATURALSTATUS_TYPE_COMBINATIONINVALID,
427
      UUID_NOMENCLATURALSTATUS_TYPE_PROVISIONAL
428
  );
429

    
430
  // 'taxonRelationships';
431
  $footnoteListKey = NULL;
432

    
433
  $skip_tags = array();
434

    
435
  $is_invalid = false;
436

    
437
  if (!$relsign) {
438

    
439
    switch ($reltype_uuid) {
440
      case UUID_HETEROTYPIC_SYNONYM_OF:
441
      case UUID_SYNONYM_OF:
442
        $relsign = $relsign_hetero;
443
        break;
444

    
445
      case UUID_HOMOTYPIC_SYNONYM_OF:
446
        $relsign = $relsign_homo;
447
        break;
448

    
449
      case UUID_MISAPPLIED_NAME_FOR:
450
      case UUID_INVALID_DESIGNATION_FOR:
451
        $skip_tags[] = 'authors';
452
        $is_invalid = true;
453
        $relsign = $relsign_invalid;
454

    
455
        break;
456

    
457
      default:
458
        $relsign = $relsign_invalid;
459
    }
460

    
461
  }
462

    
463
  if($doubtful) {
464
    $relsign = '?' . $relsign;
465
  }
466

    
467
  /*
468
  Names with status invalid or nudum are to be displayed with the
469
  $relsign_invalid, these names appear at the end of all names in their
470
  homotypic group (ordered correctly by the java cdm_lib).
471
  */
472
  if (isset($taxon->name->status) && is_array($taxon->name->status)) {
473
    foreach ($taxon->name->status as $status) {
474
      if (in_array($status->type->uuid , $nom_status_invalid_type_uuids)) {
475
        $relsign = $relsign_invalid;
476
        break;
477
      }
478
    }
479
  }
480

    
481
  // Now rendering starts ..
482
  RenderHints::pushToRenderStack('related_taxon');
483

    
484
  if (isset($taxon->name->nomenclaturalReference)) {
485
    $referenceUri = url(path_to_reference($taxon->name->nomenclaturalReference->uuid));
486
  }
487
  $taxonUri = '';
488
  if ($doLinkTaxon) {
489
    $taxonUri = url(path_to_taxon($taxon->uuid, "synonymy"));
490
  }
491
  // Printing the taxonName and the handling the special case of annotations.
492
  if (!isset($referenceUri)) {
493
    $referenceUri = FALSE;
494
  }
495
  $out_taxon_part = render_taxon_or_name($taxon, $taxonUri, $referenceUri, TRUE, FALSE, $skip_tags, $is_invalid);
496
  $taxon_footnotes = theme('cdm_annotations_as_footnotekeys',
497
       array('cdmBase_list' => array(
498
         $taxon->name,
499
         $taxon,
500
       ),
501
       'footnote_list_key' => $footnoteListKey)
502
  );
503

    
504
  $homonyms = cdm_name_relationships_of($taxon);
505

    
506
  $out = '<span class="relation_sign" title="' . $reltype_representation . '">' . $relsign . '</span>'
507
      . $out_taxon_part . $taxon_footnotes . ' '  . $homonyms;
508

    
509
  $out = uuid_anchor($taxon->uuid, $out);
510

    
511
  RenderHints::popFromRenderStack();
512

    
513
  return $out;
514
}
515

    
516

    
517
  /**
518
 * @todo document this function.
519
 */
520
function theme_cdm_taxon_list_thumbnails($variables) {
521

    
522
  $taxon = $variables['taxon'];
523
  $out = '';
524
  $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SEARCH_GALLERY_NAME);
525
  $showCaption = $gallery_settings['cdm_dataportal_show_thumbnail_captions'];
526
  if ($showCaption) {
527
    $captionElements = array(
528
      'title',
529
      'rights',
530
    );
531
  } else {
532
    $captionElements = array();
533
  }
534

    
535
  $gallery_name = $taxon->uuid;
536

    
537
  $mediaList = _load_media_for_taxon($taxon);
538

    
539
  $galleryLinkUri = path_to_taxon($taxon->uuid, 'images');
540

    
541
  $out .= theme('cdm_media_gallerie', array(
542
    'mediaList' => $mediaList,
543
    'galleryName' => $gallery_name,
544
    'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
545
    'cols' => $gallery_settings['cdm_dataportal_media_cols'],
546
    'maxRows' => $gallery_settings['cdm_dataportal_media_maxRows'],
547
    'captionElements' => $captionElements,
548
    'mediaLinkType' => 'LIGHTBOX',
549
    'alternativeMediaUri' => NULL,
550
    'galleryLinkUri' => $galleryLinkUri,
551
     ));
552

    
553
  return $out;
554
}
(8-8/9)