Project

General

Profile

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