Project

General

Profile

Download (30.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * Name 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
 * Return HTML for the lectotype citation with the correct layout.
18
 *
19
 * This function prints the lectotype citation with the correct layout.
20
 * Lectotypes are renderized in the synonymy tab of a taxon if they exist.
21
 *
22
 * @param mixed $typeDesignation
23
 *   Object containing the lectotype citation to print.
24
 *
25
 * @return string
26
 *   Valid html string.
27
 */
28
function type_designation_citation_layout($typeDesignation, $footnote_separator = ',') {
29
  $res = '';
30
  $citation = $typeDesignation->citation;
31
  $pages = $typeDesignation->citationMicroReference;
32
  if(isset($typeDesignation->typeStatus->uuid) && isset($typeDesignation->typeStatus->representation_L10n)) {
33
    if ( $typeDesignation->typeStatus->uuid == UUID_NTD_ORIGINAL_DESIGNATION || $typeDesignation->typeStatus->uuid == UUID_NTD_MONOTYPY) {
34
      $res = ' (' . $typeDesignation->typeStatus->representation_L10n . ')';
35
      return $res;
36
    }
37
  }
38

    
39
  if ($citation) {
40
    // $type = $typeDesignation_citation->type;
41
    $year = isset($citation->datePublished->start) ? substr($citation->datePublished->start, 0, 4) : '';
42
    $author = isset($citation->authorTeam->titleCache) ? $citation->authorTeam->titleCache : '';
43
    $res .= ' (designated by ';
44
    $res .= $author;
45
    $res .= ($year ? ' ' . $year : '');
46
    $res .= ($pages ? ': ' . $pages : '');
47
    // $res .= ')';
48
    $fkey_typeDesignation = FootnoteManager::addNewFootnote(RenderHints::getRenderPath() . '-typeDesignations', $typeDesignation->citation->titleCache);
49
    $res .= theme('cdm_footnote_key', array(
50
      'footnoteKey' => $fkey_typeDesignation,
51
      'separator' => $footnote_separator,
52
      'highlightable' => TRUE,
53
      'separator_off' => TRUE,
54
    )) . ')';
55
  }
56
  return $res;
57
}
58

    
59
/**
60
 * @todo Please document this function.
61
 * @see http://drupal.org/node/1354
62
 */
63
function contains_type_designation($element, $collection) {
64
  $result = FALSE;
65
  foreach ($collection as $a) {
66
    if ($a->uuid == $element->uuid) {
67
      $result = TRUE;
68
    }
69
  }
70
  return $result;
71
}
72

    
73
/**
74
 * @todo Please document this function.
75
 * @see http://drupal.org/node/1354
76
 */
77
function cdm_add_type_designations($source, $extra) {
78
  if (is_array($source)) {
79
    $result = $source;
80
    if ($extra) {
81
      foreach ($extra as $element) {
82
        if (!contains_type_designation($element, $source)) {
83
          $result[] = $element;
84
        }
85
      }
86
    }
87
  }
88
  else {
89
    $result = $extra;
90
  }
91

    
92
  return $result;
93
}
94

    
95
/**
96
 * @todo Please document this function.
97
 * @see http://drupal.org/node/1354
98
 */
99
function theme_cdm_typedesignations($variables) {
100
  $typeDesignations = $variables['typeDesignations'];
101
  /*
102
   * if(isset($renderTemplate['referencePart']['reference']) &&
103
   * $taxonName->nomenclaturalReference){ $microreference = NULL;
104
   * if(isset($renderTemplate['referencePart']['microreference'])){
105
   * $microreference = $taxonName->nomenclaturalMicroReference; } $citation =
106
   * cdm_ws_get(CDM_WS_NOMENCLATURAL_REFERENCE_CITATION,
107
   * array($typeDesignation->uuid),
108
   * "microReference=".urlencode($microreference)); $citation =
109
   * $citation->String;
110
   */
111
  RenderHints::pushToRenderStack('typedesignations');
112
  $out = '<ul class="typeDesignations">';
113
  $typeDesignation_footnotes = FALSE;
114
  $is_lectotype = FALSE;
115
  $specimenTypeDesignations = array();
116
  $separator = ',';
117
  foreach ($typeDesignations as $typeDesignation) {
118
    if ($typeDesignation->class == 'SpecimenTypeDesignation') {
119
      // SpecimenTypeDesignations should be ordered. Collect theme here only.
120
      $specimenTypeDesignations[] = $typeDesignation;
121
    }
122
    // It is a lectotype?
123
    else {
124
      if (isset($typeDesignation->typeStatus->uuid) && $typeDesignation->typeStatus->uuid == UUID_NTD_LECTOTYPE) {
125
        $is_lectotype = TRUE;
126
      }
127
      // It's a NameTypeDesignation.
128
      if ($typeDesignation->notDesignated) {
129
        $out .= '<li class="nameTypeDesignation"><span class="status">' . ($is_lectotype ? 'Lectotype' : 'Type') . '</span>: ' . t('not designated') . '</li>';
130
        // $out .= '<li class="nameTypeDesignation"><span
131
        // class="status">Lectotype</span>: '.t('not designated'). '</li>';
132
      }
133
      elseif ($typeDesignation->typeName) {
134
        $link_to_name_page = '?q=' . path_to_name($typeDesignation->typeName->uuid);
135
        $out .= '<li class="nameTypeDesignation"><span class="status">' . ($is_lectotype ? 'Lectotype' : 'Type') . '</span>';
136

    
137
        if ($typeDesignation->citation) {
138
          $out .= type_designation_citation_layout($typeDesignation, $separator);
139
          // footnotes
140
          // $fkey_typeDesignation =
141
          // FootnoteManager::addNewFootnote(RenderHints::getRenderPath() .
142
          // '-typeDesignations-' . $typeDesignation->uuid,
143
          // $typeDesignation->citation->titleCache);
144
          /*
145
          $fkey_typeDesignation =
146
          FootnoteManager::addNewFootnote(RenderHints::getRenderPath() .
147
          '-typeDesignations', $typeDesignation->citation->titleCache);
148
          $out .= theme('cdm_footnote_key', $fkey_typeDesignation,
149
          $separator, TRUE, TRUE) . ')';
150
          */
151
        }
152
        $referenceUri = '';
153
        if (isset($typeDesignation->typeName->nomenclaturalReference)) {
154
          $referenceUri = url(path_to_reference($typeDesignation->typeName->nomenclaturalReference->uuid));
155
        }
156
        $out .= ': ' . theme('cdm_taxonName', array(
157
          'taxonName' => $typeDesignation->typeName,
158
          'nameLink' => $link_to_name_page,
159
          'refenceLink' => $referenceUri,
160
          'show_annotations' => TRUE,
161
          'is_type_designation' => TRUE,
162
          ));
163
      }
164
    }
165
  }
166

    
167
  if (!empty($specimenTypeDesignations)) {
168
    // Sorting might be different for dataportals so this has to be
169
    // parameterized.
170
    usort($specimenTypeDesignations, "compare_specimenTypeDesignationStatus");
171
    foreach ($specimenTypeDesignations as $std) {
172
      $typeReference = '';
173
      // Show citation only for Lectotype or Neotype.
174
      $showCitation = isset($std->typeStatus) && ($std->typeStatus->uuid == UUID_STD_NEOTYPE || $std->typeStatus->uuid == UUID_STD_LECTOTYPE);
175
      if ($showCitation && !empty($std->citation)) {
176
        // $shortCitation = $std->citation->authorTeam->titleCache;
177
        $author_team = cdm_ws_get(CDM_WS_REFERENCE_AUTHORTEAM, $std->citation->uuid);
178
        $shortCitation = $author_team->titleCache;
179

    
180
        $shortCitation .= (strlen($shortCitation) > 0 ? ' ' : '') . partialToYear($std->citation->datePublished->start);
181
        $missingShortCitation = FALSE;
182
        if (strlen($shortCitation) == 0) {
183
          $shortCitation = theme('cdm_reference', array('reference' => $std->citation));
184
          $missingShortCitation = TRUE;
185
        }
186

    
187
        $typeReference .= '&nbsp;(' . t('designated by');
188
        $typeReference .= '&nbsp;<span class="typeReference ' . ($missingShortCitation ? '' : 'cluetip') . ' no-print" title="' . htmlspecialchars('|' . theme('cdm_reference', array('reference' => $std->citation)) . '|') . '">';
189
        $typeReference .= $shortCitation . '</span>';
190
        $typeReference .= ':' . $std->citationMicroReference . ')';
191

    
192
        $_fkey2 = FootnoteManager::addNewFootnote(RenderHints::getRenderPath() . '-lectotypes', $std->citation->titleCache);
193
        $typeReference .= theme('cdm_footnote_key', array(
194
          'footnoteKey' => $_fkey2,
195
          'separator' => $separator,
196
          'highlightable' => TRUE,
197
          'separator_off' => TRUE,
198
         ));
199
      }
200

    
201
      $derivedUnitFacadeInstance = cdm_ws_get(CDM_WS_DERIVEDUNIT_FACADE, $std->typeSpecimen->uuid);
202

    
203
      $out .= '<li class="specimenTypeDesignation">';
204
      $out .= '<span class="status">' . ((isset($std->typeStatus->representation_L10n)) ? $std->typeStatus->representation_L10n : t('Type')) . $typeReference . '</span>: ' . $derivedUnitFacadeInstance->titleCache;
205
      $out .= theme('cdm_specimen', array('specimenTypeDesignation' => $derivedUnitFacadeInstance));
206

    
207
      // Footnotes for synonymy acronyms.
208
      $_fkey = FootnoteManager::addNewFootnote(RenderHints::getRenderPath() . '-acronyms', (isset($derivedUnitFacadeInstance->collection->titleCache) ? $derivedUnitFacadeInstance->collection->titleCache : FALSE));
209
      $out .= theme('cdm_footnote_key', array('footnoteKey' => $_fkey, 'separator' => $separator));
210
      $out .= '</li>';
211

    
212
      if (!empty($std->citation)) {
213
        $render_footnote_lectotypes = TRUE;
214
        // $out .= theme('cdm_footnotes', RenderHints::getRenderPath() .
215
        // '-lectotypes');
216
      }
217
    }
218
  }
219

    
220
  $out .= '</ul>';
221

    
222
  // Render the footnotes at the end of the page.
223
  if (isset($render_footnote_lectotypes)) {
224
    $out .= theme('cdm_footnotes', array('footnoteListKey' => RenderHints::getRenderPath() . '-lectotypes'));
225
  }
226
  $out .= theme('cdm_footnotes', array('footnoteListKey' => RenderHints::getRenderPath() . '-acronyms', 'enclosingTag' => 'li'));
227
  $out .= theme('cdm_footnotes', array('footnoteListKey' => RenderHints::getRenderPath() . '-typeDesignations', 'enclosingTag' => 'li'));
228
  // $out .= theme('cdm_footnotes', RenderHints::getRenderPath() .
229
  // '-typeDesignations-' . $typeDesignation->uuid, 'li');
230
  RenderHints::popFromRenderStack();
231

    
232
  return $out;
233
}
234

    
235
/**
236
 * FIXME this definitively has to be in another spot.
237
 * just didn't know where to put it right now.
238
 * Compares the status of two SpecimenTypeDesignations
239
 *
240
 * @param string $a
241
 *   A SpecimenTypeDesignations.
242
 * @param string $b
243
 *   SpecimenTypeDesignations.
244
 */
245
function compare_specimenTypeDesignationStatus($a, $b) {
246
  /*
247
  This is the desired sort order as of now: Holotype Isotype Lectotype
248
  Isolectotype Syntype.
249
  TODO Basically, what we are trying to do is, we define
250
  an ordered array of TypeDesignation-states and use the index of this array
251
  for comparison. This array has to be filled with the cdm- TypeDesignation
252
  states and the order should be parameterisable inside the dataportal.
253
  */
254
  // Make that static for now.
255
  $typeOrder = array(
256
    'Holotype',
257
    'Isotype',
258
    'Lectotype',
259
    'Isolectotype',
260
    'Syntype',
261
  );
262

    
263
  $aQuantifier = FALSE;
264
  $bQuantifier = FALSE;
265
  if (isset($a->typeStatus->label) && isset($b->typeStatus->label)) {
266
    $aQuantifier = array_search($a->typeStatus->label, $typeOrder);
267
    $bQuantifier = array_search($b->typeStatus->label, $typeOrder);
268
  }
269
  if ($aQuantifier == $bQuantifier) {
270
    // Sort alphabetically.
271
    return (isset($a->typeStatus->label) && isset($b->typeStatus->label) && $a->typeStatus->label < $b->typeStatus->label) ? -1 : 1;
272
  }
273
  return ($aQuantifier < $bQuantifier) ? -1 : 1;
274
}
275

    
276
/**
277
 * @todo Please document this function.
278
 * @see http://drupal.org/node/1354
279
 */
280
function theme_cdm_nameRelationships($variables) {
281
  $nameRelationships = $variables['nameRelationships'];
282
  $skipTypes = $variables['skipTypes'];
283
  if (!$nameRelationships) {
284
    return;
285
  }
286

    
287
  RenderHints::pushToRenderStack('nameRelationships');
288
  $footnoteListKey = 'nameRelationships';
289
  RenderHints::setFootnoteListKey($footnoteListKey);
290

    
291
  // Group by relationship type.
292
  $relationshipGroups = array();
293
  foreach ($nameRelationships as $nameRelationship) {
294
    if (!array_key_exists($nameRelationship->type->uuid, $relationshipGroups)) {
295
      $relationshipGroups[$nameRelationship->type->uuid] = array();
296
    }
297
    $relationshipGroups[$nameRelationship->type->uuid][] = $nameRelationship;
298
  }
299

    
300
  // Generate output.
301
  $out = '';
302
  $block = new stdclass(); // Empty object.
303
  foreach ($relationshipGroups as $group) {
304
    $type = $group[0]->type;
305

    
306
    if (is_array($skipTypes) && in_array($type->uuid, $skipTypes)) {
307
      continue;
308
    }
309

    
310
    $block->module = 'cdm_dataportal';
311
    $block->subject = t(ucfirst($type->inverseRepresentation_L10n));
312
    $block->delta = generalizeString(strtolower($type->inverseRepresentation_L10n));
313

    
314
    foreach ($group as $relationship) {
315
      $relatedNames[] = cdm_taggedtext2html($relationship->fromName->taggedName);
316
    }
317

    
318
    $block->content .= implode('; ', $relatedNames);
319
    $out .= theme('block', $block);
320
  }
321
  $out .= theme('cdm_footnotes', array('footnoteListKey' => $footnoteListKey, 'enclosingTag' => 'li'));
322

    
323
  RenderHints::popFromRenderStack();
324
  return $out;
325
}
326

    
327
/**
328
 * @todo Please document this function.
329
 * @see http://drupal.org/node/1354
330
 */
331
function theme_cdm_homotypicSynonymLine($variables) {
332
  $taxon = $variables['taxon'];
333
  $out = '';
334
  $out .= '<li class="synonym">' . cdm_related_taxon($taxon, UUID_HOMOTYPIC_SYNONYM_OF) . '</li>';
335

    
336
  return $out;
337
}
338

    
339
/**
340
 * @todo Please document this function.
341
 * @see http://drupal.org/node/1354
342
 */
343
function theme_cdm_heterotypicSynonymyGroup($variables) {
344
  $homotypicalGroup = $variables['homotypicalGroup'];
345
  RenderHints::pushToRenderStack('heterotypicSynonymyGroup');
346

    
347
  $out = '';
348
  $out = '<ul class="heterotypicSynonymyGroup">';
349
  $footnoteListKey = (isset($homotypicalGroup[0]) ? $homotypicalGroup[0]->uuid : 'NULL');
350
  RenderHints::setFootnoteListKey($footnoteListKey);
351

    
352
  $is_first_entry = TRUE;
353
  $typeDesignations = NULL;
354
  foreach ($homotypicalGroup as $synonym) {
355
    if ($is_first_entry) {
356
      $is_first_entry = FALSE;
357
      $typeDesignations = cdm_ws_get(CDM_WS_PORTAL_NAME_TYPEDESIGNATIONS, $synonym->name->uuid);
358
      // Is first list entry.
359
      $out .= '<li class="firstentry synonym">' . cdm_related_taxon($synonym, UUID_HETEROTYPIC_SYNONYM_OF) . '</li>';
360
    }
361
    else {
362
      $out .= '<li class="synonym">' . cdm_related_taxon($synonym, UUID_HOMOTYPIC_SYNONYM_OF) . '</li>';
363
    }
364
  }
365

    
366
  if ($typeDesignations) {
367
    $out .= theme('cdm_typedesignations', array('typeDesignations' => $typeDesignations));
368
  }
369

    
370
  $out .= theme('cdm_annotation_footnotes', array('footnoteListKey' => $footnoteListKey, 'enclosingTag' => 'li'));
371
  $out .= '</ul>';
372

    
373
  RenderHints::popFromRenderStack();
374
  return $out;
375
}
376

    
377
/**
378
 * @todo Please document this function.
379
 * @see http://drupal.org/node/1354
380
 */
381
function theme_cdm_homotypicSynonymyGroup($variables) {
382
  $synonymList = $variables['synonymList'];
383
  $accepted_taxon_uuid = $variables['accepted_taxon_uuid'];
384
  $prependedSynonyms = $variables['prependedSynonyms'];
385
  RenderHints::pushToRenderStack('homotypicSynonymyGroup');
386

    
387
  $footnoteListKey = isset($prependedSynonyms[0]) ? $prependedSynonyms[0]->uuid : (isset($synonymList[0]) ? $synonymList[0]->uuid : 'NULL');
388
  $accepted_taxon_footnoteListKey = RenderHints::getFootnoteListKey();
389
  RenderHints::setFootnoteListKey($footnoteListKey);
390

    
391
  if (!is_array($synonymList) || count($synonymList) == 0) {
392
    return;
393
  }
394

    
395
  $out = '<ul class="homotypicSynonyms">';
396

    
397
  if (!empty($prependedSynonyms)) {
398
    foreach ($prependedSynonyms as $taxon) {
399
      $out .= '<li class="synonym">' . cdm_related_taxon($taxon, UUID_HOMOTYPIC_SYNONYM_OF) . '</li>';
400
    }
401
  }
402

    
403
  foreach ($synonymList as $synonym) {
404
    $out .= '<li class="synonym">' . cdm_related_taxon($synonym, UUID_HOMOTYPIC_SYNONYM_OF) . '</li>';
405
  }
406

    
407
  $homonym_typeDesignations = cdm_ws_get(CDM_WS_PORTAL_NAME_TYPEDESIGNATIONS, $synonymList[0]->name->uuid);
408
  $accepted_typeDesignations = cdm_ws_get(CDM_WS_PORTAL_TAXON_NAMETYPEDESIGNATIONS, $accepted_taxon_uuid);
409
  if ($accepted_typeDesignations) {
410
    $typeDesignations = cdm_add_type_designations($homonym_typeDesignations, $accepted_typeDesignations);
411
  }
412
  else {
413
    $typeDesignations = $homonym_typeDesignations;
414
  }
415
  if ($typeDesignations) {
416
    $out .= theme('cdm_typedesignations', array('typeDesignations' => $typeDesignations));
417
  }
418
  // To avoiding drupal warnings (#1830).
419
  if ($accepted_taxon_footnoteListKey) {
420
    // Why FALSE???
421
    $out .= theme('cdm_footnotes', array('footnoteListKey' => $accepted_taxon_footnoteListKey, 'enclosingTag' => 'li'));
422
  }
423

    
424
  $out .= theme('cdm_annotation_footnotes', array('footnoteListKey' => $footnoteListKey, 'enclosingTag' => 'li'));
425
  $out .= '</ul>';
426

    
427
  RenderHints::popFromRenderStack();
428
  return $out;
429
}
430

    
431
/**
432
 * @todo document this function.
433
 */
434
function get_nameRenderTemplate($renderPath, $nameLink = NULL, $refenceLink = NULL) {
435
  // TODO implement admin user interface to replace switch statement
436
  // preliminar solution: using themes.
437
  $template = NULL;
438

    
439
  // Find best matching default RenderTemplate in theme.
440
  /*
441
  echo "<br/><br/>RENDER PATH: ".$renderPath;
442
  var_dump('RENDER PATH: ' . $renderPath);
443
  */
444

    
445
  // Preserve renderPath_base.
446
  // if (($separatorPos = strpos($renderPath, '.')) >= 0) {
447
  if (($separatorPos = strpos($renderPath, '.')) > 0) {
448
  }
449
  else {
450
    $separatorPos = strlen($renderPath);
451
  }
452
  $renderPath_base = substr($renderPath, 0, $separatorPos);
453

    
454
  $template = theme('get_nameRenderTemplate', array('renderPath' => $renderPath_base));
455

    
456
  if (!empty($template)) {
457
    while (!is_array($template) && strlen($renderPath) > 0) {
458
      $template = theme('get_nameRenderTemplate', array('renderPath' => $renderPath));
459

    
460
      $renderPath = substr($renderPath, 0, strrpos($renderPath, '.'));
461
      /*
462
      if(!is_array($template)){
463
        echo "<br/>->".$renderPath;
464
      }
465
      */
466
    }
467
    // Otherwise get default RenderTemplate from theme.
468
    if (!is_array($template)) {
469
        $template = theme('get_nameRenderTemplate', array('renderPath' => '#DEFAULT'));
470
    }
471
  }
472
  else {
473
    switch ($renderPath_base) {
474
      case 'list_of_taxa':
475
      case 'acceptedFor':
476
      case 'taxon_page_synonymy':
477
      case 'typedesignations':
478
      case 'taxon_page_title':
479
      case 'polytomousKey':
480
      case 'na':
481
        $template = array(
482
          'namePart' => array('#uri' => TRUE),
483
          // 'authorshipPart' => TRUE,
484
        );
485
        break;
486
      case 'nar':
487
        $template = array(
488
          'namePart' => array('#uri' => TRUE),
489
          'authorshipPart' => TRUE,
490
          'referencePart' => array('#uri' => TRUE),
491
          'microreferencePart' => TRUE,
492
        );
493
        break;
494
      default:
495
        $template = array(
496
          'namePart' => array('#uri' => TRUE),
497
          'authorshipPart' => TRUE,
498
          'referencePart' => array('#uri' => TRUE),
499
          'microreferencePart' => TRUE,
500
          'statusPart' => TRUE,
501
          'descriptionPart' => TRUE,
502
        );
503
    }
504
  }
505

    
506
  if ($nameLink && isset($template['nameAuthorPart']['#uri'])) {
507
    $template['nameAuthorPart']['#uri'] = $nameLink;
508
  }
509
  else {
510
    unset($template['nameAuthorPart']['#uri']);
511
  }
512

    
513
  if ($nameLink && isset($template['namePart']['#uri'])) {
514
    $template['namePart']['#uri'] = $nameLink;
515
  }
516
  else {
517
    unset($template['namePart']['#uri']);
518
  }
519

    
520
  if ($refenceLink && isset($template['referencePart']['#uri'])) {
521
    $template['referencePart']['#uri'] = $refenceLink;
522
  }
523
  else {
524
    unset($template['referencePart']['#uri']);
525
  }
526

    
527
  return $template;
528
}
529

    
530
/**
531
 * @todo document this function.
532
 */
533
function get_partDefinition($taxonNameType) {
534

    
535
  // TODO implement admin user interface to allow specify the partdefinitions
536
  // for any type.
537
  // Preliminar solution: using themes.
538
  $partdef = theme('get_partDefinition', array('nameType' => $taxonNameType));
539

    
540
  if (!is_array($partdef)) {
541
    switch ($taxonNameType) {
542
      case 'ZoologicalName':
543
        $partdef = array(
544
          'namePart' => array('name' => TRUE),
545
          'referencePart' => array('authorTeam' => TRUE),
546
          'microreferencePart' => array('microreference' => TRUE),
547
          'statusPart' => array('status' => TRUE),
548
          'descriptionPart' => array('description' => TRUE),
549
        );
550
        break;
551
      case 'BotanicalName':
552
      default:
553
        $partdef = array(
554
          'namePart' => array(
555
            'name' => TRUE,
556
            'authors' => TRUE,
557
          ),
558
          'referencePart' => array(
559
            'reference' => TRUE,
560
            'microreference' => TRUE,
561
          ),
562
          'statusPart' => array('status' => TRUE),
563
          'descriptionPart' => array('description' => TRUE),
564
        );
565
        break;
566
        /*
567
        default: $partdef = array(
568
          'namePart' => array(
569
          'name' => TRUE,
570
          'authorTeam' => TRUE
571
        ),
572
        'referencePart' => array(
573
          'reference' => TRUE
574
        ),
575
        'microreferencePart' => array(
576
          'microreference' => TRUE,
577
        ),
578
        'statusPart' => array(
579
          'status' => TRUE,
580
        ),
581
        'descriptionPart' => array(
582
          'description' => TRUE,
583
        ),
584
        );
585
        */
586
    }
587
  }
588
  return $partdef;
589
}
590

    
591
/**
592
 * @todo Please document this function.
593
 * @see http://drupal.org/node/1354
594
 */
595
function theme_cdm_taxonName($variables) {
596
  $taxonName = $variables['taxonName'];
597

    
598
  $nameLink = $variables['nameLink'];
599
  $refenceLink = $variables['refenceLink'];
600
  $show_annotations = $variables['show_annotations'];
601
  $is_type_designation = $variables['is_type_designation'];
602
  $skiptags = $variables['skiptags'];
603
  $renderTemplate = get_nameRenderTemplate(RenderHints::getRenderPath(), $nameLink, $refenceLink);
604
  $partDefinition = get_partDefinition($taxonName->class);
605

    
606
  // Apply definitions to template.
607
  foreach ($renderTemplate as $part => $uri) {
608

    
609
    if (isset($partDefinition[$part])) {
610
      $renderTemplate[$part] = $partDefinition[$part];
611
    }
612
    if (is_array($uri) && isset($uri['#uri'])) {
613
      $renderTemplate[$part]['#uri'] = $uri['#uri'];
614
    }
615
  }
616

    
617
  normalize_TaggedName($taxonName->taggedName);
618

    
619
  $firstEntryIsValidNamePart = isset($taxonName->taggedName) && is_array($taxonName->taggedName) && isset($taxonName->taggedName[0]->text) && is_string($taxonName->taggedName[0]->text) && $taxonName->taggedName[0]->text != '' && isset($taxonName->taggedName[0]->type) && $taxonName->taggedName[0]->type == 'name';
620

    
621
  // Got to use second entry as first one, see ToDo comment below ...
622
  if ($firstEntryIsValidNamePart) {
623

    
624
    $taggedName = $taxonName->taggedName;
625
    $lastAuthorElementString = FALSE;
626
    $hasNamePart_with_Authors = isset($renderTemplate['namePart']) && isset($renderTemplate['namePart']['authors']);
627
    $hasNameAuthorPart_with_Authors = isset($renderTemplate['nameAuthorPart']) && isset($renderTemplate['nameAuthorPart']['authors']);
628

    
629
    if (!(($hasNamePart_with_Authors) || ($hasNameAuthorPart_with_Authors))) {
630
      // Find author and split off from name.
631
      // TODO expecting to find the author as the last element.
632
      /*
633
      if($taggedName[count($taggedName)- 1]->type == 'authors'){
634
        $authorTeam = $taggedName[count($taggedName)- 1]->text;
635
        unset($taggedName[count($taggedName)- 1]);
636
      }
637
      */
638

    
639
      // Remove all authors.
640
      $taggedNameNew = array();
641
      foreach ($taggedName as $element) {
642
        if ($element->type != 'authors') {
643
          $taggedNameNew[] = $element;
644
        }
645
        else {
646
          $lastAuthorElementString = $element->text;
647
        }
648
      }
649
      $taggedName = $taggedNameNew;
650
    }
651
    $name = '<span class="' . $taxonName->class . '">' . theme('cdm_taggedtext2html', array(
652
      'taggedtxt' => $taggedName,
653
      'tag' => 'span',
654
      'glue' => ' ',
655
      'skiptags' => $skiptags,
656
      )) . '</span>';
657
  }
658
  else {
659
    $name = '<span class="' . $taxonName->class . '_titleCache">' . $taxonName->titleCache . '</span>';
660
  }
661

    
662
  // Fill name into $renderTemplate.
663
  array_setr('name', $name, $renderTemplate);
664

    
665
  // Fill with authorTeam.
666
  /*
667
  if($authorTeam){
668
    $authorTeamHtml = ' <span class="authorTeam">'.$authorTeam.'</span>';
669
    array_setr('authorTeam', $authorTeamHtml, $renderTemplate);
670
  }
671
  */
672

    
673
  // Fill with reference.
674
  if (isset($renderTemplate['referencePart']) && !$is_type_designation) {
675

    
676
    // [Eckhard]:"Komma nach dem Taxonnamen ist grunsätzlich falsch,
677
    // Komma nach dem Autornamen ist überall dort falsch, wo ein "in" folgt."
678
    if (isset($renderTemplate['referencePart']['reference']) && isset($taxonName->nomenclaturalReference)) {
679
      $microreference = NULL;
680
      if (isset($renderTemplate['referencePart']['microreference'])&& isset($taxonName->nomenclaturalMicroReference)) {
681
        $microreference = $taxonName->nomenclaturalMicroReference;
682
      }
683
      $citation = cdm_ws_getNomenclaturalReference($taxonName->nomenclaturalReference->uuid, $microreference);
684

    
685
      // Find preceding element of the reference.
686
      $precedingKey = get_preceding_contentElementKey('reference', $renderTemplate);
687
      if (str_beginsWith($citation, ", in")) {
688
        $citation = substr($citation, 2);
689
        $separator = ' ';
690
      }
691
      elseif (!str_beginsWith($citation, "in") && $precedingKey == 'authors') {
692
        $separator = ', ';
693
      }
694
      else {
695
        $separator = ' ';
696
      }
697

    
698
      $referenceArray['#separator'] = $separator;
699
      $referenceArray['#html'] = '<span class="reference">' . $citation . '</span>';
700
      array_setr('reference', $referenceArray, $renderTemplate);
701
    }
702

    
703
    // If authors have been removed from the name part the last named authorteam
704
    // should be added to the reference citation, otherwise, keep the separator
705
    // out of the reference.
706
    if (isset($renderTemplate['referencePart']['authors']) && $lastAuthorElementString) {
707
      // If the nomenclaturalReference citation is not included in the
708
      // reference part but diplay of the microreference
709
      // is wanted, append the microreference to the authorTeam.
710
      if (!isset($renderTemplate['referencePart']['reference']) && isset($renderTemplate['referencePart']['microreference'])) {
711
        $separator = ": ";
712
        $citation = $taxonName->nomenclaturalMicroReference;
713
      }
714
      $referenceArray['#html'] = ' <span class="reference">' . $lastAuthorElementString . $separator . $citation . '</span>';
715
      array_setr('authors', $referenceArray, $renderTemplate);
716
    }
717
  }
718

    
719
  // Fill with status.
720
  $statusHtml = '';
721
  if (isset($taxonName->status) && is_array($taxonName->status)) {
722
    if (array_setr('status', TRUE, $renderTemplate)) {
723
      if (isset($taxonName->status[0])) {
724
        foreach ($taxonName->status as $status) {
725
          $statusHtml .= ', ' . $status->type->representation_L10n_abbreviatedLabel;
726
        }
727
      }
728
      array_setr('status', '<span class="nomenclatural_status">' . $statusHtml . '</span>', $renderTemplate);
729
    }
730
  }
731

    
732
  // Fill with protologues etc...
733
  $descriptionHtml = '';
734
  if (array_setr('description', TRUE, $renderTemplate)) {
735
    $descriptions = cdm_ws_get(CDM_WS_PORTAL_NAME_DESCRIPTIONS, $taxonName->uuid);
736
    foreach ($descriptions as $description) {
737
      if (!empty($description)) {
738
        foreach ($description->elements as $description_element) {
739
          $second_citation = '';
740
          if (isset($description_element->multilanguageText_L10n) && $description_element->multilanguageText_L10n->text) {
741
            $second_citation = '[& ' . $description_element->multilanguageText_L10n->text . '].';
742
          }
743
          $descriptionHtml .= $second_citation;
744
          $descriptionHtml .= theme("cdm_media", array('descriptionElement' => $description_element, 'mimeTypePreference' => array(
745
  'application/pdf',
746
  'image/png',
747
  'image/jpeg',
748
  'image/gif',
749
  'text/html',
750
)));
751

    
752
        }
753
      }
754
    }
755
    array_setr('description', $descriptionHtml, $renderTemplate);
756
  }
757

    
758
  // Render.
759
  $out = '<span ref="/name/' . $taxonName->uuid . '">';
760

    
761
  foreach ($renderTemplate as $partName => $part) {
762
    $separator = '';
763
    $partHtml = '';
764
    $uri = FALSE;
765
    if (!is_array($part)) {
766
      continue;
767
    }
768
    if (isset($part['#uri']) && is_string($part['#uri'])) {
769
      $uri = $part['#uri'];
770
      unset($part['#uri']);
771
    }
772
    foreach ($part as $key => $content) {
773
      $html = '';
774
      if (is_array($content)) {
775
        $html = $content['#html'];
776
        $separator = $content['#separator'];
777
      }
778
      elseif (is_string($content)) {
779
        $html = $content;
780
      }
781
      $partHtml .= '<span class="' . $key . '">' . $html . '</span>';
782
    }
783
    if ($uri) {
784
      $out .= $separator . '<a href="' . $uri . '" class="' . $partName . '">' . $partHtml . '</a>';
785
    }
786
    else {
787
      $out .= $separator . $partHtml;
788
    }
789
  }
790
  $out .= '</span>';
791
  if ($show_annotations) {
792
    // $out .= theme('cdm_annotations_as_footnotekeys', $taxonName);
793
  }
794
  return $out;
795
}
796

    
797
/**
798
 * Recursively searches the array for the $key and sets the given value.
799
 *
800
 * @param mixed $key
801
 *   Key to search for.
802
 * @param mixed $value
803
 *   Value to set.
804
 * @param array $array
805
 *   Array to search in.
806
 *
807
 * @return bool
808
 *   True if the key has been found.
809
 */
810
function &array_setr($key, $value, array &$array) {
811
  $res = NULL;
812
  foreach ($array as $k => &$v) {
813
    if ($key == $k) {
814
      $v = $value;
815
      return $array;
816
    }
817
    elseif (is_array($v)) {
818
      $innerArray = array_setr($key, $value, $v);
819
      if ($innerArray) {
820
        return $array;
821
      }
822
    }
823
  }
824
  return $res;
825
}
826

    
827
/**
828
 * @todo Please document this function.
829
 * @see http://drupal.org/node/1354
830
 */
831
function &get_preceding_contentElement($contentElementKey, array &$renderTemplate) {
832
  $res = NULL;
833
  $precedingElement = NULL;
834
  foreach ($renderTemplate as &$part) {
835
    foreach ($part as $key => &$element) {
836
      if ($key == $contentElementKey) {
837
        return $precedingElement;
838
      }
839
      $precedingElement = $element;
840
    }
841
  }
842
  return $res;
843
}
844

    
845
/**
846
 * @todo Please document this function.
847
 * @see http://drupal.org/node/1354
848
 */
849
function &get_preceding_contentElementKey($contentElementKey, array &$renderTemplate) {
850
  $res = NULL;
851
  $precedingKey = NULL;
852
  foreach ($renderTemplate as &$part) {
853
    if (is_array($part)) {
854
      foreach ($part as $key => &$element) {
855
        if ($key == $contentElementKey) {
856
          return $precedingKey;
857
        }
858
        if (!str_beginsWith($key, '#')) {
859
          $precedingKey = $key;
860
        }
861
      }
862
    }
863
  }
864
  return $res;
865
}
866

    
867
/**
868
 * Returns HTML for a name in your theme, when implemented.
869
 *
870
 * This function returns currently nothing, but can be used to override
871
 * how names are rendered in your theme. See the code that is commented out
872
 * for an example usage. it is used in the function get_nameRenderTemplate.
873
 * See that function to find out how the create template is used.
874
 *
875
 * @see get_nameRenderTemplate()
876
 *
877
 * @param array $variables
878
 *   An associative array containing:
879
 *   - renderPath: feature in which the name is displayed.
880
 *
881
 * @ingroup: themeable
882
 */
883
function theme_get_nameRenderTemplate($variables) {
884
  /*
885
  // Example usage:
886
  $render_path = $variables['renderPath'];
887
  $template = array();
888
  switch ($render_path) {
889
    case 'taxon_page_title':
890
    case 'polytomousKey':
891
      $template = array(
892
        'namePart' => array(
893
          '#uri' => TRUE
894
        )
895
      );
896
      break;
897
    case 'taxon_page_synonymy':
898
    case 'related_taxon':
899
      $template = array(
900
        'nameAuthorPart' => array(
901
          '#uri' => TRUE
902
        ), 'referencePart' => TRUE, 'statusPart' => TRUE, 'descriptionPart' => TRUE
903
      );
904
      break;
905
    case 'acceptedFor':
906
      $template = array(
907
        'nameAuthorPart' => array(
908
          '#uri' => TRUE
909
        ), 'referencePart' => TRUE
910
      );
911
      break;
912
    case 'typedesignations':
913
    case 'list_of_taxa':
914
    case '#DEFAULT':
915
      $template = array(
916
        'nameAuthorPart' => array(
917
           '#uri' => TRUE
918
        ), 'referencePart' => TRUE
919
      );
920
  }
921
  return $template;
922
  */
923
  return FALSE;
924
}
(5-5/9)