1
|
<?php
|
2
|
// $Id$
|
3
|
|
4
|
/*
|
5
|
* @file
|
6
|
* cdm_taxontree.module
|
7
|
*
|
8
|
* Copyright (C) 2007 EDIT
|
9
|
* European Distributed Institute of Taxonomy
|
10
|
* http://www.e-taxonomy.eu
|
11
|
*
|
12
|
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
13
|
* See LICENSE.TXT at the top of this package for the full license terms.
|
14
|
*/
|
15
|
|
16
|
|
17
|
/**
|
18
|
* Implementation of hook_menu()
|
19
|
*/
|
20
|
function cdm_taxontree_menu($may_cache) {
|
21
|
|
22
|
$items = array();
|
23
|
if ($may_cache) {
|
24
|
|
25
|
$items[] = array(
|
26
|
'path' => 'cdm_taxontree/set',
|
27
|
'callback' => 'cdm_taxontree_set',
|
28
|
'access' => true,
|
29
|
'type' => MENU_CALLBACK,
|
30
|
);
|
31
|
|
32
|
}
|
33
|
return $items;
|
34
|
}
|
35
|
|
36
|
|
37
|
/**
|
38
|
* Implementation of hook_block()
|
39
|
*
|
40
|
* @param String $op
|
41
|
* @param int $delta
|
42
|
*/
|
43
|
function cdm_taxontree_block($op='list', $delta=0) {
|
44
|
if ($op == "list") {
|
45
|
$block[0]["info"] = t('CDM Taxon Tree');
|
46
|
return $block;
|
47
|
}
|
48
|
else if ($op == 'view') {
|
49
|
switch($delta){
|
50
|
case 0:
|
51
|
$block['subject'] = t('CDM Taxon Tree');
|
52
|
$taxonUuid_inFocus = _cdm_get_taxonuuid();
|
53
|
$tree = cdm_taxontree_build_tree($taxonUuid_inFocus);
|
54
|
$block['content'] = theme('cdm_taxontree_block', $tree);
|
55
|
drupal_add_css(drupal_get_path('module', 'cdm_taxontree').'/cdm_taxontree.css');
|
56
|
drupal_add_js(drupal_get_path('module', 'cdm_taxontree').'/js/cdm_taxontree.js');
|
57
|
if($taxonUuid_inFocus){
|
58
|
drupal_add_js(drupal_get_path('module', 'cdm_taxontree').'/js/jquery.scrollTo.js');
|
59
|
drupal_add_js(drupal_get_path('module', 'cdm_taxontree').'/js/jquery.dimensions.js');
|
60
|
drupal_add_js('
|
61
|
if (Drupal.jsEnabled) {
|
62
|
$(document).ready(function()
|
63
|
{
|
64
|
//var activeElement = $(\'div.cdm_taxontree_scroller_x .active\');
|
65
|
$(\'div.cdm_taxontree_scroller_x\').scrollTo($(\'.active\'));});
|
66
|
}', 'inline');
|
67
|
}
|
68
|
return $block;
|
69
|
}
|
70
|
}
|
71
|
}
|
72
|
|
73
|
function cdm_taxontree_set($key, $value){
|
74
|
|
75
|
if(is_string($key)){
|
76
|
$_SESSION['cdm']['taxontree'][$key] = $value;
|
77
|
}
|
78
|
|
79
|
if($_REQUEST['destination']){
|
80
|
$destination = $_REQUEST['destination'];
|
81
|
unset($_REQUEST['destination']);
|
82
|
drupal_goto($destination);
|
83
|
}
|
84
|
}
|
85
|
|
86
|
function _get_compact_mode(){
|
87
|
|
88
|
if(!isset($_SESSION['cdm']['taxontree']['compact_mode'])){
|
89
|
$_SESSION['cdm']['taxontree']['compact_mode'] = 'expanded';
|
90
|
}
|
91
|
return $_SESSION['cdm']['taxontree']['compact_mode'];
|
92
|
}
|
93
|
|
94
|
/**
|
95
|
* builds a tree of TaxonNode instances, whereas the instances are extended by some fields:
|
96
|
*
|
97
|
* - $node->filter: values ( 'on', 'excluded', 'included' )
|
98
|
* - $node->expanded: values ( 'expanded', 'collapsed' )
|
99
|
* $node->focused: values ( TRUE, FALSE )
|
100
|
*
|
101
|
* @param unknown_type $taxonUuid
|
102
|
* @return unknown
|
103
|
*/
|
104
|
function cdm_taxontree_build_tree($taxonUuid = null){
|
105
|
|
106
|
// find the secRefUuid
|
107
|
$secRefUuid = null;
|
108
|
if($taxonUuid){
|
109
|
//TODO poor performance here:
|
110
|
$taxon = cdm_ws_get(CDM_WS_TAXON, $taxonUuid);
|
111
|
$secRefUuid = $taxon->sec->uuid;
|
112
|
}
|
113
|
|
114
|
if(!$secRefUuid){
|
115
|
$secRef = _cdm_dataportal_currentSecRef_array();
|
116
|
$secRefUuid = $secRef['uuid'];
|
117
|
// compact_modes: 'expanded', 'compact', 'flattened'
|
118
|
}
|
119
|
$compact_tree = cdm_dataportal_filters_active() && _get_compact_mode() != 'expanded';
|
120
|
|
121
|
// get the root level
|
122
|
$root_tree = cdm_ws_get(CDM_WS_TREENODE_ROOT, $secRefUuid);
|
123
|
$root_tree = _cdm_resultset2nodelist($root_tree, cdm_dataportal_filters_active());
|
124
|
|
125
|
if(cdm_dataportal_filters_active()){
|
126
|
// the paths up to active filters are inactive in the user interface and
|
127
|
// thus cannot be browsed by expanding nodes
|
128
|
// therefore we need to build up the branches for all nodes which are set as filters
|
129
|
// the branches are merged with the root
|
130
|
foreach(cdm_dataportal_filters_get() as $uuid=>$filter){
|
131
|
$branch = cdm_taxontree_build_path($uuid, TRUE, $compact_tree === false);
|
132
|
$root_tree = _cdm_taxontree_merge($root_tree, $branch);
|
133
|
}
|
134
|
}
|
135
|
|
136
|
// build the the branch for the focused node and merge it with the root
|
137
|
if($taxonUuid){
|
138
|
$branch = cdm_taxontree_build_path($taxonUuid, NULL, (cdm_dataportal_filters_active() ? NULL : TRUE), TRUE);
|
139
|
$root_tree = _cdm_taxontree_merge($root_tree, $branch);
|
140
|
}
|
141
|
|
142
|
//reorder siblings & populate expanded nodes with children and propagate the filter attribute
|
143
|
$root_tree = cdm_taxontree_populate($root_tree, $compact_tree === false);
|
144
|
|
145
|
// flatten tree
|
146
|
if($compact_tree && _get_compact_mode() == 'flattened'){
|
147
|
$root_tree = cdm_taxontree_flatten($root_tree);
|
148
|
}
|
149
|
|
150
|
return $root_tree;
|
151
|
}
|
152
|
|
153
|
/**
|
154
|
* Builds the specific branch path for $taxonUuid.
|
155
|
* The branch path reaches from the parent root node of $taxonUuid up to $taxonUuid.
|
156
|
*
|
157
|
* @param unknown_type $taxonUuid
|
158
|
* @param $is_filter_path whether the upmost node of this path is mapped by an active filter
|
159
|
* @param $is_expanded whether all nodes along the tree are expanded
|
160
|
* @return a subtree
|
161
|
*/
|
162
|
function cdm_taxontree_build_path($taxonUuid, $is_filter_path = null, $is_expanded = null, $is_focused = FALSE){
|
163
|
|
164
|
$branch_path = array();
|
165
|
$parents = cdm_ws_get(CDM_WS_TREENODE_PARENTS, $taxonUuid);
|
166
|
if(!$parents){
|
167
|
return false;
|
168
|
}
|
169
|
//TODO reorder parents in JSON stubs and remove the if condition below
|
170
|
if(variable_get('cdm_webservice_isStub', 0)){
|
171
|
$parents = array_reverse($parents);
|
172
|
}
|
173
|
|
174
|
$parents = _cdm_resultset2nodelist($parents, NULL);
|
175
|
$lastParent = null;
|
176
|
foreach($parents as $pnode){
|
177
|
$pnode->focused = false;
|
178
|
if($lastParent){
|
179
|
$pnode->children = array($lastParent->uuid => $lastParent);
|
180
|
if(!is_null($is_filter_path)){
|
181
|
$pnode->filter = ($is_filter_path ? 'excludes' : 'included');
|
182
|
}
|
183
|
if(!is_null($is_expanded)){
|
184
|
$pnode->expanded = ($is_expanded ? 'expanded' : 'collapsed');
|
185
|
}
|
186
|
} else {
|
187
|
// the uppermost node of branch
|
188
|
if(!is_null($is_filter_path)){
|
189
|
$pnode->filter = ($is_filter_path ? 'on' : 'includes');
|
190
|
}
|
191
|
// uppermost node is always expanded if it has children
|
192
|
$pnode->focused = $is_focused;
|
193
|
$pnode->expanded = ($pnode->hasChildren ? 'expanded' : 'collapsed');
|
194
|
}
|
195
|
$lastParent = $pnode;
|
196
|
}
|
197
|
$branch_path[$pnode->uuid] = $pnode;
|
198
|
return $branch_path;
|
199
|
}
|
200
|
|
201
|
/**
|
202
|
* Performs two steps on each level of the tree:
|
203
|
* 1. reorder siblings except root (is expected to be ordered jet) alphabetically
|
204
|
* 2. populate children of expanded nodes & propagate the filter attribute
|
205
|
*
|
206
|
* @param unknown_type $tree
|
207
|
* @return unknown
|
208
|
*/
|
209
|
function cdm_taxontree_populate($tree, $expand_excluded, $filter_default = null){
|
210
|
|
211
|
if(!is_array($tree)){
|
212
|
return false;
|
213
|
}
|
214
|
foreach(array_keys($tree) as $uuid){
|
215
|
|
216
|
if(!isset($tree[$uuid]->filter) && !is_null($filter_default)){
|
217
|
$tree[$uuid]->filter = $filter_default;
|
218
|
}
|
219
|
|
220
|
if( $tree[$uuid]->expanded == 'expanded' && ($expand_excluded || $tree[$uuid]->filter != 'excluded')){
|
221
|
$children = cdm_ws_get(CDM_WS_TREENODE_CHILDREN, $uuid);
|
222
|
$children = _cdm_resultset2nodelist($children, ($tree[$uuid]->filter == 'excludes'));
|
223
|
|
224
|
// store the children of the node for later processing
|
225
|
if(is_array($tree[$uuid]->children)){
|
226
|
$pnode_children = $tree[$uuid]->children;
|
227
|
} else {
|
228
|
$pnode_children = false;
|
229
|
}
|
230
|
// replace the children by the newly retrieved child nodes
|
231
|
$tree[$uuid]->children = $children;
|
232
|
|
233
|
if($pnode_children){
|
234
|
// recurse into the childtree which was stored before
|
235
|
$pnode_children = cdm_taxontree_populate($pnode_children, $expand_excluded ,$tree[$uuid]->filter);
|
236
|
// recombine
|
237
|
foreach($pnode_children as $childUuid=>$cnode){
|
238
|
$tree[$uuid]->children[$childUuid] = $cnode;
|
239
|
}
|
240
|
}
|
241
|
} else {
|
242
|
// reorder nodes which are not expanded, expanded nodes are reordered implicitly above
|
243
|
if(isset($tree[$uuid]->children) && count($tree[$uuid]->children) > 1) {
|
244
|
// copy the children into an array which can be sorted by its keys
|
245
|
$ordered = array();
|
246
|
foreach($tree[$uuid]->children as $cnode){
|
247
|
// concatenate full name and uid
|
248
|
$reordered[str_pad($cnode->fullname, 255, '-').$cnode->uuid] = $cnode;
|
249
|
}
|
250
|
// sort
|
251
|
ksort($reordered);
|
252
|
// move the children back into the parent node
|
253
|
$tree[$uuid]->children = array();
|
254
|
foreach($reordered as $cnode){
|
255
|
$tree[$uuid]->children[$cnode->uuid] = $cnode;
|
256
|
}
|
257
|
}
|
258
|
$tree[$uuid]->children = cdm_taxontree_populate($tree[$uuid]->children, $expand_excluded, $tree[$uuid]->filter);
|
259
|
}
|
260
|
}
|
261
|
return $tree;
|
262
|
}
|
263
|
|
264
|
function cdm_taxontree_flatten($tree, &$new_root = null){
|
265
|
if(!$new_root){
|
266
|
$new_root = array();
|
267
|
}
|
268
|
foreach($tree as $node){
|
269
|
if($node->filter == 'on'){
|
270
|
$new_root[$node->uuid] = $node;
|
271
|
} else if(is_array($node->children)){
|
272
|
cdm_taxontree_flatten($node->children, $new_root);
|
273
|
}
|
274
|
}
|
275
|
return $new_root;
|
276
|
}
|
277
|
|
278
|
|
279
|
/**
|
280
|
* Merge a branch into a root tree
|
281
|
*
|
282
|
* @param unknown_type $tree
|
283
|
* @param unknown_type $branch
|
284
|
* @return the merged $tree
|
285
|
*/
|
286
|
function _cdm_taxontree_merge($tree, $branch) {
|
287
|
|
288
|
if(!$branch){
|
289
|
return $tree;
|
290
|
}
|
291
|
|
292
|
foreach(array_keys($tree) as $uuid) {
|
293
|
// check if node exists in $branch
|
294
|
if(!empty($branch[$uuid])) {
|
295
|
if(isset($tree[$uuid]->filter)){
|
296
|
$branch[$uuid]->filter = $tree[$uuid]->filter;
|
297
|
}
|
298
|
if(isset($tree[$uuid]->expanded)){
|
299
|
$branch[$uuid]->expanded = $tree[$uuid]->expanded;
|
300
|
}
|
301
|
// $Uuid exists check if the node in tree1 or tree2 contains children
|
302
|
if(is_array($branch[$uuid]->children) && is_array($tree[$uuid]->children)) {
|
303
|
// merge recursive
|
304
|
$tree[$uuid]->children = _cdm_taxontree_merge($tree[$uuid]->children, $branch[$uuid]->children);
|
305
|
} else if(is_array($branch[$uuid]->children)){
|
306
|
$tree[$uuid] = $branch[$uuid];
|
307
|
}
|
308
|
unset($branch[$uuid]);
|
309
|
}
|
310
|
}
|
311
|
// append remaining items from branch to tree
|
312
|
foreach(array_keys($branch) as $uuid){
|
313
|
$tree[$uuid] = $branch[$uuid];
|
314
|
}
|
315
|
return $tree;
|
316
|
}
|
317
|
|
318
|
|
319
|
/**
|
320
|
* Replaces the keys of an array of TreeNode instances
|
321
|
* by the $treeNode->uuid of the single array elements.
|
322
|
* An sets additional fields
|
323
|
*
|
324
|
* @param $resultset array of TreeNode instances as +returned by the cdm web service
|
325
|
* @param $excluded whether the $resultset is included by a active filter. Is ignored if NULL.
|
326
|
* @param $expanded whether the children of the nodes in the $resultset are expanded or not. Is ignored if NULL.
|
327
|
*/
|
328
|
function _cdm_resultset2nodelist($resultset, $excluded = null, $expanded = null){
|
329
|
|
330
|
if(! is_array($resultset)) {
|
331
|
return false;
|
332
|
}
|
333
|
|
334
|
$tree = array();
|
335
|
foreach($resultset as $treeNode){
|
336
|
if(!is_null($excluded)){
|
337
|
$treeNode->filter = ($excluded ? 'excluded': 'included');
|
338
|
}
|
339
|
if(!is_null($expanded)){
|
340
|
$treeNode->expanded = ($expanded ? 'expanded': 'collapsed');
|
341
|
}
|
342
|
$tree[$treeNode->uuid] = $treeNode;
|
343
|
}
|
344
|
return $tree;
|
345
|
}
|
346
|
|
347
|
|
348
|
function theme_cdm_taxontree_block($tree){
|
349
|
|
350
|
$out = '';
|
351
|
if(cdm_dataportal_filters_active()){
|
352
|
$out .= theme('cdm_taxontree_contoller', _get_compact_mode());
|
353
|
}
|
354
|
$out .= '<div class="cdm_taxontree_scroller_x"><div class="cdm_taxontree_container"><div class="cdm_taxontree_scroller_y"><div class="cdm_taxontree_border">'.theme('cdm_taxontree', $tree, !cdm_dataportal_filters_active(), TRUE, 'cdm_taxontree_node_concept_switch').'</div></div></div></div>';
|
355
|
return $out;
|
356
|
}
|
357
|
|
358
|
function theme_cdm_taxontree_contoller($compact_mode){
|
359
|
|
360
|
static $modes = array('expanded', 'compact', 'flattened');
|
361
|
|
362
|
$out = '<div class="settings">';
|
363
|
foreach($modes as $mode){
|
364
|
if($compact_mode == $mode){
|
365
|
$out .= t($mode);
|
366
|
} else {
|
367
|
$out .= l(t($mode), 'cdm_taxontree/set/compact_mode/'.$mode, array(), drupal_get_destination());
|
368
|
}
|
369
|
$out .= ' ';
|
370
|
}
|
371
|
|
372
|
return $out.'</div>';
|
373
|
}
|
374
|
|
375
|
function theme_cdm_taxontree($tree, $filterIncludes = null, $show_filter_switch = false, $tree_node_callback = false){
|
376
|
|
377
|
if(!is_array($tree)) {
|
378
|
return false;
|
379
|
}
|
380
|
|
381
|
if(is_null($filterIncludes)){
|
382
|
// set $filterIncludes true if no filters are set.
|
383
|
$filterIncludes = !cdm_dataportal_filters_active();
|
384
|
}
|
385
|
|
386
|
$out = '<ul class="cdm_taxontree">';
|
387
|
foreach($tree as $node){
|
388
|
$out .= theme('cdm_taxontree_node', $node, $filterIncludes, $show_filter_switch, $tree_node_callback);
|
389
|
}
|
390
|
$out .= '</ul>';
|
391
|
return $out;
|
392
|
}
|
393
|
|
394
|
function theme_cdm_taxontree_node($node, $filterIncludes, $show_filter_switch = false, $tree_node_callback = false){
|
395
|
|
396
|
$is_leaf = !$node->hasChildren || $node->hasChildren == 0;
|
397
|
$is_expanded = isset($node->expanded) && $node->expanded = 'expanded';
|
398
|
|
399
|
if($filterIncludes){
|
400
|
$name = l(cdm_dataportal_shortname_of($node), cdm_dataportal_taxon_path($node->uuid));
|
401
|
$filter_class = 'filter_included';
|
402
|
} else {
|
403
|
if($node->filter == 'on') {
|
404
|
$name = l(cdm_dataportal_shortname_of($node), cdm_dataportal_taxon_path($node->uuid));
|
405
|
$filter_class = 'filter_on';
|
406
|
} else {
|
407
|
$name .= cdm_dataportal_shortname_of($node);
|
408
|
$filter_class = 'filter_excluded';
|
409
|
}
|
410
|
}
|
411
|
$nextLevelIncluded = $node->filter == 'on' || $filterIncludes;
|
412
|
|
413
|
$cdm_proxy_url = false;
|
414
|
if(!$is_leaf && !$is_expanded && $filter_class != 'filter_excluded'){
|
415
|
$ws_url = cdm_compose_url(CDM_WS_TREENODE_CHILDREN, array($node->uuid));
|
416
|
$cdm_proxy_url = url('cdm_api/proxy/'.urlencode($ws_url).'/cdm_taxontree/'.($nextLevelIncluded ? 1 : 0).'/'.($show_filter_switch ? 1 : 0).'/'.$tree_node_callback);
|
417
|
}
|
418
|
|
419
|
// list item
|
420
|
$out = '<li class="'
|
421
|
.($node->focused ? 'focused ' : '')
|
422
|
.($is_leaf ? 'leaf ':($is_expanded ?'expanded ':'collapsed '))
|
423
|
.$filter_class.'"'
|
424
|
.($cdm_proxy_url ? 'title="'.$cdm_proxy_url.'"' : '')
|
425
|
.'>';
|
426
|
|
427
|
if($show_filter_switch){
|
428
|
// filter icon
|
429
|
$out .= theme('cdm_taxontree_node_filter_switch', $node, $filter_class);
|
430
|
}
|
431
|
|
432
|
// taxon name
|
433
|
$out .= $name;
|
434
|
|
435
|
// concept_switch or other theme callbacks
|
436
|
if($tree_node_callback){
|
437
|
$out .= theme($tree_node_callback, $node);
|
438
|
}
|
439
|
|
440
|
if(isset($node->children) && is_array($node->children)){
|
441
|
$out .= theme('cdm_taxontree', $node->children, $nextLevelIncluded);
|
442
|
}
|
443
|
$out .= '</li>';
|
444
|
|
445
|
return $out;
|
446
|
}
|
447
|
|
448
|
function theme_cdm_taxontree_node_filter_switch(&$node, $filter_class){
|
449
|
$out = '';
|
450
|
|
451
|
switch($filter_class){
|
452
|
case 'filter_included':
|
453
|
$filter_icon = 'visible_implicit_small.gif';
|
454
|
break;
|
455
|
case 'filter_excluded':
|
456
|
$filter_icon = 'invisible_small.gif';
|
457
|
break;
|
458
|
case 'filter_on':
|
459
|
$filter_icon = 'visible_small.gif';
|
460
|
break;
|
461
|
}
|
462
|
|
463
|
$filter_op = $node->filter == 'on' ? 'remove' : 'add';
|
464
|
|
465
|
$out .= ' '
|
466
|
.l('<img src="'.drupal_get_path('module', 'cdm_taxontree').'/'.$filter_icon.'" alt="[f]" />',
|
467
|
'cdm_dataportal/filter/'.$filter_op.'/'.$node->uuid, array('class'=>'filter_'.$filter_op),
|
468
|
'destination='.cdm_dataportal_taxon_path($node->uuid),
|
469
|
null, false, true);
|
470
|
|
471
|
return $out;
|
472
|
}
|
473
|
|
474
|
function theme_cdm_taxontree_node_concept_switch(&$node){
|
475
|
$out = '';
|
476
|
|
477
|
if(isset($node->alternativeConceptRefs[0])){
|
478
|
$out = l(
|
479
|
'<img src="'.drupal_get_path('module', 'cdm_taxontree').'/concept_switch.gif" alt="[->]" />',
|
480
|
'cdm_dataportal/taxon/alternative/'.$node->uuid,
|
481
|
array('rel'=>'cdm_dataportal/taxon/alternative/'.$node->uuid, 'class'=>'concept_switch'),
|
482
|
null, null, false, true);
|
483
|
}
|
484
|
return $out;
|
485
|
}
|
486
|
|
487
|
function theme_cdm_taxontree_node_reference(&$node){
|
488
|
|
489
|
$out = ' <span class="sec_ref widget_select" style="background-color:#'._uuid_to_rgbhex($node->secUuid).'" title="'.$node->secUuid.'">'.$node->secUuid.'</span>';
|
490
|
return $out;
|
491
|
}
|
492
|
|
493
|
function cdm_taxontree_widget($default_uuid = false){
|
494
|
|
495
|
drupal_add_js(drupal_get_path('module', 'cdm_taxontree').'/js/cdm_taxontree_widget.js');
|
496
|
|
497
|
$out = '<div class="cdm_taxontree_widget">';
|
498
|
$out .= '<div class="tree">'.theme('cdm_taxontree', cdm_taxontree_build_tree(), NULL, FALSE, 'cdm_taxontree_node_reference').'</div>';
|
499
|
$out .= '<div class="selected_nodes"><label>'.t('Selected Nodes').'</label><ul class="listing"><li><input type="text" class="value_1232-stub" value="1232-stub" /></li></ul></div>';
|
500
|
$out .= '</div>';
|
501
|
return $out;
|
502
|
}
|
503
|
|
504
|
|
505
|
// --------------------------------------------------- //
|
506
|
|
507
|
function _uuid_to_rgbhex($uuid){
|
508
|
|
509
|
$xfoot = _str_crossfoot($uuid);
|
510
|
$h = $xfoot / 2 / 2;
|
511
|
$h = $h - floor($h);
|
512
|
$RGB = _hsv_2_rgb($h, 0.45, 1);
|
513
|
return dechex($RGB['R']).dechex($RGB['G']).dechex($RGB['B']);
|
514
|
}
|
515
|
|
516
|
function _str_crossfoot($str)
|
517
|
{
|
518
|
$xfoot = 0;
|
519
|
for($i=0; $i<strlen($str); $i++)
|
520
|
{
|
521
|
$xfoot = $xfoot + ord($str[$i]);
|
522
|
}
|
523
|
return $xfoot;
|
524
|
}
|
525
|
|
526
|
|
527
|
function _cdm_get_taxonuuid(){
|
528
|
|
529
|
//TODO make the path configurable
|
530
|
if (arg(0)=="cdm_dataportal" && arg(1)=="taxon" && arg(2)!==0){
|
531
|
$taxon_uuid = arg(2);
|
532
|
} else {
|
533
|
$taxon_uuid = $_SESSION['cdm_dataportal']['tree']['taxon_uuid'];
|
534
|
}
|
535
|
|
536
|
return $taxon_uuid;
|
537
|
}
|
538
|
|
539
|
function _hsv_2_rgb($H, $S, $V) // HSV Values:Number 0-1
|
540
|
{ // RGB Results:Number 0-255
|
541
|
$RGB = array();
|
542
|
|
543
|
if($S == 0)
|
544
|
{
|
545
|
$R = $G = $B = $V * 255;
|
546
|
}
|
547
|
else
|
548
|
{
|
549
|
$var_H = $H * 6;
|
550
|
$var_i = floor( $var_H );
|
551
|
$var_1 = $V * ( 1 - $S );
|
552
|
$var_2 = $V * ( 1 - $S * ( $var_H - $var_i ) );
|
553
|
$var_3 = $V * ( 1 - $S * (1 - ( $var_H - $var_i ) ) );
|
554
|
|
555
|
if ($var_i == 0) { $var_R = $V ; $var_G = $var_3 ; $var_B = $var_1 ; }
|
556
|
else if ($var_i == 1) { $var_R = $var_2 ; $var_G = $V ; $var_B = $var_1 ; }
|
557
|
else if ($var_i == 2) { $var_R = $var_1 ; $var_G = $V ; $var_B = $var_3 ; }
|
558
|
else if ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2 ; $var_B = $V ; }
|
559
|
else if ($var_i == 4) { $var_R = $var_3 ; $var_G = $var_1 ; $var_B = $V ; }
|
560
|
else { $var_R = $V ; $var_G = $var_1 ; $var_B = $var_2 ; }
|
561
|
|
562
|
$R = $var_R * 255;
|
563
|
$G = $var_G * 255;
|
564
|
$B = $var_B * 255;
|
565
|
}
|
566
|
|
567
|
$RGB['R'] = $R;
|
568
|
$RGB['G'] = $G;
|
569
|
$RGB['B'] = $B;
|
570
|
|
571
|
return $RGB;
|
572
|
}
|