Project

General

Profile

Download (17.6 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * Functions for dealing with CDM entities from the package model.common
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
 * @defgroup compose Compose functions
21
 * @{
22
 * Functions which are composing Drupal render arays
23
 *
24
 * The cdm_dataportal module needs to compose rather complex render arrays from
25
 * the data returned by the CDM REST service. The compose functions are
26
 * responsible for creating the render arrays.
27
 *
28
 * All these functions are also implementations of the compose_hook()
29
 * which is used in the proxy_content() function.
30
 * @}
31
 */
32

    
33
/**
34
 * Compose an render array from a CDM Marker object.
35
 *
36
 * compose_hook() implementation
37
 *
38
 * @param object $marker
39
 *   CDM instance of type Marker
40
 * @return array
41
 *   A drupal render array
42
 *
43
 * @ingroup compose
44
 */
45
function compose_cdm_marker($marker) {
46

    
47
  $render_array = array(
48
      // ---- generic
49
      //  these entries should be common to all cdm enitiy render arrays
50
      '#theme' => 'cdm_marker', // TODO   add alternative theme funcitons: 'cdm_marker_' . marker.type.label
51
      '#attributes' => array('class' => html_class_attribute_ref($marker)),
52

    
53
      // ---- individual
54
      '#label' => $marker->markerType->representation_L10n . ': ' . (($marker->flag !== TRUE ? t('yes') : t('no'))),
55
  );
56

    
57
  return $render_array;
58
}
59

    
60
/**
61
 * Checks if the given $cdm_entitiy has a marker the type references by the
62
 * $marker_type_uuid and returns TRUE if a matching marker has been found.
63
 *
64
 * @param object $cdm_entitiy A CDM Entity
65
 * @param string $marker_type_uuid
66
 */
67
function cdm_entity_has_marker($cdm_entitiy, $marker_type_uuid) {
68
  if(isset($cdm_entitiy->markers[0]) && !is_uuid($marker_type_uuid)){
69
    foreach ($cdm_entitiy->markers as $marker) {
70
      if(isset($marker->markerType) && $marker->markerType->uuid == $marker_type_uuid){
71
        return TRUE;
72
      }
73
    }
74
  }
75
  return FALSE;
76
}
77

    
78
/**
79
 * Sorts an array of CDM IdentifiableSource instances by 1. by the
80
 * author teams family names and 2. by the publication date.
81
 *
82
 * @param array $sources
83
 *    The array of CDM IdentifiableSource instances
84
 * @return array
85
 *  An array of drupal render arrays
86
 */
87
function oder_and_render_original_sources($sources){
88
    $sort_array = array();
89
    foreach ($sources as $source) {
90

    
91
      $order_key = '';
92

    
93
      // find the familynames
94
      if(isset($source->citation->uuid) && !isset($source->citation->authorship)){
95
        $authorteam = cdm_ws_get(CDM_WS_REFERENCE_AUTHORTEAM, $source->citation->uuid);
96

    
97
        $persons = array();
98
        if($authorteam->class == 'Team'){
99
          if(isset($authorteam->teamMembers)){
100
            $persons = $authorteam->teamMembers;
101
          }
102
        } else {
103
          $persons[] = $authorteam;
104
        }
105

    
106
        foreach($persons as $person){
107
          if(!empty($person->lastname)){
108
            $order_key .= $person->lastname;
109
          } else {
110
            $order_key .= $person->titleCache;
111
          }
112
        }
113
        if(empty($order_key)){
114
          $order_key = $authorteam->titleCache;
115
        }
116

    
117
      }
118
      $order_key = str_pad($order_key, 50);
119

    
120
      // add publication date to the key
121
      if(isset($source->citation->datePublished)){
122
        $order_key .= '_' . timePeriodAsOrderKey($source->citation->datePublished);
123
      } else {
124
        $order_key .= '_' . "0000";
125
      }
126

    
127
      // padd key until unique
128
      while(array_key_exists($order_key, $sort_array)){
129
        $order_key .= "_";
130
      }
131

    
132
      $sort_array[$order_key] = render_original_source($source);
133
    }
134
    ksort($sort_array);
135
    return array_values ($sort_array);
136
}
137

    
138
/**
139
 * Compare callback to be used in usort to sort image sources of CDM OriginalSource instances.
140
 *
141
 * TODO the compare strategy implemented in oder_and_render_original_sources() is probably better but is not taking the
142
 * originalName into account.
143
 *
144
 * @param $a
145
 * @param $b
146
 */
147
function compare_original_sources($a, $b){
148

    
149
  $a_string = '';
150
  if(isset($a->citation->titleCache)) {
151
    $a_string = $a->citation->titleCache;
152
  }
153
  if((isset($a->nameUsedInSource))){
154
    $a_string .= $a->nameUsedInSource->titleCache;
155
  } elseif (isset($a->originalNameString)){
156
    $a_string .= $a->originalNameString;
157
  }
158

    
159
  $b_string = '';
160
  if(isset($b->citation->titleCache)) {
161
    $b_string = $b->citation->titleCache;
162
  };
163
  if((isset($b->nameUsedInSource))){
164
    $b_string .= $b->nameUsedInSource->titleCache;
165
  } elseif (isset($b->originalNameString)){
166
    $b_string .= $b->originalNameString;
167
  }
168

    
169
  if ($a_string == $b_string) {
170
    return 0;
171
  }
172
  return ($a_string < $b_string) ? -1 : 1;
173
}
174

    
175
/**
176
 * Compare callback to be used in usort to sort image sources of CDM Media instances.
177
 *
178
 * @param $a
179
 * @param $b
180
 */
181
function compare_text_data($a, $b) {
182

    
183
  if ($a->multilanguageText_L10n->text == $b->multilanguageText_L10n->text) {
184
    return 0;
185
  }
186
  return ($a->multilanguageText_L10n->text < $b->multilanguageText_L10n->text) ? -1 : 1;
187
}
188

    
189
  /**
190
   * Compare two different footnotes objects.
191
   *
192
   * The comparison is based on the footnote key. The one which is
193
   * displayed as footnote number.
194
   *
195
   * @param mixed $a
196
   *   Footnote object $a.
197
   * @param mixed $b
198
   *   Footnote object $b.
199
   */
200
  function footnotes_key_compare($a, $b) {
201
    $res = 0;
202
    if (empty($a) || empty($b)) {
203
      return $res;
204
    }
205
    if ($a->keyStr < $b->keyStr) {
206
      $res = -1;
207
    }
208
    elseif ($a->keyStr > $b->keyStr) {
209
      $res = 1;
210
    }
211
    return $res;
212
  }
213

    
214

    
215
/**
216
 * Creates an array suitable to be used in min_max_markup()
217
 *
218
 * @return array
219
 */
220
function min_max_array()
221
{
222
// FIXME use UUIDs instead? how about idInVocab?
223
  $min_max = array(
224
      'Extreme Min' => NULL,
225
      'Min' => NULL,
226
      'Average' => NULL,
227
      'Max' => NULL,
228
      'Extreme Max' => NULL,
229
  );
230
  return $min_max;
231
}
232

    
233
/**
234
 * Creates markup from a min max array.
235
 *
236
 * NOTE: use  min_max_array() to create an appropriate array
237
 *
238
 * @param $min_max
239
 *  the min-max array
240
 * @param $unit
241
 *  Defaults to no unit
242
 * @return string
243
 */
244
function min_max_markup($min_max, $unit = '') {
245

    
246
  $min_max_markup = '';
247
  // create min-max string
248
  if ($min_max['Min'] !== NULL && $min_max['Max'] !== NULL && $min_max['Min']->_value == $min_max['Max']->_value) {
249
    // min and max are identical
250
    $min_max['Average'] = $min_max['Min'];
251
    $min_max['Min'] = NULL;
252
    $min_max['Max'] = NULL;
253
  }
254

    
255
  // check for inconsistent cases, eg. only Max and average given
256
  if ($min_max['Min'] === NULL && $min_max['Max'] !== NULL) {
257
    // min missing
258
    $min_max['Min'] = '?';
259
  }
260
  if ($min_max['Min'] !== NULL && $min_max['Max'] === NULL) {
261
    // max missing
262
    $min_max['Max'] = '?';
263
  }
264

    
265

    
266
  foreach ($min_max as $key => $statistical_val) {
267
    if ($statistical_val !== NULL) {
268

    
269
      if ($statistical_val == '?') {
270
        $val_markup = $statistical_val;
271
      } else {
272
        $val_markup = '<span class="'
273
            . html_class_attribute_ref($statistical_val) . ' '
274
            . (isset($statistical_val->type) ? $statistical_val->type->termType : '') . ' ">'
275
            . $statistical_val->_value . '</span>';
276
      }
277

    
278
      if (strlen($min_max_markup)) {
279
        $min_max_markup .= '–';
280
      }
281
      if (str_beginsWith($key, 'Extreme')) {
282
        $val_markup = "($val_markup)";
283
      }
284
      $min_max_markup .= $val_markup;
285
    }
286
  }
287
  return $min_max_markup . ' ' . $unit;
288
}
289

    
290
/**
291
 * Creates min max markup to represent a min-average-max measure optionally with an error value.
292
 *
293
 * The fields that are taken into account are:
294
 * - field_base_name = min
295
 * - field_base_nameMax = max
296
 * - field_base_nameText = free text
297
 * - field_base_nameError = error value
298
 *
299
 * @param $object
300
 *    The object having min max measurement fields
301
 * @param string $field_base_name
302
 *    The base name for all measurement fields. This name is at the same time the full name of the
303
 *    min value.
304
 * @return string
305
 *   The markup for the min max
306
 */
307
function min_max_measure($object, $field_base_name)
308
{
309
  static $default_unit = 'm';
310

    
311
  $field_name = $field_base_name . 'Text';
312
  if (@is_string($object->$field_name)) {
313
    // Freetext overrides all other data
314
    $min_max_markup = ' ' . $object->$field_name;
315
  } else {
316
    // create markup for the atomized min max data
317
    $min_max_array = min_max_array();
318
    if (@is_numeric($object->$field_base_name)) {
319
      $min_max_array['Min'] = new stdClass();
320
      $min_max_array['Min']->_value = $object->$field_base_name;
321
    }
322
    $field_name = $field_base_name . 'Max';
323
    if (@is_numeric($object->$field_name)) {
324
      $min_max_array['Max'] = new stdClass();
325
      $min_max_array['Max']->_value = $object->$field_name;
326
    }
327
    $min_max_markup = min_max_markup($min_max_array, $default_unit);
328
  }
329

    
330
  return $min_max_markup;
331
}
332

    
333
// TODO  move below code into new file: agent.inc
334

    
335
/*
336
 * Compose an render array from a CDM TaxonNodeAgentRelation object as Taxon Expert.
337
 *
338
 * compose_hook() implementation
339
 *
340
 * @param object $taxon_node_agent_relation
341
 *   CDM instance of type TaxonNodeAgentRelation
342
 * @return array
343
 *   A drupal render array
344
 *
345
 * @ingroup compose
346
 */
347
function compose_cdm_taxon_expert($taxon_node_agent_relation) {
348

    
349
  $label_suffix = ':';
350

    
351
  if($taxon_node_agent_relation->class == 'DefaultPagerImpl'){
352
    // oops this is a pager
353
    // this situation will occur when this compose is executed
354
    // through the proxy_content() method
355
    $taxon_node_agent_relation = $taxon_node_agent_relation->records[0];
356

    
357
  }
358

    
359
  if(is_object($taxon_node_agent_relation->agent)) {
360
    $agent_details = compose_cdm_team_or_person_base($taxon_node_agent_relation->agent);
361
    // all data will be added to the groups of the agent_details render array
362
    $groups = &$agent_details[0]['#groups'];
363

    
364
    @_description_list_group_add($groups, t('Role'). $label_suffix, $taxon_node_agent_relation->type->representation_L10n);
365

    
366
    $family_tnars = cdm_ws_fetch_all(CDM_WS_PORTAL_AGENT . '/' . $taxon_node_agent_relation->agent->uuid . '/taxonNodeAgentRelations', array("rank"=>"Familia"));
367

    
368
    $taxa_markup = array(
369
      '#theme_wrappers' => array('container'),
370
      '#attributes' => array('class' => array('managed_taxa')),
371
      '#wrapper_attributes' => array('class' => 'sublist-container')
372
      );
373
    foreach($family_tnars as $tnar){
374
      if(is_object($tnar->taxonNode->taxon)){
375
        $taxa_markup[$tnar->taxonNode->taxon->titleCache] = markup_to_render_array(render_taxon_or_name($tnar->taxonNode->taxon, url(path_to_taxon($tnar->taxonNode->taxon->uuid))));
376
      }
377
    }
378
    ksort($taxa_markup);
379

    
380
    @_description_list_group_add($groups, t('Families'). $label_suffix, array($taxa_markup));
381

    
382
  }
383

    
384
  return $agent_details;
385
}
386

    
387

    
388
/*
389
 * Compose an render array from a CDM TeamOrPersonBase object.
390
 *
391
 * compose_hook() implementation
392
 *
393
 * TODO: currently mainly implemented for Agent, add Team details
394
 *
395
 * @param object $team_or_person
396
 *   CDM instance of type TeamOrPersonBase
397
 * @return array
398
 *   A drupal render array
399
 *
400
 * @ingroup compose
401
 */
402
function compose_cdm_team_or_person_base($team_or_person, $data = array()) {
403

    
404
  $groups = array();
405

    
406
  $label_suffix = ':';
407

    
408
  // $weight = 0;
409
  if($team_or_person){
410

    
411
    if(is_object($team_or_person->lifespan)){
412
      // ToDo render as date* - date† ?
413
      @_description_list_group_add($groups, t('Lifespan'). $label_suffix, timePeriodToString($team_or_person->lifespan) /*, '' , $weight++ */);
414
    }
415

    
416
    // nomenclaturalTitle
417
    @_description_list_group_add($groups, "Nomenclatural Title". $label_suffix, $team_or_person->nomenclaturalTitle);
418
    // collectorTitle
419
    @_description_list_group_add($groups, "Collector Title". $label_suffix, $team_or_person->collectorTitle);
420

    
421
    // institutionalMemberships
422
    if(is_array($team_or_person->institutionalMemberships)){
423

    
424
      $institutes_ra =  array();
425
      foreach($team_or_person->institutionalMemberships as $membership) {
426
        $membership_groups = array();
427
        @_description_list_group_add($membership_groups, t('Department'). $label_suffix, $membership->department);
428
        @_description_list_group_add($membership_groups, t('Role'). $label_suffix, $membership->role);
429
        if(is_object($membership->period)){
430
          @_description_list_group_add($membership_groups, t('Period'). $label_suffix, timePeriodToString($membership->period));
431
        }
432
        if(is_object($membership->institute->contact)){
433
          $institute_contact_details = compose_cdm_contact($membership->institute->contact, $membership->institute->titleCache);
434
          if(is_array($institute_contact_details[0]['#groups'])){
435
            $membership_groups = array_merge($membership_groups, $institute_contact_details[0]['#groups']);
436
          }
437
        }
438
        if(count($membership_groups) > 0){
439
          $institutes_ra[]  = array(
440
            '#title' => $membership->institute->titleCache,
441
            '#theme' => 'description_list',
442
            '#groups' => $membership_groups,
443
            '#attributes' => array('class' => html_class_attribute_ref($membership)),
444
            '#wrapper_attributes' => array('class' => 'sublist-container')
445
          );
446
        } else {
447
          // no further details for the membership, display the title
448
          $institutes_ra[] = markup_to_render_array('<h3>' . $membership->institute->titleCache . '</h3>');
449
        }
450

    
451
      }
452

    
453
      $label = count($institutes_ra) > 1 ? t('Institutes'):  t('Institute');
454
      @_description_list_group_add($groups, $label. $label_suffix, $institutes_ra /*, '' , $weight++ */);
455
    }
456

    
457

    
458
    // Contact
459
    $agent_contact_details = compose_cdm_contact($team_or_person->contact, $team_or_person->titleCache);
460
    if(is_array($agent_contact_details[0]['#groups'])){
461
      $groups = array_merge($groups, $agent_contact_details[0]['#groups']);
462
    }
463

    
464
    // additional data
465
    foreach($data as $key=>$value){
466
      @_description_list_group_add($sub_dl_groups, t('@key', array('@key' => $key)), $value /*, '' , $weight++ */);
467
    }
468

    
469
  }
470

    
471
  $team_or_person_details = array(
472
    '#title' => $team_or_person->titleCache,
473
    '#theme' => 'description_list',
474
    '#groups' => $groups,
475
    '#attributes' => array('class' => html_class_attribute_ref($team_or_person)),
476
  );
477
  return array($team_or_person_details);
478
}
479

    
480

    
481
/*
482
 * Compose an render array from a CDM Contact object.
483
 *
484
 * compose_hook() implementation
485
 *
486
 * TODO: currently mainly implemented for Agent, add Team details
487
 *
488
 * @param object $contact
489
 *   CDM instance of type Contact
490
 * @param $title
491
 *   The title for the description list header
492
 * @param $weight
493
 *   Optional weight for the description list entries
494
 * @return array
495
 *   A drupal render array
496
 *
497
 * @ingroup compose
498
 */
499
function compose_cdm_contact($contact, $title, $weight = 0)
500
{
501

    
502
  $groups = array();
503

    
504
  $contact_details = null;
505

    
506
  $label_suffix = ':';
507

    
508
  $contact_field_names_map = array(
509
    'emailAddresses' => t('Email'),
510
    'urls' => t('Urls'),
511
    'phoneNumbers' => t('Phone'),
512
    'faxNumbers' => t('Fax'),
513
  );
514

    
515
  // Contact
516
  if(is_object($contact)){
517
    if(isset($contact->addresses)){
518
      // TODO ....
519
      // $sub_groups = array();
520
      // foreach($contact->addresses as $address){
521
      //   @_description_list_group_add($sub_groups, $label, $contact->$fieldName, '', $weight++);
522
      // }
523
    }
524
    foreach($contact_field_names_map as $fieldName => $label){
525
      if(is_array($contact->$fieldName)){
526
        @_description_list_group_add($groups, $label . $label_suffix, $contact->$fieldName, '', $weight++);
527
      }
528
    }
529
    $contact_details = array(
530
      '#title' => $title,
531
      '#theme' => 'description_list',
532
      '#groups' => $groups
533
    );
534

    
535

    
536
  } else if(is_string($title)) {
537
    // if the contact entity is empty but the title is given anyway
538
    // we are only adding the title, using the description_list
539
    // structure is not possible since it would be empty due to
540
    // missing group data
541
    $contact_details = array('#markup' => '<h3>' . $title . '</h3>');
542
  }
543

    
544
  return array($contact_details);
545

    
546
}
547

    
548
/**
549
 * Compose an render array from a CDM Extension objects.
550
 *
551
 * @param $extensions
552
 *    An array of CDM Extension objects
553
 * @return array
554
 *   A render array containing the fields of the supplied $sequence
555
 *
556
 * @ingroup compose
557
 */
558
function compose_extensions($extensions)
559
{
560
  $extensions_render_array= null;
561
  $extensions_by_type = array();
562
  foreach ($extensions as $extension) {
563
    if (@is_string($extension->value)) {
564
      if (!isset($extensions_by_type[$extension->type->representation_L10n])) {
565
        $extensions_by_type[$extension->type->representation_L10n] = array();
566
      }
567
      $extensions_by_type[$extension->type->representation_L10n][] = markup_to_render_array($extension->value);
568
    }
569
  }
570

    
571
  if (count($extensions_by_type)) {
572
    $sub_dl_groups = array();
573
    foreach ($extensions_by_type as $type_label => $text_list) {
574
      @_description_list_group_add($sub_dl_groups, $type_label . ':', $text_list);
575
    }
576
    $extensions_render_array = array(
577
      array('#theme' => 'description_list', '#groups' => $sub_dl_groups)
578
    );
579
    return $extensions_render_array;
580
  }
581
  return $extensions_render_array;
582
}
583

    
584
function formatParams($params) {
585
    if (is_array($params)){
586
        $keys =array_keys($params);
587
        $paramString = '';
588
        foreach ($keys as $k ){
589
            if ($k != 'pageNumber' && $k != 'pageSize'){
590
                $paramString .= ' -'.$k.'='.urlencode($params[$k]);
591
            }
592
        }
593
    }
594
    return $paramString;
595
}
596

    
597
function formatWSParams($params) {
598
    if (is_array($params)){
599
        $keys =array_keys($params);
600
        $paramString = '';
601
        foreach ($keys as $k ){
602
            if ($k != 'pageNumber' && $k != 'pageSize'){
603
                $paramString .= '&'.$k.'='.urlencode($params[$k]);
604
            }
605
        }
606
    }
607
    return $paramString;
608
}
609

    
(1-1/10)