Project

General

Profile

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

    
21

    
22
/**
23
 * Composes the view on specimens and occurrences as derivate tree
24
 * starting from the field unit including all derivatives.
25
 *
26
 * @param array $root_unit_dtos
27
 *   list of SpecimenOrObservationDTOs
28
 *
29
 * @return array
30
 *   The Drupal render array
31
 *
32
 * @ingroup compose
33
 * @see CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TREE
34
 *
35
 */
36
function compose_specimen_table_top_down_new(array $root_unit_dtos) {
37
  // add icons
38
  $expand_icon = font_awesome_icon_markup(
39
    'fa-plus-square-o',
40
    [
41
      'alt' => 'Show details',
42
      'class' => ['expand_icon'],
43
    ]
44
  );
45
  $collapse_icon = font_awesome_icon_markup(
46
    'fa-minus-square-o',
47
    [
48
      'alt' => 'Show details',
49
      'class' => ['collapse_icon'],
50
    ]
51
  );
52

    
53
  $derivation_tree = derived_units_tree($root_unit_dtos);
54

    
55
  $render_array = [];
56
  $render_array['derived-unit-tree'] = $derivation_tree;
57

    
58
  _add_js_derivation_tree('.derived-unit-tree');
59

    
60
  return $render_array;
61
}
62

    
63
/**
64
 * Creates the root levels and trees for all subordinate derivatives.
65
 *
66
 * See derived_units_sub_tree()
67
 *
68
 * @param array $root_unit_dtos
69
 *     list of SpecimenOrObservationDTOs
70
 *
71
 * @return array
72
 *    An array which can be used in render arrays to be passed to the
73
 * theme_table() and theme_list().
74
 */
75
function derived_units_tree(array $root_unit_dtos) {
76

    
77
  $root_items = [];
78
  //we need one more item to contain the items of one level (fieldunit, derivate data etc.)
79
  foreach ($root_unit_dtos as &$sob_dto) {
80
    $field_unit_dto_render_array = compose_cdm_specimen_or_observation_dto_details_grid($sob_dto);
81
    $root_item = [
82
      '#prefix' => '<div class="derived-unit-tree">',
83
      '#suffix' => '</div>',
84
      '#type' => 'container',
85
      '#attributes' => [
86
        'class' => [
87
          'derived-unit-item derived-unit-tree-root',
88
          html_class_attribute_ref($sob_dto),
89
        ],
90
      ],
91
      'div-container' => [
92
        'root-item-and-sub-tree' => [
93
          markup_to_render_array('<div class="unit-header"><div class="unit-label">' . $sob_dto->label . '</div></div>'
94
            . '<div class="unit-content-wrapper">' // allows to apply the borders between .derived-unit-tree-root and .unit-content
95
            . '<div class="unit-content">' . drupal_render($field_unit_dto_render_array) . '</div>'
96
            . '</div>'),
97
        ],
98
      ],
99

    
100
    ];
101
    if (isset($sob_dto->derivatives) && sizeof($sob_dto->derivatives) > 0) {
102
      usort($sob_dto->derivatives, 'compare_specimen_or_observation_dtos');
103
      // children are displayed in a nested list.
104
      $root_item['div-container']['root-item-and-sub-tree'][] = derived_units_sub_tree($sob_dto->derivatives);
105
    }
106
    $root_items[] = $root_item;
107
  }
108

    
109
  return $root_items;
110
}
111

    
112
/**
113
 * @param array $unit_dtos
114
 *
115
 * @return array
116
 */
117
function derived_units_sub_tree(array $unit_dtos) {
118

    
119
  $list_items = derived_units_as_list_items($unit_dtos);
120

    
121
  $derivation_tree = [
122
    '#theme' => 'item_list',
123
    '#type' => 'ul',
124
    '#attributes' => [
125
      'class' => CDM_SPECIMEN_LIST_VIEW_MODE_OPTION_DERIVATE_TREE . ' derived-unit-sub-tree',
126
    ],
127
    '#items' => $list_items,
128
  ];
129
  return $derivation_tree;
130
}
131

    
132
/**
133
 * Creates render array items for FieldUnitDTO or DerivedUnitDTO.
134
 *
135
 * @param array $root_unit_dtos
136
 *     list of SpecimenOrObservationDTOs
137
 *
138
 * @return array
139
 *    An array which can be used in render arrays to be passed to the
140
 * theme_table() and theme_list().
141
 */
142
function derived_units_as_list_items(array $root_unit_dtos) {
143

    
144
  $list_items = [];
145
  //we need one more item to contain the items of one level (fieldunit, derivate data etc.)
146
  foreach ($root_unit_dtos as &$sob_dto) {
147
    $item = [];
148
    $item['class'] = ['derived-unit-item ', html_class_attribute_ref($sob_dto)];
149
    // data" element of the array is used as the contents of the list item
150
    $item['data'] = [];
151
    $units_render_array = compose_cdm_specimen_or_observation_dto_details_grid($sob_dto);
152
    $item['data'] = '<div class="unit-header"><div class="unit-label">' . $sob_dto->label . '</div></div>'
153
      . '<div class="unit-content">' . drupal_render($units_render_array) . '</div>';
154
    if (isset($sob_dto->derivatives) && sizeof($sob_dto->derivatives) > 0) {
155
      usort($sob_dto->derivatives, 'compare_specimen_or_observation_dtos');
156
      // children are displayed in a nested list.
157
      $item['children'] = derived_units_as_list_items($sob_dto->derivatives);
158
    }
159
    $list_items[] = $item;
160
  }
161

    
162
  return $list_items;
163
}
164

    
165
/**
166
 * Compose grid of details tabled for a CDM SpecimenOrObservationDTO
167
 *
168
 * The resulting render array will contain separate DOM block level elements
169
 * with header line for the various kind of information like, location,
170
 * gathering, specimen/observation, DNA, etc.
171
 *
172
 *
173
 * Subordinate derivatives will not be included. For showing the derivation
174
 * hierarchy see methods like derived_units_sub_tree()
175
 *
176
 * compose_hook() implementation
177
 *
178
 * @param object $sob_dto
179
 *   the CDM FieldUnitDTO or DerivedUnitDTO to compose
180
 *   the render array for.
181
 * @param bool $compact_mode
182
 *   Currently unused, but added for compatibility with
183
 *   compose_cdm_specimen_or_observation($specimen_or_observation,
184
 *   $isSpecimen_page = false, &$derivatives = null)
185
 * @param array $derivatives
186
 *   the render array which contains the compositions of the derivatives
187
 *   of the supplied $specimenOrObservation
188
 *
189
 * @return array
190
 *  The render array for the SpecimenOrObservationDTO
191
 *
192
 * @ingroup compose
193
 */
194
function compose_cdm_specimen_or_observation_dto_details_grid($sob_dto, $compact_mode = FALSE, &$derivatives = NULL) {
195
  //TODO !!!! add derivation event information like method, etc
196
  $render_array = [];
197
  if (!$sob_dto) {
198
    return $render_array;
199
  }
200
  if ($sob_dto->type == 'FieldUnit') {
201
    $render_array['field-unit'] = compose_cdm_field_unit_dto_details($sob_dto, $compact_mode);
202
    if (isset($sob_dto->gatheringEvent)) {
203
      $render_array['gathering'] = compose_cdm_gathering_dto_details($sob_dto->gatheringEvent, $compact_mode);
204
    }
205
  } else {
206
    $render_array['storage'] = compose_cdm_derived_unit_dto_storage_details($sob_dto, $compact_mode);
207
    $render_array['type-designations'] = compose_cdm_unit_dto_type_designations($sob_dto, $compact_mode);
208
    if($sob_dto->type == 'DnaSample'){
209
      // FIXME:
210
      $render_array['dna-sample'] = compose_cdm_derived_unit_dto_sequences($sob_dto, $compact_mode);
211
    } else if($sob_dto->type == 'MediaSpecimen' && isset_not_empty($sob_dto->mediaSpecimen)) {
212
      $render_array['media-specimens'] = cdm_sob_dto_media_table($sob_dto->mediaSpecimen, $sob_dto, 'Media Specimens');
213
    }
214
  }
215
  if(isset_not_empty($sob_dto->determinedNames)){
216
    $render_array['determinations'] = compose_cdm_sob_dto_determinations($sob_dto, $compact_mode);
217
  }
218
  if(isset_not_empty($sob_dto->listOfMedia)){
219
    $render_array['media'] = cdm_sob_dto_media_table($sob_dto->listOfMedia, $sob_dto, 'Media');;
220
  }
221

    
222
  return $render_array;
223
}
224
/**
225
 * Data rows with details for a SpecimenOrObservationDTO to be used in a table
226
 * @param object $sob_dto
227
 *   the CDM SpecimenOrObservationDTO
228
 * @param bool $compact_mode
229
 *   Currently unused,
230
 *
231
 * @return array
232
 *  The data rows
233
 */
234
function sob_dto_details_rows($sob_dto, $compact_mode = FALSE) {
235

    
236
  $table_row_data = [];
237

    
238
  if (isset_not_empty($sob_dto->recordBase)) {
239
    $label = cdm_term_representation($sob_dto->recordBase);
240
    if($label == 'Dna Sample'){
241
      $label == 'DNA Sample';
242
    }
243
    $table_row_data[0] = cdm_sob_dto_table_row(
244
      cdm_occurrence_field_name_label('recordBase'),
245
      $label);
246
  }
247
  if (isset_not_empty($sob_dto->kindOfUnit)) {
248
    $table_row_data[] = cdm_sob_dto_table_row(
249
      cdm_occurrence_field_name_label('kindOfUnit'),
250
      cdm_term_representation($sob_dto->kindOfUnit));
251
  }
252
  if (isset_not_empty($sob_dto->preferredStableUri)) {
253
    $table_row_data[] = cdm_sob_dto_table_row(
254
      cdm_occurrence_field_name_label('preferredStableUri'),
255
      cdm_external_uri($sob_dto->preferredStableUri, false));
256
  }
257
  if (isset_not_empty($sob_dto->sex)) {
258
    $table_row_data[] = cdm_sob_dto_table_row(
259
      cdm_occurrence_field_name_label('sex'),
260
      cdm_term_representation($sob_dto->sex));
261
  }
262
  if (isset_not_empty($sob_dto->lifeStage)) {
263
    $table_row_data[] = cdm_sob_dto_table_row(
264
      cdm_occurrence_field_name_label('lifeStage'),
265
      cdm_term_representation($sob_dto->lifeStage));
266
  }
267

    
268
  return $table_row_data;
269
}
270

    
271

    
272
/**
273
 * Compose a table of details for a FieldUnitDTO.
274
 *
275
 * The resulting DOM block level element will have a header line and details.
276
 *
277
 * compose_hook() implementation
278
 *
279
 * @param object $fu_dto
280
 *   the CDM FieldUnitDTO
281
 * @param bool $compact_mode
282
 *   Currently unused,
283
 *
284
 * @return array
285
 *  The render array for the SpecimenOrObservationDTO
286
 *
287
 * @ingroup compose
288
 */
289
function compose_cdm_field_unit_dto_details($fu_dto, $compact_mode = FALSE) {
290

    
291
  $table_row_data = sob_dto_details_rows($fu_dto, $compact_mode);
292

    
293
  if (isset_not_empty($fu_dto->individualCount)) {
294
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('individualCount'), $fu_dto->individualCount);
295
  }
296
  if (isset_not_empty($fu_dto->definition)) {
297
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('definition'), $fu_dto->definition);
298
  }
299
  if (isset_not_empty($fu_dto->fieldNumber)) {
300
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('fieldNumber'), $fu_dto->fieldNumber);
301
  }
302
  if (isset_not_empty($fu_dto->primaryCollector)) {
303
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('primaryCollector'), $fu_dto->primaryCollector);
304
  }
305
  if (isset_not_empty($fu_dto->fieldNotes)) {
306
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('fieldNotes'), $fu_dto->fieldNotes);
307
  }
308

    
309
  $heading = $table_row_data[0]['data'][1];
310
  unset($table_row_data[0]);
311
  return cdm_sob_dto_table(t($heading), $table_row_data, $fu_dto, 2);
312
}
313

    
314
/**
315
 * Compose details table for a DerivedUnitDTO.
316
 *
317
 * The resulting DOM block level element will have a header line and details.
318
 *
319
 * compose_hook() implementation
320
 *
321
 * @param object $du_dto
322
 *   the CDM DerivedUnitDTO
323
 * @param bool $compact_mode
324
 *   Currently unused,
325
 *
326
 * @return array
327
 *  The render array for the DerivedUnitDTO
328
 *
329
 * @ingroup compose
330
 */
331
function compose_cdm_derived_unit_dto_storage_details($du_dto, $compact_mode = FALSE) {
332

    
333
  $table_row_data = sob_dto_details_rows($du_dto, $compact_mode);
334

    
335
  if (isset($du_dto->accessionNumber)) {
336
    $table_row_data[] = cdm_sob_dto_table_row(
337
      cdm_occurrence_field_name_label('accessionNumber'),
338
      $du_dto->accessionNumber);
339
  }
340
  if (isset($du_dto->collection)) {
341
    $table_row_data[] = cdm_sob_dto_table_row(
342
      cdm_occurrence_field_name_label('collection'),
343
      render_collection_dto($du_dto->collection));
344
  }
345
  if (isset($du_dto->storedUnder)) {
346
    $taxon_name = cdm_ws_get(CDM_WS_PORTAL_NAME, array($du_dto->storedUnder->uuid));
347
    $table_row_data[] = cdm_sob_dto_table_row(
348
      cdm_occurrence_field_name_label('storedUnder'),
349
      render_taxon_or_name($taxon_name, path_to_name($taxon_name->uuid)));
350
  }
351
  if (isset_not_empty($du_dto->characterData)) {
352
    $table_row_data[] = cdm_sob_dto_table_row(
353
      cdm_occurrence_field_name_label('characterData'),
354
      icon_link(path_to_specimen($du_dto->uuid), '', FALSE), false);
355
  }
356

    
357
  $heading = $table_row_data[0]['data'][1];
358
  unset($table_row_data[0]);
359
  return cdm_sob_dto_table(t($heading), $table_row_data, $du_dto, 1);
360
}
361

    
362
/**
363
 * Compose an render array from a CDM GatheringDTO.
364
 *
365
 * The resulting DOM block level element will have a header line and details.
366
 *
367
 * compose_hook() implementation
368
 *
369
 * @param object $gathering_dto
370
 *   the CDM GatheringDTO object
371
 * @param bool $compact_mode
372
 *   Currently unused,
373
 *
374
 * @return array
375
 *  The render array for the GatheringDTO
376
 *
377
 * @ingroup compose
378
 */
379
function compose_cdm_gathering_dto_details($gathering_dto, $compact_mode = FALSE) {
380

    
381
  $table_row_data = [];
382
  if (isset_not_empty($gathering_dto->date)) {
383
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('date'),
384
      partialToDate($gathering_dto->date));
385
  }
386
  if (isset_not_empty($gathering_dto->collector)) {
387
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('collector'),
388
      $gathering_dto->collector);
389
  }
390
  if (isset_not_empty($gathering_dto->description)) {
391
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('description'),
392
      $gathering_dto->description);
393
  }
394
  if (isset_not_empty($gathering_dto->locality)) {
395
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('locality'),
396
      $gathering_dto->locality);
397
  }
398
  if (isset_not_empty($gathering_dto->country)) {
399
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('country'),
400
      $gathering_dto->country);
401
  }
402
  if (isset_not_empty($gathering_dto->collectingMethod)) {
403
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('collectingMethod'),
404
      $gathering_dto->collectingMethod);
405
  }
406
  if (isset($gathering_dto->exactLocation)) {
407
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('exactLocation'),
408
      render_point($gathering_dto->exactLocation));
409
  }
410
  if (isset($gathering_dto->absoluteElevation)) {
411
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('absoluteElevation'),
412
      statistical_values_from_gathering_event($gathering_dto, 'absoluteElevation'));
413
  }
414
  if (isset($gathering_dto->distanceToGround) && $gathering_dto->distanceToGround > 0) {
415
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('distanceToGround'),
416
      statistical_values_from_gathering_event($gathering_dto, 'distanceToGround'));
417
  }
418
  if (isset($gathering_dto->distanceToWaterSurface) && $gathering_dto->distanceToWaterSurface > 0) {
419
    $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('distanceToWaterSurface'),
420
      statistical_values_from_gathering_event($gathering_dto, 'distanceToWaterSurface'));
421
  }
422
  if (isset_not_empty($gathering_dto->collectingAreas)) {
423
    $area_representations = [];
424
    foreach ($gathering_dto->collectingAreas as $area) {
425
      // $area_representations[] = l($area->representation_L10n, path_to_named_area($area->uuid));
426
      $area_representations[] = $area;
427
    }
428
    if (!empty($area_representations)) {
429
      $table_row_data[] = cdm_sob_dto_table_row(cdm_occurrence_field_name_label('collectingAreas'),
430
        implode(', ', $area_representations)
431
      );
432
    }
433
  }
434

    
435
  return cdm_sob_dto_table(t("Gathering & Location"), $table_row_data, $gathering_dto, 1);
436
}
437

    
438
/**
439
 * Compose an render array from the SpecimenOrObservationDTO.determinedNames.
440
 *
441
 * The resulting DOM block level element will have a header line and details.
442
 *
443
 * compose_hook() implementation
444
 *
445
 * @param object $sob_dto
446
 *   the CDM SpecimenOrObservationDTO
447
 * @param bool $compact_mode
448
 *   Currently unused,
449
 *
450
 * @return array
451
 *  The render array for the SpecimenOrObservationDTO.determinedNames
452
 *
453
 * @ingroup compose
454
 */
455
function compose_cdm_sob_dto_determinations($sob_dto, $compact_mode = FALSE) {
456

    
457
  $table_row_data = [];
458

    
459
  foreach ($sob_dto->determinedNames as $name) {
460
    $taxon_name = cdm_ws_get(CDM_WS_PORTAL_NAME, $name->uuid);
461
    $table_row_data[] = cdm_sob_dto_table_row(NULL, render_taxon_or_name($taxon_name, url(path_to_name($taxon_name->uuid))));
462
  }
463

    
464
  $label = count($table_row_data) > 1 ? t("Identifications") : t("Identification");
465
  return cdm_sob_dto_table($label, $table_row_data, $sob_dto, 1);
466
}
467

    
468
/**
469
 * Compose an render array from the DerivedUnitDTO.specimenTypeDesignations.
470
 *
471
 * The resulting DOM block level element will have a header line and details.
472
 *
473
 * compose_hook() implementation
474
 *
475
 * @param object $unit_dto
476
 *   the CDM DerivedUnitDTO
477
 * @param bool $compact_mode
478
 *   Currently unused,
479
 *
480
 * @return array
481
 *  The render array for the SpecimenOrObservationDTO.determinedNames
482
 *
483
 * @ingroup compose
484
 */
485
function compose_cdm_unit_dto_type_designations($unit_dto, $compact_mode = FALSE) {
486

    
487
  $table_row_data = [];
488

    
489
  if (isset_not_empty($unit_dto->specimenTypeDesignations)) {
490
    $table_row_data[] = cdm_sob_dto_table_row(
491
      NULL,
492
      render_specimen_typedesignation_dto($unit_dto->specimenTypeDesignations));
493
  }
494

    
495
  return cdm_sob_dto_table(t('Type designations'), $table_row_data, $unit_dto, 5, 2);
496
}
497

    
498
/**
499
 * @param $listOfMedia
500
 * @param $sob_dto
501
 * @param $heading
502
 *
503
 * @return array|null
504
 */
505
function cdm_sob_dto_media_table(array $listOfMedia, $sob_dto, $heading) {
506
  $table_row_data = [];
507
  $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
508
  $captionElements = array(
509
    'title',
510
    '#uri' => t('open media'),
511
  );
512
  $gallery_markup = compose_cdm_media_gallerie(array(
513
    'mediaList' => $listOfMedia,
514
    'galleryName' => $sob_dto->uuid,
515
    'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
516
    'cols' => $gallery_settings['cdm_dataportal_media_cols'],
517
    'maxRows' => isset($gallery_settings['cdm_dataportal_media_maxRows']) ? isset($gallery_settings['cdm_dataportal_media_maxRows']) : null,
518
    'captionElements' => $captionElements,
519
    'mediaLinkType' => 'LIGHTBOX',
520
    'alternativeMediaUri' => NULL,
521
    'galleryLinkUri' => NULL,
522
    'showCaption' => true
523
  ));
524
  $table_row_data[] = cdm_sob_dto_table_row(NULL, $gallery_markup);
525
  $grid_col_span = count($listOfMedia) > 1 ? 2 : NULL;
526
  return cdm_sob_dto_table(t($heading), $table_row_data, $sob_dto, 20, $grid_col_span);
527
}
528

    
529
/**
530
 * Compose an render array from the DerivedUnitDTO.sequences.
531
 *
532
 * The resulting DOM block level element will have a header line and details.
533
 *
534
 * compose_hook() implementation
535
 *
536
 * @param object $unit_dto
537
 *   the CDM DerivedUnitDTO
538
 * @param bool $compact_mode
539
 *   Currently unused,
540
 *
541
 * @return array
542
 *  The render array for the DerivedUnitDTO.sequences.
543
 *
544
 * @ingroup compose
545
 *
546
 * TODO see  #3347 (services and REST service controller for molecular classes implemented)
547
 */
548
function compose_cdm_derived_unit_dto_sequences($unit_dto, $compact_mode = FALSE) {
549

    
550
  $table_row_data = [];
551
  if(isset_not_empty($unit_dto->sequences)){
552
    foreach ($unit_dto->sequences as $sequence) {
553
      if (isset($sequence->geneticAccessionNumber)) {
554
        $table_row_data[] = cdm_sob_dto_table_row(
555
          cdm_occurrence_field_name_label('geneticAccessionNumber'),
556
          $sequence->geneticAccessionNumber);
557
      }
558
      // TODO ....
559
    }
560
  }
561

    
562
  return cdm_sob_dto_table(t('Storage'), $table_row_data, $unit_dto, 1);
563
}
564

    
565
/**
566
 * Creates a form array for showing details of SpecimenOrObservationDTO in a
567
 * tabular form with heading.
568
 *
569
 * @param $table_heading
570
 * @param array $table_row_data
571
 * @param $sob_dto
572
 * @param $weight
573
 *  The weight determining the order of the drupal render element
574
 * @param $grid_col_span
575
 *  The number of grid colums the table should
576
 *
577
 * @return array|null
578
 */
579
function cdm_sob_dto_table($table_heading, array $table_row_data, $sob_dto, $weight = NULL, $grid_col_span = 1) {
580

    
581
  if (count($table_row_data) > 0) {
582
    $wrapper_style = '';
583
    if($grid_col_span > 1){
584
      $wrapper_style = ' style="grid-column-start: span ' . $grid_col_span. ';"';
585
    }
586
    $sob_table = [
587
      '#theme' => 'table',
588
      '#prefix' => '<div class="table-wrapper"' . $wrapper_style . '>',
589
      '#suffix' => '</div>',
590
      '#header' => [
591
        [
592
          'data' => $table_heading,
593
          'colspan' => 2,
594
        ],
595
      ],
596
      "#rows" => $table_row_data,
597
      "#attributes" => [
598
        "class" => [
599
          'specimen-or-observation-details',
600
          html_class_attribute_ref($sob_dto)
601
        ],
602
      ],
603
    ];
604
    if ($weight) {
605
      $sob_table['#weight'] = $weight;
606
    }
607
    return $sob_table;
608
  }
609
  return NULL;
610
}
611

    
612
function cdm_sob_dto_table_row($label, $value) {
613
  if ($value) {
614
    if($label) {
615
      return [
616
        'data' => [
617
          [
618
            'data' => str_replace(':', '', $label),
619
            'class' => [
620
              'label',
621
            ],
622
          ],
623
          $value,
624
        ],
625
        'no_striping' => TRUE,
626
      ];
627
    } else {
628
      // value spanning two columns
629
      return [
630
        'data' => [
631
          [
632
            'data' => $value,
633
            'colspan' => 2,
634
          ]
635
        ],
636
        'no_striping' => TRUE,
637
      ];
638
    }
639
  }
640
  return NULL;
641
}
(9-9/15)