Project

General

Profile

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