Project

General

Profile

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