diff --git a/lib/scm/gitlab.class.php b/lib/scm/gitlab.class.php index 2142dc644d..cb5457fa2d 100644 --- a/lib/scm/gitlab.class.php +++ b/lib/scm/gitlab.class.php @@ -949,4 +949,27 @@ class gitlab } return $lists; } + + /** + * 获取特定对象的api。 + * Get api url for target. + * + * @param string $target + * @access public + * @return string + */ + public function getApiUrl(string $target): string + { + if($target == 'project') + { + return str_replace('repository/', '', $this->root). "?private_token={$this->token}"; + } + $params = array(); + $params['private_token'] = $this->token; + $params['page'] = 1; + $params['per_page'] = isset($params['per_page']) ? $params['per_page'] : 100; + + $api = $this->root . $target . '?' . http_build_query($params); + return $api; + } } diff --git a/module/gitlab/model.php b/module/gitlab/model.php index 87f28feeb8..0549fd0a56 100644 --- a/module/gitlab/model.php +++ b/module/gitlab/model.php @@ -441,6 +441,21 @@ class gitlabModel extends model return $this->loadModel('pipeline')->update($id); } + /** + * 设置项目信息。 + * Set project data. + * + * @param int $gitlabID + * @param int $projectID + * @param object $project + * @access public + * @return void + */ + public function setProject(int $gitlabID, int $projectID, object $project): void + { + $this->projects[$gitlabID][$projectID] = $project; + } + /** * Send an api get request. * diff --git a/module/repo/control.php b/module/repo/control.php index bc4e003610..38ffa4ac37 100644 --- a/module/repo/control.php +++ b/module/repo/control.php @@ -571,14 +571,16 @@ 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 = $scm->branch(); - $initTags = $scm->tags(''); + $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; diff --git a/module/repo/zen.php b/module/repo/zen.php index 8fae7ff1c3..49f9a18127 100644 --- a/module/repo/zen.php +++ b/module/repo/zen.php @@ -440,5 +440,106 @@ class repoZen extends repo $lastCommitDate = date('Y-m-d H:i:s', strtotime($lastRevision->committed_date)); if(empty($repo->lastCommit) || $lastCommitDate > $repo->lastCommit) $this->dao->update(TABLE_REPO)->set('lastCommit')->eq($lastCommitDate)->where('id')->eq($repo->id)->exec(); } + + /** + * 获取browse方法项目、分支、tags信息。 + * Get project、branches、tags info for browse method. + * + * @param object $repo + * @access protected + * @return array + */ + protected function getBrowseInfo(object $repo): array + { + if($repo->SCM == 'Gitlab') + { + $scm = $this->app->loadClass('scm'); + $scm->setEngine($repo); + $urls['project']['url'] = $scm->engine->getApiUrl("project"); + $urls['branches']['url'] = $scm->engine->getApiUrl('branches'); + $urls['tags']['url'] = $scm->engine->getApiUrl('tags'); + + $this->app->loadClass('requests', true); + $result = requests::request_multiple($urls); + + if($result['project']->status_code == 200) + { + $project = json_decode($result['project']->body); + $this->loadModel('gitlab')->setProject((int)$repo->gitService, (int)$repo->project, $project); + } + if(!is_null($result['branches']->headers->offsetGet('x-total'))) + { + $branchList = json_decode($result['branches']->body); + $totalPages = $result['branches']->headers->offsetGet('x-total-pages'); + if($totalPages > 1) + { + $requests = array(); + for($page = 2; $page <= $totalPages; $page++) + { + $requests[$page]['url'] = str_replace('page=1', "page={$page}", $urls['branches']['url']); + } + + $reponses = requests::request_multiple($requests, array('timeout' => 10)); + foreach($reponses as $reponse) + { + $data = json_decode($reponse->body); + if(!is_array($data)) continue; + $branchList = array_merge($branchList, $data); + } + } + + $branches = array(); + $default = array(); + if(!empty($branchList) && is_array($branchList)) + { + foreach($branchList as $branch) + { + if(!isset($branch->name)) continue; + if($branch->default) + { + $default[$branch->name] = $branch->name; + } + else + { + $branches[$branch->name] = $branch->name; + } + } + + if(empty($branches) and empty($default)) $branches['master'] = 'master'; + asort($branches); + $branches = $default + $branches; + } + } + if(!is_null($result['tags']->headers->offsetGet('x-total'))) + { + $tagList = json_decode($result['tags']->body); + $totalPages = $result['tags']->headers->offsetGet('x-total-pages'); + if($totalPages > 1) + { + $requests = array(); + for($page = 2; $page <= $totalPages; $page++) + { + $requests[$page]['url'] = str_replace('page=1', "page={$page}", $urls['tags']['url']); + } + + $reponses = requests::request_multiple($requests, array('timeout' => 10)); + foreach($reponses as $reponse) + { + $data = json_decode($reponse->body); + if(!is_array($data)) continue; + $tagList = array_merge($tagList, $data); + } + } + + $tags = array(); + if(!empty($tagList) && is_array($tagList)) + { + foreach($tagList as $tag) $tags[] = $tag->name; + } + } + + return array(isset($branches) ? $branches : false, isset($tags) ? $tags : false); + } + } }