Project

General

Profile

Download (78.8 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
 * Provides the HTML markup for a specimen page
22
 *
23
 * @param $specimen
24
 *
25
 * @return string
26
 *  The markup for a specimen page
27
 */
28
function render_cdm_specimen_page($specimen)
29
{
30

    
31
    $specimen_details = compose_cdm_specimen_or_observation($specimen, true);
32
    //$detail_html .= drupal_render($specimen_details);
33

    
34
    $specimen->_fieldObjectMedia = cdm_ws_get(CDM_WS_DERIVEDUNIT_FACADE, array(
35
        $specimen->uuid,
36
        'fieldObjectMediaDTO',
37
    ));
38
    $specimen->_derivedUnitMedia = cdm_ws_get(CDM_WS_DERIVEDUNIT_FACADE, array(
39
        $specimen->uuid,
40
        'derivedUnitMedia',
41
    ));
42
    $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
43
    $captionElements = array(
44
        'title',
45
        '#uri' => t('open media'),
46
    );
47
    if (isset($specimen->fieldObjectMediaDTO) ) {
48
        $gallery_html = compose_cdm_media_gallerie(array(
49
            'mediaList' => $specimen->fieldObjectMediaDTO,
50
            'galleryName' => $specimen->titleCache,
51
            'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
52
            'cols' => $gallery_settings['cdm_dataportal_media_cols'],
53
            'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
54
            'captionElements' => $captionElements,
55
            'mediaLinkType' => 'LIGHTBOX',
56
            'alternativeMediaUri' => NULL,
57
            'galleryLinkUri' => NULL,
58
        ));
59
        $specimen_details[] = markup_to_render_array($gallery_html);
60
    }
61

    
62
    if (isset($specimen->_derivedUnitMedia) ) {
63
        $gallery_html = compose_cdm_media_gallerie(array(
64
            'mediaList' => $specimen->_derivedUnitMedia,
65
            'galleryName' => $specimen->titleCache,
66
            'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
67
            'cols' => $gallery_settings['cdm_dataportal_media_cols'],
68
            'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
69
            'captionElements' => $captionElements,
70
            'mediaLinkType' => 'LIGHTBOX',
71
            'alternativeMediaUri' => NULL,
72
            'galleryLinkUri' => NULL,
73
        ));
74
        $specimen_details[] = markup_to_render_array($gallery_html);
75
    }
76

    
77
    $specimen_array = $specimen_details;
78
    $output = "";
79
    foreach($specimen_array as $value){
80
        $renderArray = array(
81
            '#theme' => 'item_list',
82
            '#items' => array($value),
83
            '#type' => 'ul');
84
        $output .= drupal_render($renderArray);
85
    }
86

    
87

    
88
    return $output;
89
}
90

    
91

    
92
/**
93
 * Renders a DerivedUnit either in a compact form or with full details.
94
 *
95
 * @param $derived_unit_dto
96
 *  The DerivedUnitDTO
97
 * @param $with_full_details
98
 *  Wether to render the dertived unit data with full details, like for example for the specimen page
99
 *
100
 * @return string
101
 *  The markup for a specimen page
102
 */
103
function render_cdm_specimenDTO_page($derived_unit_dto, $with_full_details = false)
104
{
105
    $detail_html = "";
106
    //link to specimen page
107
    $path_to_specimen = path_to_specimen($derived_unit_dto->uuid);
108
    if (!$with_full_details) {
109
        $specimenPageLink = l($derived_unit_dto->specimenIdentifier, $path_to_specimen);
110
        $detail_html .= "<strong>Specimen summary: $specimenPageLink</strong><br>";
111
    }
112

    
113
    if($with_full_details) {
114
        if($derived_unit_dto->summaryLabel){
115
            $detail_html .= "<br>".$derived_unit_dto->summaryLabel."<br>";
116

    
117
        }
118
    }
119
    if ($derived_unit_dto->preferredStableUri) {
120
        $stableIdentifierLink = l($derived_unit_dto->preferredStableUri, $derived_unit_dto->preferredStableUri);
121
        $detail_html .= create_label("Preferred stable URI") . $stableIdentifierLink . "<br>";
122
    }
123
    if ($with_full_details) {
124
        // associated taxa
125
        if ($derived_unit_dto->associatedTaxa) {
126
            $detail_html .= "<br>";
127
            $detail_html .= create_label("Associated with");
128
            if (sizeof($derived_unit_dto->associatedTaxa) > 1) {
129
                $detail_html .= "<br>";
130
            }
131
            foreach ($derived_unit_dto->associatedTaxa as $associatedTaxon) {
132
                $detail_html .= l($associatedTaxon->label, path_to_taxon($associatedTaxon->uuid, "specimens"));//$associatedTaxon->second."<br>";
133
            }
134
            $detail_html .= "<br>";
135
        }
136
    }
137
    // - type information
138
    $types = "";
139
    if (isset($derived_unit_dto->types)) {
140
        //typed taxa
141
        foreach ($derived_unit_dto->types as $typeStatus => $typedTaxa) {
142
            if($derived_unit_dto->types){
143
                if(empty($typeStatus) || $typeStatus == "_empty_"|| $typeStatus == ""){
144
                    $detail_html .= "<i>Type for:</i> ";
145
                } else {
146
                    $detail_html .= "<i>".ucfirst($typeStatus)."</i> of ";
147
                }
148
                foreach($typedTaxa as $typedTaxon){
149
                    $detail_html .= $typedTaxon." ";
150

    
151
                }
152
            } else {
153
                $types .= $typeStatus . " ";
154
            }
155
           $detail_html .= '<br>';
156
        }
157
    }
158
    $derivation_tree_summary_dto = $derived_unit_dto->derivationTreeSummary;
159
    // - specimen scans
160
    $specimenScans = create_html_links($derivation_tree_summary_dto->specimenScans, true);
161
    // - molecular data
162
    $molecularData = "";
163
    if ($derivation_tree_summary_dto->molecularDataList) {
164
        foreach ($derivation_tree_summary_dto->molecularDataList as $molecular) {
165
            //provider link
166
            if (isset($molecular->providerLink)) {
167
                $molecularData .= create_html_link($molecular->providerLink, true);
168
            } else {
169
                $molecularData .= "[no provider]";
170
            }
171
            //contig link
172
            if (isset($molecular->contigFiles)) {
173
                $molecularData .= "[";
174
                if (sizeof($molecular->contigFiles) > 0) {
175
                    foreach ($molecular->contigFiles as $contigFile) {
176
                        if (isset($contigFile->contigLink)) {
177
                            if (isset($contigFile->contigLink->uri) and $contigFile->contigLink->uri != null) {
178
                                $molecularData .= create_html_link($contigFile->contigLink, true) . " ";
179
                            }
180
                        } else {
181
                            $molecularData .= "no contig ";
182
                        }
183
                        //primer links
184
                        if (isset($contigFile->primerLinks)) {
185
                            $molecularData .= create_html_links($contigFile->primerLinks, true);
186
                        }
187
                    }
188
                }
189
                $molecularData = rtrim($molecularData, " ");
190
                $molecularData .= "]";
191
            }
192
            //FIXME separate with comma (remove trailing comma)
193
        }
194
    }
195
    // - detail images
196
    $detailImages = create_html_links($derivation_tree_summary_dto->detailImages, true);
197

    
198
    if ($types) {
199
        $detail_html .= $with_full_details ? "<br>" : "";
200
        $detail_html .= create_label("Type(s)") . $types . "<br>";
201
    }
202
    if ($specimenScans and !$with_full_details) {
203
        $detail_html .= create_label("Specimen Scans") . $specimenScans . "<br>";
204
    }
205
    //specimen scan image gallery
206
    if ($with_full_details and isset($derivation_tree_summary_dto->specimenScanUuids) and !empty($derivation_tree_summary_dto->specimenScanUuids)) {
207
        $detail_html .= addImageGallery("Specimen scans", $derivation_tree_summary_dto->specimenScanUuids);
208
    }
209

    
210
    if ($molecularData) {
211
        $detail_html .= $with_full_details ? "<br>" : "";
212
        $detail_html .= create_label("Molecular Data") . $molecularData . "<br>";
213
    }
214

    
215
    if ($detailImages and !$with_full_details) {
216
        $detail_html .= create_label("Detail Images") . $detailImages . "<br>";
217
    }
218

    
219
    //detail image gallery
220
    if ($with_full_details and isset($derivation_tree_summary_dto->detailImageUuids) and !empty($derivation_tree_summary_dto->detailImageUuids)) {
221
        $detail_html .= addImageGallery("Detail Images", $derivation_tree_summary_dto->detailImageUuids);
222
    }
223

    
224
    //character data
225
    if ($derived_unit_dto->characterData) {
226
        $detail_html .= $with_full_details ? "<br>" : "";
227
        $detail_html .= create_label("Character Data");
228
        if ($with_full_details) {
229
            $detail_html .= "<br>";
230
            foreach ($derived_unit_dto->characterData as $characterStatePair) {
231
                $detail_html .= "<i>" . $characterStatePair->first . "</i>:" . $characterStatePair->second;
232
                $detail_html .= "<br>";
233
        }
234
        } else {
235
            $detail_html .= l("detail page", $path_to_specimen);
236
            $detail_html .= "<br>";
237
        }
238
    }
239
    return $detail_html;
240
}
241

    
242
function addImageGallery($galleryName, $imageUuids)
243
{
244
    $images = array();
245
    foreach ($imageUuids as $uuid) {
246
        $images[] = cdm_ws_get(CDM_WS_PORTAL_MEDIA, $uuid);
247
    }
248

    
249
    $gallery_html = '';
250
    if (count($imageUuids) > 0) {
251
        $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
252
        $captionElements = array(
253
            'title',
254
            'rights',
255
        );
256
        $alternativeMediaUris = array();
257
        foreach ($images as $image) {
258
            $mediaUri = getMediaUri($image);
259
            if ($mediaUri) {
260
                $alternativeMediaUris[] = $mediaUri;
261
            } else {
262
                $alternativeMediaUris[] = path_to_media($image->uuid);
263
            }
264
        }
265

    
266

    
267

    
268
        $gallery_html = compose_cdm_media_gallerie(array(
269
            'mediaList' => $images,
270
            'galleryName' => $galleryName,
271
            'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
272
            'cols' => $gallery_settings['cdm_dataportal_media_cols'],
273
            'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
274
            'captionElements' => $captionElements,
275
            'mediaLinkType' => 'LIGHTBOX',
276
          // 'alternativeMediaUri' => $alternativeMediaUris,
277
            'alternativeMediaUri' => NULL,
278
            'galleryLinkUri' => NULL,
279
        ));
280
    }
281
    return "<br>" . create_label($galleryName) . "<br>" . $gallery_html;
282
}
283

    
284
function getMediaUri($media)
285
{
286
    if (isset($media->representations) && sizeof($media->representations) == 1
287
        && isset($media->representations[0]->parts) &&
288
        sizeof($media->representations[0]->parts) == 1) {
289
        return $media->representations[0]->parts[0]->uri;
290
    }
291
    return null;
292
}
293

    
294

    
295
/**
296
 * Formats the given string to a label for displaying key-object pairs in HTML
297
 * @return string
298
 */
299
function create_label($label)
300
{
301
    return "<span class='specimen_table_label'>" . $label . ": </span>";
302
}
303

    
304
/**
305
 * Provides a humane representation for an occurrence or observation field name.
306
 * @param string $field
307
 *    The field name.
308
 * @return string
309
 *    The label for the fieldname.
310
 */
311
function cdm_occurrence_field_name_label($field){
312

    
313
  static $field_labels = array(
314
    'class' => 'Basis of Record',
315
    'fieldNumber' => 'Collecting number',
316
    'absoluteElevation' => 'Altitude',
317
    'absoluteElevationMinimum' => 'Altitude maximum',
318
    'absoluteElevationMaximum' => 'Altitude minimum',
319
    'getGatheringPeriod' => 'Gathering period'
320
  );
321

    
322
  if(str_endsWith($field,'_L10n')){
323
    $field = str_replace('_L10n', '', $field );
324
  }
325
  if (isset($field_labels[$field])) {
326
    $field = $field_labels[$field];
327
  }
328

    
329
  $field = preg_replace_callback(
330
    '/([a-z])([A-Z])/',
331
    function ($m) {
332
      return $m[1] . ' ' . strtolower ($m[2]);
333
    },
334
    $field);
335

    
336
  return t('@field-name:', array('@field-name' => ucfirst($field)));
337
}
338

    
339
/**
340
 * Compose an render array from a CDD SpecimenOrObservation entity.
341
 *
342
 * compose_hook() implementation
343
 *
344
 * @param object $specimen_or_observation
345
 *   the CDM FieldUnit or DerivedUnit to compose
346
 *   the render array for.
347
 * @param bool $isSpecimen_page
348
 * @param array $derivatives
349
 *   the render array which contains the compositions of the derivatives
350
 *   of the supplied $specimenOrObservation
351
 *
352
 * @return array
353
 *   the supplied render array $derivatives to which the composition of the supplied
354
 *   $specimenOrObservation has been added to
355
 *
356
 * @throws \Exception
357
 * @ingroup compose
358
 */
359

    
360
function compose_cdm_specimen_or_observation($specimen_or_observation, $isSpecimen_page = false, &$derivatives = null)
361
{
362
    $exclude_occurrence_fields = &drupal_static(__FUNCTION__);
363
    if (!isset($exclude_occurrence_fields)) {
364
        $exclude_occurrence_fields = array(
365
            'uuid',
366
            'titleCache',
367
            'protectedTitleCache',
368
            'derivedUnitMedia',
369
            'created',
370
            'publish',
371
            'updated',
372
            'class',
373
            'collectionCode'
374
        );
375
    }
376
    if ((variable_get(CDM_SPECIMEN_LIST_VIEW_MODE, CDM_SPECIMEN_LIST_VIEW_MODE_DEFAULT) == CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TABLE) || !$isSpecimen_page){
377
        $exclude_occurrence_fields[] = 'derivationEvents';
378
    }
379

    
380
    if (!isset($derivatives)) {
381
        $derivatives = array();
382
    }
383
    $descriptions = null;
384
    $derivedFrom = null;
385

    
386
    if (is_object($specimen_or_observation)) {
387

    
388
        // request again for deeper initialization
389
        $specimen_or_observation = cdm_ws_get("portal/" . CDM_WS_OCCURRENCE, $specimen_or_observation->uuid);
390
        if ($specimen_or_observation->class == 'FieldUnit'){
391
            // WARNING: adding a List<MediaDTO> as $specimen_or_observation->_derivedUnitMedia
392
            $specimen_or_observation->_derivedUnitMedia = cdm_ws_get(CDM_WS_DERIVEDUNIT_FACADE, array(
393
                $specimen_or_observation->uuid,
394
                'fieldObjectMediaDTO',
395
            ));
396
        }else{
397
            // WARNING: adding a List<Media> as $specimen_or_observation->_derivedUnitMedia
398
            $specimen_or_observation->_derivedUnitMedia = cdm_ws_get(CDM_WS_DERIVEDUNIT_FACADE, array(
399
                $specimen_or_observation->uuid,
400
                'derivedUnitMedia',
401
            ));
402
        }
403

    
404
        $type_label = $specimen_or_observation->class;
405
        RenderHints::setFootnoteListKey($type_label . '-' . $specimen_or_observation->uuid);
406

    
407
        // collect typeStatus as label
408
        if (isset($specimen_or_observation->specimenTypeDesignations)) {
409
            $type_status = array();
410
            foreach ($specimen_or_observation->specimenTypeDesignations as $typeDesignation) {
411
                if (isset($typeDesignation->typeStatus_L10n)) {
412
                    $type_status[] = $typeDesignation->typeStatus_L10n;
413
                }
414
            }
415
            if (count($type_status) > 0) {
416
                $type_label = implode(', ', $type_status);
417
            }
418
        }
419

    
420
        $title = $type_label . ': ' . $specimen_or_observation->titleCache;
421

    
422
        $groups = array();
423

    
424
        // --- add initialized fields
425
        foreach (get_object_vars($specimen_or_observation) as $field => $value) {
426
            if (!in_array($field, $exclude_occurrence_fields) && ($value && ($field == 'recordBasis' || !is_object($value) || isset($value->class)))) {
427
                switch ($field) {
428

    
429
                  case 'recordBasis':
430
                    $label = $value->message_L10n;
431
                    if($label == 'Dna Sample'){
432
                      $label == 'DNA Sample';
433
                    }
434
                    _description_list_group_add($groups, cdm_occurrence_field_name_label($field), $label,NULL, -10);
435
                    break;
436

    
437
                    /* ---- java.lang.Object --- */
438
                    case 'class':
439
                        if ($value != '' /* FieldUnit' */) {
440
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value);
441
                        }
442
                        break;
443

    
444
                    case 'markers':
445
                        $dd_elements = array();
446
                        foreach ($value as $marker) {
447
                            $dd_elements[] = compose_cdm_marker($marker);
448
                        }
449
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $dd_elements);
450
                        break;
451

    
452

    
453
                    case 'annotations':
454
                        $dd_elements = array();
455
                        foreach ($value as $annotation) {
456
                            // TODO respect annotation type filter settings
457
                            $dd_elements[] = $annotation->text;
458
                        }
459
                        @_description_list_group_add($groups, t('Notes:'), $dd_elements);
460
                        break;
461

    
462
                    /* ---- SpecimenOrObservationBase --- */
463
                    case 'sex':
464
                    case 'lifeStage':
465
                    case 'kindOfUnit':
466
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value->representation_L10n);
467
                        break;
468

    
469
                    case 'definition':
470
                        // TODO
471
                        break;
472

    
473
                    case 'preferredStableUri':
474

    
475
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), array(array('#markup' => cdm_external_uri($value, false))));
476
                        break;
477

    
478
                    case 'specimenTypeDesignations':
479

    
480
                        //TODO: better display of details!!
481
                        @_description_list_group_add(
482
                            $groups,
483
                            cdm_occurrence_field_name_label($field),
484
                            array(
485
                                '#markup' => render_type_designations($value),
486
                            )
487
                        );
488
                        break;
489

    
490
                    case 'determinations':
491
                        $dd_elements = array();
492
                        $glue = ', ';
493

    
494
                        foreach ($value as $determinationEvent) {
495
                            $timeperiod_string = NULL;
496
                            if (isset($determinationEvent->timeperiod)) {
497
                                $timeperiod_string = timePeriodToString($determinationEvent->timeperiod);
498
                            }
499
                            $weight = isset($determinationEvent->preferred) && $determinationEvent->preferred == 1 ? '0' : ($timeperiod_string ? $timeperiod_string : '1');
500
                            // check key exists
501
                            while (array_key_exists($weight, $dd_elements)) {
502
                                $weight .= '0';
503
                            }
504

    
505
                            $taxon_name = '';
506
                            $name_link = '';
507
                            if ($determinationEvent->taxonName) {
508
                                $taxon_name = cdm_ws_get(CDM_WS_NAME, $determinationEvent->taxonName->uuid);
509
                                $taxon_name->taggedName = cdm_ws_get(CDM_WS_NAME, array($determinationEvent->taxonName->uuid, "taggedName"));
510
                                $name_link = path_to_name($determinationEvent->taxonName->uuid);
511
                            } else if ($determinationEvent->taxon) {
512
                                $taxon_name = cdm_ws_get(CDM_WS_TAXON . '/$0/name', $determinationEvent->taxon->uuid);
513
                                $name_link = path_to_taxon($determinationEvent->taxon->uuid);
514
                            }
515
                            if ($taxon_name) {
516
                                //$taxon_html = render_taxon_or_name($taxon_name, $name_link);
517

    
518
                                $taxon_html = l($taxon_name->titleCache, $name_link);
519
                                $dd_elements[$weight] = $taxon_html;
520
                            }
521
                            if (isset($determinationEvent->modifier)) {
522
                                $dd_elements[$weight] .= cdm_term_representation($determinationEvent->modifier);
523
                            }
524
                            if ($timeperiod_string) {
525
                                $dd_elements[$weight] .= $glue . $timeperiod_string;
526
                            }
527
                            if (isset($determinationEvent->actor->titleCache)) {
528
                                $dd_elements[$weight] .= $glue . $determinationEvent->actor->titleCache;
529
                            }
530
                            if (isset($determinationEvent->description)) {
531
                                $dd_elements[$weight] .= $glue . $determinationEvent->description;
532
                            }
533
                        }
534
                        ksort($dd_elements);
535
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('determinations'), $dd_elements);
536
                        break;
537

    
538
                    case 'descriptions':
539
                        $dd_elements = array();
540
                        foreach ($value as $description) {
541
                            $description = cdm_ws_get(CDM_WS_PORTAL_DESCRIPTION, $description->uuid);
542

    
543
                            if ($description->imageGallery == TRUE) {
544
                                continue;
545
                            }
546
                            $description_string = render_description_string(get_root_nodes_for_dataset($description));
547
                            $dd_elements[] = markup_to_render_array($description_string);
548
                        }
549
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $dd_elements);
550
                        break;
551
                    case '_derivedUnitMedia':
552
                        if ($isSpecimen_page) {
553
                            $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
554
                            $captionElements = array(
555
                                '#uri' => t('open media'),
556
                            );
557
                            $gallery_html = compose_cdm_media_gallerie(array(
558
                                'mediaList' => $value, // WARNING: this is either a List<Media> or List<MediaDTO>, see above ~line 361
559
                                'galleryName' => $specimen_or_observation->titleCache,
560
                                'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
561
                                'cols' => $gallery_settings['cdm_dataportal_media_cols'],
562
                                'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
563
                                'captionElements' => $captionElements,
564
                                'mediaLinkType' => 'LIGHTBOX',
565
                                'alternativeMediaUri' => NULL,
566
                                'galleryLinkUri' => NULL,
567
                            ));
568
                            @_description_list_group_add($groups, "Detail Images:", markup_to_render_array($gallery_html), '', 20);
569
                        }
570

    
571
                        // $dd_elements[] = markup_to_render_array($gallery_html);
572

    
573
                        break;
574
                    case 'sources':
575
                        RenderHints::setAnnotationsAndSourceConfig([
576
                          'sources_as_content' => TRUE,
577
                          'link_to_name_used_in_source' => TRUE,
578
                          'link_to_reference' => FALSE,
579
                          'add_footnote_keys' => FALSE,
580
                          'bibliography_aware' => FALSE
581
                        ]);
582
                        $annotations_and_sources = handle_annotations_and_sources($specimen_or_observation);
583
                        if ($annotations_and_sources->hasSourceReferences()) {
584
                            @_description_list_group_add($groups, t('Sources') . ':', join(', ', $annotations_and_sources->getSourceReferences()), '', 12);
585
                        }
586
                        break;
587

    
588

    
589
                    /* ---- DerivedUnitBase --- */
590
                    case 'derivedFrom':
591
                        $derivedFrom = $value;
592
                        if ($isSpecimen_page) {
593
                            foreach ($derivedFrom->originals as $original) {
594
                                $pathToSpecimen = path_to_specimen($original->uuid);
595
                                $description = "";
596
                                if (isset($derivedFrom->description) && $derivedFrom->description != '') {
597
                                    $description = $derivedFrom->description . ": ";
598
                                }
599

    
600
                                $originals[] = markup_to_render_array(l($description . $original->titleCache, $pathToSpecimen));
601
                                if ($original->class == 'FieldUnit') {
602
                                    $label = t('Field data');
603
                                } else {
604
                                    $label = t('Derived from');
605
                                }
606
                                @_description_list_group_add($groups, $label . ':',
607
                                    $originals,
608
                                    '', 13);
609
                            }
610
                        }
611
                        break;
612
                    case 'derivationEvents':
613
                        $derivationEvents = $value;
614
                        $derived_units = array();
615
                        if ($isSpecimen_page) {
616
                            foreach ($derivationEvents as $derivationEvent) {
617
                                foreach ($derivationEvent->derivatives as $derived_unit) {
618
                                    $pathToSpecimen = path_to_specimen($derived_unit->uuid);
619
                                    $description = "";
620
                                    if (isset($derived_unit->description) && $derived_unit->description != '') {
621
                                        $description = $derived_unit->description . ": ";
622
                                    }
623

    
624
                                    $derived_units[] = markup_to_render_array(l($description . $derived_unit->titleCache, $pathToSpecimen));
625
                                }
626
                            }
627
                            @_description_list_group_add($groups, t('Derivatives') . ':',
628
                                $derived_units,
629
                                '', 100);
630

    
631
                        }
632
                        break;
633

    
634
                    case 'collection':
635
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), array(
636
                          array('#markup' => render_collection($value))
637
                        ));
638
                        break;
639

    
640
                    case 'storedUnder':
641
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('storedUnder'), array(
642
                          array('#markup' => render_taxon_or_name($value))
643
                        ));
644
                        break;
645
                    case 'dnaQuality':
646
                        $sub_dl_groups = array();
647

    
648
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('purificationMethod'), $value->purificationMethod, NULL, 1);
649
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('ratioOfAbsorbance260_230'), $value->ratioOfAbsorbance260_230, NULL, 2);
650
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('ratioOfAbsorbance260_280'), $value->ratioOfAbsorbance260_280, NULL, 3);
651
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('concentration'), $value->concentration, NULL, 4);
652
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('concentrationUnit'), $value->concentrationUnit, NULL, 4);
653
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('qualityTerm'), $value->qualityTerm, NULL, 4);
654
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('qualityCheckDate'), $value->qualityCheckDate, NULL, 4);
655

    
656
                        if (is_array($sub_dl_groups) && sizeof($sub_dl_groups)>0) {
657
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label($field),
658
                                array(
659
                                    array('#markup' => $value->titleCache),
660
                                    array('#theme' => 'description_list', '#groups' => $sub_dl_groups)
661
                                )
662
                            );
663
                        }
664
                        break;
665

    
666
                    case 'preservation':
667
                        $sub_dl_groups = array();
668

    
669
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('medium'), $value->medium, NULL, 1);
670
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('temperature'), $value->temperature, NULL, 2);
671
                        @_description_list_group_add($sub_dl_groups, cdm_occurrence_field_name_label('definedMaterialOrMethod'), $value->definedMaterialOrMethod, NULL, 3);
672

    
673
                        if (is_array($sub_dl_groups) && sizeof($sub_dl_groups)>0) {
674
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label($field),
675
                                array(
676
                                    array('#markup' => $value->titleCache),
677
                                    array('#theme' => 'description_list', '#groups' => $sub_dl_groups)
678
                                )
679
                            );
680
                        }
681
                        break;
682

    
683
                    /* ---- Specimen --- */
684
                    case 'sequences':
685
                        $dd_elements = array();
686
                        foreach ($value as $sequence) {
687
                            $dd_elements[] = compose_cdm_sequence($sequence);
688
                        }
689
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $dd_elements);
690
                        break;
691

    
692
                    // TODO preservation
693
                    // TODO exsiccatum
694

    
695

    
696
                    /* ---- FieldObservation --- */
697
                    case 'gatheringEvent':
698
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('collector'), $value->actor->titleCache, '', 1);
699
                        @_description_list_group_add($groups, t('Gathering date'), timePeriodToString($value->timeperiod), '', 2);
700
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('description'), $value->description, '', 3);
701
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('locality'), $value->locality->text, '', 10);
702
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('country'), $value->country->representation_L10n, '', 4);
703
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('collectingMethod'), $value->collectingMethod,'',5);
704
                        if (isset($value->absoluteElevation)) {
705
                            $min_max_markup = statistical_values_from_gathering_event($value, 'absoluteElevation');
706
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label('absoluteElevation'), $min_max_markup, '',6);
707
                        }
708
                        if (isset($value->distanceToGround)) {
709
                            $min_max_markup = statistical_values_from_gathering_event($value, 'distanceToGround');
710
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label('distanceToGround'), $min_max_markup,'',7);
711
                        }
712
                        if (isset($value->distanceToWaterSurface)) {
713
                            $min_max_markup = statistical_values_from_gathering_event($value, 'distanceToWaterSurface');
714
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label('distanceToWaterSurface'), $min_max_markup, '',8);
715
                        }
716
                        if (isset($value->collectingAreas) && count($value->collectingAreas) > 0) {
717
                            $area_representations = array();
718
                            foreach ($value->collectingAreas as $area) {
719
                                $area_representations[] = l($area->representation_L10n, path_to_named_area($area->uuid));
720
                            }
721
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label('collectingAreas'),
722
                                array(
723
                                    array('#markup' => implode(', ', $area_representations))
724
                                ),'',9
725
                            );
726
                        }
727
                        if ($value->exactLocation->sexagesimalString) {
728
                            @_description_list_group_add($groups, cdm_occurrence_field_name_label('exactLocation'),
729
                                array(
730
                                    array('#markup' => render_point($value->exactLocation)),
731

    
732
                                ),'',11
733
                            );
734
                        }
735
                        break;
736

    
737
                    default:
738
                        if (is_object($value) || is_array($value)) {
739
                            drupal_set_message("Unhandled type in compose_cdm_specimen_or_observation() for field " . $field, "warning");
740
                        } else {
741
                            if ($field == 'RecordBase' && $value == 'DnaSample') {
742
                                _description_list_group_add($groups, cdm_occurrence_field_name_label($field), 'DNA Sample');
743
                            } else {
744
                                _description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value);
745
                            }
746
                        }
747

    
748
                }
749

    
750
            }
751
        } // END of loop over $derivedUnitFacade fields
752

    
753
        // Extensions
754
        // TODO: filter by using visible_extensions_sorted()
755
        // TODO: treat as top level element, see https://dev.e-taxonomy.eu/redmine/issues/2985#note-23
756
        $extensions = cdm_ws_fetch_all(CDM_WS_PORTAL_OCCURRENCE . '/'  . $specimen_or_observation->uuid . '/extensions', array($specimen_or_observation->uuid));
757
        if ($extensions && count($extensions)) {
758

    
759
            $extensions_render_array = compose_extensions($extensions);
760
            @_description_list_group_add($groups, t('Extensions') . ':',
761
                $extensions_render_array,
762
                '', 100);
763
        }
764

    
765

    
766

    
767
        // template_preprocess_description_list() is not worting by weight so we do it right here
768
        uasort($groups, 'element_sort');
769

    
770
        $occurrence_elements = array(
771
           // '#title' => $title,
772
            '#theme' => 'description_list',
773
            '#groups' => $groups,
774
            '#attributes' => array('class' => html_class_attribute_ref($specimen_or_observation)),
775
        );
776

    
777
        $derivatives[] = $occurrence_elements;
778
        // all footnotes which has been assembled so far (e.g. from typeDesignations) to here
779
//       $foonote_li_elements = render_footnotes(RenderHints::getFootnoteListKey(), 'span');
780
//        if (!empty($foonote_li_elements)) {
781
//            $derivatives[] =  array(
782
//                '#markup' =>  '<div class="footnotes">' . $foonote_li_elements . '</div>',
783
//            );
784
//        }
785

    
786
        // --- recurse into originals
787
        if (!isset($derivedFrom)  && !$isSpecimen_page) {
788
            $derivedFrom = cdm_ws_get(
789
                CDM_WS_OCCURRENCE,
790
                array($specimen_or_observation->uuid, 'derivedFrom')
791
            );
792
        }
793
        if (isset($derivedFrom) && !$isSpecimen_page) {
794
            if (isset($derivedFrom->originals)) {
795
                $derived_from_label = t('derived');
796
                $preposition = t('from');
797
                if(isset($derivedFrom->type)){
798
                    $derived_from_label = $derivedFrom->type->representation_L10n;
799
                    if($derivedFrom->type->uuid == UUID_DERIVATIONEVENTTYPE_ACCESSIONING){
800
                        $preposition = t('of');
801
                    }
802
                }
803
                if (count($groups) > 0) {
804
                    // TODO  annotations
805

    
806
                    // only display the derived from information when the derivative has any element which will be diplayed
807
                    $derivatives[] = array(
808
                        '#markup' => '<div class="derived_from">' . $derived_from_label . ' ' . $preposition . ': </div>',
809
                    );
810
                }
811
                foreach ($derivedFrom->originals as $original) {
812
                    compose_cdm_specimen_or_observation($original, $isSpecimen_page, $derivatives);
813
                }
814
            }
815
        }
816

    
817

    
818

    
819

    
820
    } // END of $specimenOrObservation exists
821

    
822
    return $derivatives;
823
}
824

    
825

    
826
/**
827
 * Compose an render array from a CDM Sequence object.
828
 *
829
 * compose_hook() implementation
830
 *
831
 * @param object $sequence
832
 *   CDM instance of type Sequence
833
 * @return array
834
 *   A render array containing the fields of the supplied $sequence
835
 *
836
 * @ingroup compose
837
 */
838
function compose_cdm_sequence($sequence, $isSpecimenPage = false)
839
{
840

    
841
    $exclude_sequence_fields = &drupal_static(__FUNCTION__);
842
    if (!isset($exclude_sequence_fields)) {
843
        $exclude_sequence_fields = array(
844
            'titleCache',
845
            'protectedTitleCache',
846
            'microReference',
847
            'created',
848
            'updated',
849
            'class',
850
        );
851
    }
852

    
853
    $groups = array();
854

    
855
    // -- retrieve additional data if necessary
856
    // TODO below call disabled since sequences are not yet supported,
857
    //      see  #3347 (services and REST service controller for molecular classes implemented)
858
    //
859
    // cdm_load_annotations($sequence);
860

    
861
    foreach (get_object_vars($sequence) as $field => $value) {
862

    
863

    
864
        if (!in_array($field, $exclude_sequence_fields) && ($value && (!is_object($value) || isset($value->class)))) {
865
            switch ($field) {
866

    
867
                case 'geneticAccessionNumber';
868

    
869
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value, NULL, 2);
870
                    break;
871

    
872

    
873
                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.
874
                    if (isset($value->name)) {
875
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value->name, NULL, 3);
876
                    }
877
                    if (isset($value->description)) {
878
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label($field) . ' ' . t('description'), $value->description, NULL, 4);
879
                    }
880
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field) , $value, NULL, 4);
881
                    break;
882

    
883
                case 'consensusSequence':
884
                    // format in genbank style, force linebreaks after each 70 nucleotites
885
                    // see also http://stackoverflow.com/questions/499137/css-how-can-i-force-a-long-string-without-any-blank-to-be-wrapped-in-xul-and
886
                    if ($value->length > 0) {
887
                        @_description_list_group_add(
888
                            $groups,
889
                            cdm_occurrence_field_name_label($field),
890
                            array(
891
                                array(
892
                                    '#markup' => '<div class="sequence-length">' . $value->length . ' ' . t('pb') . '</div><div>' . wordwrap($value->string, 70, '</br>', TRUE) . '</div>',
893
                                    '#wrapper_attributes' => array('class' => 'dna-sequence')
894
                                )
895
                            ),
896
                            5);
897
                    }
898
                    break;
899

    
900
                case 'dnaSample': // FIXME 3.3 implement
901
                    break;
902
                case 'singleReads': // FIXME 3.3 implement
903
                    break;
904
                case 'contigFile': // FIXME 3.3 implement - Media
905
                    break;
906
                case 'pherograms': // FIXME 3.3 implement - Media
907
                    break;
908
                case 'haplotype': // FIXME 3.3 implement
909
                    break;
910
                case 'dateSequenced': // FIXME 3.3 now in SingelRead
911
                    @_description_list_group_add($groups, t('Sequencing date'), timePeriodToString($value), NULL, 6);
912
                    break;
913

    
914
                case 'barcode': // boolean
915
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value ? 'Yes' : 'No', NULL, 7);
916
                    break;
917
                case 'barcodeSequencePart': // FIXME 3.3 implement, compose sequence
918
                    break;
919

    
920
                case 'citation':
921
                    @_description_list_group_add($groups,
922
                        cdm_occurrence_field_name_label($field),
923
                        cdm_reference_markup($value, $sequence->microReference),
924
                        NULL,
925
                        8
926
                    );
927
                    break;
928

    
929
                case 'publishedIn':
930
                    @_description_list_group_add($groups,
931
                        cdm_occurrence_field_name_label($field),
932
                        theme('cdm_reference', array('reference' => $value)),
933
                        NULL,
934
                        7
935
                    );
936
                    break;
937

    
938
                case 'rights':
939
                    array_merge($groups, cdm_rights_as_dl_groups($value));
940
                    break;
941

    
942
                case 'annotations':
943
                    $dd_elements = array();
944
                    foreach ($value as $annotation) {
945
                        // TODO respect annotation type filter settings
946
                        $dd_elements[] = $annotation->text;
947
                    }
948
                    @_description_list_group_add($groups, t('Notes'), $dd_elements, NULL, 9);
949
                    break;
950

    
951
                case 'markers':
952
                    $dd_elements = array();
953
                    foreach ($value as $marker) {
954
                        $dd_elements[] = compose_cdm_marker($marker);
955
                    }
956
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $dd_elements, NULL, 10);
957
                    break;
958

    
959
                case 'chromatograms':
960
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field),
961
                        array(
962
                            '#markup' => compose_cdm_media_gallerie(array('medialist' => $value)),
963
                        ),
964
                        NULL,
965
                        11);
966
                    break;
967

    
968
                default:
969
                    if (is_object($value) || is_array($value)) {
970
                        drupal_set_message("Unhandled type in compose_cdm_sequence() for field " . $field, "warning");
971
                    } else {
972
                        if (!is_array($value) && strpos($value, 'http:') !== false ){
973
                            //make links for urls
974
                            $value = l($value, $value);
975
                            $value = markup_to_render_array($value);
976
                        }
977

    
978
                       _description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value, NULL, 20);
979
                    }
980
            }
981
        }
982
    }
983

    
984
    // template_preprocess_description_list() is not worting by weight so we do it right here
985
    uasort($groups, 'element_sort');
986
    if ($isSpecimenPage) {
987
        $sequence_elements = array(
988
            '#title' => $sequence->dnaMarker,
989
            '#theme' => 'description_list',
990
            '#groups' => $groups
991
        );
992
    } else{
993
        $sequence_elements = array(
994
            '#title' => $sequence->dnaMarker -> titleCache,
995
            '#theme' => 'description_list',
996
            '#groups' => $groups
997
        );
998
    }
999

    
1000
    return $sequence_elements;
1001
}
1002

    
1003
/**
1004
 * Creates render array items for FieldUnitDTO or DerivedUnitDTO.
1005
 *
1006
 * @param array $root_unit_dtos
1007
 *     list of SpecimenOrObservationDTOs
1008
 * @return array
1009
 *    An array which can be used in render arrays to be passed to the
1010
 * theme_table() and theme_list().
1011
 */
1012
function specimen_render_array_items(array $root_unit_dtos){
1013

    
1014
  $render_array_items = array();
1015
  $items = array();
1016

    
1017
  //we need one more item to contain the items of one level (fieldunit, derivate data etc.)
1018
  foreach ($root_unit_dtos as &$sob_dto) {
1019
    $items['data'] = $sob_dto->label;
1020
    $specimen = compose_cdm_specimen_or_observation_tree_entry($sob_dto);
1021
    $children = array();
1022
    $child = array();
1023
    $child['data'] =$specimen;
1024
    // $children[] = create_specimen_array($specimenOrObservation->derivatives);
1025
    if (isset($sob_dto->derivatives) && sizeof($sob_dto->derivatives) > 0){
1026
      usort($sob_dto->derivatives, 'compare_specimen_or_observation_dtos');
1027
      $child['children']= specimen_render_array_items($sob_dto->derivatives);
1028
    }
1029
    $children[]=$child;
1030
    $items['children'] = $children;
1031
    $render_array_items[] = $items;
1032
  }
1033
  return $render_array_items;
1034
}
1035

    
1036
/**
1037
 * Composes a compressed derivate table showing all derivatives which
1038
 * stem from a common gathering event.
1039
 *
1040
 * @param $root_unit_uuids array
1041
 *  An array of uuids for cdm root units of the derivation graphs.
1042
 *
1043
 * @return array
1044
 *  A drupal render array for a table
1045
 *
1046
 * @see CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TABLE
1047
 *
1048
 * @ingroup compose
1049
 */
1050

    
1051
function compose_compressed_specimen_derivate_table($root_unit_uuids) {
1052

    
1053
  // prepare font icons
1054
  $expand_icon = font_awesome_icon_markup(
1055
    'fa-plus-square-o',
1056
    array(
1057
      'alt' => 'Show details',
1058
      'class' => array('expand_icon')
1059
    )
1060
  );
1061
  $collapse_icon = font_awesome_icon_markup(
1062
    'fa-minus-square-o',
1063
    array(
1064
      'alt' => 'Show details',
1065
      'class' => array('collapse_icon')
1066
    )
1067
  );
1068
  $detail_image_icon = '<img title="Detail Image" src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/detail_image_derivate-16x16-32.png' . '"/>';
1069
  $checked_box_icon = '<img src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/step_done.gif' . '"/>';
1070
  $sequence_icon = '<img title="Molecular Data" src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/sequence_derivate-16x16-32.png' . '"/>';
1071
  $character_data_icon = '<img title="Character Data" src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/character_data_derivate-16x16-32.png' . '"/>';
1072

    
1073
  $rowcount = 0;
1074
  $rows = array();
1075

    
1076
  foreach ($root_unit_uuids as $root_unit_uuid) {
1077

    
1078
    //get derivate hierarchy for the FieldUnit
1079
    $sob_dto = cdm_ws_get(CDM_WS_PORTAL_OCCURRENCE_AS_DTO, array($root_unit_uuid));
1080
    if ($sob_dto) {
1081
      //summary row
1082
      if($sob_dto->class == "FieldUnitDTO"){
1083
        $rows[] = array(
1084
          'id' => 'derivate_summary' . $rowcount, // summary row id
1085
          'class' => array('summary_row'),
1086
          'data' => array(
1087
            array(
1088
              'data' => $expand_icon . $collapse_icon,
1089
              'class' => array('summary_row_cell', 'summary_row_icon', 'expand_column')
1090
            ),
1091
            array(
1092
              'data' => $sob_dto->country,
1093
              'class' => array('summary_row_cell')
1094
            ),
1095
            array(
1096
              'data' => $sob_dto->date,
1097
              'class' => array('summary_row_cell')
1098
            ),
1099
            array(
1100
              'data' => $sob_dto->collectingString,
1101
              'class' => array('summary_row_cell')
1102
            ),
1103
            @array(
1104
              'data' => $sob_dto->collectionStatistics,
1105
              'class' => array('summary_row_cell')
1106
            ),
1107
            array(
1108
              'data' => $sob_dto->hasType ? $checked_box_icon : "",
1109
              'class' => array('summary_row_cell', 'summary_row_icon')
1110
            ),
1111
            array(
1112
              'data' => $sob_dto->hasSpecimenScan ? $checked_box_icon : "",
1113
              'class' => array('summary_row_cell', 'summary_row_icon')
1114
            ),
1115
            array(
1116
              'data' => ($sob_dto->hasDna ? $sequence_icon : "") . " "
1117
                . ($sob_dto->hasDetailImage ? $detail_image_icon : "") . " "
1118
                . ($sob_dto->hasCharacterData ? $character_data_icon : ""),
1119
              'class' => array('summary_row_cell', 'summary_row_icon')
1120
            )
1121
          )
1122
        );
1123
      } else {
1124
        $rows[] = array(
1125
          'id' => 'derivate_summary' . $rowcount, // summary row id
1126
          'class' => array('summary_row'),
1127
          'data' => array(
1128
            array(
1129
              'data' => $expand_icon . $collapse_icon,
1130
              'class' => array('summary_row_cell', 'summary_row_icon', 'expand_column')
1131
            ),
1132
            array(
1133
              'data' => $sob_dto->label,
1134
              'class' => array('summary_row_cell'),
1135
              'colspan' => 5
1136
            ),
1137
            array(
1138
              'data' => $sob_dto->hasSpecimenScan ? $checked_box_icon : "",
1139
              'class' => array('summary_row_cell', 'summary_row_icon')
1140
            ),
1141
            array(
1142
              'data' => ($sob_dto->hasDna ? $sequence_icon : "") . " "
1143
                . ($sob_dto->hasDetailImage ? $detail_image_icon : "") . " "
1144
                . ($sob_dto->hasCharacterData ? $character_data_icon : ""),
1145
              'class' => array('summary_row_cell', 'summary_row_icon')
1146
            )
1147
          )
1148
        );
1149
      }
1150

    
1151
      //assemble field unit details
1152
      $detail_html = "";
1153
      if ($sob_dto->summaryLabel) {
1154
        $detail_html .= create_label("Citation") . $sob_dto->summaryLabel . "<br>";
1155
      }
1156
      //assemble specimen details
1157
      if ($sob_dto->derivatives) {
1158
        $derivatives_orderd = [];
1159
        foreach ($sob_dto->derivatives as $derivative_dto) {
1160
          $derivatives_orderd[$derivative_dto->specimenIdentifier] = $derivative_dto;
1161
        }
1162
        ksort($derivatives_orderd);
1163
        foreach ($derivatives_orderd as $derivative_dto) {
1164
          $detail_html .= "<br>";
1165
          $detail_html .= render_cdm_specimenDTO_page($derivative_dto);
1166
        }
1167
      }
1168
      $detail_html .= "<br>";
1169
      //detail row resp. one BIG detail cell
1170
      $rows[] = array(
1171
        'data' => array(
1172
          array(
1173
            'data' => "", //empty first column
1174
            'class' => array('expand_column')
1175
          ),
1176
          array(
1177
            'data' => $detail_html,
1178
            'colspan' => 7,
1179
          ),
1180
        ),
1181
        'id' => 'derivate_details' . $rowcount,//details row ID
1182
        'class' => array('detail_row'),
1183
      );
1184
      $rowcount++;
1185
    }
1186
  }
1187

    
1188
  $tableId = "derivate_hierarchy_table";
1189
  $derivateHierarchyTable = array(
1190
    "#theme" => "table",
1191
    "#weight" => 2,
1192
    "#header" => array(
1193
      array(
1194
        'data' => "",
1195
        'class' => array('expand_column')
1196
      ),
1197
      "Country", "Date", "Collector + collecting number", "Herbaria", "Type", "Scan", "Derivatives"),
1198
    "#rows" => $rows,
1199
    "#attributes" => array(
1200
      "id" => $tableId,
1201
      "border" => 2
1202
    )
1203
  );
1204

    
1205
  //add toggle functionality to derivate hierarchy table
1206
  drupal_add_js_rowToggle("#" . $tableId);
1207

    
1208
  return $derivateHierarchyTable;
1209
}
1210

    
1211
/**
1212
 * Composes the view on specimens and occurrences as derivate tree
1213
 * starting from the field unit including all derivatives.
1214
 *
1215
 * @see CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TREE
1216
 *
1217
 * @param array $root_unit_dtos
1218
 *   list of SpecimenOrObservationDTOs
1219
 * @return array
1220
 *   The Drupal render array
1221
 *
1222
 * @ingroup compose
1223
 */
1224
function compose_specimen_table_top_down(array $root_unit_dtos){
1225

    
1226
  $specimen_render_array_items = specimen_render_array_items($root_unit_dtos);
1227

    
1228
    // add icons
1229
  $expand_icon = font_awesome_icon_markup(
1230
    'fa-plus-square-o',
1231
    array(
1232
      'alt' => 'Show details',
1233
      'class' => array('expand_icon')
1234
    )
1235
  );
1236
  $collapse_icon = font_awesome_icon_markup(
1237
    'fa-minus-square-o',
1238
    array(
1239
      'alt' => 'Show details',
1240
      'class' => array('collapse_icon')
1241
    )
1242
  );
1243
  $tableId = "specimen_tree_table";
1244
  $specimen_table = array(
1245
    '#theme' => 'table',
1246
    // prefix attributes and rows with '#' to let it pass toF the theme function,
1247
    // otherwise it is handled as child render array
1248
    '#attributes' => array(
1249
      'class' => 'specimens ' . CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TREE ,
1250
      'id' => $tableId
1251
    ),
1252
    '#rows' => array(),
1253
  );
1254
  $rowcount = 0;
1255
  foreach($specimen_render_array_items as $value){
1256
    $renderArray = array(
1257
      '#theme' => 'item_list',
1258
      '#items' => $value['children'],
1259
      '#type' => 'ul');
1260
    $output = drupal_render($renderArray);
1261

    
1262
    $specimen_table['#rows'][] = array(
1263
      'data' =>array(
1264
        array(
1265
          'data' => $expand_icon . $collapse_icon,
1266
          'class' => array('summary_row_cell', 'summary_row_icon', 'expand_column')
1267
        ),
1268
        $value['data']
1269
      ),
1270
      'id' => 'label' . $rowcount, // summary row id
1271
      'class' => array('summary_row'),
1272
    );
1273
    $specimen_table['#rows'][] = array(
1274
      'data' =>  array(
1275
        array(
1276
          'data' => "", //empty first column
1277
          'class' => array('expand_column')
1278
        ),
1279
        array(
1280
          'data' => $output
1281

    
1282
        )
1283
      ),
1284
      'class' =>  array('detail_row')
1285
//                'class' =>  array(
1286
//                    'descriptionElement',
1287
//                    'descriptionElement_IndividualsAssociation'
1288
      //               ),
1289
    );
1290
    $rowcount++;
1291

    
1292
  }
1293
  drupal_add_js_rowToggle("#".$tableId);
1294

    
1295
  return $specimen_table;
1296
}
1297

    
1298

    
1299
/**
1300
 * Renders a FieldUnitDTO or DerivedUnitDTO
1301
 *
1302
 * @param object $specimen_or_observation_dto
1303
 *   A FieldUnitDTO or DerivedUnitDTO object
1304
 *   the render array for
1305
 *
1306
 * @return string
1307
 *   the supplied render array $derivatives to which the composition of the
1308
 *   supplied
1309
 *   $specimenOrObservation has been added to
1310
 *
1311
 * @ingroup compose
1312
 *
1313
 * @throws \Exception
1314
 */
1315
function compose_cdm_specimen_or_observation_tree_entry($specimen_or_observation_dto) {
1316
  $exclude_occurrence_fields = &drupal_static(__FUNCTION__);
1317
  if (!isset($exclude_occurrence_fields)) {
1318
    $exclude_occurrence_fields = [
1319
      'uuid',
1320
      'titleCache',
1321
      'protectedTitleCache',
1322
      'label',
1323
      'class',
1324
      'type',
1325
      'types',
1326
      'taxonRelatedDerivedUnits',
1327
      'collectionCode',
1328
      'derivatives',
1329
      'derivateDataDTO',
1330
      'summaryLabel',
1331
      'derivationTreeSummary',
1332
      'specimenIdentifier', // combination like  collection code + accession number
1333
      'mostSignificantIdentifier',
1334
      // -----
1335
      // needed later on?
1336
      'hasDetailImage',
1337
      'hasType',
1338
      'hasSpecimenScan',
1339
      'collectionStatistics',
1340
      'collectingString'
1341
      // ----
1342
    ];
1343
  }
1344

    
1345
  if (is_object($specimen_or_observation_dto)) {
1346

    
1347
    if(isset($specimen_or_observation_dto->recordBase)){
1348
        $type_label = $specimen_or_observation_dto->recordBase->message_L10n;
1349
    }
1350
      RenderHints::setFootnoteListKey($type_label . '-' . $specimen_or_observation_dto->uuid);
1351

    
1352
      // collect typeStatus as label
1353
      if (isset($specimen_or_observation_dto->specimenTypeDesignations)) {
1354
          $type_status = array();
1355
          foreach ($specimen_or_observation_dto->specimenTypeDesignations as $typeDesignation) {
1356
              if (isset($typeDesignation->typeStatus_L10n)) {
1357
                  $type_status[] = $typeDesignation->typeStatus_L10n;
1358
              }
1359
          }
1360
          if (count($type_status) > 0) {
1361
              $type_label = implode(', ', $type_status);
1362
        }
1363
      }
1364

    
1365
      if (isset($typeDesignation->typifiedNames)){
1366
          $title = $type_label . ' for: ' . $typeDesignation->typifiedNames;
1367
      }else{
1368
          $title = $type_label;
1369
      }
1370

    
1371
        $groups = array();
1372
        $children_items = array();
1373
        // --- add initialized fields
1374
        foreach (get_object_vars($specimen_or_observation_dto) as $field => $value) {
1375
            $child_item = array();
1376

    
1377
            if (!in_array($field, $exclude_occurrence_fields) && $value ) {
1378
              switch ($field) {
1379

    
1380
                /* ---- SpecimenOrObservationBase --- */
1381
                case 'recordBase':
1382
                  $label = $value->message_L10n;
1383
                  if($label == 'Dna Sample'){
1384
                    $label == 'DNA Sample';
1385
                  }
1386
                  _description_list_group_add($groups, cdm_occurrence_field_name_label($field), $label,NULL, -10);
1387
                break;
1388
                case 'derivationEvent':
1389
                    @_description_list_group_add($groups, 'Gathering type:', ucfirst($value->derivationEventType), NULL, 1);
1390
                    break;
1391
                case 'accessionNumber':
1392
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value, NULL, 0);
1393
                    break;
1394
                case 'preferredStableUri':
1395
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), array(array('#markup' => cdm_external_uri($value, false))));
1396
                    break;
1397
                case 'characterData':
1398
                    @_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)));
1399
                  break;
1400
                case 'specimenTypeDesignations':
1401
                    @_description_list_group_add(
1402
                        $groups,
1403
                        cdm_occurrence_field_name_label($field),
1404
                        array(
1405
                            '#markup' => render_specimen_typedesignation_dto($value),
1406
                        )
1407
                    );
1408
                    break;
1409

    
1410
                case 'listOfMedia':
1411
                    $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
1412

    
1413
                    $captionElements = array(
1414
                        'title',
1415
                        '#uri' => t('open media'),
1416
                    );
1417
                    $gallery_html = compose_cdm_media_gallerie(array(
1418
                        'mediaList' => $value,
1419
                        'galleryName' => $specimen_or_observation_dto->uuid,
1420
                        'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
1421
                        'cols' => $gallery_settings['cdm_dataportal_media_cols'],
1422
                        'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
1423
                        'captionElements' => $captionElements,
1424
                        'mediaLinkType' => 'LIGHTBOX',
1425
                        'alternativeMediaUri' => NULL,
1426
                        'galleryLinkUri' => NULL,
1427
                        'showCaption' => true
1428
                    ));
1429

    
1430
                  //FIXME re-enable: // @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $gallery_html);
1431
                  break;
1432

    
1433
                  case 'sex':
1434
                  case 'lifeStage':
1435
                  case 'kindOfUnit':
1436
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), cdm_term_representation($value));
1437
                    break;
1438

    
1439
                  case 'definition':
1440
                    // TODO
1441
                    break;
1442

    
1443
                  /* ---- DerivedUnitBase --- */
1444
                  case 'collection':
1445
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), array(
1446
                      array('#markup' => render_collection_dto($value))
1447
                    ));
1448
                    break;
1449

    
1450
                  /* ---- Specimen --- */
1451
                  case 'sequences':
1452
                      $dd_elements = array();
1453
                      foreach ($value as $sequence) {
1454
                          $dd_elements[] = compose_cdm_sequence($sequence, true);
1455
                          $dd_elements[] = "";
1456
                      }
1457
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label($field), $dd_elements,'', 100);
1458
                      break;
1459

    
1460
                  // TODO preservation
1461
                  case 'storedUnder':
1462
                    $taxon_name = cdm_ws_get(CDM_WS_PORTAL_NAME, array($value->uuid));
1463
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label('storedUnder'), array(
1464
                      array('#markup' => render_taxon_or_name($taxon_name, path_to_name($taxon_name->uuid)))
1465
                    ));
1466
                  break;
1467

    
1468
                  /* ---- FieldObservation --- */
1469
                  case 'gatheringEvent':
1470

    
1471
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label('collector'), $value->collector);
1472
                      @_description_list_group_add($groups, t('Gathering date'), timePeriodToString($value->timeperiod));
1473
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label('description'), $value->description);
1474
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label('locality'), $value->locality, '', 10);
1475
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label('country'), $value->country);
1476
                      @_description_list_group_add($groups, cdm_occurrence_field_name_label('collectingMethod'), $value->collectingMethod);
1477
                      if (isset($value->absoluteElevation)) {
1478
                          $min_max_markup = statistical_values_from_gathering_event($value, 'absoluteElevation');
1479
                          @_description_list_group_add($groups, cdm_occurrence_field_name_label('absoluteElevation'), $min_max_markup);
1480
                      }
1481
                      if (isset($value->distanceToGround) && $value->distanceToGround >0) {
1482
                          $min_max_markup = statistical_values_from_gathering_event($value, 'distanceToGround');
1483
                          @_description_list_group_add($groups, cdm_occurrence_field_name_label('distanceToGround'), $min_max_markup);
1484
                      }
1485
                      if (isset($value->distanceToWaterSurface) && $value->distanceToWaterSurface > 0) {
1486
                          $min_max_markup = statistical_values_from_gathering_event($value, 'distanceToWaterSurface');
1487
                          @_description_list_group_add($groups, cdm_occurrence_field_name_label('distanceToWaterSurface'), $min_max_markup);
1488
                      }
1489

    
1490
                      if (isset($value->collectingAreas)) {
1491
                          $area_representations = array();
1492
                          foreach ($value->collectingAreas as $area) {
1493
                             // $area_representations[] = l($area->representation_L10n, path_to_named_area($area->uuid));
1494
                              $area_representations[] = $area;
1495
                          }
1496
                          if (!empty($area_representations))
1497
                              @_description_list_group_add($groups, cdm_occurrence_field_name_label('collectingAreas'),
1498
                                  array(
1499
                                      array('#markup' => implode(', ', $area_representations))
1500
                                  )
1501
                              );
1502
                      }
1503
                      if (isset($value->exactLocation)  ) {
1504
                        @_description_list_group_add($groups, cdm_occurrence_field_name_label('exactLocation'),
1505
                          array(
1506
                            array('#markup' => render_point($value->exactLocation)),
1507
                          ),'',11
1508
                        );
1509
                      }
1510
                      break;
1511

    
1512
                  /* ---- DerivationEvent --- */
1513
                  case 'derivationEvents':
1514
                    //@_description_list_group_add($groups, t('Association type'), $value->description);
1515
                    break;
1516
                  case 'determinedNames':
1517
                    $dd_elements = array();
1518
                    foreach ($value as $name) {
1519
                      $taxon_name = cdm_ws_get(CDM_WS_PORTAL_NAME, $name->uuid);
1520
                      $dd_elements[] = render_taxon_or_name($taxon_name, url(path_to_name($taxon_name->uuid)));
1521
                    }
1522
                    @_description_list_group_add($groups, cdm_occurrence_field_name_label("Identification(s)"), $dd_elements,'', 100);
1523
                    break;
1524

    
1525
                  default:
1526
                    if (is_object($value) || is_array($value)) {
1527
                        drupal_set_message("Unhandled type in compose_cdm_specimen_or_observation_tree_entry() for field " . $field, "warning");
1528
                    } else {
1529
                      _description_list_group_add($groups, cdm_occurrence_field_name_label($field), $value);
1530
                    }
1531
              }
1532
            }
1533
        } // END of loop over $derivedUnitFacade fields
1534

    
1535
        // template_preprocess_description_list() is not worting by weight so we do it right here
1536
        uasort($groups, 'element_sort');
1537
        $occurrence_elements = array(
1538
           // '#title' => $title,
1539
            '#theme' => 'description_list',
1540
            '#groups' => $groups,
1541
            '#attributes' => array('class' => html_class_attribute_ref($specimen_or_observation_dto)),
1542
        );
1543
        $output = drupal_render($occurrence_elements);
1544
        if (isset($gallery_html)){
1545
            $output .= $gallery_html;
1546
        }
1547
        $pathToSpecimen = path_to_specimen($specimen_or_observation_dto->uuid);
1548
        $output .=  l("Detail page", $pathToSpecimen);
1549
    } // END of $specimenOrObservation exists
1550

    
1551
    return $output;
1552
}
1553

    
1554
function compose_table_of_blast_result(array $data){
1555
   // get icon images
1556
  $expand_icon = font_awesome_icon_markup(
1557
      'fa-plus-square-o',
1558
      array(
1559
          'alt' => 'Show details',
1560
          'class' => array('expand_icon')
1561
      )
1562
  );
1563
  $collapse_icon = font_awesome_icon_markup(
1564
      'fa-minus-square-o',
1565
      array(
1566
          'alt' => 'Show details',
1567
          'class' => array('collapse_icon')
1568
      )
1569
  );
1570
  //$detail_image_icon = '<img title="Detail Image" src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/detail_image_derivate-16x16-32.png' . '"/>';
1571
    $rowcount = 0;
1572
    $rows = array();
1573

    
1574
    foreach ($data as $row_data){
1575
        $pathToSpecimen = path_to_specimen_by_accession_number($row_data['id']);
1576
        $specimenPageLink = l($row_data['id'], $pathToSpecimen);
1577
        $ncbiLink = l($row_data['id'], 'https://www.ncbi.nlm.nih.gov/nuccore/'.$row_data['id'].'?report=graph');
1578
        $rows[] =  array(
1579
            'data' => array(
1580
                array(
1581
                    'data' => $expand_icon . $collapse_icon,
1582
                    'class' => array('summary_row_cell', 'summary_row_icon', 'expand_column')
1583
                ),
1584
                array(
1585
                    'data' => $row_data['def'],
1586
                ),
1587
                array(
1588
                    'data' => $specimenPageLink,
1589
                ),
1590
                array(
1591
                    'data' => $row_data['hsp_align_length'],
1592
                ),
1593
                array(
1594
                   'data' => $ncbiLink,
1595
                ),
1596
                array(
1597
                    'data' => $row_data['hsp_identity']/$row_data['hsp_align_length']*100,
1598
                )
1599
            ),
1600
            'id' => 'blast_summary' . $rowcount, // summary row id
1601
            'class' => array('summary_row'),
1602
        );
1603
        $detail_html = "";
1604

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

    
1607

    
1608
        $detail_html .= "<br>";
1609
        $detail_html .= $row_data["hsp_midline"];
1610

    
1611
        //$detail_html .= "<br>";
1612

    
1613
        $rows[] = array(
1614
            'data' => array(
1615
                array(
1616
                    'data' => "", //empty first column
1617
                    'class' => array('expand_column')
1618
                ),
1619
                array(
1620
                    'data' => $detail_html,
1621
                    'colspan' => 5,
1622
                ),
1623
            ),
1624
            'id' => 'blast_detail' . $rowcount,//details row ID
1625
            'class' => array('detail_row'),
1626
        );
1627
        $rowcount++;
1628
    }
1629

    
1630
    $tableId = "blast_result_table";
1631
    $blast_result_table = array(
1632
        "#theme" => "table",
1633
        "#weight" => 2,
1634
        "#header" => array(
1635
            array(
1636
                'data' => "",
1637
                'class' => array('expand_column')
1638
            ),
1639
                        "Name", "Accession Number", "Align Length", "NCBI", "% Identity"),
1640
        "#rows" => $rows,
1641
        "#attributes" => array(
1642
            "id" => $tableId,
1643
            "border" => 2
1644
        )
1645
    );
1646

    
1647
    drupal_add_js_rowToggle("#".$tableId);
1648

    
1649
    $render_array[$tableId] = $blast_result_table;
1650
    $out = drupal_render($render_array);
1651
   //$blast_result_page-> content = drupal_render($render_array);
1652
   return $out;
1653
}
1654

    
1655

    
1656
/**
1657
 * Composes a BOTTOM-UP-SPECIMEN-TABLE for the view mode
1658
 * CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TREE
1659
 *
1660
 * @param $specimensOrObservations
1661
 * @return array
1662
 *  A drupal render array with the following keys:
1663
 *   - 'specimen_list'
1664
 *   - 'pager'
1665
 *
1666
 * @ingroup Compose
1667
 * @see CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TREE
1668
 */
1669
function compose_specimens_table_bottom_up($specimensOrObservations)
1670
{
1671

    
1672
  // --- generate the specimen list as table
1673
  $specimen_table = array(
1674
    '#theme' => 'table',
1675
    '#weight' => 2,
1676
    // prefix attributes and rows with '#' to let it pass toF the theme function,
1677
    // otherwise it is handled as child render array
1678
    '#attributes' => array('class' => 'specimens '),
1679
    '#rows' => array(),
1680
  );
1681

    
1682
  if ($specimensOrObservations) {
1683

    
1684
    foreach ($specimensOrObservations as $specimenOrObservation) {
1685

    
1686
      $mediaList = array();
1687
      if (is_array($specimenOrObservation->_fieldObjectMedia)) {
1688
        $mediaList = array_merge($mediaList, $specimenOrObservation->_fieldObjectMedia);
1689
      }
1690
      if (is_array($specimenOrObservation->_derivedUnitMedia)) {
1691
        $mediaList = array_merge($mediaList, $specimenOrObservation->_derivedUnitMedia);
1692
      }
1693

    
1694

    
1695
      // typelabel will contain the typeStatus
1696
      $type_label = '';
1697
      $typeDesignationPager = cdm_ws_get(CDM_WS_OCCURRENCE . '/$0/specimenTypeDesignations', $specimenOrObservation->uuid);
1698
      if (isset($typeDesignationPager) and isset($typeDesignationPager->records)) {
1699
        $type_status = array();
1700
        foreach ($typeDesignationPager->records as $typeDesignation) {
1701
          if (isset($typeDesignation->typeStatus->representation_L10n)) {
1702
            $type_status[] = $typeDesignation->typeStatus->representation_L10n;
1703
          }
1704
        }
1705
        $type_label = implode(', ', $type_status);
1706
        if ($type_label) {
1707
          $type_label = ucfirst($type_label) . ': ';
1708
        }
1709
      }
1710

    
1711
      // --- Specimen entry as dynamic label:
1712
      //     -> Dynabox for the specimenOrObservation
1713
      $gallery_name = $specimenOrObservation->uuid;
1714

    
1715
      $derived_unit_ws_request = cdm_compose_ws_url(CDM_WS_OCCURRENCE, array($specimenOrObservation->uuid));
1716
      // --- Render associated media.
1717
      $gallery_html = '';
1718
      if (count($mediaList) > 0) {
1719
        $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
1720
        $captionElements = array(
1721
          '#uri' => t('open media'),
1722
        );
1723

    
1724
        $gallery_html = compose_cdm_media_gallerie(array(
1725
          'mediaList' => $mediaList,
1726
          'galleryName' => $gallery_name,
1727
          'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
1728
          'cols' => $gallery_settings['cdm_dataportal_media_cols'],
1729
          'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
1730
          'captionElements' => $captionElements,
1731
          'mediaLinkType' => 'LIGHTBOX',
1732
          'alternativeMediaUri' => NULL,
1733
          'galleryLinkUri' => NULL,
1734
        ));
1735
      }
1736
      //here we should use the data we already have
1737
      $label_html = cdm_dynabox(
1738
        $specimenOrObservation->uuid,
1739
        $type_label . $specimenOrObservation->titleCache,
1740
        $derived_unit_ws_request,
1741
        'cdm_specimen_or_observation',
1742
        'Click for details',
1743
        array('div', 'div'),
1744
        array(),
1745
        null, // $content_element_selector
1746
        'function(){ jQuery(\'#media_gallery_' . $gallery_name . '\').hide(); }', // open_callback
1747
        'function(){ jQuery(\'#media_gallery_' . $gallery_name . '\').show(); }' // close_callback
1748
      );
1749

    
1750
      // --- Render associated media.
1751
      $gallery_html = '';
1752
      if (count($mediaList) > 0) {
1753
        $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
1754
        $captionElements = array(
1755
          '#uri' => t('open media'),
1756
        );
1757

    
1758
        $gallery_html = compose_cdm_media_gallerie(array(
1759
          'mediaList' => $mediaList,
1760
          'galleryName' => $gallery_name,
1761
          'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
1762
          'cols' => $gallery_settings['cdm_dataportal_media_cols'],
1763
          'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
1764
          'captionElements' => $captionElements,
1765
          'mediaLinkType' => 'LIGHTBOX',
1766
          'alternativeMediaUri' => NULL,
1767
          'galleryLinkUri' => NULL,
1768
        ));
1769
      }
1770

    
1771
      $specimen_table['#rows'][] = array(
1772
        // An array of table rows. Every row is an array of cells, or an associative array
1773
        'data' => array(
1774
          // Each cell can be either a string or an associative array
1775
          $label_html . $gallery_html
1776
        ),
1777
        'class' => array(
1778
          'descriptionElement',
1779
          'descriptionElement_IndividualsAssociation'
1780
        ),
1781
      );
1782
    }
1783
  }
1784

    
1785
  return $specimen_table;
1786
}
1787

    
1788

    
1789
/**
1790
 * Orders occurrences by date but types should be on top of the list.
1791
 *
1792
 * @param array $specimens_or_observations
1793
 *  Array of SpecimenOrObservation or fieldUnitDTOs
1794
 *
1795
 * @return array
1796
 */
1797
function order_specimens_or_observations_by_date_and_type($specimens_or_observations)
1798
{
1799
  $type_specimens = array();
1800
  $other_occurrences = array();
1801
  if(is_array($specimens_or_observations)){
1802
    foreach ($specimens_or_observations as &$occurrence) {
1803
      $typeDesignationsPager = cdm_ws_get(CDM_WS_OCCURRENCE . '/$0/specimenTypeDesignations', $occurrence->uuid);
1804
      if (isset($typeDesignationsPager->count) && $typeDesignationsPager->count > 0) {
1805
        $type_specimens[] = $occurrence;
1806
      } else {
1807
        $other_occurrences[] = $occurrence;
1808
      }
1809
    }
1810
  }
1811
  $specimens_or_observations = array_merge($type_specimens, $other_occurrences);
1812
  return $specimens_or_observations;
1813
}
1814

    
1815
/**
1816
 * Orders FieldUnitDTOs by date but types should be on top of the list.
1817
 *
1818
 * Delegates internally to order_specimens_or_observations_by_date_and_type()
1819
 *
1820
 * @param array $fieldUnitDTOs
1821
 *
1822
 * @return array
1823
 */
1824
function order_fieldUnitDtos_by_date_and_type($fieldUnitDTOs)
1825
{
1826
  $units_with_types = [];
1827
  $units_no_types = [];
1828

    
1829
  foreach($fieldUnitDTOs as $dto){
1830
    if(isset($dto->specimenTypeDesignations[0])){
1831
      $units_with_types[] = $dto;
1832
    } else {
1833
      $units_no_types[] = $dto;
1834
    }
1835
  }
1836
  usort($units_with_types, 'compare_specimen_or_observation_dtos_by_date');
1837
  usort($units_no_types, 'compare_specimen_or_observation_dtos_by_date');
1838

    
1839
  return array_merge($units_with_types, $units_no_types);
1840
}
1841

    
1842
/**
1843
 * @param $specimen
1844
 *
1845
 * @return array
1846
 */
1847
function specimen_id_and_collection_for($specimen) {
1848
  $specimenID = '';
1849
  $collection = NULL;
1850
  if (!($specimen->class == 'FieldUnit')) {
1851
    if ($specimen->collection) {
1852
      if ($specimen->collection->code) {
1853
        $collection = $specimen->collection->code;
1854
      }
1855
      elseif ($specimen->collection->name) {
1856
        $collection = $specimen->collection->name;
1857
      }
1858
    }
1859
    if ($specimen->accessionNumber) {
1860
      $specimenID = $specimen->accessionNumber;
1861
    }
1862
    elseif ($specimen->barcode) {
1863
      $specimenID = $specimen->barcode;
1864
    }
1865
    elseif ($specimen->catalogNumber) {
1866
      $specimenID = $specimen->catalogNumber;
1867
    }
1868
    elseif ($specimen->titleCache) {
1869
      $specimenID = $specimen->titleCache;
1870
    }
1871
    if (!isset($specimenID) and !isset($collection)) {
1872
      $specimenID = $specimen->uuid;
1873
    }
1874
  }
1875
  else {
1876
    if ($specimen->titleCache) {
1877
      $specimenID = $specimen->titleCache;
1878
    }
1879
    if (!isset($specimenID) and !isset($collection)) {
1880
      $specimenID = $specimen->uuid;
1881
    }
1882
  }
1883
  return [$specimenID, $collection];
1884
}
1885

    
1886
/**
1887
 * Renders a cdm collection entity as html markup.
1888
 *
1889
 * institute and super-collections
1890
 *
1891
 * @param $collection_dto
1892
 *   The CollectionDTO
1893

    
1894
 * @return string
1895
 *  The markup for the collection,
1896
 */
1897
function render_collection_dto($collection_dto){
1898
  return render_collection($collection_dto);
1899
}
1900

    
1901
/**
1902
 * Renders a cdm collection entity as html markup.
1903
 *
1904
 * institute and super-collections
1905
 *
1906
 * @param $collection
1907
 *   The CDM Collection entity or CollectionDTO
1908
 * @param bool $do_link
1909
 *   Append a link to the collection page as clickable icon (default = true).
1910
 *
1911
 * @return string
1912
 *  The markup for the collection,
1913
 */
1914
function render_collection($collection, $do_link = false /* to be made true, see #9250 */ ){
1915
  if(!is_object($collection)){
1916
    return '';
1917
  }
1918
  $is_dto = $collection->class == 'CollectionDTO';
1919
  $collection_str_list = [];
1920
  $super_collection = $collection;
1921
  while($super_collection){
1922
    $collection_str = $is_dto ? $super_collection->label : $super_collection->titleCache;
1923
    if(
1924
      (isset($super_collection->institute) && $super_collection->institute->titleCache) ||
1925
      ($is_dto && $super_collection->institute)
1926
    ){
1927
      $collection_str .= ' at ' . ($is_dto ? $super_collection->institute : $super_collection->institute->titleCache);
1928
    }
1929
    $collection_str_list[] = $collection_str;
1930
    if(isset($super_collection->superCollection)){
1931
      $super_collection = $super_collection->superCollection;
1932
    } else {
1933
      $super_collection = null;
1934
    }
1935
  }
1936
  $markup = join(' in ', $collection_str_list);
1937
  if($markup){
1938
    if($do_link){
1939
      $markup .= ' ' . cdm_internal_link(path_to_collection($collection->uuid));
1940
    }
1941
    $markup = '<span class="' . html_class_attribute_ref($collection) . '">' . $markup . '</span>';
1942
  }
1943
  return $markup;
1944
}
1945

    
1946
/**
1947
 * Compares two SpecimenTypeDesignations by identifier and label
1948
 *
1949
 * @param object $a
1950
 *   A SpecimenOrObservationDTO.
1951
 * @param object $b
1952
 *   The SpecimenOrObservationDTO.
1953
 */
1954
function compare_specimen_or_observation_dtos($a, $b) {
1955
    // Sort alphabetically.
1956
    $a_text =  isset($a->specimenIdentifier) ? $a->specimenIdentifier : $a->label;
1957
    $b_text =  isset($b->specimenIdentifier) ? $b->specimenIdentifier : $b->label;
1958
    return strcasecmp($a_text, $b_text);
1959
}
1960

    
1961
/**
1962
 * Compares two SpecimenTypeDesignations by date or label
1963
 *
1964
 * @param object $a
1965
 *   A SpecimenOrObservationDTO.
1966
 * @param object $b
1967
 *   The SpecimenOrObservationDTO.
1968
 */
1969
function compare_specimen_or_observation_dtos_by_date($a, $b) {
1970
  // Sort alphabetically.
1971
  $a_text =  isset($a->date) ? $a->date : $a->label;
1972
  $b_text =  isset($b->date) ? $b->date : $b->label;
1973
  return strcasecmp($a_text, $b_text);
1974
}
(8-8/14)