1
|
<?php
|
2
|
// $Id$
|
3
|
|
4
|
require_once('cdm/cdm_api.php');
|
5
|
|
6
|
function tagNameParts($name, $numOfNameTokens){
|
7
|
|
8
|
$out = '<span class="name">';
|
9
|
|
10
|
$token = strtok($name, " \n\t");
|
11
|
$i = 0;
|
12
|
$noSpace = true;
|
13
|
while($token != false){
|
14
|
if($i == $numOfNameTokens){
|
15
|
$out .= '</span> <span class="authors">';
|
16
|
$noSpace = true;
|
17
|
}
|
18
|
$out .= ($noSpace?'':' ').$token;
|
19
|
$noSpace = false;
|
20
|
$token = strtok(" \n\t");
|
21
|
$i++;
|
22
|
}
|
23
|
return $out.'</span>';
|
24
|
}
|
25
|
|
26
|
/**
|
27
|
* Renders the full name string (complete scientific name including the author team)
|
28
|
*
|
29
|
* @param NameTO $nameTO the taxon name
|
30
|
*/
|
31
|
function theme_cdm_name($nameTO){
|
32
|
//TODO: how to respect the different subtypes of eu.etaxonomy.cdm.model.name.TaxonNameBase ?
|
33
|
$out = '<h2>Dummy content</h2>';
|
34
|
if($nameTO){
|
35
|
$out .= '<pre>'.print_r($nameTO, true).'</pre>';
|
36
|
$out .= '<div>'.$nameTO->ws_url.'</div>';
|
37
|
//$out .= '<div>'.cdm_taggedtext2html($nameTO->taggedName).'</div>';
|
38
|
} else {
|
39
|
$out .= '<div>Item not found</div>';
|
40
|
}
|
41
|
return $out;
|
42
|
}
|
43
|
|
44
|
/**
|
45
|
* Renders the given TaxonTO. The $enclosingTag (if not set false)
|
46
|
* will get the following class attributes:
|
47
|
* - name
|
48
|
* - acceptet (only if $ptaxon is an accepted name)
|
49
|
*
|
50
|
* @param TaxonTO $taxon
|
51
|
* @param boolean $noSecundum defaults to false. If set to true the secundum part is omitted.
|
52
|
* @param string $enclosingTag defaults to span.
|
53
|
* @param boolean $showNomRef whether to dispülay the nomenclatural reference
|
54
|
* @return string of XHTML
|
55
|
*
|
56
|
* usage: taxon_detail, theme_ptname_link
|
57
|
*/
|
58
|
function theme_cdm_taxon(TaxonTO $taxon, $noSecundum = true ,$enclosingTag = 'span', $showNomRef = false){
|
59
|
|
60
|
/* TODO: port me
|
61
|
$refSecundum = false;
|
62
|
if(!$noSecundum && $taxon->ref){
|
63
|
$refSecundum = str_trunk($ptaxon->ref, 40, '...');
|
64
|
}
|
65
|
*/
|
66
|
$out = theme('cdm_name', $taxon)
|
67
|
.($refSecundum ? ' <span class="secundum">sec. '.$refSecundum.'</span>': '')
|
68
|
.$ptaxon->namePhrase;
|
69
|
/* TODO: port me
|
70
|
if($showNomRef){
|
71
|
$out .= (str_beginsWith($ptaxon->nomRef, 'in') || trim($ptaxon->nomRef) == '' ? ' ':', ').theme('cdm_nomRef',$taxon);
|
72
|
}
|
73
|
if($enclosingTag){
|
74
|
$out = '<'.$enclosingTag.' class="name'.($ptaxon->isAccepted()?' accepted':'').'"><!-- ['.$ptaxon->nameId.'|'.$ptaxon->refId.'] -->'.$out.'</'.$enclosingTag.'>';
|
75
|
}
|
76
|
*/
|
77
|
|
78
|
return $out;
|
79
|
|
80
|
}
|
81
|
|
82
|
/**
|
83
|
* Renders a link to the taxon detail page for the given $taxon
|
84
|
*
|
85
|
* @param TaxonTO $taxon
|
86
|
*/
|
87
|
function theme_cdm_taxon_link(TaxonTO $taxon, $fragment = '', $showNomRef = false){
|
88
|
|
89
|
if($fragment){
|
90
|
$fragment = '#'.$fragment;
|
91
|
}
|
92
|
|
93
|
if(!$taxon->isAccepted) {
|
94
|
$out = 'ERROR: theme_cdm_taxon_link() not accepted ptname; status:'.$taxon->status.$out;
|
95
|
}
|
96
|
|
97
|
$out = l(theme('cdm_taxon', $taxon, true, false), 'taxon', array('class'=>'accepted'), "uuid=$taxon->uuid", $fragment);
|
98
|
|
99
|
if($showNomRef){
|
100
|
$out .=' '.theme('cdm_nomRef', $ptaxon);
|
101
|
}
|
102
|
|
103
|
return $out;
|
104
|
}
|
105
|
|
106
|
//TODO: port everything below
|
107
|
|
108
|
/**
|
109
|
* Renders a list of synonyms including misapplied names which are related to the
|
110
|
* given TAXIC_PTaxon.
|
111
|
*
|
112
|
* @param TAXIC_PTaxon $ptaxon
|
113
|
* @param boolean $recursive default is false. Whether to crawl recursively into the
|
114
|
* three of relations
|
115
|
*
|
116
|
* usage taxon_detail.php.inc
|
117
|
*/
|
118
|
function render_synonyms(TAXIC_PTaxon $ptaxon, $recursive = false, $showNotes = false){
|
119
|
|
120
|
$_debug = false;
|
121
|
|
122
|
$is_higher_rank = $ptaxon->rankId < 60;
|
123
|
|
124
|
|
125
|
$out = false;
|
126
|
$last_relQualifierId = false;
|
127
|
$last_was_heterotypic = false;
|
128
|
$last_basionym_nameId = false;
|
129
|
$is_other_basionym = false;
|
130
|
|
131
|
$synonyms = findSynonyms($ptaxon->nameId, $ptaxon->refId, false, $recursive);
|
132
|
|
133
|
foreach($synonyms AS $relpt){ // -- relations loop
|
134
|
|
135
|
// whether this is the first entry in the lsit
|
136
|
$is_first_entry = $out === false;
|
137
|
|
138
|
// whether the current taxon has another basionym than the last one
|
139
|
$is_other_basionym = $last_basionym_nameId !== false
|
140
|
&& ($last_basionym_nameId !== $relpt->basionymNameId)
|
141
|
&& $relpt->relQualifierId != 3;
|
142
|
|
143
|
// whether the current taxon has another name ralation than the last one
|
144
|
$is_other_relQualifierId = $last_relQualifierId !== false && ($last_relQualifierId !== $relpt->relQualifierId);
|
145
|
|
146
|
//is here the end of list of homotypic end of heterotypic subsection?
|
147
|
//$end_of_section = ($last_relQualifierId !== false && $is_other_basionym);
|
148
|
$end_of_section = !$is_first_entry && $is_other_basionym || $is_other_relQualifierId && $relpt->relQualifierId == 3 /* misaplied */;
|
149
|
|
150
|
// name relations declared as synomyn (id=2) are assumed to be heterotypic
|
151
|
$is_heterotypic = $relpt->relQualifierId == 6 || ($relpt->relQualifierId == 2 && !$is_other_basionym && $last_was_heterotypic);
|
152
|
// DELETE ME? $is_heterotypic = $relpt->relQualifierId == 6 || ($relpt->relQualifierId == 2 && !$is_other_basionym);
|
153
|
|
154
|
$is_homotypic = $relpt->relQualifierId == 7 || $relpt->relQualifierId == 101 || $relpt->relQualifierId == 103;
|
155
|
|
156
|
// is this taxon homotypic to a previously printed heterotypic taxon, so is should be
|
157
|
// an intented subelement and re-taged as homotypic
|
158
|
$is_subelement = $is_heterotypic && !$is_other_basionym && !$is_first_entry;
|
159
|
|
160
|
$is_the_basionym = $is_homotypic && !$last_basionym_nameId;
|
161
|
|
162
|
|
163
|
if($is_first_entry){
|
164
|
$out = '<ul>'.chr(10).'<li class="blank_line"></li>'.chr(10);
|
165
|
if($is_heterotypic){
|
166
|
if($_debug) $out .= '<li><span style="color:blue; font-size: 80%;">renderTypeDesignations before first entry which is heterotypic]</span></li>';
|
167
|
$out .= renderTypeDesignations($ptaxon->nameId, '', $is_higher_rank );
|
168
|
$out .= '<li class="blank_line"></li>'.chr(10);
|
169
|
}
|
170
|
}
|
171
|
/*$out .= '<li><span style="color:blue; font-size: 80%;">last: '
|
172
|
.$last_basionym_nameId.' !== '.$relpt->basionymNameId.' '.$relpt->fullName
|
173
|
.'</span></li>';
|
174
|
*/
|
175
|
//DEBUG $out .= '<pre>'.print_r($relpt, true).'</pre>';
|
176
|
|
177
|
if($is_other_basionym){
|
178
|
if($_debug) $out .= '<li><span style="color:blue; font-size: 80%;">renderTypeDesignations 1 (relID: '.$last_relQualifierId.' for '.$last_basionym_nameId.')</span></li>';
|
179
|
$out .= renderTypeDesignations($last_basionym_nameId, ($last_was_heterotypic ? 'subelement' : ''), $is_higher_rank );
|
180
|
//$out .= renderTypeDesignations($last_basionym_nameId, '', $is_higher_rank );
|
181
|
}
|
182
|
|
183
|
if($end_of_section){
|
184
|
// find type information
|
185
|
$out .= '<li class="blank_line"></li>'.chr(10);
|
186
|
}
|
187
|
|
188
|
if($is_subelement){
|
189
|
// all those taxa which are homotypic to the preceeding basionym are to be
|
190
|
// displayed as homotypic
|
191
|
$relpt->relQualifierId = 7;
|
192
|
$cssClass = 'subelement';
|
193
|
} else {
|
194
|
$cssClass = '';
|
195
|
}
|
196
|
|
197
|
$out .= render_related_ptname($relpt, 'li', $cssClass, $showNotes).chr(10);
|
198
|
|
199
|
// remember last synonyms properties for next round
|
200
|
$last_relQualifierId = $relpt->relQualifierId;
|
201
|
$last_basionym_name = $relpt->basionymFullName;
|
202
|
$last_basionym_nameId = $relpt->basionymNameId;
|
203
|
$last_was_heterotypic = $is_heterotypic;
|
204
|
|
205
|
} // END relations loop
|
206
|
|
207
|
|
208
|
if($is_the_basionym){
|
209
|
if($_debug) $out .= '<li><span style="color:blue; font-size: 80%;">renderTypeDesignations 0 for '.$relpt->nameId.'</span></li>';
|
210
|
$out .= renderTypeDesignations($relpt->nameId, '', $is_higher_rank);
|
211
|
} else
|
212
|
// TypeDesignations for the last item
|
213
|
if($is_other_basionym || !$last_was_heterotypic){
|
214
|
if($_debug) $out .= '<li><span style="color:blue; font-size: 80%;">renderTypeDesignations 2 for '.$last_basionym_nameId.'</span></li>';
|
215
|
$out .= renderTypeDesignations($last_basionym_nameId, '', $is_higher_rank);
|
216
|
} else
|
217
|
|
218
|
// In case the given PTaxon had no synonyms ...
|
219
|
if($last_basionym_nameId === false || $last_relQualifierId == 7){
|
220
|
if($_debug) $out .= '<li><span style="color:blue; font-size: 80%;">renderTypeDesignations 3 for'.$ptaxon->nameId.'; last_basionym_nameId = '.$last_basionym_nameId.'</span></li>';
|
221
|
$out .= renderTypeDesignations($ptaxon->nameId, '', $is_higher_rank);
|
222
|
} else {
|
223
|
$out .= '<li class="blank_line"></li>'.chr(10).'</ul>';
|
224
|
}
|
225
|
|
226
|
return $out;
|
227
|
}
|
228
|
// -------------------- END function render_synonyms()
|
229
|
|
230
|
function render_homonyms(TAXIC_TaxonName $taxon){
|
231
|
$homonyms = getLaterHomonyms($taxon);
|
232
|
$out = '';
|
233
|
|
234
|
foreach($homonyms as $homnym){
|
235
|
$out .= '<li class="homonym">[non '.$homnym->authors.', '.$homnym->nomRef.']'.render_notes($homnym).'</li>';
|
236
|
}
|
237
|
|
238
|
if($out){
|
239
|
$out = '<ul>'.$out.'</ul>';
|
240
|
}
|
241
|
return $out;
|
242
|
}
|
243
|
|
244
|
/**
|
245
|
* render_related_ptname() is used by render_synonyms()
|
246
|
* @param TAXIC_PTaxon $relPTaxon
|
247
|
* @param String $enclosingTag
|
248
|
*/
|
249
|
function render_related_ptname($relPTaxon, $enclosingTag = 'li', $cssClass = '', $showNotes = false){
|
250
|
|
251
|
$cssClass .= ' '.str_replace(' ', '_', $relPTaxon->relQualifier);
|
252
|
|
253
|
switch($relPTaxon->relQualifierId){
|
254
|
case 7 :
|
255
|
case 101 :
|
256
|
case 103 : // homotypic-synonym
|
257
|
$relSign = '≡';
|
258
|
break;
|
259
|
case 3 : // misapplied_name
|
260
|
$relSign = '-';
|
261
|
break;
|
262
|
case 8 : // invalid_designation
|
263
|
$relSign = '-';
|
264
|
break;
|
265
|
default :
|
266
|
$relSign = '=';
|
267
|
break;
|
268
|
}
|
269
|
|
270
|
//$relSign .= $relPTaxon->relQualifierId;
|
271
|
|
272
|
$out = '';
|
273
|
|
274
|
if($relPTaxon->relQualifierId == 3){
|
275
|
// special look for misapplied_names
|
276
|
$relatedToName = ''; // only used in HTML comment
|
277
|
$sensuPart = ' sensu '.$relPTaxon->ref;
|
278
|
if($relPTaxon->relInversion){
|
279
|
$namePart = ($relPTaxon->isAccepted()? render_ptname_link($relPTaxon) : render_ptname($relPTaxon));
|
280
|
$out = $relPTaxon->relQualifier.' '.$namePart.' '.$sensuPart;
|
281
|
} else {
|
282
|
$namePart = '„'.trim($relPTaxon->name).'“';
|
283
|
if($relPTaxon->relPTaxon->name){
|
284
|
// only used in HTML comment!!
|
285
|
$relatedToName = trim($relPTaxon->relPTaxon->name);
|
286
|
}
|
287
|
$out .= $namePart.'</span>'.$sensuPart;
|
288
|
}
|
289
|
|
290
|
} else {
|
291
|
$relatedToName = ($relPTaxon->relPTaxon ? $relPTaxon->relPTaxon->name : false);
|
292
|
if($relPTaxon->isAccepted()) {
|
293
|
$out .= render_ptname_link($relPTaxon, null, true);
|
294
|
} else {
|
295
|
$out .= render_ptname($relPTaxon, true ,'span', true);
|
296
|
}
|
297
|
|
298
|
} // END else special look for misapplied_names
|
299
|
|
300
|
$notes = ($showNotes && showNotes() ? render_notes($relPTaxon) : '');
|
301
|
|
302
|
$out = '<'.$enclosingTag.' class="'.$cssClass.'"><!-- '.$relPTaxon->relQualifier.' '.$relatedToName.'-->'
|
303
|
.'<a name="'.$relPTaxon->nameId.'_'.$relPTaxon->refId.'" ></a><span class="relation_sign">'.$relSign.'</span> '
|
304
|
.$out . $notes
|
305
|
.'</'.$enclosingTag.'>';
|
306
|
return $out;
|
307
|
}
|
308
|
|
309
|
/**
|
310
|
* @param TAXIC_PTaxon $ptname
|
311
|
*/
|
312
|
$NOMREFSET_COUNTER = 0;
|
313
|
|
314
|
function render_nomRef($ptname){
|
315
|
global $conf;
|
316
|
global $NOMREFSET_COUNTER;
|
317
|
$NOMREFSET_COUNTER += 1;
|
318
|
if(count($protoploges = $ptname->getProtologues()) > 0){
|
319
|
$prot = $protoploges[0];
|
320
|
// FIXME: protologues are really a list of links. treat only the first
|
321
|
if(is_file($conf['abs_media_path'].$conf['protologue_path'].$prot.".png")){
|
322
|
$nomrefLink = '<span class="nomref"><a href="'.$conf['protologue_path'].$prot.'.png" rel="lightbox[nomrefset'.$NOMREFSET_COUNTER.']" title="<a href="'.$conf['protologue_quality_path'].$prot.'.tif">High Quality Scan</a>">'.trim($ptname->nomRef).'</a></span>';
|
323
|
} else {
|
324
|
$nomrefLink = '<span class="nomref"><a href="'.$conf['protologue_path'].$prot.'001.png" rel="lightbox[nomrefset'.$NOMREFSET_COUNTER.']" title="<a href="'.$conf['protologue_quality_path'].$prot.'.tif">High Quality Scan</a>">'.trim($ptname->nomRef).'</a></span>';
|
325
|
// check in filesystem if there are more pages as JPGs. TIFFs can cope with 8 pages per file, so no need for that
|
326
|
$i=2;
|
327
|
while (is_file($conf['abs_media_path'].$conf['protologue_path'].$prot.str_pad($i, 3, '0', STR_PAD_LEFT).".png")){
|
328
|
$nomrefLink = $nomrefLink." <a href='".$conf['protologue_path'].$prot.str_pad($i, 3, '0', STR_PAD_LEFT).".png' rel='lightbox[nomrefset".$NOMREFSET_COUNTER."]'></a>";
|
329
|
$i++;
|
330
|
}
|
331
|
}
|
332
|
return $nomrefLink;
|
333
|
} else {
|
334
|
return '<span class="nomref">'.trim($ptname->nomRef).'</span>';
|
335
|
}
|
336
|
|
337
|
}
|
338
|
|
339
|
function renderTypeDesignations($nameId, $cssClass = '', $togglebox = false, $separator = '<br />' , $enclosingTag = 'li'){
|
340
|
|
341
|
$typeDesignations = getTypeDesignations($nameId);
|
342
|
|
343
|
if(count($typeDesignations) > 0){
|
344
|
$out = '';
|
345
|
foreach($typeDesignations as $td){
|
346
|
|
347
|
if(strlen($out) > 0){
|
348
|
$out .= $separator.chr(10);
|
349
|
}
|
350
|
$out .= $td['TypeStatus'].' - '.html_entity_decode($td['TypePhrase']);
|
351
|
}
|
352
|
|
353
|
if($togglebox){
|
354
|
$out = '<div class="tbox_toggler"> </div><div class="tbox_content">'.$out.'</div>';
|
355
|
}
|
356
|
return '<'.$enclosingTag.' class="type_designation'.($cssClass ? ' '.$cssClass : '' ).'">'
|
357
|
.$out.'</'.$enclosingTag.'>'.chr(10);
|
358
|
|
359
|
}
|
360
|
}
|
361
|
|
362
|
/**
|
363
|
* render a numeric pager
|
364
|
*/
|
365
|
function renderNumPager($numOfPages, $activePage, $maxPagerItems, $linkUrlBase){
|
366
|
|
367
|
if ($activePage > $maxPagerItems - 2){
|
368
|
// shift visible pager items
|
369
|
$begin = $activePage - floor($maxPagerItems / 2);
|
370
|
$end = min($activePage + ceil($maxPagerItems / 2), $numOfPages);
|
371
|
} else {
|
372
|
$begin = 1;
|
373
|
$end = min($numOfPages, $maxPagerItems);
|
374
|
}
|
375
|
// hide the pager if there is only one page:
|
376
|
if($begin == $end)
|
377
|
return;
|
378
|
|
379
|
echo '<ul class="paging numeric">';
|
380
|
if ($activePage > 10){
|
381
|
echo '<li><a href="', $linkUrlBase, $activePage - 10, '" title="backward 10 pages">«</a></li>';
|
382
|
}
|
383
|
if ($activePage > 1){
|
384
|
echo '<li><a href="', $linkUrlBase, $activePage - 1, '" title="previuos"><</a></li>';
|
385
|
}
|
386
|
for ($pn = $begin; $pn <= $end ; ++$pn) {
|
387
|
if($pn != $activePage){
|
388
|
echo '<li><a href="'.$linkUrlBase.$pn.'">'. $pn. '</a></li>';
|
389
|
} else {
|
390
|
echo '<li class="active">'.$pn.'</li>';
|
391
|
}
|
392
|
}
|
393
|
if ($activePage < $numOfPages){
|
394
|
echo '<li><a href="', $linkUrlBase, $activePage + 1, '" title="next">></a></li>';
|
395
|
}
|
396
|
if ($activePage < $numOfPages - 9){
|
397
|
echo '<li><a href="', $linkUrlBase, $activePage + 10, '" title="forward 10 pages">»</a></li>';
|
398
|
}
|
399
|
if($numOfPages > 0){
|
400
|
echo '<li> (of '.$numOfPages.' pages)</li>';
|
401
|
}
|
402
|
echo '</ul>';
|
403
|
}
|
404
|
|
405
|
/**
|
406
|
* @param TAXIC_TaxonName $taxon
|
407
|
*/
|
408
|
function render_notes(TAXIC_TaxonName $taxon){
|
409
|
|
410
|
if(!showNotes()){
|
411
|
return;
|
412
|
}
|
413
|
|
414
|
$notes = array();
|
415
|
if($taxon->nameNotes && trim($taxon->nameNotes)){
|
416
|
$notes['Name Notes'] = $taxon->nameNotes;
|
417
|
}
|
418
|
if($taxon->nomRefNotes && trim($taxon->nomRefNotes)){
|
419
|
$notes['Nomenclatural Ref. Notes'] = $taxon->nomRefNotes;
|
420
|
}
|
421
|
|
422
|
if($taxon instanceof TAXIC_PTaxon){
|
423
|
if($taxon->nameNotes && trim($taxon->conceptNotes)){
|
424
|
$notes['Taxon Concept Notes'] = $taxon->conceptNotes;
|
425
|
}
|
426
|
if($taxon->refNotes && trim($taxon->refNotes)){
|
427
|
$notes['Concept Reference Notes'] = $taxon->refNotes;
|
428
|
}
|
429
|
}
|
430
|
if(count($notes) > 0){
|
431
|
$out = '<span class="note_toggler"><img src="themes/cichorieae/note_gray.gif" /><div class="note">';
|
432
|
$out .= '<div class="title"><div class="close" title="close"><img src="themes/cichorieae/close.gif" /></div>Notes on '.render_name($taxon).'</div><div class="content">';
|
433
|
foreach(array_keys($notes) as $title){
|
434
|
$out .= render_notes_entry($title, $notes[$title]);
|
435
|
}
|
436
|
return $out.'</div></div></span>';
|
437
|
} else {
|
438
|
return;
|
439
|
}
|
440
|
}
|
441
|
|
442
|
function render_notes_entry($title, $note){
|
443
|
|
444
|
return '<h4>'.$title.'</h4><p>'.htmlspecialchars($note).'</p>'.chr(10);
|
445
|
}
|
446
|
|