Project

General

Profile

Download (19.4 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * Provides external links for sources to taxa information.
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
/**
21
 * Display help and module information.
22
 *
23
 * @param string $path
24
 *   For which path of the site we're displaying help.
25
 * @param array $arg
26
 *   Array that holds the current path as would be returned from arg() function.
27
 *
28
 * @return string
29
 *   Help text for the path.
30
 */
31
function ext_links_help($path, $arg) {
32
  switch ($path) {
33
    case 'admin/help#ext_links':
34
      $output = '<p>' . t("Link to external sources like ## for taxa.") . '</p>';
35
      return $output;
36
    case 'admin/config/cdm_dataportal/ext_links':
37
      $output = '<p>' . t('The external links module allows to configure URL templates for links to external data sources.');
38
      return $output;
39
    case 'admin/config/cdm_dataportal/ext_links/%':
40
      $output = '<p>' . t('An external link template.');
41
      return $output;
42
  }
43
}
44

    
45
/**
46
 * Implements hook_menu().
47
 */
48
function ext_links_menu() {
49
  $items = [];
50

    
51
  $items['admin/config/cdm_dataportal/ext_links'] = [
52
    'title' => 'External links',
53
    'description' => 'Configure external links templates.',
54
    'page callback' => 'drupal_get_form',
55
    'page arguments' => ['ext_links_admin_overview'],
56
    'access arguments' => ['access administration pages'],
57
    'file' => 'ext_links.admin.inc'
58
  ];
59
  $items['admin/config/cdm_dataportal/ext_links/list'] = [
60
    'title' => 'List',
61
    'type' => MENU_DEFAULT_LOCAL_TASK,
62
  ];
63
  $items['admin/config/cdm_dataportal/ext_links/add'] = [
64
    'title' => 'Add external link',
65
    'page callback' => 'ext_links_admin_link_template_page',
66
    'access arguments' => ['access administration pages'],
67
    'type' => MENU_LOCAL_ACTION,
68
    'weight' => 1,
69
    'file' => 'ext_links.admin.inc',
70
  ];
71
  $items['admin/config/cdm_dataportal/ext_links/appearance'] = [
72
    'title' => 'Appearance',
73
    'page callback' => 'drupal_get_form',
74
    'page arguments' => ['ext_links_admin_appearance_page'],
75
    'access arguments' => ['access administration pages'],
76
    'type' => MENU_LOCAL_TASK,
77
    'weight' => 2,
78
    'file' => 'ext_links.admin.inc',
79
  ];
80
  $items['admin/config/cdm_dataportal/ext_links/%ext_links'] = [ // %ext_links refers to ext_links_load
81
    'title' => 'Edit external link',
82
    'page callback' => 'ext_links_admin_link_template_page',
83
    'page arguments' => [4],
84
    'access arguments' => ['access administration pages'],
85
    'file' => 'ext_links.admin.inc',
86
  ];
87
  $items['admin/config/cdm_dataportal/ext_links/%ext_links/status/%'] = [
88
    'title' => 'Enable or disable external link',
89
    'page callback' => 'ext_links_admin_link_template_set_status',
90
    'page arguments' => [4, 6],
91
    'access arguments' => ['access administration pages'],
92
 //   'type' => MENU_CALLBACK,
93
    'file' => 'ext_links.admin.inc',
94
  ];
95
  return $items;
96
}
97

    
98
/**
99
 * Retrieves a list of External Link templates, ordered by weight.
100
 *
101
 * Empty 'ext_links' tables will be initialized with the default templates.
102
 *
103
 * @see ext_links_template_defaults()
104
 *
105
 * @param $enabled_only boolean
106
 *   When TRUE external link templates with status != null are excluded from the list.
107
 * @return array
108
 *   An array of external link template objects, keyed by the format ID and ordered by
109
 *   weight.
110
 *
111
 */
112
function ext_links_templates($enabled_only = FALSE) {
113
  global $language;
114
  $link_templates = &drupal_static(__FUNCTION__, array());
115

    
116
  // cache_clear_all("ext_links_templates:{$language->language}");
117
  // All available link_templates are cached for performance.
118
  if (!is_array($link_templates) || !count($link_templates)) {
119
    if ($cache = cache_get("ext_links:{$language->language}")) {
120
      $link_templates = $cache->data;
121
    }
122
    else {
123
      $test = false;
124
      if($test){
125
        $link_templates = [];
126
        $link_templates_arrays = ext_links_template_defaults();
127
        foreach($link_templates_arrays as $a){
128
          $link_templates[] = (object)$a;
129
        }
130
      } else {
131
        $query = db_select('ext_links', 'elt')
132
          ->addTag('translatable')
133
          ->fields('elt');
134
        if($enabled_only){
135
          $query = $query->condition('status', '1');
136
        }
137
        $link_templates =
138
          $query->orderBy('weight')
139
          ->execute()
140
          ->fetchAllAssoc('id');
141
      }
142
      if(!count($link_templates)) {
143
        $link_templates_arrays = ext_links_template_defaults();
144
        $query = db_insert('ext_links')
145
          ->fields(array_keys(array_values($link_templates_arrays)[0]));
146
        foreach($link_templates_arrays as $a){
147
          $query->values($a);
148
        }
149
        try {
150
          $query->execute();
151
        } catch (Exception $e) {
152
          drupal_set_message("Error while initializing ext_links database: " . $e->getMessage(), "error");
153
        }
154
        $link_templates = [];
155
        foreach($link_templates_arrays as $a){
156
          $link_templates[] = (object)$a;
157
        }
158
      }
159
      // cache_set("ext_links:{$language->language}", $link_templates);
160
    }
161
  }
162
  return $link_templates;
163
}
164

    
165
/**
166
 * Resets the text format caches.
167
 *
168
 * @see filter_formats()
169
 */
170
function ext_links_templates_reset() {
171
  cache_clear_all('ext_links', 'cache', TRUE);
172
  drupal_static_reset('ext_links');
173
}
174

    
175
/**
176
 * Loads a text format object from the database.
177
 *
178
 * @param $extlink_id
179
 *   The external link ID. ($link->id)
180
 *
181
 * @return
182
 *   A fully-populated text format object, if the requested format exists and
183
 *   is enabled. If the format does not exist, or exists in the database but
184
 *   has been marked as disabled, FALSE is returned.
185
 *
186
 * @see ext_links_exists()
187
 */
188
function ext_links_load($extlink_id) {
189
  $test = false;
190
  if($test) {
191
    $defaults = ext_links_template_defaults();
192
    return isset($defaults[$extlink_id]) ? (object)$defaults[$extlink_id] : FALSE;
193
  }
194
  else {
195
   $link_templates = ext_links_templates();
196
    return isset($link_templates[$extlink_id]) ? $link_templates[$extlink_id] : FALSE;
197
  }
198
}
199

    
200
/**
201
 * Saves a text format object to the database.
202
 *
203
 * @param $link_template
204
 *   A link template object having the properties:
205
 *   - id: The machine name of the external link. If this corresponds
206
 *     to an existing external link, this one will be updated;
207
 *     otherwise, a new external link will be created.
208
 *   - title: The link title
209
 *   - link: The link url template.
210
 *   - status: (optional) An integer indicating whether the ext link is
211
 *     enabled (1) or not (0). Defaults to 1.
212
 *   - weight: (optional) The weight of the external link, which controls its
213
 *     placement in external link block. If omitted, the weight is set to 0.
214
 *     Defaults to NULL.
215
 *
216
 * @return
217
 *   SAVED_NEW or SAVED_UPDATED.
218
 */
219
function ext_links_save($link_template) {
220

    
221
  $link_template->title = trim($link_template->title);
222
  $link_template->cache = true;
223
  if (!isset($link_template->status)) {
224
    $link_template->status = 1;
225
  }
226
  if (!isset($link_template->weight)) {
227
    $link_template->weight = 0;
228
  }
229

    
230
  // Insert or update the text format.
231
  $return = db_merge('ext_links')
232
    ->key(array('id' => $link_template->id))
233
    ->fields(array(
234
      'id' => $link_template->id,
235
      'title' => $link_template->title,
236
      'link' => $link_template->link,
237
      'status' => (int) $link_template->status,
238
      'weight' => (int) $link_template->weight,
239
    ))
240
    ->execute();
241

    
242
  ext_links_templates_reset();
243
  return $return;
244
}
245

    
246
/**
247
 * Determines if a external link exists.
248
 *
249
 * @param $ext_link_name
250
 *   The ID of the external link to check.
251
 *
252
 * @return
253
 *   TRUE if the external link exists, FALSE otherwise.
254
 *
255
 * @see ext_links_load()
256
 */
257
function ext_links_exists($ext_link_name) {
258
  return (bool) db_query_range('SELECT 1 FROM {ext_links} WHERE name = :name', 0, 1, array(':name' => $ext_link_name))->fetchField();
259
}
260

    
261

    
262
/**
263
 * Returns the genus and the first epithet from the object taxon.
264
 *
265
 * @param $taxon
266
 *   A CDM Taxon instance object
267
 * @return array
268
 *  An associate array with two elements:
269
 *     - genus: the uninomial
270
 *     - species: the species epithet
271
 */
272
function ext_link_species_name($taxon) {
273
  $speciesName = array();
274
  $i = 0;
275
  while (isset($taxon->name->taggedName[$i]) && !isset($speciesName['species'])) {
276
    if ($taxon->name->taggedName[$i]->type == "name") {
277
      if (!isset($speciesName['genus'])) {
278
        $speciesName['genus'] = $taxon->name->taggedName[$i]->text;
279
      }
280
      else {
281
        $speciesName['species'] = $taxon->name->taggedName[$i]->text;
282
      }
283
    }
284
    $i++;
285
  }
286
  return $speciesName;
287
}
288

    
289
/**
290
 * Implements hook_block_info().
291
 */
292
function ext_links_block_info() {
293
  if (TRUE) {
294
    $block[0]["info"] = t("CDM - External Links");
295
    $block[0]["visibility"] = BLOCK_VISIBILITY_LISTED;
296
    $block[0]["pages"] = "cdm_dataportal/taxon/*\ncdm_dataportal/name/*";
297
    return $block;
298
  }
299
}
300

    
301
/**
302
 * Implements hook_block_view().
303
 */
304
function ext_links_block_view($delta) {
305
  switch ($delta) {
306
    case '0':
307
      $block['subject'] = t('Search name in') . ' ...';
308
      drupal_add_js(drupal_get_path('module', 'ext_links') . '/ext_links.js');
309
      if (variable_get('ext_links_appearance_grouped', 1)) {
310
        $block['content'] = render_ext_links_list_grouped();
311
      } else {
312
        $block['content'] = render_ext_links_list_plain();
313
      }
314
    }
315
      return $block;
316
}
317

    
318
/**
319
 * Applies the name tokens to the external link templates.
320
 *
321
 * @param $ext_link_template
322
 *
323
 * @return array
324
 *  Array with the keys:
325
 *     - title: the title of the link
326
 *     - url: the url of the link
327
 */
328
function ext_links_apply_template($ext_link_template) {
329
      $ext_link_array = [
330
        'title' => $ext_link_template->title,
331
        'url' => token_replace($ext_link_template->link, [],
332
          [
333
            'callback' => 'ext_links_token_replacement_urlencode',
334
            'clear' => true
335
          ])
336
      ];
337
  return $ext_link_array;
338
}
339

    
340
/**
341
 * Callback function to be passed to token_replace() to urlencode the token replacements.
342
 *
343
 * @param array $replacements
344
 *   The replacements for the tokens
345
 * @param array $data
346
 *    Unused, see token_replace()
347
 * @param array $options
348
 *    Unused, see token_replace()
349
 *
350
 * @see token_replace()
351
 */
352
function ext_links_token_replacement_urlencode(array &$replacements, array $data = [], array $options = []){
353
  foreach ($replacements as &$repl){
354
    $repl = rawurlencode($repl);
355
  }
356

    
357
}
358

    
359
/**
360
 * Creates html markup of ext_links grouped by category
361
 */
362
function render_ext_links_list_grouped() {
363

    
364
  $ext_links = ext_links_templates(true);
365

    
366
  $ext_links_by_category = [];
367

    
368
  foreach ($ext_links as $ext_link) {
369
    if(!array_key_exists($ext_link->category, $ext_links_by_category)){
370
      $ext_links_by_category[$ext_link->category] = [];
371
    }
372
    $ext_link_render_array = ext_links_apply_template($ext_link);
373
    $ext_links_by_category[$ext_link->category][] = $ext_link_render_array;
374
  }
375

    
376
  $block_content = '';
377
  foreach ($ext_links_by_category as $category => $ext_links) {
378
    $block_content .= "<label class=\"category-label\">" . $category . "</label><div class=\"category category-$category\">";
379
    foreach($ext_links as $ext_link){
380
      $block_content .= l($ext_link['title'], 'JavaScript:popupExternalLinks(\'' . $ext_link['url'] . '\')', ['external' => TRUE]) .'<br />';
381
    }
382
    $block_content .= "</div>";
383
  }
384

    
385
  return $block_content;
386
}
387

    
388
/**
389
 * Creates html markup of ext_links as plain list
390
 */
391
function render_ext_links_list_plain() {
392

    
393
  $ext_links_templates = ext_links_templates(true);
394
  $block_content = '';
395
  foreach ($ext_links_templates as $ext_link) {
396
    $ext_link = ext_links_apply_template($ext_link);
397
    $block_content .= l($ext_link['title'], 'JavaScript:popupExternalLinks(\'' . $ext_link['url'] . '\')', ['external' => TRUE]) .'<br />';
398
  }
399
  return $block_content;
400
}
401

    
402
/**
403
 * Implements hook_theme()
404
 */
405
function ext_links_theme() {
406
  return array(
407
    // theme_ext_links_admin_overview
408
    'ext_links_admin_overview' => array(
409
      'render element' => 'form',
410
      'file' => 'ext_links.admin.inc',
411
    )
412
  );
413
}
414

    
415
/**
416
 * Get the default external links.
417
 *
418
 * @return array
419
 *   Returns an array with default external links values.
420
 */
421
function ext_links_template_defaults() {
422
  $ext_links_default["gbif"] = array(
423
    'id' => "gbif",
424
    'link' => 'http://www.gbif.org/species/search?q=[cdm:taxon_name]',
425
    'title' => 'GBIF',
426
    'weight' => 0,
427
    'status' => 1,
428
    'category' => 'Specimens/Occurrences',
429
  );
430
  $ext_links_default["biocase"] = array(
431
    'id' => "biocase",
432
    'link' => 'http://search.biocase.org/edit/search/units/simpleSearch/query1?unitName=[cdm:taxon_name]',
433
    'title' => 'BioCASE',
434
    'weight' => 0,
435
    'status' => 1,
436
    'category' => 'Specimens/Occurrences',
437
  );
438
  $ext_links_default["nybg"] = array(
439
    'id' => "nybg",
440
    'link' => 'http://sweetgum.nybg.org/science/vh/specimen_list.php?SummaryData=[cdm:taxon_name]',
441
    'title' => 'NYBG',
442
    'weight' => 0,
443
    'status' => 1,
444
    'category' => 'Specimens/Occurrences',
445
  );
446
  $ext_links_default["tropicos"] = array(
447
    'id' => "tropicos",
448
    'link' => 'http://www.tropicos.org/NameSearch.aspx?name=[cdm:taxon_name]',
449
    'title' => 'Tropicos',
450
    'weight' => 0,
451
    'status' => 1,
452
    'category' => 'Specimens/Occurrences',
453
  );
454
  $ext_links_default["ncbi"] = array(
455
    'id' => "ncbi",
456
    'link' => 'http://www.ncbi.nlm.nih.gov/gquery/gquery.fcgi?term=%22[cdm:taxon_name]%22',
457
    'title' => 'NCBI',
458
    'weight' => 0,
459
    'status' => 1,
460
    'category' => 'Molecular Resources',
461
  );
462
  $ext_links_default["google"] = array(
463
    'id' => "google",
464
    'link' => 'http://images.google.com/images?q=%22[cdm:taxon_name]%22',
465
    'title' => 'Google Images',
466
    'weight' => 0,
467
    'status' => 1,
468
    'category' => 'Images',
469
  );
470
  $ext_links_default["europeana"] = array(
471
    'id' => "europeana",
472
    'link' => 'https://www.europeana.eu/en/search?query=[cdm:taxon_name]',
473
    'title' => 'Europeana',
474
    'weight' => 0,
475
    'status' => 1,
476
    'category' => 'Images',
477
  );
478
  $ext_links_default["morphbank"] = array(
479
    'id' => "morphbank",
480
    'link' => 'https://www.morphbank.net/Browse/ByImage/index.php?keywords=&tsnKeywords=[cdm:taxon_name]',
481
    'title' => 'Morphbank',
482
    'weight' => 0,
483
    'status' => 1,
484
    'category' => 'Images',
485
  );
486
  $ext_links_default["flickr"] = array(
487
    'id' => "flickr",
488
    'link' => 'http://www.flickr.com/search/?w=all&q=%22[cdm:taxon_name]%22',
489
    'title' => 'flickr',
490
    'weight' => 0,
491
    'status' => 1,
492
    'category' => 'Images',
493
  );
494
  $ext_links_default["scholar"] = array(
495
    'id' => "scholar",
496
    'link' => 'http://scholar.google.de/scholar?q=%22[cdm:taxon_name]%22',
497
    'title' => 'Google scholar',
498
    'weight' => 0,
499
    'status' => 1,
500
    'category' => 'Literature',
501
  );
502
  $ext_links_default["bhl"] = array(
503
    'id' => "bhl",
504
    // BHL does not normalize rank terms, ssp., sub., subsp. are not unified, therefore we skip that part:
505
    'link' => 'https://www.biodiversitylibrary.org/search?searchTerm=[cdm:taxon_name:genus_or_uninomial]+[cdm:taxon_name:epithet]+[cdm:taxon_name:infraspecific_epithet]&stype=F#/names',
506
    'title' => 'BHL',
507
    'weight' => 0,
508
    'status' => 1,
509
    'category' => 'Literature',
510
  );
511
  $ext_links_default["arkive"] = array(
512
    // domain no longer exists! Remove extlink?
513
    'id' => "arkive",
514
    'link' => 'http://www.arkive.org/search.html?q=[cdm:taxon_name]&output=xml_no_dtd&client=arkive-images&site=arkive-images&ie=utf8&oe=utf8&num=20&proxystylesheet=tng-search&filter=0&getfields=*',
515
    'title' => 'ARKive',
516
    'weight' => 0,
517
    'status' => 0,
518
    'category' => 'Images',
519
  );
520
  $ext_links_default["herbcat"] = array(
521
    'id' => "herbcat",
522
    'link' => 'http://apps.kew.org/herbcat/getSearchPageResults.do?typeSpecimen=false&imageSpecimen=false&currentName=false&typeOfCollection=all_collection&&genus=[cdm:taxon_name:genus_or_uninomial]&&species=[cdm:taxon_name:epithet]&infraspecificName=[cdm:taxon_name:infraspecific_epithet]',
523
    'title' => 'Kew Herbarium Catalogue',
524
    'weight' => 0,
525
    'status' => 1,
526
    'category' => 'Specimens/Occurrences',
527
  );
528
  $ext_links_default["wfo-specimens"] = array(
529
    'id' => "wfo-specimens",
530
    'link' => 'http://wfospecimens.cybertaxonomy.org/search/result?fullScientificName=[cdm:taxon_name]',
531
    'title' => 'World Flora Online - Specimens',
532
    'weight' => 0,
533
    'status' => 1,
534
    'category' => 'Specimens/Occurrences',
535
  );
536
  $ext_links_default["wfo"] = array(
537
    'id' => "wfo",
538
    'link' => 'http://www.worldfloraonline.org/search?query=[cdm:taxon_name]',
539
    'title' => 'World Flora Online',
540
    'weight' => 0,
541
    'status' => 1,
542
    'category' => 'Classification/Nomenclature',
543
  );
544
  $ext_links_default["iucn"] = array(
545
    'id' => "iucn",
546
    'link' => 'https://www.iucnredlist.org/search?query=[cdm:taxon_name]',
547
    'title' => 'IUCN Red List',
548
    'weight' => 0,
549
    'status' => 1,
550
    'category' => 'Conservation',
551
  );
552
  $ext_links_default["ipni"] = array(
553
    'id' => "ipni",
554
    'link' => 'https://www.ipni.org/?q=[cdm:taxon_name]',
555
    'title' => 'IPNI',
556
    'weight' => 0,
557
    'status' => 1,
558
    'category' => 'Classification/Nomenclature',
559
  );
560
  $ext_links_default["wcsp"] = array(
561
    'id' => "wcsp",
562
    'link' => 'http://wcsp.science.kew.org/qsearch.do?plantName=[cdm:taxon_name]',
563
    'title' => 'World Checklist Monocots',
564
    'weight' => 0,
565
    'status' => 1,
566
    'category' => 'Classification/Nomenclature',
567
  );
568
  $ext_links_default["col"] = array(
569
    'id' => "col",
570
    'link' => 'https://www.catalogueoflife.org/data/search?facet=rank&facet=issue&facet=status&facet=nomStatus&facet=nameType&facet=field&limit=50&offset=0&q=[cdm:taxon_name]&sortBy=taxonomic&type=EXACT',
571
    'title' => 'Catalogue of Life',
572
    'weight' => 0,
573
    'status' => 1,
574
    'category' => 'Classification/Nomenclature',
575
  );
576
  //
577
  $ext_links_default["tpl"] = array(
578
    'id' => "tpl",
579
    'link' => 'http://www.theplantlist.org/tpl/search?q=[cdm:taxon_name]',
580
    'title' => 'The Plant List',
581
    'weight' => 0,
582
    'status' => 1,
583
    'category' => 'Classification/Nomenclature',
584
  );
585
  $ext_links_default["eol"] = array(
586
    'id' => "eol",
587
    'link' => 'http://eol.org/search/?q=[cdm:taxon_name]',
588
    'title' => 'Encyclopaedia of Life',
589
    'weight' => 0,
590
    'status' => 1,
591
    'category' => 'General',
592
  );
593
  $ext_links_default["jstor"] = array(
594
    'id' => "jstor",
595
    'link' => 'https://plants.jstor.org/search?filter=name&so=ps_group_by_genus_species+asc&Query=[cdm:taxon_name]',
596
    'title' => 'JSTOR Plant Science',
597
    'weight' => 0,
598
    'status' => 1,
599
    'category' => 'General',
600
  );
601
  $ext_links_default["epic"] = array(
602
    'id' => "epic",
603
    'link' => 'http://epic.kew.org/searchepic/summaryquery.do?scientificName=[cdm:taxon_name]&searchAll=true&categories=names&categories=bibl&categories=colln&categories=taxon&categories=flora',
604
    'title' => 'ePIC',
605
    'weight' => 0,
606
    'status' => 1,
607
    'category' => 'General',
608
  );
609
  $ext_links_default["fairchild"] = array(
610
    //disabled since Fairchild Guide To Palms seems to be down
611
    'id' => "fairchild",
612
    'link' => 'http://palmguide.org/palmsearch.php?query=',
613
    'title' => 'Fairchild Guide To Palms',
614
    'weight' => 0,
615
    'status' => 0,
616
    'category' => 'Specimens/Occurrences',
617
  );
618
  $ext_links_default["ggbn"] = array(
619
    'id' => "ggbn",
620
    'link' => 'http://www.ggbn.org/ggbn_portal/search/result?fullScientificName=[cdm:taxon_name]',
621
    'title' => 'GGBN',
622
    'weight' => 0,
623
    'status' => 1,
624
    'category' => 'Molecular Resources',
625
  );
626
  return $ext_links_default;
627
}
(7-7/7)