* change it again.
This commit is contained in:
+91
-94
@@ -1945,34 +1945,113 @@ class projectModel extends model
|
||||
}
|
||||
|
||||
/**
|
||||
* Format task list for tree view
|
||||
* @param array $tasks
|
||||
* Fill tasks in tree.
|
||||
* @param object $tree
|
||||
* @param int $projectID
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function fillTasksInTree($node, $projectID)
|
||||
{
|
||||
$node = (object)$node;
|
||||
static $storyGroups, $taskGroups;
|
||||
if(empty($storyGroups))
|
||||
{
|
||||
$stories = $this->dao->select('t2.*, t1.version as taskVersion')->from(TABLE_PROJECTSTORY)->alias('t1')
|
||||
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
|
||||
->where('t1.project')->eq((int)$projectID)
|
||||
->andWhere('t2.deleted')->eq(0)
|
||||
->fetchAll();
|
||||
$storyGroups = array();
|
||||
foreach($stories as $story) $storyGroups[$story->product][$story->module][$story->id] = $story;
|
||||
}
|
||||
if(empty($taskGroups))
|
||||
{
|
||||
$tasks = $this->dao->select('*')->from(TABLE_TASK)
|
||||
->where('project')->eq((int)$projectID)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchAll();
|
||||
$taskGroups = array();
|
||||
foreach($tasks as $task) $taskGroups[$task->module][$task->story][$task->id] = $task;
|
||||
}
|
||||
|
||||
if(!empty($node->children)) foreach($node->children as $i => $child) $node->children[$i] = $this->fillTasksInTree($child, $projectID);
|
||||
|
||||
if(!isset($node->id))$node->id = 0;
|
||||
if($node->type == 'story' or $node->type == 'product')
|
||||
{
|
||||
$stories = $storyGroups[$node->root][$node->id];
|
||||
foreach($stories as $story)
|
||||
{
|
||||
$storyItem = new stdclass();
|
||||
$storyItem->type = 'story';
|
||||
$storyItem->id = 'story' . $story->id;
|
||||
$storyItem->title = $story->title;
|
||||
$storyItem->color = $story->color;
|
||||
$storyItem->pri = $story->pri;
|
||||
$storyItem->storyId = $story->id;
|
||||
$storyItem->url = helper::createLink('story', 'view', "storyID=$story->id&version=$story->version&from=project¶m=$projectID");
|
||||
$storyItem->taskCreateUrl = helper::createLink('task', 'batchCreate', "projectID={$projectID}&story={$story->id}");
|
||||
|
||||
$storyTasks = $taskGroups[$node->id][$story->id];
|
||||
if(!empty($storyTasks))
|
||||
{
|
||||
$taskItems = $this->formatTasksForTree($storyTasks, $story);
|
||||
$storyItem->tasksCount = count($taskItems);
|
||||
$storyItem->children = array();
|
||||
$storyItem->children[] = array('id' => 'tasks' . $story->id, 'tasks' => $taskItems, 'type' => 'tasks', 'actions' => false);
|
||||
}
|
||||
|
||||
$node->children[] = $storyItem;
|
||||
}
|
||||
}
|
||||
elseif($node->type == 'task')
|
||||
{
|
||||
$tasks = $taskGroups[$node->id][0];
|
||||
if(!empty($tasks))
|
||||
{
|
||||
$taskItems = $this->formatTasksForTree($tasks);
|
||||
$node->children[] = array('id' => 'tasks', 'tasks' => $taskItems, 'type' => 'tasks', 'actions' => false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$node->type = 'module';
|
||||
$node->actions = false;
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format tasks for tree.
|
||||
*
|
||||
* @param array $tasks
|
||||
* @param object $story
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function formatTasksForTree($tasks)
|
||||
public function formatTasksForTree($tasks, $story = '')
|
||||
{
|
||||
static $users;
|
||||
if(empty($users)) $users = $this->loadModel('user')->getPairs('noletter');
|
||||
|
||||
$taskItems = array();
|
||||
foreach ($tasks as $task)
|
||||
foreach($tasks => $task)
|
||||
{
|
||||
$taskItem = new stdclass();
|
||||
$taskItem->type = 'task';
|
||||
$taskItem->id = $task->id;
|
||||
$taskItem->title = $task->name;
|
||||
$taskItem->color = $task->color;
|
||||
$taskItem->pri = (int) $task->pri;
|
||||
$taskItem->pri = (int)$task->pri;
|
||||
$taskItem->status = $task->status;
|
||||
$taskItem->estimate = $task->estimate;
|
||||
$taskItem->consumed = $task->consumed;
|
||||
$taskItem->left = $task->left;
|
||||
$taskItem->assignedTo = $users[$task->assignedTo];
|
||||
$taskItem->url = helper::createLink('task', 'view', "task=$task->id");
|
||||
$taskItem->storyChanged = $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion;
|
||||
$taskItem->storyChanged = $story and $story->status == 'active' and $story->version > $story->taskVersion;
|
||||
|
||||
$buttons = '';
|
||||
$buttons = '';
|
||||
$buttons .= common::buildIconButton('task', 'assignTo', "projectID=$task->project&taskID=$task->id", $task, 'list', '', '', 'iframe', true);
|
||||
$buttons .= common::buildIconButton('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
|
||||
|
||||
@@ -1985,72 +2064,13 @@ class projectModel extends model
|
||||
$buttons .= common::buildIconButton('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
|
||||
$buttons .= common::buildIconButton('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
|
||||
$buttons .= common::buildIconButton('task', 'edit', "taskID=$task->id", '', 'list');
|
||||
|
||||
$taskItem->buttons = $buttons;
|
||||
$taskItems[] = $taskItem;
|
||||
}
|
||||
|
||||
return $taskItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build product task tree item
|
||||
* @param object $tree
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function buildProductTaskTree($node, $projectID)
|
||||
{
|
||||
$this->loadModel('story');
|
||||
$this->loadModel('task');
|
||||
|
||||
static $users;
|
||||
if(empty($users)) $users = $this->loadModel('user')->getPairs('noletter');
|
||||
|
||||
if($node->children)
|
||||
{
|
||||
foreach ($node->children as $child)
|
||||
{
|
||||
$child = $this->buildProductTaskTree($child, $projectID);
|
||||
}
|
||||
}
|
||||
|
||||
if($node->type === 'product')
|
||||
{
|
||||
$node->actions = false;
|
||||
// TODO: get product root storys and appent to children
|
||||
}
|
||||
else if($node->type === 'story')
|
||||
{
|
||||
$node->type = 'module';
|
||||
$node->actions = false;
|
||||
$stories = $this->story->getProjectStories($projectID, 'pri_asc,id_desc', 'byModule', $node->id);
|
||||
foreach ($stories as $story)
|
||||
{
|
||||
$storyItem = new stdclass();
|
||||
$storyItem->type = 'story';
|
||||
$storyItem->id = 'story' . $story->id;
|
||||
$storyItem->title = $story->title;
|
||||
$storyItem->color = $story->color;
|
||||
$storyItem->pri = $story->pri;
|
||||
$storyItem->storyId = $story->id;
|
||||
$storyItem->url = helper::createLink('story', 'view', "storyID=$story->id&version=$story->version&from=project¶m=$projectID");
|
||||
$storyItem->taskCreateUrl = helper::createLink('task', 'batchCreate', "projectID={$projectID}&story={$story->id}");
|
||||
|
||||
$storyTasks = $this->task->getStoryTasks($story->id, $projectID);
|
||||
if(!empty($storyTasks))
|
||||
{
|
||||
$taskItems = $this->formatTasksForTree($storyTasks);
|
||||
$storyItem->tasksCount = count($taskItems);
|
||||
$storyItem->children = array();
|
||||
$storyItem->children[] = array('id' => 'tasks' . $story->id, 'tasks' => $taskItems, 'type' => 'tasks', 'actions' => false);
|
||||
}
|
||||
|
||||
$node->children[] = $storyItem;
|
||||
}
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get projects tree data
|
||||
* @param int $projectID
|
||||
@@ -2059,32 +2079,9 @@ class projectModel extends model
|
||||
*/
|
||||
public function getProjectTree($projectID)
|
||||
{
|
||||
$tree = array();
|
||||
$products = $this->getProducts($projectID);
|
||||
foreach ($products as $product)
|
||||
{
|
||||
$productItem = new stdclass();
|
||||
$productItem->type = 'product';
|
||||
$productItem->id = 'product' . $product->id;
|
||||
$productItem->title = $product->name;
|
||||
$productItem->children = $this->loadModel('tree')->getFullTree($product->id, 'story');
|
||||
|
||||
$tree[] = $this->buildProductTaskTree($productItem, $projectID);
|
||||
}
|
||||
$zeroStoryTasks = $this->loadModel('task')->getStoryTasks(0, $projectID);
|
||||
if(count($zeroStoryTasks))
|
||||
{
|
||||
$zeroStoryTasks = $this->formatTasksForTree($zeroStoryTasks);
|
||||
$unlinkStoryItem = new stdclass();
|
||||
$unlinkStoryItem->type = 'unlinkStory';
|
||||
$unlinkStoryItem->id = 'unlinkStory';
|
||||
$unlinkStoryItem->tasksCount = count($zeroStoryTasks);
|
||||
$unlinkStoryItem->title = $this->lang->project->unlinkStoryTasks;
|
||||
$unlinkStoryItem->children = array();
|
||||
$unlinkStoryItem->actions = false;
|
||||
$unlinkStoryItem->children[] = array('id' => 'tasks0', 'tasks' => $zeroStoryTasks, 'type' => 'tasks', 'actions' => false);
|
||||
$tree[] = $unlinkStoryItem;
|
||||
}
|
||||
return $tree;
|
||||
$fullTrees = $this->loadModel('tree')->getFullTaskTree($projectID, 0, false);
|
||||
array_unshift($fullTrees, array('id' => 0, 'name' => '/', 'type' => 'task', 'actions' => false, 'root' => $projectID));
|
||||
foreach($fullTrees as $i => $tree) $fullTrees[$i] = $this->fillTasksInTree($tree, $projectID);
|
||||
return $fullTrees;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-14
@@ -128,20 +128,11 @@ class tree extends control
|
||||
$project = $this->loadModel('project')->getById($rootID);
|
||||
$this->view->root = $project;
|
||||
|
||||
$products = $this->project->getProducts($rootID);
|
||||
$this->view->products = $products;
|
||||
|
||||
$this->lang->set('menugroup.tree', 'project');
|
||||
$this->project->setMenu($this->project->getPairs(), $rootID);
|
||||
$this->lang->tree->menu = $this->lang->project->menu;
|
||||
$this->lang->tree->menuOrder = $this->lang->project->menuOrder;
|
||||
|
||||
$projects = $this->project->getPairs();
|
||||
unset($projects[$rootID]);
|
||||
$currentProject = key($projects);
|
||||
$parentModules = $this->tree->getParents($currentModuleID);
|
||||
$newModule = (version_compare($project->openedVersion, '4.1', '>') and $products) ? true : false;
|
||||
|
||||
$title = $project->name . $this->lang->colon . $this->lang->tree->manageProject;
|
||||
$position[] = html::a($this->createLink('project', 'task', "projectID=$rootID"), $project->name);
|
||||
$position[] = $this->lang->tree->manageProject;
|
||||
@@ -150,12 +141,8 @@ class tree extends control
|
||||
$this->view->position = $position;
|
||||
$this->view->rootID = $rootID;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->allProject = $projects;
|
||||
$this->view->newModule = $newModule;
|
||||
$this->view->currentProject = $currentProject;
|
||||
$this->view->projectModules = $this->tree->getTaskOptionMenu($currentProject, $productID);
|
||||
$this->view->currentModuleID = $currentModuleID;
|
||||
$this->view->tree = $this->tree->getFullTaskTree($rootID, $productID, 0, $newModule);
|
||||
$this->view->tree = $this->tree->getFullTaskTree($rootID, $productID);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
+69
-29
@@ -456,32 +456,52 @@ class treeModel extends model
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getFullTaskTree($projectID, $productID, $moduleID = 0, $newModule = false)
|
||||
public function getFullTaskTree($rootID, $productID = 0, $manage = true)
|
||||
{
|
||||
$tree = array_values($this->getTaskSons($projectID, $productID, $moduleID));
|
||||
if(!$moduleID)
|
||||
$extra = array('projectID' => $rootID, 'productID' => $productID, 'tip' => true);
|
||||
|
||||
/* If createdVersion <= 4.1, go to getTreeMenu(). */
|
||||
$products = $this->loadModel('product')->getProductsByProject($rootID);
|
||||
$branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products));
|
||||
|
||||
if(!$this->isMergeModule($rootID, 'task') or !$products)
|
||||
{
|
||||
$products = $this->loadModel('project')->getProducts($projectID);
|
||||
if($newModule and $products)
|
||||
{
|
||||
$productModulesTree = array();
|
||||
foreach ($products as $product)
|
||||
{
|
||||
$productModulesTree[] = array('type' => 'product', 'name' => $product->name, 'actions' => false, 'id' => 'product' . $product->id, 'children' => $this->getFullTrees($product->id, 'story'));
|
||||
}
|
||||
$tree = array_merge($productModulesTree, $tree);
|
||||
}
|
||||
$extra['tip'] = false;
|
||||
$stmt = $this->dbh->query($this->buildMenuQuery($rootID, 'task'));
|
||||
return $this->getFullTree($stmt, 'task');
|
||||
}
|
||||
if($tree)
|
||||
|
||||
/* if not manage, only get linked modules and ignore others. */
|
||||
$projectModules = $manage ? array() : $this->getTaskTreeModules($rootID, true);
|
||||
|
||||
/* Get module according to product. */
|
||||
$fullTrees = array();
|
||||
foreach($products as $id => $product)
|
||||
{
|
||||
foreach ($tree as $node)
|
||||
$productInfo = $this->product->getById($id);
|
||||
/* tree menu. */
|
||||
$productTree = '';
|
||||
$branchTrees = '';
|
||||
if(empty($branchGroups[$id])) $branchGroups[$id]['0'] = '';
|
||||
foreach($branchGroups[$id] as $branch => $branchName)
|
||||
{
|
||||
if(is_array($node))$node = (object)$node;
|
||||
$children = $this->getFullTaskTree($projectID, $productID, $node->id);
|
||||
if(!empty($children)) $node->children = $children;
|
||||
$query = $this->dao->select('*')->from(TABLE_MODULE)->where("((root = $rootID and type = 'task' and parent != 0) OR (root = $id and type = 'story' and branch ='$branch'))")
|
||||
->orderBy('grade desc, type, `order`')
|
||||
->get();
|
||||
$stmt = $this->dbh->query($query);
|
||||
if($branch == 0)$productTree = $this->getFullTree($stmt, 'task', $projectModules);
|
||||
if($branch != 0)$branchTrees[] = array('name' => $branchName, 'root' => $id, 'type' => 'branch', 'actions' => false, 'children' => $this->getFullTree($stmt, 'task', $projectModules));
|
||||
}
|
||||
$productTree[] = array('name' => $this->lang->product->branchName[$productInfo->type], 'root' => $id, 'type' => 'branch', 'actions' => false, 'children' => $branchTrees);
|
||||
$fullTrees[] = array('name' => $productInfo->name, 'root' => $id, 'type' => 'product', 'actions' => false, 'children' => $productTree);
|
||||
}
|
||||
return $tree;
|
||||
|
||||
/* Get project module. */
|
||||
$query = $this->dao->select('*')->from(TABLE_MODULE)->where("root = $rootID and type = 'task'")->orderBy('grade desc, type, `order`')->get();
|
||||
$stmt = $this->dbh->query($query);
|
||||
$taskTrees = $this->getFullTree($stmt, 'task', $projectModules);
|
||||
foreach($taskTrees as $taskModule) $fullTrees[] = $taskModule;
|
||||
return $fullTrees;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1464,14 +1484,19 @@ class treeModel extends model
|
||||
$fullTrees = array();
|
||||
if(isset($branches[0]))
|
||||
{
|
||||
$fullTrees = $this->getFullTree($rootID, $viewType, 0, $currentModuleID);
|
||||
$stmt = $this->dbh->query($this->buildMenuQuery($rootID, $viewType, $currentModuleID, 'null'));
|
||||
$fullTrees = $this->getFullTree($stmt, $viewType);
|
||||
unset($branches[0]);
|
||||
}
|
||||
if($branches)
|
||||
{
|
||||
$branchTrees = array();
|
||||
foreach($branches as $branchID => $branch) $branchTrees[] = array('name' => $branch, 'type' => 'branch', 'actions' => false, 'children' => $this->getFullTree($rootID, $viewType, $branchID, $currentModuleID));
|
||||
$fullTrees[] = array('name' => $this->lang->product->branchName[$product->type], 'type' => 'branch', 'actions' => false, 'children' => $branchTrees);
|
||||
foreach($branches as $branchID => $branch)
|
||||
{
|
||||
$stmt = $this->dbh->query($this->buildMenuQuery($rootID, $viewType, $currentModuleID, $branchID));
|
||||
$branchTrees[] = array('name' => $branch, 'root' => $rootID, 'type' => 'branch', 'actions' => false, 'children' => $this->getFullTree($stmt, $viewType));
|
||||
}
|
||||
$fullTrees[] = array('name' => $this->lang->product->branchName[$product->type], 'root' => $rootID, 'type' => 'branch', 'actions' => false, 'children' => $branchTrees);
|
||||
}
|
||||
return $fullTrees;
|
||||
}
|
||||
@@ -1485,17 +1510,32 @@ class treeModel extends model
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getFullTree($rootID, $viewType, $branch = 0, $currentModuleID = 0)
|
||||
public function getFullTree($stmt, $viewType, $keepModules = array())
|
||||
{
|
||||
$tree = array_values($this->getSons($rootID, $currentModuleID, $viewType, $branch));
|
||||
if($tree)
|
||||
$parent = array();
|
||||
while($module = $stmt->fetch())
|
||||
{
|
||||
foreach($tree as $node)
|
||||
/* Ignore useless module for task. */
|
||||
if($keepModules and !isset($keepModules[$module->id])) continue;
|
||||
if(isset($parent[$module->id]))
|
||||
{
|
||||
$children = $this->getFullTree($rootID, $viewType, $branch, $node->id);
|
||||
if($children) $node->children = $children;
|
||||
$module->children = $parent[$module->id]->children;
|
||||
unset($parent[$module->id]);
|
||||
}
|
||||
if(!isset($parent[$module->parent])) $parent[$module->parent] = new stdclass();
|
||||
$parent[$module->parent]->children[] = $module;
|
||||
}
|
||||
|
||||
if($viewType == 'task') $parentTypePairs = $this->dao->select('*')->from(TABLE_MODULE)->where('id')->in(array_keys($parent))->fetchPairs('id', 'type');
|
||||
$tree = array();
|
||||
foreach($parent as $module)
|
||||
{
|
||||
foreach($module->children as $children)
|
||||
{
|
||||
if($viewType == 'task' and isset($parentTypePairs[$children->parent]) and $parentTypePairs[$children->parent] != 'task') continue;
|
||||
$tree[] = $children;
|
||||
}
|
||||
}
|
||||
return $tree;
|
||||
return $tree;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user