Project

General

Profile

Download (87.9 KB) Statistics
| Branch: | Tag: | Revision:
1 6657531f Andreas Kohlbecker
<?php
2
/**
3
 * @file
4
 * Module to provide a CDM Dataportal.
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
 *   - Wouter Addink <w.addink@eti.uva.nl> (migration from Drupal 5 to Drupal7)
18
 */
19
20 38b27a36 Andreas Kohlbecker
  module_load_include('php', 'cdm_dataportal', 'node_types');
21
  module_load_include('php', 'cdm_dataportal', 'settings');
22
  module_load_include('php', 'cdm_dataportal', 'help');
23
  module_load_include('php', 'cdm_dataportal', 'cdm_dataportal.search');
24
25
  module_load_include('inc', 'cdm_dataportal', 'includes/common');
26 2e31ea9e Andreas Kohlbecker
  module_load_include('inc', 'cdm_dataportal', 'includes/name');
27 b7a20282 Andreas Kohlbecker
  module_load_include('inc', 'cdm_dataportal', 'includes/taxon');
28
  module_load_include('inc', 'cdm_dataportal', 'includes/references');
29 38b27a36 Andreas Kohlbecker
  module_load_include('inc', 'cdm_dataportal', 'includes/pages');
30
  module_load_include('inc', 'cdm_dataportal', 'includes/media');
31
  module_load_include('inc', 'cdm_dataportal', 'includes/maps');
32
  module_load_include('inc', 'cdm_dataportal', 'includes/occurrences');
33
  module_load_include('inc', 'cdm_dataportal', 'includes/descriptions');
34
  module_load_include('inc', 'cdm_dataportal', 'includes/pre-drupal8');
35
36
  module_load_include('inc', 'cdm_dataportal', 'theme/theme_registry');
37
  module_load_include('theme', 'cdm_dataportal', 'theme/cdm_dataportal.common');
38
  module_load_include('theme', 'cdm_dataportal', 'theme/cdm_dataportal.descriptions');
39
  module_load_include('theme', 'cdm_dataportal', 'theme/cdm_dataportal.media');
40
  module_load_include('theme', 'cdm_dataportal', 'theme/cdm_dataportal.occurrence');
41
  module_load_include('theme', 'cdm_dataportal', 'theme/cdm_dataportal.page');
42
  module_load_include('theme', 'cdm_dataportal', 'theme/cdm_dataportal.taxon');
43
  module_load_include('theme', 'cdm_dataportal', 'theme/cdm_dataportal.name');
44
  module_load_include('theme', 'cdm_dataportal', 'theme/cdm_dataportal.references');
45
46
  module_load_include('php', 'cdm_dataportal', 'classes/footnotemanager');
47
  module_load_include('php', 'cdm_dataportal', 'classes/footnote');
48
  module_load_include('php', 'cdm_dataportal', 'classes/footnotekey');
49
  module_load_include('php', 'cdm_dataportal', 'classes/renderhints');
50
51
52
  /* ============================ java script functions ============================= */
53
54
55
  /**
56
  * loads external java script files asynchronously.
57
  *
58
  * @param unknown_type $script_url
59
  */
60
  function drupal_add_js_async($script_url, $callback){
61
62
    drupal_add_js("
63
          jQuery(document).ready(function() {
64
            jQuery.ajax({
65
              url: '" . $script_url . "',
66
              dataType: 'script',
67
              cache: true, // otherwise will get fresh copy every page load
68
              success: function() {
69
                    " . $callback . "
70
              }
71
            });
72
          });"
73
    , 'inline');
74 6657531f Andreas Kohlbecker
  }
75
76 38b27a36 Andreas Kohlbecker
  /**
77
   */
78
  function drupal_add_js_rowToggle($tableId){
79 6657531f Andreas Kohlbecker
80 38b27a36 Andreas Kohlbecker
      drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . '/js/table_modification.js');
81
      drupal_add_js('jQuery(document).ready(function(){
82
          addRowToggle("' . $tableId . '");
83 6657531f Andreas Kohlbecker
      });
84 38b27a36 Andreas Kohlbecker
      ', array('type' => 'inline'));
85
  }
86 d2fd2a4c Andreas Kohlbecker
87 38b27a36 Andreas Kohlbecker
  /**
88
   * @param unknown_type $link_element_selector
89
   * @param unknown_type $progress_element_selector
90
   */
91
  function _add_js_cdm_ws_progressbar($link_element_selector, $progress_element_selector){
92
93
    $callback = "jQuery('" . $link_element_selector . "').cdm_ws_progress('" . $progress_element_selector . "');";
94
95
    drupal_add_js_async(variable_get('cdm_webservice_url', '').'js/cdm_ws_progress.js', $callback);
96
97
    //   drupal_add_js("
98
    //   	  if (Drupal.jsEnabled) {
99
    //         $(document).ready(function() {
100
    //       		$('" . $link_element_selector . "').cdm_ws_progress('" . $progress_element_selector . "');
101
    //         });
102
    //       }", 'inline');
103
    }
104
105
  /**
106
   * @todo Please document this function.
107
   * @see http://drupal.org/node/1354
108
   */
109
  function _add_js_treeselector() {
110
    // drupal_add_js(drupal_get_path('module', 'cdm_dataportal').'/js/treeselector.js');
111
    drupal_add_js("
112
        jQuery(document).ready(function() {
113
           jQuery('#cdm-taxonomictree-selector-form #edit-val').change(function () {
114
                jQuery('#cdm-taxonomictree-selector-form').submit();
115
            });
116
117
        });
118
      ",
119
      array(
120
        'type' => 'inline',
121
        'scope' => 'footer'
122
      )
123
    );
124 5ea8b301 Andreas Kohlbecker
  }
125
126 6b605d3b Andreas Kohlbecker
  function _add_js_resizable_element($selector, $y_axis_only) {
127
128
    _add_jquery_ui();
129
    $options = "";
130
    if($y_axis_only) {
131
      $options = "resize: function(event, ui) {
132
        ui.size.width = ui.originalSize.width;
133
        },
134
        handles: \"s\"";
135
136
    }
137
    drupal_add_js("
138
          jQuery(document).ready(function() {
139
             jQuery('" . $selector . "').resizable({". $options ."});
140
          });
141
        ",
142
      array(
143
        'type' => 'inline',
144
        'scope' => 'footer'
145
      )
146
    );
147
  }
148
149 38b27a36 Andreas Kohlbecker
  function _add_js_openlayers() {
150
151
    $openlayers = '/js/map/OpenLayers-2.13.1/OpenLayers.js';
152
    $proj4js = '/js/map/proj4js-1.1.0/proj4js-compressed.js';
153
154
    if(variable_get('cdm_js_devel_mode', FALSE)){
155
      // develooper mode libs
156
  //     $openlayers = '/js/map/OpenLayers-2.13.1/lib/OpenLayers.js';
157
      $openlayers = '/js/map/OpenLayers-2.13.1/OpenLayers.debug.js';
158
      $proj4js = '/js/map/proj4js-1.1.0/proj4js-combined.js';
159
    }
160
161
    drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . $openlayers,
162
      array(
163
        'type' => 'file',
164 4c21ffdb Andreas Kohlbecker
        'group' => JS_LIBRARY,
165
        'weight' => 0,
166 38b27a36 Andreas Kohlbecker
        'cache' => TRUE,
167
        'preprocess' => FALSE
168
      )
169
    );
170
171
    // see https://github.com/proj4js/proj4js
172
    // http://openlayers.org/dev/examples/using-proj4js.html
173
    drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . $proj4js,
174
      array(
175
        'type' => 'file',
176 4c21ffdb Andreas Kohlbecker
        'group' => JS_LIBRARY,
177
        'weight' => -1, // before open layers
178 38b27a36 Andreas Kohlbecker
        'cache' => TRUE,
179
      )
180
    );
181
182
    // configure the theme
183
    $openlayers_theme_path = drupal_get_path('module', 'cdm_dataportal') . '/js/map/OpenLayers-2.13.1/theme/default/';
184
    $openlayers_imp_path = drupal_get_path('module', 'cdm_dataportal') . '/js/map/img/dark/';
185
    drupal_add_js('OpenLayers.ImgPath="' . base_path() . $openlayers_imp_path . '";', array(
186
        'type' => 'inline',
187 4c21ffdb Andreas Kohlbecker
        'group' => JS_LIBRARY,
188
        'weight' => 1, // after openlayers
189 38b27a36 Andreas Kohlbecker
        'cache' => TRUE,
190
        'preprocess' => FALSE
191
      ));
192
193
    drupal_add_css($openlayers_theme_path . 'style.tidy.css',
194
      array(
195
        'type' => 'file',
196
        'cache' => TRUE,
197
        'preprocess' => FALSE
198
      )
199
    );
200 e3026d72 Andreas Kohlbecker
201 38b27a36 Andreas Kohlbecker
  }
202 e3026d72 Andreas Kohlbecker
203 38b27a36 Andreas Kohlbecker
  /**
204
   * @todo Please document this function.
205
   * @see http://drupal.org/node/1354
206
   */
207
  function _add_js_thickbox() {
208
    // ---- jQuery thickbox:
209
    /*
210
    * bug: compat-1.0.js && thickbox.js line 237 .trigger("unload") -> event is
211
    * not triggered because of problems with compat-1.0.js' see INSTALL.txt
212
    */
213
    // drupal_add_js(drupal_get_path('module',
214
    // 'cdm_dataportal').'/js/jquery.imagetool.min.js');
215
    //
216
    // Add a setting for the path to cdm_dataportal module, used to find the path
217
    // for the loading animation image in thickbox.
218
    drupal_add_js(array(
219
    'cdm_dataportal' => array(
220
    'cdm_dataportal_path' => base_path() . drupal_get_path('module', 'cdm_dataportal'),
221 10f6aa4b Andreas Kohlbecker
    )
222 38b27a36 Andreas Kohlbecker
    ),
223
    'setting'
224
        );
225
        drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . '/js/thickbox/thickbox.js');
226
        drupal_add_css(drupal_get_path('module', 'cdm_dataportal') . '/js/thickbox/cdm_thickbox.css');
227
  }
228 94550ff9 Andreas Kohlbecker
229 38b27a36 Andreas Kohlbecker
  /**
230
   * @todo Please document this function.
231
   * @see http://drupal.org/node/1354
232
   */
233
  function _add_js_lightbox($galleryID) {
234
    /*
235
     * Important Notice: The jquery.lightbox-0.5.js has been modified in order to
236 fe19a89b Andreas Kohlbecker
     * allow using the "alt" attribute for captions instead of the "title"
237
     * attribute
238
     */
239 38b27a36 Andreas Kohlbecker
    $lightbox_base_path =  drupal_get_path('module', 'cdm_dataportal') . '/js/jquery-lightbox-0.5';
240
    $lightbox_image_path = base_path() . $lightbox_base_path . '/images/';
241
    drupal_add_js($lightbox_base_path . '/js/jquery.lightbox-0.5.js');
242
    drupal_add_css($lightbox_base_path . '/css/jquery.lightbox-0.5.css');
243
    drupal_add_js('jQuery(document).ready(function() {
244
        jQuery(\'#' . $galleryID . ' a.lightbox\').lightBox({
245
          fixedNavigation:  true,
246
          imageLoading:     \'' . $lightbox_image_path . 'lightbox-ico-loading.gif\',
247
          imageBtnPrev:     \'' . $lightbox_image_path . 'lightbox-btn-prev.gif\',
248
          imageBtnNext:     \'' . $lightbox_image_path . 'lightbox-btn-next.gif\',
249
          imageBtnClose:    \'' . $lightbox_image_path . 'lightbox-btn-close.gif\',
250
          imageBlank:       \'' . $lightbox_image_path . 'lightbox-blank.gif\',
251
          adjustToWindow: true
252
        });
253 94550ff9 Andreas Kohlbecker
      });
254 38b27a36 Andreas Kohlbecker
      ', array('type' => 'inline'));
255
  }
256 94550ff9 Andreas Kohlbecker
257 38b27a36 Andreas Kohlbecker
  /**
258
   * @todo Please document this function.
259
   * @see http://drupal.org/node/1354
260
   */
261
  function _add_js_footnotes() {
262
    _add_js_domEvent();
263
    drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . '/js/footnotes.js');
264
  }
265 94550ff9 Andreas Kohlbecker
266 38b27a36 Andreas Kohlbecker
  /**
267
   * @todo Please document this function.
268
   * @see http://drupal.org/node/1354
269
   */
270
  function _add_js_ahah() {
271 b386ae48 Andreas Kohlbecker
272 38b27a36 Andreas Kohlbecker
    _add_js_domEvent(); // requires domEvent.js
273
    drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . '/js/ahah-content.js');
274
  }
275 94550ff9 Andreas Kohlbecker
276 d0d23caa Andreas Kohlbecker
/**
277
 * @todo Please document this function.
278
 * @see http://drupal.org/node/1354
279
 */
280
function _add_js_taxonomic_children($jquery_selector) {
281 b0adfd32 Andreas Kohlbecker
282
  global $base_url;
283
284
285
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . '/js/jquery.cdm.taxonomic_children.js');
286 faf4f771 Andreas Kohlbecker
  
287 d0d23caa Andreas Kohlbecker
  drupal_add_js('jQuery(document).ready(function() {
288 b0adfd32 Andreas Kohlbecker
        jQuery(\'' . $jquery_selector . '\').taxonomic_children({
289 09edee9a Andreas Kohlbecker
          // hoverClass: "fa-rotate-90",
290
          // activeClass: "fa-rotate-90",
291 b0adfd32 Andreas Kohlbecker
          classificationUuid: "' . get_current_classification_uuid() . '",
292 0af3ce28 Andreas Kohlbecker
          taxonUuid: "' . get_current_taxon_uuid() . '",
293 38da4e54 Andreas Kohlbecker
          cdmWebappBaseUri: "' . variable_get('cdm_webservice_url', '') . '",
294 b0adfd32 Andreas Kohlbecker
          proxyBaseUri: "' . $base_url . '",
295
          
296
        });
297 d0d23caa Andreas Kohlbecker
      });
298
      ', array('type' => 'inline'));
299
}
300
301 38b27a36 Andreas Kohlbecker
  /**
302
   * Adds the external javascript file for domEvent.js.
303
   *
304
   * @see drupal_add_js()
305
   */
306
  function _add_js_domEvent() {
307
    drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . '/js/domEvent.js');
308
  }
309 b386ae48 Andreas Kohlbecker
310 087bb473 Andreas Kohlbecker
  function _add_jquery_ui()
311
  {
312
    drupal_add_css(drupal_get_path('module',
313
        'cdm_dataportal') . '/js/jquery-ui-1.8.24/themes/base/jquery.ui.all.css');
314
    drupal_add_js(drupal_get_path('module',
315
        'cdm_dataportal') . '/js/jquery-ui-1.8.24/ui/jquery-ui.js',
316
      array(
317
        'type' => 'file',
318
        'weight' => JS_LIBRARY,
319
        'cache' => TRUE,
320
        'preprocess' => FALSE
321
      )
322
    );
323
  }
324
325 38b27a36 Andreas Kohlbecker
  /**
326
   * Provides the markup for an font awesome icon.
327
   *
328
   * The icons is created in default size without any extra features.
329
   *
330
   * The available icons are listed here http://fontawesome.io/cheatsheet/
331 ef12d0c6 Andreas Kohlbecker
   * fontawesome icons have much more features than implemented here in this function,
332
   * for spinning icons, fixed width icons, rotation, etc please checkout the
333 38b27a36 Andreas Kohlbecker
   * examples at http://fontawesome.io/examples/
334
   *
335
   * @parameter $icon_name
336
   *  The name of the icon which starts with 'fa-'
337
   *
338
   * @return String
339
   *    the markup for the icon in an <i> tag
340
   *
341
   */
342 b0aa9a8f Andreas Kohlbecker
  function font_awesome_icon_markup($icon_name = NULL, $attributes = array()){
343 6d9071b7 Andreas Kohlbecker
    _add_font_awesome_font();
344 38b27a36 Andreas Kohlbecker
345
346 b0aa9a8f Andreas Kohlbecker
    if($icon_name){
347
      if(!isset($attributes['class'])){
348
        $attributes['class'] = array();
349
      }
350
      $attributes['class'][] = 'fa';
351
      $attributes['class'][] = $icon_name;
352
353
      return '<i ' . drupal_attributes($attributes) . '></i>';
354 38b27a36 Andreas Kohlbecker
    }
355
356 b0aa9a8f Andreas Kohlbecker
    return '';
357 38b27a36 Andreas Kohlbecker
  }
358 94550ff9 Andreas Kohlbecker
359 6d9071b7 Andreas Kohlbecker
/**
360
 * Adds the css  containing the font awesome icons to the html header.
361
 */
362
function _add_font_awesome_font()
363
{
364
//<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
365
366
  $font_awesome_css_uri = base_path() . drupal_get_path('module', 'cdm_dataportal') . '/fonts/font-awesome-4.6.3/css/font-awesome.min.css';
367
  //$font_awesome_css_uri="//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css";
368
369
  drupal_add_html_head_link(
370
    array(
371
      'href' => $font_awesome_css_uri,
372
      'rel' => 'stylesheet'
373
    )
374
  );
375
}
376
377 38b27a36 Andreas Kohlbecker
378 6d9071b7 Andreas Kohlbecker
/* ====================== hook implementations ====================== */
379 38b27a36 Andreas Kohlbecker
  /**
380
   * Implements hook_permission().
381
   *
382
   * Valid permissions for this module.
383
   *
384
   * @return array
385 8385a9f2 Andreas Kohlbecker
   *   An array of valid permissions for the cdm_dataportal module.
386 38b27a36 Andreas Kohlbecker
   */
387
  function cdm_dataportal_permission() {
388
    return array(
389
      'administer cdm_dataportal' => array(
390 8385a9f2 Andreas Kohlbecker
        'title' => t('Administer CDM DataPortal settings'),
391
        'description' => t("Access the settings pages specific for the cdm_dataportal module"),
392 c6fe437b Andreas Kohlbecker
      ),
393
      'access cdm content' => array(
394
        'title' => t('Access CDM content'),
395
        'description' => t("Access content (taxa, names, specimens, etc.) served by the CDM web service."),
396
      ),
397 38b27a36 Andreas Kohlbecker
    );
398
  }
399 6657531f Andreas Kohlbecker
400
/**
401 f19f47fa Andreas Kohlbecker
 * Implements hook_menu().
402
 */
403 6657531f Andreas Kohlbecker
function cdm_dataportal_menu() {
404
  $items = array();
405
406
  // @see settings.php.
407
  cdm_dataportal_menu_admin($items);
408
  cdm_dataportal_menu_help($items);
409
410
  $items['cdm_dataportal/names'] = array(
411
    'page callback' => 'cdm_dataportal_view_names',
412 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
413 6657531f Andreas Kohlbecker
    'type' => MENU_CALLBACK,
414
  );
415
416
  // Optional callback arguments: page.
417
  $items['cdm_dataportal/taxon'] = array(
418
    'page callback' => 'cdm_dataportal_taxon_page_view',
419 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
420 6657531f Andreas Kohlbecker
    'type' => MENU_CALLBACK,
421
    // Expected callback arguments: uuid.
422
  );
423
424 30845bda Andreas Kohlbecker
  $items['cdm_dataportal/specimen'] = array(
425
      'page callback' => 'cdm_dataportal_specimen_page_view',
426
      'access arguments' => array('access cdm content'),
427
      'type' => MENU_CALLBACK,
428
      // Expected callback arguments: uuid.
429
  );
430
431
  $items['cdm_dataportal/named_area'] = array(
432
    'page callback' => 'cdm_dataportal_named_area_page_view',
433
    'access arguments' => array('access cdm content'),
434
    'type' => MENU_CALLBACK,
435
    // Expected callback arguments: uuid.
436
  );
437 9d37c9d9 Patric Plitzner
438 6657531f Andreas Kohlbecker
  $items['cdm_dataportal/name'] = array(
439
    'page callback' => 'cdm_dataportal_name_page_view',
440
      /*
441
    'page arguments' => array(
442
       'taxon_name_uuid',
443
       'taxon_to_hide_uuid',
444
       'synonym_uuid' => NULL
445
      ),
446
      */
447 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
448 6657531f Andreas Kohlbecker
    'type' => MENU_CALLBACK,
449
    // Expected callback arguments: uuid.
450
  );
451
452
  $items['cdm_dataportal/reference'] = array(
453
    'page callback' => 'cdm_dataportal_view_reference',
454 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
455 6657531f Andreas Kohlbecker
    'type' => MENU_CALLBACK,
456
    // Expected callback arguments: uuid.
457
  );
458
459
  $items['cdm_dataportal/reference/list'] = array(
460
    'page callback' => 'cdm_dataportal_view_reference_list',
461 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
462 6657531f Andreas Kohlbecker
    'type' => MENU_CALLBACK,
463
    // Expected callback arguments: uuid.
464
  );
465
466
  $items['cdm_dataportal/media'] = array(
467
    'page callback' => 'cdm_dataportal_view_media',
468 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
469 6657531f Andreas Kohlbecker
    'type' => MENU_CALLBACK,
470
    // Expected callback arguments:
471
    // uuid, mediarepresentation_uuid, part_uuid or part#.
472
  );
473
474
  $items['cdm_dataportal/polytomousKey'] = array(
475
    'page callback' => 'cdm_dataportal_view_polytomousKey',
476 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
477 6657531f Andreas Kohlbecker
    'type' => MENU_CALLBACK,
478
    // Expected callback arguments: polytomousKey->uuid.
479
  );
480
481
  $items['cdm_dataportal/search'] = array(
482
    'page callback' => 'cdm_dataportal_view_search_advanced',
483 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
484 6657531f Andreas Kohlbecker
    'type' => MENU_CALLBACK,
485
  );
486
487
  $items['cdm_dataportal/search/advanced'] = array(
488 29077ee5 Andreas Kohlbecker
    'title' => 'Advanced', // will be passed through t()
489 6657531f Andreas Kohlbecker
    'page callback' => 'cdm_dataportal_view_search_advanced',
490 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
491 6657531f Andreas Kohlbecker
    'type' => MENU_DEFAULT_LOCAL_TASK,
492
  );
493
494
  $items['cdm_dataportal/search/taxon_by_description'] = array(
495 579c485d Andreas Kohlbecker
    'title' => 'By content category', // will be passed through t()
496 6657531f Andreas Kohlbecker
    'page callback' => 'cdm_dataportal_view_search_taxon_by_description',
497 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
498 6657531f Andreas Kohlbecker
    'type' => MENU_LOCAL_TASK,
499
  );
500
501
  $items['cdm_dataportal/search/results/taxon'] = array(
502
    'page callback' => 'cdm_dataportal_view_search_results_taxon',
503 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
504 6657531f Andreas Kohlbecker
    'type' => MENU_CALLBACK,
505
  );
506 a6ae799b Andreas Kohlbecker
  $items['cdm_dataportal/search/registration'] = array(
507
    'page callback' => 'cdm_dataportal_view_search_registrations_results',
508
    'access arguments' => array('access cdm content'),
509
    'type' => MENU_CALLBACK,
510
  );
511 e0d3e148 Andreas Kohlbecker
  // Optional callback arguments: page.
512
  $items['cdm_dataportal/registration'] = array(
513
    'page callback' => 'cdm_dataportal_registration_page_view',
514
    'access arguments' => array('access cdm content'),
515
    'type' => MENU_CALLBACK,
516
    // Expected callback arguments: uuid.
517
  );
518 a6ae799b Andreas Kohlbecker
519 6657531f Andreas Kohlbecker
  /*
520
   $items['cdm/xml2json'] = array(
521
   'page callback' => 'cdm_view_xml2json',
522 c6fe437b Andreas Kohlbecker
   'access arguments' => array('access cdm content'),
523 6657531f Andreas Kohlbecker
   'type' => MENU_CALLBACK,
524
   );
525
   */
526
527
  // if (arg(0)=='user' && ($uid=arg(1)) && is_numeric($uid)) {
528
  // User configuration of cdm_dataportal.
529
  $items['user/%/cdm_dataportal'] = array(
530
    'title' => 'cdm_dataportal',
531 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
532 6657531f Andreas Kohlbecker
    'page callback' => 'drupal_get_form',
533
    'page arguments' => array('cdm_dataportal_user_form'),
534
    'type' => MENU_LOCAL_TASK,
535
    'weight' => 10,
536
  );
537
  // }
538
539
  // 'May not cache' in D5.
540
  $items['cdm_dataportal/name/%'] = array(
541
    // 'page callback' => 'cdm_dataportal_view_name',
542
    'page callback' => 'cdm_dataportal_name_page_view',
543
    'page arguments' => array(2, 3, 4),
544 c6fe437b Andreas Kohlbecker
    'access arguments' => array('access cdm content'),
545 6657531f Andreas Kohlbecker
    'type' => MENU_CALLBACK,
546
  );
547
548 6f1a217c Andreas Kohlbecker
  // --- Local tasks for Taxon.
549
  // --- tabbed taxon page
550 6657531f Andreas Kohlbecker
  if (variable_get('cdm_dataportal_taxonpage_tabs', 1)) {
551
    $items['cdm_dataportal/taxon/%'] = array(
552 4feeabc7 Andreas Kohlbecker
      'title' => cdm_taxonpage_tab_label('General'),
553 6657531f Andreas Kohlbecker
      'page callback' => 'cdm_dataportal_taxon_page_view',
554 c6fe437b Andreas Kohlbecker
      'access arguments' => array('access cdm content'),
555 6657531f Andreas Kohlbecker
      'type' => MENU_CALLBACK,
556
      'weight' => 1,
557
      'page arguments' => array(2, "description")
558 7663cd0b Andreas Kohlbecker
      , // Expected callback arguments: taxon_uuid.
559 6657531f Andreas Kohlbecker
    );
560
561
    $items['cdm_dataportal/taxon/%/all'] = array(
562 4feeabc7 Andreas Kohlbecker
      'title' => cdm_taxonpage_tab_label('General'),
563 6657531f Andreas Kohlbecker
      'page callback' => 'cdm_dataportal_taxon_page_view',
564 c6fe437b Andreas Kohlbecker
      'access arguments' => array('access cdm content'),
565 6657531f Andreas Kohlbecker
      'type' => MENU_CALLBACK,
566
      'weight' => 2,
567
      'page arguments' => array(2, "all")
568 7663cd0b Andreas Kohlbecker
      , // Expected callback arguments: taxon_uuid.
569 6657531f Andreas Kohlbecker
    );
570
571
    $items['cdm_dataportal/taxon/%/description'] = array(
572 4feeabc7 Andreas Kohlbecker
      'title' => cdm_taxonpage_tab_label('General'),
573 6657531f Andreas Kohlbecker
      'page callback' => 'cdm_dataportal_taxon_page_view',
574 c6fe437b Andreas Kohlbecker
      'access arguments' => array('access cdm content'),
575 6657531f Andreas Kohlbecker
      'type' => MENU_DEFAULT_LOCAL_TASK,
576
      'weight' => 2,
577
      'page arguments' => array(2, "description")
578 7663cd0b Andreas Kohlbecker
      , // Expected callback arguments: taxon_uuid.
579 6657531f Andreas Kohlbecker
    );
580
581
    $items['cdm_dataportal/taxon/%/synonymy'] = array(
582 4feeabc7 Andreas Kohlbecker
      'title' => cdm_taxonpage_tab_label('Synonymy'),
583 6657531f Andreas Kohlbecker
      'page callback' => 'cdm_dataportal_taxon_page_view',
584 c6fe437b Andreas Kohlbecker
      'access arguments' => array('access cdm content'),
585 6657531f Andreas Kohlbecker
      'type' => MENU_LOCAL_TASK,
586
      'weight' => 4,
587
      'page arguments' => array(2, "synonymy", 4)
588 7663cd0b Andreas Kohlbecker
      , // Expected callback arguments: taxon_uuid and ...
589 6657531f Andreas Kohlbecker
    );
590 7cc085da Andreas Kohlbecker
    $items['cdm_dataportal/taxon/%/images'] = array( // Images
591 4feeabc7 Andreas Kohlbecker
      'title' => cdm_taxonpage_tab_label('Images'),
592 6657531f Andreas Kohlbecker
      'page callback' => 'cdm_dataportal_taxon_page_view',
593 c6fe437b Andreas Kohlbecker
      'access arguments' => array('access cdm content'),
594 6657531f Andreas Kohlbecker
      'type' => MENU_LOCAL_TASK,
595
      'weight' => 5,
596
      'page arguments' => array(2, "images")
597 7663cd0b Andreas Kohlbecker
      , // Expected callback arguments: taxon_uuid.
598 6657531f Andreas Kohlbecker
    );
599
600 7cc085da Andreas Kohlbecker
    $items['cdm_dataportal/taxon/%/specimens'] = array( // Specimens
601 4feeabc7 Andreas Kohlbecker
      'title' => cdm_taxonpage_tab_label('Specimens'),
602 6657531f Andreas Kohlbecker
      'page callback' => 'cdm_dataportal_taxon_page_view',
603 c6fe437b Andreas Kohlbecker
      'access arguments' => array('access cdm content'),
604 6657531f Andreas Kohlbecker
      'type' => MENU_LOCAL_TASK,
605
      'weight' => 6,
606
      'page arguments' => array(2, "specimens")
607 7663cd0b Andreas Kohlbecker
      , // Expected callback arguments: taxon_uuid.
608 6657531f Andreas Kohlbecker
    );
609
610 7cc085da Andreas Kohlbecker
    $items['cdm_dataportal/taxon/%/keys'] = array( // Keys
611 4feeabc7 Andreas Kohlbecker
      'title' => cdm_taxonpage_tab_label('Keys'),
612 6657531f Andreas Kohlbecker
      'page callback' => 'cdm_dataportal_taxon_page_view',
613 c6fe437b Andreas Kohlbecker
      'access arguments' => array('access cdm content'),
614 6657531f Andreas Kohlbecker
      'type' => MENU_LOCAL_TASK,
615
      'weight' => 6,
616
      'page arguments' => array(2, "keys")
617 7663cd0b Andreas Kohlbecker
      , // Expected callback arguments: taxon_uuid.
618
    );
619
620 7cc085da Andreas Kohlbecker
    $items['cdm_dataportal/taxon/%/experts'] = array( // Experts
621 4feeabc7 Andreas Kohlbecker
      'title' => cdm_taxonpage_tab_label('Experts'),
622 7663cd0b Andreas Kohlbecker
        'page callback' => 'cdm_dataportal_taxon_page_view',
623 c6fe437b Andreas Kohlbecker
        'access arguments' => array('access cdm content'),
624 7663cd0b Andreas Kohlbecker
        'type' => MENU_LOCAL_TASK,
625
        'weight' => 6,
626
        'page arguments' => array(2, "experts")
627
    , // Expected callback arguments: taxon_uuid.
628 6657531f Andreas Kohlbecker
    );
629 93ae67cc Patrick Plitzner
630 51cc509a Patrick Plitzner
    $items['cdm_dataportal/taxon/autosuggest/%/%/%/'] = array(
631 04a1d647 Patrick Plitzner
        'page callback' => 'cdm_dataportal_taxon_autosuggest',
632 c6fe437b Andreas Kohlbecker
        'access arguments' => array('access cdm content'),
633 51cc509a Patrick Plitzner
        'page arguments' => array(3,4,5),
634 93ae67cc Patrick Plitzner
        'type' => MENU_CALLBACK
635
    );
636 6657531f Andreas Kohlbecker
  }
637
638 6f1a217c Andreas Kohlbecker
  // --- refresh link for all cdmnode types
639
  foreach (cdm_get_nodetypes() as $type=>$name) {
640
    $items['cdm_dataportal/' . $name . '/%/refresh'] = array(
641 7cc085da Andreas Kohlbecker
        'title' => 'Refresh',
642 6f1a217c Andreas Kohlbecker
        'page callback' => 'cdm_dataportal_refresh_node',
643 3113db26 Andreas Kohlbecker
        'access arguments' => array('administer cdm_dataportal'),
644 6f1a217c Andreas Kohlbecker
        'type' => MENU_LOCAL_TASK,
645
        'weight' => 100,
646
        'page arguments' => array($name, 2)
647
    );
648
  }
649
650 6657531f Andreas Kohlbecker
  return $items;
651
}
652
653
/**
654 b85ab055 Andreas Kohlbecker
 * Implements hook_init().
655
 *
656 6657531f Andreas Kohlbecker
 */
657
function cdm_dataportal_init() {
658 8fc089e1 Saskia Gennrich
  if (!path_is_admin(current_path())) {
659
    //FIXME To add CSS or JS that should be present on all pages, modules
660
    //      should not implement this hook, but declare these files in their .info file.
661
    drupal_add_css(drupal_get_path('module', 'cdm_dataportal') . '/cdm_dataportal.css');
662
    // drupal_add_css(drupal_get_path('module', 'cdm_dataportal').'/cdm_dataportal_print.css', 'print');
663
    drupal_add_css(drupal_get_path('module', 'cdm_dataportal') . '/cdm_dataportal_screen.css', array('type' => 'screen'));
664 63f6d312 Saskia Gennrich
  } else {
665
    drupal_add_css(drupal_get_path('module', 'cdm_dataportal') . '/cdm_dataportal_settings.css');
666 8fc089e1 Saskia Gennrich
  }
667 2dd59bb5 Andreas Kohlbecker
668
  if(variable_get('cdm_debug_mode', FALSE)){
669
    $file = 'temporary://drupal_debug.txt';
670
    file_put_contents($file, 'CDM DEBUG LOG for ' . $_GET['q']. "\n"); // will overwrite the file
671
  }
672 5611d467 Andreas Kohlbecker
673
  $bibliography_settings = get_bibliography_settings();
674 57d513cb Andreas Kohlbecker
  $enclosing_tag = $bibliography_settings['enabled'] == 1 ? 'div' : 'span';
675
  FootnoteManager::registerFootnoteSet('BIBLIOGRAPHY', $enclosing_tag, $bibliography_settings['key_format']);
676 6657531f Andreas Kohlbecker
}
677
678 6f1a217c Andreas Kohlbecker
function cdm_dataportal_refresh_node($cdm_node_name, $uuid, $parameters = array()){
679
680
  $base_path = 'cdm_dataportal/' . $cdm_node_name . '/' . $uuid;
681
682
  if($cdm_node_name == 'taxon' && variable_get('cdm_dataportal_taxonpage_tabs', 1)){
683
    // force reloading of all and notify user about this special loading
684
    drupal_set_message(t('The level 2 cache has been cleared for all tabs of this taxon page at once, please click here to return to the tabbed page: ')
685
        . l('Back to tabbed taxon page', $base_path));
686
    $base_path .= '/all';
687
  } else {
688
    drupal_set_message(t('The level 2 cache has been cleared for this page'));
689
  }
690
691
  $parameters['cacheL2_refresh'] ='1';
692
693
694
  drupal_goto($base_path, array('query' => $parameters));
695
}
696
697 102f8c26 Andreas Kohlbecker
/**
698
 * Implements hook_requirements($phase)
699
 */
700
function cdm_dataportal_requirements($phase) {
701
    $requirements = array();
702
    if($phase == 'runtime'){
703
704
    }
705
    return $requirements;
706
}
707
708
709 6657531f Andreas Kohlbecker
/**
710
 * The function generate form for own user cdm dataportal configurations.
711
 */
712
function cdm_dataportal_user_form($form, &$form_state) {
713 36818236 Andreas Kohlbecker
714 6657531f Andreas Kohlbecker
  global $user;
715
  $checkbox_value = 'cdm_dataportal_' . $user->uid . '_default_tab_active';
716
717 8e1dc7ec Andreas Kohlbecker
  $form['taxon_page_tabs'] = array(
718
      '#type' => 'fieldset',
719 36818236 Andreas Kohlbecker
      '#tree' => true,
720 8e1dc7ec Andreas Kohlbecker
      '#title' => t('Taxon page tabs'),
721
  );
722 36818236 Andreas Kohlbecker
723
  $form['taxon_page_tabs']['user_defined'] = array(
724 6657531f Andreas Kohlbecker
    '#type' => 'checkbox',
725
    '#title' => t('Activate user default configuration'),
726
    '#default_value' => variable_get($checkbox_value, 0),
727
    '#description' => t('Check this if you want configure your own default tab from the below menu.'),
728
  );
729
730 36818236 Andreas Kohlbecker
  $form['taxon_page_tabs']['default_tab'] = array(
731 6657531f Andreas Kohlbecker
    '#type' => 'select',
732
    '#title' => t('Default tab to display'),
733
    '#default_value' => get_default_taxon_tab(TRUE),
734
    '#options' => unserialize(CDM_DATAPORTAL_DEFAULT_TAXON_TAB),
735
    '#description' => t('<p>Select the default tab to display when visiting a taxon page. Only available if Tabbed Taxon Page is enable.</p>
736
              <strong>Note:</strong> After performing a search and clicking in any synonym, the taxon tab
737 36818236 Andreas Kohlbecker
              to be rendered will be the synonymy of the accepted taxon and not the above selected tab.'),
738
  );
739
740
741 f695daf4 Andreas Kohlbecker
  if(false){
742
    $form['developer_options'] = array(
743
        '#type' => 'fieldset',
744
        '#tree' => true,
745
        '#title' => t('Developer options'),
746
    );
747
748
    $form['developer_options']['show_render_path'] = array(
749
      '#type' => 'checkbox',
750
      '#title' => t('Display the render path for each taxon name.'),
751
      '#default_value' => variable_get($checkbox_value, 0),
752
      '#description' => t('This option is very helpful if you are editing the !link for taxon names.',
753
        array(
754
            '!link' => l(
755
              'render template', 'admin/config/cdm_dataportal/settings/layout', array('fragment' => 'edit-cdm-name-render-templates'))
756
            )
757
        ),
758
    );
759
  }
760 6657531f Andreas Kohlbecker
761
  $form['submit'] = array(
762
    '#type' => 'submit',
763
    '#value' => t('Submit'),
764
  );
765
766
  return $form;
767
}
768
769
/**
770
 * Form submission handler for user_form().
771
 *
772
 * Submits the user cdm dataportal configurations.
773
 */
774
function cdm_dataportal_user_form_submit($form, &$form_state) {
775
  global $user;
776
  $msg_type = 'status';
777
  $username = $user->name;
778
  $variable_to_use = 'cdm_dataportal_' . $user->uid . '_default_tab';
779
780 36818236 Andreas Kohlbecker
  // FIXME: this is completely wrong, see user_profile_form_submit()
781
782
  // it is only possible to change own user settings
783
  if (arg(0) == 'user' && is_numeric(arg(1)) && $user->uid == arg(1)) {
784
785
    // DEFAULT_TAXON_TAB
786 6657531f Andreas Kohlbecker
    $variable = unserialize(CDM_DATAPORTAL_DEFAULT_TAXON_TAB);
787 36818236 Andreas Kohlbecker
    variable_set($variable_to_use . '_active', $form_state['values']['taxon_page_tabs']['user_defined']);
788
    variable_set($variable_to_use, $form_state['values']['taxon_page_tabs']['default_tab']);
789
    if ($form_state['values']['taxon_page_tabs']['user_defined']) {
790 6657531f Andreas Kohlbecker
      drupal_set_message(check_plain(t('The user default tab will be used for the next taxon site visit.')));
791
      drupal_set_message(check_plain(t('The user default tab has been changed to: !tab for the user !user', array(
792
        '!tab' => $variable[variable_get($variable_to_use, 0)],
793
        '!user' => $username,
794
      ))), $msg_type);
795
    }
796
    else {
797
      drupal_set_message(check_plain(t('The user default tab wont be used for
798
        the next taxon site, check the box if you want to use the user default configuration.')));
799
    }
800 36818236 Andreas Kohlbecker
801 6657531f Andreas Kohlbecker
  }
802
  else {
803 36818236 Andreas Kohlbecker
    // Problem with the user id => variables wont be saved.
804 6657531f Andreas Kohlbecker
    $msg_type = 'warning';
805
    drupal_set_message(check_plain(t('Default tab has not been saved due to user id problems')), $msg_type);
806
  }
807
}
808
809
/**
810
 * Implements hook_block_info().
811
 */
812
function cdm_dataportal_block_info() {
813
814
    // $block[0]["info"] = t("CDM DataPortal DevLinks");
815
    // $block[1]["info"] = t("CDM DataPortal Credits");
816 fc13aa30 Andreas Kohlbecker
    $block["2"] = array(
817 beb914ef Andreas Kohlbecker
        "info" => t("CDM - Search Taxa"),
818 fc13aa30 Andreas Kohlbecker
        "cache" => DRUPAL_NO_CACHE
819
      );
820 6657531f Andreas Kohlbecker
    // $block[3]["info"] = t("CDM Filters");
821 beb914ef Andreas Kohlbecker
    $block["4"]["info"] = t("CDM  - Dataportal Print");
822
    $block["keys"]["info"] = t("CDM - Identification keys");
823 46a02272 Andreas Kohlbecker
    $block["fundedByEDIT"]["info"] = t('CDM - Powered by EDIT');
824 f9a3d0f6 Andreas Kohlbecker
    $block["classification_breadcrumbs"] =  array(
825 beb914ef Andreas Kohlbecker
        'info' => t('CDM - Classification breadcrumbs'),
826 f9a3d0f6 Andreas Kohlbecker
        'cache' => DRUPAL_CACHE_PER_PAGE
827
      );
828 bc400a17 Andreas Kohlbecker
    $block["taxonomic_children"] =  array(
829 beb914ef Andreas Kohlbecker
      'info' => t('CDM - Taxonomic children'),
830 bc400a17 Andreas Kohlbecker
      'cache' => DRUPAL_CACHE_PER_PAGE
831
    );
832 beb914ef Andreas Kohlbecker
    $block["back_to_search_results"] =  array(
833
      'title' => '<none>',
834
      'info' => t('CDM - Back to search Results'),
835
      'cache' => DRUPAL_CACHE_PER_PAGE,
836
      'visibility' => BLOCK_VISIBILITY_LISTED,
837
      'pages' => "cdm_dataportal/taxon/*", // multiple page paths separated by "\n"!!!
838
    );
839 a6ae799b Andreas Kohlbecker
  $block['registrations_search_filter'] =  array(
840 810710a0 Andreas Kohlbecker
    'title' => 'Search registrations',
841 a6ae799b Andreas Kohlbecker
    'info' => t('CDM - Registrations search filter'),
842
    'cache' => DRUPAL_CACHE_PER_PAGE,
843 810710a0 Andreas Kohlbecker
    'visibility' => BLOCK_VISIBILITY_NOTLISTED,
844 a6ae799b Andreas Kohlbecker
    'pages' => "cdm_dataportal/search/registration\ncdm_dataportal/search/registration/*", // multiple page paths separated by "\n"!!!
845
  );
846 6657531f Andreas Kohlbecker
847
    return $block;
848
}
849
850
/**
851
 * Implements hook_block_view().
852
 */
853
function cdm_dataportal_block_view($delta) {
854
  // TODO Rename block deltas (e.g. '2') to readable strings.
855
  switch ($delta) {
856
    // case 'delta-1':
857
    // $block['subject'] = t('Credits');
858
    // $block['content'] = theme('cdm_credits');
859
    // return $block;
860
    case '2':
861
      $block['subject'] = t('Search taxa');
862 191f88fd Andreas Kohlbecker
      $form = drupal_get_form('cdm_dataportal_search_taxon_form');
863
      $block['content'] = drupal_render($form);
864 6657531f Andreas Kohlbecker
865
      if (variable_get('cdm_dataportal_show_advanced_search', 1)) {
866
        $block['content'] .= '<div>' . l(t('Advanced Search'), 'cdm_dataportal/search') . '</div>';
867
      }
868
      return $block;
869
    case '4':
870 c8234bdf Andreas Kohlbecker
      $block['subject'] = '';
871 6657531f Andreas Kohlbecker
      $block['content'] = theme('cdm_print_button');
872
      return $block;
873
    case "keys":
874
      $block['subject'] = t('Identification Keys');
875
      $block['content'] = theme('cdm_block_IdentificationKeys', array('taxonUuid' => NULL));
876
      return $block;
877
    case "fundedByEDIT":
878
      // t('Funded by EDIT');
879
      $text = '<none>';
880
      $block['subject'] = $text;
881 889c74b7 Andreas Kohlbecker
      $img_tag = '<img src="' . base_path() . drupal_get_path('module', 'cdm_dataportal') . '/images/powered_by_edit.png' . '" alt="' . $text . '"/>';
882
      $block['content'] = l($img_tag, "http://cybertaxonomy.org/", array(
883 6657531f Andreas Kohlbecker
        'attributes' => array("target" => "EDIT"),
884
        'absolute' => TRUE,
885
        'html' => TRUE,
886
      ));
887
      return $block;
888 f9a3d0f6 Andreas Kohlbecker
    case 'classification_breadcrumbs':
889 0af3ce28 Andreas Kohlbecker
      $taxon_uuid = get_current_taxon_uuid();
890 38da4e54 Andreas Kohlbecker
      $block['subject'] = '<none>';
891
      $block['content'] = compose_classification_breadcrumbs($taxon_uuid);
892
      return $block;
893 bc400a17 Andreas Kohlbecker
    case 'taxonomic_children':
894
      $taxon_uuid = get_current_taxon_uuid();
895
      $block['subject'] = '<none>';
896
      $block['content'] = compose_taxonomic_children($taxon_uuid);
897
      return $block;
898 beb914ef Andreas Kohlbecker
    case 'back_to_search_results':
899
      $block['subject'] = '<none>';
900
      if (isset($_SESSION['cdm']['search'])) {
901
        $block['content'] = l(t('Back to search result'), "http://" . $_SERVER['SERVER_NAME'] . $_SESSION['cdm']['last_search']);
902
      }
903
      return $block;
904 a6ae799b Andreas Kohlbecker
    case 'registrations_search_filter':
905
      $block['subject'] = '<none>';
906
      $block['content'] = $form = drupal_get_form('cdm_dataportal_search_registration_form'); // see cdm_dataportal_search_registration_form($form, &$form_state)
907
      return $block;
908 beb914ef Andreas Kohlbecker
    default:
909
      return null;
910 6657531f Andreas Kohlbecker
  }
911
}
912
913 0af3ce28 Andreas Kohlbecker
/**
914
 * Provides the uuid of the taxon for pages with the path ./taxon/{taxon_uuid}
915
 *
916
 * @return string
917
 *   the taxon uuid or NULL
918
 */
919
function get_current_taxon_uuid()
920
{
921
  static $taxon_uuid;
922
923
  if(!isset($taxon_uuid)){
924
    if(isset($_REQUEST['currentTaxon']) && is_uuid($_REQUEST['currentTaxon'])) {
925
      $taxon_uuid = $_REQUEST['currentTaxon'];
926
    } else if (arg(1) == 'taxon' && is_uuid(arg(2))) {
927
      $taxon_uuid = arg(2);
928
    } else {
929
      $taxon_uuid = null;
930
    }
931
  }
932
933
  return $taxon_uuid;
934
}
935
936
/**
937
 * Returns the currently classification tree in use.
938
 *
939
 * @return string
940
 *   The uuid of the currently focused classification
941
 */
942
function get_current_classification_uuid() {
943
  if (isset($_SESSION['cdm']['taxonomictree_uuid']) && is_uuid($_SESSION['cdm']['taxonomictree_uuid'])) {
944
    return $_SESSION['cdm']['taxonomictree_uuid'];
945
  }
946
  else {
947
    return variable_get(CDM_TAXONOMICTREE_UUID, FALSE);
948
  }
949
}
950
951 6657531f Andreas Kohlbecker
/*
952
 function cdm_dataportal_session_clear($cdm_ws_uri_update = FALSE){
953
 $_SESSION['cdm'] = NULL;
954
 if(is_string($cdm_ws_uri_update)){
955
 $_SESSION['cdm'] = array('ws_uri'=>$cdm_ws_uri_update);
956
 }
957
 }
958
959
 function cdm_dataportal_session_validate(){
960
 if(!isset($_SESSION['cdm']['ws_uri'])){
961
 $_SESSION['cdm'] = array('ws_uri'=>variable_get('cdm_webservice_url', FALSE));
962
 } else if($_SESSION['cdm']['ws_uri'] != variable_get('cdm_webservice_url', FALSE)){
963
 cdm_dataportal_session_clear(variable_get('cdm_webservice_url', FALSE));
964
 }
965
 }
966
 */
967
968
/**
969 d7588d36 Andreas Kohlbecker
 * creates a  selector form for taxonomic trees.
970
 *
971 0af3ce28 Andreas Kohlbecker
 * @return array
972
 *  a drupal form array
973 6657531f Andreas Kohlbecker
 */
974
function cdm_taxonomictree_selector() {
975
  _add_js_treeselector();
976
977 a8a8f23c Andreas Kohlbecker
  $form = drupal_get_form('cdm_taxonomictree_selector_form');
978 d7588d36 Andreas Kohlbecker
  return $form;
979 6657531f Andreas Kohlbecker
}
980
981
/**
982
 * @todo Please document this function.
983
 * @see http://drupal.org/node/1354
984 0af3ce28 Andreas Kohlbecker
 *
985
 * @deprecated use compose_classification_selector instead
986 6657531f Andreas Kohlbecker
 */
987
function cdm_taxonomictree_selector_form($form, &$form_state) {
988
989
  $url = url('cdm_api/setvalue/session', array('query' => NULL));
990
  $form['#action'] = $url;
991
992
  $form['var'] = array(
993
    '#weight' => -3,
994
    '#type' => 'hidden',
995
    '#value' => '[cdm][taxonomictree_uuid]',
996
  );
997
998
  $destination_array = drupal_get_destination();
999
  $destination = $destination_array['destination'];
1000
1001
  $form['destination'] = array(
1002
    '#weight' => -3,
1003
    '#type' => 'hidden',
1004
    '#value' =>  $destination,
1005
  );
1006
1007 26fb3778 Andreas Kohlbecker
  $options = cdm_get_taxontrees_as_options();
1008
  $taxontree_includes = variable_get(CDM_TAXONTREE_INCLUDES, null);
1009
  if($taxontree_includes){
1010
    $filtered_options = array();
1011
    foreach($options as $uuid=>$label){
1012
      if(!empty($taxontree_includes[$uuid])){
1013
        $filtered_options[$uuid] = $label;
1014
      }
1015
    }
1016
    $options = $filtered_options;
1017
  }
1018
1019 6657531f Andreas Kohlbecker
  $form['val'] = array(
1020
    '#type' => 'select',
1021
    '#title' => t('Available classifications'),
1022 7663cd0b Andreas Kohlbecker
    '#default_value' => get_current_classification_uuid(),
1023 26fb3778 Andreas Kohlbecker
    '#options' => $options,
1024 0af3ce28 Andreas Kohlbecker
    '#attributes' => array('class' => array('highlite-first-child')),
1025 6657531f Andreas Kohlbecker
  );
1026
1027
  return $form;
1028
1029
}
1030
1031 0af3ce28 Andreas Kohlbecker
/**
1032
 *
1033
 * @ingroup compose
1034
 */
1035
function compose_classification_selector() {
1036
1037
  $destination_array = drupal_get_destination();
1038
  $destination = $destination_array['destination'];
1039
1040
  $options = cdm_get_taxontrees_as_options();
1041
  $items = array();
1042
  $taxontree_includes = variable_get(CDM_TAXONTREE_INCLUDES, null);
1043
1044
  $current_classification_uuid = get_current_classification_uuid();
1045
1046
1047
  foreach($options as $uuid=>$label){
1048
    if(!$taxontree_includes || !empty($taxontree_includes[$uuid])){
1049
1050
      $class_attributes = '';
1051
      if($current_classification_uuid == $uuid){
1052
        $class_attributes  = array('focused');
1053
      }
1054
      $items[] = array(
1055
        'data' => l($label,
1056
          'cdm_api/setvalue/session',
1057
          array(
1058
            'query' => array(
1059
              'destination' => $destination,
1060
              'val' => $uuid,
1061
              'var' => '[cdm][taxonomictree_uuid]'
1062
            ),
1063
          )
1064
        ),
1065
        'class' => $class_attributes
1066
      );
1067
    }
1068
  }
1069
1070
  $render_array = array(
1071
    '#theme' => 'item_list',
1072
    '#type' => 'ul',
1073
    '#items' => $items
1074
  );
1075
1076
  return $render_array;
1077
}
1078
1079
1080 6657531f Andreas Kohlbecker
/* UNREACHABLE since action of form directly links to view.
1081
 function cdm_dataportal_search_taxon_form_submit($form_id, $form_values) {
1082
1083
 $_SESSION['cdm']['search'] = $form_values;
1084
 //return '/cdm_dataportal/search/taxon/'.$form_values['queryString'].'/'.($form_values['vernacular']?'1':'0').'/'.$form_values['language'];
1085
 return '/cdm_dataportal/search/taxon/'.$form_values['queryString'].'/'.($form_values['onlyAccepted']?'1':'0');
1086
 //$paramstr = compose_url_prameterstr($form_values);
1087
 //return url('/cdm_dataportal/search/taxon/', array('query' => $paramstr));
1088
 }
1089
 */
1090
/* ====================== menu callback functions ====================== */
1091
/**
1092
 * @todo Please document this function.
1093
 * @see http://drupal.org/node/1354
1094
 */
1095
/*
1096
function cdm_dataportal_form_alter(&$form, &$form_state, $form_id) {
1097
  static $comment_node_disabled =  0;
1098
  static $comment_node_read_only =  1;
1099
  static $comment_node_read_write =  2;
1100
1101
  if ($form_id == 'node_type_form'
1102
   && isset($form['identity']['type'])
1103
   && array_key_exists($form['#node_type']->type, cdm_get_nodetypes())
1104
  ) {
1105
    $form['workflow']['comment'] = array(
1106
      '#type' => 'radios',
1107
      '#title' => t('Default comment setting'),
1108
      '#default_value' => variable_get('comment__' . $node->type . $form['#node_type']->type, $comment_node_disabled),
1109
      '#options' => array(t('Disabled'), t('Read only'), t('Read/Write')),
1110
      '#description' => t('Users with the <em>administer comments</em> permission will be able to override this setting.'),
1111
    );
1112
  }
1113
}
1114
*/
1115
1116
/**
1117
 * Displays a list of the known taxonomic names.
1118
 *
1119
 * When the list of taxonomic names is displayed, long lists are split up into
1120
 * multiple pages.
1121
 *
1122
 * TODO: Parameters are still preliminary.
1123
 *
1124
 * @param string $beginsWith
1125
 * @param string $page
1126
 *   Page number to diplay defaults to page 1.
1127
 * @param bool $onlyAccepted
1128
 */
1129
function cdm_dataportal_view_names($beginsWith = 'A', $page = 1, $onlyAccepted = FALSE) {
1130
1131
  $out = t('<h3>Sorry, the name list feature is not yet available in this version of the DataPortal software<h3>');
1132
1133
  /*
1134
  // FIXME the filter for accepted names will be a form element, thus this
1135
  // widget should be generated via form api preferably as block.
1136
  $out  = theme('cdm_dataportal_widget_filter_accepted', $onlyAccepted);
1137
  $out .= theme('cdm_dataportal_widget_names_list', $names, $page);
1138
  $out .= theme('cdm_listof_taxa', $taxonPager);
1139
  return $out;
1140
  */
1141
}
1142
1143
/**
1144
 * @todo Please document this function.
1145
 * @see http://drupal.org/node/1354
1146 c0223d83 Andreas Kohlbecker
 * @throws Exception
1147 6657531f Andreas Kohlbecker
 */
1148
function cdm_dataportal_view_reference($uuid, $arg2 = NULL) {
1149 f26245c8 Andreas Kohlbecker
1150
  cdm_check_valid_portal_page();
1151
1152 6cbefddc Andreas Kohlbecker
  return compose_cdm_reference_page($uuid);
1153 6657531f Andreas Kohlbecker
}
1154
1155
/**
1156 b2ebf0d3 Andreas Kohlbecker
 * Creates a view on a all references contained in the portal.
1157 b5dca1e2 Andreas Kohlbecker
 *
1158
 * This function is used at the path cdm_dataportal/reference/list
1159 6657531f Andreas Kohlbecker
 */
1160
function cdm_dataportal_view_reference_list($pageNumber) {
1161
  $referencePager = cdm_ws_page(CDM_WS_REFERENCE, variable_get('cdm_dataportal_search_items_on_page', CDM_DATAPORTAL_SEARCH_ITEMS_ON_PAGE), $pageNumber);
1162 b2ebf0d3 Andreas Kohlbecker
  cdm_reference_pager($referencePager, 'cdm_dataportal/reference/list/');
1163 6657531f Andreas Kohlbecker
}
1164
1165
/**
1166
 * @todo Please document this function.
1167
 * @see http://drupal.org/node/1354
1168
 */
1169
function cdm_dataportal_view_media($mediaUuid, $mediarepresentation_uuid = FALSE, $part = 0) {
1170 f26245c8 Andreas Kohlbecker
1171
  cdm_check_valid_portal_page();
1172
1173 6657531f Andreas Kohlbecker
  $media = cdm_ws_get(CDM_WS_PORTAL_MEDIA, $mediaUuid);
1174
  return theme('cdm_media_page', array(
1175
    'media' => $media,
1176
    'mediarepresentation_uuid' => $mediarepresentation_uuid,
1177
    'partId' => $part,
1178
    ));
1179
}
1180
1181
/**
1182
 * @todo Please document this function.
1183
 * @see http://drupal.org/node/1354
1184
 */
1185
function _load_taxonBase(&$taxonBase) {
1186
  if (isset($taxonBase->uuid)) {
1187
    $taxonBase->name = cdm_ws_get(CDM_WS_TAXON, array($taxonBase->uuid, "name"));
1188
    $taxonBase->name->taggedName = cdm_ws_get(CDM_WS_NAME, array($taxonBase->name->uuid, "taggedName"));
1189
    $taxonBase->name->nomenclaturalReference = cdm_ws_get(CDM_WS_NAME, array($taxonBase->name->uuid, "nomenclaturalReference"));
1190
  }
1191
}
1192
1193 9438ad3a Andreas Kohlbecker
/**
1194
 * Loads the media associated to the given taxon from the cdm server.
1195
 * The aggregation settings regarding taxon relathionships and
1196
 * taxonnomic childen are taken into account.
1197
 *
1198
 * The media lists are cached in a static variable.
1199
 *
1200
 * @param Taxon $taxon
1201
 *   A CDM Taxon entitiy
1202
 *
1203
 * @return array
1204
 *   An array of CDM Media entities
1205
 *
1206
 */
1207
function _load_media_for_taxon($taxon) {
1208
1209
  static $media = NULL;
1210
1211
  if(!isset($media)) {
1212
    $media = array();
1213
  }
1214
  if (!isset($media[$taxon->uuid])) {
1215
1216 f19f47fa Andreas Kohlbecker
    // --- GET Images --- //
1217
    $mediaQueryParameters = array(
1218
        "type" => "ImageFile",
1219
    );
1220
1221
    $relationship_choice = variable_get(CDM_AGGREGATE_BY_TAXON_RELATIONSHIPS, unserialize(CDM_AGGREGATE_BY_TAXON_RELATIONSHIPS_DEFAULT));
1222
    $mediaQueryParameters['relationships'] = implode(',', get_selection($relationship_choice['direct']));
1223 a950f2f9 Andreas Kohlbecker
    $mediaQueryParameters['relationshipsInvers'] = implode(',', get_selection($relationship_choice['invers']));
1224
1225
    $taxon_media_filter_choice = variable_get(CDM_TAXON_MEDIA_FILTER, unserialize(CDM_TAXON_MEDIA_FILTER_DEFAULT));
1226
    $mediaQueryParameters['includeTaxonDescriptions'] = (boolean) $taxon_media_filter_choice['includeTaxonDescriptions'] != 0;
1227
    $mediaQueryParameters['includeOccurrences'] = (boolean) $taxon_media_filter_choice['includeOccurrences'] != 0;
1228
    $mediaQueryParameters['includeTaxonNameDescriptions'] = (boolean) $taxon_media_filter_choice['includeTaxonNameDescriptions'] != 0;
1229 9438ad3a Andreas Kohlbecker
1230 f19f47fa Andreas Kohlbecker
    $ws_endpoint = NULL;
1231 9438ad3a Andreas Kohlbecker
    if ( variable_get('cdm_images_include_children', 0) == 0) {
1232
      $ws_endpoint = CDM_WS_PORTAL_TAXON_MEDIA;
1233
    } else {
1234
      $ws_endpoint = CDM_WS_PORTAL_TAXON_SUBTREE_MEDIA;
1235
    }
1236 f19f47fa Andreas Kohlbecker
1237
    $media[$taxon->uuid] = cdm_ws_get($ws_endpoint,
1238
        array(
1239
            $taxon->uuid,
1240
        ),
1241 9438ad3a Andreas Kohlbecker
        queryString($mediaQueryParameters)
1242
       );
1243
  }
1244
1245
  return $media[$taxon->uuid];
1246
}
1247
1248
/**
1249
 *
1250
 * @param Taxon $taxon
1251
 *   A CDM Taxon entitiy
1252
 *
1253
 * @return array
1254
 *   An array of CDM SpecimenOrObservation entities
1255
 *
1256
function _load_occurences_for_taxon($taxon){
1257
1258
  static $occurences = NULL;
1259 f19f47fa Andreas Kohlbecker
1260
  if(!isset($occurences)) {
1261
    $occurences = array();
1262
  }
1263 9438ad3a Andreas Kohlbecker
1264
  if (!isset($occurences[$taxon->uuid])){
1265
1266
    $relationship_choice = variable_get(CDM_AGGREGATE_BY_TAXON_RELATIONSHIPS, unserialize(CDM_AGGREGATE_BY_TAXON_RELATIONSHIPS_DEFAULT));
1267
    $relationship_choice['direct'] = get_selection($relationship_choice['direct']);
1268 f19f47fa Andreas Kohlbecker
    $relationship_choice['invers'] = get_selection($relationship_choice['invers']);
1269
1270
    $by_associatedtaxon_query = http_build_query(array(
1271
        'relationshipsInvers' => implode(',', $relationship_choice['invers']),
1272
        'relationships' => implode(',', $relationship_choice['direct']),
1273
        'pageSize' => null // all hits in one page
1274
    )
1275
    );
1276
1277
    $pager = cdm_ws_get(CDM_WS_OCCURRENCE_BY_ASSOCIATEDTAXON,
1278
        null,
1279
        $by_associatedtaxon_query . '&taxonUuid=' . $taxon->uuid
1280
    );
1281
1282
1283
    if(isset($pager->records[0])){
1284
      $occurences[$taxon->uuid] =  $pager->records;
1285
    }
1286
  }
1287 9438ad3a Andreas Kohlbecker
  return $occurences[$taxon->uuid];
1288
}
1289
 */
1290
1291 6657531f Andreas Kohlbecker
/**
1292
 * Gets a Drupal variable, string or array and returns it.
1293
 *
1294
 * Similar to the variable_get() function of Drupal, except that this function
1295
 * is able to handle arrays correctly. This function is especially useful
1296 8c962983 Andreas Kohlbecker
 * when dealing with collections of settings form elements (#tree = TRUE).
1297 6657531f Andreas Kohlbecker
 *
1298
 * @param string $variableKey
1299
 *   The Unique key of the Drupal variable in the Drupal variables table.
1300
 * @param string $defaultValueString
1301
 *   A string as for example derived from a CONSTANT.
1302
 *
1303
 * @return mixed
1304 8c962983 Andreas Kohlbecker
 *   usually an array, depending on the nature of the variable.
1305
 *
1306
 * TODO compare with get_array_variable_merged() duplicate functions?
1307 0f7c9d15 Andreas Kohlbecker
 * @deprecated rather use get_array_variable_merged() since this function
1308
 * used an array as second parameter
1309 6657531f Andreas Kohlbecker
 */
1310
function mixed_variable_get($variableKey, $defaultValueString) {
1311
  $systemDefaults = unserialize($defaultValueString);
1312
  $storedSettings = variable_get($variableKey, array());
1313
  if (is_array($storedSettings)) {
1314 8c962983 Andreas Kohlbecker
    // TODO better use drupal_array_merge_deep() ?
1315 6657531f Andreas Kohlbecker
    $settings = array_merge($systemDefaults, $storedSettings);
1316
  }
1317
  else {
1318
    $settings = $systemDefaults;
1319
  }
1320
  return $settings;
1321
}
1322
1323 b5519d3a Andreas Kohlbecker
/**
1324 0f7c9d15 Andreas Kohlbecker
 * Recursive function to convert an object into an array.
1325 b5519d3a Andreas Kohlbecker
 * also subordinate objects will be converted.
1326
 *
1327
 * @param object $object
1328 db725031 Andreas Kohlbecker
 *  the object to be converted
1329
 * @return array
1330
 *  The array
1331 b5519d3a Andreas Kohlbecker
 */
1332 db725031 Andreas Kohlbecker
function object_to_array($object) {
1333 b5519d3a Andreas Kohlbecker
  if(is_object($object) || is_array($object)) {
1334
    $array = (array)$object;
1335
    foreach ($array as $key=>$value){
1336 db725031 Andreas Kohlbecker
      $array[$key] = object_to_array($value);
1337 b5519d3a Andreas Kohlbecker
    }
1338
    return $array;
1339
  } else {
1340
    return $object;
1341
  }
1342
}
1343
1344 2fd6da0b Andreas Kohlbecker
/**
1345
 * Searches the $collection for the cdm entitiy given as $element.
1346
 *
1347
 * The elements are compared by their UUID.
1348
 *
1349
 * @param $element
1350
 *  the CDM entitiy to search for
1351
 * @param $collection
1352
 *  the list of CDM entities to search in
1353
 *
1354
 * @return boolean TRUE if the $collection contains the $element, otheriwse FALSE
1355
 *
1356
 */
1357
function contains_cdm_entitiy($element, $collection) {
1358
  $result = FALSE;
1359
  foreach ($collection as $a) {
1360
    if ($a->uuid == $element->uuid) {
1361
      $result = TRUE;
1362
    }
1363
  }
1364
  return $result;
1365
}
1366
1367
/**
1368
 * Fiters the array $entity_list of CDM entities by the list
1369
 * of $excludes. Any element contained in the $excludes will be removed
1370
 * from included int the retuned list.
1371
 *
1372
 * If the $entity_list is not an array the $excludes will be returned.
1373
 */
1374
function filter_cdm_entity_list($entity_list, $excludes) {
1375
  if (is_array($entity_list)) {
1376
    $result = $entity_list;
1377
    if ($excludes) {
1378
      foreach ($excludes as $exclude) {
1379
        if (!contains_cdm_entitiy($exclude, $entity_list)) {
1380
          $result[] = $exclude;
1381
        }
1382
      }
1383
    }
1384
  }
1385
  else {
1386
    $result = $excludes;
1387
  }
1388
  return $result;
1389
}
1390
1391 0a1151a4 Andreas Kohlbecker
/**
1392 6f5c7f2a Andreas Kohlbecker
 * Wraps the given $html string into a render array suitable for drupal_render()
1393 0a1151a4 Andreas Kohlbecker
 *
1394 65345976 Andreas Kohlbecker
 * @param $html
1395 0a1151a4 Andreas Kohlbecker
 *   the html string, see
1396
 *   http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#markup
1397 65345976 Andreas Kohlbecker
 * @param $weight
1398 0a1151a4 Andreas Kohlbecker
 *   A positive or negative number (integer or decimal).
1399
 *   see http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#weightval
1400 65345976 Andreas Kohlbecker
 * @param $prefix
1401
 *   Optional markup for the '#prefix' element of the render array
1402
 * @param $suffix
1403
 *   Optional markup for the '#suffix' element of the render array
1404 0a1151a4 Andreas Kohlbecker
 *
1405 65345976 Andreas Kohlbecker
 * @return array
1406 0a1151a4 Andreas Kohlbecker
 *   A render array
1407
 *
1408
 */
1409 65345976 Andreas Kohlbecker
function markup_to_render_array($html, $weight = FALSE, $prefix = NULL, $suffix = NULL) {
1410 6f5c7f2a Andreas Kohlbecker
  $render_array = array(
1411
    '#markup' => $html
1412 1ce9afb7 Patric Plitzner
      );
1413 6f5c7f2a Andreas Kohlbecker
  if (is_numeric($weight)) {
1414
    $render_array['#weight'] = $weight;
1415 65345976 Andreas Kohlbecker
  }
1416
  if($prefix){
1417
    $render_array['#prefix'] = $prefix;
1418
  }
1419
  if($suffix) {
1420
    $render_array['#suffix'] = $suffix;
1421
  }
1422 6f5c7f2a Andreas Kohlbecker
  return $render_array;
1423 0a1151a4 Andreas Kohlbecker
}
1424
1425 6657531f Andreas Kohlbecker
/**
1426
 * Loads the subgraph of a given PolytomousKeyNode.
1427
 *
1428
 * Loads the subgraph of the given PolytomousKeyNode recursively from
1429
 * the CDM REST service.
1430
 *
1431
 * @param mixed $polytomousKeyNode
1432
 *   PolytomousKeyNode passed by reference.
1433
 *
1434
 * @return void
1435
 */
1436
function _load_polytomousKeySubGraph(&$polytomousKeyNode) {
1437
1438
  if (!$polytomousKeyNode) {
1439
    return;
1440
  }
1441
  if ($polytomousKeyNode->class != "PolytomousKeyNode") {
1442 f19f47fa Andreas Kohlbecker
    drupal_set_message('_load_polytomousKeySubGraph(): ' . t('invalid type given.'), 'error');
1443 6657531f Andreas Kohlbecker
    return;
1444
  }
1445
  if (!is_uuid($polytomousKeyNode->uuid)) {
1446 f19f47fa Andreas Kohlbecker
    drupal_set_message('_load_polytomousKeySubGraph(): ' . t('invalid type given.'), 'error');
1447 6657531f Andreas Kohlbecker
    return;
1448
  }
1449
1450
  $polytomousKeyNode = cdm_ws_get(CDM_WS_POLYTOMOUSKEY_NODE, $polytomousKeyNode->uuid);
1451
1452
  if (!$polytomousKeyNode) {
1453
    // drupal_set_message("_load_polytomousKeyChildNodes() : could not load polytomousKeyNode", "error");
1454
    return;
1455
  }
1456
1457
  // Load children.
1458
  foreach ($polytomousKeyNode->children as &$childNode) {
1459
    _load_polytomousKeySubGraph($childNode);
1460
  }
1461
1462
  // Load subkey.
1463
  $polytomousKeyNode->subkey = cdm_ws_get(CDM_WS_POLYTOMOUSKEY_NODE, array($polytomousKeyNode->uuid, "subkey"));
1464
1465
  // Load taxon.
1466
  $polytomousKeyNode->taxon = cdm_ws_get(CDM_WS_POLYTOMOUSKEY_NODE, array($polytomousKeyNode->uuid, "taxon"));
1467
  _load_taxonBase($polytomousKeyNode->taxon);
1468
  return;
1469
}
1470
1471
/**
1472
 * @todo Please document this function.
1473
 * @see http://drupal.org/node/1354
1474
 */
1475
function cdm_dataportal_view_polytomousKey($polytomousKeyUuid) {
1476 f26245c8 Andreas Kohlbecker
1477
  cdm_check_valid_portal_page();
1478
1479 6657531f Andreas Kohlbecker
  $polytomousKey = cdm_ws_get(CDM_WS_POLYTOMOUSKEY, $polytomousKeyUuid);
1480
1481
  $sourcePager = cdm_ws_get(CDM_WS_POLYTOMOUSKEY, array($polytomousKeyUuid, 'sources'));
1482
  if (is_array($sourcePager->records)) {
1483
    $polytomousKey->sources = $sourcePager->records;
1484
    // $polytomousKey->sources->citation = cdm_ws_get(CDM_WS_POLYTOMOUSKEY, array($polytomousKeyUuid, 'sources'));
1485
  }
1486
1487
  $annotationPager = cdm_ws_get(CDM_WS_POLYTOMOUSKEY, array($polytomousKeyUuid, 'annotations'));
1488
  if (is_array($annotationPager->records)) {
1489
    $polytomousKey->annotations = $annotationPager->records;
1490
  }
1491
1492
  _load_polytomousKeySubGraph($polytomousKey->root);
1493
  return theme('cdm_polytomousKey_page', array('polytomousKey' => $polytomousKey));
1494
}
1495
1496
/**
1497
 * Creates a taxon page view or a chapter of it.
1498
 *
1499
 * The taxon page gives detailed information on a taxon, it shows:
1500
 *  - Taxon name.
1501
 *  - Full list of synonyms homotypic synonyms on top, followed by the
1502
 *    heterotypic and finally followed by misapplied names.
1503
 *    The list is ordered historically.
1504
 *  - All description associated with the taxon.
1505
 *
1506
 * @param string $uuid
1507
 * @param string $chapter
1508
 *   Name of the part to display, valid values are:
1509
 *   'description', 'images', 'synonymy', 'specimens', 'all'.
1510
 *
1511 793dae0a Andreas Kohlbecker
 * @return string
1512 6657531f Andreas Kohlbecker
 */
1513 0c5a23b6 Andreas Kohlbecker
function cdm_dataportal_taxon_page_view($uuid, $chapter = 'all') {
1514 5ea8b301 Andreas Kohlbecker
1515 f26245c8 Andreas Kohlbecker
  cdm_check_valid_taxon_page($chapter);
1516 2dd59bb5 Andreas Kohlbecker
  cdm_dd("START OF TAXON PAGE [" . $chapter . "] " . $uuid . ' for ' . $_GET['q']);
1517 5ea8b301 Andreas Kohlbecker
  // show a warning in case the javascript development mode is anabled
1518
  if(variable_get('cdm_js_devel_mode', FALSE)) {
1519
    drupal_set_message(t('The !url1 is enabled.
1520
        WARNING: this is a performance penalty and must be turned off on production websites.', array(
1521
          '!url1' => l('java-script development mode', 'admin/config/cdm_dataportal/settings', array('fragment' => 'edit-cdm-js-devel-mode'))
1522
    )),
1523
    'warning'
1524
        );
1525
  }
1526
1527 6657531f Andreas Kohlbecker
  // Display the page for the taxon defined by $uuid.
1528
  // set_last_taxon_page_tab(arg(3));
1529 0c5a23b6 Andreas Kohlbecker
  $taxonpage = cdm_dataportal_taxon_view($uuid, $chapter);
1530 6657531f Andreas Kohlbecker
  if (!empty($taxonpage)) {
1531 2dd59bb5 Andreas Kohlbecker
    cdm_dd("END OF TAXON PAGE [" . $chapter . "] " . $uuid);
1532 6657531f Andreas Kohlbecker
    return cdm_node_show(NODETYPE_TAXON, $uuid, $taxonpage->title, $taxonpage->content);
1533
  }
1534
  else {
1535 2dd59bb5 Andreas Kohlbecker
    cdm_dd("END OF TAXON PAGE [" . $chapter . "] " . $uuid . ' !!! PAGE IS EMPTY !!!');
1536 6657531f Andreas Kohlbecker
    return '';
1537
  }
1538
}
1539
1540
/**
1541 59f6da42 Andreas Kohlbecker
 * This function will genreate the taxon page part ($chapter) and returns a taxonpage object
1542
 * which has two fields, one for the page title and one for the content. Later on in the
1543
 * process chain the value contained in these fields will be passed to the cdm_node_show()
1544
 * function as the function parameters $title and $content.
1545 6657531f Andreas Kohlbecker
 *
1546
 * @param string $uuid
1547 59f6da42 Andreas Kohlbecker
 *   the uuid of the taxon to show
1548 6657531f Andreas Kohlbecker
 * @param string $chapter
1549
 *   Name of the part to display, valid values are:
1550
 *   'description', 'images', 'synonymy', 'all'.
1551
 *
1552 0c5a23b6 Andreas Kohlbecker
 * @return object with the following fields:
1553 59f6da42 Andreas Kohlbecker
 *   - title : the title of the page
1554
 *   - content: the content of the page
1555
 *
1556 8a1b451e Andreas Kohlbecker
 * @throws Exception
1557
 *
1558 6657531f Andreas Kohlbecker
 */
1559 8cf9238f Andreas Kohlbecker
function cdm_dataportal_taxon_view($uuid, $chapter = 'all') {
1560 6657531f Andreas Kohlbecker
  // Taxon object.
1561
  $taxon = cdm_ws_get(CDM_WS_PORTAL_TAXON, $uuid);
1562
  if (empty($taxon)) {
1563
    drupal_set_title(t('Taxon does not exist'), PASS_THROUGH);
1564 8a1b451e Andreas Kohlbecker
    return null;
1565 6657531f Andreas Kohlbecker
  }
1566
  $taxonpage = new stdClass();
1567
1568
  $taxonpage->title = theme('cdm_taxon_page_title', array(
1569 8cf9238f Andreas Kohlbecker
    'taxon' => $taxon
1570 6657531f Andreas Kohlbecker
  ));
1571
1572
  // Check if the taxon id contained in the currently selected tree.
1573 7663cd0b Andreas Kohlbecker
  $taxon_in_current_classification = taxon_in_current_classification($uuid);
1574 61b6ee11 Andreas Kohlbecker
1575 7663cd0b Andreas Kohlbecker
  if (!$taxon_in_current_classification) {
1576 61b6ee11 Andreas Kohlbecker
    $classifications = get_classifications_for_taxon($taxon);
1577 e24d373b Andreas Kohlbecker
    RenderHints::pushToRenderStack('not_in_current_classification');
1578
    $taxon_name_markup = render_taxon_or_name($taxon);
1579
1580 61b6ee11 Andreas Kohlbecker
    if (count($classifications) == 0) {
1581 e24d373b Andreas Kohlbecker
      drupal_set_message(t('This concept of the taxon !taxonname is not contained as an accepted taxon in the currently chosen classification.',
1582 fba00a4f Andreas Kohlbecker
        array(
1583 e24d373b Andreas Kohlbecker
        '!taxonname' => $taxon_name_markup,
1584 fba00a4f Andreas Kohlbecker
        )
1585
      ), 'warning');
1586 6657531f Andreas Kohlbecker
    }
1587
    else {
1588
      $trees = '';
1589 61b6ee11 Andreas Kohlbecker
      foreach ($classifications as $classification) {
1590
        if (isset($classification->titleCache)) {
1591
          $trees .= ($trees ? ', ' : '') . '<strong>' . $classification->titleCache . '</strong>';
1592 6657531f Andreas Kohlbecker
        }
1593
      }
1594
1595 15b7c460 Andreas Kohlbecker
      drupal_set_message(format_plural(count($trees),
1596 e24d373b Andreas Kohlbecker
          'This concept of the taxon !taxonname is not contained as an accepted taxon in the currently chosen classification, but in this one: !trees',
1597
          'This concept of the taxon !taxonname is not contained as an accepted taxon in the currently chosen classification, but in one of these: !trees',
1598
          array('!taxonname' => $taxon_name_markup, '!trees' => $trees)
1599 fba00a4f Andreas Kohlbecker
        ) ,
1600
        'warning');
1601 6657531f Andreas Kohlbecker
    }
1602 e24d373b Andreas Kohlbecker
    RenderHints::popFromRenderStack();
1603 6657531f Andreas Kohlbecker
  }
1604
1605
  // Render the taxon page.
1606 9a607f17 Andreas Kohlbecker
  $render_array = compose_cdm_taxon_page($taxon, $chapter);
1607
  $taxonpage->content = drupal_render($render_array);
1608 6657531f Andreas Kohlbecker
1609
  return $taxonpage;
1610
}
1611
1612 9d37c9d9 Patric Plitzner
/**
1613
 * Creates a specimen page view.
1614
 * @param string $uuid the UUID of the specimen
1615
 * @return array|string
1616
 */
1617
function cdm_dataportal_specimen_page_view($uuid) {
1618
1619
    //cdm_check_valid_taxon_page($chapter);
1620
    //cdm_dd("START OF TAXON PAGE [" . $chapter . "] " . $uuid . ' for ' . $_GET['q']);
1621
    // show a warning in case the javascript development mode is anabled
1622
    if(variable_get('cdm_js_devel_mode', FALSE)) {
1623
        drupal_set_message(t('The !url1 is enabled.
1624
        WARNING: this is a performance penalty and must be turned off on production websites.', array(
1625
            '!url1' => l('java-script development mode', 'admin/config/cdm_dataportal/settings', array('fragment' => 'edit-cdm-js-devel-mode'))
1626
        )),
1627
            'warning'
1628
        );
1629
    }
1630
1631
    // Display the page for the specimen defined by $uuid.
1632
    $specimenpage = cdm_dataportal_specimen_view($uuid);
1633
    if (!empty($specimenpage)) {
1634
        return cdm_node_show(NODETYPE_TAXON, $uuid, $specimenpage->title, $specimenpage->content);
1635
    }
1636
    else {
1637
        return '';
1638
    }
1639
}
1640
1641
/**
1642
 *
1643
 * Creates a specimen view.
1644
 * @param string $uuid the UUID of the specimen
1645
 * @return array|string
1646
 */
1647
function cdm_dataportal_specimen_view($uuid) {
1648 907cc9b4 Patrick Plitzner
    $specimen = cdm_ws_get(CDM_WS_PORTAL_OCCURRENCE, $uuid);
1649 9d37c9d9 Patric Plitzner
    if (empty($specimen)) {
1650
        drupal_set_title(t('Specimen does not exist'), PASS_THROUGH);
1651
        return FALSE;
1652
    }
1653
    $specimenpage = new stdClass();
1654
1655
    $specimenpage->title = theme('cdm_specimen_page_title', array(
1656
        'specimen' => $specimen
1657
    ));
1658
1659 b810158e Patric Plitzner
    // Render the specimen page.
1660
    $render_array = compose_cdm_specimen_page($uuid);
1661 9d37c9d9 Patric Plitzner
    $specimenpage->content = drupal_render($render_array);
1662
1663
    return $specimenpage;
1664
}
1665
1666 30845bda Andreas Kohlbecker
/**
1667
 *
1668
 * Creates a named area view.
1669
 * @param string $uuid the UUID of the specimen
1670
 *  * @return object
1671
 *   An object with two fields:
1672
 *     - title: the page title
1673
 *     - content: the page content
1674
 */
1675
1676
function cdm_dataportal_named_area_view($uuid) {
1677
  $named_area = cdm_ws_get(CDM_WS_PORTAL_TERM, $uuid);
1678
  if (empty($named_area) || $named_area->class !== 'NamedArea') {
1679
    drupal_set_title(t('Named area does not exist'), PASS_THROUGH);
1680
    return FALSE;
1681
  }
1682
  $named_area_page = new stdClass();
1683
1684
  $named_area_page->title = $named_area->representation_L10n;
1685
1686
  // Render the specimen page.
1687
  $render_array = compose_cdm_named_area_page($uuid);
1688
  $named_area_page->content = drupal_render($render_array);
1689
1690
  return $named_area_page;
1691
}
1692
1693
function cdm_dataportal_named_area_page_view($uuid) {
1694
1695
  cdm_check_valid_portal_page();
1696
1697
  $named_area_page = cdm_dataportal_named_area_view($uuid);
1698
  if (!empty($named_area_page)) {
1699
    return cdm_node_show(NODETYPE_NAME, $uuid, $named_area_page->title, $named_area_page->content);
1700
  }
1701
  else {
1702
    return '';
1703
  }
1704
1705
1706
}
1707
1708 6657531f Andreas Kohlbecker
/**
1709
 * Returns a name page as a Drupal node ready to be renderized by Drupal.
1710
 *
1711
 * The node page shows the taxon name title and the list of taxon related
1712
 * with such taxon. Name on the tree already in use.
1713
 *
1714 51b04faf Andreas Kohlbecker
 * @param UUID $taxon_name_uuid
1715 102f8c26 Andreas Kohlbecker
 *   The uuid of the CDM TaxonName to show a name page for
1716 51b04faf Andreas Kohlbecker
 * @param UUID $taxon_to_hide_uuid
1717
 *   A taxon which should not be displayed in the taxon list
1718
 * @param UUID $highlite_synonym_uuid
1719
 *   Optinal parameter wich takes another taxon uuid, if given the
1720
 *   target taxon pages will show the syonymy tab where the taxon
1721
 *   refenrenced by the $highlite_synonym_uuid will be highlighted
1722
 *   in case it is found on this page.
1723 6657531f Andreas Kohlbecker
 *
1724
 * @return mixed
1725
 *   The formatted name page as node.
1726
 */
1727
function cdm_dataportal_name_page_view($taxon_name_uuid, $taxon_to_hide_uuid, $synonym_uuid = NULL) {
1728
1729 f26245c8 Andreas Kohlbecker
  cdm_check_valid_portal_page();
1730
1731 6657531f Andreas Kohlbecker
  $taxonname_page = cdm_dataportal_name_view($taxon_name_uuid, $taxon_to_hide_uuid, $synonym_uuid);
1732
  if (!empty($taxonname_page)) {
1733
    return cdm_node_show(NODETYPE_NAME, $taxon_name_uuid, $taxonname_page->title, $taxonname_page->content);
1734
  }
1735
  else {
1736
    return '';
1737
  }
1738
}
1739
1740
/**
1741 102f8c26 Andreas Kohlbecker
 * View function for a TaxonName page.
1742 6657531f Andreas Kohlbecker
 *
1743 e3001c8d Andreas Kohlbecker
 * The name page lists all taxa for which the name specified by the
1744
 * $taxon_name_uuid is being used. I case there is only one name the
1745
 * page automatically redirects ti the according taxon page. Otherwise
1746
 * the list of names is displayed.
1747 6657531f Andreas Kohlbecker
 *
1748 e3001c8d Andreas Kohlbecker
 * The parameter $taxon_to_hide_uuid allows to exclude a taxon from the
1749
 * list of taxa. This is useful for example when referencing from a taxon
1750
 * to the name page and the referring taxon should not be repeaded in the
1751
 * name page.
1752 6657531f Andreas Kohlbecker
 *
1753 e3001c8d Andreas Kohlbecker
 *
1754
 * @param UUID $taxon_name_uuid
1755 102f8c26 Andreas Kohlbecker
 *   The uuid of the CDM TaxonName to show a name page for
1756 e3001c8d Andreas Kohlbecker
 * @param UUID $taxon_to_hide_uuid
1757
 *   A taxon which should not be displayed in the taxon list
1758
 * @param UUID $highlite_synonym_uuid
1759
 *   Optinal parameter wich takes another taxon uuid, if given the
1760
 *   target taxon pages will show the syonymy tab where the taxon
1761
 *   refenrenced by the $highlite_synonym_uuid will be highlighted
1762
 *   in case it is found on this page.
1763
 *
1764
 * @return object
1765
 *   An object with two fields:
1766
 *     - title: the page title
1767
 *     - content: the page content
1768 6657531f Andreas Kohlbecker
 */
1769 e3001c8d Andreas Kohlbecker
function cdm_dataportal_name_view($taxon_name_uuid, $taxon_to_hide_uuid, $highlite_synonym_uuid = NULL) {
1770 6657531f Andreas Kohlbecker
  // Getting the full taxonname object from the server.
1771 d0d068e9 Andreas Kohlbecker
  $taxon_name = cdm_ws_get(CDM_WS_PORTAL_NAME, array($taxon_name_uuid));
1772 6657531f Andreas Kohlbecker
  if (!$taxon_name) {
1773
    drupal_set_title(t('Taxon name does not exist'), PASS_THROUGH);
1774
    return FALSE;
1775
  }
1776
  // Searching for all the taxa connected with the taxon name on the tree
1777
  // in use.
1778
  $name_cache = cdm_ws_get(CDM_WS_NAME_NAMECAHE, array($taxon_name_uuid));
1779
  $request_params = array();
1780
  $request_params['query'] = $name_cache;
1781 7663cd0b Andreas Kohlbecker
  $request_params['tree'] = get_current_classification_uuid();
1782 6657531f Andreas Kohlbecker
  $request_params['doTaxa'] = 1;
1783
  $request_params['doSynonyms'] = 1;
1784
  $request_params['doTaxaByCommonNames'] = 0;
1785
  $request_params['matchMode'] = "EXACT";
1786
  $taxon_pager = cdm_ws_get(CDM_WS_PORTAL_TAXON_FIND, NULL, queryString($request_params));
1787
1788 d0d068e9 Andreas Kohlbecker
  // Removing the name where we came from.
1789 6657531f Andreas Kohlbecker
  foreach ($taxon_pager->records as $k => &$taxon) {
1790
    if ($taxon->uuid == $taxon_to_hide_uuid) {
1791
      unset($taxon_pager->records[$k]);
1792
    }
1793
  }
1794
  // Show the taxa list or go to the singular taxon.
1795
  if (sizeof($taxon_pager->records) == 1) {// Single taxon case.
1796 e3001c8d Andreas Kohlbecker
    $singleTaxon = array_pop($taxon_pager->records);
1797 6657531f Andreas Kohlbecker
    if ($singleTaxon->class != "Taxon") {
1798
      // It is a Synonym -> look for the accepted.
1799 7635cc7d Andreas Kohlbecker
      $accepted_taxon = cdm_ws_get(CDM_WS_PORTAL_TAXON_ACCEPTED, array($singleTaxon->uuid), 'classificationFilter=' . get_current_classification_uuid());
1800 e3001c8d Andreas Kohlbecker
      if (!empty($highlite_synonym_uuid)) {
1801 7635cc7d Andreas Kohlbecker
        drupal_goto('cdm_dataportal/taxon/' . $accepted_taxon->uuid . '/synonymy', array('query' => array('highlite' => $highlite_synonym_uuid)));
1802 6657531f Andreas Kohlbecker
      }
1803
      else {
1804 7635cc7d Andreas Kohlbecker
        drupal_goto('cdm_dataportal/taxon/' . $accepted_taxon->uuid . '/synonymy', array('query' => array('highlite' => $singleTaxon->uuid)));
1805 6657531f Andreas Kohlbecker
      }
1806
    }
1807
    else {
1808
      // It is an accepted taxon.
1809 e3001c8d Andreas Kohlbecker
      if (!empty($highlite_synonym_uuid)) {
1810
        drupal_goto('cdm_dataportal/taxon/' . $singleTaxon->uuid . '/synonymy', array('query' => array('highlite' => $highlite_synonym_uuid)));
1811 6657531f Andreas Kohlbecker
      }
1812
      else {
1813
        drupal_goto('cdm_dataportal/taxon/' . $singleTaxon->uuid);
1814
      }
1815
    }
1816
  }
1817
  else {// More than one taxa case.
1818
    $taxon_name_page = new stdClass();
1819 4f225a0f Andreas Kohlbecker
    $taxon_name_page->title = theme('cdm_name_page_title', array('taxon_name' => $taxon_name));
1820 6657531f Andreas Kohlbecker
    if ($taxon_pager->records) {
1821 7272d19c Andreas Kohlbecker
      $taxon_name_page->content = compose_list_of_taxa($taxon_pager->records);
1822 6657531f Andreas Kohlbecker
    }
1823
    else {
1824 6b294c11 Andreas Kohlbecker
      $taxon_name_page->content = 'This name is not assigned to a taxon.';
1825 6657531f Andreas Kohlbecker
    }
1826
    return $taxon_name_page;
1827
  }
1828
}
1829
1830 e0d3e148 Andreas Kohlbecker
/**
1831
 * Returns a registration page as a Drupal node to be rendered by Drupal.
1832
 *
1833
 * @param string  $registration_identifier_encoded
1834
 *   The persistent identifier of the registration urlencoded.
1835
 * @return mixed
1836
 *   The formatted registration page as node.
1837
 */
1838
function cdm_dataportal_registration_page_view($registration_identifier_encoded) {
1839
1840
  cdm_check_valid_portal_page("/\/cdm_dataportal\/registration\/.*$/");
1841
  $registration_page = cdm_dataportal_registration_view($registration_identifier_encoded);
1842
  return cdm_node_show_simulate($registration_page);
1843
}
1844
1845
function cdm_dataportal_registration_view($registration_identifier_encoded) {
1846
1847
  $registration_identifier = urldecode($registration_identifier_encoded);
1848
1849
1850
1851 6cbefddc Andreas Kohlbecker
  $render_array = array();
1852 e0d3e148 Andreas Kohlbecker
  $registration_dto = cdm_ws_get("registrationDTO/identifier/" . $registration_identifier_encoded);
1853
  if($registration_dto){
1854
    drupal_set_title(t('Registration') . ' ' . $registration_identifier, PASS_THROUGH);
1855
1856 5e4cae59 Andreas Kohlbecker
    $render_array = compose_registation_dto($registration_dto);
1857 e0d3e148 Andreas Kohlbecker
1858 db725031 Andreas Kohlbecker
    if(is_object($registration_dto->orderdTypeDesignationWorkingSets)){
1859
      $field_unit_uuids = array();
1860
      foreach((array)$registration_dto->orderdTypeDesignationWorkingSets as $field_unit_ref => $obj){
1861
        $tokens = explode("#", $field_unit_ref);
1862
        $field_unit_uuids[] = $tokens[1];
1863
      }
1864 67f32f09 Andreas Kohlbecker
      $render_array['specimen_table'] = compose_specimen_table($field_unit_uuids);
1865 db725031 Andreas Kohlbecker
    }
1866 e0d3e148 Andreas Kohlbecker
1867
  } else {
1868
    drupal_set_title(t('Registration not found'), PASS_THROUGH);
1869
    $render_array['error'] = markup_to_render_array("A registration with the identifier  " . $registration_identifier . " does not exist.");
1870
  }
1871
1872
  return $render_array ;
1873
}
1874
1875 6cbefddc Andreas Kohlbecker
/**
1876 5e4cae59 Andreas Kohlbecker
 * Composes information for a registation from a dtp object
1877
 *
1878 6cbefddc Andreas Kohlbecker
 * @param $registration_dto
1879 5e4cae59 Andreas Kohlbecker
 *
1880 6cbefddc Andreas Kohlbecker
 * @return array
1881 5e4cae59 Andreas Kohlbecker
 *    A drupal render array
1882
 *
1883
 * @ingroup compose
1884 6cbefddc Andreas Kohlbecker
 */
1885
function compose_registation_dto($registration_dto, $with_citation = true, $with_identifier = false)
1886
{
1887
  $render_array = array();
1888 723aa98c Andreas Kohlbecker
  $media_link_map = array();
1889 afe99f4d Andreas Kohlbecker
  $taggged_text_expanded = cdm_tagged_text_expand_entity_references($registration_dto->summaryTaggedText);
1890 723aa98c Andreas Kohlbecker
  foreach ($taggged_text_expanded  as $tagged_text){
1891
    if(isset($tagged_text->entityReference->type) && $tagged_text->entityReference->type == 'SpecimenTypeDesignation') {
1892
      $mediaDTOs = cdm_ws_get('typedesignation/$0/media', array($tagged_text->entityReference->uuid));
1893
      if(isset($mediaDTOs[0]->uri)){
1894
          $media_url_key = '{link-' . $mediaDTOs[0]->uuid . '}';
1895
          $tagged_text->text = str_replace('[icon]', '[icon]' . $media_url_key, $tagged_text->text);
1896
          $media_link_map[$media_url_key] =  cdm_external_uri($mediaDTOs[0]->uri, true);
1897
      }
1898
    }
1899
  }
1900 afe99f4d Andreas Kohlbecker
  $registation_markup = cdm_tagged_text_to_markup($taggged_text_expanded);
1901 723aa98c Andreas Kohlbecker
  foreach($media_link_map as $media_url_key => $link){
1902
    $registation_markup = str_replace($media_url_key, $link, $registation_markup);
1903
  }
1904 6cbefddc Andreas Kohlbecker
  if($with_identifier){
1905
    $registation_markup .= " " . l ($registration_dto->identifier, $registration_dto->identifier);
1906
  }
1907
  $render_array['summary'] = markup_to_render_array("<div>" . $registation_markup . "</div>");
1908 84e766b2 Andreas Kohlbecker
1909
  if ($with_citation) {
1910
    $render_array['citation'] = markup_to_render_array("<div class=\"" . html_class_attribute_ref(new TypedEntityReference("Reference", $registration_dto->citationUuid)) . "\">"
1911
      . l($registration_dto->bibliographicCitationString, path_to_reference($registration_dto->citationUuid))
1912
      . "</br>&nbsp;</div>");
1913
  }
1914
1915 6cbefddc Andreas Kohlbecker
  return $render_array;
1916
}
1917 e0d3e148 Andreas Kohlbecker
1918
1919 6657531f Andreas Kohlbecker
/**
1920 84b13813 Andreas Kohlbecker
 * Creates a page with the advance search form.
1921
 *
1922
 * NOTE: The advance search form allows searching for taxa.
1923 6657531f Andreas Kohlbecker
 */
1924
function cdm_dataportal_view_search_advanced() {
1925
  drupal_set_title(t('Advanced search'), PASS_THROUGH);
1926
  return drupal_get_form('cdm_dataportal_search_taxon_form_advanced');
1927
}
1928
1929
/**
1930 84b13813 Andreas Kohlbecker
 * Creates a page with the search form for searching by taxon descriptions.
1931 6657531f Andreas Kohlbecker
 */
1932
function cdm_dataportal_view_search_taxon_by_description() {
1933 6441ddfb Andreas Kohlbecker
  drupal_set_title(t('Search by factual data'), PASS_THROUGH);
1934 6657531f Andreas Kohlbecker
  return drupal_get_form('cdm_dataportal_search_taxon_by_description_form');
1935
}
1936
1937
/**
1938
 * Executes the search and generates the result list of taxa.
1939
 */
1940
function cdm_dataportal_view_search_results_taxon() {
1941
1942 24797d7f Andreas Kohlbecker
  $taxonPager = cdm_dataportal_search_taxon_execute();
1943 6657531f Andreas Kohlbecker
1944 f19f47fa Andreas Kohlbecker
  $showThumbnails = do_showThumbnails();
1945
1946
  $setSessionUri = url('cdm_api/setvalue/session', array(
1947
      'query' => array('var' => '[pageoption][searchtaxa][showThumbnails]', 'val' => ''),
1948
  ));
1949
1950
  drupal_add_js('jQuery(document).ready(function() {
1951
1952
      // init
1953
      if(' . $showThumbnails . ' == 1){
1954 1d69a96c Andreas Kohlbecker
          jQuery(\'.media_gallery\').show(20);
1955
      } else {
1956
          jQuery(\'.media_gallery\').hide(20);
1957
      }
1958
1959
      // add change handler
1960
      jQuery(\'#showThumbnails input.showThumbnails\').change(
1961 f19f47fa Andreas Kohlbecker
      function(event){
1962 1d69a96c Andreas Kohlbecker
        var state = 0;
1963
        if(jQuery(this).is(\':checked\')){
1964
          jQuery(\'.media_gallery\').show(20);
1965
          state = 1;
1966
        } else {
1967
          jQuery(\'.media_gallery\').hide(20);
1968
        }
1969
        // store state in session variable
1970
        var uri = \'' . $setSessionUri . '\' + state;
1971
        jQuery.get(uri);
1972
      });
1973 78e178e2 Andreas Kohlbecker
  });',
1974 f19f47fa Andreas Kohlbecker
  array('type' => "inline", 'scope' => JS_DEFAULT));
1975
1976 78e178e2 Andreas Kohlbecker
  drupal_set_title(t('Search results'), PASS_THROUGH);
1977
1978 0a1dc066 Andreas Kohlbecker
  return theme('cdm_search_taxa_results', array(
1979 6657531f Andreas Kohlbecker
    'pager' => $taxonPager,
1980
    'path' => 'cdm_dataportal/search/results/taxon',
1981
    ));
1982
}
1983
1984 a6ae799b Andreas Kohlbecker
/**
1985
 * Executes the search for registrations and generates the result list..
1986
 */
1987
function cdm_dataportal_view_search_registrations_results() {
1988
1989
  $block = block_load('cdm_dataportal', 'registrations_search_filter');
1990
  $render_array = _block_get_renderable_array(_block_render_blocks(array($block)));
1991
1992
  $registration_pager = cdm_dataportal_search_registrations_execute();
1993
1994
  drupal_set_title(t('Search registrations'), PASS_THROUGH);
1995
1996 24797d7f Andreas Kohlbecker
  $registrations_pager_array = compose_registrations_search_results($registration_pager);
1997 a6ae799b Andreas Kohlbecker
1998
  $render_array = array_merge($render_array, $registrations_pager_array);
1999
2000
  return $render_array;
2001
}
2002
2003
2004 94550ff9 Andreas Kohlbecker
/**
2005
 * Provides the standart image wich indicated a loading process
2006
 *
2007
 * @return string
2008
 *  The img html tag
2009
 */
2010
function loading_image_html() {
2011
  return '<img class="loading" src="' . base_path() . drupal_get_path('module', 'cdm_dataportal')
2012
    . '/images/loading_circle_grey_16.gif" style="display:none;">';
2013
}
2014
2015 78e178e2 Andreas Kohlbecker
/**
2016
 * Returns the state of the the showThumbnails flag set in the
2017
 * users session ($_SESSION['pageoption']['searchtaxa']['showThumbnails']).
2018
 *
2019 c5ed6357 Andreas Kohlbecker
 * @return boolean
2020 78e178e2 Andreas Kohlbecker
 *    returns 1 if the flag is set
2021
 */
2022
function do_showThumbnails() {
2023
  static $showThumbnails = null;
2024
2025
  if($showThumbnails == null) {
2026 c5ed6357 Andreas Kohlbecker
    $showThumbnails = 0;
2027
    if (!isset($_SESSION['pageoption']['searchtaxa']['showThumbnails'])) {
2028
      $showThumbnails = 0;
2029
      $search_gallery_settings = variable_get(CDM_DATAPORTAL_SEARCH_GALLERY_NAME, null);
2030
      $showThumbnails = is_array($search_gallery_settings)
2031
        && isset($search_gallery_settings['cdm_dataportal_show_taxon_thumbnails'])
2032
        && (
2033
            $search_gallery_settings['cdm_dataportal_show_taxon_thumbnails'] +
2034
            $search_gallery_settings['cdm_dataportal_show_synonym_thumbnails'] +
2035
            $search_gallery_settings['cdm_dataportal_show_thumbnail_captions'] > 0
2036
            )
2037
         ? 1 : 0;
2038 f19f47fa Andreas Kohlbecker
2039 c5ed6357 Andreas Kohlbecker
       drupal_array_set_nested_value($_SESSION, array('pageoption', 'searchtaxa', 'showThumbnails'), $showThumbnails);
2040
    }
2041 f19f47fa Andreas Kohlbecker
    $showThumbnails = $_SESSION['pageoption']['searchtaxa']['showThumbnails'];
2042
    if (!is_numeric($showThumbnails)) {
2043
      $showThumbnails = 1;
2044
    }
2045 78e178e2 Andreas Kohlbecker
  }
2046
2047
  return $showThumbnails;
2048
}
2049
2050 6657531f Andreas Kohlbecker
2051 a6ae799b Andreas Kohlbecker
2052 6657531f Andreas Kohlbecker
/* ====================== other functions ====================== */
2053
/**
2054
 * Creates a URL to the taxon page specified by the $uuid parameter.
2055
 *
2056
 * The URL will be prepended with a path element to a specific taxon page tab.
2057
 *
2058
 * This tab is either taken from the CDM_DATAPORTAL_DEFAULT_TAXON_TAB which can
2059
 * be set globally in the administrative settings or individually in the user
2060
 * profile. If the CDM_DATAPORTAL_DEFAULT_TAXON_TAB value is set to LAST_VISITED_TAB
2061
 * the last portal will stay on this last tab.
2062
 *
2063
 * A third option is offerered by the $page_tab parameter which allows overwriting this
2064
 * internal mechanism by a specific value.
2065
 *
2066
 * @param string $uuid
2067
 *   The UUID of the taxon.
2068
 * @param string $page_tab
2069
 *   Overwriting the preset mechanism by defining specific value for the
2070
 *   taxon page tab.
2071
 *
2072
 * @return string
2073
 *   The created URL.
2074
 */
2075
function path_to_taxon($uuid, $page_tab = FALSE) {
2076
2077
  $tab = get_default_taxon_tab();
2078
  $values = unserialize(CDM_DATAPORTAL_DEFAULT_TAXON_TAB);
2079
2080
  if (!$uuid) {
2081
    return FALSE;
2082
  }
2083
2084
  if ($page_tab) {
2085
    return 'cdm_dataportal/taxon/' . $uuid . '/' . $page_tab;
2086
  }
2087
  elseif (!$tab || strtolower($tab) == 'general') {
2088
    return 'cdm_dataportal/taxon/' . $uuid;
2089
  }
2090
  elseif (get_last_taxon_page_tab() &&   $tab == $values[CDM_DATAPORTAL_LAST_VISITED_TAB_ARRAY_INDEX]) {
2091
    return 'cdm_dataportal/taxon/' . $uuid . '/' . get_last_taxon_page_tab();
2092
  }
2093
  else {
2094
    return 'cdm_dataportal/taxon/' . $uuid . '/' . strtolower($tab);
2095
  }
2096
}
2097
2098 9d37c9d9 Patric Plitzner
function path_to_specimen($uuid) {
2099
2100
    if (!$uuid) {
2101
        return FALSE;
2102
    }
2103
    else {
2104
        return 'cdm_dataportal/specimen/' . $uuid;
2105
    }
2106
}
2107
2108 30845bda Andreas Kohlbecker
function path_to_named_area($uuid) {
2109
2110
  if (!$uuid) {
2111
    return FALSE;
2112
  }
2113
  else {
2114
    return 'cdm_dataportal/named_area/' . $uuid;
2115
  }
2116
}
2117
2118 6657531f Andreas Kohlbecker
/**
2119 630c7044 Andreas Kohlbecker
 * Creates a URL to show a synonmy in the according taxon page.
2120
 *
2121
 * The URL will point to the synonymy tab of the taxon page of the accepted taxon given as parameter $acceptedUuid.
2122
 * The resulting URI will include query parameters to highlight the synonym, and to optionally display
2123
 * the accepted taxons name in aform like "Foo bar is accepted taxon for Ree doo". The URI will also
2124
 * include the sysnonym uuid as fragment in order to let the browser scroll to the according location
2125
 * in the page
2126
 *
2127
 * @param string $synonymUuid
2128
 *    The uuid of the synonym
2129
 * @param string $acceptedUuid
2130
 *    The uuid of the according accepted taxon
2131
 * @return string
2132
 *    The URL to show a synonmy in the according taxon page
2133 6657531f Andreas Kohlbecker
 */
2134
function uri_to_synonym($synonymUuid, $acceptedUuid) {
2135
  $acceptedPath = path_to_taxon($acceptedUuid, "synonymy");
2136 d071bed7 Andreas Kohlbecker
  return url($acceptedPath, array(
2137
      'query' => array(
2138
        // highlite the synony in the synonymy
2139
        'highlite' => $synonymUuid,
2140
        // the taxon page is refered from a synonym and the synonym can optionally be named in the page title
2141
        // see theme_taxon_page_title()
2142
        'acceptedFor' => $synonymUuid
2143 630c7044 Andreas Kohlbecker
      ),
2144
      'fragment' => $synonymUuid
2145 d071bed7 Andreas Kohlbecker
  ));
2146
2147 6657531f Andreas Kohlbecker
}
2148
2149
/**
2150 e0d3e148 Andreas Kohlbecker
 * Composes the drupal path to the key identified by the uuid.
2151 b8bfa4bd Andreas Kohlbecker
 *
2152
 * @param string $keyType
2153
 *    the key typer corresponds to the specific class of the CDM
2154
 *    IdentificationKey. Possible values are
2155
 *      -PolytomousKey
2156
 *      -MultimediaKey
2157
 *      - ...
2158 e0d3e148 Andreas Kohlbecker
 * @param string $keyUuid
2159 b8bfa4bd Andreas Kohlbecker
 *   The UUID of the key
2160 6657531f Andreas Kohlbecker
 */
2161
function path_to_key($keyType, $keyUuid) {
2162
  if (!$keyUuid || !$keyType) {
2163
    return FALSE;
2164
  }
2165
  $keyType{0} = strtolower($keyType{0});
2166
  return "cdm_dataportal/" . $keyType . "/$keyUuid";
2167
}
2168
2169
/**
2170 e0d3e148 Andreas Kohlbecker
 * Composes the drupal path to the reference identified by the uuid.
2171
 *
2172
 * @param $uuid string String representation of the registration entity uuid.
2173
 *
2174
 * @return string
2175
 *  The drupal path
2176
 *
2177 6657531f Andreas Kohlbecker
 */
2178
function path_to_reference($uuid) {
2179
  if (!$uuid) {
2180
    return FALSE;
2181
  }
2182
  return 'cdm_dataportal/reference/' . $uuid;
2183
}
2184
2185 e0d3e148 Andreas Kohlbecker
/**
2186
 * Composes the drupal path to the reference identified by the uuid.
2187
 *
2188
 * @param string $identifier
2189
 *  The persistent identifier of the registration entity (Registration.identifier).
2190
 * @return string
2191
 *  The drupal path
2192
 */
2193
function path_to_registration($identifier) {
2194
2195
  return 'cdm_dataportal/registration/' . urlencode($identifier);
2196
}
2197
2198 6657531f Andreas Kohlbecker
/**
2199 51b04faf Andreas Kohlbecker
 * Creates the path to a cdm_dataportal taxon name page.
2200
 *
2201 e0d3e148 Andreas Kohlbecker
 * @param string $taxon_name_uuid
2202
 *   The uuid as string of the CDM TaxonName to show a name page for
2203
 * @param string $taxon_to_hide_uuid
2204
 *   The uuid as string of a taxon which should not be displayed in the taxon list
2205
 * @param string $highlite_synonym_uuid
2206
 *   Optional parameter which takes another taxon uuid, if given the
2207
 *   target taxon pages will show the synonymy tab where the taxon
2208
 *   referenced by the $highlite_synonym_uuid will be highlighted
2209 51b04faf Andreas Kohlbecker
 *   in case it is found on this page.
2210
 *
2211 e0d3e148 Andreas Kohlbecker
 * @return string
2212
 *  URI path element as string
2213 6657531f Andreas Kohlbecker
 */
2214 51b04faf Andreas Kohlbecker
function path_to_name($name_uuid, $taxon_to_hide_uuid = NULL, $synonym_uuid  = NULL) {
2215 6657531f Andreas Kohlbecker
  $res = FALSE;
2216
  if ($name_uuid) {
2217
    $res = 'cdm_dataportal/name/' . $name_uuid;
2218
  }
2219 51b04faf Andreas Kohlbecker
  if($taxon_to_hide_uuid){
2220
    $res .= '/' . $taxon_to_hide_uuid;
2221
    if($synonym_uuid){
2222
      $res .= '/' . $synonym_uuid;
2223
    }
2224
  }
2225 6657531f Andreas Kohlbecker
  return $res;
2226
}
2227
2228
/**
2229 e0d3e148 Andreas Kohlbecker
 * Composes the drupal path to the media entity identified by the uuid.
2230
 *
2231
 * @param string $uuid
2232
 *  The persistent identifier of the entity entity
2233
 * @return string
2234
 *  The drupal path
2235 6657531f Andreas Kohlbecker
 */
2236
function path_to_media($uuid, $representaion_uuid = FALSE, $partId = FALSE) {
2237
  if (!$uuid) {
2238
    return FALSE;
2239
  }
2240
  $out = 'cdm_dataportal/media/' . $uuid;
2241
  if ($representaion_uuid) {
2242
    $out .= '/' . $representaion_uuid;
2243 a867b774 Andreas Kohlbecker
    if (is_numeric($partId)) {
2244 6657531f Andreas Kohlbecker
      $out .= '/' . $partId;
2245
    }
2246
  }
2247
  return $out;
2248
}
2249
2250
/**
2251
 * Compares thisRank with thatRank.
2252
 *
2253
 * Returns a negative integer, zero, or a positive integer
2254
 * as the of thisRank is higher than, equal to, or lower than thatRank.
2255
 * e.g:
2256
 * <ul>
2257
 * <li>rank_compare({species_uuid}, {genus_uuid}) = -1</li>
2258
 * <li>rank_compare({genus_uuid}, {genus_uuid}) = 0</li>
2259
 * <li>rank_compare({genus_uuid}, {tribus_uuid}) = 1</li>
2260
 * </ul>
2261
 * <p>
2262
 * This compare logic of the underlying webservice is the
2263
 * <b>inverse logic</b> of the the one implemented in
2264
 * java.lang.Comparable#compareTo(java.lang.Object)
2265
 *
2266
 * @param $thisRankUuid
2267
 * @param $thatRankUuid
2268
 *
2269
 * @return int
2270
 *   A negative integer, zero, or a positive integer
2271
 *   as the thisRank is lower than, equal to, or higher than thatRank.
2272
 */
2273
function rank_compare($thisRankUuid, $thatRankUuid) {
2274
  $result = cdm_ws_get(CDM_WS_TERM_COMPARE, array($thisRankUuid, $thatRankUuid));
2275
  return $result->Integer;
2276
}
2277
2278
/**
2279
 * Composes an HTML element class attribute value composed of
2280 4b3be949 Andreas Kohlbecker
 * the short-name of the cdm class and the uuid of the entity.
2281
 * This class attribute should be used wherever an cdm-entity is rendered.
2282
 *
2283
 * In case of Taxon entities or TaxonNodeDTOs the secReference is also added
2284
 * to the class attributes as 'sec_uuid:<uuid>'. In case of TaxonNodeDTOs the
2285
 * Taxon uuid is added also as taxon_uuid:<uuid>
2286 6657531f Andreas Kohlbecker
 *
2287
 * These according class selectors in css must be escaped, eg:
2288
 *    .cdm\:TextData
2289
 *
2290 a6ae799b Andreas Kohlbecker
 * @param $cdm_entity
2291
 *    A CDM entity, TaxonNodeDTO or TypedEntityReference
2292 6657531f Andreas Kohlbecker
 */
2293 a6ae799b Andreas Kohlbecker
function html_class_attribute_ref($cdm_entity) {
2294 6657531f Andreas Kohlbecker
2295 4b3be949 Andreas Kohlbecker
  $attributes = '';
2296 a6ae799b Andreas Kohlbecker
  if (is_cdm_entity($cdm_entity)) {
2297
    $attributes =  "cdm:" . $cdm_entity->class . " uuid:" . $cdm_entity->uuid;
2298
  } else if($cdm_entity->class == 'TypedEntityReference') {
2299
    $attributes =  "cdm:" . $cdm_entity->type . " uuid:" . $cdm_entity->uuid;
2300 4b3be949 Andreas Kohlbecker
  }
2301 a6ae799b Andreas Kohlbecker
  if($cdm_entity->class == 'TaxonNodeDto'){
2302
    $attributes .= " taxon_uuid:"  . $cdm_entity->taxonUuid . " sec_uuid:"  . $cdm_entity->secUuid;;
2303 4b3be949 Andreas Kohlbecker
  }
2304 a6ae799b Andreas Kohlbecker
  if($cdm_entity->class == 'Taxon' && isset($cdm_entity->sec->uuid)){
2305
    $attributes .= " sec_uuid:"  . $cdm_entity->sec->uuid;
2306 6657531f Andreas Kohlbecker
  }
2307 4b3be949 Andreas Kohlbecker
  return $attributes;
2308 6657531f Andreas Kohlbecker
}
2309
2310
2311
/**
2312 a0e3ae5c Andreas Kohlbecker
 * Creates a short version of a taxonname.
2313 6657531f Andreas Kohlbecker
 *
2314 e90899ac Andreas Kohlbecker
 * The short name is created by using the taggedTitle field of
2315 a0e3ae5c Andreas Kohlbecker
 * TaxonNodeDTO instances.
2316 e90899ac Andreas Kohlbecker
 * If the taggedTitle if empty the fullname will be returned.
2317 6657531f Andreas Kohlbecker
 *
2318 a0e3ae5c Andreas Kohlbecker
 * @param object $taxonNodeDTO
2319
 *   A TaxonNodeDTO object
2320 6657531f Andreas Kohlbecker
 *
2321
 * @return string
2322
 */
2323 a0e3ae5c Andreas Kohlbecker
function cdm_dataportal_shortname_of($taxonNodeDTO) {
2324
2325 6657531f Andreas Kohlbecker
  $nameStr = '';
2326
2327 a0e3ae5c Andreas Kohlbecker
  normalize_tagged_text($taxonNodeDTO->taggedTitle);
2328 6657531f Andreas Kohlbecker
2329
  // Get all tagged text tokens of the scientific name.
2330 a0e3ae5c Andreas Kohlbecker
  foreach ($taxonNodeDTO->taggedTitle as $tagtxt) {
2331 6657531f Andreas Kohlbecker
    if ($tagtxt->type == 'name' || $tagtxt->type == 'rank') {
2332
      $nameStr .= ($nameStr ? ' ' : '') . $tagtxt->text;
2333
    }
2334
  }
2335
  $nameStr = trim($nameStr);
2336
2337
  if ($nameStr) {
2338
2339
    // Do not return short names for these.
2340 a0e3ae5c Andreas Kohlbecker
    if ($taxonNodeDTO->unplaced || $taxonNodeDTO->excluded) {
2341 6657531f Andreas Kohlbecker
      return $nameStr;
2342
    }
2343
2344
    /*
2345
    1st capture group (^[a-zA-Z]): First letter of uninomial.
2346
    Second capture group ([\p{L}]+): remaining letters of uninomial ([\p{L} = an UTF-8 letter).
2347
    Third capture group (\s+[^(\x2E]+\s+.+$|\s+[a-zA-Z]+$): letters of name,
2348
    but only matching if no '(' or '.' in second word of name,        ( \x2E = '.')
2349
    OR only one specific epithet \s+[\p{L}\x22\x2D\xD7]+$             (\x22= '"', \x2D='-', \xD7='×' )
2350
    */
2351
    $pattern = '/(^[a-zA-Z])([\p{L}]+)(\s+[^(\x2E]+\s+.+$|\s+[\p{L}\x22\x2D\xD7]+$)/u';
2352
    if (preg_match($pattern, $nameStr, $matches, PREG_OFFSET_CAPTURE)) {
2353
      return $matches[1][0] . "." . $matches[3][0];
2354
    }
2355
    else {
2356
      return $nameStr;
2357
    }
2358
  }
2359
  else {
2360 a0e3ae5c Andreas Kohlbecker
    return $taxonNodeDTO->titleCache;
2361 6657531f Andreas Kohlbecker
  }
2362
}
2363
2364
/**
2365
 * Check if a taxon is accepted by the current taxonomic tree.
2366
 *
2367
 * @param mixed $taxon
2368
 *   The Taxon obkect to check.
2369
 *
2370
 * @return bool
2371
 *   Returns TRUE if $taxon is accepted, FALSE otherwise.
2372
 */
2373
function _cdm_dataportal_acceptedByCurrentView($taxon) {
2374
2375 7663cd0b Andreas Kohlbecker
  $defaultTreeUuid = get_current_classification_uuid();
2376 6657531f Andreas Kohlbecker
2377
  if (isset($taxon->taxonNodes)) {
2378
    $taxonNodes = $taxon->taxonNodes;
2379
  }
2380
  else {
2381
    $taxonNodes = cdm_ws_get(CDM_WS_PORTAL_TAXON_TAXONNODES, $taxon->uuid);
2382
  }
2383
2384
  if ($taxon->class == "Taxon" && isset($taxonNodes)) {
2385
    foreach ($taxonNodes as $node) {
2386 586fc780 Andreas Kohlbecker
      if (isset($node->classification)){
2387
        if(is_object($node->classification)) {
2388
          if ($node->classification->uuid == $defaultTreeUuid) {
2389
            return TRUE;
2390
          }
2391 6657531f Andreas Kohlbecker
        }
2392 586fc780 Andreas Kohlbecker
        else {
2393
          if ($node->classification == $defaultTreeUuid) {
2394
            return TRUE;
2395
          }
2396 6657531f Andreas Kohlbecker
        }
2397
      }
2398
    }
2399
  }
2400
2401
  return FALSE;
2402
}
2403
2404
/**
2405 54cfa718 Andreas Kohlbecker
 * Checks is the source has one of the given types.
2406
 *
2407
 * @param object $source
2408
 *   The original source entity
2409
 * @param array $types
2410
 *   An array of elementd of the OriginalSourceType enumeration
2411
 *   If not set the default will be used which is:
2412
 *    - Lineage
2413
 *    - PrimaryMediaSource
2414
 *    - PrimaryTaxonomicSource
2415
 *    - Unknown
2416
 *    - Other
2417
 * @return boolean
2418 6657531f Andreas Kohlbecker
 */
2419 54cfa718 Andreas Kohlbecker
  function _is_original_source_type($source, $types = null) {
2420
    // this is the default
2421
    // maybe this should also be put into the settings
2422
    static $default = array(
2423
      OriginalSourceType::Lineage,
2424
      OriginalSourceType::PrimaryMediaSource,
2425
      OriginalSourceType::PrimaryTaxonomicSource,
2426
      OriginalSourceType::Unknown,
2427
      OriginalSourceType::Other,
2428
    );
2429
2430
    if(!$types){
2431
      $types = $default;
2432
    }
2433
    return isset($source->type) && in_array($source->type, $types);
2434
  }
2435 6657531f Andreas Kohlbecker
2436
/**
2437
 * @todo Please document this function.
2438
 * @see http://drupal.org/node/1354
2439
 */
2440
function _is_invers_taxonRelationship($taxonRelationship, $focusedTaxon) {
2441
  return $taxonRelationship->toTaxon->uuid == $focusedTaxon->uuid;
2442
}
2443
2444
2445
/**
2446
 * Collects all the media from a list of description elements.
2447
 *
2448
 * @param array $descriptionElements
2449
 *   The description elements from which to collect the media.
2450
 *
2451
 * @return array
2452
 *   The output with all the collected media.
2453
 */
2454
function cdm_dataportal_media_from_descriptionElements($descriptionElements) {
2455
2456
  $outArrayOfMedia = array();
2457
2458
  // Avoiding a warning box in Drupal for Flora Malesiana.
2459
  if (isset($descriptionElements) && is_array($descriptionElements)) {
2460
    foreach ($descriptionElements as $descriptionElement) {
2461
      if (isset($descriptionElement->media) && is_array($descriptionElement->media)) {
2462
        foreach ($descriptionElement->media as $media) {
2463
          if (is_object($media)) {
2464
            $outArrayOfMedia[] = $media;
2465
          }
2466
        }
2467
      }
2468
    }
2469
  }
2470
  return $outArrayOfMedia;
2471
}
2472
2473
/**
2474
 * @todo Please document this function.
2475
 * @see http://drupal.org/node/1354
2476
 *
2477 65345976 Andreas Kohlbecker
 * @param array $cdm_entities
2478 6657531f Andreas Kohlbecker
 *   An array of CdmBase instances or a single instance.
2479 28c5c87a Andreas Kohlbecker
 * @param string $footnote_list_key_suggestion
2480 6657531f Andreas Kohlbecker
 *
2481
 * @return unknown
2482
 */
2483 65345976 Andreas Kohlbecker
function cdm_annotations_as_footnotekeys($cdm_entities, $footnote_list_key_suggestion = NULL) {
2484 90597e37 Andreas Kohlbecker
2485
   static $annotations_types_filter = null;
2486 6657531f Andreas Kohlbecker
   if(!$annotations_types_filter) {
2487 90597e37 Andreas Kohlbecker
     $annotations_types_filter = unserialize(ANNOTATIONS_TYPES_AS_FOOTNOTES_DEFAULT);
2488 6657531f Andreas Kohlbecker
   }
2489
2490
  $footNoteKeys = array();
2491
2492
  // Is argument cdmBase an array?
2493 65345976 Andreas Kohlbecker
  if (!is_array($cdm_entities)) {
2494 6657531f Andreas Kohlbecker
    $cdmBase_array = array();
2495 65345976 Andreas Kohlbecker
    $cdmBase_array[] = $cdm_entities;
2496 6657531f Andreas Kohlbecker
  }
2497
  else {
2498 65345976 Andreas Kohlbecker
    $cdmBase_array = $cdm_entities;
2499 6657531f Andreas Kohlbecker
  }
2500
2501
  // Getting the key for the footnotemanager.
2502 28c5c87a Andreas Kohlbecker
  if (isset($footnote_list_key_suggestion)) {
2503
    $footnote_list_key = $footnote_list_key_suggestion;
2504 6657531f Andreas Kohlbecker
  }
2505
  else {
2506 28c5c87a Andreas Kohlbecker
    $footnote_list_key = RenderHints::getFootnoteListKey() . '-annotations';
2507 6657531f Andreas Kohlbecker
  }
2508
2509
  // Adding the footnotes keys.
2510
  foreach ($cdmBase_array as $cdmBase_element) {
2511
    $annotations = cdm_ws_getAnnotationsFor($cdmBase_element, variable_get('annotations_types_as_footnotes', $annotations_types_filter));
2512
    if (is_array($annotations)) {
2513
      foreach ($annotations as $annotation) {
2514 28c5c87a Andreas Kohlbecker
        $footNoteKeys[] = FootnoteManager::addNewFootnote($footnote_list_key, $annotation->text);
2515 6657531f Andreas Kohlbecker
      }
2516
    }
2517
  }
2518
2519
  return $footNoteKeys;
2520
}
2521
2522 d9763fd3 Andreas Kohlbecker
2523 6657531f Andreas Kohlbecker
/**
2524 d9763fd3 Andreas Kohlbecker
 * Creates a CDM Dynabox.
2525
 *
2526 c1f5d897 Andreas Kohlbecker
 * @param string $dynabox_id
2527 d9763fd3 Andreas Kohlbecker
 *   a uninque name for tha dynabox, using a cdm entity uuid as id is good practice.
2528 6657531f Andreas Kohlbecker
 * @param string $label
2529
 *   The clickable text to show.
2530
 * @param string $content_url
2531
 *   The cdm REST service request url wich will deliver the content to be shown
2532
 *   once the dynabox toggles open.
2533
 * @param string $theme
2534 1ce9afb7 Patric Plitzner
 *   The theme to be used for rendering the cdm REST service response with is
2535 6657531f Andreas Kohlbecker
 *   returned from the $content_url.
2536
 * @param string $link_alt_text
2537
 *   The value for the alt attribute of the dynabox link.
2538
 * @param array $enclosingtags
2539
 *   An array with two elements: $enclosingtags[0] will be used for the dynabox
2540
 *   element itself, $enclosingtags[1] is the tag to be used for the
2541 c1f5d897 Andreas Kohlbecker
 *   dynabox_content (optional)
2542 d9763fd3 Andreas Kohlbecker
 * @param array $attributes
2543
 * @param $content_element_selector
2544
 *   Optional jQuery selector which can be used to reference a dom element which should
2545
 *   be used as container for the content to be shown. The dynabox-<dynabox id>-content
2546
 *  element will be placed in this container.
2547
 *
2548 c1f5d897 Andreas Kohlbecker
 * @param string $open_callback
2549 1ce9afb7 Patric Plitzner
 *   optional javascript call back function to be triggered after toggling the box to
2550 c1f5d897 Andreas Kohlbecker
 *   the open state.
2551
 * @param string $close_callback
2552 1ce9afb7 Patric Plitzner
 *   optional javascript call back function to be triggered after toggling the box to
2553 c1f5d897 Andreas Kohlbecker
 *   the closed state.
2554 d9763fd3 Andreas Kohlbecker
 * @return string Returns HTML for a dynabox.
2555
 * Returns HTML for a dynabox.
2556 6657531f Andreas Kohlbecker
 */
2557 d9763fd3 Andreas Kohlbecker
function cdm_dynabox($dynabox_id, $label, $content_url, $theme, $link_alt_text,
2558
                     $enclosingtags = array('li', 'ul'), $attributes = array(),
2559
                     $content_element_selector = null,
2560
                     $open_callback = 'function(){}', $close_callback = 'function(){}' ) {
2561 6657531f Andreas Kohlbecker
  $out = '';
2562 c1f5d897 Andreas Kohlbecker
2563
  // check for plain class attribute string
2564
  $dynabox_id = preg_replace('/[^a-zA-Z0-9\-]/', '', $dynabox_id);
2565
2566 9c9d11f7 Andreas Kohlbecker
  if(!array_key_exists('class', $attributes)) {
2567
    $attributes['class'] = array();
2568
  }
2569 d9763fd3 Andreas Kohlbecker
  $attributes['id'][] = 'dynabox-' . $dynabox_id;
2570 9c9d11f7 Andreas Kohlbecker
  $dynabox_attributes = drupal_attributes($attributes);
2571
2572
2573 b386ae48 Andreas Kohlbecker
  _add_js_domEvent(); // requires domEvent.js
2574 6657531f Andreas Kohlbecker
  drupal_add_js(drupal_get_path('module', 'cdm_dataportal') . '/js/cdm_dynabox.js');
2575 c1f5d897 Andreas Kohlbecker
  drupal_add_js("
2576 94bb8db6 Andreas Kohlbecker
  jQuery(document).ready(
2577
      function() {
2578
        dynabox('". $dynabox_id ."',
2579
          {
2580
            open_callback: " . $open_callback .",
2581 d9763fd3 Andreas Kohlbecker
            close_callback: " . $close_callback .
2582
            ($content_element_selector ? ",\n content_container_selector: '" . $content_element_selector . "'" : "") . "
2583 94bb8db6 Andreas Kohlbecker
          }
2584
        );
2585
      }
2586
   );",
2587
   array(
2588
    'type'=>'inline',
2589
    'scope'=>'footer'
2590
    )
2591
  );
2592 6657531f Andreas Kohlbecker
2593 9c9d11f7 Andreas Kohlbecker
2594 6657531f Andreas Kohlbecker
  $cdm_proxy_url = url('cdm_api/proxy/' . urlencode($content_url) . "/$theme");
2595 9c9d11f7 Andreas Kohlbecker
  $out .= '<!-- dynabox for ' . $content_url . ' -->';
2596 7cc085da Andreas Kohlbecker
  $out .= '<' . $enclosingtags[0] . ' ' .  $dynabox_attributes. '><a href="' . $cdm_proxy_url . '" class="label" alt="' . t('@link-alt-text', array('@link-alt-text' => $link_alt_text)) . '">' . $label . '</a>';
2597 d9763fd3 Andreas Kohlbecker
  $out .= '  <' . $enclosingtags[1] . ' id="dynabox-' . $dynabox_id . '-content">';
2598
  $out .= '    <' . $enclosingtags[0] . ' class="dynabox-content-inner">' . loading_image_html() . '</' . $enclosingtags[0] . '>';
2599
  $out .= '    </' . $enclosingtags[1] . '>';
2600
  $out .= '  </' . $enclosingtags[0] . '>';
2601 9c9d11f7 Andreas Kohlbecker
  $out .= '<!-- dynabox end -->';
2602 6657531f Andreas Kohlbecker
  return $out;
2603
}
2604
2605
/**
2606
 * Checks whether a feature has any description elements.
2607
 *
2608
 * @param mixed $featureNode
2609
 *   A feature node as produced by the function _mergeFeatureTreeDescriptions().
2610
 *
2611
 * @see _mergeFeatureTreeDescriptions()
2612
 *
2613
 * @return bool
2614
 *   Returns TRUE if the given $featureNode or any of its subordinate nodes
2615
 *   contains at least one non empty TextData or at least one DescriptionElement
2616
 *   of an other type. A TextData element holding a multilanguageText or a
2617
 *   source reference is considered to be not empty.
2618 159cd9bb Andreas Kohlbecker
 *
2619
 * @TODO this function may have become obsolete by the new method of detecting empty blocks,
2620 1b756c5f Andreas Kohlbecker
 *       see $block_content_is_not_empty in make_feature_block_list() and
2621 0ebb6efc Andreas Kohlbecker
 *       $feature_block_has_content in compose_feature_block_items_generic
2622 6657531f Andreas Kohlbecker
 */
2623 f19f47fa Andreas Kohlbecker
function has_feature_node_description_elements($featureNode) {
2624 6657531f Andreas Kohlbecker
2625
  if (isset($featureNode->descriptionElements) && is_array($featureNode->descriptionElements) && count($featureNode->descriptionElements) > 0) {
2626 092744e1 Andreas Kohlbecker
    if(!isset($featureNode->descriptionElements['#type'])){ // #type is used to identify e.g. DTO elements: '#type' => 'DTO'
2627
      foreach ($featureNode->descriptionElements as $descriptionElement) {
2628 159cd9bb Andreas Kohlbecker
        if ($descriptionElement->class != "TextData" || isset($descriptionElement->multilanguageText_L10n->text)
2629
          && $descriptionElement->multilanguageText_L10n->text != ''
2630
          || isset($descriptionElement->sources[0])
2631
          || isset($descriptionElement->media[0]) ) {
2632 092744e1 Andreas Kohlbecker
          return TRUE;
2633
        }
2634 6657531f Andreas Kohlbecker
      }
2635
    }
2636
  }
2637 092744e1 Andreas Kohlbecker
  else if (isset($featureNode->childNodes) && is_array($featureNode->childNodes)) {
2638 fae36a2a Andreas Kohlbecker
    foreach ($featureNode->childNodes as $child) {
2639 f19f47fa Andreas Kohlbecker
      if (has_feature_node_description_elements($child)) {
2640 6657531f Andreas Kohlbecker
        return TRUE;
2641
      }
2642
    }
2643
  }
2644
  return FALSE;
2645
}
2646 f26245c8 Andreas Kohlbecker
2647
/**
2648
 * Checks if the current page is a valid taxon portal page and responds with HTTP status 404 (not found) otherwise
2649
 *
2650
 * @param $chapter
2651
 *   The taxon page chapter or part
2652
 */
2653
function cdm_check_valid_taxon_page($chapter){
2654
  static $taxon_tabs = null;
2655
2656
  cdm_check_valid_portal_page();
2657
2658
  if($taxon_tabs == null){
2659
    $taxon_tabs = array('all', 'description');
2660
    foreach(get_taxon_tabs_list() as $tab){
2661
      $taxon_tabs[] = strtolower($tab);
2662
    }
2663
  }
2664
2665
  if(!in_array($chapter, $taxon_tabs)){
2666
    // oops this is not a valid chapter name
2667 b4a5c2be Andreas Kohlbecker
    http_response_code(404); // 404 = Not Found
2668 f26245c8 Andreas Kohlbecker
  }
2669
2670
}
2671
2672
/**
2673 e0d3e148 Andreas Kohlbecker
 * Checks if the current page is a valid portal page and responds with HTTP status 404 (not found) otherwise.
2674
 * The test applied by default it a check for the query parameter 'q' ending with a file suffix like '*.*'
2675 f26245c8 Andreas Kohlbecker
 *
2676 e0d3e148 Andreas Kohlbecker
 * @param $preg_pattern
2677
 *   Optional regular expression pattern to be used in preg_match().
2678 f26245c8 Andreas Kohlbecker
 */
2679 e0d3e148 Andreas Kohlbecker
function cdm_check_valid_portal_page($preg_pattern = null){
2680 595de9f0 Andreas Kohlbecker
  $ends_with_file_suffix_pattern = '/\/[^\.\/]*[\.][^\.\/]*$/';
2681 e0d3e148 Andreas Kohlbecker
  if($preg_pattern === null){
2682
    $preg_pattern = $ends_with_file_suffix_pattern;
2683
  }
2684
  if(preg_match($preg_pattern, $_GET['q'])){
2685 f26245c8 Andreas Kohlbecker
    // oops this urls ends with a file_suffix and thus does not refer to a portal page
2686 b4a5c2be Andreas Kohlbecker
    http_response_code(404); // 404 = Not Found
2687 595de9f0 Andreas Kohlbecker
    exit('HTTP 404');
2688 f26245c8 Andreas Kohlbecker
  }
2689
}
2690 b2b9e057 Andreas Kohlbecker
2691
/**
2692
 * Generates the diff of the texts and presents it in a HTML diff viewer.
2693
 *
2694
 * @param $text_a
2695
 * @param $text_b
2696
 * @return string
2697
 */
2698
function diff_viewer($text_a, $text_b) {
2699
2700
  static $diff_viewer_count = 0;
2701
2702
  $element_id = 'part_definitions_diff_' . $diff_viewer_count++;
2703
2704
  // http://code.stephenmorley.org/php/diff-implementation/
2705
  module_load_include('php', 'cdm_dataportal', 'lib/class.Diff');
2706
  drupal_add_css(drupal_get_path('module',
2707
      'cdm_dataportal') . '/css/diff.css');
2708 087bb473 Andreas Kohlbecker
  _add_jquery_ui();
2709 b2b9e057 Andreas Kohlbecker
  drupal_add_js(
2710
    'jQuery(document).ready( function(){
2711
        jQuery(\'#' . $element_id . '\').accordion({
2712
        collapsible: true,
2713
        active: false,
2714
        fillSpace: true,
2715
        }).children(\'div\').css({ \'height\': \'auto\' });
2716
        jQuery(\'#' . $element_id . ' table.diff\').prepend(\'<thead><tr><th>Default</th><th>User defined<th></th><tr></thead>\');
2717
     });'
2718
    , array(
2719
    'type' => 'inline',
2720
    'scope' => 'footer'
2721
  ));
2722
2723
  $diff = Diff::compare($text_a,
2724
    $text_b);
2725
  $diff_viewer_markup = '<div id="' . $element_id . '"><h3>View Diff</h3><div>'
2726
    . Diff::toTable($diff, '', '')
2727
    . '</div></div>';
2728
  return $diff_viewer_markup;
2729
}
2730