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, $taxonUuid_inFocus);
|
55
|
drupal_add_css(drupal_get_path('module', 'cdm_taxontree').'/cdm_taxontree.css');
|
56
|
drupal_add_js(drupal_get_path('module', 'cdm_taxontree').'/cdm_taxontree.js');
|
57
|
return $block;
|
58
|
}
|
59
|
}
|
60
|
}
|
61
|
|
62
|
function cdm_taxontree_set($key, $value){
|
63
|
|
64
|
if(is_string($key)){
|
65
|
$_SESSION['cdm']['taxontree'][$key] = $value;
|
66
|
}
|
67
|
|
68
|
if($_REQUEST['destination']){
|
69
|
$destination = $_REQUEST['destination'];
|
70
|
unset($_REQUEST['destination']);
|
71
|
drupal_goto($destination);
|
72
|
}
|
73
|
return '##'.$destination;
|
74
|
}
|
75
|
|
76
|
|
77
|
function cdm_taxontree_build_tree($taxonUuid){
|
78
|
|
79
|
// find the secRefUuid
|
80
|
if($taxonUuid){
|
81
|
//TODO poor performance here:
|
82
|
$taxon = cdm_ws_get(CDM_WS_TAXON, $taxonUuid);
|
83
|
$secRefUuid = $taxon->sec->uuid;
|
84
|
}
|
85
|
|
86
|
if(!$secRefUuid){
|
87
|
$secRef = _cdm_dataportal_currentSecRef_array();
|
88
|
$secRefUuid = $secRef['uuid'];
|
89
|
}
|
90
|
|
91
|
$filtersActive = isset($_SESSION['cdm']['filters']) && count($_SESSION['cdm']['filters']) > 0;
|
92
|
$compact_tree = $filtersActive && $_SESSION['cdm']['taxontree']['compact'] == 1;
|
93
|
|
94
|
if(!$compact_tree){
|
95
|
// get the root
|
96
|
$root_tree = cdm_ws_get(CDM_WS_TREENODE_ROOT, $secRefUuid);
|
97
|
$root_tree = _cdm_resultset2tree($root_tree);
|
98
|
|
99
|
if($filtersActive){
|
100
|
// the paths up to active filters are inactivated and thus cannot be browsed by expanding nodes
|
101
|
// therefore we need to build up the branches for all nodes which are set as filters
|
102
|
// the branches are merged with the root
|
103
|
foreach($_SESSION['cdm']['filters'] as $uuid=>$filter){
|
104
|
$branch = cdm_taxontree_build_branch($uuid);
|
105
|
$root_tree = _cdm_taxontree_merge($root_tree, $branch);
|
106
|
}
|
107
|
}
|
108
|
// build the the branch for the focused node and merge it with the root
|
109
|
if($taxonUuid){
|
110
|
$branch = cdm_taxontree_build_branch($taxonUuid);
|
111
|
$root_tree = _cdm_taxontree_merge($root_tree, $branch);
|
112
|
}
|
113
|
} else {
|
114
|
$root_tree = $_SESSION['cdm']['filters'];
|
115
|
/* if(){
|
116
|
foreach($_SESSION['cdm']['filters'] as $uuid=>$filter){
|
117
|
$branch = cdm_taxontree_build_branch($uuid #### , !$compact_tree #### );
|
118
|
$root_tree = _cdm_taxontree_merge($root_tree, $branch);
|
119
|
}
|
120
|
}*/
|
121
|
}
|
122
|
|
123
|
|
124
|
|
125
|
return $root_tree;
|
126
|
}
|
127
|
|
128
|
/**
|
129
|
* Builds the specific branch for $taxonUuid.
|
130
|
* The branch reaches from the parent root node of $taxonUuid up to the children of $taxonUuid.
|
131
|
* The siblings od all parent of $taxonUuid are included except for the root siblings.
|
132
|
*
|
133
|
* @param unknown_type $taxonUuid
|
134
|
* @return a subtree
|
135
|
*/
|
136
|
function cdm_taxontree_build_branch($taxonUuid){
|
137
|
|
138
|
$branch = array();
|
139
|
$parents = cdm_ws_get(CDM_WS_TREENODE_PARENTS, $taxonUuid);
|
140
|
//TODO improve performance by changing the web service and thus making this line obsolete
|
141
|
$parents = array_reverse($parents);
|
142
|
$parents = _cdm_resultset2tree($parents);
|
143
|
$lastParent = null;
|
144
|
foreach($parents as $pnode){
|
145
|
if($pnode->hasChildren){
|
146
|
$children = cdm_ws_get(CDM_WS_TREENODE_CHILDREN, $pnode->uuid);
|
147
|
$children = _cdm_resultset2tree($children);
|
148
|
$pnode->children = $children;
|
149
|
if($lastParent){
|
150
|
$pnode->children[$lastParent->uuid] = $lastParent;
|
151
|
}
|
152
|
}
|
153
|
$lastParent = $pnode;
|
154
|
}
|
155
|
$branch[$pnode->uuid] = $pnode;
|
156
|
return $branch;
|
157
|
}
|
158
|
|
159
|
/**
|
160
|
* Merge a branch into a root tree
|
161
|
*
|
162
|
* @param unknown_type $tree
|
163
|
* @param unknown_type $branch
|
164
|
* @return the merged $tree
|
165
|
*/
|
166
|
function _cdm_taxontree_merge($tree, $branch) {
|
167
|
|
168
|
foreach($tree AS $uuid => $node) {
|
169
|
// check IF node exists is $branch
|
170
|
if(!empty($branch[$uuid])) {
|
171
|
// $Uuid exists check if the node in tree1 or tree2 contains children
|
172
|
if(is_array($branch[$uuid]->children) && is_array($tree[$uuid]->children)) {
|
173
|
// merge recursive
|
174
|
$tree[$uuid]->children = _cdm_taxontree_merge($tree[$uuid]->children, $branch[$uuid]->children);
|
175
|
} else if(is_array($branch[$uuid]->children)){
|
176
|
$tree[$uuid] = $branch[$uuid];
|
177
|
}
|
178
|
}
|
179
|
}
|
180
|
unset($uuid, $node);
|
181
|
return $tree;
|
182
|
}
|
183
|
|
184
|
function theme_cdm_taxontree_block($tree, $taxonUuid_inFocus = null, $filterIncludes = null){
|
185
|
|
186
|
$out = '';
|
187
|
if(isset($_SESSION['cdm']['filters']) && count($_SESSION['cdm']['filters']) > 0){
|
188
|
$do_compact = isset($_SESSION['cdm']['taxontree']['compact']) && $_SESSION['cdm']['taxontree']['compact'] == false;
|
189
|
$out = '<div class="settings">'.l(($do_compact? t('compact tree'):t('expand tree')), 'cdm_taxontree/set/compact/'.($do_compact ? 1:0), array(), drupal_get_destination()).'</div>';
|
190
|
}
|
191
|
$out .= theme('cdm_taxontree', $tree, $taxonUuid_inFocus, $filterIncludes);
|
192
|
return $out;
|
193
|
}
|
194
|
|
195
|
function theme_cdm_taxontree($tree, $taxonUuid_inFocus = null, $filterIncludes = null){
|
196
|
|
197
|
if(! is_array($tree)) {
|
198
|
return false;
|
199
|
}
|
200
|
|
201
|
if(is_null($filterIncludes)){
|
202
|
// set $filterIncludes true if no filters are set.
|
203
|
$filterIncludes = !isset($_SESSION['cdm']['filters']) || count($_SESSION['cdm']['filters']) == 0;
|
204
|
}
|
205
|
|
206
|
$out = '<ul class="cdm_taxontree">';
|
207
|
foreach($tree as $node){
|
208
|
$out .= theme('cdm_taxontree_node', $node, $taxonUuid_inFocus == $node->uuid, $filterIncludes);
|
209
|
}
|
210
|
$out .= '</ul>';
|
211
|
return $out;
|
212
|
}
|
213
|
|
214
|
function theme_cdm_taxontree_node($node, $isFocused, $filterIncludes = false){
|
215
|
|
216
|
$is_leaf = !$node->hasChildren || $node->hasChildren == 0;
|
217
|
|
218
|
$is_expanded = !$is_leaf && isset($node->children);
|
219
|
|
220
|
$cdm_proxy_url = false;
|
221
|
if(!$is_leaf && !$is_expanded){
|
222
|
$ws_url = cdm_compose_url(CDM_WS_TREENODE_CHILDREN, array($node->uuid));
|
223
|
$cdm_proxy_url = url('cdm_api/proxy/'.urlencode($ws_url)."/cdm_taxontree");
|
224
|
}
|
225
|
|
226
|
if($filterIncludes){
|
227
|
//
|
228
|
$name = l(cdm_dataportal_shortname_of($node), cdm_dataportal_taxon_path($node->uuid));
|
229
|
$filter_icon = 'visible_implicit.gif';
|
230
|
$filter_on = false;
|
231
|
} else {
|
232
|
$filter_on = isset($_SESSION['cdm']['filters'][$node->uuid]);
|
233
|
if($filter_on) {
|
234
|
$name = l(cdm_dataportal_shortname_of($node), cdm_dataportal_taxon_path($node->uuid));
|
235
|
$filter_icon = 'visible.gif';
|
236
|
} else {
|
237
|
$filter_icon = 'invisible.gif';
|
238
|
$name .= cdm_dataportal_shortname_of($node);
|
239
|
}
|
240
|
}
|
241
|
|
242
|
$filter_op = isset($_SESSION['cdm']['filters'][$node->uuid]) ? 'remove' : 'add';
|
243
|
|
244
|
// list item
|
245
|
$out = '<li class="'
|
246
|
.($isFocused ?'focused ':'')
|
247
|
.($is_leaf ?'leaf ':($is_expanded ?'expanded ':'collapsed '))
|
248
|
.($filterIncludes ? 'filter_includes' : ($filter_on ? 'filter_on' : 'filter_excludes'))
|
249
|
.'"'
|
250
|
.($cdm_proxy_url ? 'title="'.$cdm_proxy_url.'"' : '')
|
251
|
.'>';
|
252
|
|
253
|
// filter icon
|
254
|
$out .= ' '.l('<img src="'.drupal_get_path('module', 'cdm_taxontree').'/'.$filter_icon.'" alt="[f]"', 'cdm_dataportal/filter/'.$filter_op.'/'.$node->uuid, array('class'=>'filter_'.$filter_op), 'destination='.cdm_dataportal_taxon_path($node->uuid), null, false, true);
|
255
|
|
256
|
// taxon name
|
257
|
$out .= $name;
|
258
|
|
259
|
// concept_switch
|
260
|
if(isset($node->alternativeConceptRefs[0])){
|
261
|
$out .= l('<img src="'.drupal_get_path('module', 'cdm_taxontree').'/concept_switch.gif" alt="[->]"', 'cdm_dataportal/taxon/alternative/'.$node->uuid, array('rel'=>'cdm_dataportal/taxon/alternative/'.$node->uuid, 'class'=>'concept_switch'), null, null, false, true);
|
262
|
}
|
263
|
|
264
|
if(isset($node->children) && is_array($node->children)){
|
265
|
$out .= theme('cdm_taxontree', $node->children, $taxonUuid_inFocus, ($filter_on || $filterIncludes));
|
266
|
}
|
267
|
$out .= '</li>';
|
268
|
|
269
|
return $out;
|
270
|
}
|
271
|
|
272
|
/**
|
273
|
* Replaces the keys of an array of TreeNode instances
|
274
|
* by the $treeNode->uuid of the single array elements.
|
275
|
*
|
276
|
* @param $resultset array of TreeNode instances as +returned by the cdm web service
|
277
|
*/
|
278
|
function _cdm_resultset2tree($resultset){
|
279
|
|
280
|
if(! is_array($resultset)) {
|
281
|
return false;
|
282
|
}
|
283
|
|
284
|
$tree = array();
|
285
|
foreach($resultset as $treeNode){
|
286
|
$tree[$treeNode->uuid] = $treeNode;
|
287
|
}
|
288
|
return $tree;
|
289
|
}
|
290
|
|
291
|
|
292
|
function _cdm_get_taxonuuid(){
|
293
|
|
294
|
//TODO make the path configurable
|
295
|
if (arg(0)=="cdm_dataportal" && arg(1)=="taxon" && arg(2)!==0){
|
296
|
$taxon_uuid = arg(2);
|
297
|
} else {
|
298
|
$taxon_uuid = $_SESSION['cdm_dataportal']['tree']['taxon_uuid'];
|
299
|
}
|
300
|
|
301
|
return $taxon_uuid;
|
302
|
}
|