From 79c1fe014a54cbe4afd7c774476296f5940347f0 Mon Sep 17 00:00:00 2001 From: liyuchun <563917701@qq.com> Date: Fri, 26 Aug 2022 08:44:28 +0800 Subject: [PATCH] * Code for task #65983. --- module/repo/control.php | 268 ++++++++++++++++++ module/repo/js/monaco.js | 13 + module/repo/lang/de.php | 5 + module/repo/lang/en.php | 5 + module/repo/lang/fr.php | 5 + module/repo/lang/vi.php | 5 + module/repo/lang/zh-cn.php | 5 + module/repo/model.php | 44 ++- .../repo/view/ajaxgeteditorcontent.html.php | 139 +++++---- module/repo/view/linkbug.html.php | 82 ++++++ module/repo/view/linkstory.html.php | 93 ++++++ module/repo/view/linktask.html.php | 82 ++++++ module/repo/view/monaco.html.php | 1 + 13 files changed, 684 insertions(+), 63 deletions(-) create mode 100644 module/repo/view/linkbug.html.php create mode 100644 module/repo/view/linkstory.html.php create mode 100644 module/repo/view/linktask.html.php diff --git a/module/repo/control.php b/module/repo/control.php index ebada71c96..875182431b 100644 --- a/module/repo/control.php +++ b/module/repo/control.php @@ -1004,6 +1004,274 @@ class repo extends control $this->display(); } + /** + * Link story to commit. + * + * @param int $repoID + * @param string $revision + * @param string $browseType + * @param int $param + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function linkStory($repoID, $revision, $browseType = '', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 100, $pageID = 1) + { + if(!empty($_POST['stories'])) + { + $this->repo->link($repoID, $revision, 'story'); + + if(dao::isError()) return print(js::error(dao::getError())); + return print(js::closeModal('parent', '', "parent[1].getRelation('$revision')")); + } + + $this->loadModel('story'); + $this->app->loadLang('productplan'); + + $repo = $this->repo->getRepoByID($repoID); + $product = $this->loadModel('product')->getById($repo->product); + $modules = $this->loadModel('tree')->getOptionMenu($repo->product, 'story'); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = new pager($recTotal, $recPerPage, $pageID); + + /* Build search form. */ + unset($this->lang->story->statusList['closed']); + $storyStatusList = $this->lang->story->statusList; + $queryID = $browseType == 'bySearch' ? (int)$param : 0; + + unset($this->config->product->search['fields']['product']); + $this->config->product->search['actionURL'] = $this->createLink('repo', 'linkStory', "repoID=$repoID&revision=$revision&browseType=bySearch&queryID=myQueryID"); + $this->config->product->search['queryID'] = $queryID; + $this->config->product->search['style'] = 'simple'; + $this->config->product->search['params']['plan']['values'] = $this->loadModel('productplan')->getForProducts(array($repo->product => $repo->product)); + $this->config->product->search['params']['module']['values'] = $modules; + $this->config->product->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $storyStatusList); + + if($product->type == 'normal') + { + unset($this->config->product->search['fields']['branch']); + unset($this->config->product->search['params']['branch']); + } + else + { + $this->config->product->search['fields']['branch'] = $this->lang->product->branch; + $this->config->product->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty'); + } + + session_start(); + $this->loadModel('search')->setSearchParams($this->config->product->search); + session_write_close(); + + $linkedStories = $this->repo->getRelationByCommit($repoID, $revision, 'story'); + if($browseType == 'bySearch') + { + $allStories = $this->story->getBySearch($product->id, 0, $queryID, 'id', '', 'story', array_keys($linkedStories), $pager); + } + else + { + $allStories = $this->story->getProductStories($product->id, 0, '0', 'draft,active,changed', 'story', 'id_desc', false, array_keys($linkedStories), $pager); + } + + $this->view->modules = $modules; + $this->view->users = $this->loadModel('user')->getPairs('noletter'); + $this->view->allStories = $allStories; + $this->view->product = $product; + $this->view->repoID = $repoID; + $this->view->revision = $revision; + $this->view->browseType = $browseType; + $this->view->param = $param; + $this->view->orderBy = $orderBy; + $this->view->pager = $pager; + $this->display(); + } + + /** + * Link bug to commit. + * + * @param int $repoID + * @param string $revision + * @param string $browseType + * @param int $param + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function linkBug($repoID, $revision = '', $browseType = '', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 100, $pageID = 1) + { + if(!empty($_POST['bugs'])) + { + $this->repo->link($repoID, $revision, 'bug'); + + if(dao::isError()) return print(js::error(dao::getError())); + return print(js::closeModal('parent', '', "parent[1].getRelation('$revision')")); + } + + $this->loadModel('bug'); + $this->app->loadLang('productplan'); + $queryID = ($browseType == 'bysearch') ? (int)$param : 0; + + $repo = $this->repo->getRepoByID($repoID); + $product = $this->loadModel('product')->getById($repo->product); + $modules = $this->loadModel('tree')->getOptionMenu($product->id, 'bug'); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = new pager($recTotal, $recPerPage, $pageID); + + /* Build search form. */ + $this->config->bug->search['actionURL'] = $this->createLink('repo', 'linkBug', "repoID=$repoID&revision=$revision&browseType=bySearch&queryID=myQueryID"); + $this->config->bug->search['queryID'] = $queryID; + $this->config->bug->search['style'] = 'simple'; + $this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getForProducts(array($product->id => $product->id)); + $this->config->bug->search['params']['module']['values'] = $modules; + $this->config->bug->search['params']['execution']['values'] = $this->product->getExecutionPairsByProduct($product->id); + $this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs($product->id, $branch = 'all', $params = ''); + $this->config->bug->search['params']['resolvedBuild']['values'] = $this->loadModel('build')->getBuildPairs($product->id, $branch = 'all', $params = ''); + + unset($this->config->bug->search['fields']['product']); + if($product->type == 'normal') + { + unset($this->config->bug->search['fields']['branch']); + unset($this->config->bug->search['params']['branch']); + } + else + { + $this->config->bug->search['fields']['branch'] = $this->lang->product->branch; + $this->config->bug->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty'); + } + session_start(); + $this->loadModel('search')->setSearchParams($this->config->bug->search); + session_write_close(); + + $linkedBugs = $this->repo->getRelationByCommit($repoID, $revision, 'bug'); + if($browseType == 'bySearch') + { + $allBugs = $this->bug->getBySearch($product->id, 0, $queryID, 'id_desc', array_keys($linkedBugs), $pager); + } + else + { + $allBugs = $this->bug->getActiveBugs($product->id, 0, '0', array_keys($linkedBugs), $pager); + } + + $this->view->modules = $modules; + $this->view->users = $this->loadModel('user')->getPairs('noletter'); + $this->view->allBugs = $allBugs; + $this->view->product = $product; + $this->view->repoID = $repoID; + $this->view->revision = $revision; + $this->view->browseType = $browseType; + $this->view->param = $param; + $this->view->orderBy = $orderBy; + $this->view->pager = $pager; + $this->display(); + } + + /** + * Link task to commit. + * + * @param int $repoID + * @param string $revision + * @param string $browseType + * @param int $param + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function linkTask($repoID, $revision = '', $browseType = 'unclosed', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 100, $pageID = 1) + { + if(!empty($_POST['tasks'])) + { + $this->repo->link($repoID, $revision, 'task'); + + if(dao::isError()) return print(js::error(dao::getError())); + return print(js::closeModal('parent', '', "parent[1].getRelation('$revision')")); + } + + $this->loadModel('execution'); + $this->loadModel('product'); + $this->app->loadLang('task'); + + /* Set browse type. */ + $browseType = strtolower($browseType); + $queryID = ($browseType == 'bysearch') ? (int)$param : 0; + + $repo = $this->repo->getRepoByID($repoID); + $product = $this->loadModel('product')->getById($repo->product); + $modules = $this->loadModel('tree')->getOptionMenu($product->id, $viewType = 'task'); + + /* Load pager. */ + $this->app->loadClass('pager', $static = true); + $pager = new pager($recTotal, $recPerPage, $pageID); + + /* Build search form. */ + $this->config->execution->search['actionURL'] = $this->createLink('repo', 'linkTask', "repoID=$repoID&revision=$revision&browseType=bySearch&queryID=myQueryID", '', true); + $this->config->execution->search['queryID'] = $queryID; + $this->config->execution->search['style'] = 'simple'; + $this->config->execution->search['params']['module']['values'] = $modules; + $this->config->execution->search['params']['execution']['values'] = $this->product->getExecutionPairsByProduct($product->id); + + /* Get executions by product. */ + $productExecutions = $this->product->getExecutionPairsByProduct($product->id); + $productExecutionIDs = array_filter(array_keys($productExecutions)); + $this->config->execution->search['params']['execution']['values'] = array_filter($productExecutions); + + session_start(); + $this->loadModel('search')->setSearchParams($this->config->execution->search); + session_write_close(); + + /* Get tasks by executions. */ + $allTasks = array(); + foreach($productExecutionIDs as $productExecutionID) + { + $tasks = $this->execution->getTasks(0, $productExecutionID, array(), $browseType, $queryID, 0, $orderBy, null); + $allTasks = array_merge($tasks, $allTasks); + } + + /* Filter linked tasks. */ + $linkedTasks = $this->repo->getRelationByCommit($repoID, $revision, 'task'); + $linkedTaskIDs = array_keys($linkedTasks); + foreach($allTasks as $key => $task) + { + if(in_array($task->id, $linkedTaskIDs)) unset($allTasks[$key]); + } + + /* Page the records. */ + $pager->setRecTotal(count($allTasks)); + $pager->setPageTotal(); + if($pager->pageID > $pager->pageTotal) $pager->setPageID($pager->pageTotal); + $count = 1; + $limitMin = ($pager->pageID - 1) * $pager->recPerPage; + $limitMax = $pager->pageID * $pager->recPerPage; + foreach($allTasks as $key => $task) + { + if($count <= $limitMin or $count > $limitMax) unset($allTasks[$key]); + $count ++; + } + + $this->view->modules = $modules; + $this->view->users = $this->loadModel('user')->getPairs('noletter'); + $this->view->allTasks = $allTasks; + $this->view->product = $product; + $this->view->repoID = $repoID; + $this->view->revision = $revision; + $this->view->browseType = $browseType; + $this->view->param = $param; + $this->view->orderBy = $orderBy; + $this->view->pager = $pager; + $this->display(); + } + /** * Ajax sync comment. * diff --git a/module/repo/js/monaco.js b/module/repo/js/monaco.js index ff3d66f057..5ed0f85e5f 100644 --- a/module/repo/js/monaco.js +++ b/module/repo/js/monaco.js @@ -132,3 +132,16 @@ $(function() } }) }); + +/** + * Load link object page. + * + * @param string $link + * @access public + * @return void + */ +function loadLinkPage(link) +{ + $('#linkObject').attr('href', link); + $('#linkObject').click() +} diff --git a/module/repo/lang/de.php b/module/repo/lang/de.php index 7630e4dcd4..fd0a325297 100644 --- a/module/repo/lang/de.php +++ b/module/repo/lang/de.php @@ -41,6 +41,8 @@ $lang->repo->downloadZip = 'Download Zip file'; $lang->repo->sshClone = 'Clone with SSH'; $lang->repo->httpClone = 'Clone with HTTP'; $lang->repo->cloneUrl = 'Clone URL'; +$lang->repo->linkTask = 'Link Task'; +$lang->repo->unlinkedTasks = 'Unlinked Tasks'; $lang->repo->submit = 'Submit'; $lang->repo->cancel = 'Cancel'; @@ -104,6 +106,9 @@ $lang->repo->job = 'Job'; $lang->repo->fileServerUrl = 'File Server Url'; $lang->repo->fileServerAccount = 'File Server Account'; $lang->repo->fileServerPassword = 'File Server Password'; +$lang->repo->linkStory = 'Link ' . $lang->SRCommon; +$lang->repo->linkBug = 'Link Bug'; +$lang->repo->linkTask = 'Link Task'; $lang->repo->title = 'Title'; $lang->repo->status = 'Status'; diff --git a/module/repo/lang/en.php b/module/repo/lang/en.php index 7eea815f38..f2af467ff2 100644 --- a/module/repo/lang/en.php +++ b/module/repo/lang/en.php @@ -41,6 +41,8 @@ $lang->repo->downloadZip = 'Download compressed package'; $lang->repo->sshClone = 'Clone with SSH'; $lang->repo->httpClone = 'Clone with HTTP'; $lang->repo->cloneUrl = 'Clone URL'; +$lang->repo->linkTask = 'Link Task'; +$lang->repo->unlinkedTasks = 'Unlinked Tasks'; $lang->repo->submit = 'Submit'; $lang->repo->cancel = 'Cancel'; @@ -104,6 +106,9 @@ $lang->repo->job = 'Job'; $lang->repo->fileServerUrl = 'File Server Url'; $lang->repo->fileServerAccount = 'File Server Account'; $lang->repo->fileServerPassword = 'File Server Password'; +$lang->repo->linkStory = 'Link ' . $lang->SRCommon; +$lang->repo->linkBug = 'Link Bug'; +$lang->repo->linkTask = 'Link Task'; $lang->repo->title = 'Title'; $lang->repo->status = 'Status'; diff --git a/module/repo/lang/fr.php b/module/repo/lang/fr.php index 32f93f5a36..88ea6832b5 100644 --- a/module/repo/lang/fr.php +++ b/module/repo/lang/fr.php @@ -41,6 +41,8 @@ $lang->repo->downloadZip = 'Download compressed package'; $lang->repo->sshClone = 'Clone with SSH'; $lang->repo->httpClone = 'Clone with HTTP'; $lang->repo->cloneUrl = 'Clone URL'; +$lang->repo->linkTask = 'Link Task'; +$lang->repo->unlinkedTasks = 'Unlinked Tasks'; $lang->repo->submit = 'Soumettre'; $lang->repo->cancel = 'Annuler'; @@ -104,6 +106,9 @@ $lang->repo->job = 'Job'; $lang->repo->fileServerUrl = 'File Server Url'; $lang->repo->fileServerAccount = 'File Server Account'; $lang->repo->fileServerPassword = 'File Server Password'; +$lang->repo->linkStory = 'Link ' . $lang->SRCommon; +$lang->repo->linkBug = 'Link Bug'; +$lang->repo->linkTask = 'Link Task'; $lang->repo->title = 'Titre'; $lang->repo->status = 'Statut'; diff --git a/module/repo/lang/vi.php b/module/repo/lang/vi.php index 81861ae77e..33e7fede17 100644 --- a/module/repo/lang/vi.php +++ b/module/repo/lang/vi.php @@ -41,6 +41,8 @@ $lang->repo->downloadZip = 'Download compressed package'; $lang->repo->sshClone = 'Clone with SSH'; $lang->repo->httpClone = 'Clone with HTTP'; $lang->repo->cloneUrl = 'Clone URL'; +$lang->repo->linkTask = 'Link Task'; +$lang->repo->unlinkedTasks = 'Unlinked Tasks'; $lang->repo->submit = 'Gửi'; $lang->repo->cancel = 'Hủy'; @@ -104,6 +106,9 @@ $lang->repo->job = 'Job'; $lang->repo->fileServerUrl = 'File Server Url'; $lang->repo->fileServerAccount = 'File Server Account'; $lang->repo->fileServerPassword = 'File Server Password'; +$lang->repo->linkStory = 'Link ' . $lang->SRCommon; +$lang->repo->linkBug = 'Link Bug'; +$lang->repo->linkTask = 'Link Task'; $lang->repo->title = 'Tiêu đề'; $lang->repo->status = 'Tình trạng'; diff --git a/module/repo/lang/zh-cn.php b/module/repo/lang/zh-cn.php index 2ac898fbb9..3e6d1e0816 100644 --- a/module/repo/lang/zh-cn.php +++ b/module/repo/lang/zh-cn.php @@ -41,6 +41,8 @@ $lang->repo->downloadZip = '下载压缩包'; $lang->repo->sshClone = '使用SSH克隆'; $lang->repo->httpClone = '使用HTTP克隆'; $lang->repo->cloneUrl = '克隆地址'; +$lang->repo->linkTask = '关联任务'; +$lang->repo->unlinkedTasks = '未关联任务'; $lang->repo->submit = '提交'; $lang->repo->cancel = '取消'; @@ -104,6 +106,9 @@ $lang->repo->job = '构建任务'; $lang->repo->fileServerUrl = '预合并后上传服务器目录'; $lang->repo->fileServerAccount = '文件服务器登录用户名'; $lang->repo->fileServerPassword = '文件服务器登录密码'; +$lang->repo->linkStory = '关联' . $lang->SRCommon; +$lang->repo->linkBug = '关联Bug'; +$lang->repo->linkTask = '关联任务'; $lang->repo->title = '标题'; $lang->repo->status = '状态'; diff --git a/module/repo/model.php b/module/repo/model.php index 4c3da8e837..ce9b51582a 100644 --- a/module/repo/model.php +++ b/module/repo/model.php @@ -313,6 +313,40 @@ class repoModel extends model return true; } + /** + * Create commit link. + * + * @param int $repoID + * @param string $revision + * @param string $type + * @access public + * @return void + */ + public function link($repoID, $revision, $type = 'story') + { + $this->loadModel('action'); + if($type == 'story') $links = $this->post->stories; + if($type == 'bug') $links = $this->post->bugs; + if($type == 'task') $links = $this->post->tasks; + + $revisionID = $this->dao->select('id')->from(TABLE_REPOHISTORY)->where('repo')->eq($repoID)->andWhere('revision')->eq($revision)->fetch('id'); + foreach($links as $linkID) + { + $relation = new stdclass; + $relation->AType = 'revision'; + $relation->AID = $revisionID; + $relation->relation = 'commit'; + $relation->BType = $type; + $relation->BID = $linkID; + + $this->dao->replace(TABLE_RELATION)->data($relation)->exec(); + + if($type == 'story') $this->action->create('story', $linkID, 'createmr'); + if($type == 'bug') $this->action->create('bug', $linkID, 'createmr'); + if($type == 'task') $this->action->create('task', $linkID, 'createmr'); + } + } + /** * Save repo state. * @@ -2593,16 +2627,18 @@ class repoModel extends model * * @param int $repoID * @param string $commit + * @param string $type story|bug|task * @access public * @return array */ - public function getRelationByCommit($repoID, $commit) + public function getRelationByCommit($repoID, $commit, $type = '') { $relationList = $this->dao->select('t1.BID as id, t1.BType as type')->from(TABLE_RELATION)->alias('t1') - ->leftJoin(TABLE_REPOHISTORY)->alias('t2') - ->on('t1.AID = t2.id') + ->leftJoin(TABLE_REPOHISTORY)->alias('t2')->on('t1.AID = t2.id') ->where('t2.revision')->eq($commit) ->andWhere('t2.repo')->eq($repoID) + ->andWhere('t1.AType')->eq('revision') + ->beginIF($type)->andWhere('t1.BType')->eq($type)->fi() ->fetchAll(); $storyIDs = array(); @@ -2630,6 +2666,8 @@ class repoModel extends model $titleList = array(); foreach($relationList as $key => $relation) { + if($type) $key = $relation->id; + $titleList[$key] = array( 'id' => $relation->id, 'type' => $relation->type, diff --git a/module/repo/view/ajaxgeteditorcontent.html.php b/module/repo/view/ajaxgeteditorcontent.html.php index 86653140fb..65f426668e 100644 --- a/module/repo/view/ajaxgeteditorcontent.html.php +++ b/module/repo/view/ajaxgeteditorcontent.html.php @@ -17,8 +17,13 @@ js::set('codeContent', trim($content)); js::set('file', $pathInfo); js::set('blames', $blames); js::set('blameTmpl', $lang->repo->blamTmpl); +js::set('repoID', $repoID); js::import($jsRoot . '/zui/tabs/tabs.min.js'); js::import($jsRoot . 'monaco-editor/min/vs/loader.js'); +$canLinkStory = common::hasPriv('repo', 'linkStory'); +$canLinkBug = common::hasPriv('repo', 'linkBug'); +$canLinkTask = common::hasPriv('repo', 'linkTask'); +$canUnlinkObject = common::hasPriv('repo', 'unlinkObject'); ?>