Project

General

Profile

Download (14.3 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 = $a->citation->titleCache;
156
  if((isset($a->nameUsedInSource))){
157
    $a_string .= $a->nameUsedInSource->titleCache;
158
  } elseif (isset($a->originalNameString)){
159
    $a_string .= $a->originalNameString;
160
  }
161

    
162
  $b_string = $b->citation->titleCache;
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
 * NOTE: use  min_max_array() to create an appropriate array
235
 *
236
 * @param $min_max
237
 * @return string
238
 */
239
function min_max_markup($min_max) {
240

    
241
  $min_max_markup = '';
242
  // create min-max string
243
  if ($min_max['Min'] !== NULL && $min_max['Max'] !== NULL && $min_max['Min']->_value == $min_max['Max']->_value) {
244
    $min_max['Average'] = $min_max['Min'];
245
    $min_max['Min'] = NULL;
246
    $min_max['Max'] = NULL;
247
  }
248

    
249
  // check for inconsistent cases, eg. only Max and average given
250
  if ($min_max['Min'] === NULL && $min_max['Max'] !== NULL) {
251
    $min_max['Min'] = '?';
252
  }
253
  if ($min_max['Min'] !== NULL && $min_max['Max'] === NULL) {
254
    $min_max['Max'] = '?';
255
  }
256

    
257

    
258
  foreach ($min_max as $key => $statistical_val) {
259
    if ($statistical_val !== NULL) {
260

    
261
      if ($statistical_val == '?') {
262
        $val_markup = $statistical_val;
263
      } else {
264
        $val_markup = '<span class="'
265
            . html_class_attribute_ref($statistical_val) . ' '
266
            . (isset($statistical_val->type) ? $statistical_val->type->termType : '') . ' ">'
267
            . $statistical_val->_value . '</span>';
268
      }
269

    
270
      if (strlen($min_max_markup)) {
271
        $min_max_markup .= '–';
272
      }
273
      if (str_beginsWith($key, 'Extreme')) {
274
        $val_markup = "($val_markup)";
275
      }
276
      $min_max_markup .= $val_markup;
277
    }
278
  }
279
  return $min_max_markup;
280
}
281

    
282
// TODO  move below code into new file: agent.inc
283

    
284
/*
285
 * Compose an render array from a CDM TaxonNodeAgentRelation object as Taxon Expert.
286
 *
287
 * compose_hook() implementation
288
 *
289
 * @param object $taxon_node_agent_relation
290
 *   CDM instance of type TaxonNodeAgentRelation
291
 * @return array
292
 *   A drupal render array
293
 *
294
 * @ingroup compose
295
 */
296
function compose_cdm_taxon_expert($taxon_node_agent_relation) {
297

    
298
  $label_suffix = ':';
299

    
300
  if($taxon_node_agent_relation->class == 'DefaultPagerImpl'){
301
    // oops this is a pager
302
    // this situation will occur when this compose is executed
303
    // through the proxy_content() method
304
    $taxon_node_agent_relation = $taxon_node_agent_relation->records[0];
305

    
306
  }
307

    
308
  if(is_object($taxon_node_agent_relation->agent)) {
309
    $agent_details = compose_cdm_team_or_person_base($taxon_node_agent_relation->agent);
310
    // all data will be added to the groups of the agent_details render array
311
    $groups = &$agent_details[0]['#groups'];
312

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

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

    
317
    $taxa_markup = array(
318
      '#theme_wrappers' => array('container'),
319
      '#attributes' => array('class' => array('managed_taxa')),
320
      '#wrapper_attributes' => array('class' => 'sublist-container')
321
      );
322
    foreach($family_tnars as $tnar){
323
      if(is_object($tnar->taxonNode->taxon)){
324
        $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))));
325
      }
326
    }
327
    ksort($taxa_markup);
328

    
329
    @_description_list_group_add($groups, t('Families'). $label_suffix, array($taxa_markup));
330

    
331
  }
332

    
333
  return $agent_details;
334
}
335

    
336

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

    
353
  $groups = array();
354

    
355
  $label_suffix = ':';
356

    
357
  // $weight = 0;
358
  if($team_or_person){
359

    
360
    if(is_object($team_or_person->lifespan)){
361
      // ToDo render as date* - date† ?
362
      @_description_list_group_add($groups, t('Lifespan'). $label_suffix, timePeriodToString($team_or_person->lifespan) /*, '' , $weight++ */);
363
    }
364

    
365
    // nomenclaturalTitle
366
    @_description_list_group_add($groups, "Nomenclatural Title". $label_suffix, $team_or_person->nomenclaturalTitle);
367
    // collectorTitle
368
    @_description_list_group_add($groups, "Collector Title". $label_suffix, $team_or_person->collectorTitle);
369

    
370
    // institutionalMemberships
371
    if(is_array($team_or_person->institutionalMemberships)){
372

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

    
400
      }
401

    
402
      $label = count($institutes_ra) > 1 ? t('Institutes'):  t('Institute');
403
      @_description_list_group_add($groups, $label. $label_suffix, $institutes_ra /*, '' , $weight++ */);
404
    }
405

    
406

    
407
    // Contact
408
    $agent_contact_details = compose_cdm_contact($team_or_person->contact, $team_or_person->titleCache);
409
    if(is_array($agent_contact_details[0]['#groups'])){
410
      $groups = array_merge($groups, $agent_contact_details[0]['#groups']);
411
    }
412

    
413
    // additional data
414
    foreach($data as $key=>$value){
415
      @_description_list_group_add($sub_dl_groups, t($key), $value /*, '' , $weight++ */);
416
    }
417

    
418
  }
419

    
420
  $team_or_person_details = array(
421
    '#title' => $team_or_person->titleCache,
422
    '#theme' => 'description_list',
423
    '#groups' => $groups,
424
    '#attributes' => array('class' => html_class_attribute_ref($team_or_person)),
425
  );
426
  return array($team_or_person_details);
427
}
428

    
429

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

    
451
  $groups = array();
452

    
453
  $label_suffix = ':';
454

    
455
  $contact_field_names_map = array(
456
    'emailAddresses' => t('Email'),
457
    'urls' => t('Urls'),
458
    'phoneNumbers' => t('Phone'),
459
    'faxNumbers' => t('Fax'),
460
  );
461

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

    
482

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

    
491
  return array($contact_details);
492

    
493
}
(1-1/8)