can_view_task($task_details)) { Flyspray::show_error(9); } $id = Req::num('task_id'); $page->assign('task_id', $id); $prunemode = Req::num('prune', 0); $selfurl = createURL('depends', $id); $pmodes = array(L('none'), L('pruneclosedlinks'), L('pruneclosedtasks')); foreach ($pmodes as $mode => $desc) { if ($mode == $prunemode) { $strlist[] = $desc; } else { $strlist[] = "$desc\n"; } } $page->uses('strlist'); $starttime = microtime(); $sql= 'SELECT t1.task_id AS id1, t1.item_summary AS sum1, t1.percent_complete AS pct1, t1.is_closed AS clsd1, lst1.status_name AS stat1, t1.task_severity AS sev1, t1.task_priority AS pri1, t1.closure_comment AS com1, u1c.real_name AS clsdby1, r1.resolution_name as res1, t2.task_id AS id2, t2.item_summary AS sum2, t2.percent_complete AS pct2, t2.is_closed AS clsd2, lst2.status_name AS stat2, t2.task_severity AS sev2, t2.task_priority AS pri2, t2.closure_comment AS com2, u2c.real_name AS clsdby2, r2.resolution_name as res2 FROM {dependencies} AS d JOIN {tasks} AS t1 ON d.task_id=t1.task_id LEFT JOIN {users} AS u1c ON t1.closed_by=u1c.user_id LEFT JOIN {list_status} AS lst1 ON t1.item_status = lst1.status_id LEFT JOIN {list_resolution} AS r1 ON t1.resolution_reason=r1.resolution_id JOIN {tasks} AS t2 ON d.dep_task_id=t2.task_id LEFT JOIN {list_status} AS lst2 ON t2.item_status = lst2.status_id LEFT JOIN {users} AS u2c ON t2.closed_by=u2c.user_id LEFT JOIN {list_resolution} AS r2 ON t2.resolution_reason=r2.resolution_id WHERE t1.project_id= ? ORDER BY d.task_id, d.dep_task_id'; $get_edges = $db->query($sql, array($proj->id)); $edge_list = array(); $rvrs_list = array(); $node_list = array(); while ($row = $db->fetchRow($get_edges)) { extract($row, EXTR_REFS); $edge_list[$id1][] = $id2; $rvrs_list[$id2][] = $id1; if (!isset($node_list[$id1])) { $node_list[$id1] = array('id'=>$id1, 'sum'=>$sum1, 'pct'=>$pct1, 'clsd'=>$clsd1, 'status_name'=>$stat1, 'sev'=>$sev1, 'pri'=>$pri1, 'com'=>$com1, 'clsdby'=>$clsdby1, 'res'=>$res1); } if (!isset($node_list[$id2])) { $node_list[$id2] = array('id'=>$id2, 'sum'=>$sum2, 'pct'=>$pct2, 'clsd'=>$clsd2, 'status_name'=>$stat2, 'sev'=>$sev2, 'pri'=>$pri2, 'com'=>$com2, 'clsdby'=>$clsdby2, 'res'=>$res2); } } // Now we have our lists of nodes and edges, along with a helper // list of reverse edges. Time to do the graph coloring, so we know // which ones are in our particular connected graph. We'll set up a // list and fill it up as we visit nodes that are connected to our // main task. $connected = array(); $levelsdown = 0; $levelsup = 0; function connectsTo($id, $down, $up) { global $connected, $edge_list, $rvrs_list, $levelsdown, $levelsup; global $prunemode, $node_list; if (!isset($connected[$id])) { $connected[$id]=1; } if ($down > $levelsdown) { $levelsdown = $down; } if ($up > $levelsup ) { $levelsup = $up ; } /* echo '
';
echo "$id ($down d, $up u) => $levelsdown d $levelsup u
\n"; echo 'nodes:';print_r($node_list); echo 'edges:';print_r($edge_list); echo 'rvrs:';print_r($rvrs_list); echo 'levelsdown:';print_r($levelsdown); echo "\n".'levelsup';print_r($levelsup); echo '
'; */ if (empty($node_list)){ return; } if (!isset($node_list[$id])){ return; } $selfclosed = $node_list[$id]['clsd']; if (isset($edge_list[$id])) { foreach ($edge_list[$id] as $neighbor) { $neighborclosed = $node_list[$neighbor]['clsd']; if (!isset($connected[$neighbor]) && !($prunemode==1 && $selfclosed && $neighborclosed) && !($prunemode==2 && $neighborclosed)) { connectsTo($neighbor, $down, $up+1); } } } if (isset($rvrs_list[$id])) { foreach ($rvrs_list[$id] as $neighbor) { $neighborclosed = $node_list[$neighbor]['clsd']; if (!isset($connected[$neighbor]) && !($prunemode==1 && $selfclosed && $neighborclosed) && !($prunemode==2 && $neighborclosed)) { connectsTo($neighbor, $down+1, $up); } } } } connectsTo($id, 0, 0); $connected_nodes = array_keys($connected); sort($connected_nodes); // Now lets get rid of the extra junk in our arrays. // In prunemode 0, we know we're only going to have to get rid of // whole lists, and not elements in the lists, because if they were // in the list, they'd be connected, so we wouldn't be removing them. // In prunemode 1 or 2, we may have to remove stuff from the list, because // you can have an edge to a node that didn't end up connected. foreach (array("edge_list", "rvrs_list", "node_list") as $l) { foreach (${$l} as $n => $list) { if (!isset($connected[$n])) { unset(${$l}[$n]); } if ($prunemode!=0 && $l!="node_list" && isset(${$l}[$n])) { // Only keep entries that appear in the $connected_nodes list ${$l}[$n] = array_intersect(${$l}[$n], $connected_nodes); } } } // Now we've got everything we need... prepare JSON data $resultData = array(); foreach ($node_list as $task_id => $taskInfo) { $adjacencies = array(); if (isset($edge_list[$task_id])) { foreach ($edge_list[$task_id] as $dst) { array_push($adjacencies, array('nodeTo' => $dst, 'nodeFrom' => $task_id)); } } if ($task_id == $id) { $color = '#5F9729'; } else if ($taskInfo['clsd']) { $color = '#808080'; } else { $color = '#83548B'; } $newTask = array('id' => $task_id, 'name' => tpl_tasklink($task_id), 'data' => array('$color' => $color, '$type' => 'circle', '$dim' => 15), 'adjacencies' => $adjacencies); array_push($resultData, $newTask); } $jasonData = json_encode($resultData); $page->assign('jasonData', $jasonData); $page->assign('task_id', $id); $page->setTitle(sprintf('FS#%d : %s', $id, L('dependencygraph'))); $page->pushTpl('depends.tpl'); ?>