Project

General

Profile

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