* code for task #47149.

This commit is contained in:
王怡栋
2022-01-13 09:03:35 +08:00
parent 2adc0f0d1c
commit 37d1c0e9e6
13 changed files with 933 additions and 12 deletions
+2
View File
@@ -1 +1,3 @@
ALTER TABLE `zt_project` ADD `vision` varchar(10) NOT NULL DEFAULT 'common' AFTER `order`;
ALTER TABLE `zt_product` ADD `vision` varchar(10) NOT NULL DEFAULT 'common' AFTER `order`;
ALTER TABLE `zt_doclib` ADD `vision` varchar(10) NOT NULL DEFAULT 'common' AFTER `order`;
@@ -7,7 +7,6 @@ $lang->mainNav->menuOrder[35] = 'doc';
$lang->mainNav->menuOrder[45] = 'system';
$lang->mainNav->menuOrder[65] = 'admin';
/* My menu. */
$lang->my->menu = new stdclass();
$lang->my->menu->index = array('link' => "$lang->dashboard|my|index");
@@ -50,3 +49,6 @@ $lang->scrum->menu->settings['subMenu'] = new stdclass();
$lang->scrum->menu->settings['subMenu']->view = array('link' => "$lang->overview|project|view|project=%s", 'alias' => 'edit');
$lang->scrum->menu->settings['subMenu']->members = array('link' => "{$lang->team->common}|project|team|project=%s", 'alias' => 'managemembers,team');
$lang->scrum->menu->settings['subMenu']->whitelist = array('link' => "{$lang->whitelist}|project|whitelist|project=%s", 'subModule' => 'personnel');
$lang->URCommon = '目标';
$lang->SRCommon = '目标';
@@ -0,0 +1,187 @@
<?php
class product extends control
{
public function browse($productID = 0, $branch = '', $browseType = '', $param = 0, $storyType = 'story', $orderBy = '', $recTotal = 0, $recPerPage = 20, $pageID = 1, $projectID = 0)
{
/* Load datatable and execution. */
$this->loadModel('datatable');
$this->loadModel('execution');
$this->loadModel('user');
$projectProducts = $this->loadModel('product')->getProducts($projectID);
$productPlans = $this->execution->getPlans($projectProducts);
$this->products = array();
foreach($projectProducts as $productID => $product) $this->products[$productID] = $product->name;
$productID = key($projectProducts);
$product = $projectProducts[$productID];
$showBranch = $this->loadModel('branch')->showBranch($productID, 0, $projectID);
if(!empty($product)) $this->session->set('currentProductType', $product->type);
/* Set menu. */
$this->session->set('storyList', $this->app->getURI(true), 'project');
$this->loadModel('project')->setMenu($projectID);
$branches = $this->loadModel('branch')->getList($productID, $projectID, 'all');
$branch = ($this->cookie->preBranch !== '' and $branch === '' and isset($branches[$this->cookie->preBranch])) ? $this->cookie->preBranch : $branch;
$branchID = $branch;
/* Lower browse type. */
$browseType = strtolower($browseType);
/* Set product, module and query. */
setcookie('preProductID', $productID, $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true);
setcookie('preBranch', $branch, $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true);
if($this->cookie->preProductID != $productID or $this->cookie->preBranch != $branch)
{
$_COOKIE['storyModule'] = 0;
setcookie('storyModule', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, false);
}
if($browseType == 'bymodule' or $browseType == '')
{
setcookie('storyModule', (int)$param, 0, $this->config->webRoot, '', $this->config->cookieSecure, false);
if($this->app->tab == 'project') setcookie('storyModuleParam', (int)$param, 0, $this->config->webRoot, '', $this->config->cookieSecure, false);
$_COOKIE['storyBranch'] = 'all';
setcookie('storyBranch', 'all', 0, $this->config->webRoot, '', $this->config->cookieSecure, false);
if($browseType == '') setcookie('treeBranch', $branch, 0, $this->config->webRoot, '', $this->config->cookieSecure, false);
}
$cookieModule = $this->app->tab == 'project' ? $this->cookie->storyModuleParam : $this->cookie->storyModule;
$moduleID = ($browseType == 'bymodule') ? (int)$param : (($browseType == 'bysearch') ? 0 : ($cookieModule ? $cookieModule : 0));
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
/* Set moduleTree. */
$createModuleLink = $storyType == 'story' ? 'createStoryLink' : 'createRequirementLink';
if($browseType == '')
{
setcookie('treeBranch', $branch, 0, $this->config->webRoot, '', $this->config->cookieSecure, false);
$browseType = 'unclosed';
}
else
{
$branch = $this->cookie->treeBranch;
}
/* If in project story and not chose product, get project story mdoules. */
$moduleTree = $this->loadModel('tree')->getTreeMenu($productID, 'story', $startModuleID = 0, array('treeModel', $createModuleLink), array('projectID' => $projectID, 'productID' => $productID), 'all', "&param=$param&storyType=$storyType");
if($browseType != 'bymodule') $this->session->set('storyBrowseType', $browseType);
/* Process the order by field. */
if(!$orderBy) $orderBy = $this->cookie->productStoryOrder ? $this->cookie->productStoryOrder : 'id_desc';
setcookie('productStoryOrder', $orderBy, 0, $this->config->webRoot, '', $this->config->cookieSecure, true);
/* Append id for secend sort. */
$sort = common::appendOrder($orderBy);
/* Load pager. */
$this->app->loadClass('pager', $static = true);
if($this->app->getViewType() == 'xhtml') $recPerPage = 10;
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Display of branch label. */
$showBranch = $this->loadModel('branch')->showBranch($productID);
$product = $this->product->getById($productID);
/* Get stories. */
$stories = $this->product->getStories($productID, $branchID, $browseType, $queryID, $moduleID, $storyType, $sort, $pager);
/* Display status of branch. */
$branchOption = array();
$branchTagOption = array();
foreach($branches as $branchInfo)
{
$branchOption[$branchInfo->id] = $branchInfo->name;
$branchTagOption[$branchInfo->id] = $branchInfo->name . ($branchInfo->status == 'closed' ? ' (' . $this->lang->branch->statusList['closed'] . ')' : '');
}
/* Process the sql, get the conditon partion, save it to session. */
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'story', ($browseType != 'bysearch' and $browseType != 'reviewbyme' and $this->app->rawModule != 'projectstory'));
if(!empty($stories)) $stories = $this->loadModel('story')->mergeReviewer($stories);
/* Get related tasks, bugs, cases count of each story. */
$storyIdList = array();
foreach($stories as $story)
{
$storyIdList[$story->id] = $story->id;
if(!empty($story->children))
{
foreach($story->children as $child) $storyIdList[$child->id] = $child->id;
}
}
$storyTasks = $this->loadModel('task')->getStoryTaskCounts($storyIdList);
$storyBugs = $this->loadModel('bug')->getStoryBugCounts($storyIdList);
$storyCases = $this->loadModel('testcase')->getStoryCaseCounts($storyIdList);
/* Change for requirement story title. */
if($storyType == 'requirement')
{
$this->lang->story->title = str_replace($this->lang->SRCommon, $this->lang->URCommon, $this->lang->story->title);
$this->lang->story->create = str_replace($this->lang->SRCommon, $this->lang->URCommon, $this->lang->story->create);
$this->config->product->search['fields']['title'] = $this->lang->story->title;
unset($this->config->product->search['fields']['plan']);
unset($this->config->product->search['fields']['stage']);
}
/* Build search form. */
$rawModule = $this->app->rawModule;
$rawMethod = $this->app->rawMethod;
$params = $rawModule == 'projectstory' ? "projectID=$projectID&" : '';
$actionURL = $this->createLink($rawModule, $rawMethod, $params . "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID&storyType=$storyType");
$this->config->product->search['onMenuBar'] = 'yes';
$this->product->buildSearchForm($productID, $this->products, $queryID, $actionURL, $branch);
$showModule = !empty($this->config->datatable->productBrowse->showModule) ? $this->config->datatable->productBrowse->showModule : '';
$productName = ($this->app->rawModule == 'projectstory' and empty($productID)) ? $this->lang->product->all : $this->products[$productID];
/* Assign. */
$this->view->title = $productName . $this->lang->colon . $this->lang->product->browse;
$this->view->position[] = $productName;
$this->view->position[] = $this->lang->product->browse;
$this->view->productID = $productID;
$this->view->product = $product;
$this->view->productName = $productName;
$this->view->moduleID = $moduleID;
$this->view->stories = $stories;
$this->view->plans = $this->loadModel('productplan')->getPairs($productID, $branch === 'all' ? '' : $branch, '', true);
$this->view->productPlans = isset($productPlans) ? array(0 => '') + $productPlans : array();
$this->view->summary = $this->product->summary($stories, $storyType);
$this->view->moduleTree = $moduleTree;
$this->view->parentModules = $this->tree->getParents($moduleID);
$this->view->pager = $pager;
$this->view->users = $this->user->getPairs('noletter|pofirst|nodeleted');
$this->view->orderBy = $orderBy;
$this->view->browseType = $browseType;
$this->view->modules = $this->tree->getOptionMenu($productID, 'story', 0, $branchID);
$this->view->moduleID = $moduleID;
$this->view->moduleName = ($moduleID and $moduleID !== 'all') ? $this->tree->getById($moduleID)->name : $this->lang->tree->all;
$this->view->branch = $branch;
$this->view->branchID = $branchID;
$this->view->branchOption = $branchOption;
$this->view->branchTagOption = $branchTagOption;
$this->view->showBranch = $showBranch;
$this->view->storyStages = $this->product->batchGetStoryStage($stories);
$this->view->setModule = true;
$this->view->storyTasks = $storyTasks;
$this->view->storyBugs = $storyBugs;
$this->view->storyCases = $storyCases;
$this->view->param = $param;
$this->view->projectID = $projectID;
$this->view->products = $this->products;
$this->view->projectProducts = isset($projectProducts) ? $projectProducts : array();
$this->view->storyType = $storyType;
$this->view->from = $this->app->tab;
$this->view->modulePairs = $showModule ? $this->tree->getModulePairs($productID, 'story', $showModule) : array();
$this->display();
}
}
@@ -0,0 +1,700 @@
<?php
/**
* The browse view file of product module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package product
* @version $Id: browse.html.php 4909 2013-06-26 07:23:50Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
?>
<?php
if(empty($productID))
{
$productID = key($projectProducts);
$product = $projectProducts[$productID];
$productName = $product->name;
}
?>
<?php include $this->app->getModuleRoot() . '/common/view/header.html.php';?>
<?php include $this->app->getModuleRoot() . '/common/view/datatable.fix.html.php';?>
<style>
body {margin-bottom: 25px;}
#mainMenu .btn-toolbar .btn-group .dropdown-menu .btn-active-text:hover .text {color: #fff;}
#mainMenu .btn-toolbar .btn-group .dropdown-menu .btn-active-text:hover .text:after {border-bottom: unset;}
.body-modal #mainMenu>.btn-toolbar {width: auto;}
</style>
<?php js::set('browseType', $browseType);?>
<?php js::set('productID', $productID);?>
<?php js::set('projectID', $projectID);?>
<?php js::set('branch', $branch);?>
<?php js::set('rawModule', $this->app->rawModule);?>
<?php js::set('productType', $this->app->tab == 'product' ? $product->type : '');?>
<?php
$unfoldStories = isset($config->product->browse->unfoldStories) ? json_decode($config->product->browse->unfoldStories, true) : array();
$unfoldStories = zget($unfoldStories, $productID, array());
js::set('unfoldStories', $unfoldStories);
js::set('unfoldAll', $lang->execution->treeLevel['all']);
js::set('foldAll', $lang->execution->treeLevel['root']);
js::set('storyType', $storyType);
$lang->story->createCommon = $storyType == 'story' ? $lang->story->createStory : $lang->story->createRequirement;
$isProjectStory = $this->app->rawModule == 'projectstory';
$projectIDParam = $isProjectStory ? "projectID=$projectID&" : '';
?>
<style>
.btn-group .icon-close:before {font-size: 5px; vertical-align: 25%;}
.btn-group a i.icon-plus, .btn-group a i.icon-link {font-size: 16px;}
.btn-group a.btn-secondary, .btn-group a.btn-primary {border-right: 1px solid rgba(255,255,255,0.2);}
.btn-group button.dropdown-toggle.btn-secondary, .btn-group button.dropdown-toggle.btn-primary {padding:6px;}
</style>
<div id="mainMenu" class="clearfix">
<?php if(!$isProjectStory):?>
<div id="sidebarHeader">
<div class="title" title="<?php echo $moduleName;?>">
<?php
echo $moduleName;
if($moduleID and $moduleID !== 'all')
{
$removeLink = $browseType == 'bymodule' ? $this->createLink($this->app->rawModule, $this->app->rawMethod, $projectIDParam . "productID=$productID&branch=$branch&browseType=$browseType&param=0&storyType=$storyType&orderBy=$orderBy&recTotal=0&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("storyModule")';
echo html::a($removeLink, "<i class='icon icon-sm icon-close'></i>", '', "class='text-muted'");
}
?>
</div>
</div>
<?php endif;?>
<div class="btn-toolbar pull-left">
<?php if($isProjectStory): ?>
<div class="btn-group">
<a href="javascript:;" class="btn btn-link" style="padding-right: 0;"> <?php echo $moduleName;?> </a>
<?php
if($moduleID)
{
$removeLink = $browseType == 'bymodule' ? $this->createLink($this->app->rawModule, $this->app->rawMethod, $projectIDParam . "productID=$productID&branch=$branch&browseType=$browseType&param=0&storyType=$storyType&orderBy=$orderBy&recTotal=0&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("storyModuleParam")';
echo html::a($removeLink, "<i class='icon icon-sm icon-close'></i>", '', "class='text-muted btn btn-link' style='padding-left: 0;'");
}
?>
</div>
<?php endif;?>
<?php
if(!commonModel::isTutorialMode())
{
foreach(customModel::getFeatureMenu($this->app->rawModule, $this->app->rawMethod) as $menuItem)
{
if(isset($menuItem->hidden)) continue;
if($menuItem->name == 'emptysr' && $storyType == 'story') continue;
$menuBrowseType = strpos($menuItem->name, 'QUERY') === 0 ? 'bySearch' : $menuItem->name;
if($menuItem->name == 'more')
{
if(!empty($lang->product->moreSelects))
{
$moreLabel = $lang->more;
$moreLabelActive = '';
$storyBrowseType = $this->session->storyBrowseType;
if(isset($lang->product->moreSelects[$storyBrowseType]))
{
$moreLabel = "<span class='text'>{$lang->product->moreSelects[$storyBrowseType]}</span> <span class='label label-light label-badge'>{$pager->recTotal}</span>";
$moreLabelActive = 'btn-active-text';
}
echo '<div class="btn-group" id="more">';
echo html::a('javascript:;', $moreLabel . " <span class='caret'></span>", '', "data-toggle='dropdown' class='btn btn-link $moreLabelActive'");
echo "<ul class='dropdown-menu'>";
foreach($lang->product->moreSelects as $key => $value)
{
$active = $key == $storyBrowseType ? 'btn-active-text' : '';
echo '<li>' . html::a($this->createLink($this->app->rawModule, $this->app->rawMethod, $projectIDParam . "productID=$productID&branch=$branch&browseType=$key&param=0&storyType=$storyType"), "<span class='text'>{$value}</span>", '', "class='btn btn-link $active'") . '</li>';
}
echo '</ul></div>';
}
}
elseif($menuItem->name == 'QUERY')
{
$searchBrowseLink = $this->createLink($this->app->rawModule, $this->app->rawMethod, $projectIDParam . "productID=$productID&branch=$branch&browseType=$menuBrowseType&param=%s&storyType=$storyType");
$isBySearch = $this->session->storyBrowseType == 'bysearch';
include $this->app->getModuleRoot() . '/common/view/querymenu.html.php';
}
else
{
$menuItemName = strtolower($menuItem->name);
echo html::a($this->createLink($this->app->rawModule, $this->app->rawMethod, $projectIDParam . "productID=$productID&branch=$branch&browseType=$menuBrowseType&param=0&storyType=$storyType"), "<span class='text'>$menuItem->text</span>" . ($menuItemName == $this->session->storyBrowseType ? ' <span class="label label-light label-badge">' . $pager->recTotal . '</span>' : ''), '', "id='{$menuItem->name}Tab' class='btn btn-link" . ($this->session->storyBrowseType == $menuItemName ? ' btn-active-text' : '') . "'");
}
}
}
?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->product->searchStory;?></a>
</div>
<?php if(!isonlybody()):?>
<div class="btn-toolbar pull-right">
<?php if($this->app->rawModule != 'projectstory') common::printIcon('story', 'report', "productID=$productID&branchID=$branch&storyType=$storyType&browseType=$browseType&moduleID=$moduleID&chartType=pie", '', 'button', 'bar-chart muted'); ?>
<div class="btn-group">
<button class="btn pull-right btn-link" data-toggle="dropdown"><i class="icon icon-export muted"></i> <span class="text"><?php echo $lang->export ?></span> <span class="caret"></span></button>
<ul class="dropdown-menu" id='exportActionMenu'>
<?php
$tab = $isProjectStory ? 'project' : 'product';
$class = common::hasPriv('story', 'export') ? '' : "class=disabled";
$misc = common::hasPriv('story', 'export') ? "data-toggle='modal' data-type='iframe' class='export' data-app='$tab'" : "class=disabled";
$link = common::hasPriv('story', 'export') ? $this->createLink('story', 'export', "productID=$productID&orderBy=$orderBy&projectID=0&browseType=$browseType&type=$storyType") : '#';
echo "<li $class>" . html::a($link, $lang->story->export, '', $misc) . "</li>";
?>
</ul>
</div>
<?php if(common::canModify('product', $product)):?>
<div class='btn-group dropdown'>
<?php
$createStoryLink = $this->createLink('story', 'create', "product=$productID&branch=$branch&moduleID=$moduleID&storyID=0&projectID=$projectID&bugID=0&planID=0&todoID=0&extra=&type=$storyType");
$batchCreateLink = $this->createLink('story', 'batchCreate', "productID=$productID&branch=$branch&moduleID=$moduleID&storyID=0&project=$projectID&plan=0&type=$storyType");
$buttonLink = '';
$buttonTitle = '';
$buttonType = $from == 'project' ? 'btn-secondary' : 'btn-primary';
if(common::hasPriv('story', 'batchCreate'))
{
$buttonLink = empty($productID) ? '' : $batchCreateLink;
$buttonTitle = $lang->story->batchCreate;
}
if(common::hasPriv('story', 'create'))
{
$buttonLink = $createStoryLink;
$buttonTitle = $lang->story->create;
}
$hidden = empty($buttonLink) ? 'hidden' : '';
echo html::a($buttonLink, "<i class='icon icon-plus'></i> $buttonTitle", '', "class='btn $buttonType $hidden create-story-btn' data-app='$tab'");
?>
<?php if(!empty($productID) and common::hasPriv('story', 'batchCreate') and common::hasPriv('story', 'create')): ?>
<button type='button' class="btn <?php echo $buttonType?> dropdown-toggle" data-toggle='dropdown'><span class='caret'></span></button>
<ul class='dropdown-menu pull-right'>
<li>
<?php
if(commonModel::isTutorialMode())
{
$wizardParams = helper::safe64Encode("productID=$productID&branch=$branch&moduleID=$moduleID");
if($isProjectStory) $wizardParams = helper::safe64Encode("productID=$productID&branch=$branch&moduleID=$moduleID&storyID=&projectID=$projectID");
$link = $this->createLink('tutorial', 'wizard', "module=story&method=create&params=$wizardParams");
echo html::a($link, $lang->story->createCommon, '', "data-app='$tab'");
}
else
{
echo html::a($createStoryLink, $lang->story->create, '', "data-group='$tab'");
}
?>
</li>
<li><?php echo html::a($batchCreateLink, $lang->story->batchCreate, '', "data-group='$tab'");?></li>
</ul>
<?php endif;?>
</div>
<?php endif;?>
</div>
<?php endif;?>
</div>
<?php if($this->app->getViewType() == 'xhtml'):?>
<div id="xx-title">
<strong>
<?php echo $this->product->getByID($productID)->name ?>
</strong>
<div class="linkButton" onclick="handleLinkButtonClick()">
<span title="<?php echo $lang->viewDetails;?>">
<i class="icon icon-import icon-rotate-270"></i>
</span>
</div>
</div>
<?php endif;?>
<div id="mainContent" class="main-row fade">
<div class="side-col" id="sidebar">
<div class="sidebar-toggle"><i class="icon icon-angle-left"></i></div>
<div class="cell">
<?php if(!$moduleTree):?>
<hr class="space">
<div class="text-center text-muted">
<?php echo $lang->product->noModule;?>
</div>
<hr class="space">
<?php endif;?>
<?php echo $moduleTree;?>
<div class="text-center">
<?php if($productID) common::printLink('tree', 'browse', "rootID=$productID&view=story&currentModuleID=0&branch=$branchID", $lang->tree->manage, '', "class='btn btn-info btn-wide'");?>
<hr class="space-sm" />
</div>
</div>
</div>
<div class="main-col">
<div class="cell<?php if($browseType == 'bysearch') echo ' show';?>" id="queryBox" data-module='story'></div>
<?php if(empty($stories)):?>
<div class="table-empty-tip">
<p>
<span class="text-muted"><?php echo $storyType == 'story' ? $lang->story->noStory : $lang->story->noRequirement;?></span>
<?php if(common::canModify('product', $product) and common::hasPriv('story', 'create')):?>
<?php echo html::a($this->createLink('story', 'create', "productID={$productID}&branch={$branch}&moduleID={$moduleID}&storyID=0&projectID=$projectID&bugID=0&planID=0&todoID=0&extra=&type=$storyType"), "<i class='icon icon-plus'></i> " . $lang->story->createCommon, '', "class='btn btn-info' data-app='$from'");?>
<?php endif;?>
</p>
</div>
<?php else:?>
<form class="main-table table-story skip-iframe-modal" method="post" id='productStoryForm'>
<div class="table-header fixed-right">
<nav class="btn-toolbar pull-right"></nav>
</div>
<?php
$datatableId = $this->moduleName . ucfirst($this->methodName);
$useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable');
$vars = "productID=$productID&branch=$branch&browseType=$browseType&param=$param&storyType=$storyType&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";
if($from == 'project') $vars = "projectID=$projectID&productID=$productID&branch=$branch&browseType=$browseType&param=$param&storyType=$storyType&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";
if($useDatatable) $this->app->getModuleRoot() . '/common/view/datatable.html.php';
$setting = $this->datatable->getSetting('product');
$widths = $this->datatable->setFixedFieldWidth($setting);
$columns = 0;
$canBeChanged = common::canModify('product', $product);
$canBatchEdit = ($canBeChanged and common::hasPriv('story', 'batchEdit'));
$canBatchClose = (common::hasPriv('story', 'batchClose') and strtolower($browseType) != 'closedbyme' and strtolower($browseType) != 'closedstory');
$canBatchReview = ($canBeChanged and common::hasPriv('story', 'batchReview'));
$canBatchChangeStage = ($canBeChanged and common::hasPriv('story', 'batchChangeStage'));
$canBatchChangeBranch = ($canBeChanged and common::hasPriv('story', 'batchChangeBranch'));
$canBatchChangeModule = ($canBeChanged and common::hasPriv('story', 'batchChangeModule'));
$canBatchChangePlan = ($canBeChanged and common::hasPriv('story', 'batchChangePlan'));
$canBatchAssignTo = ($canBeChanged and common::hasPriv('story', 'batchAssignTo'));
$canBatchUnlink = ($canBeChanged and $this->app->tab == 'project' and common::hasPriv('projectstory', 'batchUnlinkStory'));
$canBatchImportToLib = ($canBeChanged and $this->app->tab == 'project' and isset($this->config->maxVersion) and common::hasPriv('story', 'batchImportToLib'));
$canBatchAction = ($canBatchEdit or $canBatchClose or $canBatchReview or $canBatchChangeStage or $canBatchChangeModule or $canBatchChangePlan or $canBatchAssignTo or $canBatchUnlink or $canBatchImportToLib);
?>
<?php if(!$useDatatable) echo '<div class="table-responsive">';?>
<table class='table has-sort-head<?php if($useDatatable) echo ' datatable';?>' id='storyList' data-fixed-left-width='<?php echo $widths['leftWidth']?>' data-fixed-right-width='<?php echo $widths['rightWidth']?>'>
<thead>
<tr>
<?php if($this->app->getViewType() == 'xhtml'):?>
<?php
foreach($setting as $key => $value)
{
if($value->id == 'title' || $value->id == 'id' || $value->id == 'pri' || $value->id == 'status')
{
if($storyType == 'requirement' and (in_array($value->id, array('plan', 'stage')))) $value->show = false;
if($value->show)
{
$this->datatable->printHead($value, $orderBy, $vars, $canBatchAction);
$columns ++;
}
}
}?>
<?php else:?>
<?php
foreach($setting as $key => $value)
{
if($storyType == 'requirement' and (in_array($value->id, array('plan', 'stage')))) $value->show = false;
if($value->show)
{
$this->datatable->printHead($value, $orderBy, $vars, $canBatchAction);
$columns ++;
}
}
?>
<?php endif;?>
</tr>
</thead>
<tbody>
<?php foreach($stories as $story):?>
<tr data-id='<?php echo $story->id?>' data-estimate='<?php echo $story->estimate?>' data-cases='<?php echo zget($storyCases, $story->id, 0);?>'>
<?php $story->from = $from;?>
<?php if($this->app->getViewType() == 'xhtml'):?>
<?php
foreach($setting as $key => $value)
{
if($value->id == 'title' || $value->id == 'id' || $value->id == 'pri' || $value->id == 'status')
{
$this->story->printCell($value, $story, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table');
}
}?>
<?php else:?>
<?php foreach($setting as $key => $value) $this->story->printCell($value, $story, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table');?>
<?php endif;?>
</tr>
<?php if(!empty($story->children)):?>
<?php $i = 0;?>
<?php foreach($story->children as $key => $child):?>
<?php $child->from = $from;?>
<?php $class = $i == 0 ? ' table-child-top' : '';?>
<?php $class .= ($i + 1 == count($story->children)) ? ' table-child-bottom' : '';?>
<tr class='table-children<?php echo $class;?> parent-<?php echo $story->id;?>' data-id='<?php echo $child->id?>' data-status='<?php echo $child->status?>' data-estimate='<?php echo $child->estimate?>'>
<?php if($this->app->getViewType() == 'xhtml'):?>
<?php
foreach($setting as $key => $value)
{
if($value->id == 'title' || $value->id == 'id' || $value->id == 'pri' || $value->id == 'status')
{
$this->story->printCell($value, $child, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', $storyType);
}
}?>
<?php else:?>
<?php foreach($setting as $key => $value) $this->story->printCell($value, $child, $users, $branchOption, $storyStages, $modulePairs, $storyTasks, $storyBugs, $storyCases, $useDatatable ? 'datatable' : 'table', $storyType);?>
<?php endif;?>
</tr>
<?php $i ++;?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
</tbody>
</table>
<?php if(!$useDatatable) echo '</div>';?>
<div class="table-footer">
<?php if($canBatchAction):?>
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<?php endif;?>
<div class="table-actions btn-toolbar">
<div class='btn-group dropup'>
<?php
$disabled = $canBatchEdit ? '' : "disabled='disabled'";
$actionLink = $this->createLink('story', 'batchEdit', "productID=$productID&projectID=$projectID&branch=$branch&storyType=$storyType");
?>
<?php echo html::commonButton($lang->edit, "data-form-action='$actionLink' $disabled");?>
<button type='button' class='btn dropdown-toggle' data-toggle='dropdown'><span class='caret'></span></button>
<ul class='dropdown-menu'>
<?php
$class = $canBatchClose ? '' : "class='disabled'";
$actionLink = $this->createLink('story', 'batchClose', "productID=$productID&projectID=0&storyType=$storyType");
$misc = $canBatchClose ? "onclick=\"setFormAction('$actionLink', '', '#productStoryForm')\"" : '';
echo "<li $class>" . html::a('#', $lang->close, '', $misc) . "</li>";
$class = $canBatchUnlink ? '' : "class='disabled'";
echo "<li $class>" . html::a('#', $lang->story->unlink, '', "id='batchUnlinkStory'") . "</li>";
if($canBatchReview)
{
echo "<li class='dropdown-submenu'>";
echo html::a('javascript:;', $lang->story->review, '', "id='reviewItem'");
echo "<ul class='dropdown-menu'>";
unset($lang->story->reviewResultList['']);
unset($lang->story->reviewResultList['revert']);
foreach($lang->story->reviewResultList as $key => $result)
{
$actionLink = $this->createLink('story', 'batchReview', "result=$key");
if($key == 'reject')
{
echo "<li class='dropdown-submenu'>";
echo html::a('#', $result, '', "id='rejectItem'");
echo "<ul class='dropdown-menu'>";
unset($lang->story->reasonList['']);
unset($lang->story->reasonList['subdivided']);
unset($lang->story->reasonList['duplicate']);
foreach($lang->story->reasonList as $key => $reason)
{
$actionLink = $this->createLink('story', 'batchReview', "result=reject&reason=$key");
echo "<li>";
echo html::a('#', $reason, '', "onclick=\"setFormAction('$actionLink', 'hiddenwin', '#productStoryForm')\"");
echo "</li>";
}
echo '</ul></li>';
}
else
{
echo '<li>' . html::a('#', $result, '', "onclick=\"setFormAction('$actionLink', 'hiddenwin', '#productStoryForm')\"") . '</li>';
}
}
echo '</ul></li>';
}
else
{
$class= "class='disabled'";
echo "<li $class>" . html::a('javascript:;', $lang->story->review, '', $class) . '</li>';
}
if($canBatchChangeBranch and $this->session->currentProductType and $this->session->currentProductType != 'normal' and $productID)
{
$withSearch = count($branchTagOption) > 8;
echo "<li class='dropdown-submenu'>";
echo html::a('javascript:;', $lang->product->branchName[$this->session->currentProductType], '', "id='branchItem'");
echo "<div class='dropdown-menu" . ($withSearch ? ' with-search':'') . "'>";
echo "<ul class='dropdown-list'>";
foreach($branchTagOption as $id => $branchName)
{
$actionLink = $this->createLink('story', 'batchChangeBranch', "branchID=$id");
echo "<li class='option' data-key='$id'>" . html::a('#', $branchName, '', "onclick=\"setFormAction('$actionLink', 'hiddenwin', '#productStoryForm')\"") . "</li>";
}
echo '</ul>';
if($withSearch) echo "<div class='menu-search'><div class='input-group input-group-sm'><input type='text' class='form-control' placeholder=''><span class='input-group-addon'><i class='icon-search'></i></span></div></div>";
echo '</div></li>';
}
if($storyType == 'story')
{
if($canBatchChangeStage)
{
echo "<li class='dropdown-submenu'>";
echo html::a('javascript:;', $lang->story->stageAB, '', "id='stageItem'");
echo "<ul class='dropdown-menu'>";
foreach($lang->story->stageList as $key => $stage)
{
if(empty($key)) continue;
if(strpos('tested|verified|released|closed', $key) === false) continue;
$actionLink = $this->createLink('story', 'batchChangeStage', "stage=$key");
echo "<li>" . html::a('#', $stage, '', "onclick=\"setFormAction('$actionLink', 'hiddenwin', '#productStoryForm')\"") . "</li>";
}
echo '</ul></li>';
}
else
{
$class= "class='disabled'";
echo "<li $class>" . html::a('javascript:;', $lang->story->stageAB, '', $class) . '</li>';
}
}
?>
</ul>
</div>
<?php $isShowModuleBTN = ($this->app->tab == 'project' and $browseType != 'bybranch') ? false : true;?>
<?php if($canBatchChangeModule and $productID and $branchID !== 'all' and $isShowModuleBTN):?>
<div class="btn-group dropup">
<button data-toggle="dropdown" type="button" class="btn"><?php echo $lang->story->moduleAB;?> <span class="caret"></span></button>
<?php $withSearch = count($modules) > 8;?>
<div class="dropdown-menu search-list<?php if($withSearch) echo ' search-box-sink';?>" data-ride="searchList">
<?php if($withSearch):?>
<div class="input-control search-box has-icon-left has-icon-right search-example">
<input id="moduleSearchBox" type="search" autocomplete="off" class="form-control search-input">
<label for="moduleSearchBox" class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label>
<a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a>
</div>
<?php $modulesPinYin = common::convert2Pinyin($modules);
?>
<?php endif;?>
<div class="list-group">
<?php
foreach($modules as $moduleId => $module)
{
$searchKey = $withSearch ? ('data-key="' . zget($modulesPinYin, $module, '') . '"') : '';
$actionLink = $this->createLink('story', 'batchChangeModule', "moduleID=$moduleId");
echo html::a('#', empty($module) ? '/' : $module, '', "$searchKey onclick=\"setFormAction('$actionLink', 'hiddenwin', '#productStoryForm')\"");
}
?>
</div>
</div>
</div>
<?php endif;?>
<?php if($canBatchChangePlan and $storyType == 'story'):?>
<div class="btn-group dropup">
<button data-toggle="dropdown" type="button" class="btn"><?php echo $lang->story->planAB;?> <span class="caret"></span></button>
<?php
unset($plans['']);
$plans = array(0 => $lang->null) + $plans;
$withSearch = count($plans) > 8;
?>
<div class="dropdown-menu search-list<?php if($withSearch) echo ' search-box-sink';?>" data-ride="searchList">
<?php if($withSearch):?>
<div class="input-control search-box has-icon-left has-icon-right search-example">
<input id="planSearchBox" type="search" autocomplete="off" class="form-control search-input">
<label for="planSearchBox" class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label>
<a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a>
</div>
<?php $plansPinYin = common::convert2Pinyin($plans);?>
<?php endif;?>
<div class="list-group">
<?php
foreach($plans as $planID => $plan)
{
$position = stripos($plan, '/');
$planLabel = $position === false ? $plan : ('<span class="label label-outline label-badge">' . substr($plan, 0, $position) . '</span>' . substr($plan, $position + 1));
$searchKey = $withSearch ? ('data-key="' . zget($plansPinYin, $plan, '') . '"') : '';
$actionLink = $this->createLink('story', 'batchChangePlan', "planID=$planID");
echo html::a('#', $planLabel, '', "$searchKey title='{$plan}' onclick=\"setFormAction('$actionLink', 'hiddenwin', '#productStoryForm')\" onmouseover=\"setBadgeStyle(this, true);\" onmouseout=\"setBadgeStyle(this, false)\"");
}
?>
</div>
</div>
</div>
<?php endif;?>
<?php if($canBatchAssignTo):?>
<div class="btn-group dropup">
<button data-toggle="dropdown" type="button" class="btn"><?php echo $lang->story->assignedTo;?> <span class="caret"></span></button>
<?php
$withSearch = count($users) > 10;
$actionLink = $this->createLink('story', 'batchAssignTo', "productID=$productID");
echo html::select('assignedTo', $users, '', 'class="hidden"');
?>
<div class="dropdown-menu search-list<?php if($withSearch) echo ' search-box-sink';?>" data-ride="searchList">
<?php if($withSearch):?>
<?php $usersPinYin = common::convert2Pinyin($users);?>
<div class="input-control search-box has-icon-left has-icon-right search-example">
<input id="userSearchBox" type="search" autocomplete="off" class="form-control search-input">
<label for="userSearchBox" class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label>
<a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a>
</div>
<?php endif;?>
<div class="list-group">
<?php foreach ($users as $key => $value):?>
<?php
if(empty($key) or $key == 'closed') continue;
$searchKey = $withSearch ? ('data-key="' . zget($usersPinYin, $value, '') . " @$key\"") : "data-key='@$key'";
echo html::a("javascript:$(\"#assignedTo\").val(\"$key\");setFormAction(\"$actionLink\", \"hiddenwin\", \"#productStoryForm\")", $value, '', $searchKey);
?>
<?php endforeach;?>
</div>
</div>
</div>
<?php endif;?>
<?php if($canBatchImportToLib):?>
<?php echo html::a('#batchImportToLib', $lang->story->importToLib, '', 'class="btn" data-toggle="modal" id="importToLib"');?>
<?php endif;?>
</div>
<div class="table-statistic"><?php echo $summary;?></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
<?php endif;?>
</div>
</div>
<div class="modal fade" id="linkStoryByPlan">
<div class="modal-dialog mw-500px">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="icon icon-close"></i></button>
<h4 class="modal-title"><?php echo $lang->execution->linkStoryByPlan;?></h4><?php echo '(' . $lang->project->linkStoryByPlanTips . ')';?>
</div>
<div class="modal-body">
<div class='input-group'>
<?php echo html::select('plan', zget($productPlans, $productID, ''), '', "class='form-control chosen' id='plan'");?>
<span class='input-group-btn'><?php echo html::commonButton($lang->execution->linkStory, "id='toTaskButton'", 'btn btn-primary');?></span>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="batchImportToLib">
<div class="modal-dialog mw-500px">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="icon icon-close"></i></button>
<h4 class="modal-title"><?php echo $lang->story->importToLib;?></h4>
</div>
<div class="modal-body">
<form method='post' class='form-ajax' action='<?php echo $this->createLink('story', 'batchImportToLib');?>'>
<table class='table table-form'>
<tr>
<th><?php echo $lang->story->lib;?></th>
<td>
<?php echo html::select('lib', $libs, '', "class='form-control chosen' required");?>
</td>
</tr>
<?php if(!common::hasPriv('assetlib', 'approveStory') and !common::hasPriv('assetlib', 'batchApproveStory')):?>
<tr>
<th><?php echo $lang->story->approver;?></th>
<td>
<?php echo html::select('assignedTo', $approvers, '', "class='form-control chosen'");?>
</td>
</tr>
<?php endif;?>
<tr>
<td colspan='2' class='text-center'>
<?php echo html::hidden('storyIdList', '');?>
<?php echo html::submitButton($lang->import, '', 'btn btn-primary');?>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
</div>
<div class="modal fade" id="batchUnlinkStoryTip">
<div class="modal-dialog mw-700px">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="icon icon-close"></i></button>
<h4 class="modal-title"><strong><?php echo $lang->projectstory->batchUnlinkTip;?></strong></h4>
</div>
<div class="modal-body">
<table class='table'>
<thead>
<tr>
<th><?php echo $lang->story->title;?></th>
<th class='w-200px'><?php echo $lang->story->link . $lang->execution->common;?></th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan='2' class='text-center'>
<?php echo html::commonButton($lang->projectstory->confirm, 'data-dismiss="modal" id="confirmBtn"', 'btn btn-primary');?>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
<script>
var moduleID = <?php echo $moduleID?>;
var branchID = $.cookie('storyBranch');
$('#module<?php echo $moduleID;?>').closest('li').addClass('active');
$('#branch' + branchID).closest('li').addClass('active');
$(function()
{
// Update table summary text.
<?php $storyCommon = $storyType == 'requirement' ? $lang->URCommon : $lang->SRCommon;?>
var checkedSummary = '<?php echo str_replace('%storyCommon%', $storyCommon, $lang->product->checkedSummary)?>';
$('#productStoryForm').table(
{
statisticCreator: function(table)
{
var $checkedRows = table.getTable().find(table.isDataTable ? '.datatable-row-left.checked' : 'tbody>tr.checked');
var $originTable = table.isDataTable ? table.$.find('.datatable-origin') : null;
var checkedTotal = $checkedRows.length;
if(!checkedTotal) return;
var checkedEstimate = 0;
var checkedCase = 0;
$checkedRows.each(function()
{
var $row = $(this);
if ($originTable)
{
$row = $originTable.find('tbody>tr[data-id="' + $row.data('id') + '"]');
}
var data = $row.data();
checkedEstimate += data.estimate;
if(data.cases > 0) checkedCase += 1;
});
var rate = Math.round(checkedCase / checkedTotal * 10000 / 100) + '' + '%';
return checkedSummary.replace('%total%', checkedTotal)
.replace('%estimate%', checkedEstimate.toFixed(1))
.replace('%rate%', rate);
}
});
});
/**
* Set the color of the badge to white.
*
* @param object obj
* @param bool isShow
* @access public
* @return void
*/
function setBadgeStyle(obj, isShow)
{
var $label = $(obj);
if(isShow == true)
{
$label.find('.label-badge').css({"color":"#fff", "border-color":"#fff"});
}
else
{
$label.find('.label-badge').css({"color":"#838a9d", "border-color":"#838a9d"});
}
}
function handleLinkButtonClick()
{
var xxcUrl = "xxc:openInApp/zentao-integrated/" + encodeURIComponent(window.location.href.replace(/.display=card/, '').replace(/\.xhtml/, '.html'));
window.open(xxcUrl);
}
</script>
<?php include $this->app->getModuleRoot() . '/common/view/footer.html.php';?>
@@ -0,0 +1,6 @@
<?php if($this->app->rawModule == 'projectstory'):?>
<script>
$('td.c-actions .icon-projectstory-unlinkStory').parent().remove();
$('td.c-actions .icon-testcase-create').parent().remove();
</script>
<?php endif;?>
@@ -0,0 +1,4 @@
<?php
unset($lang->projectstory->featureBar['story']['changed']);
unset($lang->projectstory->featureBar['story']['linkedExecution']);
unset($lang->projectstory->featureBar['story']['unlinkedExecution']);
@@ -0,0 +1,2 @@
<?php
$lang->story->children = '子目标';
+16 -2
View File
@@ -780,8 +780,22 @@ class baseControl
* 设置公共扩展。
* set common extension.
*/
$commonActionExtFile = $actionExtPath['common'] . strtolower($methodName) . '.php';
$file2Included = file_exists($commonActionExtFile) ? $commonActionExtFile : $moduleControlFile;
$file2Included = $moduleControlFile;
$commonActionExtFile = $actionExtPath['custom'] . strtolower($methodName) . '.php';
if(file_exists($commonActionExtFile)) $file2Included = $commonActionExtFile;
if(!empty($actionExtPath['vision']))
{
$commonActionExtFile = $actionExtPath['vision'] . strtolower($methodName) . '.php';
if(file_exists($commonActionExtFile)) $file2Included = $commonActionExtFile;
}
if(!empty($actionExtPath['common']))
{
$commonActionExtFile = $actionExtPath['common'] . strtolower($methodName) . '.php';
if(file_exists($commonActionExtFile)) $file2Included = $commonActionExtFile;
}
if(!empty($actionExtPath['site']))
{
+3
View File
@@ -139,6 +139,9 @@ class router extends baseRouter
*/
public function setCommonLang()
{
if(defined('COMMONLANGSETTED')) return true;
define('COMMONLANGSETTED', true);
if(!defined('ITERATION_KEY')) define('ITERATION_KEY', 0);
if(!defined('SPRINT_KEY')) define('SPRINT_KEY', 1);
if(!defined('PRODUCT_KEY')) define('PRODUCT_KEY', 0);
+2
View File
@@ -901,6 +901,7 @@ class projectModel extends model
$lib->main = '1';
$lib->acl = $project->acl != 'program' ? $project->acl : 'custom';
$lib->users = ',' . implode(',', array_filter($authorizedUsers)) . ',';
$lib->vision = zget($project, 'vision', 'common');
$this->dao->insert(TABLE_DOCLIB)->data($lib)->exec();
$this->updateProducts($projectID);
@@ -918,6 +919,7 @@ class projectModel extends model
$product->createdDate = helper::now();
$product->status = 'normal';
$product->createdVersion = $this->config->version;
$product->vision = zget($project, 'vision', 'common');
$this->dao->insert(TABLE_PRODUCT)->data($product)->exec();
$productID = $this->dao->lastInsertId();
+1 -1
View File
@@ -398,7 +398,7 @@ class story extends control
if($storyID)
{
$story = $this->story->getById($storyID);
if($story->status != 'active' or $story->stage != 'wait' or $story->parent > 0) die(js::alert($this->lang->story->errorNotSubdivide) . js::locate('back'));
if(($story->status != 'active' or $story->stage != 'wait' or $story->parent > 0) and $this->config->vision != 'lite') die(js::alert($this->lang->story->errorNotSubdivide) . js::locate('back'));
}
if(!empty($_POST))
+2 -1
View File
@@ -3515,6 +3515,7 @@ class storyModel extends model
if($action == 'createcase') return $story->type != 'requirement';
if($action == 'batchcreate' and $story->parent > 0) return false;
if($action == 'batchcreate' and $story->type == 'requirement' and $story->status != 'closed') return $story->status != 'draft';
if($action == 'batchcreate' and $config->vision == 'lite' and ($story->status == 'active' and ($story->stage == 'wait' or $story->stage == 'projected'))) return true;
if($action == 'batchcreate' and ($story->status != 'active' or $story->stage != 'wait' or !empty($story->plan))) return false;
return true;
@@ -3943,7 +3944,7 @@ class storyModel extends model
common::printIcon('story', 'close', $vars, $story, 'list', '', '', 'iframe', true);
common::printIcon('story', 'edit', $vars . "&from=$story->from", $story, 'list', '', '', '', false, "data-group=$story->from");
if($story->type != 'requirement') common::printIcon('story', 'createCase', "productID=$story->product&branch=$story->branch&module=0&from=&param=0&$vars", $story, 'list', 'sitemap', '', '', false, "data-app='qa'");
if($this->app->rawModule != 'projectstory') common::printIcon('story', 'batchCreate', "productID=$story->product&branch=$story->branch&module=$story->module&storyID=$story->id", $story, 'list', 'split', '', '', '', '', $this->lang->story->subdivide);
if($this->app->rawModule != 'projectstory' OR $this->config->vision == 'lite') common::printIcon('story', 'batchCreate', "productID=$story->product&branch=$story->branch&module=$story->module&storyID=$story->id", $story, 'list', 'split', '', '', '', '', $this->lang->story->subdivide);
if($this->app->rawModule == 'projectstory') common::printIcon('projectstory', 'unlinkStory', "projectID={$this->session->project}&storyID=$story->id", '', 'list', 'unlink', 'hiddenwin');
}
else
+5 -7
View File
@@ -405,18 +405,16 @@ class treeModel extends model
$manage = $userFunc[1] == 'createManageLink' ? true : false;
$product = $this->loadModel('product')->getById($rootID);
$onlyGetLinked = ($projectID and $this->config->vision != 'lite');
if(strpos('story|bug|case', $type) !== false and $branch === 'all' and empty($projectID))
{
if($product->type != 'normal') $branches = array(BRANCH_MAIN => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($rootID, 'noempty');
}
elseif(($type == 'story' and $this->app->rawModule == 'projectstory') or ($type == 'case' and $this->app->tab == 'project'))
{
if($product->type != 'normal' and $projectID)
{
$branches += $this->branch->getPairs($product->id, 'noempty', $projectID);
}
$executionModules = $this->getTaskTreeModules($projectID, true, $type);
if($product->type != 'normal' and $projectID) $branches += $this->branch->getPairs($product->id, 'noempty', $projectID);
if($onlyGetLinked) $executionModules = $this->getTaskTreeModules($projectID, true, $type);
}
/* Add for task #1945. check the module has case or no. */
@@ -427,7 +425,7 @@ class treeModel extends model
$stmt = $this->dbh->query($this->buildMenuQuery($rootID, $type, $startModule, $branch));
while($module = $stmt->fetch())
{
if(!$projectID)
if(!$onlyGetLinked)
{
$this->buildTree($treeMenu, $module, $type, $userFunc, $extra, $branch);
}