From 760b816acde790e25b7a670cb2877342826efb15 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 31 Mar 2022 11:02:27 +0800 Subject: [PATCH 01/50] * Fix bug #14928. --- module/story/control.php | 15 ++++++++++----- module/story/model.php | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/module/story/control.php b/module/story/control.php index 8a5e3f18eb..d82522d498 100644 --- a/module/story/control.php +++ b/module/story/control.php @@ -2329,9 +2329,10 @@ class story extends control } } - /* Get users, products and executions. */ - $users = $this->loadModel('user')->getPairs('noletter'); - $products = $this->product->getPairs('nocode'); + /* Get users, products and relations. */ + $users = $this->loadModel('user')->getPairs('noletter'); + $products = $this->product->getPairs('nocode'); + $relations = $this->story->getStoryRelationByIDs($storyIdList, $type); /* Get related objects id lists. */ $relatedProductIdList = array(); @@ -2347,6 +2348,8 @@ class story extends control $relatedBranchIdList[$story->branch] = $story->branch; $relatedStoryIDs[$story->id] = $story->id; + if(isset($relations[$story->id])) $story->linkStories = $story->linkStories . ',' . $relations[$story->id]; + /* Process related stories. */ $relatedStories = $story->childStories . ',' . $story->linkStories . ',' . $story->duplicateStory; $relatedStories = explode(',', $relatedStories); @@ -2363,7 +2366,7 @@ class story extends control /* Get related objects title or names. */ $productsType = $this->dao->select('id, type')->from(TABLE_PRODUCT)->where('id')->in($relatedProductIdList)->fetchPairs(); $relatedPlans = $this->dao->select('id, title')->from(TABLE_PRODUCTPLAN)->where('id')->in(join(',', $relatedPlanIdList))->fetchPairs(); - $relatedStories = $this->dao->select('id,title')->from(TABLE_STORY) ->where('id')->in($relatedStoryIdList)->fetchPairs(); + $relatedStories = $this->dao->select('id,title')->from(TABLE_STORY)->where('id')->in($relatedStoryIdList)->fetchPairs(); $relatedFiles = $this->dao->select('id, objectID, pathname, title')->from(TABLE_FILE)->where('objectType')->eq('story')->andWhere('objectID')->in($storyIdList)->andWhere('extra')->ne('editor')->fetchGroup('objectID'); $relatedSpecs = $this->dao->select('*')->from(TABLE_STORYSPEC)->where('`story`')->in($storyIdList)->orderBy('version desc')->fetchGroup('story'); $relatedBranch = array('0' => $this->lang->branch->main) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs(); @@ -2432,10 +2435,12 @@ class story extends control if($story->linkStories) { - $tmpLinkStories = array(); + $tmpLinkStories = array(); $linkStoriesIdList = explode(',', $story->linkStories); foreach($linkStoriesIdList as $linkStoryID) { + if(empty($linkStoryID)) continue; + $linkStoryID = trim($linkStoryID); $tmpLinkStories[] = isset($relatedStories[$linkStoryID]) ? $relatedStories[$linkStoryID] : $linkStoryID; } diff --git a/module/story/model.php b/module/story/model.php index eab6a9657c..b1733f8b60 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -4388,6 +4388,30 @@ class storyModel extends model return $story; } + /** + * Get story relation by IDs. + * + * @param array $storyIdList + * @param string $storyType + * @access public + * @return array + */ + public function getStoryRelationByIDs($storyIdList, $storyType) + { + $conditionField = $storyType == 'story' ? 'BID' : 'AID'; + $storyType = $storyType == 'story' ? 'BID, GROUP_CONCAT(`AID` SEPARATOR ",")' : 'AID, GROUP_CONCAT(`BID` SEPARATOR ",")'; + + $relations = $this->dao->select($storyType)->from(TABLE_RELATION) + ->where('AType')->eq('requirement') + ->andWhere('BType')->eq('story') + ->andWhere('relation')->eq('subdivideinto') + ->andWhere($conditionField)->in($storyIdList) + ->groupBy($conditionField) + ->fetchPairs(); + + return $relations; + } + /** * Link a story. * From 77caa6c8c5bef85e932deb0aee7e7ac210c7ac7f Mon Sep 17 00:00:00 2001 From: liyuchun Date: Thu, 31 Mar 2022 13:43:35 +0800 Subject: [PATCH 02/50] * Fix bug #13324. --- module/misc/lang/en.php | 9 --------- module/misc/lang/zh-cn.php | 2 -- 2 files changed, 11 deletions(-) diff --git a/module/misc/lang/en.php b/module/misc/lang/en.php index f215b3e610..6e426afc9a 100644 --- a/module/misc/lang/en.php +++ b/module/misc/lang/en.php @@ -28,27 +28,18 @@ $lang->misc->zentao->icons['service'] = 'heart'; $lang->misc->zentao->about['bizversion'] = 'ZenTao Biz'; $lang->misc->zentao->about['official'] = "Official Website"; -$lang->misc->zentao->about['changelog'] = "Change Log"; $lang->misc->zentao->about['license'] = "License"; - - $lang->misc->zentao->support['vip'] = "VIP Support"; $lang->misc->zentao->support['manual'] = "User Manual"; - - - - $lang->misc->zentao->cowin['reportbug'] = "Report Bug "; $lang->misc->zentao->cowin['feedback'] = "Feedback"; $lang->misc->zentao->cowin['translate'] = "Translate"; $lang->misc->zentao->cowin['recommend'] = "More"; - $lang->misc->zentao->service['idc'] = 'ZenTao Cloud'; $lang->misc->zentao->service['custom'] = 'ZenTao Custom'; -$lang->misc->zentao->service['servicemore']= 'More'; global $config; $lang->misc->zentao->others['chanzhi'] = " Zsite"; diff --git a/module/misc/lang/zh-cn.php b/module/misc/lang/zh-cn.php index 7fdcc84c52..48c663e480 100644 --- a/module/misc/lang/zh-cn.php +++ b/module/misc/lang/zh-cn.php @@ -42,13 +42,11 @@ $lang->misc->zentao->support['qqgroup'] = "官方QQ群"; $lang->misc->zentao->cowin['reportbug'] = "汇报Bug"; $lang->misc->zentao->cowin['feedback'] = "反馈需求"; -$lang->misc->zentao->cowin['translate'] = "参与翻译"; $lang->misc->zentao->cowin['recommend'] = "推荐给朋友"; $lang->misc->zentao->service['zentaotrain']= '禅道使用培训'; $lang->misc->zentao->service['idc'] = '禅道在线托管'; $lang->misc->zentao->service['custom'] = '禅道定制开发'; -$lang->misc->zentao->service['servicemore']= '更多服务...'; global $config; $lang->misc->zentao->others['chanzhi'] = " 蝉知门户"; From 2fcabdfc3f89fd3be3f5350c6f6aa02284fdeef7 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 31 Mar 2022 17:08:28 +0800 Subject: [PATCH 03/50] * Modify api function for createLink. --- framework/api/helper.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/api/helper.class.php b/framework/api/helper.class.php index 393952e38d..e14d9edc95 100644 --- a/framework/api/helper.class.php +++ b/framework/api/helper.class.php @@ -153,16 +153,16 @@ class helper extends baseHelper * @access public * @return string */ - static public function createLink($moduleName, $methodName = 'index', $vars = '', $viewType = '', $onlyBody = false) + static public function createLink($moduleName, $methodName = 'index', $vars = '', $viewType = 'json', $onlyBody = false) { global $config; - $link = parent::createLink($moduleName, $methodName, $vars, 'html'); + $link = parent::createLink($moduleName, $methodName, $vars, $viewType); $pos = strpos($link, '.php'); /* The requestTypes are: GET, PATH_INFO2, PATH_INFO */ if($config->requestType == 'GET') { - $link = '/index' . substr($link, $pos); + $link = $config->webRoot . 'index' . substr($link, $pos); } elseif($config->requestType == 'PATH_INFO2') { From f171cbf39d00679faa2836acd955407fd5f6a3c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B9=BF=E6=98=8E?= Date: Fri, 1 Apr 2022 10:00:52 +0800 Subject: [PATCH 04/50] * Add program test. --- test/class/program.class.php | 340 +------------------------ test/model/program/create.php | 1 + test/model/program/getprogresslist.php | 12 +- test/model/program/gettoppairs.php | 12 +- test/model/program/gettreemenu.php | 17 ++ test/model/program/update.php | 48 +++- 6 files changed, 73 insertions(+), 357 deletions(-) create mode 100644 test/model/program/gettreemenu.php diff --git a/test/class/program.class.php b/test/class/program.class.php index c80d39ce51..df8ed413c6 100644 --- a/test/class/program.class.php +++ b/test/class/program.class.php @@ -12,7 +12,6 @@ class programTest { global $tester; - su('admin'); $this->program = $tester->loadModel('program'); } @@ -51,35 +50,6 @@ class programTest return $this->program->getStakeholdersByPrograms($programID); } - /** - * getBudgetLeft - * - * @param int mixed $programID - * @access public - * @return void - */ - public function getBudgetLeft($programID) - { - $program = $this->program->getById(1); - - return $this->program->getBudgetLeft($program); - } - - /** - * getBudgetUnitList - * - * @access public - * @return void - */ - public function getBudgetUnitList() - { - global $app; - $app->loadConfig('project'); - $app->loadLang('project'); - - return $this->program->getBudgetUnitList(); - } - /** * getById * @@ -119,25 +89,6 @@ class programTest } } - /** - * Test get pairs by list. - * - * @param string|array $programIDList - * @access public - * @return void - */ - public function getPairsByList($programIDList = '') - { - if(empty($this->program->getPairsByList($programIDList))) - { - return array('code' => '404', 'message' => 'Not Found'); - } - else - { - return $this->program->getPairsByList($programIDList); - } - } - /** * Test get list. * @@ -156,228 +107,6 @@ class programTest } - /** - * getParentPairs - * - * @access public - * @return void - */ - public function getParentPairs() - { - return $this->program->getParentPairs(); - } - - /** - * getParentPM - * - * @param array mixed $programIdList - * @access public - * @return void - */ - public function getParentPM($programIdList) - { - return $this->program->getParentPM($programIdList); - } - - /** - * getProductPairsByID - * - * @param int $programID - * @access public - * @return void - */ - public function getProductPairsByID($programID = 0) - { - $program = $this->program->getByID($programID); - if(empty($program)) return array('message' => 'Not Found'); - return $this->program->getProductPairs($programID, 'assign', 'all'); - } - - /** - * getProductPairsByMod - * - * @param string $mode - * @access public - * @return void - */ - public function getProductPairsByMod($mode = 'assign') - { - return $this->program->getProductPairs(1, $mode, 'noclosed'); - } - - /** - * getProductPairsByStatus - * - * @param string $status - * @access public - * @return void - */ - public function getProductPairsByStatus($status = 'all') - { - return $this->program->getProductPairs(1, 'assign', $status); - } - - /** - * getProgressList - * - * @access public - * @return void - */ - public function getProgressList() - { - return $this->program->getProgressList(); - } - - /** - * getStatsByProgramID - * - * @param int $programID - * @access public - * @return void - */ - public function getStatsByProgramID($programID = 0) - { - return count($this->program->getProjectStats($programID)); - } - - /** - * getStatsByStatus - * - * @param string $browseType - * @access public - * @return void - */ - public function getStatsByStatus($browseType = 'all') - { - $projects = $this->program->getProjectStats('0', $browseType); - - if(!$projects) return 0; - foreach($projects as $project) - { - if($project->status != $browseType and $browseType != 'all' and $browseType != 'undone') return 0; - if($browseType == 'undone' and ($project->status != ('wait' or 'doing'))) return 0; - } - - return count($projects); - } - - /** - * getStatsByOrder - * - * @param string $orderBy - * @access public - * @return void - */ - public function getStatsByOrder($orderBy = 'id_desc') - { - $projects = $this->program->getProjectStats('0', 'all', '0', $orderBy); - - return checkOrder($projects, $orderBy); - } - - /** - * getStatsAddProgramTitle - * - * @param int $programTitle - * @access public - * @return void - */ - public function getStatsAddProgramTitle($programTitle = 0) - { - return $this->program->getProjectStats('0', 'all', '0', 'id_desc', '', $programTitle); - } - - /** - * getStatsByInvolved - * - * @param int $involved - * @param string $count - * @access public - * @return void - */ - public function getStatsByInvolved($involved = 0, $count = '') - { - $projects = $this->program->getProjectStats('0', 'all', '0', 'id_desc', '', '0', $involved); - - if($count == 'count') return count($projects); - return $projects; - } - - /** - * getByPrograms - * - * @param int $programIdList - * @access public - * @return void - */ - public function getByPrograms($programIdList = 0) - { - $stakeHolders = $this->program->getStakeholdersByPrograms($programIdList); - - return $stakeHolders; - } - - /** - * getByOrder - * - * @param string $orderBy - * @access public - * @return void - */ - public function getByOrder($orderBy = 'id_desc') - { - $stakeholders = $this->program->getStakeholders(2, $orderBy); - - return checkOrder($stakeholders, $orderBy); - } - - /** - * getTopPairs - * - * @param string $count - * @access public - * @return void - */ - public function getTopPairs($count = '') - { - if($count == 'count') return count($this->program->getTopPairs()); - return $this->program->getTopPairs(); - } - - /** - * getUnfinished - * - * @param mixed $programID - * @access public - * @return void - */ - public function getUnfinished($programID) - { - $program = $this->program->getById($programID); - - return $this->program->hasUnfinished($program); - } - - /** - * setTreePath - * - * @param mixed $programID - * @access public - * @return void - */ - public function setTreePath($programID) - { - $programPath = $this->program->setTreePath($programID); - if($programPath) - { - return $this->program->getById($programID); - } - else - { - return 0; - } - } - /** * update * @@ -388,75 +117,10 @@ class programTest */ public function update($programID, $data) { - global $app; - $_POST = $data; - $result = $this->program->update(10); + $this->program->update($programID); if(dao::isError()) return array('message' => dao::getError()); - $app->dbh->query("UPDATE " . TABLE_PROGRAM . " SET name = '" . $result[0]['old']. "' where id = '" . $programID . "'"); - return $result; + return $this->program->getByID($programID); } - - /** - * updateProgram - * - * @param mixed $programID - * @param int $status - * @access public - * @return void - */ - public function updateProgram($programID, $status = 0) - { - $data = array( - 'parent' => '0', - 'name' => '测试更新项目集十', - 'begin' => '2020-10-10', - 'end' => '2020-10-11', - 'acl' => 'private', - 'budget' => '100', - 'budgetUnit' => 'CNY', - 'whitelist' => array('dev10', 'dev12') - ); - - switch($status) - { - case '1': // 项目集名称已经存在时 - $data['name'] = '项目集1'; - break; - case '2': // 当计划开始为空时更新项目集信息 - $data['begin'] = ''; - break; - case '3': // 当计划完成为空时更新项目集信息 - $data['end'] = ''; - break; - case '4': // 当计划完成小于计划开始时 - $data['end'] = '2020-01-01'; - break; - case '5': // 项目集开始时间小于父项目集时 - $data['parent'] = '9'; - $data['begin'] = '2019-01-01'; - break; - default: // 更新id为10的项目集信息 - } - return $this->update($programID, $data); - } - - /** - * Test process node method. - * - * @param int $programID - * @param int $parentID - * @param string $oldPath - * @param int $oldGrade - * @access public - * @return void - */ - public function processNode($programID, $parentID, $oldPath, $oldGrade) - { - $programs = $this->program->processNode($programID, $parentID, $oldPath, $oldGrade); - return $programs; - } - } -?> diff --git a/test/model/program/create.php b/test/model/program/create.php index f6a8015851..2482bf3a23 100755 --- a/test/model/program/create.php +++ b/test/model/program/create.php @@ -2,6 +2,7 @@ loadModel('program'); +$progressList = $tester->program->getProgressList(); -r($getItemsets->getCount3()) && p() && e('100'); // 获取项目和项目集的个数 -r($getItemsets->getProgressList()) && p('1') && e('0'); // 获取id=1的项目的进度 -r($getItemsets->getProgressList()) && p('11') && e('45'); // 获取id=11的项目集的进度 \ No newline at end of file +r(count($progressList)) && p() && e('120'); // 获取项目和项目集的个数 +r($progressList) && p('1') && e('41'); // 获取id=1的项目的进度 +r($progressList) && p('11') && e('45'); // 获取id=11的项目集的进度 diff --git a/test/model/program/gettoppairs.php b/test/model/program/gettoppairs.php index 58a674e8cb..30add3b6f9 100755 --- a/test/model/program/gettoppairs.php +++ b/test/model/program/gettoppairs.php @@ -1,7 +1,7 @@ #!/usr/bin/env php loadModel('program'); -$t_checkId = 'count'; - -r($program->getTopPairs()) && p('1') && e('项目集1'); // 查看id=1的父项目集 -r($program->getTopPairs($t_checkId)) && p() && e('6'); // 查看父项目集的个数 \ No newline at end of file +r(count($tester->program->getTopPairs())) && p() && e('10'); // 获取系统中所有顶级项目集数量 +r(count($tester->program->getTopPairs('', 'noclosed'))) && p() && e('10'); // 获取系统中所有未关闭的顶级项目集数量 +r(count($tester->program->getTopPairs('', '', true))) && p() && e('10'); // 获取系统中所有顶级项目集数量 diff --git a/test/model/program/gettreemenu.php b/test/model/program/gettreemenu.php new file mode 100644 index 0000000000..efd0c0f9ba --- /dev/null +++ b/test/model/program/gettreemenu.php @@ -0,0 +1,17 @@ +#!/usr/bin/env php +loadModel('program'); +$programs1 = $tester->program->getTreeMenu(1); + +r(strlen($programs1)) && p() && e('789'); // 查看返回的字符个数 diff --git a/test/model/program/update.php b/test/model/program/update.php index 660a4b04e5..a81e60f420 100755 --- a/test/model/program/update.php +++ b/test/model/program/update.php @@ -2,6 +2,7 @@ updateProgram(10)) && p('message:end') && e('测试更新项目集十'); // 更新id为10的项目集信息 -r($t->updateProgram(10, 2)) && p('message[begin]:0') && e('『计划开始』不能为空。'); //当计划开始为空时更新项目集信息 -r($t->updateProgram(10, 3)) && p('message[end]:0') && e('『计划完成』不能为空。'); //当计划完成为空时更新项目集信息 -r($t->updateProgram(10, 4)) && p('message[end]:0') && e('『计划完成』应当大于『2020-10-10』。'); //当计划完成小于计划开始时 -r($t->updateProgram(10, 1)) && p('message[name]:0') && e('『项目集名称』已经有『项目集1』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); //项目集名称已经存在时 -r($t->updateProgram(10, 5)) && p('message:begin;message:end') && e('父项目集的开始日期:2019-09-09,开始日期不能小于父项目集的开始日期;父项目集的完成日期:2019-09-09,完成日期不能大于父项目集的完成日期');// 项目集开始时间小于父项目集时 -system("./ztest init"); \ No newline at end of file +$data = array( + 'parent' => '0', + 'name' => '测试更新项目集十', + 'begin' => '2020-10-10', + 'end' => '2022-06-01', + 'acl' => 'private', + 'budget' => '100', + 'budgetUnit' => 'CNY', + 'syncPRJUnit' => true, + 'exchangeRate' => '', + 'whitelist' => array('dev10', 'dev12') +); + +$normalProgram = $data; + +$emptyTitleProgram = $data; +$emptyTitleProgram['name'] = '项目集1'; + +$emptyBeginProgram = $data; +$emptyBeginProgram['begin'] = ''; + +$emptyEndProgram = $data; +$emptyEndProgram['end'] = ''; + +$beginGtEndProgram = $data; +$beginGtEndProgram['begin'] = '2022-07-01'; + +$beginLtParentProgram = $data; +$beginLtParentProgram['parent'] = '9'; +$beginLtParentProgram['begin'] = '2019-01-01'; + +r($program->update(10, $normalProgram)) && p('name') && e('测试更新项目集十'); // 正常更新项目集的情况 +r($program->update(10, $emptyTitleProgram)) && p('message[name]:0') && e('『项目集名称』已经有『项目集1』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 更新项目集名称重复时 +r($program->update(10, $emptyBeginProgram)) && p('message[begin]:0') && e('『计划开始』不能为空。'); // 当计划完成为空时更新项目集信息 +r($program->update(10, $emptyEndProgram)) && p('message:end') && e('子项目的最大完成日期:2022-05-27,父项目的完成日期不能小于子项目的最大完成日期'); //当计划完成小于计划开始时 +r($program->update(10, $beginGtEndProgram)) && p('message:begin') && e('子项目集的最小开始日期:2022-02-01,父项目集的开始日期不能大于子项目集的最小开始日期'); // 父项目集的开始日期大于子项目集的开始日期时 +r($program->update(10, $beginLtParentProgram)) && p('message:begin;message:end') && e('父项目集的开始日期:2022-02-09,开始日期不能小于父项目集的开始日期;父项目集的完成日期:2022-04-16,完成日期不能大于父项目集的完成日期'); // 项目集开始、结束日期和子项目不符的情况 +system("./ztest init"); From 4240b563c91707dd47397aa6d0a66f437e30978f Mon Sep 17 00:00:00 2001 From: liyuchun Date: Fri, 1 Apr 2022 10:27:27 +0800 Subject: [PATCH 05/50] * Fix bug #21061. --- module/todo/control.php | 6 ++++++ module/todo/view/view.html.php | 4 ---- module/user/view/todo.html.php | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/module/todo/control.php b/module/todo/control.php index 902196ed9a..4badd94c1f 100644 --- a/module/todo/control.php +++ b/module/todo/control.php @@ -375,6 +375,12 @@ class todo extends control if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'message' => '404 Not found')); return print(js::error($this->lang->notFound) . js::locate('back')); } + + if($todo->private and $todo->account != $this->app->user->account) + { + return print(js::error($this->lang->todo->thisIsPrivate) . js::locate('back')); + } + /* Save the session. */ if(!isonlybody()) { diff --git a/module/todo/view/view.html.php b/module/todo/view/view.html.php index 185a5daf75..f7540d8330 100644 --- a/module/todo/view/view.html.php +++ b/module/todo/view/view.html.php @@ -13,7 +13,6 @@ systemMode);?> -private or ($todo->private and $todo->account == $app->user->account)):?>