Project

General

Profile

Download (74 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * Functions for dealing with CDM entities of type SpecimenOrOccurrences
5
 *
6
 * @copyright
7
 *   (C) 2007-2012 EDIT
8
 *   European Distributed Institute of Taxonomy
9
 *   http://www.e-taxonomy.eu
10
 *
11
 *   The contents of this module are subject to the Mozilla
12
 *   Public License Version 1.1.
13
 * @see http://www.mozilla.org/MPL/MPL-1.1.html
14
 *
15
 * @author
16
 *   - Andreas Kohlbecker <a.kohlbecker@BGBM.org>
17
 */
18

    
19

    
20
/**
21
 * Renders a DerivedUnit either in a compact form or with full details.
22
 *
23
 * @param $derived_unit_dto
24
 *  The DerivedUnitDTO
25
 * @param $with_full_details
26
 *  Wether to render the dertived unit data with full details, like for example for the specimen page
27
 *
28
 * @return string
29
 *  The markup for a specimen page
30
 */
31
function render_cdm_specimenDTO_page($derived_unit_dto, $with_full_details = false)
32
{
33
    $detail_html = "";
34
    //link to specimen page
35
    $path_to_specimen = path_to_specimen($derived_unit_dto->uuid);
36
    if (!$with_full_details) {
37
        $specimenPageLink = l($derived_unit_dto->specimenShortTitle, $path_to_specimen);
38
        $detail_html .= "<strong>Specimen summary: $specimenPageLink</strong><br>";
39
    }
40

    
41
    if($with_full_details) {
42
        if($derived_unit_dto->summaryLabel){
43
            $detail_html .= "<br>".$derived_unit_dto->summaryLabel."<br>";
44

    
45
        }
46
    }
47
    if ($derived_unit_dto->preferredStableUri) {
48
        $stableIdentifierLink = l($derived_unit_dto->preferredStableUri, $derived_unit_dto->preferredStableUri);
49
        $detail_html .= create_label("Preferred stable URI") . $stableIdentifierLink . "<br>";
50
    }
51
    if ($with_full_details) {
52
        // associated taxa
53
        if ($derived_unit_dto->associatedTaxa) {
54
            $detail_html .= "<br>";
55
            $detail_html .= create_label("Associated with");
56
            if (sizeof($derived_unit_dto->associatedTaxa) > 1) {
57
                $detail_html .= "<br>";
58
            }
59
            foreach ($derived_unit_dto->associatedTaxa as $associatedTaxon) {
60
                $detail_html .= l($associatedTaxon->label, path_to_taxon($associatedTaxon->uuid, "specimens"));//$associatedTaxon->second."<br>";
61
            }
62
            $detail_html .= "<br>";
63
        }
64
    }
65
    // - type information
66
    $types = "";
67
    if (isset($derived_unit_dto->types)) {
68
        //typed taxa
69
        foreach ($derived_unit_dto->types as $typeStatus => $typedTaxa) {
70
            if($derived_unit_dto->types){
71
                if(empty($typeStatus) || $typeStatus == "_empty_"|| $typeStatus == ""){
72
                    $detail_html .= "<i>Type for:</i> ";
73
                } else {
74
                    $detail_html .= "<i>".ucfirst($typeStatus)."</i> of ";
75
                }
76
                foreach($typedTaxa as $typedTaxon){
77
                    $detail_html .= $typedTaxon." ";
78

    
79
                }
80
            } else {
81
                $types .= $typeStatus . " ";
82
            }
83
           $detail_html .= '<br>';
84
        }
85
    }
86
    $derivation_tree_summary_dto = $derived_unit_dto->derivationTreeSummary;
87
    // - specimen scans
88
    $specimenScans = create_html_links($derivation_tree_summary_dto->specimenScans, true);
89
    // - molecular data
90
    $molecularData = "";
91
    if ($derivation_tree_summary_dto->molecularDataList) {
92
        foreach ($derivation_tree_summary_dto->molecularDataList as $molecular) {
93
            //provider link
94
            if (isset($molecular->providerLink)) {
95
                $molecularData .= create_html_link($molecular->providerLink, true);
96
            } else {
97
                $molecularData .= "[no provider]";
98
            }
99
            //contig link
100
            if (isset($molecular->contigFiles)) {
101
                $molecularData .= "[";
102
                if (sizeof($molecular->contigFiles) > 0) {
103
                    foreach ($molecular->contigFiles as $contigFile) {
104
                        if (isset($contigFile->contigLink)) {
105
                            if (isset($contigFile->contigLink->uri) and $contigFile->contigLink->uri != null) {
106
                                $molecularData .= create_html_link($contigFile->contigLink, true) . " ";
107
                            }
108
                        } else {
109
                            $molecularData .= "no contig ";
110
                        }
111
                        //primer links
112
                        if (isset($contigFile->primerLinks)) {
113
                            $molecularData .= create_html_links($contigFile->primerLinks, true);
114
                        }
115
                    }
116
                }
117
                $molecularData = rtrim($molecularData, " ");
118
                $molecularData .= "]";
119
            }
120
            //FIXME separate with comma (remove trailing comma)
121
        }
122
    }
123
    // - detail images
124
    $detailImages = create_html_links($derivation_tree_summary_dto->detailImages, true);
125

    
126
    if ($types) {
127
        $detail_html .= $with_full_details ? "<br>" : "";
128
        $detail_html .= create_label("Type(s)") . $types . "<br>";
129
    }
130
    if ($specimenScans and !$with_full_details) {
131
        $detail_html .= create_label("Specimen Scans") . $specimenScans . "<br>";
132
    }
133
    //specimen scan image gallery
134
    if ($with_full_details and isset($derivation_tree_summary_dto->specimenScanUuids) and !empty($derivation_tree_summary_dto->specimenScanUuids)) {
135
        $detail_html .= addImageGallery("Specimen scans", $derivation_tree_summary_dto->specimenScanUuids);
136
    }
137

    
138
    if ($molecularData) {
139
        $detail_html .= $with_full_details ? "<br>" : "";
140
        $detail_html .= create_label("Molecular Data") . $molecularData . "<br>";
141
    }
142

    
143
    if ($detailImages and !$with_full_details) {
144
        $detail_html .= create_label("Detail Images") . $detailImages . "<br>";
145
    }
146

    
147
    //detail image gallery
148
    if ($with_full_details and isset($derivation_tree_summary_dto->detailImageUuids) and !empty($derivation_tree_summary_dto->detailImageUuids)) {
149
        $detail_html .= addImageGallery("Detail Images", $derivation_tree_summary_dto->detailImageUuids);
150
    }
151

    
152
    //character data
153
    if ($derived_unit_dto->characterData) {
154
        $detail_html .= $with_full_details ? "<br>" : "";
155
        $detail_html .= create_label("Character Data");
156
        if ($with_full_details) {
157
            $detail_html .= "<br>";
158
            foreach ($derived_unit_dto->characterData as $characterStatePair) {
159
                $detail_html .= "<i>" . $characterStatePair->first . "</i>:" . $characterStatePair->second;
160
                $detail_html .= "<br>";
161
        }
162
        } else {
163
            $detail_html .= l("detail page", $path_to_specimen);
164
            $detail_html .= "<br>";
165
        }
166
    }
167
    return $detail_html;
168
}
169

    
170
function addImageGallery($galleryName, $imageUuids)
171
{
172
    $images = array();
173
    foreach ($imageUuids as $uuid) {
174
        $images[] = cdm_ws_get(CDM_WS_PORTAL_MEDIA, $uuid);
175
    }
176

    
177
    $gallery_html = '';
178
    if (count($imageUuids) > 0) {
179
        $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
180
        $captionElements = array(
181
            'title',
182
            'rights',
183
        );
184
        $alternativeMediaUris = array();
185
        foreach ($images as $image) {
186
            $mediaUri = getMediaUri($image);
187
            if ($mediaUri) {
188
                $alternativeMediaUris[] = $mediaUri;
189
            } else {
190
                $alternativeMediaUris[] = path_to_media($image->uuid);
191
            }
192
        }
193

    
194

    
195

    
196
        $gallery_html = compose_cdm_media_gallery(array(
197
            'mediaList' => $images,
198
            'galleryName' => $galleryName,
199
            'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
200
            'cols' => $gallery_settings['cdm_dataportal_media_cols'],
201
            'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
202
            'captionElements' => $captionElements,
203
            'mediaLinkType' => 'LIGHTBOX',
204
          // 'alternativeMediaUri' => $alternativeMediaUris,
205
            'alternativeMediaUri' => NULL,
206
            'galleryLinkUri' => NULL,
207
        ));
208
    }
209
    return "<br>" . create_label($galleryName) . "<br>" . $gallery_html;
210
}
211

    
212
function getMediaUri($media)
213
{
214
    if (isset($media->representations) && sizeof($media->representations) == 1
215
        && isset($media->representations[0]->parts) &&
216
        sizeof($media->representations[0]->parts) == 1) {
217
        return $media->representations[0]->parts[0]->uri;
218
    }
219
    return null;
220
}
221

    
222

    
223
/**
224
 * Formats the given string to a label for displaying key-object pairs in HTML
225
 * @return string
226
 */
227
function create_label($label)
228
{
229
    return "<span class='specimen_table_label'>" . $label . ": </span>";
230
}
231

    
232
/**
233
 * Provides a humane representation for an occurrence or observation field name.
234
 * @param string $field
235
 *    The field name.
236
 * @return string
237
 *    The label for the fieldname.
238
 */
239
function cdm_occurrence_field_name_label($field){
240

    
241
  static $field_labels = array(
242
    'class' => 'Basis of Record',
243
    'fieldNumber' => 'Collecting number',
244
    'absoluteElevation' => 'Altitude',
245
    'absoluteElevationMinimum' => 'Altitude maximum',
246
    'absoluteElevationMaximum' => 'Altitude minimum',
247
    'getGatheringPeriod' => 'Gathering period'
248
  );
249

    
250
  if(str_endsWith($field,'_L10n')){
251
    $field = str_replace('_L10n', '', $field );
252
  }
253
  if (isset($field_labels[$field])) {
254
    $field = $field_labels[$field];
255
  }
256

    
257
  $field = preg_replace_callback(
258
    '/([a-z])([A-Z])/',
259
    function ($m) {
260
      return $m[1] . ' ' . strtolower ($m[2]);
261
    },
262
    $field);
263

    
264
  return t('@field-name:', array('@field-name' => ucfirst($field)));
265
}
266

    
267
/**
268
 * Compose an render array from a CDD SpecimenOrObservation entity.
269
 *
270
 * compose_hook() implementation
271
 *
272
 * @param object $specimen_or_observation
273
 *   the CDM FieldUnit or DerivedUnit to compose
274
 *   the render array for.
275
 * @param bool $isSpecimen_page
276
 * @param array $derivatives
277
 *   the render array which contains the compositions of the derivatives
278
 *   of the supplied $specimenOrObservation
279
 *
280
 * @return array
281
 *   the supplied render array $derivatives to which the composition of the supplied
282
 *   $specimenOrObservation has been added to
283
 *
284
 * @throws \Exception
285
 * @ingroup compose
286
 */
287

    
288
function compose_cdm_specimen_or_observation($specimen_or_observation, $isSpecimen_page = false, &$derivatives = null)
289
{
290
    $exclude_occurrence_fields = &drupal_static(__FUNCTION__);
291
    if (!isset($exclude_occurrence_fields)) {
292
        $exclude_occurrence_fields = array(
293
            'uuid',
294
            'titleCache',
295
            'protectedTitleCache',
296
            'derivedUnitMedia',
297
            'created',
298
            'publish',
299
            'updated',
300
            'class',
301
            'collectionCode'
302
        );
303
    }
304
    if ((variable_get(CDM_SPECIMEN_LIST_VIEW_MODE, CDM_SPECIMEN_LIST_VIEW_MODE_DEFAULT) == CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TABLE) || !$isSpecimen_page){
305
        $exclude_occurrence_fields[] = 'derivationEvents';
306
    }
307

    
308
    if (!isset($derivatives)) {
309
        $derivatives = array();
310
    }
311
    $descriptions = null;
312
    $derivedFrom = null;
313

    
314
    if (is_object($specimen_or_observation)) {
315

    
316
        // request again for deeper initialization
317
        $specimen_or_observation = cdm_ws_get("portal/" . CDM_WS_OCCURRENCE, $specimen_or_observation->uuid);
318
        if ($specimen_or_observation->class == 'FieldUnit'){
319
            // WARNING: adding a List<MediaDTO> as $specimen_or_observation->_derivedUnitMedia
320
            $specimen_or_observation->_derivedUnitMedia = cdm_ws_get(CDM_WS_DERIVEDUNIT_FACADE, array(
321
                $specimen_or_observation->uuid,
322
                'fieldObjectMediaDTO',
323
            ));
324
        }else{
325
            // WARNING: adding a List<Media> as $specimen_or_observation->_derivedUnitMedia
326
            $specimen_or_observation->_derivedUnitMedia = cdm_ws_get(CDM_WS_DERIVEDUNIT_FACADE, array(
327
                $specimen_or_observation->uuid,
328
                'derivedUnitMedia',
329
            ));
330
        }
331

    
332
        $type_label = $specimen_or_observation->class;
333
        RenderHints::setFootnoteListKey($type_label . '-' . $specimen_or_observation->uuid);
334

    
335
        // collect typeStatus as label
336
        if (isset($specimen_or_observation->specimenTypeDesignations)) {
337
            $type_status = array();
338
            foreach ($specimen_or_observation->specimenTypeDesignations as $typeDesignation) {
339
                if (isset($typeDesignation->typeStatus_L10n)) {
340
                    $type_status[] = $typeDesignation->typeStatus_L10n;
341
                }
342
            }
343
            if (count($type_status) > 0) {
344
                $type_label = implode(', ', $type_status);
345
            }
346
        }
347

    
348
        $title = $type_label . ': ' . $specimen_or_observation->titleCache;
349

    
350
        $groups = array();
351

    
352
        // --- add initialized fields
353
        foreach (get_object_vars($specimen_or_observation) as $field => $value) {
354
            if (!in_array($field, $exclude_occurrence_fields) && ($value && ($field == 'recordBasis' || !is_object($value) || isset($value->class)))) {
355
                switch ($field) {
356

    
357
                  case 'recordBasis':
358
                    $label = $value->representation_L10n;
359
                    if($label == 'Dna Sample'){
360
                      $label == 'DNA Sample';
361
                    }
362
                    _description_list_group_add($groups, cdm_occurrence_field_name_label($field), $label,NULL, -10);
363
                    break;
364

    
365
                    /* ---- java.lang.Object --- */
366
                    case 'class':
367
                        if ($value != '' /* FieldUnit' */) {
368
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value);
369
                        }
370
                        break;
371

    
372
                    case 'markers':
373
                        $dd_elements = array();
374
                        foreach ($value as $marker) {
375
                            $dd_elements[] = compose_cdm_marker($marker);
376
                        }
377
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $dd_elements);
378
                        break;
379

    
380

    
381
                    case 'annotations':
382
                        $dd_elements = array();
383
                        foreach ($value as $annotation) {
384
                            // TODO respect annotation type filter settings
385
                            $dd_elements[] = $annotation->text;
386
                        }
387
                        @_description_list_group_add($groups, t('Notes:'), $dd_elements);
388
                        break;
389

    
390
                    /* ---- SpecimenOrObservationBase --- */
391
                    case 'sex':
392
                    case 'lifeStage':
393
                    case 'kindOfUnit':
394
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value->representation_L10n);
395
                        break;
396

    
397
                    case 'definition':
398
                        // TODO
399
                        break;
400

    
401
                    case 'preferredStableUri':
402

    
403
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), array(array('#markup' => cdm_external_uri($value, false))));
404
                        break;
405

    
406
                    case 'specimenTypeDesignations':
407

    
408
                        //TODO: better display of details!!
409
                        @_description_list_group_add(
410
                            $groups,
411
                            cdm_occurrence_field_name_label($field),
412
                            array(
413
                                '#markup' => render_type_designations($value),
414
                            )
415
                        );
416
                        break;
417

    
418
                    case 'determinations':
419
                        $dd_elements = array();
420
                        $glue = ', ';
421

    
422
                        foreach ($value as $determinationEvent) {
423
                            $timeperiod_string = NULL;
424
                            if (isset_not_empty($determinationEvent->timeperiod)) {
425
                                $timeperiod_string = timePeriodToString($determinationEvent->timeperiod);
426
                            }
427
                            $weight = isset($determinationEvent->preferred) && $determinationEvent->preferred == 1 ? '0' : ($timeperiod_string ? $timeperiod_string : '1');
428
                            // check key exists
429
                            while (array_key_exists($weight, $dd_elements)) {
430
                                $weight .= '0';
431
                            }
432

    
433
                            $taxon_name = '';
434
                            $name_link = '';
435
                            if ($determinationEvent->taxonName) {
436
                                $taxon_name = cdm_ws_get(CDM_WS_NAME, $determinationEvent->taxonName->uuid);
437
                                $taxon_name->taggedName = cdm_ws_get(CDM_WS_NAME, array($determinationEvent->taxonName->uuid, "taggedName"));
438
                                $name_link = path_to_name($determinationEvent->taxonName->uuid);
439
                            } else if ($determinationEvent->taxon) {
440
                                $taxon_name = cdm_ws_get(CDM_WS_TAXON . '/$0/name', $determinationEvent->taxon->uuid);
441
                                $name_link = path_to_taxon($determinationEvent->taxon->uuid);
442
                            }
443
                            if ($taxon_name) {
444
                                //$taxon_html = render_taxon_or_name($taxon_name, $name_link);
445

    
446
                                $taxon_html = l($taxon_name->titleCache, $name_link);
447
                                $dd_elements[$weight] = $taxon_html;
448
                            }
449
                            if (isset_not_empty($determinationEvent->modifier)) {
450
                                $dd_elements[$weight] .= cdm_term_representation($determinationEvent->modifier);
451
                            }
452
                            if ($timeperiod_string) {
453
                                $dd_elements[$weight] .= $glue . $timeperiod_string;
454
                            }
455
                            if (isset_not_empty($determinationEvent->actor->titleCache)) {
456
                                $dd_elements[$weight] .= $glue . $determinationEvent->actor->titleCache;
457
                            }
458
                            if (isset_not_empty($determinationEvent->description)) {
459
                                $dd_elements[$weight] .= $glue . $determinationEvent->description;
460
                            }
461
                        }
462
                        ksort($dd_elements);
463
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('determinations'), $dd_elements);
464
                        break;
465

    
466
                    case 'descriptions':
467
                        $dd_elements = array();
468
                        foreach ($value as $description) {
469
                            $description = cdm_ws_get(CDM_WS_PORTAL_DESCRIPTION, $description->uuid);
470

    
471
                            if ($description->imageGallery == TRUE) {
472
                                continue;
473
                            }
474
                            $description_string = render_description_string(get_root_nodes_for_dataset($description));
475
                            $dd_elements[] = markup_to_render_array($description_string);
476
                        }
477
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $dd_elements);
478
                        break;
479
                    case '_derivedUnitMedia':
480
                        if ($isSpecimen_page) {
481
                            $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
482
                            $captionElements = array(
483
                                '#uri' => t('open media'),
484
                            );
485
                            $gallery_html = compose_cdm_media_gallery(array(
486
                                'mediaList' => $value, // WARNING: this is either a List<Media> or List<MediaDTO>, see above ~line 361
487
                                'galleryName' => $specimen_or_observation->titleCache,
488
                                'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
489
                                'cols' => $gallery_settings['cdm_dataportal_media_cols'],
490
                                'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
491
                                'captionElements' => $captionElements,
492
                                'mediaLinkType' => 'LIGHTBOX',
493
                                'alternativeMediaUri' => NULL,
494
                                'galleryLinkUri' => NULL,
495
                            ));
496
                            @_description_list_group_add($groups, "Detail Images:", markup_to_render_array($gallery_html), '', 20);
497
                        }
498

    
499
                        // $dd_elements[] = markup_to_render_array($gallery_html);
500

    
501
                        break;
502
                    case 'sources':
503
                        RenderHints::setAnnotationsAndSourceConfig([
504
                          'sources_as_content' => TRUE,
505
                          'link_to_name_used_in_source' => TRUE,
506
                          'link_to_reference' => FALSE,
507
                          'add_footnote_keys' => FALSE,
508
                          'bibliography_aware' => FALSE
509
                        ]);
510
                        $annotations_and_sources = handle_annotations_and_sources($specimen_or_observation);
511
                        if ($annotations_and_sources->hasSourceReferences()) {
512
                            @_description_list_group_add($groups, t('Sources') . ':', join(', ', $annotations_and_sources->getSourceReferences()), '', 12);
513
                        }
514
                        break;
515

    
516

    
517
                    /* ---- DerivedUnitBase --- */
518
                    case 'derivedFrom':
519
                        $derivedFrom = $value;
520
                        if ($isSpecimen_page) {
521
                            foreach ($derivedFrom->originals as $original) {
522
                                $pathToSpecimen = path_to_specimen($original->uuid);
523
                                $description = "";
524
                                if (isset($derivedFrom->description) && $derivedFrom->description != '') {
525
                                    $description = $derivedFrom->description . ": ";
526
                                }
527

    
528
                                $originals[] = markup_to_render_array(l($description . $original->titleCache, $pathToSpecimen));
529
                                if ($original->class == 'FieldUnit') {
530
                                    $label = t('Field data');
531
                                } else {
532
                                    $label = t('Derived from');
533
                                }
534
                                @_description_list_group_add($groups, $label . ':',
535
                                    $originals,
536
                                    '', 13);
537
                            }
538
                        }
539
                        break;
540
                    case 'derivationEvents':
541
                        $derivationEvents = $value;
542
                        $derived_units = array();
543
                        if ($isSpecimen_page) {
544
                            foreach ($derivationEvents as $derivationEvent) {
545
                                foreach ($derivationEvent->derivatives as $derived_unit) {
546
                                    $pathToSpecimen = path_to_specimen($derived_unit->uuid);
547
                                    $description = "";
548
                                    if (isset($derived_unit->description) && $derived_unit->description != '') {
549
                                        $description = $derived_unit->description . ": ";
550
                                    }
551

    
552
                                    $derived_units[] = markup_to_render_array(l($description . $derived_unit->titleCache, $pathToSpecimen));
553
                                }
554
                            }
555
                            @_description_list_group_add($groups, t('Derivatives') . ':',
556
                                $derived_units,
557
                                '', 100);
558

    
559
                        }
560
                        break;
561

    
562
                    case 'collection':
563
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), array(
564
                          array('#markup' => render_collection($value))
565
                        ));
566
                        break;
567

    
568
                    case 'storedUnder':
569
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('storedUnder'), array(
570
                          array('#markup' => render_taxon_or_name($value))
571
                        ));
572
                        break;
573
                    case 'dnaQuality':
574
                        $sub_dl_groups = array();
575

    
576
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('purificationMethod'), $value->purificationMethod, NULL, 1);
577
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('ratioOfAbsorbance260_230'), $value->ratioOfAbsorbance260_230, NULL, 2);
578
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('ratioOfAbsorbance260_280'), $value->ratioOfAbsorbance260_280, NULL, 3);
579
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('concentration'), $value->concentration, NULL, 4);
580
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('concentrationUnit'), $value->concentrationUnit, NULL, 4);
581
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('qualityTerm'), $value->qualityTerm, NULL, 4);
582
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('qualityCheckDate'), $value->qualityCheckDate, NULL, 4);
583

    
584
                        if (is_array($sub_dl_groups) && sizeof($sub_dl_groups)>0) {
585
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label($field),
586
                                array(
587
                                    array('#markup' => $value->titleCache),
588
                                    array('#theme' => 'description_list', '#groups' => $sub_dl_groups)
589
                                )
590
                            );
591
                        }
592
                        break;
593

    
594
                    case 'preservation':
595
                        $sub_dl_groups = array();
596

    
597
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('medium'), $value->medium, NULL, 1);
598
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('temperature'), $value->temperature, NULL, 2);
599
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('definedMaterialOrMethod'), $value->definedMaterialOrMethod, NULL, 3);
600

    
601
                        if (is_array($sub_dl_groups) && sizeof($sub_dl_groups)>0) {
602
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label($field),
603
                                array(
604
                                    array('#markup' => $value->titleCache),
605
                                    array('#theme' => 'description_list', '#groups' => $sub_dl_groups)
606
                                )
607
                            );
608
                        }
609
                        break;
610

    
611
                    /* ---- Specimen --- */
612
                    case 'sequences':
613
                        $dd_elements = array();
614
                        foreach ($value as $sequence) {
615
                            $dd_elements[] = compose_cdm_sequence($sequence);
616
                        }
617
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $dd_elements);
618
                        break;
619

    
620
                    // TODO preservation
621
                    // TODO exsiccatum
622

    
623

    
624
                    /* ---- FieldObservation --- */
625
                    case 'gatheringEvent':
626
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('collector'), $value->actor->titleCache, '', 1);
627
                        @_description_list_group_add($groups, t('Gathering date'), timePeriodToString($value->timeperiod), '', 2);
628
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('description'), $value->description, '', 3);
629
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('locality'), $value->locality->text, '', 10);
630
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('country'), $value->country->representation_L10n, '', 4);
631
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('collectingMethod'), $value->collectingMethod,'',5);
632
                        if (isset_not_empty($value->absoluteElevation)) {
633
                            $min_max_markup = statistical_values_from_gathering_event($value, 'absoluteElevation');
634
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label('absoluteElevation'), $min_max_markup, '',6);
635
                        }
636
                        if (isset_not_empty($value->distanceToGround)) {
637
                            $min_max_markup = statistical_values_from_gathering_event($value, 'distanceToGround');
638
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label('distanceToGround'), $min_max_markup,'',7);
639
                        }
640
                        if (isset_not_empty($value->distanceToWaterSurface)) {
641
                            $min_max_markup = statistical_values_from_gathering_event($value, 'distanceToWaterSurface');
642
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label('distanceToWaterSurface'), $min_max_markup, '',8);
643
                        }
644
                        if (isset_not_empty($value->collectingAreas)) {
645
                            $area_representations = array();
646
                            foreach ($value->collectingAreas as $area) {
647
                                $area_representations[] = l($area->representation_L10n, path_to_named_area($area->uuid));
648
                            }
649
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label('collectingAreas'),
650
                                array(
651
                                    array('#markup' => implode(', ', $area_representations))
652
                                ),'',9
653
                            );
654
                        }
655
                        if (isset_not_empty($value->exactLocation->sexagesimalString)) {
656
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label('exactLocation'),
657
                                array(
658
                                    array('#markup' => render_point($value->exactLocation)),
659

    
660
                                ),'',11
661
                            );
662
                        }
663
                        break;
664

    
665
                    default:
666
                        if (is_object($value) || is_array($value)) {
667
                            drupal_set_message("Unhandled type in compose_cdm_specimen_or_observation() for field " . $field, "warning");
668
                        } else {
669
                            if ($field == 'RecordBase' && $value == 'DnaSample') {
670
                                _description_list_group_add($groups, cdm_occurrence_field_name_label($field), 'DNA Sample');
671
                            } else {
672
                                _description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value);
673
                            }
674
                        }
675

    
676
                }
677

    
678
            }
679
        } // END of loop over $derivedUnitFacade fields
680

    
681
        // Extensions
682
        // TODO: filter by using visible_extensions_sorted()
683
        // TODO: treat as top level element, see https://dev.e-taxonomy.eu/redmine/issues/2985#note-23
684
        $extensions = cdm_ws_fetch_all(CDM_WS_PORTAL_OCCURRENCE . '/'  . $specimen_or_observation->uuid . '/extensions', array($specimen_or_observation->uuid));
685
        if ($extensions && count($extensions)) {
686

    
687
            $extensions_render_array = compose_extensions($extensions);
688
            @_description_list_group_add($groups, t('Extensions') . ':',
689
                $extensions_render_array,
690
                '', 100);
691
        }
692

    
693

    
694

    
695
        // template_preprocess_description_list() is not worting by weight so we do it right here
696
        uasort($groups, 'element_sort');
697

    
698
        $occurrence_elements = array(
699
           // '#title' => $title,
700
            '#theme' => 'description_list',
701
            '#groups' => $groups,
702
            '#attributes' => array('class' => html_class_attribute_ref($specimen_or_observation)),
703
        );
704

    
705
        $derivatives[] = $occurrence_elements;
706
        // all footnotes which has been assembled so far (e.g. from typeDesignations) to here
707
//       $foonote_li_elements = render_footnotes(RenderHints::getFootnoteListKey(), 'span');
708
//        if (!empty($foonote_li_elements)) {
709
//            $derivatives[] =  array(
710
//                '#markup' =>  '<div class="footnotes">' . $foonote_li_elements . '</div>',
711
//            );
712
//        }
713

    
714
        // --- recurse into originals
715
        if (!isset($derivedFrom)  && !$isSpecimen_page) {
716
            $derivedFrom = cdm_ws_get(
717
                CDM_WS_OCCURRENCE,
718
                array($specimen_or_observation->uuid, 'derivedFrom')
719
            );
720
        }
721
        if (isset($derivedFrom) && !$isSpecimen_page) {
722
            if (isset($derivedFrom->originals)) {
723
                $derived_from_label = t('derived');
724
                $preposition = t('from');
725
                if(isset($derivedFrom->type)){
726
                    $derived_from_label = $derivedFrom->type->representation_L10n;
727
                    if($derivedFrom->type->uuid == UUID_DERIVATIONEVENTTYPE_ACCESSIONING){
728
                        $preposition = t('of');
729
                    }
730
                }
731
                if (count($groups) > 0) {
732
                    // TODO  annotations
733

    
734
                    // only display the derived from information when the derivative has any element which will be diplayed
735
                    $derivatives[] = array(
736
                        '#markup' => '<div class="derived_from">' . $derived_from_label . ' ' . $preposition . ': </div>',
737
                    );
738
                }
739
                foreach ($derivedFrom->originals as $original) {
740
                    compose_cdm_specimen_or_observation($original, $isSpecimen_page, $derivatives);
741
                }
742
            }
743
        }
744

    
745

    
746

    
747

    
748
    } // END of $specimenOrObservation exists
749

    
750
    return $derivatives;
751
}
752

    
753

    
754
/**
755
 * Compose an render array from a CDM Sequence object.
756
 *
757
 * compose_hook() implementation
758
 *
759
 * @param object $sequence
760
 *   CDM instance of type Sequence
761
 * @return array
762
 *   A render array containing the fields of the supplied $sequence
763
 *
764
 * @ingroup compose
765
 */
766
function compose_cdm_sequence($sequence, $isSpecimenPage = false)
767
{
768

    
769
    $exclude_sequence_fields = &drupal_static(__FUNCTION__);
770
    if (!isset($exclude_sequence_fields)) {
771
        $exclude_sequence_fields = array(
772
            'titleCache',
773
            'protectedTitleCache',
774
            'microReference',
775
            'created',
776
            'updated',
777
            'class',
778
        );
779
    }
780

    
781
    $groups = array();
782

    
783
    // -- retrieve additional data if necessary
784
    // TODO below call disabled since sequences are not yet supported,
785
    //      see  #3347 (services and REST service controller for molecular classes implemented)
786
    //
787
    // cdm_load_annotations($sequence);
788

    
789
    foreach (get_object_vars($sequence) as $field => $value) {
790

    
791

    
792
        if (!in_array($field, $exclude_sequence_fields) && ($value && (!is_object($value) || isset($value->class)))) {
793
            switch ($field) {
794

    
795
                case 'geneticAccessionNumber';
796

    
797
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value, NULL, 2);
798
                    break;
799

    
800

    
801
                case 'dnaMarker': // FIXME 3.3 now dnaMarker (DefinedTerm)  if multiple amplifications where used to build this consensus sequence it may be the super set of the markers used in amplification.
802
                    if (isset($value->name)) {
803
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value->name, NULL, 3);
804
                    }
805
                    if (isset($value->description)) {
806
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field) . ' ' . t('description'), $value->description, NULL, 4);
807
                    }
808
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field) , $value, NULL, 4);
809
                    break;
810

    
811
                case 'consensusSequence':
812
                    // format in genbank style, force linebreaks after each 70 nucleotites
813
                    // see also http://stackoverflow.com/questions/499137/css-how-can-i-force-a-long-string-without-any-blank-to-be-wrapped-in-xul-and
814
                    if ($value->length > 0) {
815
                        @_description_list_group_add(
816
                            $groups,
817
                            cdm_occurrence_field_name_label($field),
818
                            array(
819
                                array(
820
                                    '#markup' => '<div class="sequence-length">' . $value->length . ' ' . t('pb') . '</div><div>' . wordwrap($value->string, 70, '</br>', TRUE) . '</div>',
821
                                    '#wrapper_attributes' => array('class' => 'dna-sequence')
822
                                )
823
                            ),
824
                            5);
825
                    }
826
                    break;
827

    
828
                case 'dnaSample': // FIXME 3.3 implement
829
                    break;
830
                case 'singleReads': // FIXME 3.3 implement
831
                    break;
832
                case 'contigFile': // FIXME 3.3 implement - Media
833
                    break;
834
                case 'pherograms': // FIXME 3.3 implement - Media
835
                    break;
836
                case 'haplotype': // FIXME 3.3 implement
837
                    break;
838
                case 'dateSequenced': // FIXME 3.3 now in SingelRead
839
                    @_description_list_group_add($groups, t('Sequencing date'), timePeriodToString($value), NULL, 6);
840
                    break;
841

    
842
                case 'barcode': // boolean
843
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value ? 'Yes' : 'No', NULL, 7);
844
                    break;
845
                case 'barcodeSequencePart': // FIXME 3.3 implement, compose sequence
846
                    break;
847

    
848
                case 'citation':
849
                    @_description_list_group_add($groups,
850
                        cdm_occurrence_field_name_label($field),
851
                        cdm_reference_markup($value, $sequence->microReference),
852
                        NULL,
853
                        8
854
                    );
855
                    break;
856

    
857
                case 'publishedIn':
858
                    @_description_list_group_add($groups,
859
                        cdm_occurrence_field_name_label($field),
860
                        theme('cdm_reference', array('reference' => $value)),
861
                        NULL,
862
                        7
863
                    );
864
                    break;
865

    
866
                case 'rights':
867
                    array_merge($groups, cdm_rights_as_dl_groups($value));
868
                    break;
869

    
870
                case 'annotations':
871
                    $dd_elements = array();
872
                    foreach ($value as $annotation) {
873
                        // TODO respect annotation type filter settings
874
                        $dd_elements[] = $annotation->text;
875
                    }
876
                    @_description_list_group_add($groups, t('Notes'), $dd_elements, NULL, 9);
877
                    break;
878

    
879
                case 'markers':
880
                    $dd_elements = array();
881
                    foreach ($value as $marker) {
882
                        $dd_elements[] = compose_cdm_marker($marker);
883
                    }
884
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $dd_elements, NULL, 10);
885
                    break;
886

    
887
                case 'chromatograms':
888
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field),
889
                        array(
890
                            '#markup' => compose_cdm_media_gallery(array('medialist' => $value)),
891
                        ),
892
                        NULL,
893
                        11);
894
                    break;
895

    
896
                default:
897
                    if (is_object($value) || is_array($value)) {
898
                        drupal_set_message("Unhandled type in compose_cdm_sequence() for field " . $field, "warning");
899
                    } else {
900
                        if (!is_array($value) && strpos($value, 'http:') !== false ){
901
                            //make links for urls
902
                            $value = l($value, $value);
903
                            $value = markup_to_render_array($value);
904
                        }
905

    
906
                       _description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value, NULL, 20);
907
                    }
908
            }
909
        }
910
    }
911

    
912
    // template_preprocess_description_list() is not worting by weight so we do it right here
913
    uasort($groups, 'element_sort');
914
    if ($isSpecimenPage) {
915
        $sequence_elements = array(
916
            '#title' => $sequence->dnaMarker,
917
            '#theme' => 'description_list',
918
            '#groups' => $groups
919
        );
920
    } else{
921
        $sequence_elements = array(
922
            '#title' => $sequence->dnaMarker -> titleCache,
923
            '#theme' => 'description_list',
924
            '#groups' => $groups
925
        );
926
    }
927

    
928
    return $sequence_elements;
929
}
930

    
931
/**
932
 * Creates render array items for FieldUnitDTO or DerivedUnitDTO.
933
 *
934
 * @param array $root_unit_dtos
935
 *     list of SpecimenOrObservationDTOs
936
 * @return array
937
 *    An array which can be used in render arrays to be passed to the
938
 * theme_table() and theme_list().
939
 */
940
function specimen_render_array_items(array $root_unit_dtos){
941

    
942
  $render_array_items = array();
943
  $items = array();
944

    
945
  //we need one more item to contain the items of one level (fieldunit, derivate data etc.)
946
  foreach ($root_unit_dtos as &$sob_dto) {
947
    $items['data'] = $sob_dto->label;
948
    $specimen = compose_cdm_specimen_or_observation_tree_entry($sob_dto);
949
    $children = array();
950
    $child = array();
951
    $child['data'] =$specimen;
952
    // $children[] = create_specimen_array($specimenOrObservation->derivatives);
953
    if (isset($sob_dto->derivatives) && sizeof($sob_dto->derivatives) > 0){
954
      usort($sob_dto->derivatives, 'compare_specimen_or_observation_dtos');
955
      $child['children']= specimen_render_array_items($sob_dto->derivatives);
956
    }
957
    $children[]=$child;
958
    $items['children'] = $children;
959
    $render_array_items[] = $items;
960
  }
961
  return $render_array_items;
962
}
963

    
964
/**
965
 * Composes a compressed derivate table showing all derivatives which
966
 * stem from a common gathering event.
967
 *
968
 * @param $root_unit_uuids array
969
 *  An array of uuids for cdm root units of the derivation graphs.
970
 *
971
 * @return array
972
 *  A drupal render array for a table
973
 *
974
 * @see CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TABLE
975
 *
976
 * @ingroup compose
977
 */
978

    
979
function compose_compressed_specimen_derivate_table($root_unit_uuids) {
980

    
981
  // prepare font icons
982
  $expand_icon = font_awesome_icon_markup(
983
    'fa-plus-square-o',
984
    array(
985
      'alt' => 'Show details',
986
      'class' => array('expand_icon')
987
    )
988
  );
989
  $collapse_icon = font_awesome_icon_markup(
990
    'fa-minus-square-o',
991
    array(
992
      'alt' => 'Show details',
993
      'class' => array('collapse_icon')
994
    )
995
  );
996
  $detail_image_icon = '<img title="Detail Image" src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/detail_image_derivate-16x16-32.png' . '"/>';
997
  $checked_box_icon = '<img src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/step_done.gif' . '"/>';
998
  $sequence_icon = '<img title="Molecular Data" src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/sequence_derivate-16x16-32.png' . '"/>';
999
  $character_data_icon = '<img title="Character Data" src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/character_data_derivate-16x16-32.png' . '"/>';
1000

    
1001
  $rowcount = 0;
1002
  $rows = array();
1003

    
1004
  foreach ($root_unit_uuids as $root_unit_uuid) {
1005

    
1006
    //get derivate hierarchy for the FieldUnit
1007
    $sob_dto = cdm_ws_get(CDM_WS_PORTAL_OCCURRENCE_AS_DTO, array($root_unit_uuid));
1008
    if ($sob_dto) {
1009
      //summary row
1010
      if($sob_dto->class == "FieldUnitDTO"){
1011
        $rows[] = array(
1012
          'id' => 'derivate_summary' . $rowcount, // summary row id
1013
          'class' => array('summary_row'),
1014
          'data' => array(
1015
            array(
1016
              'data' => $expand_icon . $collapse_icon,
1017
              'class' => array('summary_row_cell', 'summary_row_icon', 'expand_column')
1018
            ),
1019
            array(
1020
              'data' => $sob_dto->country,
1021
              'class' => array('summary_row_cell')
1022
            ),
1023
            array(
1024
              'data' => $sob_dto->date,
1025
              'class' => array('summary_row_cell')
1026
            ),
1027
            array(
1028
              'data' => $sob_dto->collectingString,
1029
              'class' => array('summary_row_cell')
1030
            ),
1031
            @array(
1032
              'data' => $sob_dto->collectionStatistics,
1033
              'class' => array('summary_row_cell')
1034
            ),
1035
            array(
1036
              'data' => $sob_dto->hasType ? $checked_box_icon : "",
1037
              'class' => array('summary_row_cell', 'summary_row_icon')
1038
            ),
1039
            array(
1040
              'data' => $sob_dto->hasSpecimenScan ? $checked_box_icon : "",
1041
              'class' => array('summary_row_cell', 'summary_row_icon')
1042
            ),
1043
            array(
1044
              'data' => ($sob_dto->hasDna ? $sequence_icon : "") . " "
1045
                . ($sob_dto->hasDetailImage ? $detail_image_icon : "") . " "
1046
                . ($sob_dto->hasCharacterData ? $character_data_icon : ""),
1047
              'class' => array('summary_row_cell', 'summary_row_icon')
1048
            )
1049
          )
1050
        );
1051
      } else {
1052
        $rows[] = array(
1053
          'id' => 'derivate_summary' . $rowcount, // summary row id
1054
          'class' => array('summary_row'),
1055
          'data' => array(
1056
            array(
1057
              'data' => $expand_icon . $collapse_icon,
1058
              'class' => array('summary_row_cell', 'summary_row_icon', 'expand_column')
1059
            ),
1060
            array(
1061
              'data' => $sob_dto->label,
1062
              'class' => array('summary_row_cell'),
1063
              'colspan' => 5
1064
            ),
1065
            array(
1066
              'data' => $sob_dto->hasSpecimenScan ? $checked_box_icon : "",
1067
              'class' => array('summary_row_cell', 'summary_row_icon')
1068
            ),
1069
            array(
1070
              'data' => ($sob_dto->hasDna ? $sequence_icon : "") . " "
1071
                . ($sob_dto->hasDetailImage ? $detail_image_icon : "") . " "
1072
                . ($sob_dto->hasCharacterData ? $character_data_icon : ""),
1073
              'class' => array('summary_row_cell', 'summary_row_icon')
1074
            )
1075
          )
1076
        );
1077
      }
1078

    
1079
      //assemble field unit details
1080
      $detail_html = "";
1081
      if ($sob_dto->summaryLabel) {
1082
        $detail_html .= create_label("Citation") . $sob_dto->summaryLabel . "<br>";
1083
      }
1084
      //assemble specimen details
1085
      if ($sob_dto->derivatives) {
1086
        $derivatives_orderd = [];
1087
        foreach ($sob_dto->derivatives as $derivative_dto) {
1088
          $derivatives_orderd[$derivative_dto->specimenShortTitle] = $derivative_dto;
1089
        }
1090
        ksort($derivatives_orderd);
1091
        foreach ($derivatives_orderd as $derivative_dto) {
1092
          $detail_html .= "<br>";
1093
          $detail_html .= render_cdm_specimenDTO_page($derivative_dto);
1094
        }
1095
      }
1096
      $detail_html .= "<br>";
1097
      //detail row resp. one BIG detail cell
1098
      $rows[] = array(
1099
        'data' => array(
1100
          array(
1101
            'data' => "", //empty first column
1102
            'class' => array('expand_column')
1103
          ),
1104
          array(
1105
            'data' => $detail_html,
1106
            'colspan' => 7,
1107
          ),
1108
        ),
1109
        'id' => 'derivate_details' . $rowcount,//details row ID
1110
        'class' => array('detail_row'),
1111
      );
1112
      $rowcount++;
1113
    }
1114
  }
1115

    
1116
  $tableId = "derivate_hierarchy_table";
1117
  $derivateHierarchyTable = array(
1118
    "#theme" => "table",
1119
    "#weight" => 2,
1120
    "#header" => array(
1121
      array(
1122
        'data' => "",
1123
        'class' => array('expand_column')
1124
      ),
1125
      "Country", "Date", "Collector + collecting number", "Herbaria", "Type", "Scan", "Derivatives"),
1126
    "#rows" => $rows,
1127
    "#attributes" => array(
1128
      "id" => $tableId,
1129
      "border" => 2
1130
    )
1131
  );
1132

    
1133
  //add toggle functionality to derivate hierarchy table
1134
  drupal_add_js_rowToggle("#" . $tableId);
1135

    
1136
  return $derivateHierarchyTable;
1137
}
1138

    
1139

    
1140
/**
1141
 * Renders a FieldUnitDTO or DerivedUnitDTO
1142
 *
1143
 * @param object $specimen_or_observation_dto
1144
 *   A FieldUnitDTO or DerivedUnitDTO object
1145
 *   the render array for
1146
 *
1147
 * @return string
1148
 *   the supplied render array $derivatives to which the composition of the
1149
 *   supplied
1150
 *   $specimenOrObservation has been added to
1151
 *
1152
 * @ingroup compose
1153
 *
1154
 * @throws \Exception
1155
 */
1156
function compose_cdm_specimen_or_observation_tree_entry($specimen_or_observation_dto) {
1157
  $exclude_occurrence_fields = &drupal_static(__FUNCTION__);
1158
  if (!isset($exclude_occurrence_fields)) {
1159
    $exclude_occurrence_fields = [
1160
      'uuid',
1161
      'titleCache',
1162
      'protectedTitleCache',
1163
      'label',
1164
      'class',
1165
      'type',
1166
      'types',
1167
      'taxonRelatedDerivedUnits',
1168
      'collectionCode',
1169
      'derivatives',
1170
      'derivateDataDTO',
1171
      'summaryLabel',
1172
      'derivationTreeSummary',
1173
      'specimenIdentifier', // combination like  collection code + accession number
1174
      'mostSignificantIdentifier',
1175
      // -----
1176
      // needed later on?
1177
      'hasDetailImage',
1178
      'hasType',
1179
      'hasSpecimenScan',
1180
      'collectionStatistics',
1181
      'collectingString'
1182
      // ----
1183
    ];
1184
  }
1185

    
1186
  if (is_object($specimen_or_observation_dto)) {
1187

    
1188
    if(isset($specimen_or_observation_dto->recordBase)){
1189
        $type_label = $specimen_or_observation_dto->recordBase->representation_L10n;
1190
    }
1191
      RenderHints::setFootnoteListKey($type_label . '-' . $specimen_or_observation_dto->uuid);
1192

    
1193
      // collect typeStatus as label
1194
      if (isset($specimen_or_observation_dto->specimenTypeDesignations)) {
1195
          $type_status = array();
1196
          foreach ($specimen_or_observation_dto->specimenTypeDesignations as $typeDesignation) {
1197
              if (isset($typeDesignation->typeStatus_L10n)) {
1198
                  $type_status[] = $typeDesignation->typeStatus_L10n;
1199
              }
1200
          }
1201
          if (count($type_status) > 0) {
1202
              $type_label = implode(', ', $type_status);
1203
        }
1204
      }
1205

    
1206
      if (isset($typeDesignation->typifiedNames)){
1207
          $title = $type_label . ' for: ' . $typeDesignation->typifiedNames;
1208
      }else{
1209
          $title = $type_label;
1210
      }
1211

    
1212
        $groups = array();
1213
        $children_items = array();
1214
        // --- add initialized fields
1215
        foreach (get_object_vars($specimen_or_observation_dto) as $field => $value) {
1216
            $child_item = array();
1217

    
1218
            if (!in_array($field, $exclude_occurrence_fields) && $value ) {
1219
              switch ($field) {
1220

    
1221
                /* ---- SpecimenOrObservationBase --- */
1222
                case 'recordBase':
1223
                  $label = $value->representation_L10n;
1224
                  if($label == 'Dna Sample'){
1225
                    $label == 'DNA Sample';
1226
                  }
1227
                  _description_list_group_add($groups, cdm_occurrence_field_name_label($field), $label,NULL, -10);
1228
                break;
1229
                case 'derivationEvent':
1230
                    @_description_list_group_add($groups, 'Gathering type:', ucfirst($value->eventType), NULL, 1);
1231
                    break;
1232
                case 'accessionNumber':
1233
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value, NULL, 0);
1234
                    break;
1235
                case 'preferredStableUri':
1236
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), array(array('#markup' => cdm_external_uri($value, false))));
1237
                    break;
1238
                case 'characterData':
1239
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), array(array('#markup' => icon_link(path_to_specimen($specimen_or_observation_dto->uuid), '', FALSE), false)));
1240
                  break;
1241
                case 'specimenTypeDesignations':
1242
                    @_description_list_group_add(
1243
                        $groups,
1244
                        cdm_occurrence_field_name_label($field),
1245
                        array(
1246
                            '#markup' => render_specimen_typedesignation_dto($value),
1247
                        )
1248
                    );
1249
                    break;
1250

    
1251
                case 'listOfMedia':
1252
                    $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
1253

    
1254
                    $captionElements = array(
1255
                        'title',
1256
                        '#uri' => t('open media'),
1257
                    );
1258
                    $gallery_html = compose_cdm_media_gallery(array(
1259
                        'mediaList' => $value,
1260
                        'galleryName' => $specimen_or_observation_dto->uuid,
1261
                        'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
1262
                        'cols' => $gallery_settings['cdm_dataportal_media_cols'],
1263
                        'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
1264
                        'captionElements' => $captionElements,
1265
                        'mediaLinkType' => 'LIGHTBOX',
1266
                        'alternativeMediaUri' => NULL,
1267
                        'galleryLinkUri' => NULL,
1268
                        'showCaption' => true
1269
                    ));
1270

    
1271
                  //FIXME re-enable: // @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $gallery_html);
1272
                  break;
1273

    
1274
                  case 'sex':
1275
                  case 'lifeStage':
1276
                  case 'kindOfUnit':
1277
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), cdm_term_representation($value));
1278
                    break;
1279

    
1280
                  case 'definition':
1281
                    // TODO
1282
                    break;
1283

    
1284
                  /* ---- DerivedUnitBase --- */
1285
                  case 'collection':
1286
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), array(
1287
                      array('#markup' => render_collection_dto($value))
1288
                    ));
1289
                    break;
1290

    
1291
                  /* ---- Specimen --- */
1292
                  case 'sequences':
1293
                      $dd_elements = array();
1294
                      foreach ($value as $sequence) {
1295
                          $dd_elements[] = compose_cdm_sequence($sequence, true);
1296
                          $dd_elements[] = "";
1297
                      }
1298
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $dd_elements,'', 100);
1299
                      break;
1300

    
1301
                  // TODO preservation
1302
                  case 'storedUnder':
1303
                    $taxon_name = cdm_ws_get(CDM_WS_PORTAL_NAME, array($value->uuid));
1304
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label('storedUnder'), array(
1305
                      array('#markup' => render_taxon_or_name($taxon_name, path_to_name($taxon_name->uuid)))
1306
                    ));
1307
                  break;
1308

    
1309
                  /* ---- FieldObservation --- */
1310
                  case 'gatheringEvent':
1311

    
1312
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label('collector'), $value->collector);
1313
                      @_description_list_group_add($groups, t('Gathering date'), timePeriodToString($value->timeperiod));
1314
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label('description'), $value->description);
1315
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label('locality'), $value->locality, '', 10);
1316
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label('country'), $value->country);
1317
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label('collectingMethod'), $value->collectingMethod);
1318
                      if (isset($value->absoluteElevation)) {
1319
                          $min_max_markup = statistical_values_from_gathering_event($value, 'absoluteElevation');
1320
                          @_description_list_group_add($groups, cdm_occurrence_field_name_label('absoluteElevation'), $min_max_markup);
1321
                      }
1322
                      if (isset($value->distanceToGround) && $value->distanceToGround >0) {
1323
                          $min_max_markup = statistical_values_from_gathering_event($value, 'distanceToGround');
1324
                          @_description_list_group_add($groups, cdm_occurrence_field_name_label('distanceToGround'), $min_max_markup);
1325
                      }
1326
                      if (isset($value->distanceToWaterSurface) && $value->distanceToWaterSurface > 0) {
1327
                          $min_max_markup = statistical_values_from_gathering_event($value, 'distanceToWaterSurface');
1328
                          @_description_list_group_add($groups, cdm_occurrence_field_name_label('distanceToWaterSurface'), $min_max_markup);
1329
                      }
1330

    
1331
                      if (isset($value->collectingAreas)) {
1332
                          $area_representations = array();
1333
                          foreach ($value->collectingAreas as $area) {
1334
                             // $area_representations[] = l($area->representation_L10n, path_to_named_area($area->uuid));
1335
                              $area_representations[] = $area;
1336
                          }
1337
                          if (!empty($area_representations))
1338
                              @_description_list_group_add($groups, cdm_occurrence_field_name_label('collectingAreas'),
1339
                                  array(
1340
                                      array('#markup' => implode(', ', $area_representations))
1341
                                  )
1342
                              );
1343
                      }
1344
                      if (isset($value->exactLocation)  ) {
1345
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('exactLocation'),
1346
                          array(
1347
                            array('#markup' => render_point($value->exactLocation)),
1348
                          ),'',11
1349
                        );
1350
                      }
1351
                      break;
1352

    
1353
                  /* ---- DerivationEvent --- */
1354
                  case 'derivationEvents':
1355
                    //@_description_list_group_add($groups, t('Association type'), $value->description);
1356
                    break;
1357
                  case 'determinedNames':
1358
                    $dd_elements = array();
1359
                    foreach ($value as $name) {
1360
                      $taxon_name = cdm_ws_get(CDM_WS_PORTAL_NAME, $name->uuid);
1361
                      $dd_elements[] = render_taxon_or_name($taxon_name, url(path_to_name($taxon_name->uuid)));
1362
                    }
1363
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label("Identification(s)"), $dd_elements,'', 100);
1364
                    break;
1365

    
1366
                  default:
1367
                    if (is_object($value) || is_array($value)) {
1368
                        drupal_set_message("Unhandled type in compose_cdm_specimen_or_observation_tree_entry() for field " . $field, "warning");
1369
                    } else {
1370
                      _description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value);
1371
                    }
1372
              }
1373
            }
1374
        } // END of loop over $derivedUnitFacade fields
1375

    
1376
        // template_preprocess_description_list() is not worting by weight so we do it right here
1377
        uasort($groups, 'element_sort');
1378
        $occurrence_elements = array(
1379
           // '#title' => $title,
1380
            '#theme' => 'description_list',
1381
            '#groups' => $groups,
1382
            '#attributes' => array('class' => html_class_attribute_ref($specimen_or_observation_dto)),
1383
        );
1384
        $output = drupal_render($occurrence_elements);
1385
        if (isset($gallery_html)){
1386
            $output .= $gallery_html;
1387
        }
1388
        $pathToSpecimen = path_to_specimen($specimen_or_observation_dto->uuid);
1389
        $output .=  l("Detail page", $pathToSpecimen);
1390
    } // END of $specimenOrObservation exists
1391

    
1392
    return $output;
1393
}
1394

    
1395
function compose_table_of_blast_result(array $data){
1396
   // get icon images
1397
  $expand_icon = font_awesome_icon_markup(
1398
      'fa-plus-square-o',
1399
      array(
1400
          'alt' => 'Show details',
1401
          'class' => array('expand_icon')
1402
      )
1403
  );
1404
  $collapse_icon = font_awesome_icon_markup(
1405
      'fa-minus-square-o',
1406
      array(
1407
          'alt' => 'Show details',
1408
          'class' => array('collapse_icon')
1409
      )
1410
  );
1411
  //$detail_image_icon = '<img title="Detail Image" src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/detail_image_derivate-16x16-32.png' . '"/>';
1412
    $rowcount = 0;
1413
    $rows = array();
1414

    
1415
    foreach ($data as $row_data){
1416
        $pathToSpecimen = path_to_specimen_by_accession_number($row_data['id']);
1417
        $specimenPageLink = l($row_data['id'], $pathToSpecimen);
1418
        $ncbiLink = l($row_data['id'], 'https://www.ncbi.nlm.nih.gov/nuccore/'.$row_data['id'].'?report=graph');
1419
        $rows[] =  array(
1420
            'data' => array(
1421
                array(
1422
                    'data' => $expand_icon . $collapse_icon,
1423
                    'class' => array('summary_row_cell', 'summary_row_icon', 'expand_column')
1424
                ),
1425
                array(
1426
                    'data' => $row_data['def'],
1427
                ),
1428
                array(
1429
                    'data' => $specimenPageLink,
1430
                ),
1431
                array(
1432
                    'data' => $row_data['hsp_align_length'],
1433
                ),
1434
                array(
1435
                   'data' => $ncbiLink,
1436
                ),
1437
                array(
1438
                    'data' => $row_data['hsp_identity']/$row_data['hsp_align_length']*100,
1439
                )
1440
            ),
1441
            'id' => 'blast_summary' . $rowcount, // summary row id
1442
            'class' => array('summary_row'),
1443
        );
1444
        $detail_html = "";
1445

    
1446
        $detail_html .= create_label("Details") . $row_data["hsp_align_length"] . "<br>";
1447

    
1448

    
1449
        $detail_html .= "<br>";
1450
        $detail_html .= $row_data["hsp_midline"];
1451

    
1452
        //$detail_html .= "<br>";
1453

    
1454
        $rows[] = array(
1455
            'data' => array(
1456
                array(
1457
                    'data' => "", //empty first column
1458
                    'class' => array('expand_column')
1459
                ),
1460
                array(
1461
                    'data' => $detail_html,
1462
                    'colspan' => 5,
1463
                ),
1464
            ),
1465
            'id' => 'blast_detail' . $rowcount,//details row ID
1466
            'class' => array('detail_row'),
1467
        );
1468
        $rowcount++;
1469
    }
1470

    
1471
    $tableId = "blast_result_table";
1472
    $blast_result_table = array(
1473
        "#theme" => "table",
1474
        "#weight" => 2,
1475
        "#header" => array(
1476
            array(
1477
                'data' => "",
1478
                'class' => array('expand_column')
1479
            ),
1480
                        "Name", "Accession Number", "Align Length", "NCBI", "% Identity"),
1481
        "#rows" => $rows,
1482
        "#attributes" => array(
1483
            "id" => $tableId,
1484
            "border" => 2
1485
        )
1486
    );
1487

    
1488
    drupal_add_js_rowToggle("#".$tableId);
1489

    
1490
    $render_array[$tableId] = $blast_result_table;
1491
    $out = drupal_render($render_array);
1492
   //$blast_result_page-> content = drupal_render($render_array);
1493
   return $out;
1494
}
1495

    
1496

    
1497
/**
1498
 * Composes a BOTTOM-UP-SPECIMEN-TABLE for the view mode
1499
 * CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TREE
1500
 *
1501
 * @param $specimensOrObservations
1502
 * @return array
1503
 *  A drupal render array with the following keys:
1504
 *   - 'specimen_list'
1505
 *   - 'pager'
1506
 *
1507
 * @ingroup Compose
1508
 * @see CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TREE
1509
 */
1510
function compose_specimens_table_bottom_up($specimensOrObservations)
1511
{
1512

    
1513
  // --- generate the specimen list as table
1514
  $specimen_table = array(
1515
    '#theme' => 'table',
1516
    '#weight' => 2,
1517
    // prefix attributes and rows with '#' to let it pass toF the theme function,
1518
    // otherwise it is handled as child render array
1519
    '#attributes' => array('class' => 'specimens '),
1520
    '#rows' => array(),
1521
  );
1522

    
1523
  if ($specimensOrObservations) {
1524

    
1525
    foreach ($specimensOrObservations as $specimenOrObservation) {
1526

    
1527
      $mediaList = array();
1528
      if (is_array($specimenOrObservation->_fieldObjectMedia)) {
1529
        $mediaList = array_merge($mediaList, $specimenOrObservation->_fieldObjectMedia);
1530
      }
1531
      if (is_array($specimenOrObservation->_derivedUnitMedia)) {
1532
        $mediaList = array_merge($mediaList, $specimenOrObservation->_derivedUnitMedia);
1533
      }
1534

    
1535

    
1536
      // typelabel will contain the typeStatus
1537
      $type_label = '';
1538
      $typeDesignationPager = cdm_ws_get(CDM_WS_OCCURRENCE . '/$0/specimenTypeDesignations', $specimenOrObservation->uuid);
1539
      if (isset($typeDesignationPager) and isset($typeDesignationPager->records)) {
1540
        $type_status = array();
1541
        foreach ($typeDesignationPager->records as $typeDesignation) {
1542
          if (isset($typeDesignation->typeStatus->representation_L10n)) {
1543
            $type_status[] = $typeDesignation->typeStatus->representation_L10n;
1544
          }
1545
        }
1546
        $type_label = implode(', ', $type_status);
1547
        if ($type_label) {
1548
          $type_label = ucfirst($type_label) . ': ';
1549
        }
1550
      }
1551

    
1552
      // --- Specimen entry as dynamic label:
1553
      //     -> Dynabox for the specimenOrObservation
1554
      $gallery_name = $specimenOrObservation->uuid;
1555

    
1556
      $derived_unit_ws_request = cdm_compose_ws_url(CDM_WS_OCCURRENCE, array($specimenOrObservation->uuid));
1557
      // --- Render associated media.
1558
      $gallery_html = '';
1559
      if (count($mediaList) > 0) {
1560
        $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
1561
        $captionElements = array(
1562
          '#uri' => t('open media'),
1563
        );
1564

    
1565
        $gallery_html = compose_cdm_media_gallery(array(
1566
          'mediaList' => $mediaList,
1567
          'galleryName' => $gallery_name,
1568
          'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
1569
          'cols' => $gallery_settings['cdm_dataportal_media_cols'],
1570
          'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
1571
          'captionElements' => $captionElements,
1572
          'mediaLinkType' => 'LIGHTBOX',
1573
          'alternativeMediaUri' => NULL,
1574
          'galleryLinkUri' => NULL,
1575
        ));
1576
      }
1577
      //here we should use the data we already have
1578
      $label_html = cdm_dynabox(
1579
        $specimenOrObservation->uuid,
1580
        $type_label . $specimenOrObservation->titleCache,
1581
        $derived_unit_ws_request,
1582
        'cdm_specimen_or_observation',
1583
        'Click for details',
1584
        array('div', 'div'),
1585
        array(),
1586
        null, // $content_element_selector
1587
        'function(){ jQuery(\'#media_gallery_' . $gallery_name . '\').hide(); }', // open_callback
1588
        'function(){ jQuery(\'#media_gallery_' . $gallery_name . '\').show(); }' // close_callback
1589
      );
1590

    
1591
      // --- Render associated media.
1592
      $gallery_html = '';
1593
      if (count($mediaList) > 0) {
1594
        $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
1595
        $captionElements = array(
1596
          '#uri' => t('open media'),
1597
        );
1598

    
1599
        $gallery_html = compose_cdm_media_gallery(array(
1600
          'mediaList' => $mediaList,
1601
          'galleryName' => $gallery_name,
1602
          'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
1603
          'cols' => $gallery_settings['cdm_dataportal_media_cols'],
1604
          'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
1605
          'captionElements' => $captionElements,
1606
          'mediaLinkType' => 'LIGHTBOX',
1607
          'alternativeMediaUri' => NULL,
1608
          'galleryLinkUri' => NULL,
1609
        ));
1610
      }
1611

    
1612
      $specimen_table['#rows'][] = array(
1613
        // An array of table rows. Every row is an array of cells, or an associative array
1614
        'data' => array(
1615
          // Each cell can be either a string or an associative array
1616
          $label_html . $gallery_html
1617
        ),
1618
        'class' => array(
1619
          'descriptionElement',
1620
          'descriptionElement_IndividualsAssociation'
1621
        ),
1622
      );
1623
    }
1624
  }
1625

    
1626
  return $specimen_table;
1627
}
1628

    
1629

    
1630
/**
1631
 * Orders occurrences by date but types should be on top of the list.
1632
 *
1633
 * @param array $specimens_or_observations
1634
 *  Array of SpecimenOrObservation or fieldUnitDTOs
1635
 *
1636
 * @return array
1637
 */
1638
function order_specimens_or_observations_by_date_and_type($specimens_or_observations)
1639
{
1640
  $type_specimens = array();
1641
  $other_occurrences = array();
1642
  if(is_array($specimens_or_observations)){
1643
    foreach ($specimens_or_observations as &$occurrence) {
1644
      $typeDesignationsPager = cdm_ws_get(CDM_WS_OCCURRENCE . '/$0/specimenTypeDesignations', $occurrence->uuid);
1645
      if (isset($typeDesignationsPager->count) && $typeDesignationsPager->count > 0) {
1646
        $type_specimens[] = $occurrence;
1647
      } else {
1648
        $other_occurrences[] = $occurrence;
1649
      }
1650
    }
1651
  }
1652
  $specimens_or_observations = array_merge($type_specimens, $other_occurrences);
1653
  return $specimens_or_observations;
1654
}
1655

    
1656
/**
1657
 * Orders FieldUnitDTOs by date but types should be on top of the list.
1658
 *
1659
 * Delegates internally to order_specimens_or_observations_by_date_and_type()
1660
 *
1661
 * @param array $fieldUnitDTOs
1662
 *
1663
 * @return array
1664
 */
1665
function order_fieldUnitDtos_by_date_and_type($fieldUnitDTOs)
1666
{
1667
  $units_with_types = [];
1668
  $units_no_types = [];
1669

    
1670
  foreach($fieldUnitDTOs as $dto){
1671
    if(isset($dto->specimenTypeDesignations[0])){
1672
      $units_with_types[] = $dto;
1673
    } else {
1674
      $units_no_types[] = $dto;
1675
    }
1676
  }
1677
  usort($units_with_types, 'compare_specimen_or_observation_dtos_by_date');
1678
  usort($units_no_types, 'compare_specimen_or_observation_dtos_by_date');
1679

    
1680
  return array_merge($units_with_types, $units_no_types);
1681
}
1682

    
1683
/**
1684
 * @param $specimen
1685
 *
1686
 * @return array
1687
 */
1688
function specimen_id_and_collection_for($specimen) {
1689
  $specimenID = '';
1690
  $collection = NULL;
1691
  if (!($specimen->class == 'FieldUnit')) {
1692
    if ($specimen->collection) {
1693
      if ($specimen->collection->code) {
1694
        $collection = $specimen->collection->code;
1695
      }
1696
      elseif ($specimen->collection->name) {
1697
        $collection = $specimen->collection->name;
1698
      }
1699
    }
1700
    if ($specimen->accessionNumber) {
1701
      $specimenID = $specimen->accessionNumber;
1702
    }
1703
    elseif ($specimen->barcode) {
1704
      $specimenID = $specimen->barcode;
1705
    }
1706
    elseif ($specimen->catalogNumber) {
1707
      $specimenID = $specimen->catalogNumber;
1708
    }
1709
    elseif ($specimen->titleCache) {
1710
      $specimenID = $specimen->titleCache;
1711
    }
1712
    if (!isset($specimenID) and !isset($collection)) {
1713
      $specimenID = $specimen->uuid;
1714
    }
1715
  }
1716
  else {
1717
    if ($specimen->titleCache) {
1718
      $specimenID = $specimen->titleCache;
1719
    }
1720
    if (!isset($specimenID) and !isset($collection)) {
1721
      $specimenID = $specimen->uuid;
1722
    }
1723
  }
1724
  return [$specimenID, $collection];
1725
}
1726

    
1727
/**
1728
 * Renders a cdm collection entity as html markup.
1729
 *
1730
 * institute and super-collections
1731
 *
1732
 * @param $collection_dto
1733
 *   The CollectionDTO
1734

    
1735
 * @return string
1736
 *  The markup for the collection,
1737
 */
1738
function render_collection_dto($collection_dto){
1739
  return render_collection($collection_dto);
1740
}
1741

    
1742
/**
1743
 * Renders a cdm collection entity as html markup.
1744
 *
1745
 * institute and super-collections
1746
 *
1747
 * @param $collection
1748
 *   The CDM Collection entity or CollectionDTO
1749
 * @param bool $do_link
1750
 *   Append a link to the collection page as clickable icon (default = true).
1751
 *
1752
 * @return string
1753
 *  The markup for the collection,
1754
 */
1755
function render_collection($collection, $do_link = false /* to be made true, see #9250 */ ){
1756
  if(!is_object($collection)){
1757
    return '';
1758
  }
1759
  $is_dto = $collection->class == 'CollectionDTO';
1760
  $collection_str_list = [];
1761
  $super_collection = $collection;
1762
  while($super_collection){
1763
    $collection_str = $is_dto ? $super_collection->label : $super_collection->titleCache;
1764
    if(
1765
    ($is_dto && $super_collection->institute) ||
1766
    (isset_not_empty($super_collection->institute) && isset_not_empty($super_collection->institute->titleCache))){
1767
      $collection_str .= ' at ' . ($is_dto ? $super_collection->institute : $super_collection->institute->titleCache);
1768
    }
1769
    $collection_str_list[] = $collection_str;
1770
    if(isset($super_collection->superCollection)){
1771
      $super_collection = $super_collection->superCollection;
1772
    } else {
1773
      $super_collection = null;
1774
    }
1775
  }
1776
  $markup = join(' in ', $collection_str_list);
1777
  if($markup){
1778
    if($do_link){
1779
      $markup .= ' ' . cdm_internal_link(path_to_collection($collection->uuid));
1780
    }
1781
    $markup = '<span class="' . html_class_attribute_ref($collection) . '">' . $markup . '</span>';
1782
  }
1783
  return $markup;
1784
}
1785

    
1786
/**
1787
 * Compares two SpecimenTypeDesignations by identifier and label
1788
 *
1789
 * @param object $a
1790
 *   A SpecimenOrObservationDTO.
1791
 * @param object $b
1792
 *   The SpecimenOrObservationDTO.
1793
 */
1794
function compare_specimen_or_observation_dtos($a, $b) {
1795
    // Sort alphabetically.
1796
    $a_text =  isset($a->specimenShortTitle) ? $a->specimenShortTitle : $a->label;
1797
    $b_text =  isset($b->specimenShortTitle) ? $b->specimenShortTitle : $b->label;
1798
    return strcasecmp($a_text, $b_text);
1799
}
1800

    
1801
/**
1802
 * Compares two SpecimenTypeDesignations by date or label
1803
 *
1804
 * @param object $a
1805
 *   A SpecimenOrObservationDTO.
1806
 * @param object $b
1807
 *   The SpecimenOrObservationDTO.
1808
 */
1809
function compare_specimen_or_observation_dtos_by_date($a, $b) {
1810
  // Sort alphabetically.
1811
  $a_text =  isset($a->date) ? $a->date : $a->label;
1812
  $b_text =  isset($b->date) ? $b->date : $b->label;
1813
  return strcasecmp($a_text, $b_text);
1814
}
(8-8/16)