Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into importExport

This commit is contained in:
tanghucheng
2022-07-20 16:02:00 +08:00
150 changed files with 4199 additions and 1738 deletions
+3
View File
@@ -377,6 +377,7 @@ $config->objectTables['gitlab'] = TABLE_PIPELINE;
$config->objectTables['jebkins'] = TABLE_PIPELINE;
$config->objectTables['stage'] = TABLE_STAGE;
$config->objectTables['apistruct'] = TABLE_APISTRUCT;
$config->objectTables['repo'] = TABLE_REPO;
$config->newFeatures = array('introduction', 'tutorial', 'youngBlueTheme', 'visions');
@@ -388,3 +389,5 @@ $config->programPriv->scrum = array('story', 'projectstory', 'projectrelease
$config->programPriv->waterfall = array_merge($config->programPriv->scrum, array('task', 'workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'issue', 'risk', 'opportunity', 'measrecord', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport'));
$config->waterfallModules = array('workestimation', 'durationestimation', 'budget', 'programplan', 'review', 'reviewissue', 'weekly', 'cm', 'milestone', 'design', 'opportunity', 'auditplan', 'trainplan', 'gapanalysis', 'pssp', 'researchplan', 'researchreport');
$config->showMainMenu = true;
+3
View File
@@ -0,0 +1,3 @@
ALTER TABLE `zt_mr` CHANGE COLUMN `gitlabID` `hostID` mediumint(8) UNSIGNED NOT NULL AFTER `id`;
ALTER TABLE `zt_mr` MODIFY COLUMN `sourceProject` varchar(50) NOT NULL AFTER `hostID`;
ALTER TABLE `zt_mr` MODIFY COLUMN `targetProject` varchar(50) NOT NULL AFTER `sourceBranch`;
+3 -3
View File
@@ -955,10 +955,10 @@ CREATE TABLE IF NOT EXISTS `zt_module` (
-- DROP TABLE IF EXISTS `zt_mr`;
CREATE TABLE IF NOT EXISTS `zt_mr` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`gitlabID` mediumint(8) unsigned NOT NULL,
`sourceProject` int unsigned NOT NULL,
`hostID` mediumint(8) unsigned NOT NULL,
`sourceProject` varchar(50) NOT NULL,
`sourceBranch` varchar(100) NOT NULL,
`targetProject` int unsigned NOT NULL,
`targetProject` varchar(50) NOT NULL,
`targetBranch` varchar(100) NOT NULL,
`mriid` int unsigned NOT NULL,
`title` varchar(255) NOT NULL,
+14
View File
@@ -658,6 +658,20 @@ class baseRouter
$_POST = validater::filterSuper($_POST);
$_GET = validater::filterSuper($_GET);
$_COOKIE = validater::filterSuper($_COOKIE);
/* Filter common get and cookie vars. */
if($this->config->framework->filterParam == 2)
{
global $filter;
foreach($filter->default->get as $key => $rules)
{
if(isset($_GET[$key]) and !validater::checkByRule($_GET[$key], $rules)) unset($_GET[$key]);
}
foreach($filter->default->cookie as $key => $rules)
{
if(isset($_COOKIE[$key]) and !validater::checkByRule($_COOKIE[$key], $rules)) unset($_COOKIE[$key]);
}
}
}
/**
+815
View File
@@ -0,0 +1,815 @@
<?php
class gitea
{
public $client;
public $projectID;
private $pageLimit = 50;
/**
* Construct
*
* @param string $client gitea api url.
* @param string $root id of gitea project.
* @param string $username null
* @param string $password token of gitea api.
* @param string $encoding
* @access public
* @return void
*/
public function __construct($client, $root, $username, $password, $encoding = 'UTF-8')
{
$this->client = $client;
$this->root = rtrim($root, '/') . '/';
$this->token = $password;
$this->branch = isset($_COOKIE['repoBranch']) ? $_COOKIE['repoBranch'] : 'HEAD';
}
/**
* List files.
*
* @param string $path
* @param string $revision
* @access public
* @return array
*/
public function ls($path, $revision = 'HEAD')
{
if(!scm::checkRevision($revision)) return array();
$api = "contents";
$path = ltrim($path, '/');
if($path) $api .= "/$path";
$param = new stdclass();
$param->ref = $revision;
$param->recursive = 0;
if(!empty($this->branch)) $param->ref = $this->branch;
$list = $this->fetch($api, $param, true);
if(empty($list)) return array();
$infos = array();
foreach($list as $file)
{
if(!isset($file->type)) continue;
$info = new stdClass();
$info->name = $file->name;
$info->kind = $file->type;
if($file->type == 'file')
{
$file = $this->files($file->path, $this->branch);
$info->revision = zget($file, 'revision', '');
$info->comment = zget($file, 'comment', '');
$info->account = zget($file, 'committer', '');
$info->date = zget($file, 'date', '');
$info->size = zget($file, 'size', '');
}
else
{
$commits = $this->getCommitsByPath($file->path, '', '', 1, 1);
if(empty($commits) or !is_array($commits)) continue;
$commit = $commits[0];
$info->revision = $commit->sha;
$info->comment = $commit->commit->message;
$info->account = $commit->commit->author->name;
$info->date = date('Y-m-d H:i:s', strtotime($commit->commit->author->date));
$info->size = 0;
}
$infos[] = $info;
unset($info);
}
/* Sort by kind */
foreach($infos as $key => $info) $kinds[$key] = $info->kind;
if($infos) array_multisort($kinds, SORT_ASC, $infos);
return $infos;
}
/**
* Get files info.
*
* The API path requested is: "GET /projects/:id/repository/files/:file_path".
* Known issue of GitLab API: if a '%' in 'file_path', GitLab API will show a error 'file_path should be a valid file path'.
*
* @param string $path
* @param string $ref
* @access public
* @return object
* @doc https://docs.gitea.com/ee/api/repository_files.html
*/
public function files($path, $ref = 'master')
{
$path = urlencode($path);
$api = "contents/$path";
$file = $this->fetch($api, array('ref' => $ref));
if(!isset($file->name)) return false;
$commits = $this->getCommitsByPath($path, '', '', 1, 1);
$file->revision = $file->sha;
$file->size = $this->formatBytes($file->size);
if(!empty($commits))
{
$commit = $commits[0];
$file->revision = $commit->sha;
$file->committer = $commit->commit->author->name;
$file->comment = $commit->commit->message;
$file->date = date('Y-m-d H:i:s', strtotime($commit->commit->author->date));
}
return $file;
}
/**
* Get tags
*
* @param string $path
* @param string $revision
* @access public
* @return array
*/
public function tags($path, $revision = 'HEAD')
{
$api = "tags";
$tags = array();
$params = array();
$params['limit'] = $this->pageLimit;
for($page = 1; true; $page ++)
{
$params['page'] = $page;
$list = $this->fetch($api, $params);
if(empty($list) or $list == '[]') break;
foreach($list as $tag) $tags[] = $tag->name;
if(count($list) < $params['limit']) break;
}
return $tags;
}
/**
* Get branches.
*
* @access public
* @return array
*/
public function branch()
{
/* Max size of limit in gitea API is 50. */
$params = array();
$params['limit'] = $this->pageLimit;
/* Get default branch. */
$project = $this->fetch('');
$defaultBranch = $project->default_branch;
$branches = array();
$default = array();
for($page = 1; true; $page ++)
{
$params['page'] = $page;
$branchList = $this->fetch("branches", $params);
if(empty($branchList)) break;
foreach($branchList as $branch)
{
if(!isset($branch->name)) continue;
if($branch->name == $defaultBranch)
{
$default[$branch->name] = $branch->name;
}
else
{
$branches[$branch->name] = $branch->name;
}
}
/* Last page. */
if(count($branchList) < $params['limit']) break;
}
if(empty($branches) and empty($default)) $branches['master'] = 'master';
asort($branches);
$branches = $default + $branches;
return $branches;
}
/**
* Get last log.
*
* @param string $path
* @param int $count
* @access public
* @return array
*/
public function getLastLog($path, $count = 10)
{
return $this->log($path);
}
/**
* Get logs.
*
* @param string $path
* @param string $fromRevision
* @param string $toRevision
* @param int $count
* @access public
* @return array
*/
public function log($path, $fromRevision = 0, $toRevision = 'HEAD', $count = 0)
{
if(!scm::checkRevision($fromRevision)) return array();
if(!scm::checkRevision($toRevision)) return array();
$path = ltrim($path, DIRECTORY_SEPARATOR);
$count = $count == 0 ? '' : "-n $count";
$list = $this->getCommitsByPath($path, $fromRevision, $toRevision, 1, 1);
foreach($list as $commit)
{
if(isset($commit->sha)) $commit->diffs = $this->getFilesByCommit($commit->sha);
}
return $this->parseLog($list);
}
/**
* Blame file
*
* @param string $path
* @param string $revision
* @access public
* @return array
*/
public function blame($path, $revision)
{
return array();
}
/**
* Diff file.
*
* @param string $path
* @param string $fromRevision
* @param string $toRevision
* @param string $fromProject
* @param string $extra
* @access public
* @return array
*/
public function diff($path, $fromRevision, $toRevision, $fromProject = '', $extra = '')
{
if(!scm::checkRevision($fromRevision) and $extra != 'isBranchOrTag') return array();
if(!scm::checkRevision($toRevision) and $extra != 'isBranchOrTag') return array();
$diffApi = "{$this->root}git/commits/$toRevision.diff?token={$this->token}";
$diffs = commonModel::http($diffApi);
$lines = explode("\n", $diffs);
return $lines;
}
/**
* Cat file.
*
* @param string $entry
* @param string $revision
* @access public
* @return string
*/
public function cat($entry, $revision = 'HEAD')
{
if(!scm::checkRevision($revision)) return false;
if($revision == 'HEAD' and $this->branch) $revision = $this->branch;
$file = $this->files($entry, $revision);
return base64_decode($file->content);
}
/**
* Get info.
*
* @param string $entry
* @param string $revision
* @access public
* @return object
*/
public function info($entry, $revision = 'HEAD')
{
if(!scm::checkRevision($revision)) return false;
$info = new stdclass();
$info->kind = 'dir';
$info->path = $entry;
$info->revision = $revision;
$info->root = '';
if($revision == 'HEAD' and $this->branch) $info->revision = $this->branch;
if($entry)
{
$parent = dirname($entry);
if($parent == '.') $parent = '/';
if($parent == '') $parent = '/';
$list = $this->tree($parent, 0);
$file = new stdclass();
foreach($list as $node) if($node->path == $entry) $file = $node;
$commits = $this->getCommitsByPath($entry);
if(!empty($commits)) $file->revision = zget($commits[0], 'id', '');
$info->kind = (isset($file->type) and $file->type == 'tree') ? 'dir' : 'file';
}
return $info;
}
/**
* Exec git cmd.
*
* @param string $cmd
* @access public
* @todo Exec commands by gitea api.
* @return array
*/
public function exec($cmd)
{
return execCmd(escapeCmd("$this->client $cmd"), 'array');
}
/**
* Parse diff.
*
* @param array $lines
* @access public
* @return array
*/
public function parseDiff($lines)
{
if(empty($lines)) return array();
$diffs = array();
$num = count($lines);
$endLine = end($lines);
if(strpos($endLine, '\ No newline at end of file') === 0) $num -= 1;
$newFile = false;
$allFiles = array();
for($i = 0; $i < $num; $i ++)
{
$diffFile = new stdclass();
if(strpos($lines[$i], "diff --git ") === 0)
{
$fileInfo = explode(' ',$lines[$i]);
$fileName = substr($fileInfo[2], strpos($fileInfo[2], '/') + 1);
/* Prevent duplicate display of files. */
if(in_array($fileName, $allFiles)) continue;
$allFiles[] = $fileName;
$diffFile->fileName = $fileName;
for($i++; $i < $num; $i ++)
{
$diff = new stdclass();
/* Fix bug #1757. */
if($lines[$i] == '+++ /dev/null') $newFile = true;
if(strpos($lines[$i], '+++', 0) !== false) continue;
if(strpos($lines[$i], '---', 0) !== false) continue;
if(strpos($lines[$i], '======', 0) !== false) continue;
if(preg_match('/^@@ -(\\d+)(,(\\d+))?\\s+\\+(\\d+)(,(\\d+))?\\s+@@/A', $lines[$i]))
{
$startLines = trim(str_replace(array('@', '+', '-'), '', $lines[$i]));
list($oldStartLine, $newStartLine) = explode(' ', $startLines);
list($diff->oldStartLine) = explode(',', $oldStartLine);
list($diff->newStartLine) = explode(',', $newStartLine);
$oldCurrentLine = $diff->oldStartLine;
$newCurrentLine = $diff->newStartLine;
if($newFile)
{
$oldCurrentLine = $diff->newStartLine;
$newCurrentLine = $diff->oldStartLine;
}
$newLines = array();
for($i++; $i < $num; $i ++)
{
if(preg_match('/^@@ -(\\d+)(,(\\d+))?\\s+\\+(\\d+)(,(\\d+))?\\s+@@/A', $lines[$i]))
{
$i --;
break;
}
if(strpos($lines[$i], "diff --git ") === 0) break;
$line = $lines[$i];
if(strpos($line, '\ No newline at end of file') === 0)continue;
$sign = empty($line) ? '' : $line[0];
if($sign == '-' and $newFile) $sign = '+';
$type = $sign != '-' ? $sign == '+' ? 'new' : 'all' : 'old';
if($sign == '-' || $sign == '+')
{
$line = substr_replace($line, ' ', 1, 0);
if($newFile) $line = preg_replace('/^\-/', '+', $line);
}
$newLine = new stdclass();
$newLine->type = $type;
$newLine->oldlc = $type != 'new' ? $oldCurrentLine : '';
$newLine->newlc = $type != 'old' ? $newCurrentLine : '';
$newLine->line = htmlSpecialString($line);
if($type != 'new') $oldCurrentLine++;
if($type != 'old') $newCurrentLine++;
$newLines[] = $newLine;
}
$diff->lines = $newLines;
$diffFile->contents[] = $diff;
}
if(isset($lines[$i]) and strpos($lines[$i], "diff --git ") === 0)
{
$i --;
$newFile = false;
break;
}
}
$diffs[] = $diffFile;
}
}
return $diffs;
}
/**
* Get commit count.
*
* @param int $commits
* @param string $lastVersion
* @access public
* @return int
*/
public function getCommitCount($commits = 0, $lastVersion = '')
{
if(!scm::checkRevision($lastVersion)) return false;
chdir($this->root);
$revision = $this->branch ? $this->branch : 'HEAD';
return execCmd(escapeCmd("$this->client rev-list --count $revision -- ./"), 'string');
}
/**
* Get first revision.
*
* @access public
* @return string
*/
public function getFirstRevision()
{
chdir($this->root);
$list = execCmd(escapeCmd("$this->client rev-list --reverse HEAD -- ./"), 'array');
return $list[0];
}
/**
* Get latest revision
*
* @access public
* @return string
*/
public function getLatestRevision()
{
chdir($this->root);
$revision = $this->branch ? $this->branch : 'HEAD';
$list = execCmd(escapeCmd("$this->client rev-list -1 $revision -- ./"), 'array');
return $list[0];
}
/**
* Get commits.
*
* @param string $version
* @param int $count
* @param string $branch
* @access public
* @return array
*/
public function getCommits($version = '', $count = 0, $branch = '')
{
if(!scm::checkRevision($version)) return array();
$api = "commits";
$commits = array();
$files = array();
if(empty($count)) $count = $this->pageLimit;
if(!empty($version) and $count == 1)
{
$commits = $this->fetch($api, array('limit' => 1, 'sha' => $version));
$commit = $commits[0];
if(isset($commit->sha))
{
$log = new stdclass;
$log->committer = $commit->commit->author->name;
$log->revision = $commit->sha;
$log->comment = $commit->commit->message;
$log->time = date('Y-m-d H:i:s', strtotime($commit->commit->author->date));
$commits[$commit->sha] = $log;
$files[$commit->sha] = $this->getFilesByCommit($log->revision);
return array('commits' => $commits, 'files' => $files);
}
}
$params['sha'] = $branch;
if($version and $version != 'HEAD')
{
/* Get since param. */
if(substr($version, 0, 5) == 'since')
{
$since = true;
$version = substr($version, 5);
}
$committedDate = $this->getCommittedDate($version);
if(!$committedDate) return array('commits' => array(), 'files' => array());
if(!empty($since))
{
$params['since'] = $committedDate;
}
else
{
$params['until'] = $committedDate;
}
}
$list = $this->fetch($api, $params);
foreach($list as $commit)
{
if(!isset($commit->commit) or !is_object($commit->commit)) continue;
$log = new stdclass;
$log->committer = $commit->commit->author->name;
$log->revision = $commit->sha;
$log->comment = $commit->commit->message;
$log->time = date('Y-m-d H:i:s', strtotime($commit->commit->author->date));
$commits[$commit->sha] = $log;
$files[$commit->sha] = $this->getFilesByCommit($log->revision);
}
return array('commits' => $commits, 'files' => $files);
}
/**
* getCommit
*
* @param int $sha
* @access public
* @return void
*/
public function getCommittedDate($sha)
{
if(!scm::checkRevision($sha)) return null;
if(!$sha or $sha == 'HEAD') return date('c');
global $dao;
$time = $dao->select('time')->from(TABLE_REPOHISTORY)->where('revision')->eq($sha)->fetch('time');
if($time) return date('c', strtotime($time));
$params = array();
$params['sha'] = $sha;
$params['limit'] = 1;
$result = $this->fetch("commits", $params);
return (isset($resulti[0]->created)) ? date('Y-m-d H:i:s', strtotime($result->created)) : false;
}
/**
* Get commits by path.
*
* @param string $path
* @param string $fromRevision
* @param string $toRevision
* @param int $perPage
* @access public
* @return array
*/
public function getCommitsByPath($path, $fromRevision = '', $toRevision = '', $perPage = 0, $limit = 0)
{
$path = ltrim($path, DIRECTORY_SEPARATOR);
$api = "commits";
if(!$limit) $limit = $this->pageLimit;
$param = new stdclass();
$param->path = urldecode($path);
$param->limit = $limit;
$param->sha = ($toRevision != 'HEAD' and $toRevision) ? $toRevision : $this->branch;
if($perPage) $param->page = $perPage;
return $this->fetch($api, $param);
}
/**
* Get diff files by reviesion.
*
* @param int $reviesion
* @access public
* @return array
*/
public function getDiffFiles($revision)
{
$diffApi = "{$this->root}git/commits/$revision.patch?token={$this->token}";
$diffs = commonModel::http($diffApi);
$newFiles = array();
$delFiles = array();
if(!empty($diffs))
{
$diffs = explode("\n", $diffs);
foreach($diffs as $row)
{
preg_match('/^(\s)(create|delete)\smode\s\d+\s(.+)$/', $row, $matches);
if(count($matches) == 4 and !in_array($matches[3], $newFiles) and !in_array($matches[3], $delFiles))
{
if($matches[2] == 'create')
{
$newFiles[] = $matches[3];
}
elseif($matches[2] == 'delete')
{
$delFiles[] = $matches[3];
}
}
}
}
return array('newFiles' => $newFiles, 'delFiles' => $delFiles);
}
/**
* Get files by commit.
*
* @param string $commit
* @access public
* @return void
*/
public function getFilesByCommit($revision)
{
if(!scm::checkRevision($revision)) return array();
$api = "git/commits/$revision";
$results = $this->fetch($api);
if(empty($results)) return array();
$diffFiles = $this->getDiffFiles($revision);
$files = array();
foreach($results->files as $row)
{
$file = new stdclass();
$file->revision = $revision;
$file->type = 'file';
$file->path = '/' . $row->filename;
$file->action = 'M';
if(in_array($row->filename, $diffFiles['newFiles']))
{
$file->action = 'A';
}
elseif(in_array($row->filename, $diffFiles['delFiles']))
{
$file->action = 'D';
}
$files[] = $file;
}
return $files;
}
/**
* Repository/tree api.
*
* @param string $path
* @param bool $recursive
* @access public
* @return mixed
*/
public function tree($path, $recursive = 1)
{
$api = "contents";
$params = array();
$params['path'] = ltrim($path, '/');
$params['ref'] = $this->branch;
$params['recursive'] = (int) $recursive;
return $this->fetch($api, $params);
}
/**
* Fetch data from gitea api.
*
* @param string $api
* @access public
* @return mixed
*/
public function fetch($api, $params = array(), $needToLoop = false)
{
$params = (array) $params;
$params['token'] = $this->token;
$params['limit'] = isset($params['limit']) ? $params['limit'] : $this->pageLimit;
$api = ltrim($api, '/');
$api = $this->root . $api . '?' . http_build_query($params);
if($needToLoop)
{
$allResults = array();
for($page = 1; true; $page++)
{
$results = json_decode(commonModel::http($api . "&page={$page}"));
if(!is_array($results)) break;
if(!empty($results)) $allResults = array_merge($allResults, $results);
if(count($results) < $this->pageLimit) break;
}
return $allResults;
}
else
{
$response = commonModel::http($api);
if(!empty(commonModel::$requestErrors))
{
commonModel::$requestErrors = array();
return array();
}
return json_decode($response);
}
}
/**
* Format bytes shown.
*
* @param int $size
* @static
* @access public
* @return string
*/
public static function formatBytes($size)
{
if($size < 1024) return $size . 'Bytes';
if(round($size / (1024 * 1024), 2) > 1) return round($size / (1024 * 1024), 2) . 'G';
if(round($size / 1024, 2) > 1) return round($size / 1024, 2) . 'M';
return round($size, 2) . 'KB';
}
/**
* Parse log.
*
* @param array $logs
* @access public
* @return array
*/
public function parseLog($logs)
{
$parsedLogs = array();
$i = 0;
foreach($logs as $commit)
{
if(!isset($commit->sha)) continue;
$parsedLog = new stdclass();
$parsedLog->revision = $commit->sha;
$parsedLog->committer = $commit->commit->author->name;
$parsedLog->time = date('Y-m-d H:i:s', strtotime($commit->commit->author->date));
$parsedLog->comment = $commit->commit->message;
$parsedLog->change = array();
foreach($commit->diffs as $diff)
{
$parsedLog->change[$diff->path] = array();
$parsedLog->change[$diff->path]['action'] = $diff->action;
$parsedLog->change[$diff->path]['kind'] = $diff->type;
}
$parsedLogs[] = $parsedLog;
}
return $parsedLogs;
}
/**
* Get download url.
*
* @param string $branch
* @param string $ext
* @access public
* @return string
*/
public function getDownloadUrl($branch = 'master', $ext = 'zip')
{
$params['token'] = $this->token;
return "{$this->root}archive/" . urlencode($branch) . ".{$ext}" . '?' . http_build_query($params);
}
}
+17
View File
@@ -834,4 +834,21 @@ class gitlab
return $parsedLogs;
}
/**
* Get download url.
*
* @param string $branch
* @param string $ext
* @access public
* @return string
*/
public function getDownloadUrl($branch = 'master', $ext = 'zip')
{
$params = (array) $params;
$params['private_token'] = $this->token;
$params['sha'] = $branch;
return "{$this->root}archive.{$ext}" . '?' . http_build_query($params);
}
}
+13
View File
@@ -244,6 +244,19 @@ class scm
if(preg_match('/[^a-z0-9\-_\.\^\w][\x{4e00}-\x{9fa5}]/ui', $revision)) return false;
return true;
}
/**
* Get download url.
*
* @param string $branch
* @param string $ext
* @access public
* @return string
*/
public function getDownloadUrl($branch = '', $ext = 'zip')
{
return $this->engine->getDownloadUrl($branch, $ext);
}
}
/**
+2 -1
View File
@@ -46,6 +46,7 @@ $config->action->objectNameFields['gitlab'] = 'name';
$config->action->objectNameFields['gitea'] = 'name';
$config->action->objectNameFields['stage'] = 'name';
$config->action->objectNameFields['apistruct'] = 'name';
$config->action->objectNameFields['repo'] = 'name';
$config->action->commonImgSize = 870;
@@ -61,7 +62,7 @@ $config->action->majorList['execution'] = array('opened', 'edited');
$config->action->needGetProjectType = 'build,task,bug,case,testcase,caselib,testtask,testsuite,testreport,doc,issue,release,risk,design,opportunity,trainplan,gapanalysis,researchplan,researchreport,';
$config->action->needGetRelateField = ',story,productplan,release,task,build,bug,testcase,case,testtask,testreport,doc,doclib,issue,risk,opportunity,trainplan,gapanalysis,team,whitelist,researchplan,researchreport,meeting,kanbanlane,kanbancolumn,module,';
$config->action->noLinkModules = ',doclib,module,webhook,gitlab,gitea,sonarqube,pipeline,jenkins,kanban,kanbanspace,kanbancolumn,kanbanlane,kanbanregion,kanbancard,execution,project,traincategory,apistruct,program,product,user,entry,';
$config->action->noLinkModules = ',doclib,module,webhook,gitlab,gitea,sonarqube,pipeline,jenkins,kanban,kanbanspace,kanbancolumn,kanbanlane,kanbanregion,kanbancard,execution,project,traincategory,apistruct,program,product,user,entry,repo,';
$config->action->preferredTypeNum = 10;
+2
View File
@@ -133,6 +133,7 @@ $lang->action->objectTypes['gitlabbranch'] = 'GitLab Branch';
$lang->action->objectTypes['gitlabbranchpriv'] = 'GitLab Protected Branches';
$lang->action->objectTypes['gitlabtag'] = 'GitLab Tag';
$lang->action->objectTypes['gitlabtagpriv'] = 'GitLab Tag Protected';
$lang->action->objectTypes['giteauser'] = 'Gitea User';
$lang->action->objectTypes['kanbanspace'] = 'Kanban Space';
$lang->action->objectTypes['kanban'] = 'Kanban';
$lang->action->objectTypes['kanbanregion'] = 'Kanban Region';
@@ -143,6 +144,7 @@ $lang->action->objectTypes['sonarqube'] = 'SonarQube Server';
$lang->action->objectTypes['sonarqubeproject'] = 'SonarQube Project';
$lang->action->objectTypes['stage'] = 'Stage';
$lang->action->objectTypes['patch'] = 'Patch';
$lang->action->objectTypes['repo'] = 'Repo';
/* Used to describe operation history. */
$lang->action->desc = new stdclass();
+2
View File
@@ -133,6 +133,7 @@ $lang->action->objectTypes['gitlabbranch'] = 'GitLab Branch';
$lang->action->objectTypes['gitlabbranchpriv'] = 'GitLab Protected Branches';
$lang->action->objectTypes['gitlabtag'] = 'GitLab Tag';
$lang->action->objectTypes['gitlabtagpriv'] = 'GitLab Tag Protected';
$lang->action->objectTypes['giteauser'] = 'Gitea User';
$lang->action->objectTypes['kanbanspace'] = 'Kanban Space';
$lang->action->objectTypes['kanban'] = 'Kanban';
$lang->action->objectTypes['kanbanregion'] = 'Kanban Region';
@@ -143,6 +144,7 @@ $lang->action->objectTypes['sonarqube'] = 'SonarQube Server';
$lang->action->objectTypes['sonarqubeproject'] = 'SonarQube Project';
$lang->action->objectTypes['stage'] = 'Stage';
$lang->action->objectTypes['patch'] = 'Patch';
$lang->action->objectTypes['repo'] = 'Repo';
/* Used to describe operation history. */
$lang->action->desc = new stdclass();
+2
View File
@@ -133,6 +133,7 @@ $lang->action->objectTypes['gitlabbranch'] = 'GitLab Branch';
$lang->action->objectTypes['gitlabbranchpriv'] = 'GitLab Protected Branches';
$lang->action->objectTypes['gitlabtag'] = 'GitLab Tag';
$lang->action->objectTypes['gitlabtagpriv'] = 'GitLab Tag Protected';
$lang->action->objectTypes['giteauser'] = 'Gitea User';
$lang->action->objectTypes['kanbanspace'] = 'Kanban Space';
$lang->action->objectTypes['kanban'] = 'Kanban';
$lang->action->objectTypes['kanbanregion'] = 'Kanban Region';
@@ -143,6 +144,7 @@ $lang->action->objectTypes['sonarqube'] = 'SonarQube Server';
$lang->action->objectTypes['sonarqubeproject'] = 'SonarQube Project';
$lang->action->objectTypes['stage'] = 'Stage';
$lang->action->objectTypes['patch'] = 'Patch';
$lang->action->objectTypes['repo'] = 'Repo';
/* Used to describe operation history. */
$lang->action->desc = new stdclass();
+2
View File
@@ -111,6 +111,7 @@ $lang->action->objectTypes['gitlabbranch'] = 'GitLab Branch';
$lang->action->objectTypes['gitlabbranchpriv'] = 'GitLab Protected Branches';
$lang->action->objectTypes['gitlabtag'] = 'GitLab Tag';
$lang->action->objectTypes['gitlabtagpriv'] = 'GitLab Tag Protected';
$lang->action->objectTypes['giteauser'] = 'Gitea User';
$lang->action->objectTypes['kanbanspace'] = 'Kanban Space';
$lang->action->objectTypes['kanban'] = 'Kanban';
$lang->action->objectTypes['kanbanregion'] = 'Kanban Region';
@@ -121,6 +122,7 @@ $lang->action->objectTypes['sonarqube'] = 'SonarQube Server';
$lang->action->objectTypes['sonarqubeproject'] = 'SonarQube Project';
$lang->action->objectTypes['stage'] = 'Stage';
$lang->action->objectTypes['patch'] = 'Patch';
$lang->action->objectTypes['repo'] = 'Repo';
/* Used to describe operation history. */
$lang->action->desc = new stdclass();
+2
View File
@@ -133,6 +133,7 @@ $lang->action->objectTypes['gitlabbranch'] = 'GitLab分支';
$lang->action->objectTypes['gitlabbranchpriv'] = 'GitLab保护分支';
$lang->action->objectTypes['gitlabtag'] = 'GitLab标签';
$lang->action->objectTypes['gitlabtagpriv'] = 'GitLab标签保护';
$lang->action->objectTypes['giteauser'] = 'Gitea用户';
$lang->action->objectTypes['kanbanspace'] = '看板空间';
$lang->action->objectTypes['kanban'] = '看板';
$lang->action->objectTypes['kanbanregion'] = '看板区域';
@@ -143,6 +144,7 @@ $lang->action->objectTypes['sonarqube'] = 'SonarQube服务器';
$lang->action->objectTypes['sonarqubeproject'] = 'SonarQube项目';
$lang->action->objectTypes['stage'] = '阶段';
$lang->action->objectTypes['patch'] = '补丁';
$lang->action->objectTypes['repo'] = '代码库';
/* 用来描述操作历史记录。*/
$lang->action->desc = new stdclass();
+2
View File
@@ -127,12 +127,14 @@ $lang->action->objectTypes['gitlabgroup'] = 'GitLab群組';
$lang->action->objectTypes['gitlabbranch'] = 'GitLab分支';
$lang->action->objectTypes['gitlabbranchpriv'] = 'GitLab保護分支';
$lang->action->objectTypes['gitlabtag'] = 'GitLab標籤';
$lang->action->objectTypes['giteauser'] = 'Gitea用戶';
$lang->action->objectTypes['kanbanspace'] = '看板空間';
$lang->action->objectTypes['kanban'] = '看板';
$lang->action->objectTypes['kanbanregion'] = '看板區域';
$lang->action->objectTypes['kanbanlane'] = '看板泳道';
$lang->action->objectTypes['kanbancolumn'] = '看板列';
$lang->action->objectTypes['kanbancard'] = '看板卡片';
$lang->action->objectTypes['repo'] = '代码库';
/* 用來描述操作歷史記錄。*/
$lang->action->desc = new stdclass();
+16 -14
View File
@@ -984,13 +984,16 @@ class actionModel extends model
$executions = array();
if(!$this->app->user->admin)
{
if($productID == 'all') $authedProducts = $this->app->user->view->products;
if($projectID == 'all') $authedProjects = $this->app->user->view->projects;
if($executionID == 'all') $authedExecutions = $this->app->user->view->sprints;
$aclViews = isset($this->app->user->rights['acls']['views']) ? $this->app->user->rights['acls']['views'] : array();
if($productID == 'all') $authedProducts = (empty($aclViews) or (!empty($aclViews) and !empty($aclViews['product']))) ? $this->app->user->view->products : '0';
if($projectID == 'all') $authedProjects = (empty($aclViews) or (!empty($aclViews) and !empty($aclViews['project']))) ? $this->app->user->view->projects : '0';
if($executionID == 'all') $authedExecutions = (empty($aclViews) or (!empty($aclViews) and !empty($aclViews['execution']))) ? $this->app->user->view->sprints : '0';
if($productID == 'all' and $projectID == 'all')
{
$productCondition = "product " . helper::dbIN($authedProducts);
$productCondition = '';
foreach(explode(',', $authedProducts) as $product) $productCondition = empty($productCondition) ? "product LIKE '%,$product,%'" : "$productCondition OR product LIKE '%,$product,%'";
$projectCondition = "project " . helper::dbIN($authedProjects);
$executionCondition = isset($authedExecutions) ? "execution " . helper::dbIN($authedExecutions) : '';
}
@@ -999,7 +1002,9 @@ class actionModel extends model
$products = $this->loadModel('product')->getProductPairsByProject($projectID);
$executions = $this->loadModel('execution')->getPairs($projectID) + array(0 => 0);
$productCondition = "product " . helper::dbIN(array_keys($products));
$productCondition = '';
foreach(array_keys($products) as $product) $productCondition = empty($productCondition) ? "product LIKE '%,$product,%'" : "$productCondition OR product LIKE '%,$product,%'";
$projectCondition = "project = $projectID";
$executionCondition = "execution " . helper::dbIN(array_keys($executions));
}
@@ -1014,7 +1019,7 @@ class actionModel extends model
$executionCondition = "execution " . helper::dbIN(array_keys($executions));
}
$condition = "((product =',0,' or product=0) AND project = '0' AND execution = 0)";
$condition = "((product =',0,' or product = '0') AND project = '0' AND execution = '0')";
if(!empty($productCondition)) $condition .= ' OR ' . $productCondition;
if(!empty($projectCondition)) $condition .= ' OR ' . $projectCondition;
if(!empty($executionCondition)) $condition .= ' OR ' . $executionCondition;
@@ -1086,6 +1091,7 @@ class actionModel extends model
foreach($this->app->user->rights['acls']['actions'] as $moduleName => $actions)
{
if(isset($this->lang->mainNav->$moduleName) and !empty($this->app->user->rights['acls']['views']) and !isset($this->app->user->rights['acls']['views'][$moduleName])) continue;
$actionCondition .= "(`objectType` = '$moduleName' and `action` " . helper::dbIN($actions) . ") or ";
}
$actionCondition = trim($actionCondition, 'or ');
@@ -1254,15 +1260,11 @@ class actionModel extends model
/* If action type is login or logout, needn't link. */
if($actionType == 'svncommited' or $actionType == 'gitcommited') $action->actor = zget($commiters, $action->actor);
/* Get gitlab objectname. */
if(empty($action->objectName) and substr($objectType, 0, 6) == 'gitlab') $action->objectName = $action->extra;
/* Get gitlab or gitea objectname. */
if(empty($action->objectName) and (substr($objectType, 0, 6) == 'gitlab' or substr($objectType, 0, 5) == 'gitea')) $action->objectName = $action->extra;
/* Other actions, create a link. */
if(!$this->setObjectLink($action, $deptUsers))
{
unset($actions[$i]);
continue;
}
$this->setObjectLink($action, $deptUsers);
/* Set merge request link. */
if(empty($action->objectName) and $action->objectType == 'mr') $action->objectLink = '';
@@ -1437,7 +1439,6 @@ class actionModel extends model
/* Fix bug #2961. */
$isLoginOrLogout = $action->objectType == 'user' and ($action->action == 'login' or $action->action == 'logout');
if(!common::hasPriv($moduleName, $methodName) and !$isLoginOrLogout) return false;
$action->objectLabel = $objectLabel;
$action->product = trim($action->product, ',');
@@ -1536,6 +1537,7 @@ class actionModel extends model
$action->objectLink = !isset($deptUsers[$action->objectID]) ? 'javascript:void(0)' : helper::createLink($moduleName, $methodName, sprintf($vars, $action->objectID));
}
}
if(!common::hasPriv($moduleName, $methodName) and !$isLoginOrLogout) $action->objectLink = '';
}
elseif($action->objectType == 'team')
{
+1 -1
View File
@@ -25,7 +25,7 @@
$class = $action->major ? "class='active'" : '';
echo "<li $class><div>";
if($action->objectLink) printf($lang->block->dynamicInfo, $action->date, $user, $action->actionLabel, $action->objectLabel, $action->objectLink, $action->objectName, $action->objectName);
if(!$action->objectLink) printf($lang->block->noLinkDynamic, $action->date, $action->objectName, $user, $action->actionLabel, $action->objectLabel, $action->objectName);
if(!$action->objectLink) printf($lang->block->noLinkDynamic, $action->date, $action->objectName, $user, $action->actionLabel, $action->objectLabel, ' ' . $action->objectName);
echo "</div></li>";
$i++;
}
+18
View File
@@ -740,6 +740,24 @@ class bugModel extends model
$this->linkBugToBuild($bugID, $bug->resolvedBuild);
}
$linkBugs = explode(',', $bug->linkBug);
$oldLinkBugs = explode(',', $oldBug->linkBug);
$addBugs = array_diff($linkBugs, $oldLinkBugs);
$removeBugs = array_diff($oldLinkBugs, $linkBugs);
$changeBugs = array_merge($addBugs, $removeBugs);
$changeBugs = $this->dao->select('id,linkbug')->from(TABLE_BUG)->where('id')->in(array_filter($changeBugs))->fetchPairs();
foreach($changeBugs as $changeBugID => $changeBug)
{
if(in_array($changeBugID, $addBugs) and empty($changeBug)) $this->dao->update(TABLE_BUG)->set('linkBug')->eq($bugID)->where('id')->eq((int)$changeBugID)->exec();
if(in_array($changeBugID, $addBugs) and !empty($changeBug)) $this->dao->update(TABLE_BUG)->set('linkBug')->eq("$changeBug,$bugID")->where('id')->eq((int)$changeBugID)->exec();
if(in_array($changeBugID, $removeBugs))
{
$linkBugs = explode(',', $changeBug);
unset($linkBugs[array_search($bugID, $linkBugs)]);
$this->dao->update(TABLE_BUG)->set('linkBug')->eq(implode(',', $linkBugs))->where('id')->eq((int)$changeBugID)->exec();
}
}
if(!empty($bug->resolvedBy)) $this->loadModel('score')->create('bug', 'resolve', $bugID);
$this->file->updateObjectID($this->post->uid, $bugID, 'bug');
+7 -1
View File
@@ -26,7 +26,13 @@ class ciModel extends model
}
common::setMenuVars('devops', $this->session->repoID);
$this->lang->switcherMenu = $this->loadModel('repo')->getSwitcher($this->session->repoID);
if($this->session->repoID)
{
$repo = $this->loadModel('repo')->getRepoByID($this->session->repoID);
if(!in_array(strtolower($repo->SCM), $this->config->repo->gitServiceList)) unset($this->lang->devops->menu->mr);
$this->lang->switcherMenu = $this->loadModel('repo')->getSwitcher($this->session->repoID);
}
}
/**
+1
View File
@@ -150,6 +150,7 @@ $lang->openedByAB = 'Ersteller';
$lang->assignedToAB = 'Bearbeiter';
$lang->typeAB = 'Typ';
$lang->nameAB = 'Name';
$lang->code = 'Code';
$lang->pri = 'Priority';
$lang->delayed = 'Delayed';
+1
View File
@@ -150,6 +150,7 @@ $lang->openedByAB = 'CreatedBy';
$lang->assignedToAB = 'AssignedTo';
$lang->typeAB = 'Type';
$lang->nameAB = 'Name';
$lang->code = 'Code';
$lang->pri = 'Priority';
$lang->delayed = 'Delayed';
+1
View File
@@ -150,6 +150,7 @@ $lang->openedByAB = 'Créé par';
$lang->assignedToAB = 'Affecté à';
$lang->typeAB = 'Type';
$lang->nameAB = 'Name';
$lang->code = 'Code';
$lang->pri = 'Priority';
$lang->delayed = 'Delayed';
+5 -2
View File
@@ -488,7 +488,7 @@ $lang->admin->menu = new stdclass();
$lang->admin->menu->index = array('link' => "$lang->indexPage|admin|index", 'alias' => 'register,certifytemail,certifyztmobile,ztcompany');
$lang->admin->menu->company = array('link' => "{$lang->personnel->common}|company|browse|", 'subModule' => ',user,dept,group,');
$lang->admin->menu->model = array('link' => "$lang->model|custom|browsestoryconcept|", 'class' => 'dropdown dropdown-hover', 'exclude' => 'custom-index,custom-set,custom-product,custom-execution,custom-kanban,custom-required,custom-flow,custom-score,custom-feedback,custom-timezone,custom-mode');
$lang->admin->menu->custom = array('link' => "{$lang->custom->common}|custom|index", 'exclude' => 'custom-browsestoryconcept,custom-timezone,custom-estimate');
$lang->admin->menu->custom = array('link' => "{$lang->custom->common}|custom|index", 'exclude' => 'custom-browsestoryconcept,custom-timezone,custom-estimate,custom-code');
$lang->admin->menu->extension = array('link' => "{$lang->extension->common}|extension|browse", 'subModule' => 'extension');
$lang->admin->menu->dev = array('link' => "$lang->redev|dev|api", 'alias' => 'db', 'subModule' => 'dev,editor,entry');
$lang->admin->menu->message = array('link' => "{$lang->message->common}|message|index", 'subModule' => 'message,mail,webhook');
@@ -506,7 +506,10 @@ if($config->systemMode == 'new')
$lang->admin->menu->allModel['subMenu'] = new stdclass();
$lang->admin->menu->allModel['subMenu']->storyConcept = array('link' => "{$lang->storyConcept}|custom|browsestoryconcept|");
$lang->admin->menu->allModel['menuOrder'][5] = 'storyConcept';
$lang->admin->menu->allModel['subMenu']->code = array('link' => "{$lang->code}|custom|code|");
$lang->admin->menu->allModel['menuOrder'][5] = 'storyConcept';
$lang->admin->menu->allModel['menuOrder'][30] = 'code';
$lang->admin->menu->waterfall['subMenu'] = new stdclass();
$lang->admin->menu->waterfall['subMenu']->stage = array('link' => "{$lang->stage->common}|stage|setType|", 'subModule' => 'stage');
+1
View File
@@ -150,6 +150,7 @@ $lang->openedByAB = '创建';
$lang->assignedToAB = '指派';
$lang->typeAB = '类型';
$lang->nameAB = '名称';
$lang->code = '代号';
$lang->pri = '优先级';
$lang->delayed = '已延期';
+6 -4
View File
@@ -2379,8 +2379,7 @@ EOD;
}
$referer = helper::safe64Encode($uri);
print(js::locate(helper::createLink('user', 'login', "referer=$referer")));
helper::end();
die(js::locate(helper::createLink('user', 'login', "referer=$referer")));
}
}
catch(EndResponseException $endResponseException)
@@ -3084,11 +3083,13 @@ EOD;
* @param string|array $data
* @param array $options This is option and value pair, like CURLOPT_HEADER => true. Use curl_setopt function to set options.
* @param array $headers Set request headers.
* @param string $dataType
* @param string $method POST|PATCH|PUT
* @static
* @access public
* @return string
*/
public static function http($url, $data = null, $options = array(), $headers = array(), $dataType = 'data')
public static function http($url, $data = null, $options = array(), $headers = array(), $dataType = 'data', $method = 'POST')
{
global $lang, $app;
if(!extension_loaded('curl'))
@@ -3125,7 +3126,8 @@ EOD;
if(!empty($data))
{
if(is_object($data)) $data = (array) $data;
curl_setopt($curl, CURLOPT_POST, true);
if($method == 'POST') curl_setopt($curl, CURLOPT_POST, true);
if(in_array($method, array('PATCH', 'PUT'))) curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
+6
View File
@@ -7,6 +7,7 @@ include 'chosen.html.php';
<?php if(empty($_GET['onlybody']) or $_GET['onlybody'] != 'yes'):?>
<?php $this->app->loadConfig('sso');?>
<?php if(!empty($config->sso->redirect)) js::set('ssoRedirect', $config->sso->redirect);?>
<?php if($config->showMainMenu):?>
<header id='header'>
<div id='mainHeader'>
<div class='container'>
@@ -44,6 +45,11 @@ include 'chosen.html.php';
}
?>
</header>
<?php else:?>
<header id='header'>
<div id='mainHeader' style="height: 0;"></div>
</header>
<?php endif;?>
<?php endif;?>
<script>
+10 -1
View File
@@ -36,7 +36,16 @@ $uid = uniqid('');
'indent', 'outdent', 'subscript', 'superscript', '|',
'table', 'code', 'pagebreak',
'fullscreen', 'source', 'preview', 'about'];
var editorToolsMap = {fullTools: fullTools, simpleTools: simpleTools, bugTools: bugTools};
var docTools =
[ 'formatblock', 'fontname', 'fontsize', 'lineheight', '|', 'forecolor', 'hilitecolor', '|', 'bold', 'italic','underline', 'strikethrough', '|',
'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', '|',
'insertorderedlist', 'insertunorderedlist', '|',
'emoticons', 'image', 'insertfile', 'hr', '|', 'link', '|',
'undo', 'redo', '|', 'selectall', 'cut', 'copy', 'paste', '|', 'plainpaste', 'wordpaste', '|', 'removeformat', 'clearhtml','quickformat', '|',
'indent', 'outdent', 'subscript', 'superscript', '|',
'table', 'code', 'pagebreak',
'source'];
var editorToolsMap = {fullTools: fullTools, simpleTools: simpleTools, bugTools: bugTools, docTools: docTools};
/* Kindeditor default options. */
var editorDefaults =
+2
View File
@@ -46,6 +46,8 @@ class compile extends control
$this->view->job = $job;
}
$this->app->loadLang('job');
$this->loadModel('ci')->setMenu($repoID);
$this->app->loadClass('pager', $static = true);
+19
View File
@@ -848,4 +848,23 @@ class custom extends control
$this->loadModel('setting')->deleteItems("owner=system&module={$module}&key=requiredFields");
return print(js::reload('parent.parent'));
}
/**
* Set code.
*
* @access public
* @return void
*/
public function code()
{
if($_POST)
{
$this->loadModel('setting')->setItem('system.common.setCode', $this->post->code);
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'reload'));
}
$this->view->title = $this->lang->custom->code;
$this->display();
}
}
+5
View File
@@ -0,0 +1,5 @@
#readOnlyOfCode {font-size: 13px; color: #5e626d; display: flex; width: 200%;}
#readOnlyOfCode i {font-size: 14px; color: #0075ff; margin-right: 3px;}
.c-setCode {width: 150px !important;}
[lang^=en] .c-setCode, [lang^=de] .c-setCode {width: 160px !important;}
[lang^=fr] .c-setCode {width: 200px !important;}
+3
View File
@@ -54,6 +54,8 @@ $lang->custom->allUsers = 'All Users';
$lang->custom->account = 'Users';
$lang->custom->role = 'Role';
$lang->custom->dept = 'Dept';
$lang->custom->code = $lang->code;
$lang->custom->setCode = 'Enable or Disable Code';
if($config->systemMode == 'new') $lang->custom->execution = 'Execution';
if($config->systemMode == 'classic' || !$config->systemMode) $lang->custom->execution = 'Execution';
@@ -208,6 +210,7 @@ $lang->custom->notice->confirmReviewCase = 'Set the case in Wait to Normal?';
$lang->custom->notice->storyReviewTip = 'After selecting by individual, position, and department, take the union of these three filters. ';
$lang->custom->notice->selectAllTip = 'After selecting all people, the reviewers will be emptied and grayed out while hiding their positions and departments.';
$lang->custom->notice->repeatKey = 'Repeat Key %s';
$lang->custom->notice->readOnlyOfCode = 'A code is a management term that exists for secrecy or as an antonym. When code management is enabled, the code information of product, project, and execution in the system will be displayed in the creation, editing, detail, and list pages.';
$lang->custom->notice->indexPage['product'] = "ZenTao 8.2+ has Product Homepage. Do you want to go to Product Homepage?";
$lang->custom->notice->indexPage['project'] = "ZenTao 8.2+ has Project Homepage. Do you want to go to Project Homepage?";
+3
View File
@@ -54,6 +54,8 @@ $lang->custom->allUsers = 'All Users';
$lang->custom->account = 'Users';
$lang->custom->role = 'Role';
$lang->custom->dept = 'Dept';
$lang->custom->code = $lang->code;
$lang->custom->setCode = 'Enable or Disable Code';
if($config->systemMode == 'new') $lang->custom->execution = 'Execution';
if($config->systemMode == 'classic' || !$config->systemMode) $lang->custom->execution = $lang->executionCommon;
@@ -208,6 +210,7 @@ $lang->custom->notice->confirmReviewCase = 'Set the case in Wait to Normal?';
$lang->custom->notice->storyReviewTip = 'After selecting by individual, position, and department, take the union of these three filters. ';
$lang->custom->notice->selectAllTip = 'After selecting all people, the reviewers will be emptied and grayed out while hiding their positions and departments.';
$lang->custom->notice->repeatKey = 'Repeat Key %s';
$lang->custom->notice->readOnlyOfCode = 'A code is a management term that exists for secrecy or as an antonym. When code management is enabled, the code information of product, project, and execution in the system will be displayed in the creation, editing, detail, and list pages.';
$lang->custom->notice->indexPage['product'] = "ZenTao 8.2+ has Product Home. Do you want to go to Product Home?";
$lang->custom->notice->indexPage['project'] = "ZenTao 8.2+ has Project Home. Do you want to go to Project Home?";
+3
View File
@@ -54,6 +54,8 @@ $lang->custom->allUsers = 'All Users';
$lang->custom->account = 'Users';
$lang->custom->role = 'Role';
$lang->custom->dept = 'Dept';
$lang->custom->code = $lang->code;
$lang->custom->setCode = 'Activer ou Désactiver le Code';
if($config->systemMode == 'new') $lang->custom->execution = 'Execution';
if($config->systemMode == 'classic' || !$config->systemMode) $lang->custom->execution = 'Execution';
@@ -208,6 +210,7 @@ $lang->custom->notice->confirmReviewCase = 'Set the case in Wait to Normal?';
$lang->custom->notice->storyReviewTip = 'After selecting by individual, position, and department, take the union of these three filters. ';
$lang->custom->notice->selectAllTip = 'After selecting all people, the reviewers will be emptied and grayed out while hiding their positions and departments.';
$lang->custom->notice->repeatKey = 'Repeat Key %s';
$lang->custom->notice->readOnlyOfCode = "Le code est un terme de gestion utilisé pour la confidentialité ou comme alias. Lorsque la gestion du code est activée, le produit, le projet et l'exécution dans le système afficheront les informations de code sur les pages de création, de modification, de détails et de liste.";
$lang->custom->notice->indexPage['product'] = "ZenTao 8.2+ possède une page d'accueil. Voulez-vous consulter la page d'accueil du produit ?";
$lang->custom->notice->indexPage['project'] = "ZenTao 8.2+ possède une page d'accueil. Voulez-vous consulter la page d'accueil du produit ?";
+3
View File
@@ -54,6 +54,8 @@ $lang->custom->allUsers = '所有人员';
$lang->custom->account = '人员';
$lang->custom->role = '职位';
$lang->custom->dept = '部门';
$lang->custom->code = $lang->code;
$lang->custom->setCode = '是否启用代号';
if($config->systemMode == 'new') $lang->custom->execution = '执行';
if($config->systemMode == 'classic' || !$config->systemMode) $lang->custom->execution = $lang->executionCommon;
@@ -208,6 +210,7 @@ $lang->custom->notice->confirmReviewCase = '是否将待评审的用例修改
$lang->custom->notice->storyReviewTip = '按人员、职位、部门勾选后,取所有人员的并集。';
$lang->custom->notice->selectAllTip = '勾选所有人员后,会清空并置灰评审人员,同时隐藏职位、部门。';
$lang->custom->notice->repeatKey = '%s键重复';
$lang->custom->notice->readOnlyOfCode = '代号是一种管理话术,主要便于保密或作为别名存在。启用代号管理后,系统中的产品、项目、执行在创建、编辑、详情、列表等页面均会展示代号信息。';
$lang->custom->notice->indexPage['product'] = "从8.2版本起增加了产品主页视图,是否默认进入产品主页?";
$lang->custom->notice->indexPage['project'] = "从8.2版本起增加了项目主页视图,是否默认进入项目主页?";
+42
View File
@@ -0,0 +1,42 @@
<?php
/**
* The code view file of custom module of ZenTaoPMS.
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Shujie Tian <tianshujie@cnezsoft.com>
* @package custom
* @version $Id$
* @link https://www.zentao.net
*/
?>
<?php include $app->getModuleRoot() . 'common/view/header.html.php';?>
<div id='mainContent' class='main-content'>
<form class="load-indicator main-form form-ajax" method='post'>
<table class='table table-form'>
<tr>
<th class='c-setCode'><?php echo $lang->custom->setCode;?></th>
<td class='c-code text-left'>
<?php $checkedKey = isset($config->setCode) ? $config->setCode : 1;?>
<?php foreach($lang->custom->conceptOptions->URAndSR as $key => $value):?>
<label class="radio-inline"><input type="radio" name="code" value="<?php echo $key?>"<?php echo $key == $checkedKey ? " checked='checked'" : ''?> id="code<?php echo $key;?>"><?php echo $value;?></label>
<?php endforeach;?>
</td>
<td></td>
</tr>
<tr>
<th></th>
<td colspan="2" id="readOnlyOfCode">
<div class="inline-block"><i class="icon-exclamation-sign"></i>&nbsp;</div>
<div class="inline-block"><?php echo $lang->custom->notice->readOnlyOfCode;?></div>
</td>
</tr>
<tr>
<th></th>
<td class='form-actions'>
<?php echo html::submitButton();?>
</td>
</tr>
</table>
</form>
</div>
<?php include '../../common/view/footer.html.php';?>
+2 -2
View File
@@ -21,8 +21,8 @@ $config->doc->custom->objectLibs = $config->doc->customObjectLibs;
$config->doc->custom->showLibs = 'zero,children';
$config->doc->editor = new stdclass();
$config->doc->editor->create = array('id' => 'content', 'tools' => 'fullTools');
$config->doc->editor->edit = array('id' => 'content', 'tools' => 'fullTools');
$config->doc->editor->create = array('id' => 'content', 'tools' => 'docTools');
$config->doc->editor->edit = array('id' => 'content', 'tools' => 'docTools');
$config->doc->editor->view = array('id' => 'comment,lastComment', 'tools' => 'simple');
$config->doc->editor->objectlibs = array('id' => 'comment,lastComment', 'tools' => 'simple');
+32 -1
View File
@@ -347,6 +347,8 @@ class doc extends control
if($this->config->systemMode == 'new') unset($this->lang->doc->menu->project['subMenu']);
}
$this->config->showMainMenu = strpos(',html,markdown,text,', ",$docType,") === false;
/* Get libs and the default lib id. */
$gobackLink = ($objectID == 0 and $libID == 0) ? $this->createLink('doc', 'tableContents', "type=$objectType") : '';
$unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : '';
@@ -469,6 +471,8 @@ class doc extends control
}
}
$this->config->showMainMenu = strpos(',html,markdown,text,', ",{$doc->type},") === false;
$objects = $this->doc->getOrderedObjects($objectType);
$appendLib = (!empty($lib) and $lib->deleted == '1') ? $libID : 0;
$libs = $this->doc->getLibsByObject($objectType, $objectID, '', $appendLib);
@@ -782,6 +786,21 @@ class doc extends control
return print(json_encode($this->doc->getAllLibGroups()));
}
/**
* AJAX: Get libs by type.
*
* @param string $type
* @access public
* @return void
*/
public function ajaxGetLibsByType($type)
{
$unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : '';
$libs = $this->doc->getLibs($type, "withObject,$unclosed");
return print(html::select('lib', $libs, '', 'class="form-control"'));
}
/**
* Ajax get all child module.
*
@@ -1239,11 +1258,23 @@ class doc extends control
$response['message'] = $this->lang->saveSuccess;
$response['result'] = 'success';
$response['closeModal'] = true;
$response['callback'] = "redirectParentWindow(\"{$this->post->objectType}\")";
$response['callback'] = "redirectParentWindow(\"{$this->post->objectType}\", \"{$this->post->lib}\", \"{$this->post->type}\")";
return $this->send($response);
}
unset($this->lang->doc->libTypeList['book']);
$globalTypeList = $this->lang->doc->libTypeList;
$globalTypeList = $this->config->vision == 'lite' ? $globalTypeList : $globalTypeList + $this->lang->doc->libGlobalList;
$defaultType = key($globalTypeList);
$unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : '';
$libs = $this->doc->getLibs($defaultType, "withObject,$unclosed");
$this->view->globalTypeList = $globalTypeList;
$this->view->defaultType = $defaultType;
$this->view->libs = $libs;
$this->display();
}
+1
View File
@@ -0,0 +1 @@
#lib_chosen.chosen-container .chosen-results {max-height: 100px;}
+2 -2
View File
@@ -26,12 +26,12 @@ $(function()
if($(this).hasClass('ke-selected'))
{
$('#submit').removeClass('fullscreen-save')
$('#submit').addClass('btn-wide')
$('.form-actions #submit').addClass('btn-wide')
}
else
{
$('#submit').addClass('fullscreen-save')
$('#submit').removeClass('btn-wide')
$('.form-actions #submit').removeClass('btn-wide')
}
});
+23 -3
View File
@@ -2,19 +2,39 @@
* Redirect the parent window.
*
* @param string objectType
* @param int libID
* @param string docType
* @access public
* @return void
*/
function redirectParentWindow(objectType)
function redirectParentWindow(objectType, libID, docType)
{
config.onlybody = 'no';
if(objectType == 'api')
{
var link = createLink('api', 'create', 'libID=0') + '#app=doc';
var link = createLink('api', 'create', 'libID=' + libID) + '#app=doc';
}
else
{
var link = createLink('doc', 'create', 'objectType=' + objectType + '&objectID=0&libID=0') + '#app=doc';
var link = createLink('doc', 'create', 'objectType=' + objectType + '&objectID=0&libID=' + libID + '&moduleID=0&docType=' + docType) + '#app=doc';
}
window.parent.$.apps.open(link);
}
/**
* Load doc libs by type.
*
* @param string type
* @return void
*/
function loadDocLibs(type)
{
$.get(createLink('doc', 'ajaxGetLibsByType', "type=" + type), function(data)
{
$('#lib').replaceWith(data);
$('#lib_chosen').remove();
$('#lib').chosen();
})
$('#docType').toggleClass('hidden', type == 'api');
}
+17 -16
View File
@@ -136,22 +136,23 @@ $lang->doc->menuTitle = 'Menu';
$lang->doc->collectAction = 'Add Favorite';
$lang->doc->libName = 'Name';
$lang->doc->libType = 'Kategorie';
$lang->doc->custom = 'Eigene Dok Bibliothek';
$lang->doc->customAB = 'Eigene Bibliothek';
$lang->doc->createLib = 'Document Library';
$lang->doc->allLibs = 'Bibliothek';
$lang->doc->objectLibs = "{$lang->productCommon}/{$lang->executionCommon} Bibliothek Liste";
$lang->doc->showFiles = 'Dok Bibliothek';
$lang->doc->editLib = 'Edit Document Library';
$lang->doc->deleteLib = 'Bibliothek löschen';
$lang->doc->fixedMenu = 'Im Menü fixieren';
$lang->doc->removeMenu = 'Vom Menü entfernen';
$lang->doc->search = 'Suche';
$lang->doc->allCollections = 'All Collections';
$lang->doc->keywordsTips = 'Please use commas to separate multiple keywords.';
$lang->doc->sortLibs = 'Sort Libs';
$lang->doc->libName = 'Name';
$lang->doc->libType = 'Kategorie';
$lang->doc->custom = 'Eigene Dok Bibliothek';
$lang->doc->customAB = 'Eigene Bibliothek';
$lang->doc->createLib = 'Document Library';
$lang->doc->allLibs = 'Bibliothek';
$lang->doc->objectLibs = "{$lang->productCommon}/{$lang->executionCommon} Bibliothek Liste";
$lang->doc->showFiles = 'Dok Bibliothek';
$lang->doc->editLib = 'Edit Document Library';
$lang->doc->deleteLib = 'Bibliothek löschen';
$lang->doc->fixedMenu = 'Im Menü fixieren';
$lang->doc->removeMenu = 'Vom Menü entfernen';
$lang->doc->search = 'Suche';
$lang->doc->allCollections = 'All Collections';
$lang->doc->keywordsTips = 'Please use commas to separate multiple keywords.';
$lang->doc->sortLibs = 'Sort Libs';
$lang->doc->titlePlaceholder = 'Please enter the title';
global $config;
/* Query condition list. */
+17 -16
View File
@@ -136,22 +136,23 @@ $lang->doc->menuTitle = 'Direcotory';
$lang->doc->collectAction = 'Add Favorite';
$lang->doc->libName = 'Document Library';
$lang->doc->libType = 'Category';
$lang->doc->custom = 'Custom Document Library';
$lang->doc->customAB = 'Custom Doc Lib';
$lang->doc->createLib = 'Document Library';
$lang->doc->allLibs = 'Library List';
$lang->doc->objectLibs = "Document View of Library";
$lang->doc->showFiles = 'Attachments';
$lang->doc->editLib = 'Edit Document Library';
$lang->doc->deleteLib = 'Delete Document Library';
$lang->doc->fixedMenu = 'Fix to Menu';
$lang->doc->removeMenu = 'Remove from Menu';
$lang->doc->search = 'Search';
$lang->doc->allCollections = 'All Collections';
$lang->doc->keywordsTips = 'Please use commas to separate keywords.';
$lang->doc->sortLibs = 'Sort Libs';
$lang->doc->libName = 'Document Library';
$lang->doc->libType = 'Category';
$lang->doc->custom = 'Custom Document Library';
$lang->doc->customAB = 'Custom Doc Lib';
$lang->doc->createLib = 'Document Library';
$lang->doc->allLibs = 'Library List';
$lang->doc->objectLibs = "Document View of Library";
$lang->doc->showFiles = 'Attachments';
$lang->doc->editLib = 'Edit Document Library';
$lang->doc->deleteLib = 'Delete Document Library';
$lang->doc->fixedMenu = 'Fix to Menu';
$lang->doc->removeMenu = 'Remove from Menu';
$lang->doc->search = 'Search';
$lang->doc->allCollections = 'All Collections';
$lang->doc->keywordsTips = 'Please use commas to separate keywords.';
$lang->doc->sortLibs = 'Sort Libs';
$lang->doc->titlePlaceholder = 'Please enter the title';
global $config;
/* Query condition list. */
+17 -16
View File
@@ -136,22 +136,23 @@ $lang->doc->menuTitle = 'Menu';
$lang->doc->collectAction = 'Add Favorite';
$lang->doc->libName = 'Bibliothèque de Documents';
$lang->doc->libType = 'Catégorie';
$lang->doc->custom = 'Personnaliser Bibliothèque de Documents';
$lang->doc->customAB = 'Person. Bib Doc';
$lang->doc->createLib = 'Document Library';
$lang->doc->allLibs = 'Liste des Bibliothèque';
$lang->doc->objectLibs = "{$lang->productCommon}/{$lang->executionCommon} Bibliothèque";
$lang->doc->showFiles = 'Pièces Jointes';
$lang->doc->editLib = 'Edit Document Library';
$lang->doc->deleteLib = 'Supprimer Bibliothèque';
$lang->doc->fixedMenu = 'Coller au Menu';
$lang->doc->removeMenu = 'Décoller du Menu';
$lang->doc->search = 'Rechercher';
$lang->doc->allCollections = 'All Collections';
$lang->doc->keywordsTips = 'Please use commas to separate multiple keywords.';
$lang->doc->sortLibs = 'Sort Libs';
$lang->doc->libName = 'Bibliothèque de Documents';
$lang->doc->libType = 'Catégorie';
$lang->doc->custom = 'Personnaliser Bibliothèque de Documents';
$lang->doc->customAB = 'Person. Bib Doc';
$lang->doc->createLib = 'Document Library';
$lang->doc->allLibs = 'Liste des Bibliothèque';
$lang->doc->objectLibs = "{$lang->productCommon}/{$lang->executionCommon} Bibliothèque";
$lang->doc->showFiles = 'Pièces Jointes';
$lang->doc->editLib = 'Edit Document Library';
$lang->doc->deleteLib = 'Supprimer Bibliothèque';
$lang->doc->fixedMenu = 'Coller au Menu';
$lang->doc->removeMenu = 'Décoller du Menu';
$lang->doc->search = 'Rechercher';
$lang->doc->allCollections = 'All Collections';
$lang->doc->keywordsTips = 'Please use commas to separate multiple keywords.';
$lang->doc->sortLibs = 'Sort Libs';
$lang->doc->titlePlaceholder = 'Veuillez saisir le titre';
global $config;
/* Query condition list. */
+17 -16
View File
@@ -136,22 +136,23 @@ $lang->doc->menuTitle = '目录';
$lang->doc->collectAction = '收藏文档';
$lang->doc->libName = '文档库名称';
$lang->doc->libType = '文档库类型';
$lang->doc->custom = '自定义文档库';
$lang->doc->customAB = '自定义库';
$lang->doc->createLib = '创建文档库';
$lang->doc->allLibs = '文档库列表';
$lang->doc->objectLibs = "文档库文档详情";
$lang->doc->showFiles = '附件库';
$lang->doc->editLib = '编辑文档库';
$lang->doc->deleteLib = '删除文档库';
$lang->doc->fixedMenu = '固定到菜单栏';
$lang->doc->removeMenu = '从菜单栏移除';
$lang->doc->search = '搜索';
$lang->doc->allCollections = '查看全部收藏文档';
$lang->doc->keywordsTips = '多个关键字请用逗号分隔。';
$lang->doc->sortLibs = '文档库排序';
$lang->doc->libName = '文档库名称';
$lang->doc->libType = '文档库类型';
$lang->doc->custom = '自定义文档库';
$lang->doc->customAB = '自定义库';
$lang->doc->createLib = '创建文档库';
$lang->doc->allLibs = '文档库列表';
$lang->doc->objectLibs = "文档库文档详情";
$lang->doc->showFiles = '附件库';
$lang->doc->editLib = '编辑文档库';
$lang->doc->deleteLib = '删除文档库';
$lang->doc->fixedMenu = '固定到菜单栏';
$lang->doc->removeMenu = '从菜单栏移除';
$lang->doc->search = '搜索';
$lang->doc->allCollections = '查看全部收藏文档';
$lang->doc->keywordsTips = '多个关键字请用逗号分隔。';
$lang->doc->sortLibs = '文档库排序';
$lang->doc->titlePlaceholder = '请输入标题';
global $config;
/* 查询条件列表 */
+3 -130
View File
@@ -10,135 +10,8 @@
* @link http://www.zentao.net
*/
?>
<?php if($docType != '' and strpos($config->doc->officeTypes, $docType) !== false):?>
<?php include '../../common/view/header.lite.html.php';?>
<div id="mainContent" class="main-content">
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->doc->create;?></h2>
</div>
<?php if($this->config->edition != 'open'):?>
<div class='alert alert-warning strong'>
<?php printf($lang->doc->notSetOffice, zget($lang->doc->typeList, $docType), common::hasPriv('custom', 'libreoffice') ? $this->createLink('custom', 'libreoffice', '', '', true) : '###');?>
</div>
<?php else:?>
<div class='alert alert-warning strong'><?php printf($lang->doc->cannotCreateOffice, zget($lang->doc->typeList, $docType));?></div>
<?php endif;?>
</div>
</div>
<script>
$("a[href^='###']").click(function()
{
alert('<?php echo $lang->doc->noLibreOffice;?>');
});
</script>
</body>
</html>
<?php if($docType == 'html' or $docType == 'markdown' or $docType == 'text'):?>
<?php include 'createtexttype.html.php';?>
<?php else:?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<?php include '../../common/view/markdown.html.php';?>
<?php js::set('holders', $lang->doc->placeholder);?>
<?php js::set('type', 'doc');?>
<div id="mainContent" class="main-content">
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->doc->create;?></h2>
</div>
<?php if($objectType == 'custom' and empty($libs)):?>
<?php echo html::a(helper::createLink('doc', 'createLib', "type=custom&objectID=$objectID"), '<i class="icon icon-plus"></i> ' . $lang->doc->createLib, '', 'class="iframe hidden createCustomLib"');?>
<?php endif;?>
<form class="load-indicator main-form form-ajax" id="dataform" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<tbody>
<tr>
<th class='w-110px'><?php echo $lang->doc->lib;?></th>
<td> <?php echo html::select('lib', $libs, $libID, "class='form-control chosen' onchange=loadDocModule(this.value)");?> </td><td></td>
</tr>
<tr>
<th><?php echo $lang->doc->module;?></th>
<td>
<span id='moduleBox'><?php echo html::select('module', $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></span>
</td><td></td>
</tr>
<tr>
<th><?php echo $lang->doc->title;?></th>
<td colspan='2'><?php echo html::input('title', '', "class='form-control' required");?></td>
</tr>
<tr>
<th><?php echo $lang->doc->keywords;?></th>
<td colspan='2'><?php echo html::input('keywords', '', "class='form-control' placeholder='{$lang->doc->keywordsTips}'");?></td>
</tr>
<tr>
<th><?php echo $lang->doc->type;?></th>
<?php
$typeKeyList = array();
foreach($lang->doc->types as $typeKey => $typeName) $typeKeyList[$typeKey] = $typeKey;
?>
<td><?php echo html::radio('type', $lang->doc->types, zget($typeKeyList, $docType, 'text'));?></td>
</tr>
<tr id='contentBox'>
<th><?php echo $lang->doc->content;?></th>
<td colspan='2'>
<div class='contenthtml'><?php echo html::textarea('content', '', "style='width:100%;height:200px'");?></div>
<div class='contentmarkdown hidden'><?php echo html::textarea('contentMarkdown', '', "style='width:100%;height:200px'");?></div>
<?php echo html::hidden('contentType', 'html');?>
</td>
</tr>
<tr id='urlBox' class='hidden'>
<th><?php echo $lang->doc->url;?></th>
<td colspan='2'><?php echo html::input('url', '', "class='form-control'");?></td>
</tr>
<tr id='fileBox'>
<th><?php echo $lang->doc->files;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform');?></td>
</tr>
<tr>
<th><?php echo $lang->doc->mailto;?></th>
<td colspan="2">
<div class="input-group">
<?php
echo html::select('mailto[]', $users, '', "multiple class='form-control picker-select' data-drop-direction='top'");
echo $this->fetch('my', 'buildContactLists');
?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->doclib->control;?></th>
<td colspan='2'>
<?php $acl = $lib->acl == 'default' ? 'open' : $lib->acl;?>
<?php $acl = ($lib->type == 'project' and $acl == 'private') ? 'open' : $acl;?>
<?php echo html::radio('acl', $lang->doc->aclList, $acl, "onchange='toggleAcl(this.value, \"doc\")'");?>
<span class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['doc'][$acl];?></span>
</td>
</tr>
<tr id='whiteListBox' class='hidden'>
<th><?php echo $lang->doc->whiteList;?></th>
<td colspan='2'>
<div class='input-group'>
<span class='input-group-addon groups-addon'><?php echo $lang->doclib->group?></span>
<?php echo html::select('groups[]', $groups, '', "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->doclib->user?></span>
<?php echo html::select('users[]', $users, '', "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
</td>
</tr>
<tr>
<td colspan='3' class='text-center form-actions'>
<?php echo html::submitButton();?>
<?php if(empty($gobackLink)) echo html::backButton($lang->goback, "data-app='{$app->tab}'");?>
<?php if(!empty($gobackLink)) echo html::a($gobackLink, $lang->goback, '', "class='btn btn-back btn-wide'");?>
</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
<?php js::set('docType', $docType);?>
<?php js::set('noticeAcl', $lang->doc->noticeAcl['doc']);?>
<?php include '../../common/view/footer.html.php';?>
<?php include 'createothertype.html.php';?>
<?php endif;?>
+137
View File
@@ -0,0 +1,137 @@
<?php
/**
* The create view of doc module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jia Fu <fujia@cnezsoft.com>
* @package doc
* @version $Id: create.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $
* @link http://www.zentao.net
*/
?>
<?php if($docType != '' and strpos($config->doc->officeTypes, $docType) !== false):?>
<?php include '../../common/view/header.lite.html.php';?>
<div id="mainContent" class="main-content">
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->doc->create;?></h2>
</div>
<?php if($this->config->edition != 'open'):?>
<div class='alert alert-warning strong'>
<?php printf($lang->doc->notSetOffice, zget($lang->doc->typeList, $docType), common::hasPriv('custom', 'libreoffice') ? $this->createLink('custom', 'libreoffice', '', '', true) : '###');?>
</div>
<?php else:?>
<div class='alert alert-warning strong'><?php printf($lang->doc->cannotCreateOffice, zget($lang->doc->typeList, $docType));?></div>
<?php endif;?>
</div>
</div>
<script>
$("a[href^='###']").click(function()
{
alert('<?php echo $lang->doc->noLibreOffice;?>');
});
</script>
</body>
</html>
<?php else:?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<?php include '../../common/view/markdown.html.php';?>
<?php js::set('holders', $lang->doc->placeholder);?>
<?php js::set('type', 'doc');?>
<div id="mainContent" class="main-content">
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->doc->create;?></h2>
</div>
<?php if($objectType == 'custom' and empty($libs)):?>
<?php echo html::a(helper::createLink('doc', 'createLib', "type=custom&objectID=$objectID"), '<i class="icon icon-plus"></i> ' . $lang->doc->createLib, '', 'class="iframe hidden createCustomLib"');?>
<?php endif;?>
<form class="load-indicator main-form form-ajax" id="dataform" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<tbody>
<tr>
<th class='w-110px'><?php echo $lang->doc->lib;?></th>
<td> <?php echo html::select('lib', $libs, $libID, "class='form-control chosen' onchange=loadDocModule(this.value)");?> </td><td></td>
</tr>
<tr>
<th><?php echo $lang->doc->module;?></th>
<td>
<span id='moduleBox'><?php echo html::select('module', $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></span>
</td><td></td>
</tr>
<tr>
<th><?php echo $lang->doc->title;?></th>
<td colspan='2'><?php echo html::input('title', '', "class='form-control' required");?></td>
</tr>
<tr>
<th><?php echo $lang->doc->keywords;?></th>
<td colspan='2'><?php echo html::input('keywords', '', "class='form-control' placeholder='{$lang->doc->keywordsTips}'");?></td>
</tr>
<tr id='contentBox'>
<th><?php echo $lang->doc->content;?></th>
<td colspan='2'>
<div class='contenthtml'><?php echo html::textarea('content', '', "style='width:100%;height:200px'");?></div>
<div class='contentmarkdown hidden'><?php echo html::textarea('contentMarkdown', '', "style='width:100%;height:200px'");?></div>
<?php echo html::hidden('contentType', 'html');?>
<?php echo html::hidden('type', $docType);?>
</td>
</tr>
<tr id='urlBox' class='hidden'>
<th><?php echo $lang->doc->url;?></th>
<td colspan='2'><?php echo html::input('url', '', "class='form-control'");?></td>
</tr>
<tr id='fileBox'>
<th><?php echo $lang->doc->files;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform');?></td>
</tr>
<tr>
<th><?php echo $lang->doc->mailto;?></th>
<td colspan="2">
<div class="input-group">
<?php
echo html::select('mailto[]', $users, '', "multiple class='form-control picker-select' data-drop-direction='top'");
echo $this->fetch('my', 'buildContactLists');
?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->doclib->control;?></th>
<td colspan='2'>
<?php $acl = $lib->acl == 'default' ? 'open' : $lib->acl;?>
<?php $acl = ($lib->type == 'project' and $acl == 'private') ? 'open' : $acl;?>
<?php echo html::radio('acl', $lang->doc->aclList, $acl, "onchange='toggleAcl(this.value, \"doc\")'");?>
<span class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['doc'][$acl];?></span>
</td>
</tr>
<tr id='whiteListBox' class='hidden'>
<th><?php echo $lang->doc->whiteList;?></th>
<td colspan='2'>
<div class='input-group'>
<span class='input-group-addon groups-addon'><?php echo $lang->doclib->group?></span>
<?php echo html::select('groups[]', $groups, '', "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->doclib->user?></span>
<?php echo html::select('users[]', $users, '', "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
</td>
</tr>
<tr>
<td colspan='3' class='text-center form-actions'>
<?php echo html::submitButton();?>
<?php if(empty($gobackLink)) echo html::backButton($lang->goback, "data-app='{$app->tab}'");?>
<?php if(!empty($gobackLink)) echo html::a($gobackLink, $lang->goback, '', "class='btn btn-back btn-wide'");?>
</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
<?php js::set('docType', $docType);?>
<?php js::set('noticeAcl', $lang->doc->noticeAcl['doc']);?>
<?php include '../../common/view/footer.html.php';?>
<?php endif;?>
+168
View File
@@ -0,0 +1,168 @@
<?php
/**
* The create text view of doc module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Fangzhou Hu <hufangzhou@easycorp.ltd>
* @package doc
* @version $Id: createtext.html.php 975 2022-07-14 13:49:25Z $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<?php include '../../common/view/markdown.html.php';?>
<?php js::set('holders', $lang->doc->placeholder);?>
<?php js::set('type', 'doc');?>
<style>
#main {padding: 0;}
.container {padding: 0 !important;}
#mainContent {padding: 0 !important;}
#dataform {overflow: hidden}
.doc-title input {border: unset; font-size: 18px; font-weight: bold; color: #3c4353; padding-left: 16px;}
.doc-title .form-control:focus {border: unset; box-shadow: unset;}
.doc-title input::-webkit-input-placeholder {color: #D8DBDE;}
.doc-title.required:after {top: 4px; right: 0; left: 12px; display: inline-table;}
#submit {margin-right: 12px;}
#headerBox {border-bottom: 1px solid #e3e3e3;}
#editorContent {padding: 0;}
#contentBox {padding: 0; width: 100%;}
.ke-container {overflow: visible;}
.ke-container, .contentmarkdown {border: unset; background: #efefef;}
.ke-container.focus {box-shadow: unset; border-color: unset;}
.ke-toolbar {padding-left: 20px; width: 150%; height: 30px; border-bottom: unset;}
.ke-edit {border-top: 1px solid rgb(220, 220, 220)}
.ke-edit, .CodeMirror {margin-left: 20px; background: #fff;}
.kindeditor-ph {padding-left: 20px !important;}
.editor-toolbar {background: #fff; padding-left: 20px; border-right: unset; border-top: unset; height: 30px;}
.hide-sidebar .ke-edit {padding-right: 20px;}
.hide-sidebar .CodeMirror {padding-right: 50px;}
.CodeMirror.CodeMirror-wrap {border-left: 0; border-right: 0; border-bottom: 0;}
#sidebar {top: 30px;}
#sidebar .sidebar-toggle {right: 0; left: 0px; background: #efefef; border-radius: 0px; width: 20px; border-top: 1px solid rgb(220, 220, 220);}
#sidebar > .sidebar-toggle:hover {background: #efefef;}
#sidebar {width: 500px;}
#sidebar table {margin-top: 5px;}
#sidebar table th {font-weight: 400 !important;}
.hide-sidebar #sidebar > .sidebar-toggle > .icon:before {content: "\e314";}
.hide-sidebar #sidebar > .sidebar-toggle {left: -20px; z-index: 9;}
#sidebar .cell {border-top: 1px solid rgb(220, 220, 220); border-radius: 0px;}
#sidebar > .sidebar-toggle > .icon.icon-angle-right {left: 4px;}
.file-title {max-width: 130px !important;}
.th-control {vertical-align: top !important;}
#noticeAcl {margin: 0;}
</style>
<?php if($objectType == 'custom' and empty($libs)):?>
<?php echo html::a(helper::createLink('doc', 'createLib', "type=custom&objectID=$objectID"), '<i class="icon icon-plus"></i> ' . $lang->doc->createLib, '', 'class="iframe hidden createCustomLib"');?>
<?php endif;?>
<div id="mainContent" class="main-content">
<form class="load-indicator main-form form-ajax" id="dataform" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<tbody>
<tr id='headerBox'>
<td class="doc-title" colspan='4'><?php echo html::input('title', '', "placeholder='{$lang->doc->titlePlaceholder}' class='form-control' required");?></td>
<td class="text-right"><?php echo html::submitButton('', '', 'btn btn-primary') . html::backButton('', '', 'btn');?></td>
</tr>
<tr>
<td colspan='5' id="editorContent">
<div class="main-row fade in">
<div id='contentBox' class="main-col">
<div class='contenthtml'><?php echo html::textarea('content', '', "style='width:100%;'");?></div>
<div class='contentmarkdown hidden'><?php echo html::textarea('contentMarkdown', '', "style='width:100%;'");?></div>
<?php echo html::hidden('contentType', 'html');?>
<?php echo html::hidden('type', 'text');?>
</div>
<div class="basicInfoBox side-col" id="sidebar">
<div class="sidebar-toggle"><i class="icon icon-angle-right"></i></div>
<div class="cell" style="width: 100%">
<div class="detail">
<div class='detail-title'><?php echo $lang->story->legendBasicInfo;?></div>
<table class='table table-form'>
<tr>
<th class='w-100px'><?php echo $lang->doc->lib;?></th>
<td colspan="2"><?php echo html::select('lib', $libs, $libID, "class='form-control chosen' onchange=loadDocModule(this.value)");?></td>
</tr>
<tr>
<th><?php echo $lang->doc->module;?></th>
<td colspan="2">
<span id='moduleBox'><?php echo html::select('module', $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></span>
</td>
</tr>
<tr>
<th><?php echo $lang->doc->keywords;?></th>
<td colspan='2'><?php echo html::input('keywords', '', "class='form-control' placeholder='{$lang->doc->keywordsTips}'");?></td>
</tr>
<tr id='fileBox'>
<th><?php echo $lang->doc->files;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform');?></td>
</tr>
<tr>
<th><?php echo $lang->doc->mailto;?></th>
<td colspan="2">
<div class="input-group">
<?php
echo html::select('mailto[]', $users, '', "multiple class='form-control picker-select' data-drop-direction='top'");
echo $this->fetch('my', 'buildContactLists');
?>
</div>
</td>
</tr>
<tr>
<th class="th-control"><?php echo $lang->doclib->control;?></th>
<td colspan='2'>
<?php $acl = $lib->acl == 'default' ? 'open' : $lib->acl;?>
<?php $acl = ($lib->type == 'project' and $acl == 'private') ? 'open' : $acl;?>
<?php echo html::radio('acl', $lang->doc->aclList, $acl, "onchange='toggleAcl(this.value, \"doc\")'");?>
<p class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['doc'][$acl];?></p>
</td>
</tr>
<tr id='whiteListBox' class='hidden'>
<th><?php echo $lang->doc->whiteList;?></th>
<td colspan='2'>
<div class='input-group'>
<span class='input-group-addon groups-addon'><?php echo $lang->doclib->group?></span>
<?php echo html::select('groups[]', $groups, '', "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->doclib->user?></span>
<?php echo html::select('users[]', $users, '', "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</form>
</div>
<script>
$(function()
{
$('.doc-title input').focus();
$('#dataform').submit(function()
{
setTimeout(function(){$('#dataform').scrollTop(0)}, 100);
});
var contentHeight = $(document).height() - 120;
$('#sidebar').height(contentHeight);
setTimeout(function(){$('.ke-edit-iframe, .ke-edit').height(contentHeight);}, 100);
setTimeout(function(){$('.CodeMirror').height(contentHeight);}, 100);
$('#editorContent .icon.icon-angle-right').css('top', '50%');
})
</script>
<?php js::set('docType', $docType);?>
<?php js::set('noticeAcl', $lang->doc->noticeAcl['doc']);?>
<?php include '../../common/view/footer.html.php';?>
+5 -106
View File
@@ -10,109 +10,8 @@
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php if($doc->contentType == 'html') include '../../common/view/kindeditor.html.php';?>
<?php if($doc->contentType == 'markdown') include '../../common/view/markdown.html.php';?>
<?php js::set('needUpdateContent', $doc->content != $doc->draft);?>
<?php js::set('confirmUpdateContent', $lang->doc->confirmUpdateContent);?>
<?php js::set('docID', $doc->id);?>
<?php js::set('draft', $doc->draft);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2>
<span class='label label-id'><?php echo $doc->id;?></span>
<?php echo html::a($this->createLink('doc', 'view', "docID=$doc->id"), $doc->title, '', "title='$doc->title'");?>
<small> <?php echo $lang->arrow . ' ' . $lang->doc->edit;?></small>
</h2>
<div class='pull-right'><?php echo html::a('###', $lang->save, '', 'id="top-submit" class="btn btn-primary"');?></div>
</div>
<form class='load-indicator main-form form-ajax' method='post' enctype='multipart/form-data' id='dataform'>
<table class='table table-form'>
<tr>
<th class='w-110px'><?php echo $lang->doc->lib;?></th>
<td> <?php echo html::select('lib', $libs, $doc->lib, "class='form-control chosen' onchange=loadDocModule(this.value)");?> </td><td></td>
</tr>
<tr>
<th><?php echo $lang->doc->module;?></th>
<td>
<span id='moduleBox'><?php echo html::select('module', $moduleOptionMenu, $doc->module, "class='form-control chosen'");?></span>
</td><td></td>
</tr>
<tr>
<th><?php echo $lang->doc->title;?></th>
<td colspan='2'><?php echo html::input('title', $doc->title, "class='form-control' required");?></td>
</tr>
<tr>
<th><?php echo $lang->doc->keywords;?></th>
<td colspan='2'><?php echo html::input('keywords', $doc->keywords, "class='form-control' placeholder='{$lang->doc->keywordsTips}'");?></td>
</tr>
<tr>
<th><?php echo $lang->doc->type;?></th>
<td>
<?php
$typeList = $lang->doc->types;
if(!isset($lang->doc->types[$doc->type])) $typeList = $lang->doc->typeList;
echo html::radio('type', array($doc->type => zget($typeList, $doc->type)), $doc->type);
?>
</td>
</tr>
<tr id='contentBox' <?php if($doc->type == 'url') echo "class='hidden'"?>>
<th><?php echo $lang->doc->content;?></th>
<td colspan='2'><?php echo html::textarea('content', $doc->type == 'url' ? '' : htmlSpecialString($doc->content), "style='width:100%; height:200px'") . html::hidden('contentType', $doc->contentType);?></td>
</tr>
<tr id='urlBox' <?php if($doc->type != 'url') echo "class='hidden'"?>>
<th><?php echo $lang->doc->url;?></th>
<td colspan='2'><?php echo html::input('url', $doc->type == 'url' ? $doc->content : '', "class='form-control'");?></td>
</tr>
<tr id='fileBox'>
<th><?php echo $lang->doc->files;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform');?></td>
</tr>
<tr>
<th><?php echo $lang->doc->mailto;?></th>
<td colspan="2">
<div class="input-group">
<?php
echo html::select('mailto[]', $users, $doc->mailto, "multiple class='form-control picker-select' data-drop-direction='top'");
echo $this->fetch('my', 'buildContactLists');
?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->doclib->control;?></th>
<td colspan='2'>
<?php $acl = $lib->acl == 'private' ? 'private' : $doc->acl;?>
<?php echo html::radio('acl', $lang->doc->aclList, $acl, "onchange='toggleAcl(this.value, \"doc\")'")?>
<span class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['doc'][$acl];?></span>
</td>
</tr>
<tr id='whiteListBox' class='hidden'>
<th><?php echo $lang->doc->whiteList;?></th>
<td colspan='2'>
<div class='input-group w-p100'>
<span class='input-group-addon groups-addon'><?php echo $lang->doclib->group?></span>
<?php echo html::select('groups[]', $groups, $doc->groups, "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
<div class='input-group w-p100'>
<span class='input-group-addon'><?php echo $lang->doclib->user?></span>
<?php echo html::select('users[]', $users, $doc->users, "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
</td>
</tr>
<tr>
<td colspan='3' class='text-center form-actions'>
<?php
echo html::hidden('editedDate', $doc->editedDate);
echo html::submitButton();
echo html::backButton($lang->goback, "data-app='{$app->tab}'");
?>
</td>
</tr>
</table>
</form>
</div>
</div>
<?php js::set('noticeAcl', $lang->doc->noticeAcl['doc']);?>
<?php include '../../common/view/footer.html.php';?>
<?php if($doc->type == 'text'):?>
<?php include 'edittexttype.html.php';?>
<?php else:?>
<?php include 'editothertype.html.php';?>
<?php endif;?>
+118
View File
@@ -0,0 +1,118 @@
<?php
/**
* The edit view of doc module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jia Fu <fujia@cnezsoft.com>
* @package doc
* @version $Id: edit.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php if($doc->contentType == 'html') include '../../common/view/kindeditor.html.php';?>
<?php if($doc->contentType == 'markdown') include '../../common/view/markdown.html.php';?>
<?php js::set('needUpdateContent', $doc->content != $doc->draft);?>
<?php js::set('confirmUpdateContent', $lang->doc->confirmUpdateContent);?>
<?php js::set('docID', $doc->id);?>
<?php js::set('draft', $doc->draft);?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2>
<span class='label label-id'><?php echo $doc->id;?></span>
<?php echo html::a($this->createLink('doc', 'view', "docID=$doc->id"), $doc->title, '', "title='$doc->title'");?>
<small> <?php echo $lang->arrow . ' ' . $lang->doc->edit;?></small>
</h2>
<div class='pull-right'><?php echo html::a('###', $lang->save, '', 'id="top-submit" class="btn btn-primary"');?></div>
</div>
<form class='load-indicator main-form form-ajax' method='post' enctype='multipart/form-data' id='dataform'>
<table class='table table-form'>
<tr>
<th class='w-110px'><?php echo $lang->doc->lib;?></th>
<td> <?php echo html::select('lib', $libs, $doc->lib, "class='form-control chosen' onchange=loadDocModule(this.value)");?> </td><td></td>
</tr>
<tr>
<th><?php echo $lang->doc->module;?></th>
<td>
<span id='moduleBox'><?php echo html::select('module', $moduleOptionMenu, $doc->module, "class='form-control chosen'");?></span>
</td><td></td>
</tr>
<tr>
<th><?php echo $lang->doc->title;?></th>
<td colspan='2'><?php echo html::input('title', $doc->title, "class='form-control' required");?></td>
</tr>
<tr>
<th><?php echo $lang->doc->keywords;?></th>
<td colspan='2'><?php echo html::input('keywords', $doc->keywords, "class='form-control' placeholder='{$lang->doc->keywordsTips}'");?></td>
</tr>
<tr>
<th><?php echo $lang->doc->type;?></th>
<td>
<?php
$typeList = $lang->doc->types;
if(!isset($lang->doc->types[$doc->type])) $typeList = $lang->doc->typeList;
echo html::radio('type', array($doc->type => zget($typeList, $doc->type)), $doc->type);
?>
</td>
</tr>
<tr id='contentBox' <?php if($doc->type == 'url') echo "class='hidden'"?>>
<th><?php echo $lang->doc->content;?></th>
<td colspan='2'><?php echo html::textarea('content', $doc->type == 'url' ? '' : htmlSpecialString($doc->content), "style='width:100%; height:200px'") . html::hidden('contentType', $doc->contentType);?></td>
</tr>
<tr id='urlBox' <?php if($doc->type != 'url') echo "class='hidden'"?>>
<th><?php echo $lang->doc->url;?></th>
<td colspan='2'><?php echo html::input('url', $doc->type == 'url' ? $doc->content : '', "class='form-control'");?></td>
</tr>
<tr id='fileBox'>
<th><?php echo $lang->doc->files;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform');?></td>
</tr>
<tr>
<th><?php echo $lang->doc->mailto;?></th>
<td colspan="2">
<div class="input-group">
<?php
echo html::select('mailto[]', $users, $doc->mailto, "multiple class='form-control picker-select' data-drop-direction='top'");
echo $this->fetch('my', 'buildContactLists');
?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->doclib->control;?></th>
<td colspan='2'>
<?php $acl = $lib->acl == 'private' ? 'private' : $doc->acl;?>
<?php echo html::radio('acl', $lang->doc->aclList, $acl, "onchange='toggleAcl(this.value, \"doc\")'")?>
<span class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['doc'][$acl];?></span>
</td>
</tr>
<tr id='whiteListBox' class='hidden'>
<th><?php echo $lang->doc->whiteList;?></th>
<td colspan='2'>
<div class='input-group w-p100'>
<span class='input-group-addon groups-addon'><?php echo $lang->doclib->group?></span>
<?php echo html::select('groups[]', $groups, $doc->groups, "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
<div class='input-group w-p100'>
<span class='input-group-addon'><?php echo $lang->doclib->user?></span>
<?php echo html::select('users[]', $users, $doc->users, "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
</td>
</tr>
<tr>
<td colspan='3' class='text-center form-actions'>
<?php
echo html::hidden('editedDate', $doc->editedDate);
echo html::submitButton();
echo html::backButton($lang->goback, "data-app='{$app->tab}'");
?>
</td>
</tr>
</table>
</form>
</div>
</div>
<?php js::set('noticeAcl', $lang->doc->noticeAcl['doc']);?>
<?php include '../../common/view/footer.html.php';?>
+167
View File
@@ -0,0 +1,167 @@
<?php
/**
* The create view of doc module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jia Fu <fujia@cnezsoft.com>
* @package doc
* @version $Id: create.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php if($doc->contentType == 'html') include '../../common/view/kindeditor.html.php';?>
<?php if($doc->contentType == 'markdown') include '../../common/view/markdown.html.php';?>
<?php js::set('needUpdateContent', $doc->content != $doc->draft);?>
<?php js::set('confirmUpdateContent', $lang->doc->confirmUpdateContent);?>
<?php js::set('docID', $doc->id);?>
<?php js::set('draft', $doc->draft);?>
<?php js::set('holders', $lang->doc->placeholder);?>
<?php js::set('type', 'doc');?>
<style>
#main {padding: 0;}
.container {padding: 0 !important;}
#mainContent {padding: 0 !important;}
#dataform {overflow: hidden}
.doc-title input {border: unset; font-size: 18px; font-weight: bold; color: #3c4353; padding-left: 16px;}
.doc-title .form-control:focus {border: unset; box-shadow: unset;}
.doc-title input::-webkit-input-placeholder {color: #D8DBDE;}
.doc-title.required:after {top: 4px; right: 0; left: 12px; display: inline-table;}
#submit {margin-right: 12px;}
#headerBox {border-bottom: 1px solid #e3e3e3;}
#editorContent {padding: 0;}
#contentBox {padding: 0; width: 100%;}
.ke-container {overflow: visible;}
.ke-container, .contenthtml {border: unset; background: #efefef;}
.ke-container.focus {box-shadow: unset; border-color: unset;}
.ke-toolbar {padding-left: 20px; width: 150%; height: 30px; border-bottom: unset;}
.ke-edit {border-top: 1px solid rgb(220, 220, 220)}
.ke-edit, .CodeMirror {margin-left: 20px; background: #fff;}
.kindeditor-ph {padding-left: 20px !important;}
.editor-toolbar {background: #fff; padding-left: 20px; border-right: unset; border-top: unset; height: 30px;}
.hide-sidebar .ke-edit {padding-right: 20px;}
.hide-sidebar .CodeMirror {padding-right: 50px;}
.CodeMirror.CodeMirror-wrap {border-left: 0; border-right: 0; border-bottom: 0;}
#sidebar {top: 30px;}
#sidebar .sidebar-toggle {right: 0; left: 0px; background: #efefef; border-radius: 0px; width: 20px; border-top: 1px solid rgb(220, 220, 220);}
#sidebar > .sidebar-toggle:hover {background: #efefef;}
#sidebar {width: 500px;}
#sidebar table {margin-top: 5px;}
#sidebar table th {font-weight: 400 !important;}
.hide-sidebar #sidebar > .sidebar-toggle > .icon:before {content: "\e314";}
.hide-sidebar #sidebar > .sidebar-toggle {left: -20px; z-index: 9;}
#sidebar .cell {border-top: 1px solid rgb(220, 220, 220); border-radius: 0px;}
#sidebar > .sidebar-toggle > .icon.icon-angle-right {left: 4px;}
.file-title {max-width: 130px !important;}
.th-control {vertical-align: top !important;}
#noticeAcl {margin: 0;}
</style>
<div id="mainContent" class="main-content">
<form class="load-indicator main-form form-ajax" id="dataform" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<tbody>
<tr id='headerBox'>
<td class="doc-title" colspan='4'><?php echo html::input('title', $doc->title, "placeholder='{$lang->doc->titlePlaceholder}' class='form-control' required");?></td>
<td class="text-right"><?php echo html::submitButton('', '', 'btn btn-primary') . html::backButton('', '', 'btn');?></td>
</tr>
<tr>
<td colspan='5' id="editorContent">
<div class="main-row fade in">
<div id='contentBox' class="main-col">
<div class='contenthtml'><?php echo html::textarea('content', htmlSpecialString($doc->content), "style='width:100%;'");?></div>
<?php echo html::hidden('contentType', $doc->contentType);?>
<?php echo html::hidden('type', 'text');?>
<?php echo html::hidden('editedDate', $doc->editedDate);?>
</div>
<div class="basicInfoBox side-col" id="sidebar">
<div class="sidebar-toggle"><i class="icon icon-angle-right"></i></div>
<div class="cell" style="width: 100%">
<div class="detail">
<div class='detail-title'><?php echo $lang->story->legendBasicInfo;?></div>
<table class='table table-form'>
<tr>
<th class='w-100px'><?php echo $lang->doc->lib;?></th>
<td colspan="2" class="required"><?php echo html::select('lib', $libs, $doc->lib, "class='form-control chosen' onchange=loadDocModule(this.value)");?></td>
</tr>
<tr>
<th><?php echo $lang->doc->module;?></th>
<td colspan="2">
<span id='moduleBox'><?php echo html::select('module', $moduleOptionMenu, $doc->module, "class='form-control chosen'");?></span>
</td>
</tr>
<tr>
<th><?php echo $lang->doc->keywords;?></th>
<td colspan='2'><?php echo html::input('keywords', $doc->keywords, "class='form-control' placeholder='{$lang->doc->keywordsTips}'");?></td>
</tr>
<tr id='fileBox'>
<th><?php echo $lang->doc->files;?></th>
<td colspan='2'><?php echo $this->fetch('file', 'buildform');?></td>
</tr>
<tr>
<th><?php echo $lang->doc->mailto;?></th>
<td colspan="2">
<div class="input-group">
<?php
echo html::select('mailto[]', $users, $doc->mailto, "multiple class='form-control picker-select' data-drop-direction='top'");
echo $this->fetch('my', 'buildContactLists');
?>
</div>
</td>
</tr>
<tr>
<th class="th-control"><?php echo $lang->doclib->control;?></th>
<td colspan='2'>
<?php $acl = $lib->acl == 'private' ? 'private' : $doc->acl;?>
<?php echo html::radio('acl', $lang->doc->aclList, $acl, "onchange='toggleAcl(this.value, \"doc\")'")?>
<p class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['doc'][$acl];?></p>
</td>
</tr>
<tr id='whiteListBox' class='hidden'>
<th><?php echo $lang->doc->whiteList;?></th>
<td colspan='2'>
<div class='input-group w-p100'>
<span class='input-group-addon groups-addon'><?php echo $lang->doclib->group?></span>
<?php echo html::select('groups[]', $groups, $doc->groups, "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
<div class='input-group w-p100'>
<span class='input-group-addon'><?php echo $lang->doclib->user?></span>
<?php echo html::select('users[]', $users, $doc->users, "class='form-control picker-select' multiple data-drop-direction='top'")?>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</form>
</div>
<script>
$(function()
{
$('.doc-title input').focus();
$('#dataform').submit(function()
{
setTimeout(function(){$('#dataform').scrollTop(0)}, 100);
});
var contentHeight = $(document).height() - 120;
$('#sidebar').height(contentHeight);
setTimeout(function(){$('.ke-edit-iframe, .ke-edit').height(contentHeight);}, 100);
setTimeout(function(){$('.CodeMirror').height(contentHeight);}, 100);
$('#editorContent .icon.icon-angle-right').css('top', '50%');
})
</script>
<?php js::set('noticeAcl', $lang->doc->noticeAcl['doc']);?>
<?php include '../../common/view/footer.html.php';?>
+13 -6
View File
@@ -21,12 +21,19 @@
<table class='table table-form'>
<tr>
<th class='w-80px'><?php echo $lang->doc->libType;?></th>
<?php if($config->vision == 'lite'):?>
<?php $globalList = $lang->doc->libTypeList;?>
<?php else:?>
<?php $globalList = $lang->doc->libTypeList + $lang->doc->libGlobalList;?>
<?php endif;?>
<td class='w-p90'><?php echo html::radio('objectType', $globalList, key($globalList));?></td>
<td class='w-p90'><?php echo html::radio('objectType', $globalTypeList, $defaultType, "onchange=loadDocLibs(this.value)");?></td>
</tr>
<tr>
<th class='w-100px'><?php echo $lang->doc->lib;?></th>
<td class='w-p90'><?php echo html::select('lib', $libs, '', "class='form-control chosen'");?></td>
</tr>
<tr id='docType'>
<th><?php echo $lang->doc->type;?></th>
<?php
$typeKeyList = array();
foreach($lang->doc->types as $typeKey => $typeName) $typeKeyList[$typeKey] = $typeKey;
?>
<td><?php echo html::radio('type', $lang->doc->types, 'text');?></td>
</tr>
<tr>
<td colspan='3' class='text-center form-actions'><?php echo html::submitButton($lang->confirm);?></td>
+15 -5
View File
@@ -139,7 +139,14 @@ $config->execution->gantt->linkType['end']['end'] = 2;
$config->execution->gantt->linkType['begin']['end'] = 3;
$config->execution->datatable = new stdclass();
$config->execution->datatable->defaultField = array('id', 'name', 'code', 'project', 'PM', 'status', 'progress', 'percent', 'attribute', 'begin', 'end', 'estimate', 'consumed', 'left', 'burn', 'actions');
if(!isset($config->setCode) or $config->setCode == 1)
{
$config->execution->datatable->defaultField = array('id', 'name', 'code', 'project', 'PM', 'status', 'progress', 'percent', 'attribute', 'begin', 'end', 'estimate', 'consumed', 'left', 'burn', 'actions');
}
else
{
$config->execution->datatable->defaultField = array('id', 'name', 'project', 'PM', 'status', 'progress', 'percent', 'attribute', 'begin', 'end', 'estimate', 'consumed', 'left', 'burn', 'actions');
}
$config->execution->datatable->fieldList['id']['title'] = 'idAB';
$config->execution->datatable->fieldList['id']['fixed'] = 'left';
@@ -151,10 +158,13 @@ $config->execution->datatable->fieldList['name']['fixed'] = 'left';
$config->execution->datatable->fieldList['name']['width'] = 'auto';
$config->execution->datatable->fieldList['name']['required'] = 'yes';
$config->execution->datatable->fieldList['code']['title'] = 'code';
$config->execution->datatable->fieldList['code']['fixed'] = 'no';
$config->execution->datatable->fieldList['code']['width'] = '95';
$config->execution->datatable->fieldList['code']['required'] = 'no';
if(!isset($config->setCode) or $config->setCode == 1)
{
$config->execution->datatable->fieldList['code']['title'] = 'code';
$config->execution->datatable->fieldList['code']['fixed'] = 'no';
$config->execution->datatable->fieldList['code']['width'] = '95';
$config->execution->datatable->fieldList['code']['required'] = 'no';
}
$config->execution->datatable->fieldList['project']['title'] = 'project';
$config->execution->datatable->fieldList['project']['fixed'] = 'no';
+5 -4
View File
@@ -462,7 +462,7 @@ class executionModel extends model
$oldExecution = $this->dao->findById($executionID)->from(TABLE_EXECUTION)->fetch();
/* Judgment of required items. */
if($oldExecution->type != 'stage' and $this->post->code == '')
if($oldExecution->type != 'stage' and $this->post->code == '' and (!isset($this->config->setCode) or $this->config->setCode == 1))
{
dao::$errors['code'] = sprintf($this->lang->error->notempty, $this->lang->execution->code);
return false;
@@ -660,13 +660,12 @@ class executionModel extends model
foreach($data->executionIDList as $executionID)
{
$executionName = $data->names[$executionID];
$executionCode = $data->codes[$executionID];
if(isset($data->codes)) $executionCode = $data->codes[$executionID];
$executionID = (int)$executionID;
$executions[$executionID] = new stdClass();
$executions[$executionID]->id = $executionID;
$executions[$executionID]->name = $executionName;
$executions[$executionID]->code = $executionCode;
$executions[$executionID]->PM = $data->PMs[$executionID];
$executions[$executionID]->PO = $data->POs[$executionID];
$executions[$executionID]->QD = $data->QDs[$executionID];
@@ -680,13 +679,15 @@ class executionModel extends model
$executions[$executionID]->days = $data->dayses[$executionID];
$executions[$executionID]->lastEditedBy = $this->app->user->account;
$executions[$executionID]->lastEditedDate = helper::now();
if(isset($data->codes)) $executions[$executionID]->code = $executionCode;
if(isset($data->projects)) $executions[$executionID]->project = zget($data->projects, $executionID, 0);
if(isset($data->attributes)) $executions[$executionID]->attribute = zget($data->attributes, $executionID, '');
if($executions[$executionID]->status == 'closed') $executions[$executionID]->closedDate = helper::now();
if($executions[$executionID]->status == 'suspended') $executions[$executionID]->suspendedDate = helper::today();
/* Check unique code for edited executions. */
if($projectModel == 'scrum' and empty($executionCode))
if($projectModel == 'scrum' and isset($executionCode) and empty($executionCode))
{
dao::$errors['code'][] = 'execution#' . $executionID . sprintf($this->lang->error->notempty, $this->lang->project->code);
return false;
+11 -9
View File
@@ -35,14 +35,12 @@
}
}
$minWidth = (count($visibleFields) > 5) ? 'w-150px' : '';
$name = $from == 'execution' ? 'execName' : 'name';
$code = $from == 'execution' ? 'execCode' : 'code';
$PM = $from == 'execution' ? 'execPM' : 'PM';
$type = $from == 'execution' ? 'execType' : 'type';
$desc = $from == 'execution' ? 'execDesc' : 'desc';
$status = $from == 'execution' ? 'execStatus' : 'status';
$name = $from == 'execution' ? 'execName' : 'name';
$code = $from == 'execution' ? 'execCode' : 'code';
$PM = $from == 'execution' ? 'execPM' : 'PM';
$type = $from == 'execution' ? 'execType' : 'type';
$desc = $from == 'execution' ? 'execDesc' : 'desc';
$status = $from == 'execution' ? 'execStatus' : 'status';
?>
<form class='main-form' method='post' target='hiddenwin' id='executionForm' action='<?php echo inLink('batchEdit');?>'>
<div class="table-responsive">
@@ -54,7 +52,9 @@
<th class='c-project required' style="width:100%"><?php echo $lang->execution->projectName;?></th>
<?php endif;?>
<th class='required <?php echo $minWidth?>' style="width:100%"><?php echo $lang->execution->$name;?></th>
<?php if(!isset($config->setCode) and $config->setCode == 1):?>
<th class='c-code required'><?php echo $lang->execution->$code;?></th>
<?php endif;?>
<th class='c-user<?php echo zget($visibleFields, 'PM', ' hidden') . zget($requiredFields, 'PM', '', ' required');?>'><?php echo $lang->execution->$PM;?></th>
<th class='c-user<?php echo zget($visibleFields, 'PO', ' hidden') . zget($requiredFields, 'PO', '', ' required');?>'><?php echo $lang->execution->PO;?></th>
<th class='c-user<?php echo zget($visibleFields, 'QD', ' hidden') . zget($requiredFields, 'QD', '', ' required');?>'><?php echo $lang->execution->QD;?></th>
@@ -86,7 +86,9 @@
<td class='text-left' style='overflow:visible'><?php echo html::select("projects[$executionID]", $allProjects, $executions[$executionID]->project, "class='form-control picker-select' data-lastselected='{$executions[$executionID]->project}' onchange='changeProject(this, $executionID, {$executions[$executionID]->project})'");?></td>
<?php endif;?>
<td title='<?php echo $executions[$executionID]->name?>'><?php echo html::input("names[$executionID]", $executions[$executionID]->name, "id='names{$executionID}' class='form-control'");?></td>
<td><?php echo html::input("codes[$executionID]", $executions[$executionID]->code, "class='form-control'");?></td>
<?php if(!isset($config->setCode) and $config->setCode == 1):?>
<td><?php echo html::input("codes[$executionID]", $executions[$executionID]->code, "class='form-control'");?></td>
<?php endif;?>
<td class='text-left<?php echo zget($visibleFields, 'PM', ' hidden')?>' style='overflow:visible'><?php echo html::select("PMs[$executionID]", $pmUsers, $executions[$executionID]->PM, "class='form-control picker-select'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'PO', ' hidden')?>' style='overflow:visible'><?php echo html::select("POs[$executionID]", $poUsers, $executions[$executionID]->PO, "class='form-control picker-select'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'QD', ' hidden')?>' style='overflow:visible'><?php echo html::select("QDs[$executionID]", $qdUsers, $executions[$executionID]->QD, "class='form-control picker-select'");?></td>
+2
View File
@@ -70,10 +70,12 @@
<td class="col-main"><?php echo html::input('name', $name, "class='form-control' required");?></td>
<td colspan='2'></td>
</tr>
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
<tr>
<th><?php echo $showExecutionExec ? $lang->execution->execCode : $lang->execution->code;?></th>
<td><?php echo html::input('code', $code, "class='form-control' required");?></td><td></td><td></td>
</tr>
<?php endif;?>
<tr>
<th id='dateRange'><?php echo $lang->execution->dateRange;?></th>
<td>
+1 -1
View File
@@ -88,7 +88,7 @@
<span class='label-action'><?php echo $action->actionLabel;?></span>
<span class="text"><?php echo $action->objectLabel;?></span>
<span class="label label-id"><?php echo $action->objectID;?></span>
<?php if($action->objectName) echo html::a($action->objectLink, $action->objectName);?>
<?php if($action->objectName) echo !empty($action->objectLink) ? html::a($action->objectLink, $action->objectName) : $action->objectName;?>
</span>
</div>
</li>
+2
View File
@@ -39,10 +39,12 @@
<th class='w-120px'><?php echo $lang->execution->name;?></th>
<td><?php echo html::input('name', $execution->name, "class='form-control' required");?></td><td></td>
</tr>
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
<tr>
<th><?php echo $lang->execution->code;?></th>
<td><?php echo html::input('code', $execution->code, "class='form-control' required");?></td>
</tr>
<?php endif;?>
<tr>
<th id="dateRange"><?php echo $lang->execution->dateRange;?></th>
<td>
+2 -1
View File
@@ -158,7 +158,8 @@
<div class="col-sm-12">
<div class="cell">
<div class="detail">
<h2 class="detail-title"><span class="label-id"><?php echo $execution->id;?></span> <span class="label label-light label-outline"><?php echo $execution->code;?></span> <?php echo $execution->name;?></h2>
<?php $hiddenCode = (isset($config->setCode) and $config->setCode == 0) ? 'hidden' : '';?>
<h2 class="detail-title"><span class="label-id"><?php echo $execution->id;?></span> <span class="label label-light label-outline <?php echo $hiddenCode;?>"><?php echo $execution->code;?></span> <?php echo $execution->name;?></h2>
<div class="detail-content article-content">
<div><span class="text-limit hidden" data-limit-size="40"><?php echo $execution->desc;?></span><a class="text-primary text-limit-toggle small" data-text-expand="<?php echo $lang->expand;?>" data-text-collapse="<?php echo $lang->collapse;?>"></a></div>
<p>
+8 -2
View File
@@ -131,8 +131,14 @@ class gitModel extends model
$gitlabAccountPairs = array();
if($repo->SCM == 'Gitlab')
{
$gitlabUserList = $this->loadModel('gitlab')->apiGetUsers($repo->gitlab);
$acountIDPairs = $this->gitlab->getUserIdAccountPairs($repo->gitlab);
$gitlabUserList = $this->loadModel('gitlab')->apiGetUsers($repo->gitService);
$acountIDPairs = $this->gitlab->getUserIdAccountPairs($repo->gitService);
foreach($gitlabUserList as $gitlabUser) $gitlabAccountPairs[$gitlabUser->realname] = zget($acountIDPairs, $gitlabUser->id, '');
}
elseif($repo->SCM == 'Gitea')
{
$gitlabUserList = $this->loadModel('gitea')->apiGetUsers($repo->gitService);
$acountIDPairs = $this->gitea->getUserAccountIdPairs($repo->gitService, 'openID,account');
foreach($gitlabUserList as $gitlabUser) $gitlabAccountPairs[$gitlabUser->realname] = zget($acountIDPairs, $gitlabUser->id, '');
}
+55
View File
@@ -43,6 +43,12 @@ class gitea extends control
/* Admin user don't need bind. */
$giteaList = $this->gitea->getList($orderBy, $pager);
$myGiteas = $this->gitea->getGiteaListByAccount();
foreach($giteaList as $gitea)
{
$gitea->isBindUser = true;
if(!$this->app->user->admin and !isset($myGiteas[$gitea->id])) $gitea->isBindUser = false;
}
$this->view->title = $this->lang->gitea->common . $this->lang->colon . $this->lang->gitea->browse;
$this->view->giteaList = $giteaList;
@@ -164,4 +170,53 @@ class gitea extends control
return true;
}
/**
* Bind gitea user to zentao users.
*
* @param int $giteaID
* @access public
* @return void
*/
public function bindUser($giteaID)
{
$zentaoUsers = $this->dao->select('account,email,realname')->from(TABLE_USER)->fetchAll('account');
$userPairs = $this->loadModel('user')->getPairs('noclosed|noletter');
if($_POST)
{
$this->gitea->bindUser($giteaID);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->server->http_referer));
}
$this->view->title = $this->lang->gitea->bindUser;
$this->view->userPairs = $userPairs;
$this->view->giteaUsers = $this->gitea->apiGetUsers($giteaID);
$this->view->bindedUsers = $this->gitea->getUserAccountIdPairs($giteaID);
$this->view->matchedResult = $this->gitea->getMatchedUsers($giteaID, $this->view->giteaUsers, $zentaoUsers);
$this->display();
}
/**
* Ajax getProjectBranches
*
* @param int $giteaID
* @param string $project
* @access public
* @return void
*/
public function ajaxGetProjectBranches($giteaID, $project)
{
if(!$giteaID or !$project) return $this->send(array('message' => array()));
$project = urldecode(base64_decode($project));
$branches = $this->gitea->apiGetBranches($giteaID, $project);
$options = "<option value=''></option>";
foreach($branches as $branch)
{
$options .= "<option value='{$branch->name}'>{$branch->name}</option>";
}
$this->send($options);
}
}
+10 -2
View File
@@ -8,6 +8,13 @@ $lang->gitea->edit = 'Edit Gitea';
$lang->gitea->view = 'View Gitea';
$lang->gitea->delete = 'Delete Gitea';
$lang->gitea->confirmDelete = 'Do you want to delete this Gitea server?';
$lang->gitea->bindUser = 'Bind User';
$lang->gitea->giteaAccount = 'Gitea Account';
$lang->gitea->zentaoAccount = 'Zentao Account';
$lang->gitea->bindingStatus = 'Binding Status';
$lang->gitea->notBind = 'Not bind';
$lang->gitea->binded = 'Binded';
$lang->gitea->bindDynamic = '%s and Zentao user %s';
$lang->gitea->browseAction = 'Gitea List';
$lang->gitea->deleteAction = 'Delete Gitea';
@@ -17,8 +24,9 @@ $lang->gitea->name = "Server Name";
$lang->gitea->url = 'Server URL';
$lang->gitea->token = 'Token';
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
$lang->gitea->bindUserError = "Can not bind users repeatedly %s";
$lang->gitea->server = "Server List";
$lang->gitea->lblCreate = 'Create Gitea Server';
+10 -2
View File
@@ -8,6 +8,13 @@ $lang->gitea->edit = 'Edit Gitea';
$lang->gitea->view = 'View Gitea';
$lang->gitea->delete = 'Delete Gitea';
$lang->gitea->confirmDelete = 'Do you want to delete this Gitea server?';
$lang->gitea->bindUser = 'Bind User';
$lang->gitea->giteaAccount = 'Gitea Account';
$lang->gitea->zentaoAccount = 'Zentao Account';
$lang->gitea->bindingStatus = 'Binding Status';
$lang->gitea->notBind = 'Not bind';
$lang->gitea->binded = 'Binded';
$lang->gitea->bindDynamic = '%s and Zentao user %s';
$lang->gitea->browseAction = 'Gitea List';
$lang->gitea->deleteAction = 'Delete Gitea';
@@ -17,8 +24,9 @@ $lang->gitea->name = "Server Name";
$lang->gitea->url = 'Server URL';
$lang->gitea->token = 'Token';
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
$lang->gitea->bindUserError = "Can not bind users repeatedly %s";
$lang->gitea->server = "Server List";
$lang->gitea->lblCreate = 'Create Gitea Server';
+10 -2
View File
@@ -8,6 +8,13 @@ $lang->gitea->edit = 'Edit Gitea';
$lang->gitea->view = 'View Gitea';
$lang->gitea->delete = 'Delete Gitea';
$lang->gitea->confirmDelete = 'Do you want to delete this Gitea server?';
$lang->gitea->bindUser = 'Bind User';
$lang->gitea->giteaAccount = 'Gitea Account';
$lang->gitea->zentaoAccount = 'Zentao Account';
$lang->gitea->bindingStatus = 'Binding Status';
$lang->gitea->notBind = 'Not bind';
$lang->gitea->binded = 'Binded';
$lang->gitea->bindDynamic = '%s and Zentao user %s';
$lang->gitea->browseAction = 'Gitea List';
$lang->gitea->deleteAction = 'Delete Gitea';
@@ -17,8 +24,9 @@ $lang->gitea->name = "Server Name";
$lang->gitea->url = 'Server URL';
$lang->gitea->token = 'Token';
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
$lang->gitea->bindUserError = "Can not bind users repeatedly %s";
$lang->gitea->server = "Server List";
$lang->gitea->lblCreate = 'Create Gitea Server';
+10 -2
View File
@@ -8,6 +8,13 @@ $lang->gitea->edit = 'Edit Gitea';
$lang->gitea->view = 'View Gitea';
$lang->gitea->delete = 'Delete Gitea';
$lang->gitea->confirmDelete = 'Do you want to delete this Gitea server?';
$lang->gitea->bindUser = 'Bind User';
$lang->gitea->giteaAccount = 'Gitea Account';
$lang->gitea->zentaoAccount = 'Zentao Account';
$lang->gitea->bindingStatus = 'Binding Status';
$lang->gitea->notBind = 'Not bind';
$lang->gitea->binded = 'Binded';
$lang->gitea->bindDynamic = '%s and Zentao user %s';
$lang->gitea->browseAction = 'Gitea List';
$lang->gitea->deleteAction = 'Delete Gitea';
@@ -17,8 +24,9 @@ $lang->gitea->name = "Server Name";
$lang->gitea->url = 'Server URL';
$lang->gitea->token = 'Token';
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
$lang->gitea->tokenLimit = "The current token has no admin privilege. Please regenerate one with root user in Gitea.";
$lang->gitea->hostError = "So the current Gitea server address is invalid, please confirm that the current server can be accessed and try again.";
$lang->gitea->bindUserError = "Can not bind users repeatedly %s";
$lang->gitea->server = "Server List";
$lang->gitea->lblCreate = 'Create Gitea Server';
+10 -2
View File
@@ -8,6 +8,13 @@ $lang->gitea->edit = '编辑Gitea';
$lang->gitea->view = '查看Gitea';
$lang->gitea->delete = '删除Gitea';
$lang->gitea->confirmDelete = '确认删除该Gitea吗?';
$lang->gitea->bindUser = '绑定用户';
$lang->gitea->giteaAccount = 'Gitea用户';
$lang->gitea->zentaoAccount = '禅道用户';
$lang->gitea->bindingStatus = '绑定状态';
$lang->gitea->notBind = '未绑定';
$lang->gitea->binded = '已绑定';
$lang->gitea->bindDynamic = '%s与禅道用户%s';
$lang->gitea->browseAction = 'Gitea列表';
$lang->gitea->deleteAction = '删除Gitea';
@@ -17,8 +24,9 @@ $lang->gitea->name = "服务器名称";
$lang->gitea->url = '服务器地址';
$lang->gitea->token = 'Token';
$lang->gitea->tokenLimit = "Gitea Token权限不足。";
$lang->gitea->hostError = "当前Gitea服务器地址无效,请确认当前服务器可被访问";
$lang->gitea->tokenLimit = "Gitea Token权限不足。";
$lang->gitea->hostError = "当前Gitea服务器地址无效,请确认当前服务器可被访问";
$lang->gitea->bindUserError = "不能重复绑定用户 %s";
$lang->gitea->server = "服务器列表";
$lang->gitea->lblCreate = '添加Gitea服务器';
+7
View File
@@ -8,6 +8,13 @@ $lang->gitea->edit = '编辑Gitea';
$lang->gitea->view = '查看Gitea';
$lang->gitea->delete = '删除Gitea';
$lang->gitea->confirmDelete = '确认删除该Gitea吗?';
$lang->gitea->bindUser = '绑定用户';
$lang->gitea->giteaAccount = 'Gitea用户';
$lang->gitea->zentaoAccount = '禅道用户';
$lang->gitea->bindingStatus = '绑定状态';
$lang->gitea->notBind = '未绑定';
$lang->gitea->binded = '已绑定';
$lang->gitea->bindDynamic = '%s与禅道用户%s';
$lang->gitea->browseAction = 'Gitea列表';
$lang->gitea->deleteAction = '删除Gitea';
+369
View File
@@ -104,6 +104,63 @@ class giteaModel extends model
return $this->loadModel('pipeline')->update($id);
}
/**
* Bind users.
*
* @param int $giteaID
* @access public
* @return array
*/
public function bindUser($giteaID)
{
$userPairs = $this->loadModel('user')->getPairs('noclosed|noletter');
$users = $this->post->zentaoUsers;
$giteaNames = $this->post->giteaUserNames;
$accountList = array();
$repeatUsers = array();
foreach($users as $openID => $user)
{
if(empty($user)) continue;
if(isset($accountList[$user])) $repeatUsers[] = zget($userPairs, $user);
$accountList[$user] = $openID;
}
if(count($repeatUsers))
{
dao::$errors[] = sprintf($this->lang->gitea->bindUserError, join(',', $repeatUsers));
return false;
}
$user = new stdclass;
$user->providerID = $giteaID;
$user->providerType = 'gitea';
$oldUsers = $this->dao->select('*')->from(TABLE_OAUTH)->where('providerType')->eq($user->providerType)->andWhere('providerID')->eq($user->providerID)->fetchAll('openID');
foreach($users as $openID => $account)
{
$existAccount = isset($oldUsers[$openID]) ? $oldUsers[$openID] : '';
if($existAccount and $existAccount->account != $account)
{
$this->dao->delete()
->from(TABLE_OAUTH)
->where('openID')->eq($openID)
->andWhere('providerType')->eq($user->providerType)
->andWhere('providerID')->eq($user->providerID)
->exec();
$this->loadModel('action')->create('giteauser', $giteaID, 'unbind', '', sprintf($this->lang->gitea->bindDynamic, $giteaNames[$openID], $zentaoUsers[$existAccount->account]->realname));
}
if(!$existAccount or $existAccount->account != $account)
{
if(!$account) continue;
$user->account = $account;
$user->openID = $openID;
$this->dao->insert(TABLE_OAUTH)->data($user)->exec();
$this->loadModel('action')->create('giteauser', $giteaID, 'bind', '', sprintf($this->lang->gitea->bindDynamic, $giteaNames[$openID], $zentaoUsers[$account]->realname));
}
}
}
/**
* Api error handling.
*
@@ -224,4 +281,316 @@ class giteaModel extends model
->andWhere('account')->eq($account)
->fetchPairs('providerID');
}
/**
* Get zentao account gitea user id pairs of one gitea.
*
* @param int $giteaID
* @access public
* @return array
*/
public function getUserAccountIdPairs($giteaID, $fields = 'account,openID')
{
return $this->dao->select($fields)->from(TABLE_OAUTH)
->where('providerType')->eq('gitea')
->andWhere('providerID')->eq($giteaID)
->fetchPairs();
}
/**
* Get gitea user id by zentao account.
*
* @param int $giteaID
* @param string $zentaoAccount
* @access public
* @return array
*/
public function getUserIDByZentaoAccount($giteaID, $zentaoAccount)
{
return $this->dao->select('openID')->from(TABLE_OAUTH)
->where('providerType')->eq('gitea')
->andWhere('providerID')->eq($giteaID)
->andWhere('account')->eq($zentaoAccount)
->fetch('openID');
}
/**
* Get matched gitea users.
*
* @param int $giteaID
* @param array $giteaUsers
* @param array $zentaoUsers
* @access public
* @return array
*/
public function getMatchedUsers($giteaID, $giteaUsers, $zentaoUsers)
{
$matches = new stdclass;
foreach($giteaUsers as $giteaUser)
{
foreach($zentaoUsers as $zentaoUser)
{
if($giteaUser->account == $zentaoUser->account) $matches->accounts[$giteaUser->account][] = $zentaoUser->account;
if($giteaUser->realname == $zentaoUser->realname) $matches->names[$giteaUser->realname][] = $zentaoUser->account;
if($giteaUser->email == $zentaoUser->email) $matches->emails[$giteaUser->email][] = $zentaoUser->account;
}
}
$bindedUsers = $this->getUserAccountIdPairs($giteaID, 'openID,account');
$matchedUsers = array();
foreach($giteaUsers as $giteaUser)
{
if(isset($bindedUsers[$giteaUser->account]))
{
$giteaUser->zentaoAccount = $bindedUsers[$giteaUser->account];
$matchedUsers[] = $giteaUser;
continue;
}
$matchedZentaoUsers = array();
if(isset($matches->accounts[$giteaUser->account])) $matchedZentaoUsers = array_merge($matchedZentaoUsers, $matches->accounts[$giteaUser->account]);
if(isset($matches->emails[$giteaUser->email])) $matchedZentaoUsers = array_merge($matchedZentaoUsers, $matches->emails[$giteaUser->email]);
if(isset($matches->names[$giteaUser->realname])) $matchedZentaoUsers = array_merge($matchedZentaoUsers, $matches->names[$giteaUser->realname]);
$matchedZentaoUsers = array_unique($matchedZentaoUsers);
if(count($matchedZentaoUsers) == 1)
{
$giteaUser->zentaoAccount = current($matchedZentaoUsers);
$matchedUsers[] = $giteaUser;
}
}
return $matchedUsers;
}
/**
* Get project by api.
*
* @param int $giteaID
* @param int $projectID
* @access public
* @return void
*/
public function apiGetSingleProject($giteaID, $projectID)
{
$apiRoot = $this->getApiRoot($giteaID);
if(!$apiRoot) return array();
$url = sprintf($apiRoot, "/repos/$projectID");
$project = json_decode(commonModel::http($url));
if(isset($project->name))
{
$project->name_with_namespace = $project->full_name;
$project->path_with_namespace = $project->full_name;
$project->http_url_to_repo = $project->html_url;
$project->name_with_namespace = $project->full_name;
}
return $project;
}
/**
* Get projects by api.
*
* @param int $giteaID
* @param bool $sudo
* @access public
* @return array
*/
public function apiGetProjects($giteaID, $sudo = true)
{
$apiRoot = $this->getApiRoot($giteaID, $sudo);
if(!$apiRoot) return array();
$url = sprintf($apiRoot, "/repos/search");
$allResults = array();
for($page = 1; true; $page++)
{
$results = json_decode(commonModel::http($url . "&page={$page}&limit=50"));
if(!is_array($results->data)) break;
if(!empty($results->data)) $allResults = array_merge($allResults, $results->data);
if(count($results->data) < 50) break;
}
return $allResults;
}
/**
* Get gitea user list.
*
* @param int $giteaID
* @param bool $onlyLinked
* @access public
* @return array
*/
public function apiGetUsers($giteaID, $onlyLinked = false)
{
$response = array();
$apiRoot = $this->getApiRoot($giteaID);
for($page = 1; true; $page++)
{
$url = sprintf($apiRoot, "/users/search") . "&page={$page}&limit=50";
$result = json_decode(commonModel::http($url));
if(empty($result->data)) break;
$response = array_merge($response, $result->data);
$page += 1;
}
if(empty($response)) return array();
/* Get linked users. */
$linkedUsers = array();
if($onlyLinked) $linkedUsers = $this->getUserAccountIdPairs($giteaID, 'openID,account');
$users = array();
foreach($response as $giteaUser)
{
if($onlyLinked and !isset($linkedUsers[$giteaUser->id])) continue;
$user = new stdclass;
$user->id = $giteaUser->id;
$user->realname = $giteaUser->full_name ? $giteaUser->full_name : $giteaUser->username;
$user->account = $giteaUser->username;
$user->email = zget($giteaUser, 'email', '');
$user->avatar = $giteaUser->avatar_url;
$user->createdAt = zget($giteaUser, 'created', '');
$user->lastActivityOn = zget($giteaUser, 'last_login', '');
$users[] = $user;
}
return $users;
}
/**
* Get project repository branches by api.
*
* @param int $giteaID
* @param string $project
* @access public
* @return object
*/
public function apiGetBranches($giteaID, $project, $pager = null)
{
$url = sprintf($this->getApiRoot($giteaID), "/repos/{$project}/branches");
$allResults = array();
for($page = 1; true; $page++)
{
$results = json_decode(commonModel::http($url . "&page={$page}&limit=50"));
if(!is_array($results)) break;
if(!empty($results)) $allResults = array_merge($allResults, $results);
if(count($results) < 100) break;
}
return $allResults;
}
/**
* Get Forks of a project by API.
*
* @param int $giteaID
* @param string $projectID
* @access public
* @return object
*/
public function apiGetForks($giteaID, $projectID)
{
$url = sprintf($this->getApiRoot($giteaID), "/repos/$projectID/forks");
return json_decode(commonModel::http($url));
}
/**
* Get upstream project by API.
*
* @param int $giteaID
* @param string $projectID
* @access public
* @return void
*/
public function apiGetUpstream($giteaID, $projectID)
{
$currentProject = $this->apiGetSingleProject($giteaID, $projectID);
if(isset($currentProject->parent->full_name)) return $currentProject->parent->full_name;
return array();
}
/**
* Get branches.
*
* @param int $giteaID
* @param string $project
* @access public
* @return array
*/
public function getBranches($giteaID, $project)
{
$rawBranches = $this->apiGetBranches($giteaID, $project);
$branches = array();
foreach($rawBranches as $branch) $branches[] = $branch->name;
return $branches;
}
/**
* Get gitea user id and realname pairs of one gitea.
*
* @param int $giteaID
* @access public
* @return array
*/
public function getUserIdRealnamePairs($giteaID)
{
return $this->dao->select('oauth.openID as openID,user.realname as realname')
->from(TABLE_OAUTH)->alias('oauth')
->leftJoin(TABLE_USER)->alias('user')
->on("oauth.account = user.account")
->where('providerType')->eq('gitea')
->andWhere('providerID')->eq($giteaID)
->fetchPairs();
}
/**
* Get single branch by API.
*
* @param int $giteaID
* @param int $projectID
* @param string $branch
* @access public
* @return object
*/
public function apiGetSingleBranch($giteaID, $projectID, $branch)
{
$url = sprintf($this->getApiRoot($giteaID), "/repos/$projectID/branches/$branch");
return json_decode(commonModel::http($url));
}
/**
* Get protect branches of one project.
*
* @param int $giteaID
* @param string $project
* @param string $keyword
* @access public
* @return array
*/
public function apiGetBranchPrivs($giteaID, $project, $keyword = '')
{
$keyword = urlencode($keyword);
$url = sprintf($this->getApiRoot($giteaID), "/repos/$project/branch_protections");
$branches = json_decode(commonModel::http($url));
if(!is_array($branches)) return $branches;
$newBranches = array();
foreach($branches as $branch)
{
$branch->name = $branch->branch_name;
if(empty($keyword) || stristr($branch->name, $keyword)) $newBranches[] = $branch;
}
return $newBranches;
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php
/**
* The bind user view of gitea module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Yuchun Li <liyuchun@easycorp.ltd>
* @package gitea
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div id="mainContent" class="main-content">
<div class="main-header">
<h2><?php echo $lang->gitea->bindUser;?></h2>
</div>
<form method='post' class='load-indicator main-form form-ajax' enctype='multipart/form-data'>
<div class="table-responsive">
<table class="table table-borderless w-600px">
<thead>
<tr>
<th colspan='2'><?php echo $lang->gitea->giteaAccount;?></th>
<th class='w-150px'><?php echo $lang->gitea->zentaoAccount;?></th>
<th class='w-150px'><?php echo $lang->gitea->bindingStatus;?></th>
</tr>
</thead>
<tbody>
<?php foreach($giteaUsers as $giteaUser):?>
<?php if(isset($giteaUser->zentaoAccount)) continue;?>
<?php echo html::hidden("giteaUserNames[$giteaUser->account]", $giteaUser->realname);?>
<tr>
<td class='w-60px'><?php echo html::image($giteaUser->avatar, "height=40");?></td>
<td class='text-left'>
<strong><?php echo $giteaUser->realname;?></strong>
<br>
<?php echo $giteaUser->account;?>
<?php if($giteaUser->email) echo " &lt;" . $giteaUser->email . "&gt;";?>
</td>
<td><?php echo html::select("zentaoUsers[$giteaUser->account]", $userPairs, '', "class='form-control select chosen'" );?></td>
<td><?php echo $lang->gitea->notBind;?></td>
</tr>
<?php endforeach;?>
<?php foreach($giteaUsers as $giteaUser):?>
<?php if(!isset($giteaUser->zentaoAccount)) continue;?>
<?php echo html::hidden("giteaUserNames[$giteaUser->account]", $giteaUser->realname);?>
<tr>
<td class='w-60px'><?php echo html::image($giteaUser->avatar, "height=40");?></td>
<td>
<strong><?php echo $giteaUser->realname;?></strong>
<br>
<?php echo $giteaUser->account;?>
<?php if($giteaUser->email) echo " &lt;" . $giteaUser->email . "&gt;";?>
</td>
<td><?php echo html::select("zentaoUsers[$giteaUser->account]", $userPairs, $giteaUser->zentaoAccount, "class='form-control select chosen'" );?></td>
<td>
<?php if(isset($bindedUsers[$giteaUser->zentaoAccount])):?>
<?php $zentaoAccount = zget($userPairs, $giteaUser->zentaoAccount, '');?>
<?php if(!empty($zentaoAccount)):?>
<?php echo $lang->gitea->binded;?>
<?php else:?>
<?php echo '<span class="text-red">' . $lang->gitea->bindedError . '</span>';?>
<?php endif;?>
<?php else:?>
<?php echo $lang->gitea->notBind;?>
<?php endif;?>
</td>
</tr>
<?php endforeach;?>
</tbody>
<tfoot>
<tr>
<td colspan="3" class="text-center form-actions">
<?php echo html::submitButton();?>
<?php if(!isonlybody()) echo html::a(inlink('browse', ""), $lang->goback, '', 'class="btn btn-wide"');?>
</td>
</tr>
</tfoot>
</table>
</div>
</form>
</div>
<?php include '../../common/view/footer.html.php';?>
+1
View File
@@ -56,6 +56,7 @@
<td class='c-actions text-left'>
<?php
common::printIcon('gitea', 'edit', "giteaID=$id", '', 'list', 'edit');
echo common::buildIconButton('gitea', 'bindUser', "giteaID=$id", '', 'list', 'link', '', '', false, '', '', 0, $gitea->isBindUser);
common::printIcon('gitea', 'delete', "giteaID=$id", '', 'list', 'trash', 'hiddenwin');
?>
</td>
+105 -382
View File
@@ -47,9 +47,7 @@ class gitlab extends control
foreach($gitlabList as $gitlab)
{
$token = $this->gitlab->apiGetCurrentUser($gitlab->url, $gitlab->token);
$gitlab->isAdminToken = (isset($token->is_admin) and $token->is_admin);
$gitlab->isBindUser = true;
$gitlab->isBindUser = true;
if(!$this->app->user->admin and !isset($myGitLabs[$gitlab->id])) $gitlab->isBindUser = false;
}
@@ -722,7 +720,7 @@ class gitlab extends control
}
$gitlab = $this->gitlab->getByID($gitlabID);
$repos = $this->loadModel('repo')->getGitLabRepoList($gitlabID);
$repos = $this->loadModel('repo')->getRepoListByClient($gitlabID);
$repoPairs = array();
foreach($repos as $repo) $repoPairs[$repo->path] = $repo->id;
@@ -911,176 +909,6 @@ class gitlab extends control
$this->display();
}
/**
* Browse gitlab protect branch.
*
* @param int $gitlabID
* @param int $projectID
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function browseBranchPriv($gitlabID, $projectID, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 15, $pageID = 1)
{
$project = $this->gitlab->apiGetSingleProject($gitlabID, $projectID);
if(!$this->app->user->admin)
{
$openID = $this->gitlab->getUserIDByZentaoAccount($gitlabID, $this->app->user->account);
if(!$openID) return print(js::alert($this->lang->gitlab->mustBindUser) . js::locate($this->createLink('gitlab', 'browse')));
if(!$this->gitlab->checkUserAccess($gitlabID, $projectID, $project)) return print(js::alert($this->lang->gitlab->noAccess) . js::locate($this->createLink('gitlab', 'browse')));
}
$keyword = fixer::input('post')->setDefault('keyword', '')->get('keyword');
$branches = $this->gitlab->apiGetBranchPrivs($gitlabID, $projectID, $keyword, $orderBy);
/* Pager. */
$this->app->loadClass('pager', $static = true);
$recTotal = count($branches);
$pager = new pager($recTotal, $recPerPage, $pageID);
$branchList = array_chunk($branches, $pager->recPerPage);
$this->view->keyword = $keyword;
$this->view->pager = $pager;
$this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->browseBranchPriv;
$this->view->levelLang = $this->lang->gitlab->branch->branchCreationLevelList;
$this->view->gitlabID = $gitlabID;
$this->view->projectID = $projectID;
$this->view->project = $project;
$this->view->orderBy = $orderBy;
$this->view->branchList = empty($branchList) ? $branchList: $branchList[$pageID - 1];
$this->display();
}
/**
* Set a gitlab protect branch.
*
* @param int $gitlabID
* @param int $projectID
* @param string $branch
* @access public
* @return void
*/
public function createBranchPriv($gitlabID, $projectID, $branch = '')
{
if(!$this->app->user->admin)
{
$openID = $this->gitlab->getUserIDByZentaoAccount($gitlabID, $this->app->user->account);
if(!$openID) return print(js::alert($this->lang->gitlab->mustBindUser) . js::locate($this->createLink('gitlab', 'browse')));
$project = $this->gitlab->apiGetSingleProject($gitlabID, $projectID);
if(!$this->gitlab->checkUserAccess($gitlabID, $projectID, $project)) return print(js::alert($this->lang->gitlab->noAccess) . js::locate($this->createLink('gitlab', 'browse')));
}
/* Fix error when request type is PATH_INFO and the branch name contains '-'.*/
if($branch) $branch = urldecode(helper::safe64Decode($branch));
if($_POST)
{
$this->gitlab->createBranchPriv($gitlabID, $projectID, $branch);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browseBranchPriv', "gitlabID=$gitlabID&projectID=$projectID")));
}
$branchPriv = new stdClass();
$branchPriv->name = '';
$branchPriv->mergeAccessLevel = 40; // Initialize data, and the operation authority is the maintainers by default.
$branchPriv->pushAccessLevel = 40; // Initialize data, and the operation authority is the maintainers by default.
$title = $this->lang->gitlab->createBranchPriv;
if($branch)
{
$title = $this->lang->gitlab->editBranchPriv;
$branchPriv = $this->gitlab->apiGetSingleBranchPriv($gitlabID, $projectID, $branch);
$branchPriv->name = helper::safe64Encode(urlencode($branchPriv->name));
$branchPriv->mergeAccessLevel = $this->gitlab->checkAccessLevel($branchPriv->merge_access_levels);
$branchPriv->pushAccessLevel = $this->gitlab->checkAccessLevel($branchPriv->push_access_levels);
}
$gitlabBranches = $this->gitlab->apiGetBranches($gitlabID, $projectID);
$protectBranches = $this->gitlab->apiGetBranchPrivs($gitlabID, $projectID, '', 'name_asc');
$protectNames = array_keys($protectBranches);
$branches = array();
foreach($gitlabBranches as $oneBranch)
{
if(!in_array($oneBranch->name, $protectNames) || $oneBranch->name == $branch)
{
$branchName = helper::safe64Encode(urlencode($oneBranch->name));
$branches[$branchName] = $oneBranch->name;
}
}
$this->view->title = $this->lang->gitlab->common . $this->lang->colon . $title;
$this->view->pageTitle = $title;
$this->view->gitlabID = $gitlabID;
$this->view->branch = $branch;
$this->view->projectID = $projectID;
$this->view->branches = $branches;
$this->view->branchPriv = $branchPriv;
$this->display();
}
/**
* Edit a gitlab branch protect.
*
* @param int $gitlabID
* @param int $projectID
* @param string $branch
* @access public
* @return void
*/
public function editBranchPriv($gitlabID, $projectID, $branch)
{
echo $this->fetch('gitlab', 'createBranchPriv', "gitlabID=$gitlabID&projectID=$projectID&branch=$branch");
}
/**
* Delete a gitlab protect branch.
*
* @param int $gitlabID
* @param int $projectID
* @param string $branch
* @param string $confirm
* @access public
* @return void
*/
public function deleteBranchPriv($gitlabID, $projectID, $branch, $confirm = 'no')
{
if(!$this->app->user->admin)
{
$openID = $this->gitlab->getUserIDByZentaoAccount($gitlabID, $this->app->user->account);
if(!$openID) return print(js::alert($this->lang->gitlab->mustBindUser) . js::locate($this->createLink('gitlab', 'browse')));
$project = $this->gitlab->apiGetSingleProject($gitlabID, $projectID);
if(!$this->gitlab->checkUserAccess($gitlabID, $projectID, $project)) return print(js::alert($this->lang->gitlab->noAccess) . js::locate($this->createLink('gitlab', 'browse')));
}
if($confirm != 'yes')
{
$branch = urlencode($branch);
return print(js::confirm($this->lang->gitlab->branch->confirmDelete , inlink('deleteBranchPriv', "gitlabID=$gitlabID&projectID=$projectID&branch=$branch&confirm=yes")));
}
/* Fix error when request type is PATH_INFO and the branch name contains '-'.*/
$branch = urldecode(helper::safe64Decode($branch));
$reponse = $this->gitlab->apiDeleteBranchPriv($gitlabID, $projectID, $branch);
/* If the status code beginning with 20 is returned or empty is returned, it is successful. */
if(!$reponse or substr($reponse->message, 0, 2) == '20')
{
$this->loadModel('action')->create('gitlabbranchPriv', $branch, 'deleted', '', $branch);
return print(js::reload('parent'));
}
echo js::alert($reponse->message);
}
/**
* Browse gitlab tag.
*
@@ -1135,206 +963,6 @@ class gitlab extends control
$this->display();
}
/**
* Browse gitlab protect tag.
*
* @param int $gitlabID
* @param int $projectID
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function browseTagPriv($gitlabID, $projectID, $orderBy = 'name_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$project = $this->gitlab->apiGetSingleProject($gitlabID, $projectID);
if(!$this->app->user->admin)
{
$openID = $this->gitlab->getUserIDByZentaoAccount($gitlabID, $this->app->user->account);
if(!$openID) return print(js::alert($this->lang->gitlab->mustBindUser) . js::locate($this->createLink('gitlab', 'browse')));
if(!$this->gitlab->checkUserAccess($gitlabID, $projectID, $project)) return print(js::alert($this->lang->gitlab->noAccess) . js::locate($this->createLink('gitlab', 'browse')));
}
$this->session->set('gitlabTagPrivList', $this->app->getURI(true));
$keyword = fixer::input('post')->setDefault('keyword', '')->get('keyword');
$gitlabTags = array();
$allTags = $this->gitlab->apiGetTags($gitlabID, $projectID);
foreach($allTags as $tag)
{
$gitlabTags[$tag->name] = $tag;
}
$tagList = array();
$gitlabProtectTags = $this->gitlab->apiGetTagPrivs($gitlabID, $projectID);
foreach($gitlabProtectTags as $gitlabProtectTag)
{
$tag = new stdClass();
$tag->name = $gitlabProtectTag->name;
$tag->lastCommitter = isset($gitlabTags[$tag->name]) ? $gitlabTags[$tag->name]->commit->committer_name : '';
$tag->accessLevels = $gitlabProtectTag->create_access_levels;
$tagList[] = $tag;
}
/* Data search. */
if($keyword)
{
foreach($tagList as $key => $tag)
{
if(strpos($tag->name, $keyword) === false) unset($tagList[$key]);
}
$tagList = array_values($tagList);
}
/* Data sort. */
list($order, $sort) = explode('_', $orderBy);
$orderList = array();
foreach($tagList as $tag) $orderList[] = $tag->$order;
array_multisort($orderList, $sort == 'desc' ? SORT_DESC : SORT_ASC, $tagList);
/* Pager. */
$this->app->loadClass('pager', $static = true);
$recTotal = count($tagList);
$pager = new pager($recTotal, $recPerPage, $pageID);
$tagList = array_chunk($tagList, $pager->recPerPage);
$this->view->gitlab = $this->gitlab->getByID($gitlabID);
$this->view->pager = $pager;
$this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->browseTagPriv;
$this->view->gitlabID = $gitlabID;
$this->view->projectID = $projectID;
$this->view->keyword = $keyword;
$this->view->project = $project;
$this->view->gitlabTagList = empty($tagList) ? $tagList: $tagList[$pageID - 1];
$this->view->orderBy = $orderBy;
$this->display();
}
/**
* Set a gitlab protect tag.
*
* @param int $gitlabID
* @param int $projectID
* @access public
* @return void
*/
public function createTagPriv($gitlabID, $projectID)
{
if(!$this->app->user->admin)
{
$openID = $this->gitlab->getUserIDByZentaoAccount($gitlabID, $this->app->user->account);
if(!$openID) return print(js::alert($this->lang->gitlab->mustBindUser) . js::locate($this->createLink('gitlab', 'browse')));
$project = $this->gitlab->apiGetSingleProject($gitlabID, $projectID);
if(!$this->gitlab->checkUserAccess($gitlabID, $projectID, $project)) return print(js::alert($this->lang->gitlab->noAccess) . js::locate($this->createLink('gitlab', 'browse')));
}
if($_POST)
{
$this->gitlab->createTagPriv($gitlabID, $projectID);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browseTagPriv', "gitlabID=$gitlabID&projectID=$projectID")));
}
$gitlabTags = $this->gitlab->apiGetTags($gitlabID, $projectID);
$protectTags = $this->gitlab->apiGetTagPrivs($gitlabID, $projectID, '', 'name_asc');
$protectNames = array_keys($protectTags);
$tags = array();
foreach($gitlabTags as $tag)
{
if(!in_array($tag->name, $protectNames)) $tags[$tag->name] = $tag->name;
}
$this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->createTagPriv;
$this->view->gitlabID = $gitlabID;
$this->view->projectID = $projectID;
$this->view->tags = $tags;
$this->display();
}
/**
* Edit a gitlab protect tag.
*
* @param int $gitlabID
* @param int $projectID
* @param string $tag
* @access public
* @return void
*/
public function editTagPriv($gitlabID, $projectID, $tag = '')
{
if(!$this->app->user->admin)
{
$openID = $this->gitlab->getUserIDByZentaoAccount($gitlabID, $this->app->user->account);
if(!$openID) return print(js::alert($this->lang->gitlab->mustBindUser) . js::locate($this->createLink('gitlab', 'browse')));
$project = $this->gitlab->apiGetSingleProject($gitlabID, $projectID);
if(!$this->gitlab->checkUserAccess($gitlabID, $projectID, $project)) return print(js::alert($this->lang->gitlab->noAccess) . js::locate($this->createLink('gitlab', 'browse')));
}
/* Fix error when request type is PATH_INFO and the tag name contains '-'.*/
$tag = urldecode(helper::safe64Decode($tag));
if($_POST)
{
$this->gitlab->createTagPriv($gitlabID, $projectID, $tag);
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browseTagPriv', "gitlabID=$gitlabID&projectID=$projectID")));
}
$tagPriv = $this->gitlab->apiGetSingleTagPriv($gitlabID, $projectID, $tag);
$tagPriv->createAccessLevel = $this->gitlab->checkAccessLevel($tagPriv->create_access_levels);
$this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->editTagPriv;
$this->view->gitlabID = $gitlabID;
$this->view->projectID = $projectID;
$this->view->tagPriv = $tagPriv;
$this->view->tag = $tag;
$this->display();
}
/**
* Delete a gitlab protect tag.
*
* @param int $gitlabID
* @param int $projectID
* @param string $tag
* @access public
* @return void
*/
public function deleteTagPriv($gitlabID, $projectID, $tag)
{
if(!$this->app->user->admin)
{
$openID = $this->gitlab->getUserIDByZentaoAccount($gitlabID, $this->app->user->account);
if(!$openID) return print(js::alert($this->lang->gitlab->mustBindUser) . js::locate($this->createLink('gitlab', 'browse')));
$project = $this->gitlab->apiGetSingleProject($gitlabID, $projectID);
if(!$this->gitlab->checkUserAccess($gitlabID, $projectID, $project)) return print(js::alert($this->lang->gitlab->noAccess) . js::locate($this->createLink('gitlab', 'browse')));
}
/* Fix error when request type is PATH_INFO and the tag name contains '-'.*/
$tag = urldecode(helper::safe64Decode($tag));
$reponse = $this->gitlab->apiDeleteTagPriv($gitlabID, $projectID, $tag);
/* If the status code beginning with 20 is returned or empty is returned, it is successful. */
if(!$reponse or substr($reponse->message, 0, 2) == '20')
{
$this->loadModel('action')->create('gitlabtagpriv', 0, 'deleted', '', $tag);
return print(js::reload('parent'));
}
echo js::alert($reponse->message);
}
/**
* Import gitlab issue to zentaopms.
*
@@ -1346,7 +974,7 @@ class gitlab extends control
{
$repo = $this->loadModel('repo')->getRepoByID($repoID);
$productIDList = explode(',', $repo->product);
$gitlabID = $repo->gitlab;
$gitlabID = $repo->gitService;
$projectID = $repo->project;
$gitlab = $this->gitlab->getByID($gitlabID);
@@ -1491,7 +1119,7 @@ class gitlab extends control
$bindedUsers = $this->dao->select('account,openID')
->from(TABLE_OAUTH)
->where('providerType')->eq('gitlab')
->andWhere('providerID')->eq($repo->gitlab)
->andWhere('providerID')->eq($repo->gitService)
->fetchPairs();
if(empty($repo->acl))
@@ -1511,7 +1139,7 @@ class gitlab extends control
}
}
$gitlabCurrentMembers = $this->gitlab->apiGetProjectMembers($repo->gitlab, $repo->project);
$gitlabCurrentMembers = $this->gitlab->apiGetProjectMembers($repo->gitService, $repo->project);
$addedMembers = $updatedMembers = $deletedMembers = array();
/* Get the updated data. */
@@ -1570,17 +1198,17 @@ class gitlab extends control
foreach($addedMembers as $addedMember)
{
$this->gitlab->apiCreateProjectMember($repo->gitlab, $repo->project, $addedMember);
$this->gitlab->apiCreateProjectMember($repo->gitService, $repo->project, $addedMember);
}
foreach($updatedMembers as $updatedMember)
{
$this->gitlab->apiUpdateProjectMember($repo->gitlab, $repo->project, $updatedMember);
$this->gitlab->apiUpdateProjectMember($repo->gitService, $repo->project, $updatedMember);
}
foreach($deletedMembers as $deletedMemberID)
{
$this->gitlab->apiDeleteProjectMember($repo->gitlab, $repo->project, $deletedMemberID);
$this->gitlab->apiDeleteProjectMember($repo->gitService, $repo->project, $deletedMemberID);
}
$repo->acl->users = array_values($accounts);
@@ -1590,7 +1218,7 @@ class gitlab extends control
$repo = $this->loadModel('repo')->getRepoByID($repoID);
$users = $this->loadModel('user')->getPairs('noletter|noempty|nodeleted|noclosed');
$projectMembers = $this->gitlab->apiGetProjectMembers($repo->gitlab, $repo->project);
$projectMembers = $this->gitlab->apiGetProjectMembers($repo->gitService, $repo->project);
if(!is_array($projectMembers)) $projectMembers = array();
/* Get users accesslevel. */
@@ -1598,7 +1226,7 @@ class gitlab extends control
$bindedUsers = $this->dao->select('openID,account')
->from(TABLE_OAUTH)
->where('providerType')->eq('gitlab')
->andWhere('providerID')->eq($repo->gitlab)
->andWhere('providerID')->eq($repo->gitService)
->fetchPairs();
foreach($projectMembers as $projectMember)
@@ -1746,4 +1374,99 @@ class gitlab extends control
echo js::alert($reponse->message);
}
/**
* Manage a gitlab branch protected.
*
* @param int $repoID
* @param int $projectID
* @access public
* @return void
*/
public function manageBranchPriv($gitlabID, $projectID)
{
if(!$this->app->user->admin)
{
$openID = $this->gitlab->getUserIDByZentaoAccount($gitlabID, $this->app->user->account);
if(!$openID) return print(js::alert($this->lang->gitlab->mustBindUser) . js::locate($this->createLink('gitlab', 'browse')));
$project = $this->gitlab->apiGetSingleProject($gitlabID, $projectID);
if(!$this->gitlab->checkUserAccess($gitlabID, $projectID, $project)) return print(js::alert($this->lang->gitlab->noAccess) . js::locate($this->createLink('gitlab', 'browse')));
}
$hasAccessBranches = $this->gitlab->apiGetBranchPrivs($gitlabID, $projectID, '', 'name_asc');
foreach($hasAccessBranches as $branch)
{
$branch->pushAccess = $this->gitlab->checkAccessLevel($branch->push_access_levels);
$branch->mergeAccess = $this->gitlab->checkAccessLevel($branch->merge_access_levels);
}
if(!empty($_POST))
{
$result = $this->gitlab->manageBranchPrivs($gitlabID, $projectID, $hasAccessBranches);
if(!empty($result)) return $this->send(array('result' => 'fail', 'message' => sprintf($this->lang->gitlab->svaeFailed, implode(', ', $result))));
return $this->send(array('message' => $this->lang->saveSuccess, 'result' => 'success', 'locate' => inlink('browseProject', "gitlabID=$gitlabID")));
}
$allBranches = $this->gitlab->apiGetBranches($gitlabID, $projectID);
$noAccessBranches = array();
foreach($allBranches as $branch)
{
if(!isset($hasAccessBranches[$branch->name])) $noAccessBranches[$branch->name] = $branch->name;
}
$this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->browseBranchPriv;
$this->view->gitlabID = $gitlabID;
$this->view->projectID = $projectID;
$this->view->hasAccessBranches = $hasAccessBranches;
$this->view->noAccessBranches = $noAccessBranches;
$this->display();
}
/**
* Manage a gitlab tag protected.
*
* @param int $repoID
* @param int $projectID
* @access public
* @return void
*/
public function manageTagPriv($gitlabID, $projectID)
{
if(!$this->app->user->admin)
{
$openID = $this->gitlab->getUserIDByZentaoAccount($gitlabID, $this->app->user->account);
if(!$openID) return print(js::alert($this->lang->gitlab->mustBindUser) . js::locate($this->createLink('gitlab', 'browse')));
$project = $this->gitlab->apiGetSingleProject($gitlabID, $projectID);
if(!$this->gitlab->checkUserAccess($gitlabID, $projectID, $project)) return print(js::alert($this->lang->gitlab->noAccess) . js::locate($this->createLink('gitlab', 'browse')));
}
$hasAccessTags = $this->gitlab->apiGetTagPrivs($gitlabID, $projectID, '', 'name_asc');
foreach($hasAccessTags as $tag)
{
$tag->createAccess = $this->gitlab->checkAccessLevel($tag->create_access_levels);
}
if(!empty($_POST))
{
$result = $this->gitlab->manageTagPrivs($gitlabID, $projectID, $hasAccessTags);
if(!empty($result)) return $this->send(array('result' => 'fail', 'message' => sprintf($this->lang->gitlab->svaeFailed, implode(', ', $result))));
return $this->send(array('message' => $this->lang->saveSuccess, 'result' => 'success', 'locate' => inlink('browseProject', "gitlabID=$gitlabID")));
}
$allTags = $this->gitlab->apiGetTags($gitlabID, $projectID);
$noAccessTags = array();
foreach($allTags as $tag)
{
if(!isset($hasAccessTags[$tag->name])) $noAccessTags[$tag->name] = $tag->name;
}
$this->view->title = $this->lang->gitlab->common . $this->lang->colon . $this->lang->gitlab->browseTagPriv;
$this->view->gitlabID = $gitlabID;
$this->view->projectID = $projectID;
$this->view->hasAccessTags = $hasAccessTags;
$this->view->noAccessTags = $noAccessTags;
$this->display();
}
}
+74
View File
@@ -0,0 +1,74 @@
/* Update other picker on change */
$.zui.Picker.DEFAULTS.onChange = function(event)
{
var picker = event.picker;
if(!picker.$formItem.is('[name^=branches]')) return;
var select = picker.$formItem[0];
var newItem = event.value.length ? $.extend({}, picker.getListItem(event.value), {disabled: true}) : $.extend({}, picker.getListItem(event.oldValue), {disabled: false});
$('.user-picker[name^=branches]').each(function()
{
if(this === select) return;
var $select = $(this);
var selectPicker = $select.data('zui.picker');
if(selectPicker) selectPicker.updateOptionList([$.extend({}, newItem)]);
});
}
/**
* Save branch priv.
*
* @access public
* @return void
*/
function savePriv()
{
$('#saveBtn').addClass('hidden');
$('#submit').removeClass('hidden');
$('#submit').click();
}
/**
* Add item.
*
* @param object $obj
* @access public
* @return void
*/
function addItem(obj)
{
var item = $('#addItem').html().replace(/%i%/g, itemIndex);
var $tr = $('<tr class="addedItem">' + item + '</tr>').insertAfter($(obj).closest('tr'));
var $branches = $tr.find('select').addClass('user-picker').trigger('list:updated').picker({type: 'user'});
itemIndex++;
var disabledItems = [];
$('.user-picker[name^=branches]').each(function()
{
if(this === $branches[0]) return;
var $select = $(this);
var picker = $select.data('zui.picker');
if(!picker) return;
var selectItem = picker.getListItem(picker.getValue());
if(selectItem) disabledItems.push($.extend({}, selectItem, {disabled: true}));
});
if(disabledItems.length) $branches.data('zui.picker').updateOptionList(disabledItems);
}
/**
* Delete item.
*
* @param object $obj
* @access public
* @return void
*/
function deleteItem(obj)
{
if($('#privForm .table tbody').children().length < 2) return false;
$(obj).closest('tr').find('.picker .picker-selection-remove').click();
$(obj).closest('tr').remove();
}
+74
View File
@@ -0,0 +1,74 @@
/* Update other picker on change */
$.zui.Picker.DEFAULTS.onChange = function(event)
{
var picker = event.picker;
if(!picker.$formItem.is('[name^=tags]')) return;
var select = picker.$formItem[0];
var newItem = event.value.length ? $.extend({}, picker.getListItem(event.value), {disabled: true}) : $.extend({}, picker.getListItem(event.oldValue), {disabled: false});
$('.user-picker[name^=tags]').each(function()
{
if(this === select) return;
var $select = $(this);
var selectPicker = $select.data('zui.picker');
if(selectPicker) selectPicker.updateOptionList([$.extend({}, newItem)]);
});
}
/**
* Save tag priv.
*
* @access public
* @return void
*/
function savePriv()
{
$('#saveBtn').addClass('hidden');
$('#submit').removeClass('hidden');
$('#submit').click();
}
/**
* Add item.
*
* @param object $obj
* @access public
* @return void
*/
function addItem(obj)
{
var item = $('#addItem').html().replace(/%i%/g, itemIndex);
var $tr = $('<tr class="addedItem">' + item + '</tr>').insertAfter($(obj).closest('tr'));
var $tags = $tr.find('select').addClass('user-picker').trigger('list:updated').picker({type: 'user'});
itemIndex++;
var disabledItems = [];
$('.user-picker[name^=tags]').each(function()
{
if(this === $tags[0]) return;
var $select = $(this);
var picker = $select.data('zui.picker');
if(!picker) return;
var selectItem = picker.getListItem(picker.getValue());
if(selectItem) disabledItems.push($.extend({}, selectItem, {disabled: true}));
});
if(disabledItems.length) $tags.data('zui.picker').updateOptionList(disabledItems);
}
/**
* Delete item.
*
* @param object $obj
* @access public
* @return void
*/
function deleteItem(obj)
{
if($('#privForm .table tbody').children().length < 2) return false;
$(obj).closest('tr').find('.picker .picker-selection-remove').click();
$(obj).closest('tr').remove();
}
+2 -7
View File
@@ -34,7 +34,7 @@ $lang->gitlab->browseUser = "User";
$lang->gitlab->browseGroup = "Group";
$lang->gitlab->browseBranch = "GitLab Branch List";
$lang->gitlab->browseTag = "GitLab Tag List";
$lang->gitlab->browseTagPriv = "GitLab Tag protected List";
$lang->gitlab->browseTagPriv = "Protected tag";
$lang->gitlab->gitlabIssue = "GitLab Issue";
$lang->gitlab->zentaoProduct = 'Zentao Product';
$lang->gitlab->objectType = 'Type'; // task, bug, story
@@ -52,14 +52,9 @@ $lang->gitlab->createBranch = 'Add branch';
$lang->gitlab->manageGroupMembers = 'Manage group member';
$lang->gitlab->createWebhook = 'Create Webhook';
$lang->gitlab->browseBranchPriv = 'Protect branch';
$lang->gitlab->createBranchPriv = 'Cerate branch protected';
$lang->gitlab->editBranchPriv = 'Edit branch protected';
$lang->gitlab->deleteBranchPriv = 'Delete branch protected';
$lang->gitlab->createTag = 'Create Tag';
$lang->gitlab->deleteTag = 'Delete tag';
$lang->gitlab->createTagPriv = 'Create tag protected';
$lang->gitlab->editTagPriv = 'Edit tag protected';
$lang->gitlab->deleteTagPriv = 'Delete tag protected';
$lang->gitlab->svaeFailed = '『%s』save failed';
$lang->gitlab->id = 'ID';
$lang->gitlab->name = "Server Name";
+2 -7
View File
@@ -34,7 +34,7 @@ $lang->gitlab->browseUser = "User";
$lang->gitlab->browseGroup = "Group";
$lang->gitlab->browseBranch = "GitLab Branch List";
$lang->gitlab->browseTag = "GitLab Tag List";
$lang->gitlab->browseTagPriv = "GitLab Tag protected List";
$lang->gitlab->browseTagPriv = "Protected tag";
$lang->gitlab->gitlabIssue = "GitLab Issue";
$lang->gitlab->zentaoProduct = 'Zentao Product';
$lang->gitlab->objectType = 'Type'; // task, bug, story
@@ -52,14 +52,9 @@ $lang->gitlab->createBranch = 'Add branch';
$lang->gitlab->manageGroupMembers = 'Manage group member';
$lang->gitlab->createWebhook = 'Create Webhook';
$lang->gitlab->browseBranchPriv = 'Protect branch';
$lang->gitlab->createBranchPriv = 'Cerate branch protected';
$lang->gitlab->editBranchPriv = 'Edit branch protected';
$lang->gitlab->deleteBranchPriv = 'Delete branch protected';
$lang->gitlab->createTag = 'Create Tag';
$lang->gitlab->deleteTag = 'Delete tag';
$lang->gitlab->createTagPriv = 'Create tag protected';
$lang->gitlab->editTagPriv = 'Edit tag protected';
$lang->gitlab->deleteTagPriv = 'Delete tag protected';
$lang->gitlab->svaeFailed = '『%s』save failed';
$lang->gitlab->id = 'ID';
$lang->gitlab->name = "Server Name";
+2 -7
View File
@@ -34,7 +34,7 @@ $lang->gitlab->browseUser = "User";
$lang->gitlab->browseGroup = "Group";
$lang->gitlab->browseBranch = "GitLab Branch List";
$lang->gitlab->browseTag = "GitLab Tag List";
$lang->gitlab->browseTagPriv = "GitLab Tag protected List";
$lang->gitlab->browseTagPriv = "Protected tag";
$lang->gitlab->gitlabIssue = "GitLab Issue";
$lang->gitlab->zentaoProduct = 'Zentao Product';
$lang->gitlab->objectType = 'Type'; // task, bug, story
@@ -52,14 +52,9 @@ $lang->gitlab->createBranch = 'Add branch';
$lang->gitlab->manageGroupMembers = 'Manage group member';
$lang->gitlab->createWebhook = 'Create Webhook';
$lang->gitlab->browseBranchPriv = 'Protect branch';
$lang->gitlab->createBranchPriv = 'Cerate branch protected';
$lang->gitlab->editBranchPriv = 'Edit branch protected';
$lang->gitlab->deleteBranchPriv = 'Delete branch protected';
$lang->gitlab->createTag = 'Create Tag';
$lang->gitlab->deleteTag = 'Delete tag';
$lang->gitlab->createTagPriv = 'Create tag protected';
$lang->gitlab->editTagPriv = 'Edit tag protected';
$lang->gitlab->deleteTagPriv = 'Delete tag protected';
$lang->gitlab->svaeFailed = '『%s』save failed';
$lang->gitlab->id = 'ID';
$lang->gitlab->name = "Server Name";
+2 -7
View File
@@ -34,7 +34,7 @@ $lang->gitlab->browseUser = "User";
$lang->gitlab->browseGroup = "Group";
$lang->gitlab->browseBranch = "GitLab Branch List";
$lang->gitlab->browseTag = "GitLab Tag List";
$lang->gitlab->browseTagPriv = "GitLab Tag protected List";
$lang->gitlab->browseTagPriv = "Protected tag";
$lang->gitlab->gitlabIssue = "GitLab Issue";
$lang->gitlab->zentaoProduct = 'Zentao Product';
$lang->gitlab->objectType = 'Type'; // task, bug, story
@@ -52,14 +52,9 @@ $lang->gitlab->createBranch = 'Add branch';
$lang->gitlab->manageGroupMembers = 'Manage group member';
$lang->gitlab->createWebhook = 'Create Webhook';
$lang->gitlab->browseBranchPriv = 'Protect branch';
$lang->gitlab->createBranchPriv = 'Cerate branch protected';
$lang->gitlab->editBranchPriv = 'Edit branch protected';
$lang->gitlab->deleteBranchPriv = 'Delete branch protected';
$lang->gitlab->createTag = 'Create Tag';
$lang->gitlab->deleteTag = 'Delete tag';
$lang->gitlab->createTagPriv = 'Create tag protected';
$lang->gitlab->editTagPriv = 'Edit tag protected';
$lang->gitlab->deleteTagPriv = 'Delete tag protected';
$lang->gitlab->svaeFailed = '『%s』save failed';
$lang->gitlab->id = 'ID';
$lang->gitlab->name = "Server Name";
+2 -7
View File
@@ -34,7 +34,7 @@ $lang->gitlab->browseUser = "用户";
$lang->gitlab->browseGroup = "群组";
$lang->gitlab->browseBranch = "GitLab分支列表";
$lang->gitlab->browseTag = "GitLab标签列表";
$lang->gitlab->browseTagPriv = "GitLab标签保护列表";
$lang->gitlab->browseTagPriv = "标签保护管理";
$lang->gitlab->gitlabIssue = "{$lang->gitlab->common} issue";
$lang->gitlab->zentaoProduct = '禅道产品';
$lang->gitlab->objectType = '类型'; // task, bug, story
@@ -52,14 +52,9 @@ $lang->gitlab->createBranch = '添加分支';
$lang->gitlab->manageGroupMembers = '群组成员管理';
$lang->gitlab->createWebhook = '创建Webhook';
$lang->gitlab->browseBranchPriv = '分支保护管理';
$lang->gitlab->createBranchPriv = '创建分支保护';
$lang->gitlab->editBranchPriv = '编辑分支保护';
$lang->gitlab->deleteBranchPriv = '删除分支保护';
$lang->gitlab->createTag = '创建标签';
$lang->gitlab->deleteTag = '删除标签';
$lang->gitlab->createTagPriv = '创建标签保护';
$lang->gitlab->editTagPriv = '编辑标签保护';
$lang->gitlab->deleteTagPriv = '删除标签保护';
$lang->gitlab->svaeFailed = '『%s』保存失败';
$lang->gitlab->id = 'ID';
$lang->gitlab->name = "服务器名称";
+65 -104
View File
@@ -1203,7 +1203,7 @@ class gitlabModel extends model
/* Return an empty array if where is one existing webhook. */
if($this->isWebhookExists($repo, $hook->url)) return array();
$result = $this->apiCreateHook($repo->gitlab, $repo->project, $hook);
$result = $this->apiCreateHook($repo->gitService, $repo->project, $hook);
if(!empty($result->id)) return true;
return false;
@@ -1218,7 +1218,7 @@ class gitlabModel extends model
*/
public function isWebhookExists($repo, $url = '')
{
$hookList = $this->apiGetHooks($repo->gitlab, $repo->project);
$hookList = $this->apiGetHooks($repo->gitService, $repo->project);
foreach($hookList as $hook)
{
if($hook->url == $url) return true;
@@ -2549,59 +2549,49 @@ class gitlabModel extends model
}
/**
* Get single protct branch by API.
* Manage branch privs.
*
* @param int $gitlabID
* @param int $projectID
* @param string $branch
* @param array $protected
* @access public
* @return object
* @return array
*/
public function apiGetSingleBranchPriv($gitlabID, $projectID, $branch)
public function manageBranchPrivs($gitlabID, $projectID, $protected = array())
{
if(empty($gitlabID)) return false;
$branch = urlencode($branch);
$url = sprintf($this->getApiRoot($gitlabID), "/projects/$projectID/protected_branches/$branch");
return json_decode(commonModel::http($url));
}
$data = (array)fixer::input('post')->get();
extract($data);
$failure = array();
/**
* Create gitlab potect branch.
*
* @param int $gitlabID
* @param int $projectID
* @param string $branch
* @access public
* @return bool
*/
public function createBranchPriv($gitlabID, $projectID, $branch = '')
{
$priv = fixer::input('post')->get();
if(empty($priv->name))
/* Remove privs. */
foreach($protected as $name => $branch)
{
dao::$errors['name'][] = $this->lang->gitlab->branch->emptyPrivNameError;
return false;
if(!in_array($name, $branches))
{
$result = $this->apiDeleteBranchPriv($gitlabID, $projectID, $name);
if($result and substr($result->message, 0, 2) != '20') $failure[] = $name;
}
}
$priv->name = urldecode(helper::safe64Decode($priv->name));
$singleBranch = $this->apiGetSingleBranchPriv($gitlabID, $projectID, $priv->name);
if(empty($branch) && !empty($singleBranch->id))
$priv = new stdClass();
foreach($branches as $key => $name)
{
dao::$errors['name'][] = $this->lang->gitlab->branch->issetPrivNameError;
return false;
/* Process exists data. */
if(isset($protected[$name]))
{
if($protected[$name]->pushAccess == $pushLevels[$key] and $protected[$name]->mergeAccess == $mergeLevels[$key]) continue;
$result = $this->apiDeleteBranchPriv($gitlabID, $projectID, $name);
if(isset($result->message) and substr($result->message, 0, 2) != '20') $failure[] = $name;
}
$priv->name = $name;
$priv->push_access_level = $pushLevels[$key];
$priv->merge_access_level = $mergeLevels[$key];
$response = $this->apiCreateBranchPriv($gitlabID, $projectID, $priv);
if(isset($response->message) and substr($response->message, 0, 2) != '20') $failure[] = $name;
}
if(!empty($branch) && !empty($singleBranch->id)) $this->apiDeleteBranchPriv($gitlabID, $projectID, $branch);
$response = $this->apiCreateBranchPriv($gitlabID, $projectID, $priv);
if(!empty($response->id))
{
$action = empty($branch) ? 'created' : 'edited';
$this->loadModel('action')->create('gitlabbranchpriv', $response->id, $action, '', $response->name);
return true;
}
return $this->apiErrorHandling($response);
return array_unique($failure);
}
/**
@@ -2630,7 +2620,7 @@ class gitlabModel extends model
* @param int $projectID
* @param string $branch
* @access public
* @return object
* @return array
*/
public function apiDeleteBranchPriv($gitlabID, $projectID, $branch)
{
@@ -2642,58 +2632,48 @@ class gitlabModel extends model
}
/**
* Create gitlab protect tag.
* Manage tag privs.
*
* @param int $gitlabID
* @param int $projectID
* @param string $tag
* @param array $protected
* @access public
* @return bool
* @return array
*/
public function createTagPriv($gitlabID, $projectID, $tag = '')
public function manageTagPrivs($gitlabID, $projectID, $protected = array())
{
$priv = fixer::input('post')->get();
if(empty($priv->name))
$data = (array)fixer::input('post')->get();
extract($data);
$failure = array();
/* Remove privs. */
foreach($protected as $name => $tag)
{
dao::$errors['name'][] = $this->lang->gitlab->tag->emptyPrivNameError;
return false;
if(!in_array($name, $tags))
{
$result = $this->apiDeleteTagPriv($gitlabID, $projectID, $name);
if($result and substr($result->message, 0, 2) != '20') $failure[] = $name;
}
}
$singleTag = $this->apiGetSingleTagPriv($gitlabID, $projectID, $priv->name);
if(empty($tag) && !empty($singleTag->id))
$priv = new stdClass();
foreach($tags as $key => $name)
{
dao::$errors['name'][] = $this->lang->gitlab->tag->issetPrivNameError;
return false;
/* Process exists data. */
if(isset($protected[$name]))
{
if($protected[$name]->createAccess == $createLevels[$key]) continue;
$result = $this->apiDeleteTagPriv($gitlabID, $projectID, $name);
if(isset($result->message) and substr($result->message, 0, 2) != '20') $failure[] = $name;
}
$priv->name = $name;
$priv->create_access_level = $createLevels[$key];
$response = $this->apiCreateTagPriv($gitlabID, $projectID, $priv);
if(isset($response->message) and substr($response->message, 0, 2) != '20') $failure[] = $name;
}
if(!empty($tag) && !empty($singleTag->name)) $this->apiDeleteTagPriv($gitlabID, $projectID, $tag);
$response = $this->apiCreateTagPriv($gitlabID, $projectID, $priv);
if(!empty($response->id))
{
$action = empty($tag) ? 'created' : 'edited';
$this->loadModel('action')->create('gitlabtagpriv', $response->id, $action, '', $response->name);
return true;
}
return $this->apiErrorHandling($response);
}
/**
* Get single protct tag by API.
*
* @param int $gitlabID
* @param int $projectID
* @param string $tag
* @access public
* @return object
*/
public function apiGetSingleTagPriv($gitlabID, $projectID, $tag)
{
if(empty($gitlabID)) return false;
$tag = urlencode($tag);
$url = sprintf($this->getApiRoot($gitlabID), "/projects/$projectID/protected_tags/$tag");
return json_decode(commonModel::http($url));
return array_unique($failure);
}
/**
@@ -2896,23 +2876,4 @@ class gitlabModel extends model
$html .= '</div>';
return $html;
}
/**
* Download zip code.
*
* @param int $gitlabID
* @param int $projectID
* @param string $branch
* @param string $ext tar.gz|tar.bz2|tbz|tbz2|tb2|bz2|tar|zip
* @access public
* @return string
*/
public function downloadCode($gitlabID = 0, $projectID = 0, $branch = '', $ext = 'zip')
{
if(empty($gitlabID) or empty($projectID)) return false;
$url = sprintf($this->getApiRoot($gitlabID), "/projects/$projectID/repository/archive." . $ext);
if($branch) $url .= '&sha=' . $branch;
return $url;
}
}
+2 -2
View File
@@ -43,7 +43,7 @@
</thead>
<tbody>
<?php foreach ($gitlabList as $id => $gitlab): ?>
<tr class='text' title='<?php if(!$gitlab->isAdminToken) echo $lang->gitlab->tokenLimit;?>'>
<tr class='text'>
<td class='text-center'><?php echo $id;?></td>
<td class='text-c-name' title='<?php echo $gitlab->name;?>'>
<?php if(common::hasPriv('gitlab', 'browseProject')):?>
@@ -55,7 +55,7 @@
<td class='text' title='<?php echo $gitlab->url;?>'><?php echo html::a($gitlab->url, $gitlab->url, '_target');?></td>
<td class='c-actions text-left'>
<?php
$disabled = (empty($gitlab->isAdminToken) or !$gitlab->isBindUser) ? false : true;
$disabled = $gitlab->isBindUser ? true : false;
common::printIcon('gitlab', 'edit', "gitlabID=$id", '', 'list', 'edit');
echo common::buildIconButton('gitlab', 'bindUser', "gitlabID=$id", '', 'list', 'link', '', '', false, '', '', 0, $disabled);
common::printIcon('gitlab', 'delete', "gitlabID=$id", '', 'list', 'trash', 'hiddenwin');
@@ -1,81 +0,0 @@
<?php
/**
* The browse view file of gitlab protext branch of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Yanyi Cao <caoyanyi@easycorp.ltd>
* @package gitlab
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div id="mainMenu" class="clearfix">
<div class='pull-left'>
<?php echo html::a($this->createLink('gitlab', 'browseProject', "gitlabID=$gitlabID"), "<i class='icon icon-back icon-sm'></i> " . $lang->goback, '', "class='btn btn-secondary'");?>
</div>
<div id="sidebarHeader">
<div class="title" title="<?php echo $project->name_with_namespace; ?>"><?php echo $project->name_with_namespace; ?></div>
</div>
<div class="btn-toolbar pull-left">
<div>
<form id='branchPrivForm' method='post'>
<?php echo html::input('keyword', $keyword, "class='form-control' placeholder='{$lang->gitlab->branch->placeholderSearch}' style='display: inline-block;width:auto;margin:0 10px'");?>
<a id="branchSearch" class="btn btn-primary"><?php echo $lang->gitlab->search?></a>
</form>
</div>
</div>
<div class="btn-toolbar pull-right">
<?php if(common::hasPriv('gitlab', 'createBranchPriv')) common::printLink('gitlab', 'createBranchPriv', "gitlabID=$gitlabID&projectID=$projectID", "<i class='icon icon-plus'></i> " . $lang->gitlab->createBranchPriv, '', "class='btn btn-primary'");?>
</div>
</div>
<?php if(empty($branchList)):?>
<div class="table-empty-tip">
<p>
<span class="text-muted"><?php echo $lang->noData;?></span>
<?php if(empty($keyword) and common::hasPriv('gitlab', 'createBranchPriv')):?>
<?php echo html::a($this->createLink('gitlab', 'createBranchPriv', "gitlabID=$gitlabID&projectID=$projectID"), "<i class='icon icon-plus'></i> " . $lang->gitlab->createBranchPriv, '', "class='btn btn-info'");?>
<?php endif;?>
</p>
</div>
<?php else:?>
<div id='mainContent' class='main-row'>
<form class='main-table' id='ajaxForm' method='post'>
<table id='branchList' class='table has-sort-head table-fixed'>
<?php $vars = "gitlabID={$gitlabID}&projectID={$projectID}&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<thead>
<tr>
<th class='c-name text-left'><?php common::printOrderLink('name', $orderBy, $vars, $lang->gitlab->branch->name);?></th>
<th class='text-left'><?php echo $lang->gitlab->branch->mergeAllowed;?></th>
<th class='text-left'><?php echo $lang->gitlab->branch->pushAllowed;?></th>
<th class='c-actions-4'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
<?php foreach ($branchList as $id => $branch): ?>
<?php $branch->merge_access_level = $this->gitlab->checkAccessLevel($branch->merge_access_levels); ?>
<?php $branch->push_access_level = $this->gitlab->checkAccessLevel($branch->push_access_levels); ?>
<tr class='text'>
<td class='text-c-name' title='<?php echo $branch->name;?>'><?php echo $branch->name;?></td>
<td class-'text' title="<?php echo $levelLang[$branch->merge_access_level];?>"><?php echo $levelLang[$branch->merge_access_level];?></td>
<td class='text' title="<?php echo $levelLang[$branch->push_access_level];?>"><?php echo $levelLang[$branch->push_access_level];?></td>
<td class='c-actions text-left'>
<?php
/* Fix error when request type is PATH_INFO and the branch name contains '-'.*/
$branchName = helper::safe64Encode(urlencode($branch->name));
if(common::hasPriv('gitlab', 'editBranchPriv')) common::printLink('gitlab', 'editBranchPriv', "gitlabID=$gitlabID&projectID=$projectID&branch=$branchName", "<i class='icon icon-edit'></i> ", '', "title={$lang->gitlab->editBranchPriv} class='btn btn-primary'");
if(common::hasPriv('gitlab', 'deleteBranchPriv')) echo html::a($this->createLink('gitlab', 'deleteBranchPriv', "gitlabID=$gitlabID&projectID=$projectID&branch=$branchName"), '<i class="icon-trash"></i>', 'hiddenwin', "title='{$lang->gitlab->deleteBranchPriv}' class='btn'");
?>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<?php if($branchList):?>
<div class='table-footer'><?php $pager->show('right', 'pagerjs');?></div>
<?php endif;?>
</form>
</div>
<?php endif;?>
<?php include '../../common/view/footer.html.php';?>
+2 -2
View File
@@ -60,8 +60,8 @@
<td class='text' title='<?php echo substr($gitlabProject->last_activity_at, 0, 10);?>'><?php echo substr($gitlabProject->last_activity_at, 0, 10);?></td>
<td class='c-actions text-left'>
<?php
echo common::buildIconButton('gitlab', 'browseBranchPriv', "gitlabID=$gitlabID&projectID=$gitlabProject->id", '', 'list', 'branch-lock', '', '', false, '', '', 0, ($gitlabProject->isMaintainer and $gitlabProject->default_branch));
echo common::buildIconButton('gitlab', 'browseTagPriv', "gitlabID=$gitlabID&projectID=$gitlabProject->id", '', 'list', 'tag-lock', '', '', false, '', '', 0, ($gitlabProject->isMaintainer and $gitlabProject->default_branch));
echo common::buildIconButton('gitlab', 'manageBranchPriv', "gitlabID=$gitlabID&projectID=$gitlabProject->id", '', 'list', 'branch-lock', '', '', false, '', $this->lang->gitlab->browseBranchPriv, 0, ($gitlabProject->isMaintainer and $gitlabProject->default_branch));
echo common::buildIconButton('gitlab', 'manageTagPriv', "gitlabID=$gitlabID&projectID=$gitlabProject->id", '', 'list', 'tag-lock', '', '', false, '', $this->lang->gitlab->browseTagPriv, 0, ($gitlabProject->isMaintainer and $gitlabProject->default_branch));
echo common::buildIconButton('gitlab', 'manageProjectMembers', 'repoID=' . zget($repoPairs, $gitlabProject->id), '', 'list', 'team', '', '', false, '', '', 0, isset($repoPairs[$gitlabProject->id]));
echo common::buildIconButton('gitlab', 'createWebhook', 'repoID=' . zget($repoPairs, $gitlabProject->id), '', 'list', 'change', 'hiddenwin', '', false, '', '', 0, isset($repoPairs[$gitlabProject->id]));
echo common::buildIconButton('gitlab', 'importIssue', 'repoID=' . zget($repoPairs, $gitlabProject->id), '', 'list', 'link', '', '', false, '', '', 0, isset($repoPairs[$gitlabProject->id]));
-82
View File
@@ -1,82 +0,0 @@
<?php
/**
* The browse view file of gitlab module of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Gang Zeng <zenggang@easycorp.ltd>
* @package gitlab
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('vars', "keyword=%s&orderBy=id_desc&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID=1")?>
<?php js::set('gitlabID', $gitlabID)?>
<div id="mainMenu" class="clearfix">
<div class='pull-left'>
<?php echo html::linkButton('<i class="icon icon-back icon-sm"></i> ' . $lang->goback, $this->createLink('gitlab', 'browseProject', "gitlabID=$gitlabID"), 'self', '','btn btn-secondary');?>
</div>
<div id="sidebarHeader">
<div class="title" title="<?php echo $project->name_with_namespace; ?>"><?php echo $project->name_with_namespace; ?></div>
</div>
<div class="btn-toolbar pull-left">
<div>
<form id='tagForm' method='post'>
<?php echo html::input('keyword', $keyword, "class='form-control' placeholder='{$lang->gitlab->tag->placeholderSearch}' style='display: inline-block;width:auto;margin:0 10px'");?>
<a id="tagSearch" class="btn btn-primary"><?php echo $lang->gitlab->search?></a>
</form>
</div>
</div>
<div class="btn-toolbar pull-right">
<?php common::printLink('gitlab', 'createTagPriv', "gitlabID=$gitlabID&projectID=$projectID", "<i class='icon icon-plus'></i> " . $lang->gitlab->createTagPriv, '', "class='btn btn-primary'");?>
</div>
</div>
<?php if(empty($gitlabTagList)):?>
<div class="table-empty-tip">
<p>
<span class="text-muted"><?php echo $lang->noData;?></span>
<?php if(empty($keyword) and common::hasPriv('gitlab', 'createTag')):?>
<?php echo html::a($this->createLink('gitlab', 'createTagPriv', "gitlabID=$gitlabID&projectID=$projectID"), "<i class='icon icon-plus'></i> " . $lang->gitlab->createTagPriv, '', "class='btn btn-info'");?>
<?php endif;?>
</p>
</div>
<?php else:?>
<div id='mainContent' class='main-row'>
<form class='main-table' id='ajaxForm' method='post'>
<table id='gitlabTagList' class='table has-sort-head table-fixed'>
<?php $vars = "gitlabID={$gitlabID}&projectID={$projectID}&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<thead>
<tr>
<th class='c-name text-left'><?php common::printOrderLink('name', $orderBy, $vars, $lang->gitlab->tag->name);?></th>
<th class='text-left'><?php echo $lang->gitlab->tag->lastCommitter;?></th>
<th class='text-left'><?php common::printOrderLink('accessLevels', $orderBy, $vars, $lang->gitlab->tag->accessLevel);?></th>
<th class='c-actions-2'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
<?php foreach ($gitlabTagList as $id => $gitlabTag): ?>
<?php $gitlabTag->accessLevel = $this->gitlab->checkAccessLevel($gitlabTag->accessLevels); ?>
<tr class='text'>
<td class='text-c-name' title='<?php echo $gitlabTag->name;?>'><?php echo $gitlabTag->name;?></td>
<td class='text'><?php echo $gitlabTag->lastCommitter;?></td>
<td class='text'><?php echo zget($lang->gitlab->branch->branchCreationLevelList, $gitlabTag->accessLevel);?></td>
<td class='c-actions text-left'>
<?php
/* Fix error when request type is PATH_INFO and the tag name contains '-'.*/
$tagName = helper::safe64Encode(urlencode($gitlabTag->name));
common::printLink('gitlab', 'editTagPriv', "gitlabID=$gitlabID&projectID=$projectID&tag_name=$tagName", "<i class='icon icon-edit'></i> ", '', "title={$lang->gitlab->editTagPriv} class='btn btn-primary'");
common::printLink('gitlab', 'deleteTagPriv', "gitlabID=$gitlabID&projectID={$projectID}&tag_name=$tagName", "<i class='icon icon-trash'></i> ", '', "title='{$lang->gitlab->deleteTagPriv}' class='btn btn-primary' target='hiddenwin' onclick='if(confirm(\"{$lang->gitlab->tag->protectConfirmDel}\")==false) return false;'");
?>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<?php if($gitlabTagList):?>
<div class='table-footer'><?php $pager->show('right', 'pagerjs');?></div>
<?php endif;?>
</form>
</div>
<?php endif;?>
<?php include '../../common/view/footer.html.php';?>
@@ -1,47 +0,0 @@
<?php
/**
* The create view file of protext branch of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Yanyi Cao <caoyanyi@easycorp.ltd>
* @package gitlab
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div id='mainContent' class='main-row'>
<div class='main-col main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $pageTitle;?></h2>
</div>
<form id='branchForm' method='post' class='form-ajax' enctype="multipart/form-data">
<?php if($branchPriv->name) echo html::hidden('name', $branchPriv->name);?>
<table class='table table-form'>
<tr>
<th><?php echo $lang->gitlab->branch->name;?></th>
<td><?php echo html::select('name', $branches, $branchPriv->name, "class='form-control chosen' " . ($branch ? 'disabled' : ''));?></td>
</tr>
<tr>
<th><?php echo $lang->gitlab->branch->mergeAllowed;?></th>
<td><?php echo html::select('merge_access_level', $lang->gitlab->branch->branchCreationLevelList, $branchPriv->mergeAccessLevel, "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->gitlab->branch->pushAllowed;?></th>
<td><?php echo html::select('push_access_level', $lang->gitlab->branch->branchCreationLevelList, $branchPriv->pushAccessLevel, "class='form-control'");?></td>
</tr>
<tr>
<th></th>
<td class='text-center form-actions'>
<?php echo html::submitButton();?>
<?php if(!isonlybody()) echo html::a(inlink('browseBranchPriv', "gitlabID=$gitlabID&projectID=$projectID"), $lang->goback, '', 'class="btn btn-wide"');?>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
-43
View File
@@ -1,43 +0,0 @@
<?php
/**
* The create view file of protect tag of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Yuchun Li <liyuchun@easycorp.ltd>
* @package gitlab
* @version $Id$
* @link https://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div id='mainContent' class='main-row'>
<div class='main-col main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->gitlab->createTagPriv;?></h2>
</div>
<form id='branchForm' method='post' class='form-ajax' enctype="multipart/form-data">
<table class='table table-form'>
<tr>
<th class='w-110px'><?php echo $lang->gitlab->tag->name;?></th>
<td><?php echo html::select('name', $tags, '', "class='form-control chosen'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->gitlab->tag->accessLevel;?></th>
<td><?php echo html::select('create_access_level', $lang->gitlab->branch->branchCreationLevelList, '40', "class='form-control chosen'");?></td>
</tr>
<tr>
<th></th>
<td class='text-center form-actions'>
<?php echo html::submitButton();?>
<?php if(!isonlybody()) echo html::a(inlink('browseTagPriv', "gitlabID=$gitlabID&projectID=$projectID"), $lang->goback, '', 'class="btn btn-wide"');?>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
-44
View File
@@ -1,44 +0,0 @@
<?php
/**
* The edit view file of protect tag of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Yuchun Li <liyuchun@easycorp.ltd>
* @package gitlab
* @version $Id$
* @link https://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div id='mainContent' class='main-row'>
<div class='main-col main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $lang->gitlab->editTagPriv;?></h2>
</div>
<form id='branchForm' method='post' class='form-ajax' enctype="multipart/form-data">
<table class='table table-form'>
<tr>
<th class='w-110px'><?php echo $lang->gitlab->tag->name;?></th>
<td><?php echo html::input('tagName', $tag, "class='form-control' disabled");?></td>
<td></td>
<?php echo html::hidden('name', $tag);?>
</tr>
<tr>
<th><?php echo $lang->gitlab->tag->accessLevel;?></th>
<td><?php echo html::select('create_access_level', $lang->gitlab->branch->branchCreationLevelList, $tagPriv->createAccessLevel, "class='form-control chosen'");?></td>
</tr>
<tr>
<th></th>
<td class='text-center form-actions'>
<?php echo html::submitButton();?>
<?php if(!isonlybody()) echo html::a(inlink('browseTagPriv', "gitlabID=$gitlabID&projectID=$projectID"), $lang->goback, '', 'class="btn btn-wide"');?>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
@@ -0,0 +1,82 @@
<?php include '../../common/view/header.html.php';?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left'>
<span class='btn btn-link btn-active-text'>
<?php echo html::a('###', "<span class='text'> {$lang->gitlab->browseBranchPriv}</span>");?>
</span>
</div>
</div>
<div id='mainContent' class='main-content'>
<form class='main-form form-ajax' method='post' id='privForm'>
<table class='table table-form'>
<thead>
<tr class='text-center'>
<th class='c-names'><?php echo $lang->gitlab->branch->name;?></th>
<th class='c-levels'><?php echo $lang->gitlab->branch->mergeAllowed;?></th>
<th class='c-levels'><?php echo $lang->gitlab->branch->pushAllowed;?></th>
<th class="c-actions"><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
<?php $i = 0;?>
<?php if(!empty($hasAccessBranches)):?>
<?php foreach($hasAccessBranches as $branch):?>
<tr>
<td><?php echo html::input("names[$i]", $branch->name, "class='form-control' readonly");?></td>
<td><?php echo html::select("mergeLevels[$i]", $lang->gitlab->branch->branchCreationLevelList, $branch->mergeAccess, "class='form-control user-picker'");?></td>
<td>
<?php echo html::select("pushLevels[$i]", $lang->gitlab->branch->branchCreationLevelList, $branch->pushAccess, "class='form-control user-picker'");?>
<?php echo html::hidden("branches[$i]", $branch->name);?>
</td>
<td class='c-actions text-center'>
<?php echo html::a('javascript:;', "<i class='icon-plus'></i>", '', "onclick='addItem(this)' class='btn btn-link'");?>
<?php echo html::a('javascript:;', "<i class='icon icon-close'></i>", '', "onclick='deleteItem(this)' class='btn btn-link'");?>
</td>
</tr>
<?php $i ++;?>
<?php endforeach;?>
<?php endif;?>
<?php for($j = 0; $j < 5; $j ++):?>
<tr class='addedItem'>
<td><?php echo html::select("branches[$i]", array(''=>'') + $noAccessBranches, '', "class='form-control user-picker'");?></td>
<td><?php echo html::select("mergeLevels[$i]", $lang->gitlab->branch->branchCreationLevelList, 40, "class='form-control user-picker'");?></td>
<td><?php echo html::select("pushLevels[$i]", $lang->gitlab->branch->branchCreationLevelList, 40, "class='form-control user-picker'");?></td>
<td class='c-actions text-center'>
<?php echo html::a('javascript:;', "<i class='icon-plus'></i>", '', "onclick='addItem(this)' class='btn btn-link'");?>
<?php echo html::a('javascript:;', "<i class='icon icon-close'></i>", '', "onclick='deleteItem(this)' class='btn btn-link'");?>
</td>
</tr>
<?php $i ++;?>
<?php endfor;?>
</tbody>
<tfoot>
<tr>
<td colspan='4' class='text-center form-actions'>
<?php
echo html::submitButton('', '', 'hidden btn btn-wide btn-primary');
echo html::commonButton($lang->save, 'onclick="savePriv()" id="saveBtn"', 'btn btn-wide btn-primary');
echo html::backButton();
?>
</td>
</tr>
</tfoot>
</table>
<?php js::set('itemIndex', $i);?>
</form>
</div>
<div>
<?php $i = '%i%';?>
<table class='hidden'>
<tr id='addItem' class='hidden'>
<td><?php echo html::select("branches[]", array(''=>'') + $noAccessBranches, '', "class='form-control'");?></td>
<td><?php echo html::select("mergeLevels[]", $lang->gitlab->branch->branchCreationLevelList, 40, "class='form-control'");?></td>
<td><?php echo html::select("pushLevels[]", $lang->gitlab->branch->branchCreationLevelList, 40, "class='form-control'");?></td>
<td class='c-actions text-center'>
<?php echo html::a('javascript:;', "<i class='icon-plus'></i>", '', "onclick='addItem(this)' class='btn btn-link'");?>
<?php echo html::a('javascript:;', "<i class='icon icon-close'></i>", '', "onclick='deleteItem(this)' class='btn btn-link'");?>
</td>
</tr>
</table>
</div>
<?php include '../../common/view/footer.html.php';?>
+76
View File
@@ -0,0 +1,76 @@
<?php include '../../common/view/header.html.php';?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left'>
<span class='btn btn-link btn-active-text'>
<?php echo html::a('###', "<span class='text'> {$lang->gitlab->browseTagPriv}</span>");?>
</span>
</div>
</div>
<div id='mainContent' class='main-content'>
<form class='main-form form-ajax' method='post' id='privForm'>
<table class='table table-form'>
<thead>
<tr class='text-center'>
<th class='c-names'><?php echo $lang->gitlab->tag->name;?></th>
<th class='c-levels'><?php echo $lang->gitlab->tag->accessLevel;?></th>
<th class="c-actions"><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
<?php $i = 0;?>
<?php if(!empty($hasAccessTags)):?>
<?php foreach($hasAccessTags as $tag):?>
<tr>
<td><?php echo html::input("names[$i]", $tag->name, "class='form-control' readonly");?></td>
<td><?php echo html::select("createLevels[$i]", $lang->gitlab->branch->branchCreationLevelList, $tag->createAccess, "class='form-control user-picker'");?></td>
<td class='c-actions text-center'>
<?php echo html::hidden("tags[$i]", $tag->name);?>
<?php echo html::a('javascript:;', "<i class='icon-plus'></i>", '', "onclick='addItem(this)' class='btn btn-link'");?>
<?php echo html::a('javascript:;', "<i class='icon icon-close'></i>", '', "onclick='deleteItem(this)' class='btn btn-link'");?>
</td>
</tr>
<?php $i ++;?>
<?php endforeach;?>
<?php endif;?>
<?php for($j = 0; $j < 5; $j ++):?>
<tr class='addedItem'>
<td><?php echo html::select("tags[$i]", array(''=>'') + $noAccessTags, '', "class='form-control user-picker'");?></td>
<td><?php echo html::select("createLevels[$i]", $lang->gitlab->branch->branchCreationLevelList, 40, "class='form-control user-picker'");?></td>
<td class='c-actions text-center'>
<?php echo html::a('javascript:;', "<i class='icon-plus'></i>", '', "onclick='addItem(this)' class='btn btn-link'");?>
<?php echo html::a('javascript:;', "<i class='icon icon-close'></i>", '', "onclick='deleteItem(this)' class='btn btn-link'");?>
</td>
</tr>
<?php $i ++;?>
<?php endfor;?>
</tbody>
<tfoot>
<tr>
<td colspan='4' class='text-center form-actions'>
<?php
echo html::submitButton('', '', 'hidden btn btn-wide btn-primary');
echo html::commonButton($lang->save, 'onclick="savePriv()" id="saveBtn"', 'btn btn-wide btn-primary');
echo html::backButton();
?>
</td>
</tr>
</tfoot>
</table>
<?php js::set('itemIndex', $i);?>
</form>
</div>
<div>
<?php $i = '%i%';?>
<table class='hidden'>
<tr id='addItem' class='hidden'>
<td><?php echo html::select("tags[]", array(''=>'') + $noAccessTags, '', "class='form-control'");?></td>
<td><?php echo html::select("createLevels[]", $lang->gitlab->branch->branchCreationLevelList, 40, "class='form-control'");?></td>
<td class='c-actions text-center'>
<?php echo html::a('javascript:;', "<i class='icon-plus'></i>", '', "onclick='addItem(this)' class='btn btn-link'");?>
<?php echo html::a('javascript:;', "<i class='icon icon-close'></i>", '', "onclick='deleteItem(this)' class='btn btn-link'");?>
</td>
</tr>
</table>
</div>
<?php include '../../common/view/footer.html.php';?>
+17 -16
View File
@@ -1284,6 +1284,7 @@ $lang->resource->custom->browseStoryConcept = 'browseStoryConcept';
$lang->resource->custom->setDefaultConcept = 'setDefaultConcept';
$lang->resource->custom->deleteStoryConcept = 'deleteStoryConcept';
$lang->resource->custom->kanban = 'kanban';
$lang->resource->custom->code = 'code';
$lang->custom->methodOrder[5] = 'index';
$lang->custom->methodOrder[10] = 'set';
@@ -1300,6 +1301,8 @@ $lang->custom->methodOrder[60] = 'editStoryConcept';
$lang->custom->methodOrder[65] = 'browseStoryConcept';
$lang->custom->methodOrder[70] = 'setDefaultConcept';
$lang->custom->methodOrder[75] = 'deleteStoryConcept';
$lang->custom->methodOrder[80] = 'kanban';
$lang->custom->methodOrder[85] = 'code';
$lang->resource->datatable = new stdclass();
$lang->resource->datatable->setGlobal = 'setGlobal';
@@ -1344,17 +1347,11 @@ $lang->resource->gitlab->browseBranch = 'browseBranch';
$lang->resource->gitlab->webhook = 'webhook';
$lang->resource->gitlab->createWebhook = 'createWebhook';
$lang->resource->gitlab->manageProjectMembers = 'manageProjectMembers';
$lang->resource->gitlab->browseBranchPriv = 'browseBranchPriv';
$lang->resource->gitlab->createBranchPriv = 'createBranchPriv';
$lang->resource->gitlab->editBranchPriv = 'editBranchPriv';
$lang->resource->gitlab->deleteBranchPriv = 'deleteBranchPriv';
$lang->resource->gitlab->manageBranchPriv = 'browseBranchPriv';
$lang->resource->gitlab->manageTagPriv = 'browseTagPriv';
$lang->resource->gitlab->browseTag = 'browseTag';
$lang->resource->gitlab->createTag = 'createTag';
$lang->resource->gitlab->deleteTag = 'deleteTag';
$lang->resource->gitlab->browseTagPriv = 'browseTagPriv';
$lang->resource->gitlab->createTagPriv = 'createTagPriv';
$lang->resource->gitlab->editTagPriv = 'editTagPriv';
$lang->resource->gitlab->deleteTagPriv = 'deleteTagPriv';
$lang->gitlab->methodOrder[5] = 'browse';
$lang->gitlab->methodOrder[10] = 'create';
@@ -1381,23 +1378,27 @@ $lang->gitlab->methodOrder[115] = 'browseBranch';
$lang->gitlab->methodOrder[120] = 'webhook';
$lang->gitlab->methodOrder[125] = 'createWebhook';
$lang->gitlab->methodOrder[130] = 'manageProjectMembers';
$lang->gitlab->methodOrder[135] = 'browseTag';
$lang->gitlab->methodOrder[140] = 'browseTagPriv';
$lang->gitlab->methodOrder[145] = 'deleteTagPriv';
$lang->gitlab->methodOrder[135] = 'manageBranchPriv';
$lang->gitlab->methodOrder[140] = 'manageTagPriv';
$lang->gitlab->methodOrder[145] = 'browseTag';
$lang->gitlab->methodOrder[150] = 'createTag';
$lang->gitlab->methodOrder[155] = 'deleteTag';
/* Gitea. */
$lang->resource->gitea = new stdclass();
$lang->resource->gitea->browse = 'browse';
$lang->resource->gitea->create = 'create';
$lang->resource->gitea->edit = 'edit';
$lang->resource->gitea->view = 'view';
$lang->resource->gitea->delete = 'delete';
$lang->resource->gitea->browse = 'browse';
$lang->resource->gitea->create = 'create';
$lang->resource->gitea->edit = 'edit';
$lang->resource->gitea->view = 'view';
$lang->resource->gitea->delete = 'delete';
$lang->resource->gitea->bindUser = 'bindUser';
$lang->gitea->methodOrder[5] = 'browse';
$lang->gitea->methodOrder[10] = 'create';
$lang->gitea->methodOrder[15] = 'edit';
$lang->gitea->methodOrder[20] = 'view';
$lang->gitea->methodOrder[25] = 'delete';
$lang->gitea->methodOrder[30] = 'bindUser';
/* SonarQube. */
$lang->resource->sonarqube = new stdclass();
+2
View File
@@ -1,3 +1,5 @@
.tree .active{font-weight: bold;}
.with-side .side {position: absolute; width: 130px;}
.with-side .main {padding-left: 145px; float: left;}
.side-col {width: 160px;}
.panel-sm .panel-body {padding: 10px;}
+3 -3
View File
@@ -114,7 +114,7 @@ class job extends control
$repoTypes[$repo->id] = $repo->SCM;
if(strtolower($repo->SCM) == 'gitlab')
{
if(isset($repo->gitlab)) $gitlab = $this->loadModel('gitlab')->getByID($repo->gitlab);
if(isset($repo->gitService)) $gitlab = $this->loadModel('gitlab')->getByID($repo->gitService);
if(!empty($gitlab)) $tokenUser = $this->gitlab->apiGetCurrentUser($gitlab->url, $gitlab->token);
if(!isset($tokenUser->is_admin) or !$tokenUser->is_admin) continue;
$gitlabRepos[$repo->id] = $repo->name;
@@ -180,7 +180,7 @@ class job extends control
$repo = $this->loadModel('repo')->getRepoByID($job->repo);
$this->view->repo = $this->loadModel('repo')->getRepoByID($job->repo);
if($repo->SCM == 'Gitlab') $this->view->refList = $this->loadModel('gitlab')->getReferenceOptions($repo->gitlab, $repo->project);
if($repo->SCM == 'Gitlab') $this->view->refList = $this->loadModel('gitlab')->getReferenceOptions($repo->gitService, $repo->project);
$repoList = $this->repo->getList($this->projectID);
$repoPairs = array(0 => '', $repo->id => $repo->name);
@@ -383,7 +383,7 @@ class job extends control
public function ajaxGetRefList($repoID)
{
$repo = $this->loadModel('repo')->getRepoByID($repoID);
if($repo->SCM == 'Gitlab') $refList = $this->loadModel('gitlab')->getReferenceOptions($repo->gitlab, $repo->project);
if($repo->SCM == 'Gitlab') $refList = $this->loadModel('gitlab')->getReferenceOptions($repo->gitService, $repo->project);
if($repo->SCM != 'Gitlab') $refList = $this->repo->getBranches($repo, true);
$this->send(array('result' => 'success', 'refList' => $refList));
}
+3 -4
View File
@@ -1852,11 +1852,10 @@ class kanban extends control
public function ajaxGetContactUsers($field, $contactListID)
{
$this->loadModel('user');
$list = $contactListID ? $this->user->getContactListByID($contactListID) : '';
$list = $contactListID ? $this->user->getContactListByID($contactListID) : '';
$users = $this->user->getPairs('nodeleted|noclosed', '', $this->config->maxCount);
$users = $this->user->getPairs('devfirst|nodeleted|noclosed', $list ? $list->userList : '', $this->config->maxCount);
if(!$contactListID) return print(html::select($field . '[]', $users, '', "class='form-control picker-select' multiple"));
if(!$contactListID or !isset($list->userList)) return print(html::select($field . '[]', $users, '', "class='form-control picker-select' multiple"));
return print(html::select($field . '[]', $users, $list->userList, "class='form-control picker-select' multiple"));
}
+4 -2
View File
@@ -23,5 +23,7 @@
#copyKanbanModal .copyContentBox > .checkbox-primary {display: inline-block; margin-left: 10px; margin-top: -1px;}
#copyKanbanModal .copyContentBox > .checkbox-primary:first-child {margin-left: 20px;}
#copyContentbasicInfo {cursor: not-allowed;}
#team ~ #contactListMenu_chosen, #whitelist ~ #contactListMenu_chosen {vertical-align: top;}
#team ~ #contactListMenu_chosen > .chosen-drop, #whitelist ~ #contactListMenu_chosen > .chosen-drop {top: 32px;}
#team ~ #contactListMenu_chosen {vertical-align: top;}
#whitelist ~ #contactListMenu_chosen {vertical-align: bottom;}
#team ~ #contactListMenu_chosen > .chosen-drop {top: 32px;}
#whitelist ~ #contactListMenu_chosen > .chosen-drop {bottom: 32px;}
+4 -2
View File
@@ -10,5 +10,7 @@
#mainContent .objectBox .checkbox-primary>label:after {width: 14px; height: 14px;}
[lang^='en'] .columnWidth {width: 120px;}
[lang^='zh-cn'] .columnWidth {width: 80px;}
#team ~ #contactListMenu_chosen, #whitelist ~ #contactListMenu_chosen {vertical-align: top;}
#team ~ #contactListMenu_chosen > .chosen-drop, #whitelist ~ #contactListMenu_chosen > .chosen-drop {top: 32px;}
#team ~ #contactListMenu_chosen {vertical-align: top;}
#whitelist ~ #contactListMenu_chosen {vertical-align: bottom;}
#team ~ #contactListMenu_chosen > .chosen-drop {top: 32px;}
#whitelist ~ #contactListMenu_chosen > .chosen-drop {bottom: 32px;}
+20
View File
@@ -128,3 +128,23 @@ function loadAllUsers()
$('#owner').chosen();
});
}
/**
* The owners that loads kanban.
*
* @oaram int spaceID
* @access public
* @return void
*/
function loadOwners(spaceID)
{
var link = createLink('kanban', 'ajaxLoadUsers', 'spaceID='+ spaceID + '&field=owner&selectedUser=' + $('#owner').val());
$.get(link, function(data)
{
$('#owner').replaceWith(data);
$('#owner' + "_chosen").remove();
$('#owner').next('.picker').remove();
$('#owner').chosen();
});
}
-20
View File
@@ -92,23 +92,3 @@ function loadUsers(spaceID)
if(spaceType != 'private') loadOwners(spaceID);
}
/**
* The owners that loads kanban.
*
* @oaram int spaceID
* @access public
* @return void
*/
function loadOwners(spaceID)
{
var link = createLink('kanban', 'ajaxLoadUsers', 'spaceID='+ spaceID + '&field=owner&selectedUser=' + $('#owner').val());
$.get(link, function(data)
{
$('#owner').replaceWith(data);
$('#owner' + "_chosen").remove();
$('#owner').next('.picker').remove();
$('#owner').chosen();
});
}
+2 -2
View File
@@ -59,7 +59,7 @@
<td colspan='2'>
<div class="input-group">
<?php echo html::select('team[]', $users, isset($copyKanban->team) ? $copyKanban->team : '', "class='form-control picker-select' multiple data-dropDirection='bottom'");?>
<?php echo $this->fetch('my', 'buildContactLists', 'dropdownName=team');?>
<?php echo $this->fetch('my', 'buildContactLists', "dropdownName=team");?>
</div>
</td>
</tr>
@@ -100,7 +100,7 @@
<td colspan='2'>
<div class="input-group">
<?php echo html::select('whitelist[]', $users, isset($copyKanban->whitelist) ? $copyKanban->whitelist : '', 'class="form-control picker-select" multiple');?>
<?php echo $this->fetch('my', 'buildContactLists', 'dropdownName=whitelist');?>
<?php echo $this->fetch('my', 'buildContactLists', "dropdownName=whitelist&attr=data-drop_direction='up'");?>
</div>
</td>
</tr>
+1 -1
View File
@@ -36,7 +36,7 @@
<td colspan='2'>
<div class="input-group">
<?php echo html::select('team[]', $users, '', "class='form-control picker-select' multiple data-drop-direction='bottom'");?>
<?php echo $this->fetch('my', 'buildContactLists');?>
<?php echo $this->fetch('my', 'buildContactLists', "dropdownName=team");?>
</div>
</td>
</tr>
+2 -2
View File
@@ -22,7 +22,7 @@
<table class='table table-form'>
<tr>
<th><?php echo $lang->kanban->space;?></th>
<td><?php echo html::select('space', $spacePairs, $kanban->space, "class='form-control chosen'");?></td>
<td><?php echo html::select('space', $spacePairs, $kanban->space, "class='form-control chosen' onchange='loadOwners(this.value)'");?></td>
</tr>
<tr>
<th><?php echo $lang->kanban->WIPCount;?></th>
@@ -99,7 +99,7 @@
<td colspan='2'>
<div class="input-group">
<?php echo html::select('whitelist[]', $users, $kanban->whitelist, 'class="form-control picker-select" multiple');?>
<?php echo $this->fetch('my', 'buildContactLists', 'dropdownName=whitelist');?>
<?php echo $this->fetch('my', 'buildContactLists', "dropdownName=whitelist&attr=data-drop_direction='up'");?>
</div>
</td>
</tr>
+1 -1
View File
@@ -37,7 +37,7 @@
<td colspan='2'>
<div class="input-group">
<?php echo html::select('team[]', $users, $team, "class='form-control picker-select' multiple data-drop-direction='bottom'");?>
<?php echo $this->fetch('my', 'buildContactLists');?>
<?php echo $this->fetch('my', 'buildContactLists', "dropdownName=team");?>
</div>
</td>
</tr>
+2
View File
@@ -32,3 +32,5 @@ $config->mrapproval = new stdclass();
$config->mrapproval->create = new stdclass();
$config->mrapproval->create->skippedFields = '';
$config->mrapproval->create->requiredFields = 'mrID,account,date,action';
$config->mr->gitServiceList = array('gitlab', 'gitea');
+131 -85
View File
@@ -34,25 +34,24 @@ class mr extends control
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
$repos = $this->loadModel('repo')->getListBySCM('Gitlab');
$repos = $this->loadModel('repo')->getListBySCM(array('Gitlab', 'Gitea'));
if(empty($repos)) $this->locate($this->repo->createLink('create'));
$repoID = $this->repo->saveState($repoID, $objectID);
$repo = $this->repo->getRepoByID($repoID);
if($repo->SCM != 'Gitlab') $repo = $repos[0];
if(!in_array(strtolower($repo->SCM), $this->config->mr->gitServiceList)) $repo = $repos[0];
$this->loadModel('ci')->setMenu($repo->id);
$projects = $this->mr->getAllGitlabProjects($repoID);
$projects = $this->mr->getAllProjects($repoID, $repo->SCM);
$MRList = $this->mr->getList($mode, $param, $orderBy, $pager, empty($projects) ? false : $projects, $repoID);
/* Save current URI to session. */
$this->session->set('mrList', $this->app->getURI(true), 'repo');
/* Sync GitLab MR to ZenTao Database. */
$MRList = $this->mr->batchSyncMR($MRList);
$MRList = $this->mr->batchSyncMR($MRList, $repo->SCM);
/* Check whether Mr is linked with the product. */
$this->loadModel('gitlab');
foreach($MRList as $MR)
{
$product = $this->mr->getMRProduct($MR);
@@ -63,7 +62,17 @@ class mr extends control
$this->app->loadLang('compile');
$openIDList = array();
if(!$this->app->user->admin) $openIDList = $this->loadModel('gitlab')->getGitLabListByAccount($this->app->user->account);
if(!$this->app->user->admin)
{
if($repo->SCM == 'Gitlab')
{
$openIDList = $this->loadModel('gitlab')->getGitLabListByAccount($this->app->user->account);
}
else
{
$openIDList = $this->loadModel('gitea')->getGiteaListByAccount($this->app->user->account);
}
}
$this->view->title = $this->lang->mr->common . $this->lang->colon . $this->lang->mr->browse;
$this->view->MRList = $MRList;
@@ -95,19 +104,30 @@ class mr extends control
return $this->send($result);
}
$gitlabHosts = $this->loadModel('gitlab')->getPairs();
$gitlabUsers = $this->gitlab->getGitLabListByAccount();
foreach($gitlabHosts as $gitlabID=> $gitlabHost)
$hosts = $this->loadModel('pipeline')->getList(array('gitea', 'gitlab'));
if(!$this->app->user->admin)
{
if(!$this->app->user->admin and !isset($gitlabUsers[$gitlabID])) unset($gitlabHosts[$gitlabID]);
$gitlabUsers = $this->loadModel('gitlab')->getGitLabListByAccount();
$giteaUsers = $this->loadModel('gitea')->getGiteaListByAccount();
foreach($hosts as $hostID => $host)
{
if($host->type == 'gitLab' and isset($gitlabUsers[$hostID])) continue;
if($host->type == 'gitea' and isset($giteaUsers[$hostID])) continue;
unset($hosts[$hostID]);
}
}
$hostPairs = array();
foreach($hosts as $host) $hostPairs[$host->id] = '[' . ucfirst($host->type) . "] {$host->name}";
$this->app->loadLang('repo'); /* Import lang in repo module. */
$this->app->loadLang('compile');
$this->view->title = $this->lang->mr->create;
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->view->jobList = $this->loadModel('job')->getList();
$this->view->gitlabHosts = $gitlabHosts;
$this->view->title = $this->lang->mr->create;
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->view->jobList = $this->loadModel('job')->getList();
$this->view->hostPairs = $hostPairs;
$this->view->hosts = $hosts;
$this->display();
}
@@ -126,38 +146,40 @@ class mr extends control
}
$MR = $this->mr->getByID($MRID);
if(isset($MR->gitlabID)) $rawMR = $this->mr->apiGetSingleMR($MR->gitlabID, $MR->targetProject, $MR->mriid);
if(isset($MR->hostID)) $rawMR = $this->mr->apiGetSingleMR($MR->hostID, $MR->targetProject, $MR->mriid);
$this->view->title = $this->lang->mr->edit;
$this->view->MR = $MR;
$this->view->rawMR = isset($rawMR) ? $rawMR : false;
if(!isset($rawMR->id) or (isset($rawMR->message) and $rawMR->message == '404 Not found') or empty($rawMR)) return $this->display();
$branchList = $this->loadModel('gitlab')->getBranches($MR->gitlabID, $MR->targetProject);
$host = $this->loadModel('pipeline')->getByID($MR->hostID);
$scm = $host->type;
$branchList = $this->loadModel($scm)->getBranches($MR->hostID, $MR->targetProject);
$MR->canDeleteBranch = true;
$branchPrivs = $this->loadModel($scm)->apiGetBranchPrivs($MR->hostID, $MR->sourceProject);
foreach($branchPrivs as $priv)
{
if($MR->canDeleteBranch and $priv->name == $MR->sourceBranch) $MR->canDeleteBranch = false;
}
$targetBranchList = array();
foreach($branchList as $branch) $targetBranchList[$branch] = $branch;
/* Fetch user list both in Zentao and current GitLab project. */
$bindedUsers = $this->gitlab->getUserIdRealnamePairs($MR->gitlabID);
$rawProjectUsers = $this->gitlab->apiGetProjectUsers($MR->gitlabID, $MR->targetProject);
$users = array();
foreach($rawProjectUsers as $rawProjectUser)
{
if(!empty($bindedUsers[$rawProjectUser->id])) $users[$rawProjectUser->id] = $bindedUsers[$rawProjectUser->id];
}
$gitlabUsers = $this->gitlab->getUserAccountIdPairs($MR->gitlabID);
$bindedUsers = $this->$scm->getUserIdRealnamePairs($MR->hostID);
$gitUsers = $this->$scm->getUserAccountIdPairs($MR->hostID);
/* Check permissions. */
if(!$this->app->user->admin)
if(!$this->app->user->admin and $scm == 'gitlab')
{
$groupIDList = array(0 => 0);
$groups = $this->gitlab->apiGetGroups($MR->gitlabID, 'name_asc', 'developer');
$groups = $this->scm->apiGetGroups($MR->hostID, 'name_asc', 'developer');
foreach($groups as $group) $groupIDList[] = $group->id;
$sourceProject = $this->gitlab->apiGetSingleProject($MR->gitlabID, $MR->sourceProject);
$isDeveloper = $this->gitlab->checkUserAccess($MR->gitlabID, 0, $sourceProject, $groupIDList, 'developer');
$sourceProject = $this->scm->apiGetSingleProject($MR->hostID, $MR->sourceProject);
$isDeveloper = $this->scm->checkUserAccess($MR->hostID, 0, $sourceProject, $groupIDList, 'developer');
if(!isset($gitlabUsers[$this->app->user->account]) or !$isDeveloper) return print(js::alert($this->lang->mr->errorLang[3]) . js::locate($this->createLink('mr', 'browse')));
if(!isset($gitUsers[$this->app->user->account]) or !$isDeveloper) return print(js::alert($this->lang->mr->errorLang[3]) . js::locate($this->createLink('mr', 'browse')));
}
/* Import lang for required modules. */
@@ -166,7 +188,7 @@ class mr extends control
$this->loadModel('compile');
$repoList = array();
$rawRepoList = $this->repo->getGitLabRepoList($MR->gitlabID, $MR->sourceProject);
$rawRepoList = $this->repo->getRepoListByClient($MR->hostID, $MR->sourceProject);
foreach($rawRepoList as $rawRepo) $repoList[$rawRepo->id] = "[$rawRepo->id] $rawRepo->name";
$jobList = array();
@@ -181,10 +203,11 @@ class mr extends control
$this->view->title = $this->lang->mr->edit;
$this->view->MR = $MR;
$this->view->host = $host;
$this->view->targetBranchList = $targetBranchList;
$this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed');
$this->view->assignee = $MR->assignee;
$this->view->reviewer = zget($gitlabUsers, $MR->reviewer, '');
$this->view->reviewer = zget($gitUsers, $MR->reviewer, '');
$this->display();
}
@@ -204,12 +227,12 @@ class mr extends control
if($MR->synced)
{
$res = $this->mr->apiDeleteMR($MR->gitlabID, $MR->targetProject, $MR->mriid);
$res = $this->mr->apiDeleteMR($MR->hostID, $MR->targetProject, $MR->mriid);
if(isset($res->message)) return print(js::alert($this->mr->convertApiError($res->message)));
}
$this->dao->delete()->from(TABLE_MR)->where('id')->eq($id)->exec();
echo js::locate(inlink('browse'), 'parent');
echo js::reload('parent');
}
/**
@@ -223,23 +246,25 @@ class mr extends control
{
$MR = $this->mr->getByID($id);
if(!$MR) return print(js::error($this->lang->notFound) . js::locate($this->createLink('mr', 'browse')));
if(isset($MR->gitlabID)) $rawMR = $this->mr->apiGetSingleMR($MR->gitlabID, $MR->targetProject, $MR->mriid);
if(isset($MR->hostID)) $rawMR = $this->mr->apiGetSingleMR($MR->hostID, $MR->targetProject, $MR->mriid);
if($MR->synced and (!isset($rawMR->id) or (isset($rawMR->message) and $rawMR->message == '404 Not found') or empty($rawMR))) return $this->display();
$this->loadModel('gitlab');
$host = $this->loadModel('pipeline')->getByID($MR->hostID);
$scm = $host->type;
$this->loadModel($scm);
$this->loadModel('job');
/* Sync MR from GitLab to ZentaoPMS. */
$MR = $this->mr->apiSyncMR($MR);
$sourceProject = $this->gitlab->apiGetSingleProject($MR->gitlabID, $MR->sourceProject);
$targetProject = $this->gitlab->apiGetSingleProject($MR->gitlabID, $MR->targetProject);
$sourceBranch = $this->gitlab->apiGetSingleBranch($MR->gitlabID, $MR->sourceProject, $MR->sourceBranch);
$targetBranch = $this->gitlab->apiGetSingleBranch($MR->gitlabID, $MR->targetProject, $MR->targetBranch);
$sourceProject = $this->$scm->apiGetSingleProject($MR->hostID, $MR->sourceProject);
$targetProject = $this->$scm->apiGetSingleProject($MR->hostID, $MR->targetProject);
$sourceBranch = $this->$scm->apiGetSingleBranch($MR->hostID, $MR->sourceProject, $MR->sourceBranch);
$targetBranch = $this->$scm->apiGetSingleBranch($MR->hostID, $MR->targetProject, $MR->targetBranch);
$projectOwner = true;
if(isset($MR->gitlabID) and !$this->app->user->admin)
if(isset($MR->hostID) and !$this->app->user->admin)
{
$openID = $this->gitlab->getUserIDByZentaoAccount($MR->gitlabID, $this->app->user->account);
$openID = $this->$scm->getUserIDByZentaoAccount($MR->hostID, $this->app->user->account);
if(!$projectOwner and isset($sourceProject->owner->id) and $sourceProject->owner->id == $openID) $projectOwner = true;
}
@@ -320,22 +345,10 @@ class mr extends control
}
}
/* Accept MR by using the mapped user in GitLab. */
$sudoUser = $this->mr->getSudoUsername($MR->gitlabID, $MR->targetProject);
if(isset($MR->gitlabID))
{
if(!empty($sudoUser)) $rawMR = $this->mr->apiAcceptMR($MR->gitlabID, $MR->targetProject, $MR->mriid, $sudoUser);
if(empty($sudoUser)) $rawMR = $this->mr->apiAcceptMR($MR->gitlabID, $MR->targetProject, $MR->mriid);
}
if(isset($MR->hostID)) $rawMR = $this->mr->apiAcceptMR($MR->hostID, $MR->targetProject, $MR->mriid, $MR);
if(isset($rawMR->state) and $rawMR->state == 'merged')
{
///* Force reload when locate to the url. */
//$random = uniqid();
//return $this->send(array('result' => 'success', 'message' => $this->lang->mr->mergeSuccess, 'locate' => helper::createLink('mr', 'browse', "random={$random}")));
$this->mr->logMergedAction($MR);
return $this->send(array('result' => 'success', 'message' => $this->lang->mr->mergeSuccess, 'locate' => helper::createLink('mr', 'browse')));
}
@@ -372,7 +385,7 @@ class mr extends control
$rawMR = null;
if($MR->synced)
{
$rawMR = $this->mr->apiGetSingleMR($MR->gitlabID, $MR->targetProject, $MR->mriid);
$rawMR = $this->mr->apiGetSingleMR($MR->hostID, $MR->targetProject, $MR->mriid);
if(!isset($rawMR->id) or (isset($rawMR->message) and $rawMR->message == '404 Not found') or empty($rawMR)) return $this->display();
}
$this->view->rawMR = $rawMR;
@@ -594,7 +607,7 @@ class mr extends control
$this->loadModel('search')->setSearchParams($this->config->product->search);
$MR = $this->mr->getByID($MRID);
$relatedStories = $this->mr->getCommitedLink($MR->gitlabID, $MR->targetProject, $MR->mriid, 'story');
$relatedStories = $this->mr->getCommitedLink($MR->hostID, $MR->targetProject, $MR->mriid, 'story');
$linkedStories = $this->mr->getLinkList($MRID, $product->id, 'story');
if($browseType == 'bySearch')
@@ -679,7 +692,7 @@ class mr extends control
$this->loadModel('search')->setSearchParams($this->config->bug->search);
$MR = $this->mr->getByID($MRID);
$relatedBugs = $this->mr->getCommitedLink($MR->gitlabID, $MR->targetProject, $MR->mriid, 'bug');
$relatedBugs = $this->mr->getCommitedLink($MR->hostID, $MR->targetProject, $MR->mriid, 'bug');
$linkedBugs = $this->mr->getLinkList($MRID, $product->id, 'bug');
if($browseType == 'bySearch')
@@ -751,7 +764,7 @@ class mr extends control
$this->loadModel('search')->setSearchParams($this->config->execution->search);
$MR = $this->mr->getByID($MRID);
$relatedTasks = $this->mr->getCommitedLink($MR->gitlabID, $MR->targetProject, $MR->mriid, 'task');
$relatedTasks = $this->mr->getCommitedLink($MR->hostID, $MR->targetProject, $MR->mriid, 'task');
$linkedTasks = $this->mr->getLinkList($MRID, $product->id, 'task');
/* Get executions by product. */
@@ -884,46 +897,57 @@ class mr extends control
/**
* AJAX: Get MR target projects.
*
* @param int $gitlabID
* @param int $hostID
* @param int $projectID
* @param string $scm
* @access public
* @return void
*/
public function ajaxGetMRTargetProjects($gitlabID, $projectID)
public function ajaxGetMRTargetProjects($hostID, $projectID, $scm = 'gitlab')
{
$this->loadModel('gitlab');
$this->loadModel($scm);
if($scm != 'gitlab') $projectID = urldecode(base64_decode($projectID));
/* First step: get forks. Only get first level forks(not recursively). */
$projects = $this->gitlab->apiGetForks($gitlabID, $projectID);
$projects = $scm == 'gitlab' ? $this->$scm->apiGetForks($hostID, $projectID) : array();
/* Second step: get project itself. */
$projects[] = $this->gitlab->apiGetSingleProject($gitlabID, $projectID);
$projects[] = $this->$scm->apiGetSingleProject($hostID, $projectID);
/* Last step: find its upstream recursively. */
$project = $this->gitlab->apiGetUpstream($gitlabID, $projectID);
$project = $this->$scm->apiGetUpstream($hostID, $projectID);
if(!empty($project)) $projects[] = $project;
while(!empty($project) and isset($project->id))
if(!empty($project) and isset($project->id))
{
$project = $this->gitlab->apiGetUpstream($gitlabID, $project->id);
if(empty($project)) break;
$projects[] = $project;
$project = $this->$scm->apiGetUpstream($hostID, $project->id);
if(!empty($project)) $projects[] = $project;
}
$groupIDList = array(0 => 0);
$groups = $this->gitlab->apiGetGroups($gitlabID, 'name_asc', 'developer');
foreach($groups as $group) $groupIDList[] = $group->id;
foreach($projects as $key => $project)
if($scm == 'gitlab')
{
if($this->gitlab->checkUserAccess($gitlabID, 0, $project, $groupIDList, 'developer') == false) unset($projects[$key]);
}
$groupIDList = array(0 => 0);
$groups = $this->$scm->apiGetGroups($hostID, 'name_asc', 'developer');
foreach($groups as $group) $groupIDList[] = $group->id;
foreach($projects as $key => $project)
{
if($this->$scm->checkUserAccess($hostID, 0, $project, $groupIDList, 'developer') == false) unset($projects[$key]);
}
if(!$projects) return $this->send(array('message' => array()));
if(!$projects) return $this->send(array('message' => array()));
}
$options = "<option value=''></option>";
foreach($projects as $project)
{
$options .= "<option value='{$project->id}' data-name='{$project->name}'>{$project->name_with_namespace}</option>";
if($scm == 'gitlab')
{
$options .= "<option value='{$project->id}' data-name='{$project->name}'>{$project->name_with_namespace}</option>";
}
else
{
$options .= "<option value='{$project->full_name}' data-name='{$project->full_name}'>{$project->full_name}</option>";
}
}
$this->send($options);
@@ -932,14 +956,16 @@ class mr extends control
/**
* AJAX: Get repo list.
*
* @param int $gitlabID
* @param int $hostID
* @param int $projectID
* @return void
*/
public function ajaxGetRepoList($gitlabID, $projectID)
public function ajaxGetRepoList($hostID, $projectID)
{
$this->loadModel('repo');
$repoList = $this->repo->getGitLabRepoList($gitlabID, $projectID);
$host = $this->loadModel('pipeline')->getByID($hostID);
if($host->type != 'gitlab') $projectID =urldecode(base64_decode($projectID));
$repoList = $this->loadModel('repo')->getRepoListByClient($hostID, $projectID);
if(!$repoList) return $this->send(array('message' => array()));
$options = "<option value=''></option>";
@@ -984,18 +1010,38 @@ class mr extends control
/**
* Ajax check same opened mr for source branch.
*
* @param int $gitlabID
* @param int $hostID
* @access public
* @return void
*/
public function ajaxCheckSameOpened($gitlabID)
public function ajaxCheckSameOpened($hostID)
{
$sourceProject = $this->post->sourceProject;
$sourceBranch = $this->post->sourceBranch;
$targetProject = $this->post->targetProject;
$targetBranch = $this->post->targetBranch;
$result = $this->mr->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
$result = $this->mr->checkSameOpened($hostID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
echo json_encode($result);
}
/**
* Ajax get branch pivs.
*
* @param int $hostID
* @param int|string $project
* @access public
* @return void
*/
public function ajaxGetBranchPivs($hostID, $project)
{
$host = $this->loadModel('pipeline')->getByID($hostID);
$scm = $host->type;
if($scm == 'gitea') $project = urldecode(base64_decode($project));
$branches = $this->loadModel($scm)->apiGetBranchPrivs($hostID, $project);
$branchPrivs = array();
foreach($branches as $branch) $branchPrivs[$branch->name] = $branch->name;
echo json_encode($branchPrivs);
}
}

Some files were not shown because too many files have changed in this diff Show More