Project

General

Profile

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