* Adjust code

This commit is contained in:
zenggang
2023-10-23 09:38:18 +00:00
parent d2ec248bc1
commit feeefdc819
5 changed files with 1045 additions and 764 deletions
+183 -412
View File
@@ -43,7 +43,7 @@ class repo extends control
* @access public
* @return void
*/
public function commonAction($repoID = 0, $objectID = 0)
public function commonAction(int $repoID = 0, int $objectID = 0)
{
$tab = $this->app->tab;
$this->repos = $this->repo->getRepoPairs($tab, $objectID);
@@ -74,12 +74,15 @@ class repo extends control
}
/**
* 版本库列表。
* List all repo.
*
* @param int $objectID
* @param string $orderBy
* @param int $recPerPage
* @param int $pageID
* @param string $type
* @param int $param
* @access public
* @return void
*/
@@ -88,9 +91,7 @@ class repo extends control
$repoID = $this->repo->saveState(0, $objectID);
if($this->viewType !== 'json') $this->commonAction($repoID, $objectID);
$repoList = $this->repo->getList(0, '', $orderBy, null, false, true, $type, $param);
$sonarRepoList = $this->loadModel('job')->getSonarqubeByRepo(array_keys($repoList));
$repoList = $this->repo->getList(0, '', $orderBy, null, false, true, $type, $param);
/* Pager. */
$this->app->loadClass('pager', true);
$recTotal = count($repoList);
@@ -99,23 +100,13 @@ class repo extends control
$repoList = empty($repoList) ? array() : $repoList[$pageID - 1];
/* Get success jobs of sonarqube.*/
$jobIDList = array();
foreach($repoList as $repo)
{
if(isset($sonarRepoList[$repo->id])) $jobIDList[] = $sonarRepoList[$repo->id]->id;
}
$successJobs = $this->loadModel('compile')->getSuccessJobs($jobIDList);
$sonarRepoList = $this->loadModel('job')->getSonarqubeByRepo(array_keys($repoList));
$successJobs = $this->loadModel('compile')->getSuccessJobs(helper::arrayColumn($sonarRepoList, 'id'));
$products = $this->loadModel('product')->getPairs('all', 0, '', 'all');
$projects = $this->loadModel('project')->getPairs();
session_start();
$this->config->repo->search['params']['product']['values'] = $products;
$this->config->repo->search['params']['projects']['values'] = $projects;
$this->config->repo->search['actionURL'] = $this->createLink('repo', 'maintain', "objectID={$objectID}&orderBy={$orderBy}&recPerPage={$recPerPage}&pageID={$pageID}&type=bySearch&param=myQueryID");
$this->config->repo->search['queryID'] = $param;
$this->config->repo->search['onMenuBar'] = 'yes';
$this->loadModel('search')->setSearchParams($this->config->repo->search);
$this->repoZen->buildRepoSearchForm($products, $projects, $objectID, $orderBy, $recPerPage, $pageID, $param);
$this->view->title = $this->lang->repo->common . $this->lang->colon . $this->lang->repo->browse;
$this->view->type = $type;
@@ -174,25 +165,32 @@ class repo extends control
/**
* Edit a repo.
*
* @param int $repoID
* @param int $objectID
* @param int $repoID
* @param int $objectID
* @access public
* @return void
*/
public function edit($repoID, $objectID = 0)
public function edit(int $repoID, int $objectID = 0)
{
$this->commonAction($repoID, $objectID);
$repo = $this->repo->getByID($repoID);
if($_POST)
{
$noNeedSync = $this->repo->update($repoID);
$repo = $this->repo->getByID($repoID);
/* Prepare data. */
$formData = form::data($this->config->repo->form->edit);
$isPipelineServer = in_array(strtolower($this->post->SCM), $this->config->repo->gitServiceList) ? true : false;
$editData = $this->repoZen->prepareEdit($formData, $repo, $isPipelineServer);
if($editData) $noNeedSync = $this->repo->update($editData, $repoID, $isPipelineServer);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
$newRepo = $this->repo->getByID($repoID);
$actionID = $this->loadModel('action')->create('repo', $repoID, 'edited');
$changes = common::createChanges($repo, $newRepo);
$this->action->logHistory($actionID, $changes);
if(!$noNeedSync)
{
$link = $this->repo->createLink('showSyncCommit', "repoID=$repoID");
@@ -201,41 +199,7 @@ class repo extends control
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('maintain')));
}
$this->app->loadLang('action');
$scm = strtolower($repo->SCM);
if(in_array($scm, $this->config->repo->gitServiceList))
{
$serviceID = isset($repo->gitService) ? $repo->gitService : 0;
$projects = $this->loadModel($scm)->apiGetProjects($serviceID);
$options = array();
foreach($projects as $project)
{
if($scm == 'gitlab') $options[$project->id] = $project->name_with_namespace;
if($scm == 'gitea') $options[$project->full_name] = $project->full_name;
if($scm == 'gogs') $options[$project->full_name] = $project->full_name;
}
$this->view->projects = $options;
}
$products = $this->loadModel('product')->getPairs('', 0, '', 'all');
$linkedProducts = $this->loadModel('product')->getByIdList(explode(',', $repo->product));
$linkedProductPairs = array_combine(array_keys($linkedProducts), helper::arrayColumn($linkedProducts, 'name'));
$products = $products + $linkedProductPairs;
$this->view->title = $this->lang->repo->common . $this->lang->colon . $this->lang->repo->edit;
$this->view->repo = $repo;
$this->view->repoID = $repoID;
$this->view->objectID = $objectID;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->loadModel('user')->getPairs('noletter|noempty|nodeleted|noclosed');
$this->view->products = $products;
$this->view->relatedProjects = $this->repo->filterProject(explode(',', $repo->product), explode(',', $repo->projects));
$this->view->serviceHosts = $this->loadModel('pipeline')->getPairs($repo->SCM);
$this->display();
$this->repoZen->buildEditForm($repoID, $objectID);
}
/**
@@ -247,147 +211,19 @@ class repo extends control
* @access public
* @return void
*/
public function delete($repoID, $objectID = 0, $confirm = 'no')
public function delete(int $repoID, int $objectID = 0, string $confirm = 'no')
{
if($confirm == 'no') return print(js::confirm($this->lang->repo->notice->delete, $this->repo->createLink('delete', "repoID=$repoID&objectID=$objectID&confirm=yes")));
$relationID = $this->dao->select('id')->from(TABLE_RELATION)
->where('extra')->eq($repoID)
->andWhere('AType')->eq('design')
->fetch();
$error = $relationID ? $this->lang->repo->error->deleted : '';
$jobs = $this->dao->select('*')->from(TABLE_JOB)->where('repo')->eq($repoID)->andWhere('deleted')->eq('0')->fetchAll();
if($jobs) $error .= ($error ? '\n' : '') . $this->lang->repo->error->linkedJob;
$error = $this->repoZen->checkDeleteError($repoID);
if($error) return $this->send(array('result' => 'fail', 'message' => $error));
$this->dao->delete()->from(TABLE_REPOHISTORY)->where('repo')->eq($repoID)->exec();
$this->dao->delete()->from(TABLE_REPOFILES)->where('repo')->eq($repoID)->exec();
$this->dao->delete()->from(TABLE_REPOBRANCH)->where('repo')->eq($repoID)->exec();
$this->dao->delete()->from(TABLE_REPO)->where('id')->eq($repoID)->exec();
$this->repo->deleteRepo($repoID);
if(dao::isError()) return print(js::error(dao::getError()));
$this->loadModel('action')->create('repo', $repoID, 'deleted', '');
return $this->send(array('result' => 'success', 'load' => true));
}
/**
* Get diff editor content by ajax.
*
* @param int $repoID
* @param int $objectID
* @param string $entry
* @param string $oldRevision
* @param string $newRevision
* @param string $showBug
* @param string $encoding
* @access public
* @return void
*/
public function ajaxGetDiffEditorContent($repoID, $objectID = 0, $entry = '', $oldRevision = '', $newRevision = '', $showBug = 'false', $encoding = '')
{
if(!$entry) $entry = (string) $this->cookie->repoCodePath;
$file = $entry;
$repo = $this->repo->getByID($repoID);
$entry = urldecode($this->repo->decodePath($entry));
$revision = str_replace('*', '-', $oldRevision);
$nRevision = str_replace('*', '-', $newRevision);
$entry = urldecode($entry);
$pathInfo = pathinfo($entry);
$encoding = empty($encoding) ? $repo->encoding : $encoding;
$encoding = strtolower(str_replace('_', '-', $encoding));
$this->scm->setEngine($repo);
$info = $this->scm->info($entry, $nRevision);
$this->view->title = $this->lang->repo->common . $this->lang->colon . $this->lang->repo->diff;
$this->view->type = 'diff';
$this->view->encoding = str_replace('-', '_', $encoding);
$this->view->repoID = $repoID;
$this->view->objectID = $objectID;
$this->view->repo = $repo;
$this->view->revision = $nRevision;
$this->view->oldRevision = $revision;
$this->view->file = $file;
$this->view->entry = $entry;
$this->view->info = $info;
$this->view->content = '';
$this->view->pathInfo = $pathInfo;
$this->view->suffix = 'c';
$this->view->blames = array();
$this->view->showEditor = true;
$this->display('repo', 'ajaxgeteditorcontent');
}
/**
* Get editor content by ajax.
*
* @param int $repoID
* @param int $objectID
* @param string $entry
* @param string $revision
* @param string $showBug
* @param string $encoding
* @access public
* @return void
*/
public function ajaxGetEditorContent($repoID, $objectID = 0, $entry = '', $revision = 'HEAD', $showBug = 'false', $encoding = '')
{
if(!$entry) $entry = (string) $this->cookie->repoCodePath;
$file = $entry;
$repo = $this->repo->getByID($repoID);
$entry = urldecode($this->repo->decodePath($entry));
$revision = str_replace('*', '-', $revision);
$this->scm->setEngine($repo);
$info = $this->scm->info($entry, $revision);
$path = $entry ? $info->path : '';
if($info->kind == 'dir') $this->locate($this->repo->createLink('browse', "repoID=$repoID&branchID=&objectID=$objectID&path=" . $this->repo->encodePath($path) . "&revision=$revision"));
$content = $this->scm->cat($entry, $revision);
$entry = urldecode($entry);
$pathInfo = pathinfo($entry);
$encoding = empty($encoding) ? $repo->encoding : $encoding;
$encoding = strtolower(str_replace('_', '-', $encoding));
$suffix = '';
if(isset($pathInfo["extension"])) $suffix = strtolower($pathInfo["extension"]);
if(!$suffix or (!array_key_exists($suffix, $this->config->program->suffix) and strpos($this->config->repo->images, "|$suffix|") === false)) $suffix = $this->repo->isBinary($content, $suffix) ? 'binary' : 'c';
if(strpos($this->config->repo->images, "|$suffix|") !== false)
{
$content = base64_encode($content);
}
elseif($encoding != 'utf-8')
{
$content = helper::convertEncoding($content, $encoding);
}
$this->view->title = $this->lang->repo->common . $this->lang->colon . $this->lang->repo->view;
$this->view->type = 'view';
$this->view->showBug = $showBug;
$this->view->encoding = str_replace('-', '_', $encoding);
$this->view->repoID = $repoID;
$this->view->branchID = $this->cookie->repoBranch;
$this->view->objectID = $objectID;
$this->view->repo = $repo;
$this->view->revision = $revision;
$this->view->oldRevision = '';
$this->view->file = $file;
$this->view->entry = $entry;
$this->view->path = $entry;
$this->view->info = $info;
$this->view->suffix = $suffix;
$this->view->content = $content ? $content : '';
$this->view->pathInfo = $pathInfo;
$this->view->showEditor = (strpos($this->config->repo->images, "|$suffix|") === false and $suffix != 'binary') ? true : false;
$this->display();
}
/**
* View repo file with monaco editor.
*
@@ -442,7 +278,6 @@ class repo extends control
public function view($repoID, $objectID = 0, $entry = '', $revision = 'HEAD', $showBug = 'false', $encoding = '')
{
set_time_limit(0);
$browser = helper::getBrowser();
if($this->get->repoPath) $entry = $this->get->repoPath;
$this->repo->setBackSession('view', true);
if($repoID == 0) $repoID = $this->session->repoID;
@@ -457,6 +292,8 @@ class repo extends control
session_start();
$this->session->set('storyList', inlink('view', "repoID=$repoID&objectID=$objectID&entry=$entry&revision=$revision&showBug=$showBug&encoding=$encoding"), 'product');
session_write_close();
$browser = helper::getBrowser();
if($browser['name'] != 'ie') return print($this->fetch('repo', 'monaco', "repoID=$repoID&objectID=$objectID&entry=$entry&revision=$revision&showBug=$showBug&encoding=$encoding"));
if($_POST)
@@ -560,15 +397,19 @@ class repo extends control
/* Get path. */
if($this->get->repoPath) $path = $this->get->repoPath;
$path = $this->repo->decodePath($path);
if($_POST)
{
$oldRevision = isset($this->post->revision[1]) ? $this->post->revision[1] : '';
$newRevision = isset($this->post->revision[0]) ? $this->post->revision[0] : '';
$this->locate($this->repo->createLink('diff', "repoID=$repoID&objectID=$objectID&entry=" . $this->repo->encodePath($path) . "&oldrevision=$oldRevision&newRevision=$newRevision"));
}
/* Set menu and session. */
$this->commonAction($repoID, $objectID);
$this->repo->setBackSession('list', true);
session_start();
$this->session->set('revisionList', $this->app->getURI(true));
$this->session->set('gitlabBranchList', $this->app->getURI(true));
session_write_close();
$this->repoZen->setBrowseSession();
/* Get repo and synchronous commit. */
$repo = $this->repo->getByID($repoID);
@@ -579,96 +420,40 @@ class repo extends control
}
if(!$repo->synced) $this->locate($this->repo->createLink('showSyncCommit', "repoID=$repoID&objectID=$objectID"));
if($repo->SCM == 'Gitlab') list($branchInfo, $tagInfo) = $this->repoZen->getBrowseInfo($repo);
/* Set branch or tag for git. */
$branches = $tags = $branchesAndTags = array();
if(in_array($repo->SCM, $this->config->repo->gitTypeList))
{
$scm = $this->app->loadClass('scm');
$scm->setEngine($repo);
$branches = isset($branchInfo) && $branchInfo !== false ? $branchInfo : $scm->branch();
$initTags = isset($tagInfo) && $tagInfo !== false ? $tagInfo : $scm->tags('');
foreach($initTags as $tag) $tags[$tag] = $tag;
$branchesAndTags = $branches + $tags;
if(empty($branchID) and $this->cookie->repoBranch and $this->session->repoID == $repoID) $branchID = $this->cookie->repoBranch;
if($branchID) $this->repo->setRepoBranch($branchID);
if(!isset($branchesAndTags[$branchID]))
{
$branchID = (string)key($branches);
$this->repo->setRepoBranch($branchID);
}
}
else
{
$this->repo->setRepoBranch('');
}
/* Decrypt path. */
$path = $this->repo->decodePath($path);
$branchInfo = $tagInfo = false;
if($repo->SCM == 'Gitlab') list($branchInfo, $tagInfo) = $this->repoZen->getBrowseInfo($repo);
list($branchID, $branches, $tags, $branchesAndTags) = $this->repoZen->setBranchTag($repo, $branchID, $branchInfo, $tagInfo);
/* Load pager. */
$this->app->loadClass('pager', true);
$pager = new pager($recTotal, $recPerPage, $pageID);
if($_POST)
{
$oldRevision = isset($this->post->revision[1]) ? $this->post->revision[1] : '';
$newRevision = isset($this->post->revision[0]) ? $this->post->revision[0] : '';
$this->locate($this->repo->createLink('diff', "repoID=$repoID&objectID=$objectID&entry=" . $this->repo->encodePath($path) . "&oldrevision=$oldRevision&newRevision=$newRevision"));
}
/* Refresh repo. */
if(empty($refresh) and $this->cookie->repoRefresh) $refresh = $this->cookie->repoRefresh;
if($refresh)
{
$this->repo->updateCommit($repoID, $objectID, $originBranchID);
if($repo->SCM == 'Gitlab') $this->repo->checkDeletedBranches($repoID, $branches);
}
if($this->cookie->repoRefresh) helper::setcookie('repoRefresh', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, true);
/* Set logType and revisions. */
$logType = $type;
$revisions = $this->repo->getCommits($repo, $path, $revision, $logType, $pager);
/* Get revisions. */
$revisions = $this->repoZen->getCommits($repo, $path, $revision, $type, $pager, $objectID);
$lastRevision = current($revisions);
$lastRevision = empty($lastRevision) ? new stdclass() : $lastRevision;
$pathInfo = '&root=' . $this->repo->encodePath(empty($path) ? '/' : $path);
foreach($revisions as $item)
{
$item->link = $this->repo->createLink('revision', "repoID=$repoID&objectID=$objectID&revision={$item->revision}" . $pathInfo);
$item->revision = $repo->SCM != 'Subversion' ? substr($item->revision, 0, 10) : $item->revision;
}
if($path == '') $this->repoZen->updateLastCommit($repo, $lastRevision);
/* Get files info. */
$infos = $this->repoZen->getFilesInfo($repo, $path, $branchID, $refresh, $revision, $lastRevision);
$base64BranchID = helper::safe64Encode(base64_encode($branchID));
foreach($infos as $info)
{
$infoPath = trim(urldecode($path) . '/' . $info->name, '/');
$info->revision = $repo->SCM == 'Subversion' ? $info->revision : substr($info->revision, 0, 10);
if($info->kind == 'dir')
{
$info->link = $this->repo->createLink('browse', "repoID=$repoID&branchID=$base64BranchID&objectID=$objectID&path=" . $this->repo->encodePath($infoPath));
}
else
{
$info->link = $this->repo->createLink('view', "repoID=$repoID&objectID=$objectID&entry=" . $this->repo->encodePath($infoPath));
}
}
if($this->cookie->repoRefresh) helper::setcookie('repoRefresh', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, true);
$infos = $this->repoZen->getFilesInfo($repo, $path, $branchID, $refresh, $revision, $lastRevision, $base64BranchID, $objectID);
/* Synchronous commit only in root path. */
if(in_array($repo->SCM, $this->config->repo->gitTypeList) && $repo->SCM != 'Gitlab' && empty($path) && $infos && empty($revisions)) $this->locate($this->repo->createLink('showSyncCommit', "repoID=$repoID&objectID=$objectID&branch=" . helper::safe64Encode(base64_encode($this->cookie->repoBranch))));
$this->view->title = $this->lang->repo->common;
$this->view->repo = $repo;
$this->view->repos = $this->repos;
$this->view->revisions = $revisions;
$this->view->revision = $revision;
$this->view->infos = $infos;
@@ -681,7 +466,7 @@ class repo extends control
$this->view->currentProject = $this->app->tab == 'project' ? $this->loadModel('project')->getByID($objectID) : null;
$this->view->pager = $pager;
$this->view->path = urldecode($path);
$this->view->logType = $logType;
$this->view->logType = $type;
$this->view->cloneUrl = $this->repo->getCloneUrl($repo);
$this->view->cacheTime = isset($lastRevision->time) ? date('m-d H:i', strtotime($lastRevision->time)) : date('m-d H:i');
$this->view->branchOrTag = $branchOrTag;
@@ -1094,71 +879,29 @@ class repo extends control
* @access public
* @return void
*/
public function linkStory($repoID, $revision, $browseType = '', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 10, $pageID = 1)
public function linkStory(int $repoID, string $revision, string $browseType = '', int $param = 0, string $orderBy = 'id_desc', int $recTotal = 0, int $recPerPage = 10, int $pageID = 1)
{
if(!empty($_POST['stories']))
{
$this->repo->link($repoID, $revision, 'story');
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
return $this->send(array('result' => 'success', 'callback' => "$('.tab-content .active iframe')[0].contentWindow.getRelation('$revision')", 'closeModal' => true));
}
if(!empty($_POST['stories'])) return $this->send($this->repoZen->linkObject($repoID, $revision, 'story'));
$this->loadModel('story');
$this->app->loadLang('release');
$this->app->loadModuleConfig('release');
$this->loadModel('release');
$this->app->loadLang('productplan');
$repo = $this->repo->getByID($repoID);
$product = $this->loadModel('product')->getById($repo->product);
$modules = $this->loadModel('tree')->getOptionMenu($repo->product, 'story');
$product = $this->loadModel('product')->getById((int)$repo->product);
$modules = $this->loadModel('tree')->getOptionMenu((int)$repo->product, 'story');
$queryID = $browseType == 'bySearch' ? (int)$param : 0;
/* Load pager. */
$this->app->loadClass('pager', 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($product->id => $product->id));
$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'] = $this->loadModel('branch')->getPairs($product->id, '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, $orderBy, '', 'story', array_keys($linkedStories), $pager);
}
else
{
$allStories = $this->story->getProductStories($product->id, 0, '0', 'draft,active,changed', 'story', $orderBy, false, array_keys($linkedStories), $pager);
}
$this->repoZen->buildStorySearchForm($repoID, $revision, $browseType, $queryID, $product, $modules);
$this->view->modules = $modules;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->allStories = $allStories;
$this->view->allStories = $this->repoZen->getLinkStories($repoID, $revision, $browseType, $product, $orderBy, $pager, $queryID);
$this->view->product = $product;
$this->view->repoID = $repoID;
$this->view->revision = $revision;
@@ -1183,71 +926,29 @@ class repo extends control
* @access public
* @return void
*/
public function linkBug($repoID, $revision = '', $browseType = '', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 10, $pageID = 1)
public function linkBug(int $repoID, string $revision = '', string $browseType = '', int $param = 0, string $orderBy = 'id_desc', int $recTotal = 0, int $recPerPage = 10, int $pageID = 1)
{
if(!empty($_POST['bugs']))
{
$this->repo->link($repoID, $revision, 'bug');
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
return $this->send(array('result' => 'success', 'callback' => "$('.tab-content .active iframe')[0].contentWindow.getRelation('$revision')", 'closeModal' => true));
}
if(!empty($_POST['bugs'])) return $this->send($this->repoZen->linkObject($repoID, $revision, 'bug'));
$this->loadModel('bug');
$this->app->loadLang('release');
$this->app->loadModuleConfig('release');
$this->loadModel('release');
$this->app->loadLang('productplan');
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
$repo = $this->repo->getByID($repoID);
$product = $this->loadModel('product')->getById($repo->product);
$modules = $this->loadModel('tree')->getOptionMenu($product->id, 'bug');
$product = $this->loadModel('product')->getById((int)$repo->product);
$modules = $this->loadModel('tree')->getOptionMenu((int)$product->id, 'bug');
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
/* Load pager. */
$this->app->loadClass('pager', 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, 'all', '');
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->loadModel('build')->getBuildPairs($product->id, 'all', '');
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'] = $this->loadModel('branch')->getPairs($product->id, '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, $orderBy, array_keys($linkedBugs), $pager);
}
else
{
$allBugs = $this->bug->getActiveBugs($product->id, 0, '0', array_keys($linkedBugs), $pager, $orderBy);
}
foreach($allBugs as $bug) $bug->statusText = $this->processStatus('bug', $bug);
$this->repoZen->buildBugSearchForm($repoID, $revision, $browseType, $queryID, $product, $modules);
$this->view->modules = $modules;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->allBugs = $allBugs;
$this->view->allBugs = $this->repoZen->getLinkBugs($repoID, $revision, $browseType, $product, $orderBy, $pager, $queryID);
$this->view->product = $product;
$this->view->repoID = $repoID;
$this->view->revision = $revision;
@@ -1272,16 +973,9 @@ class repo extends control
* @access public
* @return void
*/
public function linkTask($repoID, $revision = '', $browseType = 'unclosed', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 10, $pageID = 1)
public function linkTask(int $repoID, string $revision = '', string $browseType = 'unclosed', int $param = 0, string $orderBy = 'id_desc', int $recTotal = 0, int $recPerPage = 10, int $pageID = 1)
{
if(!empty($_POST['tasks']))
{
$this->repo->link($repoID, $revision, 'task');
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
return $this->send(array('result' => 'success', 'callback' => "$('.tab-content .active iframe')[0].contentWindow.getRelation('$revision')", 'closeModal' => true));
}
if(!empty($_POST['tasks'])) return $this->send($this->repoZen->linkObject($repoID, $revision, 'task'));
$this->loadModel('execution');
$this->loadModel('product');
@@ -1289,64 +983,26 @@ class repo extends control
/* Set browse type. */
$browseType = strtolower($browseType);
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
$repo = $this->repo->getByID($repoID);
$product = $this->loadModel('product')->getById($repo->product);
$modules = $this->loadModel('tree')->getOptionMenu($product->id, 'task');
$product = $this->loadModel('product')->getById((int)$repo->product);
$modules = $this->loadModel('tree')->getOptionMenu((int)$product->id, 'task');
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
/* Load pager. */
$this->app->loadClass('pager', 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 ++;
}
/* Build search form. */
$this->repoZen->buildTaskSearchForm($repoID, $revision, $browseType, $queryID, $product, $modules, $productExecutions);
$this->view->modules = $modules;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->allTasks = $allTasks;
$this->view->allTasks = $this->repoZen->getLinkTasks($repoID, $revision, $browseType, $product, $orderBy, $pager, $queryID, $productExecutionIDs);
$this->view->product = $product;
$this->view->repoID = $repoID;
$this->view->revision = $revision;
@@ -1414,6 +1070,121 @@ class repo extends control
$this->display();
}
/**
* Get diff editor content by ajax.
*
* @param int $repoID
* @param int $objectID
* @param string $entry
* @param string $oldRevision
* @param string $newRevision
* @param string $showBug
* @param string $encoding
* @access public
* @return void
*/
public function ajaxGetDiffEditorContent($repoID, $objectID = 0, $entry = '', $oldRevision = '', $newRevision = '', $showBug = 'false', $encoding = '')
{
if(!$entry) $entry = (string) $this->cookie->repoCodePath;
$file = $entry;
$repo = $this->repo->getByID($repoID);
$entry = urldecode($this->repo->decodePath($entry));
$revision = str_replace('*', '-', $oldRevision);
$nRevision = str_replace('*', '-', $newRevision);
$entry = urldecode($entry);
$pathInfo = pathinfo($entry);
$encoding = empty($encoding) ? $repo->encoding : $encoding;
$encoding = strtolower(str_replace('_', '-', $encoding));
$this->scm->setEngine($repo);
$info = $this->scm->info($entry, $nRevision);
$this->view->title = $this->lang->repo->common . $this->lang->colon . $this->lang->repo->diff;
$this->view->type = 'diff';
$this->view->encoding = str_replace('-', '_', $encoding);
$this->view->repoID = $repoID;
$this->view->objectID = $objectID;
$this->view->repo = $repo;
$this->view->revision = $nRevision;
$this->view->oldRevision = $revision;
$this->view->file = $file;
$this->view->entry = $entry;
$this->view->info = $info;
$this->view->content = '';
$this->view->pathInfo = $pathInfo;
$this->view->suffix = 'c';
$this->view->blames = array();
$this->view->showEditor = true;
$this->display('repo', 'ajaxgeteditorcontent');
}
/**
* Get editor content by ajax.
*
* @param int $repoID
* @param int $objectID
* @param string $entry
* @param string $revision
* @param string $showBug
* @param string $encoding
* @access public
* @return void
*/
public function ajaxGetEditorContent($repoID, $objectID = 0, $entry = '', $revision = 'HEAD', $showBug = 'false', $encoding = '')
{
if(!$entry) $entry = (string) $this->cookie->repoCodePath;
$file = $entry;
$repo = $this->repo->getByID($repoID);
$entry = urldecode($this->repo->decodePath($entry));
$revision = str_replace('*', '-', $revision);
$this->scm->setEngine($repo);
$info = $this->scm->info($entry, $revision);
$path = $entry ? $info->path : '';
if($info->kind == 'dir') $this->locate($this->repo->createLink('browse', "repoID=$repoID&branchID=&objectID=$objectID&path=" . $this->repo->encodePath($path) . "&revision=$revision"));
$content = $this->scm->cat($entry, $revision);
$entry = urldecode($entry);
$pathInfo = pathinfo($entry);
$encoding = empty($encoding) ? $repo->encoding : $encoding;
$encoding = strtolower(str_replace('_', '-', $encoding));
$suffix = '';
if(isset($pathInfo["extension"])) $suffix = strtolower($pathInfo["extension"]);
if(!$suffix or (!array_key_exists($suffix, $this->config->program->suffix) and strpos($this->config->repo->images, "|$suffix|") === false)) $suffix = $this->repo->isBinary($content, $suffix) ? 'binary' : 'c';
if(strpos($this->config->repo->images, "|$suffix|") !== false)
{
$content = base64_encode($content);
}
elseif($encoding != 'utf-8')
{
$content = helper::convertEncoding($content, $encoding);
}
$this->view->title = $this->lang->repo->common . $this->lang->colon . $this->lang->repo->view;
$this->view->type = 'view';
$this->view->showBug = $showBug;
$this->view->encoding = str_replace('-', '_', $encoding);
$this->view->repoID = $repoID;
$this->view->branchID = $this->cookie->repoBranch;
$this->view->objectID = $objectID;
$this->view->repo = $repo;
$this->view->revision = $revision;
$this->view->oldRevision = '';
$this->view->file = $file;
$this->view->entry = $entry;
$this->view->path = $entry;
$this->view->info = $info;
$this->view->suffix = $suffix;
$this->view->content = $content ? $content : '';
$this->view->pathInfo = $pathInfo;
$this->view->showEditor = (strpos($this->config->repo->images, "|$suffix|") === false and $suffix != 'binary') ? true : false;
$this->display();
}
/**
* Ajax sync comment.
*
+255
View File
@@ -0,0 +1,255 @@
<?php
global $lang, $app;
$app->loadLang('sonarqube');
$app->loadLang('bug');
$config->repo->dtable = new stdclass();
$config->repo->dtable->fieldList['name']['name'] = 'name';
$config->repo->dtable->fieldList['name']['title'] = $lang->repo->name;
$config->repo->dtable->fieldList['name']['type'] = 'title';
$config->repo->dtable->fieldList['name']['width'] = '0.2';
$config->repo->dtable->fieldList['product']['name'] = 'productNames';
$config->repo->dtable->fieldList['product']['title'] = $lang->repo->product;
$config->repo->dtable->fieldList['product']['type'] = 'text';
$config->repo->dtable->fieldList['product']['sortType'] = false;
$config->repo->dtable->fieldList['product']['width'] = '136';
$config->repo->dtable->fieldList['product']['hint'] = true;
$config->repo->dtable->fieldList['project']['name'] = 'projectNames';
$config->repo->dtable->fieldList['project']['title'] = $lang->repo->projects;
$config->repo->dtable->fieldList['project']['type'] = 'text';
$config->repo->dtable->fieldList['project']['sortType'] = false;
$config->repo->dtable->fieldList['project']['width'] = '136';
$config->repo->dtable->fieldList['project']['hint'] = true;
$config->repo->dtable->fieldList['scm']['name'] = 'SCM';
$config->repo->dtable->fieldList['scm']['title'] = $lang->repo->type;
$config->repo->dtable->fieldList['scm']['type'] = 'scm';
$config->repo->dtable->fieldList['scm']['sortType'] = true;
$config->repo->dtable->fieldList['scm']['map'] = $lang->repo->scmList;
$config->repo->dtable->fieldList['scm']['group'] = 1;
$config->repo->dtable->fieldList['path']['name'] = 'codePath';
$config->repo->dtable->fieldList['path']['title'] = $lang->repo->path;
$config->repo->dtable->fieldList['path']['type'] = 'text';
$config->repo->dtable->fieldList['path']['hint'] = true;
$config->repo->dtable->fieldList['path']['width'] = '260';
$config->repo->dtable->fieldList['path']['group'] = 1;
$config->repo->dtable->fieldList['lastSubmit']['name'] = 'lastSubmitTime';
$config->repo->dtable->fieldList['lastSubmit']['title'] = $lang->repo->lastSubmitTime;
$config->repo->dtable->fieldList['lastSubmit']['type'] = 'datetime';
$config->repo->dtable->fieldList['lastSubmit']['sortType'] = false;
$config->repo->dtable->fieldList['lastSubmit']['width'] = '128';
$config->repo->dtable->fieldList['job']['name'] = 'job';
$config->repo->dtable->fieldList['job']['hidden'] = true;
$config->repo->dtable->fieldList['actions']['name'] = 'actions';
$config->repo->dtable->fieldList['actions']['title'] = $lang->actions;
$config->repo->dtable->fieldList['actions']['type'] = 'actions';
$config->repo->dtable->fieldList['actions']['width'] = '132';
$config->repo->dtable->fieldList['actions']['menu'] = array('execJob', 'reportView', 'edit', 'delete');
$config->repo->dtable->fieldList['actions']['list']['edit']['icon'] = 'edit';
$config->repo->dtable->fieldList['actions']['list']['edit']['hint'] = $lang->repo->edit;
$config->repo->dtable->fieldList['actions']['list']['execJob']['icon'] = 'sonarqube';
$config->repo->dtable->fieldList['actions']['list']['execJob']['hint'] = $lang->sonarqube->execJob;
$config->repo->dtable->fieldList['actions']['list']['execJob']['url'] = array('module' => 'sonarqube', 'method' => 'execJob', 'params' => "jobID={job}");
$config->repo->dtable->fieldList['actions']['list']['execJob']['className'] = 'ajax-submit';
$config->repo->dtable->fieldList['actions']['list']['reportView']['icon'] = 'audit';
$config->repo->dtable->fieldList['actions']['list']['reportView']['hint'] = $lang->sonarqube->reportView;
$config->repo->dtable->fieldList['actions']['list']['reportView']['url'] = array('module' => 'sonarqube', 'method' => 'reportView', 'params' => "jobID={job}");
$config->repo->dtable->fieldList['actions']['list']['delete']['icon'] = 'trash';
$config->repo->dtable->fieldList['actions']['list']['delete']['hint'] = $lang->repo->delete;
$config->repo->dtable->fieldList['actions']['list']['delete']['data-confirm'] = $this->lang->repo->notice->delete;
$config->repo->dtable->fieldList['actions']['list']['delete']['className'] = 'ajax-submit';
$config->repo->repoDtable = new stdclass();
$config->repo->repoDtable->fieldList['name']['name'] = 'name';
$config->repo->repoDtable->fieldList['name']['title'] = $lang->repo->name;
$config->repo->repoDtable->fieldList['name']['minWidth'] = '160';
$config->repo->repoDtable->fieldList['name']['sortType'] = false;
$config->repo->repoDtable->fieldList['name']['type'] = 'shortTitle';
$config->repo->repoDtable->fieldList['name']['fixed'] = false;
$config->repo->repoDtable->fieldList['name']['hint'] = true;
$config->repo->repoDtable->fieldList['name']['checkbox'] = false;
$config->repo->repoDtable->fieldList['revision']['name'] = 'revision';
$config->repo->repoDtable->fieldList['revision']['title'] = $lang->repo->revisions;
$config->repo->repoDtable->fieldList['revision']['sortType'] = false;
$config->repo->repoDtable->fieldList['revision']['width'] = '90';
$config->repo->repoDtable->fieldList['revision']['hint'] = true;
$config->repo->repoDtable->fieldList['time']['name'] = 'date';
$config->repo->repoDtable->fieldList['time']['title'] = $lang->repo->time;
$config->repo->repoDtable->fieldList['time']['sortType'] = false;
$config->repo->repoDtable->fieldList['time']['type'] = 'date';
$config->repo->repoDtable->fieldList['time']['hint'] = true;
$config->repo->repoDtable->fieldList['committer']['name'] = 'account';
$config->repo->repoDtable->fieldList['committer']['title'] = $lang->repo->committer;
$config->repo->repoDtable->fieldList['committer']['sortType'] = false;
$config->repo->repoDtable->fieldList['committer']['type'] = 'user';
$config->repo->repoDtable->fieldList['committer']['hint'] = true;
$config->repo->repoDtable->fieldList['comment']['name'] = 'originalComment';
$config->repo->repoDtable->fieldList['comment']['title'] = $lang->repo->comment;
$config->repo->repoDtable->fieldList['comment']['sortType'] = false;
$config->repo->repoDtable->fieldList['comment']['type'] = 'text';
$config->repo->repoDtable->fieldList['comment']['hint'] = true;
$config->repo->commentDtable = new stdclass();
$config->repo->commentDtable->fieldList['id']['title'] = '';
$config->repo->commentDtable->fieldList['id']['name'] = '';
$config->repo->commentDtable->fieldList['id']['type'] = 'checkID';
$config->repo->commentDtable->fieldList['id']['fixed'] = false;
$config->repo->commentDtable->fieldList['id']['sortType'] = false;
$config->repo->commentDtable->fieldList['id']['checkbox'] = true;
$config->repo->commentDtable->fieldList['id']['width'] = '25';
$config->repo->commentDtable->fieldList['revision']['name'] = 'revision';
$config->repo->commentDtable->fieldList['revision']['title'] = $lang->repo->revisions;
$config->repo->commentDtable->fieldList['revision']['sortType'] = false;
$config->repo->commentDtable->fieldList['revision']['type'] = 'title';
$config->repo->commentDtable->fieldList['revision']['fixed'] = false;
$config->repo->commentDtable->fieldList['revision']['width'] = '100';
$config->repo->commentDtable->fieldList['revision']['hint'] = true;
$config->repo->commentDtable->fieldList['commit']['name'] = 'commit';
$config->repo->commentDtable->fieldList['commit']['title'] = $lang->repo->commit;
$config->repo->commentDtable->fieldList['commit']['sortType'] = false;
$config->repo->commentDtable->fieldList['commit']['width'] = '50';
$config->repo->commentDtable->fieldList ['commit']['hint'] = true;
$config->repo->commentDtable->fieldList['time'] = $config->repo->repoDtable->fieldList['time'];
$config->repo->commentDtable->fieldList['time']['name'] = 'time';
$config->repo->commentDtable->fieldList['committer'] = $config->repo->repoDtable->fieldList['committer'];
$config->repo->commentDtable->fieldList['comment'] = $config->repo->repoDtable->fieldList['comment'];
$config->repo->commentDtable->fieldList['comment']['name'] = 'originalComment';
$config->repo->commentDtable->fieldList['committer']['name'] = 'committer';
$config->repo->logDtable = new stdclass();
$config->repo->logDtable->fieldList['id']['hidden'] = true;
$config->repo->logDtable->fieldList['revision']['type'] = 'revision';
$config->repo->logDtable->fieldList['revision']['width'] = '100';
$config->repo->logDtable->fieldList['revision']['checkbox'] = true;
$config->repo->logDtable->fieldList['revision']['nestedToggle'] = false;
$config->repo->logDtable->fieldList['commit']['type'] = 'number';
$config->repo->logDtable->fieldList['commit']['width'] = '50';
$config->repo->logDtable->fieldList['commit']['sortType'] = false;
$config->repo->logDtable->fieldList['date']['name'] = 'time';
$config->repo->logDtable->fieldList['date']['type'] = 'datetime';
$config->repo->logDtable->fieldList['date']['sortType'] = false;
$config->repo->logDtable->fieldList['committer']['name'] = 'committer';
$config->repo->logDtable->fieldList['comment']['type'] = 'html';
$config->repo->logDtable->fieldList['comment']['width'] = '600';
$config->repo->blameDtable = new stdclass();
$config->repo->blameDtable->fieldList['revision']['type'] = 'revision';
$config->repo->blameDtable->fieldList['revision']['width'] = '120';
$config->repo->blameDtable->fieldList['commit']['type'] = 'number';
$config->repo->blameDtable->fieldList['commit']['sortType'] = false;
$config->repo->blameDtable->fieldList['commit']['width'] = '80';
$config->repo->blameDtable->fieldList['committer']['name'] = 'committer';
$config->repo->blameDtable->fieldList['committer']['width'] = '150';
$config->repo->blameDtable->fieldList['line']['type'] = 'number';
$config->repo->blameDtable->fieldList['line']['sortType'] = false;
$config->repo->blameDtable->fieldList['line']['width'] = '80';
$config->repo->blameDtable->fieldList['content']['title'] = $lang->repo->code;
$config->repo->blameDtable->fieldList['content']['type'] = 'html';
$config->repo->blameDtable->fieldList['content']['width'] = '700';
$app->loadLang('task');
$app->loadModuleConfig('task');
$config->repo->taskDtable = new stdclass();
$config->repo->taskDtable->fieldList = array();
$config->repo->taskDtable->fieldList['id']['name'] = 'id';
$config->repo->taskDtable->fieldList['id']['title'] = $lang->idAB;
$config->repo->taskDtable->fieldList['id']['type'] = 'id';
$config->repo->taskDtable->fieldList['id']['checkbox'] = true;
$config->repo->taskDtable->fieldList['pri']['title'] = $lang->priAB;
$config->repo->taskDtable->fieldList['pri']['type'] = 'pri';
$config->repo->taskDtable->fieldList['pri']['sortType'] = true;
$config->repo->taskDtable->fieldList['pri']['show'] = true;
$config->repo->taskDtable->fieldList['pri']['group'] = 1;
$config->repo->taskDtable->fieldList['pri']['fixed'] = 'left';
$config->repo->taskDtable->fieldList['name']['flex'] = 1;
$config->repo->taskDtable->fieldList['name']['nestedToggle'] = false;
$config->repo->taskDtable->fieldList['name']['sortType'] = true;
$config->repo->taskDtable->fieldList['name']['required'] = true;
$config->repo->taskDtable->fieldList['name']['fixed'] = 'left';
$config->repo->taskDtable->fieldList['name']['type'] = 'nestedTitle';
$config->repo->taskDtable->fieldList['name']['title'] = $lang->task->name;
$config->repo->taskDtable->fieldList['name']['link'] = array('module' => 'task', 'method' => 'view', 'params' => 'taskID={id}', 'target' => '_blank');
$config->repo->taskDtable->fieldList['finishedBy']['title'] = $lang->task->finishedByAB;
$config->repo->taskDtable->fieldList['finishedBy']['type'] = 'user';
$config->repo->taskDtable->fieldList['finishedBy']['sortType'] = true;
$config->repo->taskDtable->fieldList['finishedBy']['show'] = true;
$config->repo->taskDtable->fieldList['finishedBy']['group'] = 4;
$config->repo->taskDtable->fieldList['assignedTo']['type'] = 'user';
$config->repo->taskDtable->fieldList['assignedTo']['sortType'] = true;
$config->repo->taskDtable->fieldList['assignedTo']['show'] = true;
$config->repo->taskDtable->fieldList['assignedTo']['group'] = 3;
$config->repo->taskDtable->fieldList['assignedTo']['currentUser'] = $app->user->account;
$config->repo->taskDtable->fieldList['assignedTo']['title'] = $lang->task->assignedTo;
$config->repo->taskDtable->fieldList['assignedTo']['assignLink'] = array('module' => 'task', 'method' => 'assignTo', 'params' => 'executionID={execution}&taskID={id}');
$config->repo->taskDtable->fieldList['status']['title'] = $lang->statusAB;
$config->repo->taskDtable->fieldList['status']['type'] = 'status';
$config->repo->taskDtable->fieldList['status']['statusMap'] = $lang->task->statusList;
$config->repo->taskDtable->fieldList['status']['sortType'] = true;
$config->repo->taskDtable->fieldList['status']['show'] = true;
$config->repo->taskDtable->fieldList['status']['group'] = 1;
$config->repo->reviewDtable = new stdclass();
$config->repo->reviewDtable->fieldList['id']['title'] = $lang->idAB;
$config->repo->reviewDtable->fieldList['id']['type'] = 'id';
$config->repo->reviewDtable->fieldList['title']['type'] = 'title';
$config->repo->reviewDtable->fieldList['title']['link'] = array('module' => 'bug', 'method' => 'view', 'params' => 'bugID={id}&from=repo');
$config->repo->reviewDtable->fieldList['fileLocation']['title'] = $lang->repo->file . '/' . $lang->repo->location;
$config->repo->reviewDtable->fieldList['fileLocation']['name'] = 'entry';
$config->repo->reviewDtable->fieldList['fileLocation']['width'] = '300';
$config->repo->reviewDtable->fieldList['revisionA']['name'] = 'revisionA';
$config->repo->reviewDtable->fieldList['revisionA']['width'] = '100';
$config->repo->reviewDtable->fieldList['revisionA']['hint'] = true;
$config->repo->reviewDtable->fieldList['type']['title'] = $lang->repo->type;
$config->repo->reviewDtable->fieldList['type']['name'] = 'repoType';
$config->repo->reviewDtable->fieldList['type']['map'] = $lang->repo->typeList;
$config->repo->reviewDtable->fieldList['status']['map'] = $lang->bug->statusList;
$config->repo->reviewDtable->fieldList['openedBy']['type'] = 'user';
$config->repo->reviewDtable->fieldList['assignedTo']['type'] = 'user';
$config->repo->reviewDtable->fieldList['openedDate']['type'] = 'datetime';
+34
View File
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
$config->repo->form = new stdclass();
$config->repo->form->create = common::formConfig('repo', 'create');
$config->repo->form->create['product'] = array('required' => true, 'type' => 'array');
$config->repo->form->create['projects'] = array('required' => false, 'type' => 'array', 'default' => array());
$config->repo->form->create['SCM'] = array('required' => true, 'type' => 'string', 'filter' => 'trim');
$config->repo->form->create['serviceHost'] = array('required' => false, 'type' => 'int');
$config->repo->form->create['serviceProject'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->create['name'] = array('required' => true, 'type' => 'string', 'filter' => 'trim');
$config->repo->form->create['path'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->create['encoding'] = array('required' => true, 'type' => 'string');
$config->repo->form->create['client'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->create['account'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->create['password'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->create['encrypt'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->create['desc'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->edit = common::formConfig('repo', 'edit');
$config->repo->form->edit['product'] = array('required' => true, 'type' => 'array');
$config->repo->form->edit['projects'] = array('required' => false, 'type' => 'array', 'default' => array());
$config->repo->form->edit['SCM'] = array('required' => true, 'type' => 'string', 'filter' => 'trim');
$config->repo->form->edit['serviceHost'] = array('required' => false, 'type' => 'int');
$config->repo->form->edit['serviceProject'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->edit['name'] = array('required' => true, 'type' => 'string', 'filter' => 'trim');
$config->repo->form->edit['path'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->edit['encoding'] = array('required' => true, 'type' => 'string');
$config->repo->form->edit['client'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->edit['account'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->edit['password'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->edit['encrypt'] = array('required' => false, 'type' => 'string', 'default' => '');
$config->repo->form->edit['desc'] = array('required' => false, 'type' => 'string', 'default' => '');
+37 -335
View File
@@ -77,7 +77,6 @@ class repoModel extends model
}
if(!in_array(strtolower($repo->SCM), $this->config->repo->gitServiceList)) unset($this->lang->devops->menu->mr);
// if(count($repos) > 1) $this->lang->switcherMenu = $this->getSwitcher($repoID);
}
if(!in_array($this->app->methodName, array('maintain', 'create', 'edit','import'))) common::setMenuVars('devops', $repoID);
@@ -86,39 +85,6 @@ class repoModel extends model
session_write_close();
}
/**
* Get switcher.
*
* @param int $repoID
* @access public
* @return string
*/
public function getSwitcher($repoID)
{
$currentModule = $this->app->moduleName;
$currentMethod = $this->app->methodName;
if(!in_array($currentModule, $this->config->repo->switcherModuleList)) return '';
if($currentModule == 'repo' and !in_array($currentMethod, $this->config->repo->switcherMethodList)) return '';
$currentRepo = $this->getByID($repoID);
$currentRepoName = $currentRepo->name;
if($this->app->viewType == 'mhtml' and $repoID)
{
$output = $this->lang->repo->common . $this->lang->colon;
$output .= "<a id='currentItem' href=\"javascript:showSearchMenu('repo', '$repoID', '$currentModule', '$currentMethod', '')\">{$currentRepoName} <span class='icon-caret-down'></span></a><div id='currentItemDropMenu' class='hidden affix enter-from-bottom layer'></div>";
return $output;
}
$projectID = $this->app->tab == 'project' ? $this->get->objectID : 0;
$dropMenuLink = helper::createLink('repo', 'ajaxGetDropMenu', "repoID=$repoID&module=$currentModule&method=$currentMethod&projectId=$projectID");
$output = "<div class='btn-group header-btn' id='swapper'><button data-toggle='dropdown' type='button' class='btn' id='currentItem' title='{$currentRepoName}'><span class='text'>{$currentRepoName}</span> <span class='caret' style='margin-bottom: -1px'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label 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>'; $output .= "</div></div>";
return $output;
}
/**
* Get repo list.
*
@@ -130,34 +96,9 @@ class repoModel extends model
* @access public
* @return array
*/
public function getList($projectID = 0, $SCM = '', $orderBy = 'id_desc', $pager = null, $getCodePath = false, $lastSubmitTime = false, $type = '', $param = 0)
public function getList(int $projectID = 0, string $SCM = '', string $orderBy = 'id_desc', object $pager = null, bool $getCodePath = false, bool $lastSubmitTime = false, string $type = '', int $param = 0): array
{
$repoQuery = '';
if($type == 'bySearch')
{
$queryID = $param;
$queryName = 'repoQuery';
if($queryID && $queryID != 'myQueryID')
{
$query = $this->loadModel('search')->getZinQuery($queryID);
if($query)
{
$this->session->set($queryName, $query->sql);
$this->session->set('repoForm', $query->form);
}
else
{
$this->session->set($queryName, ' 1 = 1');
}
}
else
{
if($this->session->$queryName == false) $this->session->set($queryName, ' 1 = 1');
}
$repoQuery = $this->session->$queryName;
}
$repoQuery = $type == 'bySearch' ? $this->repoTao->processSearchQuery($param) : '';
$repos = $this->dao->select('*')->from(TABLE_REPO)
->where('deleted')->eq('0')
@@ -167,16 +108,6 @@ class repoModel extends model
->page($pager)
->fetchAll('id');
if($getCodePath)
{
$gitlabRepos = array();
foreach($repos as $repo)
{
if($repo->SCM == 'Gitlab') $gitlabRepos[$repo->id] = $repo;
}
$this->loadModel('gitlab')->apiMultiGetProjects($gitlabRepos);
}
/* Get products. */
$productIdList = $this->loadModel('product')->getProductIDByProject($projectID, false);
foreach($repos as $i => $repo)
@@ -187,32 +118,18 @@ class repoModel extends model
{
unset($repos[$i]);
}
else
elseif($projectID)
{
if($projectID)
$hasPriv = false;
foreach(explode(',', $repo->product) as $productID)
{
$hasPriv = false;
foreach(explode(',', $repo->product) as $productID)
{
if(isset($productIdList[$productID])) $hasPriv = true;
}
if(!$hasPriv) unset($repos[$i]);
if(isset($productIdList[$productID])) $hasPriv = true;
}
if(!$hasPriv) unset($repos[$i]);
}
if($lastSubmitTime)
{
if($repo->lastCommit)
{
$repo->lastSubmitTime = $repo->lastCommit;
}
else
{
$lastRevision = $this->repoTao->getLastRevision($repo->id);
$repo->lastSubmitTime = isset($lastRevision->time) ? $lastRevision->time : '';
}
}
if($lastSubmitTime) $repo->lastSubmitTime = $repo->lastCommit ? $repo->lastCommit : $this->repoTao->getLastRevision($repo->id);
if(in_array(strtolower($repo->SCM), $this->config->repo->gitServiceList)) $repo = $this->processGitService($repo, $getCodePath);
}
@@ -259,20 +176,6 @@ class repoModel extends model
*/
public function create(object $repo, bool $isPipelineServer): int|false
{
if($isPipelineServer)
{
$serviceProject = $this->dao->select('*')->from(TABLE_REPO)
->where('`SCM`')->eq($repo->SCM)
->andWhere('`serviceHost`')->eq($repo->serviceHost)
->andWhere('`serviceProject`')->eq($repo->serviceProject)
->fetch();
if($serviceProject)
{
dao::$errors['serviceProject'][] = $this->lang->repo->error->projectUnique;
return false;
}
}
$this->dao->insert(TABLE_REPO)->data($repo, 'serviceToken')
->batchCheck($this->config->repo->create->requiredFields, 'notempty')
->batchCheckIF($repo->SCM != 'Gitlab', 'path,client', 'notempty')
@@ -356,65 +259,18 @@ class repoModel extends model
}
/**
* 更新版本库。
* Update a repo.
*
* @param object $data
* @param int $id
* @param bool $isPipelineServer
* @access public
* @return bool
*/
public function update($id)
public function update(object $data, int $id, bool $isPipelineServer): bool
{
$repo = $this->getByID($id);
if($repo->client != $this->post->client and !$this->checkClient()) return false;
if(!$this->checkConnection()) return false;
$isPipelineServer = in_array(strtolower($this->post->SCM), $this->config->repo->gitServiceList) ? true : false;
$data = fixer::input('post')
->setIf($isPipelineServer, 'password', $this->post->serviceToken)
->setDefault('client', 'svn')
->setIf($this->post->SCM == 'Gitlab', 'client', '')
->setIf($this->post->SCM == 'Gitlab', 'extra', $this->post->serviceProject)
->setDefault('prefix', $repo->prefix)
->setIf($this->post->SCM == 'Gitlab', 'prefix', '')
->setDefault('product', '')
->skipSpecial('path,client,account,password,desc')
->join('product', ',')
->setDefault('projects', '')->join('projects', ',')
->get();
if($data->path != $repo->path) $data->synced = 0;
$data->acl = empty($data->acl) ? '' : json_encode($data->acl);
if($data->SCM == 'Subversion' and $data->path != $repo->path)
{
$scm = $this->app->loadClass('scm');
$scm->setEngine($data);
$info = $scm->info('');
$infoRoot = urldecode($info->root);
$data->prefix = empty($infoRoot) ? '' : trim(str_ireplace($infoRoot, '', str_replace('\\', '/', $data->path)), '/');
if($data->prefix) $data->prefix = '/' . $data->prefix;
}
elseif($data->SCM != $repo->SCM and $data->SCM == 'Git')
{
$data->prefix = '';
}
if($isPipelineServer)
{
$serviceProject = $this->dao->select('*')->from(TABLE_REPO)
->where('`SCM`')->eq($data->SCM)
->andWhere('`serviceHost`')->eq($data->serviceHost)
->andWhere('`serviceProject`')->eq($data->serviceProject)
->andWhere('id')->ne($id)
->fetch();
if($serviceProject)
{
dao::$errors['serviceProject'][] = $this->lang->repo->error->projectUnique;
return false;
}
}
if(($repo->serviceHost != $data->serviceHost || $repo->serviceProject != $data->serviceProject) && $data->SCM == 'Gitlab')
{
@@ -456,9 +312,7 @@ class repoModel extends model
if(($repo->serviceHost != $data->serviceHost || $repo->serviceProject != $data->serviceProject) && $repo->path != $data->path)
{
$this->dao->delete()->from(TABLE_REPOHISTORY)->where('repo')->eq($id)->exec();
$this->dao->delete()->from(TABLE_REPOFILES)->where('repo')->eq($id)->exec();
$this->dao->delete()->from(TABLE_REPOBRANCH)->where('repo')->eq($id)->exec();
$this->repoTao->deleteInfoByID($id);
return false;
}
@@ -521,12 +375,28 @@ class repoModel extends model
$this->dao->replace(TABLE_RELATION)->data($relation)->exec();
if($type == 'story') $this->action->create('story', $linkID, 'linked2revision', '', $revisionID, $commiter);
if($type == 'bug') $this->action->create('bug', $linkID, 'linked2revision', '', $revisionID, $commiter);
if($type == 'task') $this->action->create('task', $linkID, 'linked2revision', '', $revisionID, $commiter);
$this->action->create($type, $linkID, 'linked2revision', '', $revisionID, $committer);
}
}
/**
* 删除一个版本库。
* Delete a repo.
*
* @param int $repoID
* @access public
* @return bool
*/
public function deleteRepo(int $repoID): bool
{
$this->repoTao->deleteInfoByID($repoID);
$this->dao->delete()->from(TABLE_REPO)->where('id')->eq($repoID)->exec();
if(dao::isError()) return false;
$this->loadModel('action')->create('repo', $repoID, 'deleted', '');
return true;
}
/**
* Unlink object and commit revision.
*
@@ -1571,49 +1441,6 @@ class repoModel extends model
);
}
/**
* Check svn/git client.
*
* @access public
* @return bool
*/
public function checkClient()
{
if($this->post->SCM == 'Gitlab') return true;
if(!$this->config->features->checkClient) return true;
if(!$this->post->client)
{
dao::$errors['client'] = sprintf($this->lang->error->notempty, $this->lang->repo->client);
return false;
}
/* Check command injection. */
if(preg_match('/[ #&;`,\|*?~<>^()\[\]{}$]/', $this->post->client))
{
dao::$errors['client'] = $this->lang->repo->error->clientPath;
return false;
}
$clientVersionFile = $this->session->clientVersionFile;
if(empty($clientVersionFile))
{
$clientVersionFile = $this->app->getLogRoot() . uniqid('version_') . '.log';
session_start();
$this->session->set('clientVersionFile', $clientVersionFile);
session_write_close();
}
if(file_exists($clientVersionFile)) return true;
$cmd = $this->post->client . " --version > $clientVersionFile";
dao::$errors['client'] = sprintf($this->lang->repo->error->safe, $clientVersionFile, $cmd);
return false;
}
/**
* remove client version file.
*
@@ -1633,131 +1460,6 @@ class repoModel extends model
}
}
/**
* Check connection
*
* @access public
* @return void
*/
public function checkConnection()
{
if(empty($_POST)) return false;
$scm = $this->post->SCM;
$client = $this->post->client;
$account = $this->post->account;
$password = $this->post->password;
$encoding = strtoupper($this->post->encoding);
$path = $this->post->path;
if($encoding != 'UTF8' and $encoding != 'UTF-8') $path = helper::convertEncoding($path, 'utf-8', $encoding);
if($scm == 'Subversion')
{
/* Get svn version. */
$versionCommand = "$client --version --quiet 2>&1";
exec($versionCommand, $versionOutput, $versionResult);
if($versionResult)
{
$message = sprintf($this->lang->repo->error->output, $versionCommand, $versionResult, implode("<br />", $versionOutput));
dao::$errors['client'] = $this->lang->repo->error->cmd . "<br />" . nl2br($message);
return false;
}
$svnVersion = end($versionOutput);
$path = '"' . str_replace(array('%3A', '%2F', '+'), array(':', '/', ' '), urlencode($path)) . '"';
if(stripos($path, 'https://') === 1 or stripos($path, 'svn://') === 1)
{
if(version_compare($svnVersion, '1.6', '<'))
{
dao::$errors['client'] = $this->lang->repo->error->version;
return false;
}
$command = "$client info --username $account --password $password --non-interactive --trust-server-cert-failures=cn-mismatch --trust-server-cert --no-auth-cache $path 2>&1";
if(version_compare($svnVersion, '1.9', '<')) $command = "$client info --username $account --password $password --non-interactive --trust-server-cert --no-auth-cache $path 2>&1";
}
elseif(stripos($path, 'file://') === 1)
{
$command = "$client info --non-interactive --no-auth-cache $path 2>&1";
}
else
{
$command = "$client info --username $account --password $password --non-interactive --no-auth-cache $path 2>&1";
}
exec($command, $output, $result);
if($result)
{
$message = sprintf($this->lang->repo->error->output, $command, $result, implode("<br />", $output));
if(stripos($message, 'Expected FS format between') !== false and strpos($message, 'found format') !== false)
{
dao::$errors['client'] = $this->lang->repo->error->clientVersion;
return false;
}
if(preg_match('/[^\:\/A-Za-z0-9_\-\'\"\.]/', $path))
{
dao::$errors['encoding'] = $this->lang->repo->error->encoding . "<br />" . nl2br($message);
return false;
}
dao::$errors['submit'] = $this->lang->repo->error->connect . "<br>" . nl2br($message);
return false;
}
}
elseif(in_array($scm, array('Gitea', 'Gogs')))
{
if($this->post->name != '' and $this->post->serviceProject != '')
{
$module = strtolower($scm);
$project = $this->loadModel($module)->apiGetSingleProject($this->post->serviceHost, $this->post->serviceProject);
if(isset($project->tokenCloneUrl))
{
$path = $this->app->getAppRoot() . 'www/data/repo/' . $this->post->name . '_' . $module;
if(!realpath($path))
{
$cmd = 'git clone --progress -v "' . $project->tokenCloneUrl . '" "' . $path . '" > "' . $this->app->getTmpRoot() . "log/clone.progress.$module.{$this->post->name}.log\" 2>&1 &";
if(PHP_OS == 'WINNT') $cmd = "start /b $cmd";
exec($cmd);
}
$_POST['path'] = $path;
}
else
{
dao::$errors['serviceProject'] = $this->lang->repo->error->noCloneAddr;
return false;
}
}
}
elseif($scm == 'Git')
{
if(!is_dir($path))
{
dao::$errors['path'] = sprintf($this->lang->repo->error->noFile, $path);
return false;
}
if(!chdir($path))
{
if(!is_executable($path))
{
dao::$errors['path'] = sprintf($this->lang->repo->error->noPriv, $path);
return false;
}
dao::$errors['path'] = $this->lang->repo->error->path;
return false;
}
$command = "$client tag 2>&1";
exec($command, $output, $result);
if($result)
{
dao::$errors['submit'] = $this->lang->repo->error->connect . "<br />" . sprintf($this->lang->repo->error->output, $command, $result, implode("<br />", $output));
return false;
}
}
return true;
}
/**
* Replace comment link.
*
@@ -2082,7 +1784,7 @@ class repoModel extends model
}
else
{
$this->task->recordEstimate($taskID);
$this->task->recordWorkhour($taskID);
}
$action->action = $scm == 'svn' ? 'svncommited' : 'gitcommited';
@@ -2265,8 +1967,8 @@ class repoModel extends model
{
foreach($actionFiles as $file)
{
$catLink = trim(html::a($this->buildURL('cat', $repoRoot . $file, $log->revision, $scm), 'view', '', "data-width='960'"));
$diffLink = trim(html::a($this->buildURL('diff', $repoRoot . $file, $log->revision, $scm), 'diff', '', "data-width='960'"));
$catLink = trim(html::a($this->buildURL('cat', $repoRoot . $file, $log->revision, $scm), 'view', '', "class='iframe' data-width='960'"));
$diffLink = trim(html::a($this->buildURL('diff', $repoRoot . $file, $log->revision, $scm), 'diff', '', "class='iframe' data-width='960'"));
$diff .= $action . " " . $file . " $catLink ";
$diff .= $action == 'M' ? "$diffLink\n" : "\n" ;
}
@@ -2967,7 +2669,7 @@ class repoModel extends model
}
$stories = empty($storyIDs) ? array() : $this->loadModel('story')->getByList($storyIDs);
$bugs = empty($bugIDs) ? array() : $this->loadModel('bug')->getByList($bugIDs);
$tasks = empty($taskIDs) ? array() : $this->loadModel('task')->getByList($taskIDs);
$tasks = empty($taskIDs) ? array() : $this->loadModel('task')->getByIdList($taskIDs);
$titleList = array();
foreach($relationList as $key => $relation)
+536 -17
View File
@@ -47,6 +47,110 @@ class repoZen extends repo
->setDefault('projects', '')->join('projects', ',')
->get();
$acl = $this->checkACL();
if(!$acl) return false;
$repo->acl = json_encode($acl);
if($repo->SCM == 'Subversion')
{
$scm = $this->app->loadClass('scm');
$scm->setEngine($repo);
$info = $scm->info('');
$infoRoot = urldecode($info->root);
$repo->prefix = empty($infoRoot) ? '' : trim(str_ireplace($infoRoot, '', str_replace('\\', '/', $repo->path)), '/');
if($repo->prefix) $repo->prefix = '/' . $repo->prefix;
}
if($isPipelineServer)
{
$serviceProject = $this->dao->select('*')->from(TABLE_REPO)
->where('`SCM`')->eq($repo->SCM)
->andWhere('`serviceHost`')->eq($repo->serviceHost)
->andWhere('`serviceProject`')->eq($repo->serviceProject)
->fetch();
if($serviceProject)
{
dao::$errors['serviceProject'][] = $this->lang->repo->error->projectUnique;
return false;
}
}
return $repo;
}
/**
* 准备编辑版本库的数据。
* Prepare edit repo data.
*
* @param form $formData
* @param object $oldRepo
* @param bool $isPipelineServer
* @access protected
* @return object|false
*/
protected function prepareEdit(form $formData, object $oldRepo, bool $isPipelineServer): object|false
{
if($oldRepo->client != $this->post->client and !$this->checkClient()) return false;
if(!$this->checkConnection()) return false;
$repo = $formData
->setIf($isPipelineServer, 'password', $this->post->serviceToken)
->setDefault('client', 'svn')
->setIf($this->post->SCM == 'Gitlab', 'client', '')
->setIf($this->post->SCM == 'Gitlab', 'extra', $this->post->serviceProject)
->setIf($this->post->SCM == 'Gitlab', 'prefix', '')
->setDefault('product', '')
->skipSpecial('path,client,account,password,desc')
->join('product', ',')
->setDefault('projects', '')->join('projects', ',')
->get();
if($repo->path != $oldRepo->path) $repo->synced = 0;
$acl = $this->checkACL();
if(!$acl) return false;
$repo->acl = json_encode($acl);
if($repo->SCM == 'Subversion')
{
$scm = $this->app->loadClass('scm');
$scm->setEngine($repo);
$info = $scm->info('');
$infoRoot = urldecode($info->root);
$repo->prefix = empty($infoRoot) ? '' : trim(str_ireplace($infoRoot, '', str_replace('\\', '/', $repo->path)), '/');
if($repo->prefix) $repo->prefix = '/' . $repo->prefix;
}
elseif($repo->SCM != $oldRepo->SCM and $repo->SCM == 'Git')
{
$repo->prefix = '';
}
if($isPipelineServer)
{
$serviceProject = $this->dao->select('*')->from(TABLE_REPO)
->where('`SCM`')->eq($repo->SCM)
->andWhere('`serviceHost`')->eq($repo->serviceHost)
->andWhere('`serviceProject`')->eq($repo->serviceProject)
->andWhere('id')->ne($oldRepo->id)
->fetch();
if($serviceProject)
{
dao::$errors['serviceProject'][] = $this->lang->repo->error->projectUnique;
return false;
}
}
return $repo;
}
/**
* 检查权限数据。
* Check acl.
*
* @access protected
* @return array|false
*/
protected function checkACL(): array|false
{
$acl = $this->post->acl;
if($acl['acl'] == 'custom')
{
@@ -59,18 +163,7 @@ class repoZen extends repo
return false;
}
}
$repo->acl = json_encode($acl);
if($repo->SCM == 'Subversion')
{
$scm = $this->app->loadClass('scm');
$scm->setEngine($repo);
$info = $scm->info('');
$infoRoot = urldecode($info->root);
$repo->prefix = empty($infoRoot) ? '' : trim(str_ireplace($infoRoot, '', str_replace('\\', '/', $repo->path)), '/');
if($repo->prefix) $repo->prefix = '/' . $repo->prefix;
}
return $repo;
return $acl;
}
/**
@@ -253,7 +346,6 @@ class repoZen extends repo
protected function buildCreateForm(int $objectID): void
{
$repoID = $this->repo->saveState(0, $objectID);
$this->commonAction($repoID, $objectID);
$this->app->loadLang('action');
@@ -278,6 +370,53 @@ class repoZen extends repo
$this->display();
}
/**
* 构建编辑版本库页面数据。
* Build form fields for edit repo.
*
* @param int $objectID
* @access protected
* @return void
*/
protected function buildEditForm(int $repoID, int $objectID): void
{
$repo = $this->repo->getByID($repoID);
$this->app->loadLang('action');
$scm = strtolower($repo->SCM);
if(in_array($scm, $this->config->repo->gitServiceList))
{
$serviceID = isset($repo->gitService) ? $repo->gitService : 0;
$projects = $this->loadModel($scm)->apiGetProjects($serviceID);
$options = array();
foreach($projects as $project)
{
if($scm == 'gitlab') $options[$project->id] = $project->name_with_namespace;
if($scm == 'gitea') $options[$project->full_name] = $project->full_name;
if($scm == 'gogs') $options[$project->full_name] = $project->full_name;
}
$this->view->projects = $options;
}
$products = $this->loadModel('product')->getPairs('', 0, '', 'all');
$linkedProducts = $this->loadModel('product')->getByIdList(explode(',', $repo->product));
$linkedProductPairs = array_combine(array_keys($linkedProducts), helper::arrayColumn($linkedProducts, 'name'));
$products = $products + $linkedProductPairs;
$this->view->title = $this->lang->repo->common . $this->lang->colon . $this->lang->repo->edit;
$this->view->repo = $repo;
$this->view->repoID = $repoID;
$this->view->objectID = $objectID;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->loadModel('user')->getPairs('noletter|noempty|nodeleted|noclosed');
$this->view->products = $products;
$this->view->relatedProjects = $this->repo->filterProject(explode(',', $repo->product), explode(',', $repo->projects));
$this->view->serviceHosts = $this->loadModel('pipeline')->getPairs($repo->SCM);
$this->display();
}
/**
* 准备批量创建版本库的数据。
* Prepare batch create repo data.
@@ -342,10 +481,12 @@ class repoZen extends repo
* @param int $refresh
* @param string $revision
* @param object $lastRevision
* @param string $base64BranchID
* @param int $objectID
* @access protected
* @return array
*/
protected function getFilesInfo(object $repo, string $path, string $branchID, int $refresh, string $revision, object $lastRevision): array
protected function getFilesInfo(object $repo, string $path, string $branchID, int $refresh, string $revision, object $lastRevision, string $base64BranchID, int $objectID): array
{
if($repo->SCM == 'Gitlab')
{
@@ -381,6 +522,17 @@ class repoZen extends repo
{
$info->originalComment = $info->comment;
$info->comment = $this->repo->replaceCommentLink($info->comment);
$info->revision = $repo->SCM == 'Subversion' ? $info->revision : substr($info->revision, 0, 10);
$infoPath = trim(urldecode($path) . '/' . $info->name, '/');
if($info->kind == 'dir')
{
$info->link = $this->repo->createLink('browse', "repoID={$repo->id}&branchID=$base64BranchID&objectID=$objectID&path=" . $this->repo->encodePath($infoPath));
}
else
{
$info->link = $this->repo->createLink('view', "repoID={$repo->id}&objectID=$objectID&entry=" . $this->repo->encodePath($infoPath));
}
}
return $infos;
@@ -468,7 +620,7 @@ class repoZen extends repo
$this->loadModel('gitlab')->setProject((int)$repo->gitService, (int)$repo->project, $project);
}
if(!is_null($result['branches']->headers->offsetGet('x-total')))
if(!empty($result['branches']->headers) && !is_null($result['branches']->headers->offsetGet('x-total')))
{
$branchList = json_decode($result['branches']->body);
$totalPages = $result['branches']->headers->offsetGet('x-total-pages');
@@ -511,7 +663,7 @@ class repoZen extends repo
$branches = $default + $branches;
}
}
if(!is_null($result['tags']->headers->offsetGet('x-total')))
if(!empty($result['branches']->headers) && !is_null($result['tags']->headers->offsetGet('x-total')))
{
$tagList = json_decode($result['tags']->body);
$totalPages = $result['tags']->headers->offsetGet('x-total-pages');
@@ -542,5 +694,372 @@ class repoZen extends repo
return array(isset($branches) ? $branches : false, isset($tags) ? $tags : false);
}
}
}
/**
* 为git类型版本库设置分支和tag。
* Set branch or tag for git.
*
* @param object $repo
* @param string $branchID
* @param array|bool $branchInfo
* @param array|bool $tagInfo
* @access protected
* @return array
*/
protected function setBranchTag(object $repo, string $branchID, array|bool $branchInfo = false, array|bool $tagInfo = false): array
{
$repoID = $repo->id;
$branches = $tags = $branchesAndTags = array();
if(in_array($repo->SCM, $this->config->repo->gitTypeList))
{
$scm = $this->app->loadClass('scm');
$scm->setEngine($repo);
$branches = isset($branchInfo) && $branchInfo !== false ? $branchInfo : $scm->branch();
$initTags = isset($tagInfo) && $tagInfo !== false ? $tagInfo : $scm->tags('');
foreach($initTags as $tag) $tags[$tag] = $tag;
$branchesAndTags = $branches + $tags;
if(empty($branchID) and $this->cookie->repoBranch and $this->session->repoID == $repoID) $branchID = $this->cookie->repoBranch;
if($branchID) $this->repo->setRepoBranch($branchID);
if(!isset($branchesAndTags[$branchID]))
{
$branchID = (string)key($branches);
$this->repo->setRepoBranch($branchID);
}
return array($branchID, $branches, $tags, $branchesAndTags);
}
else
{
$this->repo->setRepoBranch('');
return array('', array(), array(), array());
}
}
/**
* 获取commits列表
* Get commits.
*
* @param object $repo
* @param string $path
* @param string $revision
* @param string $type
* @param object $pager
* @param int $objectID
* @access protected
* @return array
*/
protected function getCommits(object $repo, string $path, string $revision, string $type, object $pager, int $objectID): array
{
$revisions = $this->repo->getCommits($repo, $path, $revision, $type, $pager);
$pathInfo = '&root=' . $this->repo->encodePath(empty($path) ? '/' : $path);
foreach($revisions as $item)
{
$item->link = $this->repo->createLink('revision', "repoID={$repo->id}&objectID=$objectID&revision={$item->revision}" . $pathInfo);
$item->revision = $repo->SCM != 'Subversion' ? substr($item->revision, 0, 10) : $item->revision;
}
return $revisions;
}
/**
* 设置session信息。
* Set session.
*
* @access protected
* @return void
*/
protected function setBrowseSession(): void
{
$this->repo->setBackSession('list', true);
session_start();
$this->session->set('revisionList', $this->app->getURI(true));
$this->session->set('gitlabBranchList', $this->app->getURI(true));
session_write_close();
}
/**
* 构建版本库搜索框。
* Build repo search form.
*
* @param array $products
* @param array $projects
* @param int $objectID
* @param string $orderBy
* @param int $recPerPage
* @param int $pageID
* @param int $param
* @access protected
* @return void
*/
protected function buildRepoSearchForm(array $products, array $projects, int $objectID, string $orderBy, int $recPerPage, int $pageID, int $param): void
{
session_start();
$this->config->repo->search['params']['product']['values'] = $products;
$this->config->repo->search['params']['projects']['values'] = $projects;
$this->config->repo->search['actionURL'] = $this->createLink('repo', 'maintain', "objectID={$objectID}&orderBy={$orderBy}&recPerPage={$recPerPage}&pageID={$pageID}&type=bySearch&param=myQueryID");
$this->config->repo->search['queryID'] = $param;
$this->config->repo->search['onMenuBar'] = 'yes';
$this->loadModel('search')->setSearchParams($this->config->repo->search);
session_write_close();
}
/**
* 构建需求搜索表格。
* Build story search form.
*
* @param int $repoID
* @param string $revision
* @param string $browseType
* @param int $queryID
* @param object $product
* @param array $modules
* @access protected
* @return void
*/
protected function buildStorySearchForm(int $repoID, string $revision, string $browseType, int $queryID, object $product, array $modules): void
{
unset($this->lang->story->statusList['closed']);
$storyStatusList = $this->lang->story->statusList;
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($product->id => $product->id));
$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'] = $this->loadModel('branch')->getPairs($product->id, 'noempty');
}
session_start();
$this->loadModel('search')->setSearchParams($this->config->product->search);
session_write_close();
}
/**
* 获取关联需求列表。
* Get link stories list.
*
* @param int $repoID
* @param string $revision
* @param string $browseType
* @param object $product
* @param string $orderBy
* @param object $pager
* @param int $queryID
* @access protected
* @return array
*/
protected function getLinkStories(int $repoID, string $revision, string $browseType, object $product, string $orderBy, object $pager, int $queryID): array
{
$linkedStories = $this->repo->getRelationByCommit($repoID, $revision, 'story');
if($browseType == 'bySearch')
{
$allStories = $this->loadModel('story')->getBySearch($product->id, 0, $queryID, $orderBy, 0, 'story', array_keys($linkedStories), $pager);
}
else
{
$allStories = $this->loadModel('story')->getProductStories($product->id, 0, '0', 'draft,active,changed', 'story', $orderBy, false, array_keys($linkedStories), $pager);
}
return $allStories;
}
/**
* 构建bug搜索表格。
* Build bug search form.
*
* @param int $repoID
* @param string $revision
* @param string $browseType
* @param int $queryID
* @param object $product
* @param array $modules
* @access protected
* @return void
*/
protected function buildBugSearchForm(int $repoID, string $revision, string $browseType, int $queryID, object $product, array $modules): void
{
$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->loadModel('product')->getExecutionPairsByProduct($product->id);
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getBuildPairs(array($product->id), 'all', '');
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->loadModel('build')->getBuildPairs(array($product->id), 'all', '');
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'] = $this->loadModel('branch')->getPairs($product->id, 'noempty');
}
session_start();
$this->loadModel('search')->setSearchParams($this->config->bug->search);
session_write_close();
}
/**
* 获取关联bug列表。
* Get link bugs list.
*
* @param int $repoID
* @param string $revision
* @param string $browseType
* @param object $product
* @param string $orderBy
* @param object $pager
* @param int $queryID
* @access protected
* @return array
*/
protected function getLinkBugs(int $repoID, string $revision, string $browseType, object $product, string $orderBy, object $pager, int $queryID): array
{
$linkedBugs = $this->repo->getRelationByCommit($repoID, $revision, 'bug');
if($browseType == 'bySearch')
{
$allBugs = $this->loadModel('bug')->getBySearch($product->id, 0, $queryID, $orderBy, array_keys($linkedBugs), $pager);
}
else
{
$allBugs = $this->loadModel('bug')->getActiveBugs($product->id, 0, '0', array_keys($linkedBugs), $pager, $orderBy);
}
foreach($allBugs as $bug) $bug->statusText = $this->processStatus('bug', $bug);
return $allBugs;
}
/**
* 构建任务搜索表格。
* Build task search form.
*
* @param int $repoID
* @param string $revision
* @param string $browseType
* @param int $queryID
* @param object $product
* @param array $modules
* @param array $productExecutions
* @access protected
* @return void
*/
protected function buildTaskSearchForm(int $repoID, string $revision, string $browseType, int $queryID, object $product, array $modules, array $productExecutions): void
{
$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->loadModel('product')->getExecutionPairsByProduct($product->id);
$this->config->execution->search['params']['execution']['values'] = array_filter($productExecutions);
session_start();
$this->loadModel('search')->setSearchParams($this->config->execution->search);
session_write_close();
}
/**
* 获取关联任务列表。
* Get link tasks list.
*
* @param int $repoID
* @param string $revision
* @param string $browseType
* @param object $product
* @param string $orderBy
* @param object $pager
* @param int $queryID
* @param array $productExecutionIDs
* @access protected
* @return array
*/
protected function getLinkTasks(int $repoID, string $revision, string $browseType, object $product, string $orderBy, object $pager, int $queryID, array $productExecutionIDs): array
{
$allTasks = array();
foreach($productExecutionIDs as $productExecutionID)
{
$tasks = $this->loadModel('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 ++;
}
return $allTasks;
}
/**
* 关联对象。
* Link object.
*
* @param int $repoID
* @param string $revision
* @param string $type story|bug|task
* @access protected
* @return array
*/
protected function linkObject(int $repoID, string $revision, string $type): array
{
$this->repo->link($repoID, $revision, $type);
if(dao::isError()) return array('result' => 'fail', 'message' => dao::getError());
return array('result' => 'success', 'callback' => "$('.tab-content .active iframe')[0].contentWindow.getRelation('$revision')", 'closeModal' => true);
}
/**
* 检查删除版本库的错误。
* Check repo delete error.
*
* @param int $repoID
* @access protected
* @return string
*/
protected function checkDeleteError(int $repoID): string
{
$relationID = $this->dao->select('id')->from(TABLE_RELATION)
->where('extra')->eq($repoID)
->andWhere('AType')->eq('design')
->fetch();
$error = $relationID ? $this->lang->repo->error->deleted : '';
$jobs = $this->dao->select('*')->from(TABLE_JOB)->where('repo')->eq($repoID)->andWhere('deleted')->eq('0')->fetchAll();
if($jobs) $error .= ($error ? '\n' : '') . $this->lang->repo->error->linkedJob;
return $error;
}
}