diff --git a/module/gitfox/model.php b/module/gitfox/model.php index d13b9e998e..1aee2bddec 100644 --- a/module/gitfox/model.php +++ b/module/gitfox/model.php @@ -152,12 +152,12 @@ class gitfoxModel extends model $apiRoot = $this->getApiRoot($gitfoxID); if(!$apiRoot) return array(); - $url = sprintf($apiRoot->url, "/repos?listAllRepos"); + $url = sprintf($apiRoot->url, "/repos"); $allResults = array(); for($page = 1; true; $page++) { - $results = json_decode(commonModel::http($url . "&query={$query}&page={$page}&limit=100")); + $results = json_decode(commonModel::http($url . "?query={$query}&page={$page}&limit=100")); if(!is_array($results)) break; if(!empty($results)) $allResults = array_merge($allResults, $results); if(count($results) < 100) break; @@ -279,6 +279,133 @@ class gitfoxModel extends model if(empty($hook->url)) continue; if($hook->url == $url) return true; } + + return false; + } + + /** + * 通过api创建gitfox项目。 + * Create a gitfox repo by api. + * + * @param int $gitfoxID + * @param object $repo + * @access public + * @return object|array|null|false + */ + public function apiCreateRepo(int $gitfoxID, object $repo): object|array|null|false + { + if(empty($repo->identifier)) return false; + + $apiRoot = $this->getApiRoot($gitfoxID); + $url = sprintf($apiRoot->url, "/repos"); + + $repo->default_branch = 'main'; + $repo->is_public = true; + $repo->readme = true; + $repo->git_ignore = ''; + + return json_decode(commonModel::http($url, $repo, array(), $apiRoot->header, 'json')); + } + + /** + * 获取gitfox的群组列表。 + * Get groups of one gitfox. + * + * @param int $gitfoxID + * @param string $orderBy + * @param string $minRole + * @param string $keyword + * @access public + * @return array + */ + public function apiGetGroups(int $gitfoxID, string $orderBy = 'id_desc', string $keyword = ''): array + { + $apiRoot = $this->getApiRoot($gitfoxID); + $url = sprintf($apiRoot->url, "/spaces"); + + if($keyword) $url .= '&query=' . urlencode($keyword); + + $order = 'desc'; + $sort = 'id'; + if(strpos($orderBy, '_') !== false) list($sort, $order) = explode('_', $orderBy); + + $allResults = array(); + for($page = 1; true; $page++) + { + $pageUrl = $url . "?order={$order}&sort={$sort}&page={$page}&limit=100"; + $results = json_decode(commonModel::http($pageUrl, null, array(), $apiRoot->header)); + if(!is_array($results)) break; + if(!empty($results)) $allResults = array_merge($allResults, $results); + if(count($results) < 100) break; + } + + return $allResults; + } + + /** + * 通过api删除一个gitfox代码库。 + * Delete a gitfox project by api. + * + * @param int $gitfoxID + * @param int $repoID + * @access public + * @return object|array|null|false + */ + public function apiDeleteRepo(int $gitfoxID, int $repoID): object|array|null|false + { + if(empty($repoID)) return false; + + $apiRoot = $this->getApiRoot($gitfoxID); + $url = sprintf($apiRoot->url, "/repos/{$repoID}"); + return json_decode(commonModel::http($url, array(), array(CURLOPT_CUSTOMREQUEST => 'DELETE'), $apiRoot->header)); + } + + /** + * 错误处理。 + * Api error handling. + * + * @param object $response + * @access public + * @return bool + */ + public function apiErrorHandling(object $response): bool + { + if(!empty($response->error)) + { + dao::$errors[] = $response->error; + return false; + } + if(!empty($response->message)) + { + if(is_string($response->message)) + { + $errorKey = array_search($response->message, $this->lang->gitfox->apiError); + dao::$errors[] = $errorKey === false ? $response->message : zget($this->lang->gitfox->errorLang, $errorKey); + } + else + { + foreach($response->message as $field => $fieldErrors) + { + if(empty($fieldErrors)) continue; + + if(is_string($fieldErrors)) + { + $errorKey = array_search($fieldErrors, $this->lang->gitfox->apiError); + if($fieldErrors) dao::$errors[$field][] = $errorKey === false ? $fieldErrors : zget($this->lang->gitfox->errorLang, $errorKey); + } + else + { + foreach($fieldErrors as $error) + { + $errorKey = array_search($error, $this->lang->gitfox->apiError); + if($error) dao::$errors[$field][] = $errorKey === false ? $error : zget($this->lang->gitfox->errorLang, $errorKey); + } + } + } + } + } + + if(!$response) dao::$errors[] = false; return false; } } diff --git a/module/repo/config/form.php b/module/repo/config/form.php index 22ef7d6e6b..6392b93edf 100644 --- a/module/repo/config/form.php +++ b/module/repo/config/form.php @@ -38,7 +38,7 @@ $config->repo->form->createRepo = array(); $config->repo->form->createRepo['product'] = array('required' => true, 'type' => 'array', 'default' => array(), 'filter' => 'join'); $config->repo->form->createRepo['projects'] = array('required' => false, 'type' => 'array', 'default' => array(), 'filter' => 'join'); $config->repo->form->createRepo['serviceHost'] = array('required' => false, 'type' => 'int'); -$config->repo->form->createRepo['namespace'] = array('required' => true, 'type' => 'int'); +$config->repo->form->createRepo['namespace'] = array('required' => true, 'type' => 'string'); $config->repo->form->createRepo['name'] = array('required' => true, 'type' => 'string', 'filter' => 'trim'); $config->repo->form->createRepo['desc'] = array('required' => false, 'type' => 'string', 'default' => ''); $config->repo->form->createRepo['client'] = array('required' => false, 'type' => 'string', 'default' => 'git'); diff --git a/module/repo/control.php b/module/repo/control.php index 1521f376be..0ac61144e6 100644 --- a/module/repo/control.php +++ b/module/repo/control.php @@ -190,11 +190,11 @@ class repo extends control if($repo) $repoID = $this->repo->createRepo($repo); if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); - if($formData->SCM == 'Gitlab') + if(in_array($formData->SCM, $this->config->repo->notSyncSCM)) { /* Add webhook. */ $repo = $this->repo->getByID($repoID); - $this->loadModel('gitlab')->updateCodePath($repo->serviceHost, $repo->serviceProject, $repo->id); + $this->loadModel($formData->SCM)->updateCodePath($repo->serviceHost, (int)$repo->serviceProject, (int)$repo->id); $this->repo->updateCommitDate($repoID); } @@ -1150,7 +1150,7 @@ class repo extends control $logs = array(); $version = 1; - if($repo->SCM != 'Gitlab') + if(in_array($repo->SCM, $this->config->repo->notSyncSCM)) { $latestInDB = $this->repo->getLatestCommit($repoID, false); diff --git a/module/repo/model.php b/module/repo/model.php index 3f86f317c0..2e7d2ddc0f 100644 --- a/module/repo/model.php +++ b/module/repo/model.php @@ -230,36 +230,32 @@ class repoModel extends model return false; } - $response = $this->createGitlabRepo($repo, $repo->namespace); + $server = $this->loadModel('pipeline')->getByID($repo->serviceHost); - $this->loadModel($repo->SCM); + $method = $server->type == 'gitlab' ? 'createGitlabRepo' : 'createGitFoxRepo'; + $response = $this->$method($repo, $repo->namespace); + + $this->loadModel($server->type); if(!empty($response->id)) { - // $this->loadModel('action')->create($repo->SCM . 'project', $response->id, 'created', '', $repo->name); $repo->path = $response->path; $repo->serviceProject = $response->serviceProject; $repo->extra = $response->extra; - - if(in_array($repo->SCM, $this->config->repo->notSyncSCM)) - { - $path = $this->checkGiteaConnection($repo->SCM, $repo->name, $repo->serviceHost, $repo->serviceProject); - - if($path === false) return false; - $repo->path = $path; - } + $repo->SCM = $server->type == 'gitlab' ? 'Gitlab' : 'GitFox'; unset($repo->namespace); $repoID = $this->create($repo, false); if(dao::isError()) { - $this->{$repo->SCM}->apiDeleteProject($repo->serviceHost, $response->id); + $deleteMethod = $server->type == 'gitlab' ? 'apiDeleteProject' : 'apiDeleteRepo'; + $this->{$server->type}->$deleteMethod($repo->serviceHost, $response->id); return false; } return $repoID; } - return $this->{$repo->SCM}->apiErrorHandling($response); + return $this->{$server->type}->apiErrorHandling($response); } /** @@ -271,13 +267,13 @@ class repoModel extends model * @access public * @return object|false */ - public function createGitlabRepo(object $repo, int $namespace): object|false + public function createGitlabRepo(object $repo, string $namespace): object|false { $project = new stdclass(); $project->name = $repo->name; $project->path = $repo->name; $project->description = $repo->desc; - $project->namespace_id = $namespace; + $project->namespace_id = (int)$namespace; $project->initialize_with_readme = true; $response = $this->loadModel('gitlab')->apiCreateProject($repo->serviceHost, $project); @@ -293,6 +289,36 @@ class repoModel extends model return $result; } + /** + * 创建gitfox远程版本库。 + * Create gitfox repo. + * + * @param object $repo + * @param int $namespace + * @access public + * @return object|false + */ + public function createGitFoxRepo(object $repo, string $namespace): object|false + { + $project = new stdclass(); + $project->identifier = $repo->name; + $project->description = $repo->desc; + $project->parent_ref = (string)$namespace; + $project->readme = true; + + $response = $this->loadModel('gitfox')->apiCreateRepo($repo->serviceHost, $project); + + if(empty($response->id)) return $response; + + $result = new stdclass(); + $result->id = $response->id; + $result->path = $response->git_url; + $result->serviceProject = $response->id; + $result->extra = $response->id; + + return $result; + } + /** * 批量创建版本库。 * Batch create repos. @@ -2376,6 +2402,24 @@ class repoModel extends model return $options; } + /** + * Get gitfox groups. + * + * @param int $gitfoxID + * @access public + * @return void + */ + public function getGitFoxGroups(int $gitfoxID): array + { + $groups = $this->loadModel('gitfox')->apiGetGroups($gitfoxID, 'identifier_asc'); + $options = array(); + foreach($groups as $group) + { + $options[] = array('text' => $group->identifier, 'value' => $group->id); + } + return $options; + } + /** * Get gitea groups. * diff --git a/module/repo/ui/createrepo.html.php b/module/repo/ui/createrepo.html.php index 5578eb15b5..52b1bd54fd 100644 --- a/module/repo/ui/createrepo.html.php +++ b/module/repo/ui/createrepo.html.php @@ -80,19 +80,6 @@ formPanel set::items($repoGroups), set::control("picker") ), - formRow - ( - ($config->inContainer || $config->inQuickon) ? setClass('hidden') : setClass('hide-service'), - set::style(array('display' => $server && $server->type == 'gitlab' ? 'none' : 'flex')), - formGroup - ( - set::width('1/2'), - set::name("client"), - set::label($lang->repo->client), - set::required(true), - set::placeholder($lang->repo->example->client->git) - ) - ), formGroup ( set::width('1/2'), diff --git a/module/repo/zen.php b/module/repo/zen.php index 5227170be8..9611db6986 100644 --- a/module/repo/zen.php +++ b/module/repo/zen.php @@ -415,7 +415,7 @@ class repoZen extends repo $gitlabHosts = $this->loadModel('gitlab')->getPairs(); $gitfoxHosts = $this->loadModel('gitfox')->getPairs(); - $serviceHosts = array_merge($gitlabHosts, $gitfoxHosts); + $serviceHosts = $gitlabHosts + $gitfoxHosts; $repoGroups = array(); @@ -423,8 +423,6 @@ class repoZen extends repo { $serverID = array_keys($serviceHosts)[0]; $repoGroups = $this->repo->getGroups($serverID); - $server = $this->loadModel('pipeline')->getByID($serverID); - $this->view->server = $server; } $this->view->title = $this->lang->repo->common . $this->lang->colon . $this->lang->repo->create;