Project

General

Profile

Download (9.37 KB) Statistics
| Branch: | Tag: | Revision:
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 .= '&nbsp;'.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="[-&gt;]"', '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
}
(4-4/14)