Project

General

Profile

Download (14.4 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_dataporal 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
 * @param bool $do_theme if set TRUE the sources will be themed
85
 *        by theme_cdm_OriginalSource
86
 * @return multitype:
87
 */
88
function oder_sources($sources, $do_theme = false){
89
    $sort_array = array();
90
    foreach ($sources as $source) {
91

    
92
      $order_key = '';
93

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

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

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

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

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

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

    
133

    
134
      if($do_theme) {
135
        $sort_array[$order_key] = theme('cdm_OriginalSource', array('source' => $source));
136
      } else {
137
        $sort_array[$order_key] = $source;
138
      }
139
    }
140
    ksort($sort_array);
141
    return array_values ($sort_array);
142
}
143

    
144
/**
145
 * Compare callback to be used in usort to sort image sources of CDM OriginalSource instances.
146
 *
147
 * TODO the compare strategy implemnted in oder_sources() is probably better but is not taking the
148
 * originalName into account.
149
 *
150
 * @param $a
151
 * @param $b
152
 */
153
function compare_original_sources($a, $b){
154

    
155
  $a_string = '';
156
  if(isset($a->citation->titleCache)) {
157
    $a_string = $a->citation->titleCache;
158
  }
159
  if((isset($a->nameUsedInSource))){
160
    $a_string .= $a->nameUsedInSource->titleCache;
161
  } elseif (isset($a->originalNameString)){
162
    $a_string .= $a->originalNameString;
163
  }
164

    
165
  $b_string = '';
166
  if(isset($b->citation->titleCache)) {
167
    $b_string = $b->citation->titleCache;
168
  };
169
  if((isset($b->nameUsedInSource))){
170
    $b_string .= $b->nameUsedInSource->titleCache;
171
  } elseif (isset($b->originalNameString)){
172
    $b_string .= $b->originalNameString;
173
  }
174

    
175
  if ($a_string == $b_string) {
176
    return 0;
177
  }
178
  return ($a_string < $b_string) ? -1 : 1;
179
}
180

    
181
/**
182
 * Compare callback to be used in usort to sort image sources of CDM Media instances.
183
 *
184
 * @param $a
185
 * @param $b
186
 */
187
function compare_text_data($a, $b) {
188

    
189
  if ($a->multilanguageText_L10n->text == $b->multilanguageText_L10n->text) {
190
    return 0;
191
  }
192
  return ($a->multilanguageText_L10n->text < $b->multilanguageText_L10n->text) ? -1 : 1;
193
}
194

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

    
220

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

    
239
/**
240
 * NOTE: use  min_max_array() to create an appropriate array
241
 *
242
 * @param $min_max
243
 * @return string
244
 */
245
function min_max_markup($min_max) {
246

    
247
  $min_max_markup = '';
248
  // create min-max string
249
  if ($min_max['Min'] !== NULL && $min_max['Max'] !== NULL && $min_max['Min']->_value == $min_max['Max']->_value) {
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_max['Min'] = '?';
258
  }
259
  if ($min_max['Min'] !== NULL && $min_max['Max'] === NULL) {
260
    $min_max['Max'] = '?';
261
  }
262

    
263

    
264
  foreach ($min_max as $key => $statistical_val) {
265
    if ($statistical_val !== NULL) {
266

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

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

    
288
// TODO  move below code into new file: agent.inc
289

    
290
/*
291
 * Compose an render array from a CDM TaxonNodeAgentRelation object as Taxon Expert.
292
 *
293
 * compose_hook() implementation
294
 *
295
 * @param object $taxon_node_agent_relation
296
 *   CDM instance of type TaxonNodeAgentRelation
297
 * @return array
298
 *   A drupal render array
299
 *
300
 * @ingroup compose
301
 */
302
function compose_cdm_taxon_expert($taxon_node_agent_relation) {
303

    
304
  $label_suffix = ':';
305

    
306
  if($taxon_node_agent_relation->class == 'DefaultPagerImpl'){
307
    // oops this is a pager
308
    // this situation will occur when this compose is executed
309
    // through the proxy_content() method
310
    $taxon_node_agent_relation = $taxon_node_agent_relation->records[0];
311

    
312
  }
313

    
314
  if(is_object($taxon_node_agent_relation->agent)) {
315
    $agent_details = compose_cdm_team_or_person_base($taxon_node_agent_relation->agent);
316
    // all data will be added to the groups of the agent_details render array
317
    $groups = &$agent_details[0]['#groups'];
318

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

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

    
323
    $taxa_markup = array(
324
      '#theme_wrappers' => array('container'),
325
      '#attributes' => array('class' => array('managed_taxa')),
326
      '#wrapper_attributes' => array('class' => 'sublist-container')
327
      );
328
    foreach($family_tnars as $tnar){
329
      if(is_object($tnar->taxonNode->taxon)){
330
        $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))));
331
      }
332
    }
333
    ksort($taxa_markup);
334

    
335
    @_description_list_group_add($groups, t('Families'). $label_suffix, array($taxa_markup));
336

    
337
  }
338

    
339
  return $agent_details;
340
}
341

    
342

    
343
/*
344
 * Compose an render array from a CDM TeamOrPersonBase object.
345
 *
346
 * compose_hook() implementation
347
 *
348
 * TODO: currently mainly implemented for Agent, add Team details
349
 *
350
 * @param object $team_or_person
351
 *   CDM instance of type TeamOrPersonBase
352
 * @return array
353
 *   A drupal render array
354
 *
355
 * @ingroup compose
356
 */
357
function compose_cdm_team_or_person_base($team_or_person, $data = array()) {
358

    
359
  $groups = array();
360

    
361
  $label_suffix = ':';
362

    
363
  // $weight = 0;
364
  if($team_or_person){
365

    
366
    if(is_object($team_or_person->lifespan)){
367
      // ToDo render as date* - date† ?
368
      @_description_list_group_add($groups, t('Lifespan'). $label_suffix, timePeriodToString($team_or_person->lifespan) /*, '' , $weight++ */);
369
    }
370

    
371
    // nomenclaturalTitle
372
    @_description_list_group_add($groups, "Nomenclatural Title". $label_suffix, $team_or_person->nomenclaturalTitle);
373
    // collectorTitle
374
    @_description_list_group_add($groups, "Collector Title". $label_suffix, $team_or_person->collectorTitle);
375

    
376
    // institutionalMemberships
377
    if(is_array($team_or_person->institutionalMemberships)){
378

    
379
      $institutes_ra =  array();
380
      foreach($team_or_person->institutionalMemberships as $membership) {
381
        $membership_groups = array();
382
        @_description_list_group_add($membership_groups, t('Department'). $label_suffix, $membership->department);
383
        @_description_list_group_add($membership_groups, t('Role'). $label_suffix, $membership->role);
384
        if(is_object($membership->period)){
385
          @_description_list_group_add($membership_groups, t('Period'). $label_suffix, timePeriodToString($membership->period));
386
        }
387
        if(is_object($membership->institute->contact)){
388
          $institute_contact_details = compose_cdm_contact($membership->institute->contact, $membership->institute->titleCache);
389
          if(is_array($institute_contact_details[0]['#groups'])){
390
            $membership_groups = array_merge($membership_groups, $institute_contact_details[0]['#groups']);
391
          }
392
        }
393
        if(count($membership_groups) > 0){
394
          $institutes_ra[]  = array(
395
            '#title' => $membership->institute->titleCache,
396
            '#theme' => 'description_list',
397
            '#groups' => $membership_groups,
398
            '#attributes' => array('class' => html_class_attribute_ref($membership)),
399
            '#wrapper_attributes' => array('class' => 'sublist-container')
400
          );
401
        } else {
402
          // no further details for the membership, display the title
403
          $institutes_ra[] = markup_to_render_array('<h3>' . $membership->institute->titleCache . '</h3>');
404
        }
405

    
406
      }
407

    
408
      $label = count($institutes_ra) > 1 ? t('Institutes'):  t('Institute');
409
      @_description_list_group_add($groups, $label. $label_suffix, $institutes_ra /*, '' , $weight++ */);
410
    }
411

    
412

    
413
    // Contact
414
    $agent_contact_details = compose_cdm_contact($team_or_person->contact, $team_or_person->titleCache);
415
    if(is_array($agent_contact_details[0]['#groups'])){
416
      $groups = array_merge($groups, $agent_contact_details[0]['#groups']);
417
    }
418

    
419
    // additional data
420
    foreach($data as $key=>$value){
421
      @_description_list_group_add($sub_dl_groups, t('@key', array('@key' => $key)), $value /*, '' , $weight++ */);
422
    }
423

    
424
  }
425

    
426
  $team_or_person_details = array(
427
    '#title' => $team_or_person->titleCache,
428
    '#theme' => 'description_list',
429
    '#groups' => $groups,
430
    '#attributes' => array('class' => html_class_attribute_ref($team_or_person)),
431
  );
432
  return array($team_or_person_details);
433
}
434

    
435

    
436
/*
437
 * Compose an render array from a CDM Contact object.
438
 *
439
 * compose_hook() implementation
440
 *
441
 * TODO: currently mainly implemented for Agent, add Team details
442
 *
443
 * @param object $contact
444
 *   CDM instance of type Contact
445
 * @param $title
446
 *   The title for the description list header
447
 * @param $weight
448
 *   Optional weight for the description list entries
449
 * @return array
450
 *   A drupal render array
451
 *
452
 * @ingroup compose
453
 */
454
function compose_cdm_contact($contact, $title, $weight = 0)
455
{
456

    
457
  $groups = array();
458

    
459
  $label_suffix = ':';
460

    
461
  $contact_field_names_map = array(
462
    'emailAddresses' => t('Email'),
463
    'urls' => t('Urls'),
464
    'phoneNumbers' => t('Phone'),
465
    'faxNumbers' => t('Fax'),
466
  );
467

    
468
  // Contact
469
  if(is_object($contact)){
470
    if(isset($contact->addresses)){
471
      // TODO ....
472
      // $sub_groups = array();
473
      // foreach($contact->addresses as $address){
474
      //   @_description_list_group_add($sub_groups, $label, $contact->$fieldName, '', $weight++);
475
      // }
476
    }
477
    foreach($contact_field_names_map as $fieldName => $label){
478
      if(is_array($contact->$fieldName)){
479
        @_description_list_group_add($groups, $label . $label_suffix, $contact->$fieldName, '', $weight++);
480
      }
481
    }
482
    $contact_details = array(
483
      '#title' => $title,
484
      '#theme' => 'description_list',
485
      '#groups' => $groups
486
    );
487

    
488

    
489
  } else if(is_string($title)) {
490
    // if the contact entity is empty but the title is given anyway
491
    // we are only adding the title, using the description_list
492
    // structure is not possible since it would be empty due to
493
    // missing group data
494
    $contact_details = array('#markup' => '<h3>' . $title . '</h3>');
495
  }
496

    
497
  return array($contact_details);
498

    
499
}
(1-1/10)