Project

General

Profile

Download (76 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
// $Id$
3

    
4
/*
5
 * Copyright (C) 2007 EDIT
6
 * European Distributed Institute of Taxonomy
7
 * http://www.e-taxonomy.eu
8
 */
9

    
10
function _add_js_thickbox(){
11
  // ---- jQuery thickbox:
12
  /*
13
  * bug: compat-1.0.js && thickbox.js line 237 .trigger("unload")
14
  * -> event is not triggered because of problems with compat-1.0.js'
15
  * see INSTALL.txt
16
  *
17
  */
18
  //drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/jquery.imagetool.min.js');
19
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/thickbox/thickbox.js');
20
  drupal_add_css(drupal_get_path('module', 'cdm_dataportal').'/js/thickbox/cdm_thickbox.css');
21
}
22

    
23
function _add_js_lightbox($galleryID){
24
  $lightBoxBasePath = drupal_get_path('module', 'cdm_dataportal') .'/js/jquery-lightbox-0.5';
25
  drupal_add_js($lightBoxBasePath.'/js/jquery.lightbox-0.5.js');
26
  drupal_add_css($lightBoxBasePath.'/css/jquery.lightbox-0.5.css');
27
  drupal_add_js ('$(document).ready(function() {
28
      $(\'#'.$galleryID.' a.lightbox\').lightBox({
29
        fixedNavigation:  true,
30
        imageLoading:     \''.$lightBoxBasePath.'/images/lightbox-ico-loading.gif\', 
31
        imageBtnPrev:     \''.$lightBoxBasePath.'/images/lightbox-btn-prev.gif\',    
32
        imageBtnNext:     \''.$lightBoxBasePath.'/images/lightbox-btn-next.gif\',   
33
        imageBtnClose:    \''.$lightBoxBasePath.'/images/lightbox-btn-close.gif\',  
34
        imageBlank:       \''.$lightBoxBasePath.'/images/lightbox-blank.gif\'
35
      });
36
    });', 'inline');
37
}
38

    
39

    
40
function _add_js_cluetip(){
41
  
42
  //TODO replace by http://www.socialembedded.com/labs/jQuery-Tooltip-Plugin/jQuery-Tooltip-Plugin.html
43
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/cluetip/jquery.cluetip.js');
44
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/jquery.dimensions.js');
45
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/cluetip/jquery.hoverIntent.js');
46
  drupal_add_css(drupal_get_path('module', 'cdm_dataportal').'/js/cluetip/jquery.cluetip.css');
47
  drupal_add_js ("$(document).ready(function(){
48
      $('.cluetip').css({color: '#0062C2'}).cluetip({
49
        splitTitle: '|',
50
        showTitle: true,
51
        activation: 'hover',
52
        sicky: true,
53
        arrows: true,
54
        dropShadow: false,
55
        cluetipClass: 'rounded'
56
      });
57
    });", 'inline');
58
}
59

    
60
/**
61
 * TODO if getting fragment from request is possible remove $_REQUEST['highlite'] HACK
62
 * NOT WORKING since fragments are not available to the server
63
 function fragment(){
64
 global $fragment;
65
 if(!$fragment){
66
 $fragment = substr($_SERVER['REQUEST_URI'], strrpos($_SERVER['REQUEST_URI'], '#'));
67
 }
68
 return $fragment;
69
 }
70
 */
71

    
72
function uuid_anchor($uuid, $innerHTML){
73
  $highlite = $_REQUEST['highlite'] == $uuid;
74
  return '<a name="'.$uuid.'" ></a><span class="'.($highlite ? 'highlite' : '').'">'.$innerHTML.'</span>';
75
}
76

    
77
/**
78
 * Enter description here...
79
 *
80
 * @param unknown_type $name
81
 * @param unknown_type $numOfNameTokens
82
 * @return unknown
83
 * @deprecated looks like this is not used anymore
84
 */
85
function tagNameParts($name, $numOfNameTokens){
86

    
87
  $out = '<span class="name">';
88

    
89
  $token = strtok($name, " \n\t");
90
  $i = 0;
91
  $noSpace = true;
92
  while($token != false){
93
    if($i == $numOfNameTokens){
94
      $out .= '</span> <span class="authors">';
95
      $noSpace = true;
96
    }
97
    $out .= ($noSpace?'':' ').$token;
98
    $noSpace = false;
99
    $token = strtok(" \n\t");
100
    $i++;
101
  }
102
  return $out.'</span>';
103
}
104

    
105
/**
106
 * Converts an array of TagedText items into a sequence of corresponding html tags whereas
107
 * each item will provided with a class attribute which set to the key of the TaggedText item.
108
 *
109
 * @param array $taggedtxt
110
 * @param String $tag
111
 * @param String $glue the string by which the chained text tokens are concatenated together.
112
 *       Default is a blank character
113
 * @return String of HTML
114
 */
115
function theme_cdm_taggedtext2html(array &$taggedtxt, $tag = 'span', $glue = ' ', $skiptags = array()){
116
  $out = '';
117
  $i = 0;
118
  foreach($taggedtxt as $tt){
119
    if(!in_array($tt->type, $skiptags) && strlen($tt->text) > 0){
120
      $out .= (strlen($out) > 0 && ++$i < count($taggedtxt)? $glue : '').'<'.$tag.' class="'.$tt->type.'">'.t($tt->text).'</'.$tag.'>';
121
    }
122
  }
123
  return $out;
124
}
125

    
126
/**
127
 * Almost any cdmObject may be annotated. Therefore we provide a generic way to display
128
 * as well as create or update annotations.
129
 *
130
 * TODO it should be configurable which objects can be annotated as this might differ in dataportals
131
 *
132
 */
133
function theme_cdm_annotation($cdmBase){
134
  if(!$cdmBase->uuid){
135
    return;
136
  }else{
137

    
138
    drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/cdm_annotations.js');
139
    drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/jquery.form.js');
140

    
141
    $annotatableUuid = $cdmBase->uuid;
142
    //FIXME annotations only available as property of e.g. taxon, name, ...
143
    $annotationUrl = cdm_compose_url(CDM_WS_ANNOTATIONS, array($annotatableUuid));
144

    
145
    $annotationProxyUrl = url('cdm_api/proxy/'. urlencode($annotationUrl).'/cdm_annotation_content');
146

    
147
    $out = ' <span class="annotation">';
148
    $out .= '<span class="annotation_toggle" rel="'.$annotationProxyUrl.'">+</span>';
149
     
150

    
151
    $out .= '<div class="annotation_box"></div>';
152
    $out .= '</span>';
153

    
154
    return $out;
155

    
156
  }
157
}
158

    
159
function theme_cdm_annotation_content($AnnotationTO){
160
  
161
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/cdm_annotations.js');
162
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/jquery.form.js');
163

    
164
  $out .= theme('cdm_list_of_annotations', $AnnotationTO->annotationElements);
165

    
166
  $annotationUrl = cdm_compose_url(CDM_WS_ANNOTATIONS, array($AnnotationTO->uuid));
167
  $annotationProxyUrl = url('cdm_api/proxy/'. urlencode($annotationUrl).'/cdm_annotation_post');
168

    
169
  // TODO users have to be authenticated to the dataportal to be able to write annotations
170
  $out .= '
171
  			<div class="annotation_create">
172
  				<form action="'.$annotationProxyUrl.'" method="POST">
173
  					<textarea name="annotation"></textarea>
174
  					<input type="hidden" name="commentator" value="">
175
  					<input type="submit" value="'.t('Save annotation').'" />
176
  				</form>
177
 			</div>
178
	';
179

    
180
  return $out;
181
}
182

    
183
function theme_cdm_list_of_annotations($annotationElements){
184

    
185
  $out = '<ul class="annotation_list">';
186

    
187
  foreach ($annotationElements as $key => $row){
188
    $created[$key] = $row;
189
  }
190
  array_multisort($created, SORT_ASC, $annotationElements);
191

    
192
  foreach ($annotationElements as $annotation){
193
    $out .= '<li>' . $annotation->text . '</li>';
194
  }
195

    
196
  $out .= '</ul>';
197

    
198
  return $out;
199

    
200
}
201

    
202
function theme_cdm_media($descriptionElement, $mimeTypePreference){
203
  $out = "";
204

    
205
  _add_js_thickbox();
206

    
207
  $uuid = $descriptionElement->uuid;
208
  $feature = $descriptionElement->feature;
209
  $medias = $descriptionElement->media;
210

    
211
  foreach($medias as $media){
212
    $prefRepresentations = cdm_preferred_media_representations($media, $mimeTypePreference, 300, 400);
213
    $mediaRepresentation = array_shift($prefRepresentations);
214
    if($mediaRepresentation) {
215

    
216
      $contentTypeDirectory = substr($mediaRepresentation->mimeType, 0, stripos($mediaRepresentation->mimeType, '/'));
217

    
218
      $out .= theme('cdm_media_mime_' . $contentTypeDirectory,  $mediaRepresentation, $feature);
219

    
220
      //			$attributes = array('class'=>'thickbox', 'rel'=>'descriptionElement-'.$uuid, 'title'=>$feature->term);
221
      //		    for($i = 0; $part = $mediaRepresentation->representationParts[$i]; $i++){
222
      //		    	if($i == 0){
223
      //		    	    $image_url = drupal_get_path('module', 'cdm_dataportal').'/images/'.$feature->term.'-media.png';
224
      //		    	    $media = '<img src="'.$image_url.'" height="14px" alt="'.$feature->term.'" />';
225
      //		    	    $out .= l($media, $part->uri, $attributes, NULL, NULL, TRUE, TRUE);
226
      //		    	} else {
227
      //		    		$out .= l('', $part->uri, $attributes, NULL, NULL, TRUE);
228
      //		    	}
229
      //		  	}
230
    } else {
231
      // no media available, so display just the type term
232
      $out .=  $feature->representation_L10n;
233
    }
234
  }
235
  return $out;
236

    
237
}
238

    
239
function theme_cdm_mediaTypeTerm($feature){
240
  $icon_url = drupal_get_path('module', 'cdm_dataportal').'/images/'.$feature->representation_L10n.'-media.png';
241
  return '<img src="'.$icon_url.'" height="14px" alt="'.$feature->representation_L10n.'" />';
242
}
243

    
244
function theme_cdm_media_mime_application($mediaRepresentation, $feature){
245

    
246
  foreach($mediaRepresentation->parts as $part){
247
    $attributes = array('title'=>$feature->representation_L10n, 'target'=>'_blank');
248
    $out .= l(theme('cdm_mediaTypeTerm', $feature), $part->uri, $attributes, NULL, NULL, TRUE, TRUE);
249
  }
250
  return $out;
251
}
252

    
253
function theme_cdm_media_mime_image($mediaRepresentation, $feature){
254
  $out = '';
255
  $attributes = array('class'=>'thickbox', 'rel'=>'representation-'.$representation->uuid, 'title'=>$feature->representation_L10n);
256
  for($i = 0; $part = $representation->representationParts[$i]; $i++){
257
    if($i == 0){
258
       
259
      $out .= l(theme('cdm_mediaTypeTerm', $feature), $part->uri, $attributes, NULL, NULL, TRUE, TRUE);
260
    } else {
261
    		$out .= l('', $part->uri, $attributes, NULL, NULL, TRUE);
262
    }
263
  }
264
  return $out;
265
}
266

    
267
function theme_cdm_media_mime_text($representation, $feature){
268

    
269
  foreach($representation->parts as $part){
270
    $attributes = array('title'=>$feature->representation_L10n . t(' link will open in a new window'), 'target'=>'_blank');
271
    $out .= l(theme('cdm_mediaTypeTerm', $feature), $part->uri, $attributes, NULL, NULL, TRUE, TRUE);
272
  }
273
  return $out;
274
}
275

    
276

    
277
function theme_cdm_media_caption($media, $elements = array('title', 'description', 'file', 'filename'), $fileUri = null){
278
  $out = '<div class="media_caption">';
279
  if(isset($elements['title']) && $media->title_L10n){
280
    $out .= '<span class="title">'.$media->title_L10n.'</span>';
281
  }
282
  if(isset($elements['description']) && $media->description_L10n){
283
    $out .= '<span class="description">'.$media->description_L10n.'</span>';
284
  }
285
  if(isset($elements['file'])){
286
    $out .= '<span class="file">'.$media->title_L10n.'</span>';
287
  }
288
  if(isset($elements['filename']) && $fileUri){
289
    $filename = substr($fileUri, strrpos($fileUri, "/")+1);
290
    $out .= '<span class="filename">'.$filename.'</span>';
291
  }
292
  $out .= '</div>';
293
  return $out;
294
}
295

    
296
/**
297
 */
298
function theme_cdm_taxon_list_thumbnails($taxon){
299
      
300
    $gallery_name = $taxon->uuid;
301
    
302
    $showCaption = variable_get('cdm_dataportal_findtaxa_show_thumbnail_captions', 1);
303
    $prefMimeTypeRegex = 'image:.*';
304
    $prefMediaQuality = '*';
305
    $cols = variable_get('cdm_dataportal_findtaxa_media_cols', 3);
306
    $maxRows = variable_get('cdm_dataportal_findtaxa_media_maxRows', 1);
307
    $maxExtend = variable_get('cdm_dataportal_findtaxa_media_maxextend', 120);
308
    
309
    if($showCaption){
310
      $captionElements = array('title', '#uri'=>t('open Image'));
311
    }
312
    
313
    $galleryLinkUri = path_to_taxon($taxon->uuid).'/images';
314
    $mediaList = cdm_ws_get(CDM_WS_TAXON_MEDIA, array($taxon->uuid, $prefMimeTypeRegex, $prefMediaQuality));
315
    $out .= theme('cdm_media_gallerie', $mediaList, $gallery_name ,$maxExtend, $cols, $maxRows, $captionElements, 'LIGHTBOX', null, $galleryLinkUri);
316

    
317
    return $out;
318
}
319

    
320

    
321
/**
322
 * @param $mediaList an array of Media entities
323
 * @param $maxExtend
324
 * @param $cols
325
 * @param $maxRows
326
 * @param $captionElements an array possible values are like in the following example: array('title', 'description', 'file', 'filename'), to add a link to the caption: array('title', '#uri'=>t('open Image'));
327
 * @param $mediaLinkType valid values: 
328
 *      "NONE": do not link the images, 
329
 *      "LIGHTBOX": open the link in a light box,
330
 *      "NORMAL": link to the image page or to the $alternativeMediaUri if it is defined
331
 * @param $alternativeMediaUri an array of alternative URIs to link the images wich will overwrite the URIs of the media parts. 
332
 *     The order of URI in this array must correspond with the order of images in $mediaList
333
 * @param $moreLink an URI to link the the hint on more images to; if null no link is created
334
 * @return unknown_type
335
 */
336
function theme_cdm_media_gallerie($mediaList, $galleryName, $maxExtend = 150, $cols = 4, $maxRows = false, $captionElements = array('title'),
337
    $mediaLinkType = 'LIGHTBOX', $alternativeMediaUri = null, $galleryLinkUri = null ){
338
      
339
  //TODO correctly handle multiple media representation parts
340
  
341
  // prevent from errors
342
  if(!isset($mediaList[0])){
343
    return;
344
  }
345
  
346
  $galleryID = "media_gallery_".$galleryName;
347
  
348
  // prepare media links
349
  $doLink = false;
350
  $linkAttributes = null;
351
  if($mediaLinkType != 'NONE'){
352
    $doLink = true;    
353
  }
354
  if($mediaLinkType == 'LIGHTBOX'){
355
    $doLink = true;
356
    //_add_js_thickbox();
357
    //$linkAttributes = array("class"=>"thickbox", "rel"=>"media_gallerie".$galleryName);
358
    _add_js_lightbox($galleryID);
359
    $linkAttributes = array("class"=>"lightbox");
360
  }
361
  
362
  // render the media gallery grid 
363
  $out = '<table id="'.$galleryID.'" class="media_gallery">';
364
    $out .= '<colgroup>';
365
    for($c = 0; $c < $cols; $c++){
366
      $out .= '<col width="'.(100 / $cols).'%">';
367
    }
368
    $out .= '</colgroup>';
369
    
370
  $mediaIndex = 0;
371
  for($r = 0; ($r < $maxRows || !$maxRows) && count($mediaList) > 0; $r++){
372
    $captionParts = array();
373
    $out .= '<tr>';  
374
    for($c = 0; $c < $cols; $c++){
375
      $media = array_shift($mediaList);
376
      if(isset($media->representations[0]->parts[0])){
377
        $contentTypeDirectory = substr($media->representations[0]->mimeType, 0, stripos($media->representations[0]->mimeType, '/'));
378
        $mediaIndex++;
379
        $mediaPartHtml = theme('cdm_media_gallerie_'.$contentTypeDirectory, $media->representations[0]->parts[0], $maxExtend, TRUE);
380
        
381
        // --- compose Media Link
382
        $mediaLinkUri = false;
383
        if($alternativeMediaUri){
384
          if(isset($alternativeMediaUri[$mediaIndex])){
385
            $mediaLinkUri = $alternativeMediaUri[$mediaIndex];
386
          }
387
          if(is_string($alternativeMediaUri)){
388
            $mediaLinkUri = $alternativeMediaUri;
389
          }
390
        } else {
391
          $mediaLinkUri = $media->representations[0]->parts[0]->uri;
392
        }
393
        $linkAttributes['title'] = ($media->title_L10n ? $media->title_L10n : '')
394
            .($media->title_L10n && $media->description_L10n ? ' - ' : '')
395
            .($media->description_L10n ? $media->description_L10n : '');
396
        
397
        // --- assemble captions
398
        if(isset($media->representations[0]->parts[0]->uri)){
399
          $fileUri = $media->representations[0]->parts[0]->uri;
400
        }
401
        $captionPartHtml = theme('cdm_media_caption', $media, $captionElements, $fileUri);
402
        if(isset($captionElements['#uri'])){
403
          $captionPartHtml .= l($captionElements['#uri'], path_to_media($media->uuid), null, null, null, FALSE, TRUE);
404
        }
405
        $captionParts[] = $captionPartHtml;
406
        
407
        // --- surround imagePart with link
408
        if($doLink){
409
          $mediaPartHtml = l($mediaPartHtml, $mediaLinkUri, $linkAttributes, null, null, FALSE, TRUE);
410
        }
411
        
412
      } else {
413
        $mediaPartHtml = '';
414
        $captionParts[] = '';
415
      }
416
      $out .= '<td>'.$mediaPartHtml.'</td>';
417
    }
418
    $out .= '</tr>';
419
    if(isset($captionElements[0])){
420
      $out .= '<tr>';
421
      // add caption row
422
      foreach($captionParts as $captionPartHtml){
423
        $out .= '<td>'.$captionPartHtml.'</td>';
424
      }
425
      $out .= '</tr>';  
426
    }
427
  }
428
 if($galleryLinkUri){
429
    if(count($mediaList) > 0){
430
       $moreHtml = count($mediaList).' '.t('more in gallery');
431
    } else {
432
      $moreHtml = t('open gallery');
433
    }
434
    $moreHtml = l($moreHtml, $galleryLinkUri);
435
    $out .= '<tr><td colspan="'.$cols.'">'.$moreHtml.'</td></tr>';
436
  }
437
  $out .= '</table>';
438
  return $out;
439
}
440

    
441
function theme_cdm_media_gallerie_image($mediaRepresentationPart, $maxExtend, $addPassePartout = FALSE, $attributes = null){
442
  //TODO merge with theme_cdm_media_mime_image?
443
  
444
  if(isset($mediaRepresentationPart)){
445
    $h = $mediaRepresentationPart->height;
446
    $w = $mediaRepresentationPart->width;
447
    $margins = '0 0 0 0';
448
    $ratio = $w / $h;
449
    if($ratio > 1){
450
      $displayHeight = round($maxExtend / $ratio);
451
      $displayWidth = $maxExtend;
452
      $m = round(($maxExtend - $displayHeight) / 2);
453
      $margins = 'margin:'.$m.'px 0 '.$m.'px 0;';
454
    } else {
455
      $displayHeight = $maxExtend;
456
      $displayWidth = round($maxExtend * $ratio);
457
      $m = round(($maxExtend - $displayWidth) / 2);
458
      $margins = 'margin:0 '.$m.'px 0 '.$m.'px;';
459
    }
460
    
461
    // turn attributes array into string
462
    $attrStr = ' ';
463
    //$attributes['title'] = 'h:'.$h.', w:'.$w.',ratio:'.$ratio;
464
    if(is_array($attributes)){
465
      foreach($attributes as $name=>$value){
466
        $attrStr .= $name.'="'.$value.'" ';
467
      }
468
    }
469
    
470
    //return  '<img src="'."http://wp5.e-taxonomy.eu/dataportal/cichorieae/media/photos/Lapsana_communis_A_01.jpg".'" width="'.$maxExtend.'" height="'.$maxExtend.'" />';
471
    if($addPassePartout){
472
      $out .= '<div class="image-passe-partout" style="width:'.$maxExtend.'px; height:'.$maxExtend.'px;">';
473
    } else {
474
      // do not add margins if no pass partout is shown
475
      $margins = '';
476
    }
477
    $out .= '<img src="'.$mediaRepresentationPart->uri.'" width="'.$displayWidth.'" height="'.$displayHeight.'" style="'.$margins.'"'.$attrStr.' /></div>';
478
    return $out;
479
  }
480

    
481
}
482

    
483
function theme_cdm_openlayers_image($mediaRepresentationPart, $maxExtend){
484
  
485
  // see http://trac.openlayers.org/wiki/UsingCustomTiles#UsingTilesWithoutaProjection
486
  // and http://trac.openlayers.org/wiki/SettingZoomLevels
487
  
488
  $w = $mediaRepresentationPart->width;
489
  $h = $mediaRepresentationPart->height;
490
  
491
  // calculate  maxResolution (default is 360 deg / 256 px) and the bounds
492
  if($w > $h){
493
    $lat = 90;
494
    $lon = 90 * ($h / $w);
495
    $maxRes = $w / $maxExtend;
496
  } else {
497
    $lat = 90 * ($w / $h);
498
    $lon = 90;
499
    $maxRes =  $h / $maxExtend ;
500
  }
501
  
502
  $maxRes *= 1;
503
  drupal_add_js('
504
 var map;
505

    
506
 var imageLayerOptions={
507
     maxResolution: '.$maxRes.',
508
     maxExtent: new OpenLayers.Bounds(0, 0, '.$w.', '.$h.')
509
  };
510
  var mapOptions={
511
     restrictedExtent:  new OpenLayers.Bounds(0, 0, '.$w.', '.$h.')
512
  };
513
 
514
 var graphic = new OpenLayers.Layer.Image(
515
          \'Image Title\',
516
          \''.$mediaRepresentationPart->uri.'\',
517
          new OpenLayers.Bounds(0, 0, '.$w.', '.$h.'),
518
          new OpenLayers.Size('.$w.', '.$h.'),
519
          imageLayerOptions
520
          );
521
  
522
 function init() {
523
   map = new OpenLayers.Map(\'openlayers_image\', mapOptions);
524
   map.addLayers([graphic]);
525
   map.setCenter(new OpenLayers.LonLat(0, 0), 1);
526
   map.zoomToMaxExtent();
527
 }
528
 
529
$(document).ready(function(){
530
  init();
531

    
532
});'
533
      , 'inline');
534
      $out = '<div id="openlayers_image" class="image_viewer" style="width: '.$maxExtend.'px; height:'.($maxExtend).'px"></div>';
535
      return $out;
536
  
537
}
538

    
539
function theme_cdm_media_page($media, $mediarepresentation_uuid = false, $partId = false){
540
  $out = '';
541

    
542

    
543
  // determine which reprresentation and which part to show
544
  $representationIdx = 0;
545
  if($mediarepresentation_uuid){
546
    $i = 0;
547
    foreach($media->representations as $representation) {
548
      if($representation->uuid == $mediarepresentation_uuid){  
549
        $representationIdx = $i;
550
      }
551
      $i++;
552
    }
553
  } else {
554
    $mediarepresentation_uuid = $media->representations[0]->uuid;
555
  }
556

    
557
  $partIdx  = 0;
558
  if(!is_numeric($partId)){
559
    // assuming it is an uuid
560
    $i = 0;
561
    foreach($media->representations[$representationIdx]->parts as $part) {
562
      if($part->uuid == $partId){  
563
        $partIdx = $i;
564
      }
565
      $i++;
566
    }
567
  } else {
568
   // assuming it is an index
569
    $partIdx = $partId;
570
  }
571
  
572
  
573
  $title = $media->title_L10n;
574
  
575
  $imageMaxExtend = variable_get('image-page-maxextend', 400);
576
  
577
  if(!$title){
578
    $title = 'Media '.$media->uuid.'';
579
  }
580
  
581
  drupal_set_title($title);
582

    
583
  
584
  $out .= '<div class="media">';
585
  
586
  $out .= '<div class="viewer">';
587
  //$out .= theme('cdm_media_gallerie_image', $representation->parts[$partIdx], $imageMaxExtend);
588
  $out .= theme('cdm_openlayers_image', $media->representations[$representationIdx]->parts[$partIdx], $imageMaxExtend);
589
  $out .= '</div>';
590
  
591
  // general media metadata
592
  $out .= '<h4 class="title">'.$media->title_L10n.'</h4>';
593
  $out .= '<div class="description">'.$media->description_L10n.'</div>';
594
  $out .= '<div class="artist">'.$media->artist->titleCache.'</div>';
595
  $out .= '<ul class="rights">';
596
  foreach($media->rights as $right){  
597
    $out .= '<li>'.theme('cdm_right', $right).'</li>';
598
  }
599
  $out .= '</ul>';
600

    
601
  //tabs for the different representations
602
  //ul.secondary 
603
  $out .= '<ul class="primary">';
604
  foreach($media->representations as $representation){
605
    $out .= '<li>'.l($media->representations[$representationIdx]->mimeType, path_to_media($media->uuid, $mediarepresentation_uuid, $partIdx)).'</li>';
606
  }
607
  $out .= '</ul>';
608

    
609
  // representation(-part) specific metadata
610
  $thumbnailMaxExtend = 100;
611
  $out .= '<table>';
612
  //$out .= '<tr><th colspan="3">'.t('MimeType').': '.$media->representations[$representationIdx]->mimeType.'</th></tr>';
613
  $i = 0;
614
  foreach($media->representations[$representationIdx]->parts as $part){
615
    $out .= '<tr><th>'.t('Part').' '.($i + 1).'</th><td>';
616
    switch($part->class){
617
      case 'ImageFile': $out .= $part->width.' x '.$part->height.' - '.$part->size.'k'; break;
618
      case 'AudioFile': 
619
      case 'MovieFile': $out .= t('Duration').': '.$part->duration.'s - '.$part->size.'k'; break;
620
      default: $out .= $part->size.'k';
621
    }   
622
    $out .= '</td><td><a href="'.url(path_to_media($media->uuid, $mediarepresentation_uuid, $i)).'">'.theme('cdm_media_gallerie_image', $part, $thumbnailMaxExtend, true);'</a></td><tr>';
623
    $i++;
624
  }
625
  $out .= '</table>';
626
  $out .= '</div>';
627
  
628
  return $out;
629
}
630

    
631
function theme_cdm_right($right){
632
  $out = '<div class="right">';
633
  $out .= '<span class="type">'.$right->type->representation_L10n.' </span>';
634
  if($right->uri){
635
    $out .= '<a href="'.$right->uri.'>'.$right->abbreviatedText.'</a>';
636
  } else {
637
    $out .= $right->abbreviatedText;
638
  }
639
  $out .= '<span class="agent"> '.$right->abbreviatedText.'</span>';
640
  $out .= '</div>';
641
  return $out;
642
  //$right->type->representation_L10n
643
}
644

    
645
/**
646
 * TODO
647
 * Quick-and-dirty solution to show distribution service to exemplar groups
648
 *
649
 * @param unknown_type $featureTo
650
 * @return unknown
651
 */
652
function theme_cdm_descriptionElements_distribution($taxon){
653
  
654

    
655
  $server = variable_get('cdm_dataportal_geoservice_access_point', false);
656

    
657
  if(!server){
658
    return "<p>No geoservice specified</p>";
659
  }else{
660
    $map_data_parameters = cdm_ws_get(CDM_WS_GEOSERVICE_DISTRIBUTIONMAP, $taxon->uuid);
661

    
662
    $display_width = variable_get('cdm_dataportal_geoservice_display_width', false);
663
    $bounding_box = variable_get('cdm_dataportal_geoservice_bounding_box', false);
664
    $labels_on = variable_get('cdm_dataportal_geoservice_labels_on', 0);
665

    
666
    $query_string = ($display_width ? '&ms=' . $display_width: '')
667
      . ($bounding_box ? '&bbox=' .  $bounding_box : '')
668
      . ($labels_on ? '&labels=' .  $labels_on : '');
669
      
670
      $query_string .= '&img=false&legend=1&mlp=3';
671
      
672
    if(variable_get('cdm_dataportal_map_openlayers', 1)){
673
      // embed into openlayers viewer
674
      //$server = 'http://edit.csic.es/v1/areas_sld.php';
675
      $server = 'http://edit.csic.es/v1/test.php';
676
      $map_tdwg_Uri = url($server. '?' .$map_data_parameters->String, $query_string);
677
      
678
      //#print($map_tdwg_Uri.'<br>');
679
      
680
      //$map_tdwg_Uri ='http://edit.csic.es/v1/areas3_ol.php?l=earth&ad=tdwg4:c:UGAOO,SAROO,NZSOO,SUDOO,SPAAN,BGMBE,SICSI,TANOO,GEROO,SPASP,KENOO,SICMA,CLCBI,YUGMA,GRCOO,ROMOO,NZNOO,CLCMA,YUGSL,CLCLA,ALGOO,SWIOO,CLCSA,MDROO,HUNOO,ETHOO,BGMLU,COROO,BALOO,POROO,BALOO|e:CZESK,GRBOO|g:AUTAU|b:LBSLB,TUEOO|d:IREIR,AUTLI,POLOO,IRENI|f:NETOO,YUGCR|a:TUEOO,BGMBE,LBSLB||tdwg3:c:BGM,MOR,SPA,SIC,ITA,MOR,SPA,FRA|a:YUG,AUT&as=a:8dd3c7,,1|b:fdb462,,1|c:4daf4a,,1|d:ffff33,,1|e:bebada,,1|f:ff7f00,,1|g:377eb8,,1&&ms=610&bbox=-180,-90,180,90';
681
      //$tdwg_sldFile = cdm_http_request($map_tdwg_Uri);
682
      
683
      // get the respone from the map service
684
      $responseObj = cdm_ws_get($map_tdwg_Uri, null, null, "GET", TRUE);
685
      $responseObj = $responseObj[0];
686
      
687
      // get the sld files from the response object
688
      if(isset($responseObj->layers)){
689
        $layerSlds = $responseObj->layers;
690
        foreach($layerSlds as $layer){
691
          $tdwg_sldUris[$layer->tdwg] = "http://edit.csic.es/v1/sld/".$layer->sld;
692
          //#print($tdwg_sldUris[$layer->tdwg].'<br>');
693
        }
694
      }
695
      // get the bbox from the response object
696
      $zoomto_bbox = ($bounding_box ? $bounding_box : ($responseObj->bbox ? $responseObj->bbox :'-180, -90, 180, 90') );
697
      
698
      $add_tdwg1 = (isset($tdwg_sldUris['tdwg1']) ? "
699
          tdwg_1.params.SLD = '".$tdwg_sldUris['tdwg1']."';
700
          map.addLayers([tdwg_1]);" : '');
701
      $add_tdwg2 = (isset($tdwg_sldUris['tdwg2']) ? "
702
          tdwg_2.params.SLD = '".$tdwg_sldUris['tdwg2']."';
703
          map.addLayers([tdwg_2]);" : '');
704
      $add_tdwg3 = (isset($tdwg_sldUris['tdwg3']) ? "
705
          tdwg_3.params.SLD = '".$tdwg_sldUris['tdwg3']."';
706
          map.addLayers([tdwg_3]);" : '');
707
      $add_tdwg4 = (isset($tdwg_sldUris['tdwg4']) ? "
708
          tdwg_4.params.SLD = '".$tdwg_sldUris['tdwg4']."';
709
          map.addLayers([tdwg_4]);" : '');
710
      
711
//      $googleMapsApiKey_localhost = 'ABQIAAAAFho6eHAcUOTHLmH9IYHAeBRi_j0U6kJrkFvY4-OX2XYmEAa76BTsyMmEq-tn6nFNtD2UdEGvfhvoCQ';
712
//      drupal_set_html_head(' <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key='.$googleMapsApiKey_localhost.'"></script>');
713

    
714
      /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
715
       * OpenLayers.js must be loaded BEFORE jQuery. 
716
       * If jQuery loaded before $.something will fail in IE8.
717
       * Therefore we add OpenLayers.js it in the page.tpl.php
718
       */
719
      //drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/OpenLayers/OpenLayers.js', 'core', 'header');
720
      drupal_add_js('
721
 var map;
722
 
723
 var layerOptions = {
724
     maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
725
     isBaseLayer: false,
726
     displayInLayerSwitcher: false
727
  };
728
 
729
 var tdwg_1 = new OpenLayers.Layer.WMS.Untiled( 
730
    "tdwg level 1", 
731
    "http://edit.csic.es/geoserver/wms",
732
    {layers:"topp:tdwg_level_1",transparent:"true", format:"image/png"},
733
    layerOptions
734
  );
735
  
736
 var tdwg_2 = new OpenLayers.Layer.WMS.Untiled( 
737
    "tdwg level 2", 
738
    "http://edit.csic.es/geoserver/wms",
739
    {layers:"topp:tdwg_level_2",transparent:"true", format:"image/png"},
740
    layerOptions
741
  );
742
  
743
 var tdwg_3 = new OpenLayers.Layer.WMS.Untiled( 
744
    "tdwg level 3", 
745
    "http://edit.csic.es/geoserver/wms",
746
    {layers:"topp:tdwg_level_3", transparent:"true", format:"image/png"},
747
    layerOptions
748
  );
749
  
750
  var tdwg_4 = new OpenLayers.Layer.WMS.Untiled( 
751
    "tdwg level 4", 
752
    "http://edit.csic.es/geoserver/wms",
753
    {layers:"topp:tdwg_level_4",transparent:"true", format:"image/png"},
754
    layerOptions
755
  );
756
  
757
 // make baselayer
758
 layerOptions[\'isBaseLayer\'] = true; 
759
 
760
 var ol_wms = new OpenLayers.Layer.WMS( 
761
    "OpenLayers WMS",
762
    "http://labs.metacarta.com/wms/vmap0",
763
    {layers: \'basic\'}, 
764
    layerOptions
765
  );
766
  
767
  
768
  // ------------------------------
769
  
770
  
771
 function init() {
772
 
773
   var mapOptions={
774
// controls break openlayers in IE8 !!!!!!!!!!!!!!
775
//     controls: 
776
//       [
777
//         new OpenLayers.Control.LayerSwitcher({\'ascending\':false}),
778
//         new OpenLayers.Control.PanZoomBar(),
779
//         //new OpenLayers.Control.PanZoom(),
780
//         new OpenLayers.Control.MouseToolbar(),
781
//         //new OpenLayers.Control.MousePosition(),
782
//         //new OpenLayers.Control.KeyboardDefaults()
783
//       ],
784
       maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
785
       maxResolution: '.(360 / $display_width).',
786
       restrictedExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
787
       projection: new OpenLayers.Projection("EPSG:4326")
788
    };
789
    
790
   
791
   map = new OpenLayers.Map(\'openlayers_map\', mapOptions);
792
   map.addLayers([ol_wms]);
793
   '.$add_tdwg1.'
794
   '.$add_tdwg2.'
795
   '.$add_tdwg3.'
796
   '.$add_tdwg4.'
797
   map.zoomToExtent(new OpenLayers.Bounds('.$zoomto_bbox.'), true);
798
 }
799
 
800
$(document).ready(function(){
801
  init();
802

    
803
});'
804
      , 'inline');
805
      $out = '<div id="openlayers_map" class="smallmap" style="width: '.$display_width.'px; height:'.($display_width / 2).'px"></div>';
806
      
807
    } else {
808
      // simple image
809
      $mapUri = url($server. '?' .$map_data_parameters->String, $query_string);
810
      $out .= '<img class="distribution_map" src="'.$mapUri.'" alt="Distribution Map" />'; 
811
    }
812
    
813
    // add a simple legend
814
    if(variable_get('cdm_dataportal_geoservice_legend_on', TRUE)){
815
      $legenddata = array(
816
        'native' => "4daf4a",
817
        'native_doubtfully_native' => "377eb8",
818
        'cultivated' => "984ea3",
819
        'introduced' => "ff7f00",
820
        'introduced adventitious' => "ffff33",
821
        'introduced cultivated' => "a65628",
822
        'introduced naturalized' => "f781bf"
823
      );
824
      
825
      $out .= '<div class="distribution_map_legend">';
826
      foreach($legenddata as $term => $color){
827
        $out .= '<img style="width: 3em; height: 1em; background-color: #'.$color.'" src="'.
828
        drupal_get_path('module', 'cdm_dataportal').'/images/clear.gif" />'.t($term).' ';
829
      }
830
      $out .= '</div>';
831
    }
832
    
833
    return $out;
834
  }
835
}
836

    
837
function theme_cdm_taxonName($taxonName, $nameLink = NULL, $refenceLink = NULL, $renderPath = null){
838
  
839
  $renderTemplate = get_nameRenderTemplate($renderPath, $nameLink, $refenceLink);
840
  
841
  $partDefinition = get_partDefinition($taxonName->class);
842
  
843
  // apply defintions to template
844
  foreach($renderTemplate as $part=>$uri){
845
    if(isset($partDefinition[$part])){
846
      $renderTemplate[$part] = $partDefinition[$part];
847
    }
848
    if(is_array($uri)){
849
      $renderTemplate[$part]['#uri'] = $uri['#uri'];
850
    }
851
  }
852
  
853
  if(isset($taxonName->taggedName)){
854
    
855
    $taggedName = $taxonName->taggedName;
856
    // due to a bug in the cdmlib the taggedName alway has a lst empty element, we will remove it:
857
    array_pop($taggedName);
858
    
859
    $lastAuthorElementString = false;
860
    $hasNamePart_with_Authors = isset($renderTemplate['namePart']) && isset($renderTemplate['namePart']['authors']);
861
    $hasNameAuthorPart_with_Authors = isset($renderTemplate['nameAuthorPart']) && isset($renderTemplate['nameAuthorPart']['authors']);
862
    
863
    if(!($hasNamePart_with_Authors || $hasNameAuthorPart_with_Authors)){
864
//      // find author and split off from name 
865
//      // TODO expecting to find the author as the last element
866
//      if($taggedName[count($taggedName)- 1]->type == 'authors'){
867
//        $authorTeam = $taggedName[count($taggedName)- 1]->text;
868
//        unset($taggedName[count($taggedName)- 1]);
869
//      }
870

    
871
        // remove all authors
872
        $taggedNameNew = array();
873
        foreach($taggedName as $element){
874
          if($element->type != 'authors'){
875
            $taggedNameNew[] = $element;
876
          } else {
877
              $lastAuthorElementString = $element->text;
878
          }
879
       }
880
       $taggedName = $taggedNameNew;
881
       
882
    }
883
    $name = '<span class="'.$taxonName->class.'">'.theme('cdm_taggedtext2html', $taggedName).'</span>';
884
  } else {  
885
    $name = '<span class="'.$taxonName->class.'_titleCache">'.$taxonName->titleCache.'</span>';
886
  }
887
  
888
  // fill name into $renderTemplate
889
  array_setr('name', $name, $renderTemplate);
890
 
891
//  // fill with authorTeam
892
//  if($authorTeam){
893
//    $authorTeamHtml = ' <span class="authorTeam">'.$authorTeam.'</span>';
894
//    array_setr('authorTeam', $authorTeamHtml, $renderTemplate);
895
//  }
896

    
897
  
898
  // fill with reference
899
  if(isset($renderTemplate['referencePart'])){
900
    
901
    // [Eckhard]:"Komma nach dem Taxonnamen ist grunsätzlich falsch, 
902
    // Komma nach dem Autornamen ist überall dort falsch, wo ein "in" folgt."
903
    if(isset($renderTemplate['referencePart']['reference']) && $taxonName->nomenclaturalReference){
904
      $microreference = null;
905
      if(isset($renderTemplate['referencePart']['microreference'])){
906
        $microreference = $taxonName->nomenclaturalMicroReference;
907
      }
908
      $citation = cdm_ws_get(CDM_WS_NOMENCLATURAL_REFERENCE_CITATION, array($taxonName->nomenclaturalReference->uuid, $microreference));
909
      $citation = $citation->String;
910
      // find preceding element of the refrence
911
      $precedingKey = get_preceding_contentElementKey('reference', $renderTemplate);
912
      if(str_beginsWith($citation, ", in")){
913
        $citation = substr($citation, 2);
914
        $separator = ' ';
915
      } else if(!str_beginsWith($citation, "in") && $precedingKey == 'authors'){
916
        $separator = ', ';
917
      } else {
918
        $separator = ' ';
919
      }
920
      
921
      $referenceArray['#separator'] = $separator;
922
      $referenceArray['#html'] = '<span class="reference">'.$citation.'</span>';      
923
      array_setr('reference', $referenceArray, $renderTemplate);
924
    }
925
    
926
    // if authors have been removed from the name part the last named authorteam 
927
    // should be added to the reference citation, otherwise, keep the separator 
928
    // out of the reference 
929
    if(isset($renderTemplate['referencePart']['authors']) && $lastAuthorElementString){
930
      // if the nomenclaturalReference cintation is not included in the reference part but diplay of the microreference
931
      // is whanted append the microreference to the authorTeam
932
      if(!isset($renderTemplate['referencePart']['reference']) && isset($renderTemplate['referencePart']['microreference'])){
933
          $separator = ": ";
934
          $citation = $taxonName->nomenclaturalMicroReference;
935
      }
936
      $referenceArray['#html'] = ' <span class="reference">'.$lastAuthorElementString.$separator.$citation.'</span>';
937
      array_setr('authors', $referenceArray, $renderTemplate);
938
    }
939
    
940
  }
941
  
942
  // fill with status
943
  if(array_setr('status', true, $renderTemplate)){
944
    if(isset($taxon->name->status[0])){
945
      foreach($taxon->name->status as $status){
946
        $statusHtml .= ', '.$status->type->representation_L10n;
947
      }
948
    }
949
    array_setr('status', ' <span class="nomenclatural_status">'.$statusHtml.'</span>', $renderTemplate);
950
  }
951

    
952
  // fill with protologues etc...
953
  if(array_setr('description', true, $renderTemplate)){
954
    $descriptions = cdm_ws_get(CDM_WS_NAME_DESCRIPTIONS, $taxonName->uuid);
955
    foreach($descriptions as $description){
956
        if(!empty($description)){
957
          foreach($description->elements as $description_element){
958
            $descriptionHtml .= theme("cdm_media", $description_element, array('application/pdf', 'image/png', 'image/jpeg', 'image/gif', 'text/html'));
959
          }
960
        }
961
    }
962
    array_setr('description', $descriptionHtml, $renderTemplate);
963
  }  
964
  
965
  // render
966
  $out = '';
967
  foreach($renderTemplate as $partName=>$part){
968
    $separator = '';
969
    $partHtml = '';
970
    $uri = false;
971
    if(!is_array($part)){
972
      continue;
973
    }
974
    if(isset($part['#uri']) && is_string($part['#uri'])){
975
      $uri = $part['#uri'];
976
      unset($part['#uri']);
977
    }
978
    foreach($part as $key=>$content){
979
      $html = '';
980
      if(is_array($content)){
981
        $html = $content['#html'];
982
        $separator = $content['#separator'];
983
      } else if(is_string($content)){
984
        $html = $content;
985
      }
986
      $partHtml .= '<span class="'.$key.'">'.$html.'</span>';
987
    }
988
    if($uri){
989
      $out .= $separator.'<a href="'.$uri.'" class="'.$partName.'">'.$partHtml.'</a>';
990
    } else {
991
      $out .= $separator.$partHtml;
992
    }
993
  }
994
  
995
  return $out;
996
}
997

    
998
/**
999
 * Recursively searches the array for the $key and sets the given value
1000
 * @param $key
1001
 * @param $value  
1002
 * @param $array
1003
 * @return true if the key has been found
1004
 */
1005
function &array_setr($key, $value, array &$array){
1006
  foreach($array as $k=>&$v){
1007
    if($key == $k){
1008
      $v = $value;
1009
      return $array;
1010
    } else if(is_array($v)){
1011
      $innerArray = array_setr($key, $value, $v);
1012
      if($innerArray){
1013
        return $array;
1014
      }
1015
    }
1016
  }
1017
  return null;
1018
}
1019

    
1020
function &get_preceding_contentElement($contentElementKey, array &$renderTemplate){
1021
  $precedingElement = null;
1022
  foreach($renderTemplate as &$part){
1023
    foreach($part as $key=>&$element){
1024
      if($key == $contentElementKey){
1025
        return $precedingElement;
1026
      }
1027
      $precedingElement = $element;
1028
    }
1029
  }
1030
  return null;
1031
}
1032

    
1033
function &get_preceding_contentElementKey($contentElementKey, array &$renderTemplate){
1034
  $precedingKey = null;
1035
  foreach($renderTemplate as &$part){
1036
    foreach($part as $key=>&$element){
1037
      if($key == $contentElementKey){
1038
        return $precedingKey;
1039
      }
1040
      if(!str_beginsWith($key, '#')){
1041
        $precedingKey = $key;
1042
      }
1043
    }
1044
  }
1045
  return null;
1046
}
1047

    
1048

    
1049
function theme_cdm_related_taxon($taxon, $reltype_uuid = '', $displayNomRef = true){
1050

    
1051
  $relsign = '';
1052
  $name_prefix = '';
1053
  $name_postfix = '';
1054
  switch ($reltype_uuid){
1055
    case UUID_HETEROTYPIC_SYNONYM_OF:
1056
    case UUID_SYNONYM_OF:
1057
      $relsign = '=';
1058
      break;
1059
    case UUID_HOMOTYPIC_SYNONYM_OF:
1060
      $relsign = '≡';
1061
      break;
1062
    case UUID_MISAPPLIED_NAME_FOR:
1063
    case UUID_INVALID_DESIGNATION_FOR:
1064
      $relsign = '&ndash;'; // &ndash; &mdash; &minus;
1065
      $name_prefix = '"';
1066
      $name_postfix = '"';
1067
      break;
1068
    default :
1069
      $relsign = '&ndash;';
1070
  }
1071
  
1072
  $renderPath = 'related_taxon';
1073

    
1074
  //$taxonUri = url(path_to_taxon($taxon->uuid));
1075
  if($taxon->name->nomenclaturalReference){
1076
    $referenceUri = url(path_to_reference($taxon->name->nomenclaturalReference->uuid));
1077
  }
1078
  $nameHtml = theme('cdm_taxonName', $taxon->name, $taxonUri, $referenceUri, $renderPath);
1079
  
1080
  $out = '<span class="relation_sign">'.$relsign.'</span>'.$name_prefix . $nameHtml . $name_postfix;
1081
  return $out;
1082

    
1083
}
1084

    
1085
/**
1086
 * will theme form elements of type 'select_secuuid'
1087
 * see $form['cdm_dataportal']['secuuid_widget']
1088
 * @param FormElement $element
1089
 */
1090
function theme_select_secuuid($element) {
1091

    
1092
  $default_uuid = variable_get($element['#varname'], false);
1093

    
1094
  $tree = cdm_taxontree_build_tree(null, false); // get root nodes
1095
  $secUuids = array();
1096
  foreach($tree as $node){
1097
    $secUuids[] = $node->secUuid;
1098
  }
1099
  cdm_api_secref_cache_prefetch($secUuids);
1100

    
1101
  theme('cdm_taxontree_add_scripts');
1102
  drupal_add_js('$(document).ready(function() {$(\'ul.cdm_taxontree\').cdm_taxontree(
1103
  {
1104
    widget:                 true,
1105
    element_name:           \''.$element['#varname'].'\',  //
1106
    multiselect:            '.($element['#multiple']?'true':'false').',         //
1107
  }
1108
  );});', 'inline');
1109

    
1110
  $out  = '<div class="cdm_taxontree_widget">';
1111
  $out .= '<div class="taxontree">'.theme('cdm_taxontree', $tree, NULL, FALSE, 'cdm_taxontree_node_reference').'</div>';
1112
  $out .= $element['#children'].'<div style="clear: both;" /></div>';
1113

    
1114
  return theme(
1115
    'form_element',
1116
  array(
1117
      '#title' => $element['#title'],
1118
      '#description' => $element['#description'],
1119
      '#id' => $element['#id'],
1120
      '#required' => $element['#required'],
1121
      '#error' => $element['#error'],
1122
  ),
1123
  $out
1124
  );
1125
}
1126

    
1127
function theme_cdm_dynabox($label, $content_url, $theme, $enclosingtag = 'li'){
1128
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/cdm_dynabox.js');
1129
  
1130
  $cdm_proxy_url = url('cdm_api/proxy/'.urlencode($content_url)."/$theme");
1131
  $out .= '<li class="dynabox"><span class="label" alt="'.t('Click for accepted taxon').'">'.$label.'</span>';
1132
  $out .= '<ul class="dynabox_content" title="'.$cdm_proxy_url.'"><li><img class="loading" src="'.drupal_get_path('module', 'cdm_dataportal').'/images/loading_circle_grey_16.gif" style="display:none;"></li></ul>';
1133
  return $out;
1134
}
1135

    
1136
function theme_cdm_list_of_taxa($records, $showMedia = false){
1137
  
1138
  $renderPath = 'list_of_taxa';
1139
  
1140
  $showMedia_taxa = variable_get('cdm_dataportal_findtaxa_show_taxon_thumbnails', 1);
1141
  $showMedia_synonyms = variable_get('cdm_dataportal_findtaxa_show_synonym_thumbnails', 0);
1142
  
1143
  // .. well, for sure not as performant as before, but better than nothing.
1144
  $synonym_uuids = array();
1145
  foreach($records as $taxon){
1146
    if($taxon->class != "Taxon"){
1147
      if(!array_key_exists($taxon->uuid, $synonym_uuids)){
1148
        $synonym_uuids[$taxon->uuid] = $taxon->uuid;
1149
      }
1150
    }
1151
  }
1152
  // batch service not jet implemented: 
1153
  // $table_of_accepted = cdm_ws_property(CDM_WS_TAXON_ACCEPTED, join(',', $synonym_uuids));
1154
  // thus ...
1155
  $table_of_accepted = array();
1156
  foreach($synonym_uuids as $synUuid){
1157
    $table_of_accepted[$synUuid] = cdm_ws_get(CDM_WS_TAXON_ACCEPTED, $synUuid);
1158
  }
1159
  
1160
  $out = '<ul class="cdm_names" style="background-image: none;">';
1161
  
1162
  foreach($records as $taxon){
1163
    // its a Taxon
1164
    if($taxon->class == "Taxon"){
1165
      $taxonUri = url(path_to_taxon($taxon->uuid));
1166
      if(isset($taxon->name->nomenclaturalReference)){
1167
        $referenceUri = url(path_to_reference($taxon->name->nomenclaturalReference->uuid));
1168
      }
1169
      $out .= '<li class="Taxon">'.theme('cdm_taxonName', $taxon->name, $taxonUri, $referenceUri, $renderPath);
1170
      if($showMedia_taxa){
1171
          $out .= theme('cdm_taxon_list_thumbnails', $taxon);
1172
      }
1173
      $out .= '</li>';
1174
    } else {
1175
      // its a synonym
1176
      $uuid = $taxon->uuid;
1177
      $acceptedTaxa = $table_of_accepted[$uuid];
1178
      if(count($acceptedTaxa) == 1){
1179
        $acceptedTaxon = $acceptedTaxa[0];
1180
        $taxonUri = uri_to_synonym($taxon->uuid, $acceptedTaxon->uuid, 'synonymy');
1181
        if(isset($acceptedTaxon->name->nomenclaturalReference)){
1182
          $referenceUri = url(path_to_reference($acceptedTaxon->name->nomenclaturalReference->uuid));
1183
        }
1184
        $out .= '<li class="Synonym">'.theme('cdm_taxonName', $taxon->name, $taxonUri, $referenceUri, $renderPath);
1185
        if($showMedia_synonyms){
1186
          $out .= theme('cdm_taxon_list_thumbnails', $acceptedTaxon);
1187
        }
1188
      $out .= '</li>';
1189
      } else {
1190
        //TODO avoid using AHAH in the cdm_dynabox
1191
        //TODO add media
1192
        $out .= theme('cdm_dynabox', theme('cdm_taxonName', $taxon->name, null, null, $renderPath), cdm_compose_url(CDM_WS_TAXON_ACCEPTED, array($taxon->uuid)), 'cdm_list_of_taxa');
1193
      }
1194
    }
1195
  }
1196
  $out .= '</ul>';
1197
  return $out;
1198
}
1199

    
1200

    
1201
function theme_cdm_credits(){
1202
  return null;
1203
  $secRef_array = _cdm_dataportal_currentSecRef_array();
1204
  return '<span class="sec_reference_citation">'.$secRef_array['citation'].'</span>'
1205
  .( $secRef_array['period'] ? ' <span class="year">'.partialToYear($secRef_array['period']).'</span>' : '')
1206
  .( $secRef_array['authorTeam'] ? '<div class="author">'.$secRef_array['authorTeam']['titleCache'].'</div>' : '');
1207
}
1208

    
1209
/**
1210
 * @deprecated ??
1211
 */
1212
function theme_cdm_reference($reference, $linkToReference = FALSE, $style = NULL ){
1213
  
1214
  if($style == "ZoologicalName"){
1215
     $year = partialToYear($reference->datePublished->start);
1216
     $citation = $reference->authorTeam->titleCache.($year ? ', '.$year : '');
1217
  } else {
1218
    $citation = $reference->titleCache;    
1219
  }
1220
  if($linkToReference){
1221
    return l('<span class="reference">'.$citation.'</span>', "/cdm_dataportal/reference/".$reference->uuid, array("class"=>"reference"), NULL, NULL, FALSE ,TRUE);
1222
  } else {
1223
    return '<span class="reference">'.$citation.'</span>';
1224
  } 
1225
}
1226

    
1227
/**
1228
 * Enter description here...
1229
 *
1230
 * @param unknown_type $referenceSTO a referenceSTO or referenceTO instance
1231
 * @param unknown_type $cssClass
1232
 * @param unknown_type $separator
1233
 * @param unknown_type $enclosingTag
1234
 * @return unknown
1235
 */
1236
function theme_cdm_nomenclaturalReference($name, $doLink = FALSE, $displayMicroreference = TRUE, $displayPages = FALSE, $enclosingTag = 'span'){
1237
  
1238
  if(!$name->nomenclaturalReference){
1239
    return;
1240
  }
1241
  
1242
  $reference = $name->nomenclaturalReference;
1243
  
1244
  // different display for ZoologicalNames and others
1245
  if($name->class == ZoologicalName){
1246
    $year = partialToYear($reference->datePublished->start);
1247
    $citation = $reference->authorTeam->titleCache.($year ? ', '.$year : '');
1248
  } else {
1249
    // BotanicalName and others  
1250
    $citation = $reference->titleCache;
1251
  }
1252
  
1253
  if($doLink){
1254
    $citationHtml = l($citation, "/cdm_dataportal/reference/".$reference->uuid, array(), NULL, NULL, FALSE, TRUE);
1255
  } else {
1256
    $citationHtml = $citation;
1257
  }
1258
  
1259
  if(!empty($citation)){
1260
    $citationHtml = (str_beginsWith($citation, 'in') ? '&nbsp;':',&nbsp;') . $citationHtml;
1261
    if($displayMicroreference && $name->nomenclaturalMicroReference){
1262
      $microreference = '<span class="pages">:&nbsp;' . $name->nomenclaturalMicroReference . '</span>'; 
1263
    }  
1264
    if($displayPages){ //TODO substitute for microreference in dipterea? -> check theme.php#L85
1265
      $citation .= ': '.$reference->pages;
1266
    }
1267
    $citationHtml .= $microreference;
1268
  }
1269
  
1270
  
1271
  return '<'.$enclosingTag.' class="reference">'.$citationHtml.'</'.$enclosingTag.'>'; ;
1272
}
1273

    
1274
/**
1275
 * Allows theaming of the taxon page tabs
1276
 * 
1277
 * @param $tabname
1278
 * @return unknown_type
1279
 */
1280
function theme_cdm_taxonpage_tab($tabname){
1281
   //TODO replace by using translations or theme the menue tabs itself instead?
1282
  switch($tabname){
1283
    default: return t($tabname); 
1284
  }
1285
}
1286

    
1287
/**
1288
 * default title for a taxon page
1289
 *
1290
 * @param NameTO $nameTO
1291
 * @return the formatted taxon name
1292
 */
1293
function theme_cdm_taxon_page_title($taxon){
1294
  
1295
  $renderPath = 'taxon_page_title';
1296
  if(isset($taxon->name->nomenclaturalReference)){
1297
        $referenceUri = url(path_to_reference($taxon->name->nomenclaturalReference->uuid));
1298
  }
1299
  return '<span class="'.$taxon->class.'">'.theme('cdm_taxonName', $taxon->name, null, $referenceUri, $renderPath).'</span>';
1300
}
1301

    
1302

    
1303
function theme_cdm_acceptedFor($renderPath = false){
1304
  $out = '';
1305
  if(!$renderPath){
1306
    $renderPath = 'acceptedFor';
1307
  }
1308
  if(isset($_REQUEST['acceptedFor'])){
1309
     
1310
     $synonym = cdm_ws_get(CDM_WS_TAXON, $_REQUEST['acceptedFor']);
1311
     
1312
     if($synonym){
1313
       $out .= '<span class="acceptedFor">';
1314
       $out .= t('is accepted for ');
1315
       if(isset($synonym->name->nomenclaturalReference)){
1316
             $referenceUri = url(path_to_reference($synonym->name->nomenclaturalReference->uuid));
1317
       }
1318
       $out .= theme('cdm_taxonName', $synonym->name, null, $referenceUri, $renderPath);
1319
       $out .= '</span>';
1320
     }
1321
  }
1322
  
1323
  return $out;
1324
}
1325

    
1326
function theme_cdm_back_to_search_result_button(){
1327
  $out = '';
1328
  if($_SESSION['cdm']['search']){
1329
    /*['cdm']['last_search']*/
1330
    //$out .= '<div id="backButton">'.l(t('Back to search result'), $_SESSION ).'</div>';
1331
    $out .= '<div id="backButton">'.l(t('Back to search result'), "http://" . $_SERVER['SERVER_NAME'] . $_SESSION['cdm']['last_search'] ).'</div>';
1332
  
1333
  }
1334
  return $out;
1335
}
1336

    
1337
/**
1338
 * A wrapper function that groups available information to show by default, when
1339
 * a taxon page is requested by the browser.
1340
 * Individual themeing has to decide what this page should include (see methods beneath)
1341
 * and what information should go into tabs or should not be shown at all.
1342
 *
1343
 * It is headed by the name of the accepted taxon without author and reference.
1344
 * @param $taxonTO the taxon object
1345
 * @param $page_part name of the part to display,
1346
 *         valid values are: 'description', 'images', 'synonymy', 'all'
1347
 */
1348
function theme_cdm_taxon_page_general($taxon, $page_part = 'description') {
1349
  
1350
  $page_part = variable_get('cdm_dataportal_taxonpage_tabs', 1) ? $page_part : 'all';
1351
  $hideTabs = array();
1352
  
1353
  
1354
  // get images
1355
  $prefMimeTypeRegex = 'image:.*';
1356
  $prefMediaQuality = '*';
1357
  $media = cdm_ws_get(CDM_WS_TAXON_MEDIA, array($taxon->uuid, $prefMimeTypeRegex, $prefMediaQuality));
1358
  if(!isset($media[0])) {
1359
    $hideTabs[] = theme('cdm_taxonpage_tab', 'Images');
1360
  }
1361
  
1362
  // hideImage flag depending on administative preset
1363
  $hideImages = false;
1364
  if(variable_get('image_hide_rank', '0') != '0'){
1365
    $rankCompare = rank_compare($taxon->name->rank->uuid, variable_get('image_hide_rank', '-99'));
1366
    $hideImages =  ($rankCompare > -1);
1367
  }
1368
  // $hideTabs[] = theme('cdm_taxonpage_tab', 'General');
1369
  // $hideTabs[] = theme('cdm_taxonpage_tab', 'Synonymy')
1370
  
1371
  // hide tabs
1372
  $tabhide_js = '';
1373
  foreach($hideTabs as $tabText) {
1374
    $tabhide_js .= "$('.tabs.primary').children('li').children('a:contains(\"$tabText\")').hide();\n";
1375
  }
1376
  drupal_add_js("
1377
  $(document).ready(function(){
1378
      $tabhide_js
1379
    });", 'inline');
1380
      
1381
  $out = '';
1382
  $out .= theme('cdm_back_to_search_result_button');
1383
  $out .= theme('cdm_acceptedFor', 'page_general');
1384
  
1385
  // --- DESCRIPTION --- //
1386
  if($page_part == 'description' || $page_part == 'all'){
1387
    
1388
    $featureTree = cdm_ws_get(CDM_WS_FEATURETREE, variable_get('cdm_dataportal_featuretree_uuid', false));
1389
    $taxonDescriptions = cdm_ws_get(CDM_WS_TAXON_DESCRIPTIONS, $taxon->uuid);
1390
    $mergedTrees = cdm_ws_descriptions_by_featuretree($featureTree, $taxonDescriptions, variable_get('cdm_dataportal_descriptions_separated', FALSE));
1391
 
1392
    $out .= '<div id="general">';
1393
    $out .= theme('cdm_taxon_page_description', $taxon, $mergedTrees, $media, $hideImages);
1394
    $out .= '</div>';
1395
  }
1396
  // --- IMAGES --- //
1397
  if(!$hideImages && $page_part == 'images' || $page_part == 'all'){
1398
    $out .= '<div id="images">';
1399
    if($page_part == 'all'){
1400
      $out .= '<h2>'.t('Images').'</h2>';
1401
    }
1402
    $out .= theme('cdm_taxon_page_images', $taxon, $media);
1403
    $out .= '</div>';
1404
  }
1405
  // --- SYNONYMY --- //
1406
  if($page_part == 'synonymy' || $page_part == 'all'){
1407
    $out .= '<div id="synonymy">';
1408
    if($page_part == 'all'){
1409
      $out .= '<h2>'.t('Synonymy').'</h2>';
1410
    }
1411
    $addAcceptedTaxon = !variable_get('cdm_dataportal_nomref_in_title', 1);
1412
    $out .= theme('cdm_taxon_page_synonymy', $taxon, $addAcceptedTaxon);
1413

    
1414
    if(variable_get('cdm_dataportal_display_name_relations', 1)){
1415
      
1416
      $nameRelationships = cdm_ws_get(CDM_WS_TAXON_NAMERELATIONS, $taxon->uuid);
1417
      // TODO is it correct to skip relationsFromThisName since all relationships are to be understood as 'is .... of'
1418
      if(variable_get('cdm_dataportal_name_relations_skiptype_basionym', 1)){
1419
        $skip = array(UUID_BASIONYM);
1420
      }
1421
      $out .= theme('cdm_nameRelations', $nameRelationships, $skip);
1422
     }
1423
    $out .= '</div>';
1424
  }
1425

    
1426
  return $out;
1427
}
1428

    
1429
/**
1430
 * Outputs all descriptive data and shows the preferred picture of the
1431
 * accepted taxon.
1432
 *
1433
 */
1434
function theme_cdm_taxon_page_description($taxon, $mergedTrees, $media = null, $hideImages = false){
1435
  
1436
//  if(!$hideImages){
1437
//    // preferred image
1438
//    // hardcoded for testing;
1439
//    $defaultRepresentationPart = false;
1440
//    $defaultRepresentationPart->width = 184;
1441
//    $defaultRepresentationPart->height = 144;
1442
//    $defaultRepresentationPart->uri = drupal_get_path('theme', 'palmweb_2').'/images/no_picture.png';
1443
//    
1444
//    // preferred image size 184px × 144
1445
//    $imageMaxExtend = 184;
1446
//    $out .= '<div class="preferredImage">'.$defaultRepresentationPart->uri.theme('cdm_preferredImage', $media, $defaultRepresentationPart, $imageMaxExtend).'</div>';
1447
//  }
1448
  
1449
  // description TOC
1450
  $out .= theme('cdm_featureTreeTOCs', $mergedTrees);
1451
  // description
1452
  $out .= theme('cdm_featureTrees', $mergedTrees, $taxon);
1453
  return $out;
1454
}
1455

    
1456
/**
1457
 * Show whole synonymy for the accepted taxon. Synonymy list is headed by the complete scientific name
1458
 * of the accepted taxon with nomenclatural reference.
1459
 *
1460
 */
1461
function theme_cdm_taxon_page_synonymy($taxon, $addAcceptedTaxon){
1462
  
1463
  $renderPath = 'taxon_page_synonymy';
1464
  $synomymie = cdm_ws_get(CDM_WS_TAXON_SYNONYMY, $taxon->uuid);
1465
  $taxonRelationships = cdm_ws_get(CDM_WS_TAXON_RELATIONS, $taxon->uuid);
1466
  $skip = array(UUID_BASIONYM);
1467
 
1468
  if($addAcceptedTaxon){
1469
    if(isset($taxon->name->nomenclaturalReference)){
1470
           $referenceUri = url(path_to_reference($taxon->name->nomenclaturalReference->uuid));
1471
     }
1472
    $out .= theme('cdm_taxonName', $taxon->name, null, $referenceUri, $renderPath);
1473
  }
1474
  
1475
  if($addAcceptedTaxon && !isset($synomymie->homotypicSynonymsByHomotypicGroup[0])){
1476
    // display the type information for the added taxon
1477
    $typeDesignations = cdm_ws_get(CDM_WS_TAXON_NAMETYPEDESIGNATIONS, $taxon->uuid);
1478
    if($typeDesignations){
1479
      $out .= theme('cdm_typedesignations', $typeDesignations);
1480
    }
1481
  } else {
1482
    // reder the homotypicSynonymyGroup including the type information
1483
    $out .= theme('cdm_homotypicSynonymyGroup', $synomymie->homotypicSynonymsByHomotypicGroup);
1484
  }
1485
  if($synomymie->heterotypicSynonymyGroups) {
1486
    foreach($synomymie->heterotypicSynonymyGroups as $homotypicalGroup){
1487
      $out .= theme('cdm_heterotypicSynonymyGroup', $homotypicalGroup);
1488
    }
1489
  }
1490

    
1491
  $out .= theme('cdm_taxonRelations', $taxonRelationships, $skip);
1492

    
1493
  return $out;
1494
}
1495

    
1496
/**
1497
 * Show the collection of images stored with the accepted taxon
1498
 * 
1499
 */
1500
function theme_cdm_taxon_page_images($taxon, $media){
1501
  
1502
  $hasImages = isset($media[0]);
1503
  
1504
  if($hasImages){
1505
    //
1506
    $maxExtend = 150;
1507
    $cols = 3; 
1508
    $maxRows = false;
1509
    $alternativeMediaUri = null;
1510
    $captionElements = array('title', '#uri'=>t('open Image'));
1511
    $gallery_name = $taxon->uuid;
1512
    $out = '<div class="image-gallerie">';
1513
    $out .= theme('cdm_media_gallerie', $media, $gallery_name, $maxExtend, $cols, $maxRows, $captionElements, null, null);
1514
    $out .= '</div>';
1515
  }else{
1516
    $out = 'No images available.';
1517
  
1518
  }
1519
  return $out;
1520

    
1521
}
1522

    
1523
function theme_cdm_reference_pager($referencePager, $path, $parameters = array()){
1524
  drupal_set_title(t('Bibliographic Index'));
1525
  $out = '';
1526
  if(count($referencePager->records) > 0){
1527
    $out .= '<ul>';
1528
    foreach($referencePager->records as $reference){
1529
      $reference->fullCitation = $reference->titleCache; //FIXME remove hack for matching cdm entity to STO
1530
      $out .= '<li>'.theme('cdm_reference', $reference, TRUE).'</li>';
1531
    }
1532
    $out .= '</ul>';
1533
    $out .= theme('cdm_pager', $referencePager,  $path, $parameters);
1534
  } else {
1535
    $out = '<h4 class="error">Sorry, this page contains not entries.</h4>';
1536
  }
1537
  return $out;
1538
}
1539

    
1540
/**
1541
 * Show a reference in it's atomized form
1542
 */
1543
function theme_cdm_reference_page($referenceTO){
1544
  if($referenceTO->titleCache) {
1545
    drupal_set_title($referenceTO->titleCache);
1546
  } else {
1547
    drupal_set_title($referenceTO->fullCitation);
1548
  }
1549
  $field_order = array(
1550
    "title",
1551
    //"titleCache",
1552
    //"citation",
1553
    "authorTeam",
1554
    "editor",
1555
    "publisher",
1556
    "placePublished",
1557
    "datePublished",
1558
    "year",
1559
    "edition",      // class Book
1560
    "volume",       // class Article
1561
    "seriesPart",
1562
    "inSeries",
1563
    "inJournal",     // class Article
1564
    "inBook",        // class BookSection
1565
    "nomRefBase",    // class BookSection, Book, Article
1566
    "inProceedings", // class InProceedings
1567
    "pages",         // class Article
1568
    "series",        // class Article, PrintSeries
1569
    "school",        // class Thesis
1570
    "institution",   // class Report
1571
    "organization",  // class Proceedings
1572
    "nextVersion",
1573
    "previousVersion",
1574
    "isbn",         // class Book
1575
    "issn",         // class Journal
1576
    "uri",
1577
  );
1578
  
1579
  $table_rows = array();
1580
  foreach($field_order as $fieldname){
1581
      if(isset($referenceTO->$fieldname)){
1582
        if($fieldname == "datePublished") {
1583
          $partial = $referenceTO->$fieldname;
1584
          $datePublished = '';
1585
          if($partial->start){
1586
            $datePublished = substr($partial->start, 0, 4).'-'.substr($partial->start, 4, 2).'-'.substr($partial->start, 6, 2);
1587
          }
1588
          if($partial->end){
1589
            $datePublished = (strlen($datePublished) > 0 ? ' '.t('to').' ' : '').substr($partial->end, 0, 4).'-'.substr($partial->end, 4, 2).'-'.substr($partial->end, 6, 2);
1590
          }
1591
          $table_rows[] = array(t(ucfirst(strtolower($fieldname))), $datePublished);
1592
        } else if(is_object($referenceTO->$fieldname)){
1593
          $table_rows[] = array(t(ucfirst(strtolower($fieldname))), $referenceTO->$fieldname->titleCache);
1594
        } else {
1595
          $table_rows[] = array(t(ucfirst(strtolower($fieldname))), $referenceTO->$fieldname);
1596
        }
1597
      }
1598
  }
1599
  return theme("table", array("","") , $table_rows);
1600
}
1601

    
1602
/**
1603
 * Show a synonym page
1604
 *
1605
 * TODO what should show on this page exactly?
1606
 *
1607
 */
1608
function theme_cdm_synonym_page(){
1609

    
1610
}
1611

    
1612
function theme_cdm_preferredImage($media, $defaultRepresentationPart, $imageMaxExtend, $parameters = ''){
1613

    
1614
  if(isset($media[0])){
1615
    $representationPart = $media[0]->representations[0]->parts[0];
1616
    if($parameters){
1617
      $representationPart->uri.$parameters;
1618
    }
1619
  } else {
1620
    $representationPart = $defaultRepresentationPart;
1621
  }
1622
  
1623
  //$widthAndHeight = ($imageWidth ? ' width="'.$imageWidth : '').($imageHeight ? '" height="'.$imageHeight : '');
1624
//  $imageUri = $preferredMedia ? $preferredMedia->representations[0]->parts[0]->uri . $parameters : $defaultImage;
1625
  $attributes = array('alt'=>($preferredMedia ? $preferredMedia->representations[0]->parts[0]->uri : "no image available"));
1626
  $out .= theme('cdm_media_gallerie_image', $representationPart, $imageMaxExtend, false, $attributes);
1627
  // $out = '<img class="left" '.$widthAndHeight.' " src="'.$imageUri.'" alt="'.$altText.'" />';
1628
  return $out;
1629
}
1630

    
1631
function theme_cdm_homotypicSynonymyGroup($synonymList, $prependedSynonyms = array()){
1632

    
1633
  if(! is_array($synonymList) || count($synonymList) == 0){
1634
    return;
1635
  }
1636
  
1637
  $out = '<ul class="homotypicSynonyms">';
1638

    
1639
  if(!empty($prependedSynonyms)){
1640
    foreach($prependedSynonyms as $taxon){
1641
      $out .= '<li class="synonym">'.theme('cdm_related_taxon', $taxon, UUID_HOMOTYPIC_SYNONYM_OF).'</li>';
1642
    }
1643
  }
1644

    
1645
  foreach($synonymList as $synonym){
1646
    $out .= '<li class="synonym">'.theme('cdm_related_taxon', $synonym, UUID_HOMOTYPIC_SYNONYM_OF).'</li>';
1647
  }
1648
  
1649
  $typeDesignations = cdm_ws_get(CDM_WS_TAXON_NAMETYPEDESIGNATIONS, $synonymList[0]->uuid);
1650
  if($typeDesignations){
1651
    $out .= theme('cdm_typedesignations', $typeDesignations);
1652
  }
1653

    
1654
  $out .= '</ul>';
1655
  return $out;
1656
}
1657

    
1658
function theme_cdm_homotypicSynonymLine($taxon){
1659
  $out = '';
1660
  $out .= '<li class="synonym">'.theme('cdm_related_taxon', $taxon, UUID_HOMOTYPIC_SYNONYM_OF).'</li>';
1661
  return $out;
1662
}
1663

    
1664
function theme_cdm_heterotypicSynonymyGroup($homotypicalGroup){
1665
  $out = '';
1666
  $out = '<ul class="heterotypicSynonymyGroup">';
1667

    
1668
  $is_first_entry = true;
1669
  $typeDesignations = null;
1670
  foreach($homotypicalGroup as $synonym){
1671
    if($is_first_entry){
1672
      $is_first_entry = false;
1673
      //$typeDesignations = cdm_ws_get(CDM_WS_NAME_TYPEDESIGNATIONS, $synonym->name->uuid);
1674
      $typeDesignations = cdm_ws_get(CDM_WS_TAXON_NAMETYPEDESIGNATIONS, $synonym->uuid);
1675
      // is first list entry
1676
      $out .= '<li class="firstentry synonym">'.theme('cdm_related_taxon',$synonym, UUID_HETEROTYPIC_SYNONYM_OF).'</li>';
1677
    } else {
1678
      $out .= '<li class="synonym">'.theme('cdm_related_taxon',$synonym, UUID_HOMOTYPIC_SYNONYM_OF).'</li>';
1679
    }
1680
  }
1681

    
1682
  if($typeDesignations){
1683
    $out .= theme('cdm_typedesignations', $typeDesignations);
1684
  }
1685

    
1686
  $out .= '</ul>';
1687

    
1688
  return $out;
1689
}
1690

    
1691
/**
1692
 * renders misapplied names and invalid designations.
1693
 * Both relation types are currently treated the same!
1694
 *
1695
 * @param unknown_type $taxonRelationships
1696
 * @return unknown
1697
 */
1698
function theme_cdm_taxonRelations($taxonRelationships){
1699

    
1700
  if(!$taxonRelationships){
1701
    return;
1702
  }
1703
  
1704
  _add_js_cluetip();
1705

    
1706
  // aggregate misapplied names having the same fullname:
1707
  $misapplied = array();
1708
  foreach($taxonRelationships as $taxonRelation){
1709
    if(true || $taxonRelation->type->uuid == UUID_MISAPPLIED_NAME_FOR || $taxonRelation->type->uuid == UUID_INVALID_DESIGNATION_FOR ){
1710
      
1711
      $name = $taxonRelation->fromTaxon->name->titleCache;
1712
      $authorteam = $taxonRelation->fromTaxon->sec->authorTeam->titleCache;
1713
      
1714
      if(!isset($misapplied[$name])){
1715
        $misapplied[$name]['out'] = '<span class="misapplied">'.theme('cdm_related_taxon',$taxonRelation->fromTaxon, UUID_MISAPPLIED_NAME_FOR, false).'</span>';
1716
      }
1717

    
1718
      // collect all authors for this fullname
1719
      if(isset($authorteam)){
1720
        $misapplied[$name]['authorteam'][$authorteam] = '&nbsp;<span class="sensu cluetip no-print" title="|sensu '.htmlspecialchars(theme('cdm_reference',$taxonRelation->fromTaxon->sec )).'|">sensu '
1721
                    .$authorteam.'</span>'
1722
                    .'<span class="reference only-print">sensu '.theme('cdm_reference', $taxonRelation->fromTaxon->sec ).'</span>';
1723
      }
1724

    
1725
    }
1726
  }
1727
   
1728
  // generate output
1729
  $out = '<ul class="misapplied">';
1730
  foreach($misapplied as $misapplied_name){
1731
    $out .= '<li class="synonym">'.$misapplied_name['out'] . " ";
1732
    // sorting authors
1733
    ksort($misapplied_name['authorteam']);
1734
    $out .= join('; ', $misapplied_name['authorteam']);
1735
    $out .= '</li>';
1736
  }
1737
  $out .= '</ul>';
1738
  return $out;
1739
}
1740

    
1741
function theme_cdm_nameRelations($nameRelationships, $skipTypes = false){
1742

    
1743
  // group by relationship type
1744
  $relationshipGroups = array();  
1745
  foreach($nameRelationships as $nameRelationship){
1746
    if(!array_key_exists($nameRelationship->type->uuid, $relationshipGroups)){
1747
      $relationshipGroups[$nameRelationship->type->uuid] = array();
1748
    }
1749
    $relationshipGroups[$nameRelationship->type->uuid][] = $nameRelationship;
1750
  }
1751

    
1752
  // generate output
1753
  $out = '';
1754
  foreach($relationshipGroups as $group){
1755
    $type = $group[0]->type;
1756
    
1757
    if(is_array($skipTypes) && in_array($type->uuid, $skipTypes)){
1758
      continue;
1759
    }
1760
    
1761
    $block->module = 'cdm_dataportal';
1762
    $block->subject = t(ucfirst($type->inverseRepresentation_L10n));
1763
    $block->delta = generalizeString(strtolower($type->inverseRepresentation_L10n));
1764
  
1765
    foreach($group as $relationship){    
1766
      $relatedNames[] = cdm_taggedtext2html($relationship->fromName->taggedName);
1767
    }
1768
    
1769
    $block->content .= implode('; ', $relatedNames);
1770
    $out .= theme('block', $block);
1771
  }
1772
  return $out;
1773
}
1774

    
1775
/**
1776
 * FIXME this definitively has to be in another spot. just didn't know where to put it right now.
1777
 * Compares the status of two SpecimenTypeDesignations
1778
 * @param String $a 	a SpecimenTypeDesignations
1779
 * @param String $b		another SpecimenTypeDesignations
1780
 */
1781
function compare_specimenTypeDesignationStatus($a, $b){
1782
  /* this is the desired sort oder as of now:
1783
   * 	Holotype
1784
   * 	Isotype
1785
   * 	Lectotype
1786
   * 	Isolectotype
1787
   * 	Syntype
1788
   *
1789
   * TODO
1790
   * Basically, what we are trying to do is, we define an ordered array of TypeDesignation-states
1791
   * and use the index of this array for comparison. This array has to be filled with the cdm-
1792
   * TypeDesignation states and the order should be parameterisable inside the dataportal.
1793
   */
1794
  // make that static for now
1795
  $typeOrder = array('Holotype', 'Isotype', 'Lectotype', 'Isolectotype', 'Syntype');
1796

    
1797
  $aQuantifier = array_search($a->typeStatus->label, $typeOrder);
1798
  $bQuantifier = array_search($b->typeStatus->label, $typeOrder);
1799

    
1800
  if ($aQuantifier == $bQuantifier) {
1801
    // sort alphabetically
1802
    return ($a->typeStatus->label < $b->typeStatus->label) ? -1 : 1;
1803
  }
1804
  return ($aQuantifier < $bQuantifier) ? -1 : 1;
1805

    
1806
}
1807

    
1808
function theme_cdm_typedesignations($typeDesignations = array()){
1809
  
1810
  _add_js_cluetip();
1811
  $renderPath = 'typedesignations';
1812
  $out = '<ul class="typeDesignations">';
1813

    
1814
  $specimenTypeDesignations = array();
1815
  foreach($typeDesignations as $typeDesignation){
1816
    if($typeDesignation->class == 'SpecimenTypeDesignation'){
1817
      // SpecimenTypeDesignations should be ordered. collect theme here only
1818
      $specimenTypeDesignations[] = $typeDesignation;
1819
    }else {
1820
      
1821
      // it's a NameTypeDesignation
1822
      if($typeDesignation->notDesignated){
1823
        $out .= '<li class="nameTypeDesignation"><span class="status">Type</span>: '.t('not designated'). '</li>';
1824
      }else if($typeDesignation->typeName){
1825
        
1826
        $out .= '<li class="nameTypeDesignation"><span class="status">Type</span>: ';
1827
        
1828
        if($typeDesignation->typeName->nomenclaturalReference){
1829
          $referenceUri = url(path_to_reference($typeDesignation->typeName->nomenclaturalReference->uuid));
1830
        }
1831
        $out .= theme('cdm_taxonName', $typeDesignation->typeName, null, $referenceUri, $renderPath);
1832
        
1833
//        if($typeDesignation->typeName->class == 'ZoologicalName') {
1834
//          // appending authorTeam which has been skipped in cdm_name
1835
//          $authorTeam = cdm_taggedtext_value($typeDesignation->typeName->taggedName, 'authors');
1836
//          $authorTeamPart = l('<span class="authors">'.$authorTeam.'</span>', "/cdm_dataportal/reference/".$typeDesignation->typeName->nomenclaturalReference->uuid, array(), NULL, NULL, FALSE, TRUE);
1837
//          $out .= (str_endsWith($authorTeam, ')') ? '' : ', ').$authorTeamPart;
1838
//        } else {
1839
//          $out .= ' '.theme('cdm_reference', $typeDesignation->citation, true, $referenceStyle);
1840
//          $out .= '</li>';
1841
//        }
1842
      }
1843
    }
1844
  }
1845

    
1846
  if(!empty($specimenTypeDesignations)){
1847
    // sorting might be different for dataportals so this has to be parameterized
1848
    usort($specimenTypeDesignations, "compare_specimenTypeDesignationStatus");
1849
    foreach($specimenTypeDesignations as $std){
1850

    
1851
      $typeReference = '';
1852
      //show citation only for Lectotype or Neotype
1853
      $showCitation = isset($std->typeStatus) && ($std->typeStatus->uuid == UUID_NEOTYPE || $std->typeStatus->uuid == UUID_LECTOTYPE);
1854
      if($showCitation && !empty($std->citation)){
1855
        $shortCitation = $std->citation->authorTeam->titleCache;
1856
        $shortCitation .= (strlen($shortCitation) > 0 ? ' ' : '' ). partialToYear($std->citation->datePublished->start);
1857
        if(strlen($shortCitation) == 0){
1858
          $shortCitation = theme('cdm_reference',$std->citation );
1859
          $missingShortCitation = true;
1860
        }
1861
        $typeReference .= '&nbsp;(' . t('designated by');
1862
        $typeReference .= '&nbsp;<span class="typeReference '.($missingShortCitation ? '' : 'cluetip').' no-print" title="'. htmlspecialchars('|'.theme('cdm_reference',$std->citation ).'|') .'">';
1863
        $typeReference .= $shortCitation.'</span>';
1864
        $typeReference .= ')';
1865
        //$typeReference .= '<span class="reference only-print">(designated by '.theme('cdm_reference',$std->citation ).')</span>';
1866
      }
1867

    
1868
      $out .= '<li class="specimenTypeDesignation">';
1869
      $out .= '<span class="status">'.(($std->typeStatus->representation_L10n) ? $std->typeStatus->representation_L10n : t('Type')) .$typeReference.'</span>: '.$std->typeSpecimen->titleCache;
1870
      $out .= theme('cdm_specimen', $std->typeSpecimen);
1871
      $out .= '</li>';
1872
    }
1873
  }
1874

    
1875
  $out .= '</ul>';
1876

    
1877
  return $out;
1878
}
1879

    
1880
function theme_cdm_specimen($specimen){
1881

    
1882
  _add_js_thickbox();
1883

    
1884
  $out = '';
1885
  if(isset($specimen->media[0])){
1886

    
1887
    $image_url = drupal_get_path('module', 'cdm_dataportal').'/images/external_link.gif';
1888
    // thickbox has problems reading the first url parameter, so a litte hack is needed here:
1889
    // adding a meaningless patameter &tb_hack=1& ....
1890
    $out .= '&nbsp;<a href="#TB_inline?tb_hack=1&width=300&amp;height=330&amp;inlineId=specimen_media_'.$specimen->uuid.'" class="thickbox">'
1891
    .'<img src="'.$image_url.'" title="'.t('Show media').'" /></a>';
1892

    
1893
    $out .= '<div id="specimen_media_'.$specimen->uuid.'" class="tickbox_content"><table>';
1894

    
1895
    $media_row = '<tr class="media_data">';
1896
    $meta_row = '<tr class="meta_data">';
1897

    
1898
    foreach($specimen->media as $media){
1899
      foreach($media->representations as $representation){
1900

    
1901
        //TODO this this is PART 2/2 of a HACK - select preferred representation by mimetype and size
1902
        //
1903
        if(true || $representation->mimeType == 'image/jpeg'){
1904
          foreach($representation->parts as $part){
1905
            // get media uri conversion rules if the module is installed and activated
1906
            if(module_exists('cdm_mediauri')){
1907
              $muris = cdm_mediauri_conversion($part->uri);
1908
            }
1909
            // --- handle media preview rules
1910
            if(isset($muris['preview'])){
1911

    
1912
              $a_child = '<img src="'.$muris['preview']['uri'].'" class="preview" '
1913
              .($muris['preview']['size_x'] ? 'width="'.$muris['preview']['size_x'].'"' : '')
1914
              .($muris['preview']['size_y'] ? 'width="'.$muris['preview']['size_y'].'"' : '')
1915
              .'/>';
1916
            } else {
1917
              $a_child = '<img src="'.$part->uri.'" />';
1918
            }
1919

    
1920
            // --- handle web application rules
1921
            $webapp = '';
1922
            if(isset($muris['webapp'])){
1923
              if($muris['webapp']['embed_html']){
1924
                // embed in same page
1925
                $webapp = $muris['webapp']['embed_html'];
1926
              } else {
1927
                $webapp = l(t('web application'), $muris['webapp']['uri']);
1928
              }
1929
            }
1930
            $media_row .= '<td><a href="'.$part->uri.'" target="'.$part->uuid.'">'.$a_child.'</a></td>';
1931
            $meta_row .= '<td><span class="label">'.check_plain($specimen->titleCache).'</span><div class="webapp">'.$webapp.'</div></td>';
1932
          } // END parts
1933
          //TODO this is PART 2/2 of a hack
1934
          break;
1935
        } // END representations
1936
      } // END media
1937
    }
1938
    $out .= $media_row.'</tr>';
1939
    $out .= $meta_row.'</tr>';
1940

    
1941
    $out .= '</div></table>';
1942
  }
1943
  return $out;
1944
}
1945

    
1946
function theme_cdm_featureTrees($mergedTrees, $taxon){
1947
  
1948
  if(!$mergedTrees){
1949
    return;
1950
  }
1951
  
1952
  foreach($mergedTrees as &$mTree){
1953
    //TODO diplay title and reference in case of multiple $mergedTrees -> theme
1954
    $out .= theme('cdm_feature_nodes', $mTree->root->children, $taxon);
1955
  }
1956
  return $out;
1957
}
1958

    
1959
function theme_cdm_featureTreeTOCs($mergedTrees){
1960
  
1961
  if(!$mergedTrees){
1962
    return;
1963
  }
1964
  //FIXME
1965
  $out = '<div class="featureTOC">';
1966
  $out .= '<h2>' . t('Content') .'</h2>';
1967

    
1968
  //TODO diplay title and reference in case of multiple $mergedTrees -> theme
1969
  
1970
  foreach($mergedTrees as &$mTree){
1971
    $out .= theme('cdm_feature_nodesTOC', $mTree->root->children);
1972
  }
1973
  
1974
  $out .= '</div>';
1975
  return $out;
1976
}
1977

    
1978
function theme_cdm_feature_nodes($featureNodes, $taxon){
1979
  
1980
  foreach($featureNodes as $node){
1981
      // process $descriptionElements with content only
1982
      if(is_array($node->descriptionElements) && count($node->descriptionElements) > 0){
1983

    
1984
        $featureRepresentation = isset($node->feature->representation_L10n) ? $node->feature->representation_L10n : 'Feature';
1985

    
1986
        $block->module = 'cdm_dataportal';
1987
        
1988
        if($node->feature->uuid != UUID_IMAGE){
1989
          $block->delta = generalizeString($featureRepresentation);
1990
          $block->subject = theme('cdm_feature_name', $featureRepresentation);
1991
          $block->module = "cdm_dataportal-feature";
1992

    
1993
          $block->content = theme('cdm_descriptionElements', $node->descriptionElements, $block->delta);
1994
          
1995
          // set anchor; FIXME put anchor in $block->subject
1996
          $out .= '<a name="'.$block->delta.'"></a>';
1997
          $out .= theme('block', $block);
1998

    
1999
          // TODO HACK
2000
          if($node->feature->uuid == UUID_DISTRIBUTION){
2001
            $out .= theme('cdm_descriptionElements_distribution', $taxon);
2002
          }
2003
        }
2004
      }
2005
      // theme 
2006
      if(count($node->children) > 0){
2007
        $out .= '<div class="nested_description_elements">';
2008
        $out .= theme('cdm_feature_nodes', $node->children, $taxon);
2009
        $out .= '</div>';
2010
      }
2011
  }
2012
  return $out;
2013
}
2014

    
2015

    
2016
function theme_cdm_feature_nodesTOC($featureNodes){
2017

    
2018
  $out .= '<ul>';
2019
  
2020
  foreach($featureNodes as $node){
2021
    // process $descriptionElements with content only
2022
    if(is_array($node->descriptionElements) && count($node->descriptionElements) > 0){
2023

    
2024
      $featureRepresentation = isset($node->feature->representation_L10n) ? $node->feature->representation_L10n : 'Feature';
2025
      // HACK to implement images for taxa, should be removed
2026
      if($node->feature->uuid != UUID_IMAGE){
2027
        $out .= '<li>'.l(t(ucfirst($featureRepresentation)), $_GET['q'], array("class"=>"toc"), NULL, generalizeString($featureRepresentation)).'</li>';
2028
      }
2029
    }
2030
  }
2031

    
2032
  $out .= '</ul>';
2033
  return $out;
2034
}
2035

    
2036
function theme_cdm_feature_name($feature_name){
2037
  //TODO replace by using translations ?
2038
  switch($feature_name){
2039
    default: return t(ucfirst($feature_name));
2040
  }
2041
}
2042

    
2043
function theme_cdm_descriptionElements($descriptionElements){
2044
  
2045
  $outArray = array();
2046
  $glue = '';
2047
  $sortOutArray = false;
2048
  $enclosingHtml = 'ul';
2049
  
2050
  foreach($descriptionElements as $descriptionElement){
2051
    
2052
    if($descriptionElement->feature->uuid == UUID_DISTRIBUTION){
2053
       if($descriptionElement->class == 'Distribution'){
2054
          $repr = $descriptionElement->area->representation_L10n;
2055
       } else if($descriptionElement->class == 'TextData'){
2056
         $repr = $descriptionElement->multilanguageText_L10n->text;
2057
       }
2058
      if( !array_search($repr, $outArray)){
2059
        $outArray[] = $repr;
2060
        $glue = ', ';
2061
        $sortOutArray = true;
2062
        $enclosingHtml = 'p';
2063
      }
2064
    } else if($descriptionElement->class == 'TextData'){
2065
      $outArray[] = theme('cdm_descriptionElementTextData', $descriptionElement);
2066
    } else {
2067
      $outArray[] = '<li>No method for rendering unknown description class: '.$descriptionElement->classType.'</li>';
2068
    }
2069
    
2070
  }
2071
  // take the feature of the last $descriptionElement
2072
  $feature = $descriptionElement->feature;
2073
  return theme('cdm_descriptionElementArray', $outArray, $feature, $glue, $sortOutArray, $enclosingHtml);
2074
}
2075

    
2076
function theme_cdm_descriptionElementArray($elementArray, $feature, $glue = '', $sortArray = false, $enclosingHtml = 'ul'){
2077
  $out = '<'.$enclosingHtml.' class="description" id="'.$feature->representation_L10n.'">';
2078
  
2079
  if($sortArray) sort($elementArray);
2080
  
2081
  $out .= join($elementArray, $glue);
2082
  
2083
  $out .= '</'.$enclosingHtml.'>';
2084
  return $out;
2085
}
2086

    
2087
function theme_cdm_descriptionElementTextData($element){
2088

    
2089
  $description = str_replace("\n", "<br/>", $element->multilanguageText_L10n->text);
2090
  $referenceCitation = '';
2091
  if($element->citation){
2092
      $fullCitation = $element->citation->authorTeam->titleCache;
2093
      if(isset($element->citation->datePublished->start)) {
2094
        $fullCitation .= ', '.partialToYear($element->citation->datePublished->start);
2095
      }
2096
      
2097
      $referenceCitation = l('<span class="reference">'.$fullCitation.'</span>', path_to_reference($element->citation->uuid), array("class"=>"reference"), NULL, NULL, FALSE ,TRUE);
2098
      $referenceCitation = $referenceCitation;
2099
      if($element->citationMicroReference){
2100
        $referenceCitation .= ': '. $element->citationMicroReference;
2101
      }
2102
      if($description && strlen($description) > 0){
2103
        $referenceCitation = '; '.$referenceCitation;
2104
      }
2105
  }
2106
  return '<li class="descriptionText">' . $description . $referenceCitation.'</li>';
2107
}
2108

    
2109
function theme_cdm_search_results($pager, $path, $parameters){
2110
  
2111
  
2112
  $showThumbnails = $_SESSION['pageoptions']['searchtaxa']['showThumbnails'];
2113
  if( !is_numeric($showThumbnails)){
2114
    $showThumbnails = 1;
2115
  }
2116
  $setSessionUri = url('cdm_api/setvalue/session').'/pageoptions|searchtaxa|showThumbnails/';
2117
  drupal_add_js('$(document).ready(function() {
2118
  
2119
        // init
2120
        if('.$showThumbnails.' == 1){
2121
              $(\'.media_gallery\').show(20);
2122
        } else {
2123
          $(\'.media_gallery\').hide(20);
2124
        }
2125
        // add change hander
2126
        $(\'#showThumbnails\').change(
2127
          function(event){
2128
            var state = 0;
2129
            if($(this).is(\':checked\')){
2130
              $(\'.media_gallery\').show(20);
2131
              state = 1;
2132
            } else {
2133
              $(\'.media_gallery\').hide(20);
2134
            }
2135
            // store state in session variable
2136
            var uri = \''.$setSessionUri.'\' + state;
2137
            jQuery.get(uri);
2138
          });
2139
        });', "inline");
2140

    
2141
  drupal_set_title(t('Search Results'));
2142

    
2143
  $out = ''; //l('Advanced Search', '/cdm_dataportal/search');
2144
  
2145
  $out = '<div class="page_options"><form name="pageoptions"><input id="showThumbnails" type="checkbox" name="showThumbnails" '.($showThumbnails == 1? 'checked="checked"': '').'> '.t('Show Thumbnails').'</form></div>';
2146
  if(count($pager->records) > 0){
2147
    $out .= theme('cdm_list_of_taxa', $pager->records);
2148
    $out .= theme('cdm_pager', $pager, $path, $parameters);
2149
  } else {
2150
    $out = '<h4 class="error">Sorry, no matching entries found.</h4>';
2151
  }
2152
  return $out;
2153
}
2154

    
2155

    
2156
function theme_cdm_pager(&$pager, $path, $parameters){
2157
  $out = '';
2158

    
2159
  if ($pager->pagesAvailable > 1) {
2160

    
2161
    $out .= '<div class="pager">';
2162
    if($pager->currentIndex > 0){
2163
      $out .= theme('cdm_pager_link', t('« first'), 0,  $pager, $path, $parameters, array('class' => 'pager-first'));
2164
      $out .= theme('cdm_pager_link', t('‹ previous'), $pager->currentIndex - 1, $pager, $path, $parameters, array('class' => 'pager-previous'));
2165
    }
2166

    
2167
    if($pager->indices[0] > 0){
2168
      $out .= '<div class="pager-list-dots-left">...</div>';
2169
    }
2170

    
2171
    foreach($pager->indices as $index){
2172
      $label = $index + 1;
2173
      $out .= theme('cdm_pager_link', $label, $index,  $pager, $path, $parameters, array('class' => 'pager-first'));
2174
    }
2175
    if($pager->indices[count($pager->indices) - 1] < $pager->pagesAvailable - 1){
2176
      $out .= '<div class="pager-list-dots-right">...</div>';
2177
    }
2178

    
2179
    if($pager->nextIndex){
2180
      $out .= theme('cdm_pager_link', t('next ›'), $pager->nextIndex, $pager, $path, $parameters, array('class' => 'pager-next'));
2181
      $out .= theme('cdm_pager_link', t('last »'), $pager->pagesAvailable - 1, $pager, $path, $parameters, array('class' => 'pager-last'));
2182
    }
2183
    $out .= '</div>';
2184

    
2185
    return $out;
2186
  }
2187
}
2188

    
2189
function theme_cdm_pager_link($text, $linkIndex, &$pager, $path, $parameters = array(), $attributes) {
2190

    
2191
  $out = '';
2192
  $parameters['search']['page'] = $linkIndex;
2193
  if ($linkIndex == $pager->currentIndex) {
2194
    $out = '<strong>'.$text.'</strong>';
2195
  } else {
2196
    $queryString = drupal_query_string_encode($parameters);
2197
    $out = l($text, $path, $attributes, $queryString);
2198
  }
2199
  return $out;
2200
}
(6-6/9)