This commit is contained in:
liugang
2020-03-20 10:20:07 +08:00
45 changed files with 235 additions and 149 deletions
+2 -3
View File
@@ -65,6 +65,8 @@ zentaoxx:
cp -r xuan/xxb/module/im zentaoxx/module/
cp -r xuan/xxb/module/client zentaoxx/module/
cp -r xuan/xxb/module/license zentaoxx/module/
cp -r xuan/xxb/module/owt zentaoxx/module/
cp xuan/xxb/apischeme.json zentaoxx/
mkdir -p zentaoxx/module/common/view
cp -r xuan/xxb/module/common/view/header.modal.html.php zentaoxx/module/common/view
cp -r xuan/xxb/module/common/view/marked.html.php zentaoxx/module/common/view
@@ -79,9 +81,6 @@ zentaoxx:
cp -r xuan/xxb/module/action/ext zentaoxx/module/action
cp -r xuan/xxb/config/ext/xxb.php zentaoxx/config/ext/
cp -r xuan/xxb/config/ext/maps.php zentaoxx/config/ext/
cp -r xuan/xxb/apischeme.json zentaoxx/
cp $(XUANPATH)/xxb/config/ext/maps.php zentaoxx/config/ext/
cp $(XUANPATH)/xxb/apischeme.json zentaoxx/
cp -r xuanxuan/config/* zentaoxx/config/
cp -r xuanxuan/module/* zentaoxx/module/
cp -r xuanxuan/www/* zentaoxx/www/
-17
View File
@@ -1138,23 +1138,6 @@ CREATE TABLE IF NOT EXISTS `zt_repo` (
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_relation`;
CREATE TABLE `zt_relation` (
`id` int(8) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`program` mediumint(8) NOT NULL,
`product` mediumint(8) NOT NULL,
`project` mediumint(8) NOT NULL,
`AType` char(30) NOT NULL,
`AID` mediumint(8) NOT NULL,
`AVersion` char(30) NOT NULL,
`relation` char(30) NOT NULL,
`BType` char(30) NOT NULL,
`BID` mediumint(8) NOT NULL,
`BVersion` char(30) NOT NULL,
`extra` char(30) NOT NULL,
UNIQUE KEY `relation` (`relation`,`AType`,`BType`, `AID`, `BID`)
) ENGINE='MyISAM' DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_repobranch`;
CREATE TABLE IF NOT EXISTS `zt_repobranch` (
`repo` mediumint(8) unsigned NOT NULL,
+1 -1
View File
@@ -1378,7 +1378,7 @@ class baseRouter
if(empty($extFiles) and empty($hookFiles)) return $mainModelFile;
/* 计算合并之后的modelFile路径。Compute the merged model file path. */
$extModelPrefix = ($siteExtended and !empty($this->siteCode)) ? $this->siteCode{0} . DS . $this->siteCode : '';
$extModelPrefix = ($siteExtended and !empty($this->siteCode)) ? $this->siteCode[0] . DS . $this->siteCode : '';
$mergedModelDir = $this->getTmpRoot() . 'model' . DS . ($extModelPrefix ? $extModelPrefix . DS : '');
$mergedModelFile = $mergedModelDir . $moduleName . '.php';
if(!is_dir($mergedModelDir)) mkdir($mergedModelDir, 0755, true);
@@ -45,7 +45,7 @@ class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef
protected function _compileRegex()
{
$raw = str_replace(' ', '', $this->dtd_regex);
if ($raw{0} != '(') {
if ($raw[0] != '(') {
$raw = "($raw)";
}
$el = '[#a-zA-Z0-9_.-]+';
@@ -75,7 +75,7 @@ class HTMLPurifier_TagTransform_Font extends HTMLPurifier_TagTransform
if (isset($attr['size'])) {
// normalize large numbers
if ($attr['size'] !== '') {
if ($attr['size']{0} == '+' || $attr['size']{0} == '-') {
if ($attr['size'][0] == '+' || $attr['size'][0] == '-') {
$size = (int)$attr['size'];
if ($size < -2) {
$attr['size'] = '-2';
+3 -3
View File
@@ -124,7 +124,7 @@ class GitRepo
$branches = array();
foreach($list as $localBranch)
{
if($localBranch{0} == '*') $localBranch = substr($localBranch, 1);
if($localBranch[0] == '*') $localBranch = substr($localBranch, 1);
$localBranch = trim($localBranch);
if(empty($localBranch))continue;
@@ -216,7 +216,7 @@ class GitRepo
foreach($list as $line)
{
if(empty($line)) continue;
if($line{0} == '^') $line = substr($line, 1);
if($line[0] == '^') $line = substr($line, 1);
preg_match('/^([0-9a-f]{39,40})\s.*\((\S+)\s+([\d-]+)\s(.*)\s(\d+)\)(.*)$/U', $line, $matches);
if(isset($matches[1]) and $matches[1] != $revision)
@@ -385,7 +385,7 @@ class GitRepo
$line = $lines[$i];
if(strpos($line, '\ No newline at end of file') === 0)continue;
$sign = empty($line) ? '' : $line{0};
$sign = empty($line) ? '' : $line[0];
if($sign == '-' and $newFile) $sign = '+';
$type = $sign != '-' ? $sign == '+' ? 'new' : 'all' : 'old';
if($sign == '-' || $sign == '+')
+1 -1
View File
@@ -447,7 +447,7 @@ class Subversion
$line = $lines[$i];
if(strpos($line, '\ No newline at end of file') === 0)continue;
$sign = empty($line) ? '' : $line{0};
$sign = empty($line) ? '' : $line[0];
$type = $sign != '-' ? $sign == '+' ? 'new' : 'all' : 'old';
if($sign == '-' || $sign == '+') $line = substr_replace($line, ' ', 1, 0);
+1 -1
View File
@@ -59,7 +59,7 @@ class wechatapi
$users = array();
foreach($depts->deptList as $deptID)
{
$response = $this->queryAPI($this->apiUrl . "user/simplelist?access_token={$this->token}&department_id={$deptID}");
$response = $this->queryAPI($this->apiUrl . "user/simplelist?access_token={$this->token}&department_id={$deptID}&fetch_child=1");
if($this->isError()) return array('result' => 'fail', 'message' => $this->errors);
foreach($response->userlist as $user) $users[$user->name] = $user->userid;
+31 -3
View File
@@ -34,10 +34,11 @@ class zdb
/**
* Get all tables.
*
* @param string $type if type is 'base', just get base table.
* @access public
* @return array
*/
public function getAllTables()
public function getAllTables($type = 'base')
{
global $config;
@@ -46,15 +47,42 @@ class zdb
while($table = $stmt->fetch(PDO::FETCH_ASSOC))
{
$tableType = strtolower($table['Table_type']);
if($tableType != 'base table') continue;
if($type == 'base' and $tableType != 'base table') continue;
$tableName = $table["Tables_in_{$config->db->name}"];
$allTables[$tableName] = 'table';
$allTables[$tableName] = $tableType == 'base table' ? 'table' : $tableType;
}
return $allTables;
}
/**
* Get table fields.
*
* @param string $table
* @access public
* @return array
*/
public function getTableFields($table)
{
try
{
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$sql = "DESC $table";
$rawFields = $this->dbh->query($sql)->fetchAll();
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
}
catch (PDOException $e)
{
$this->sqlError($e);
}
$fields = array();
foreach($rawFields as $field) $fields[$field->field] = $field;
return $fields;
}
/**
* Dump db.
*
+5 -5
View File
@@ -20,7 +20,7 @@ $lang->admin->certifyMobile = 'Verify your cellphone';
$lang->admin->certifyEmail = 'Verify your Email';
$lang->admin->ztCompany = 'Verify your company';
$lang->admin->captcha = 'Verification Code';
$lang->admin->getCaptcha = 'Get Verification Code';
$lang->admin->getCaptcha = 'Send Verification Code';
$lang->admin->api = 'API';
$lang->admin->log = 'Log';
@@ -40,13 +40,13 @@ $lang->admin->notice->int = "『%s』should be a positive integer.";
$lang->admin->register = new stdclass();
$lang->admin->register->common = 'Bind Account';
$lang->admin->register->caption = 'Register in ZenTao Community';
$lang->admin->register->click = 'Register here';
$lang->admin->register->caption = 'ZenTao Community Signup';
$lang->admin->register->click = 'Sign Up';
$lang->admin->register->lblAccount = '>= 3 letters and numbers';
$lang->admin->register->lblPasswd = '>= 6 letters and numbers';
$lang->admin->register->submit = 'Register';
$lang->admin->register->submit = 'Submit';
$lang->admin->register->bind = "Bind Exsiting Account";
$lang->admin->register->success = "You have registered!";
$lang->admin->register->success = "You have signed up!";
$lang->admin->bind = new stdclass();
$lang->admin->bind->caption = 'Link Account';
+3 -6
View File
@@ -122,14 +122,11 @@ $(function()
})
<?php endif;?>
<?php endif;?>
<?php $showedModal = false;?>
<?php if(!empty($config->global->showAnnual) and empty($config->global->annualShowed)):?>
<?php $this->app->loadLang('misc');?>
var myModalTrigger = new $.zui.ModalTrigger({title:'<?php echo $lang->misc->showAnnual;?>', custom: function(){return <?php echo json_encode(sprintf($lang->misc->annualDesc, $this->createLink('report', 'annualData')));?>}});
<?php $remind = $this->loadModel('misc')->getRemind();?>
<?php if(!empty($remind)):?>
var myModalTrigger = new $.zui.ModalTrigger({title:'<?php echo $lang->misc->remind;?>', custom: function(){return <?php echo json_encode($remind);?>}, width:'600px'});
var result = myModalTrigger.show();
$('#showAnnual').click(function(){myModalTrigger.close()});
<?php $this->loadModel('setting')->setItem("{$this->app->user->account}.common.global.annualShowed", 1);?>
<?php $showedModal = true;?>
<?php endif;?>
</script>
<?php if($extView = $this->getExtViewFile(__FILE__)){include $extView; return helper::cd();}?>
+1
View File
@@ -1,4 +1,5 @@
.main-actions{display: none}
#main{margin-bottom: 40px;}
#mainMenu .pull-left>a{display: none}
#mainMenu .pull-left .divider{display: none}
#mainMenu .pull-right{display: none}
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
$lang->ci->common = 'CI';
$lang->ci->job = 'Construction';
$lang->ci->job = 'Job';
$lang->ci->task = 'Task';
$lang->ci->history = 'History';
+1 -1
View File
@@ -335,7 +335,7 @@ $lang->caselib->menu->caselib = array('link' => 'Case Library|caselib|browse|l
$lang->ci = new stdclass();
$lang->ci->menu = new stdclass();
$lang->ci->menu->code = array('link' => 'Code|repo|browse|repoID=%s', 'alias' => 'diff,view,revision,log,blame,showsynccomment');
$lang->ci->menu->build = array('link' => 'Build|job|browse', 'subModule' => 'compile,job');
$lang->ci->menu->build = array('link' => 'Compile|job|browse', 'subModule' => 'compile,job');
$lang->ci->menu->jenkins = array('link' => 'Jenkins|jenkins|browse', 'alias' => 'create,edit');
$lang->ci->menu->maintain = array('link' => 'Repo|repo|maintain', 'alias' => 'create,edit');
$lang->ci->menu->rules = array('link' => 'Rule|repo|setrules');
+2 -2
View File
@@ -254,7 +254,7 @@ class commonModel extends model
{
echo '<li class="user-profile-item">';
echo "<a href='" . helper::createLink('my', 'profile') . "' class='" . (!empty($app->user->role) && isset($lang->user->roleList[$app->user->role]) ? '' : ' no-role') . "'>";
echo "<div class='avatar avatar bg-secondary avatar-circle'>" . strtoupper($app->user->account{0}) . "</div>\n";
echo "<div class='avatar avatar bg-secondary avatar-circle'>" . strtoupper($app->user->account[0]) . "</div>\n";
echo '<div class="user-profile-name">' . (empty($app->user->realname) ? $app->user->account : $app->user->realname) . '</div>';
if(isset($lang->user->roleList[$app->user->role])) echo '<div class="user-profile-role">' . $lang->user->roleList[$app->user->role] . '</div>';
echo '</a></li><li class="divider"></li>';
@@ -1766,7 +1766,7 @@ EOD;
{
$timestamp = $queryString['time'];
if(strlen($timestamp) > 10) $timestamp = substr($timestamp, 0, 10);
if(strlen($timestamp) != 10 or $timestamp{0} >= '4') $this->response('ERROR_TIMESTAMP');
if(strlen($timestamp) != 10 or $timestamp[0] >= '4') $this->response('ERROR_TIMESTAMP');
$result = $this->get->token == md5($entry->code . $entry->key . $queryString['time']);
if($result)
+1 -1
View File
@@ -22,7 +22,7 @@ $.initSidebar();
<div id="noticeBox"><?php echo $this->loadModel('score')->getNotice(); ?></div>
<script>
<?php if(!isset($config->global->browserNotice)):?>
browserNotice = '<?php echo $lang->browserNotice?>'
browserNotice = <?php echo json_encode($lang->browserNotice)?>;
function ajaxIgnoreBrowser(){$.get(createLink('misc', 'ajaxIgnoreBrowser'));}
$(function(){showBrowserNotice()});
<?php endif;?>
+10 -10
View File
@@ -1,16 +1,16 @@
<?php
$lang->compile->common = 'Build';
$lang->compile->browse = 'Build Histories';
$lang->compile->logs = 'Build Logs';
$lang->compile->common = 'Compile';
$lang->compile->browse = 'History';
$lang->compile->logs = 'Log';
$lang->compile->id = 'ID';
$lang->compile->name = 'Name';
$lang->compile->status = 'Build Status';
$lang->compile->time = 'Build Time';
$lang->compile->status = 'Status';
$lang->compile->time = 'Time';
$lang->compile->statusList['success'] = 'Success';
$lang->compile->statusList['failure'] = 'Fail';
$lang->compile->statusList['success'] = 'Done';
$lang->compile->statusList['failure'] = 'Failed';
$lang->compile->statusList['created'] = 'Created';
$lang->compile->statusList['building'] = 'Building';
$lang->compile->statusList['create_fail'] = 'Fail to create';
$lang->compile->statusList['timeout'] = 'Exec Timeout';
$lang->compile->statusList['building'] = 'Creating';
$lang->compile->statusList['create_fail'] = 'Failed to create';
$lang->compile->statusList['timeout'] = 'Timeout';
+1
View File
@@ -1,4 +1,5 @@
.side-col.col-4{display:none;}
#main{margin-bottom: 40px;}
#mainMenu{margin-top:0px;}
#mainMenu .btn{display:none;}
#mainMenu .divider{display:none;}
+1 -1
View File
@@ -569,7 +569,7 @@ class fileModel extends model
while($line)
{
/* the cell has '"', the delimiter is '",'. */
if($line{0} == '"')
if($line[0] == '"')
{
$pos = strpos($line, '",');
if($pos === false)
+2 -2
View File
@@ -361,7 +361,7 @@ class gitModel extends model
chdir($repo->path);
exec("{$this->client} config core.quotepath false");
$subPath = substr($path, strlen($repo->path));
if($subPath{0} == '/' or $subPath{0} == '\\') $subPath = substr($subPath, 1);
if($subPath[0] == '/' or $subPath[0] == '\\') $subPath = substr($subPath, 1);
$encodings = explode(',', $this->config->git->encodings);
foreach($encodings as $encoding)
@@ -402,7 +402,7 @@ class gitModel extends model
putenv('LC_CTYPE=en_US.UTF-8');
$subPath = substr($path, strlen($repo->path));
if($subPath{0} == '/' or $subPath{0} == '\\') $subPath = substr($subPath, 1);
if($subPath[0] == '/' or $subPath[0] == '\\') $subPath = substr($subPath, 1);
$encodings = explode(',', $this->config->git->encodings);
foreach($encodings as $encoding)
+21 -21
View File
@@ -21,13 +21,13 @@ $lang->install->officeDomain = 'https://www.zentao.pm';
$lang->install->start = 'Start';
$lang->install->keepInstalling = 'Continue installing this version';
$lang->install->seeLatestRelease = 'View latest version';
$lang->install->seeLatestRelease = 'View the latest version';
$lang->install->welcome = 'Thanks for choosing ZenTao!';
$lang->install->license = 'ZenTao is under Z PUBLIC LICENSE(ZPL) 1.2';
$lang->install->desc = <<<EOT
ZenTao ALM is an open source software released under <a href='http://zpl.pub/page/zplv12.html' target='_blank'>Z Public License</a>. It integrates with Product Management, Project Management, QA Management, Document Management, Todo Management, Company Management etc. ZenTao is a perfect choice for managing software development projects.
ZenTao ALM is an open source software released under <a href='http://zpl.pub/page/zplv12.html' target='_blank'>Z Public License</a>. It integrates with Product Management, Project Management, Test Management, Document Management, CI Management, etc. ZenTao is a perfect choice for managing software development projects.
ZenTao ALM is built on PHP + MySQL + zentaoPHP which is an independent framework developed by Nature Easy Soft. Third-party developers/organizations can develop extensions or customize ZenTao accordingly.
ZenTao ALM is built on PHP + MySQL + zentaoPHP which is an independent framework developed by EasyCorp. Third-party developers/organizations can develop extensions or customize ZenTao accordingly.
EOT;
$lang->install->links = <<<EOT
ZenTao ALM is developed by <strong><a href='http://en.easysoft.ltd' target='_blank' class='text-danger'>EasyCorp</a></strong>.
@@ -46,11 +46,11 @@ $lang->install->checking = 'System Checkup';
$lang->install->ok = 'Passed(√)';
$lang->install->fail = 'Failed(×)';
$lang->install->loaded = 'Loaded';
$lang->install->unloaded = 'Not Loaded';
$lang->install->unloaded = 'Not loaded';
$lang->install->exists = 'Found ';
$lang->install->notExists = 'Not found ';
$lang->install->writable = 'Writable ';
$lang->install->notWritable= 'Not Writable ';
$lang->install->notWritable= 'Not writable ';
$lang->install->phpINI = 'PHP ini File';
$lang->install->checkItem = 'Item';
$lang->install->current = 'Current Setting';
@@ -114,14 +114,14 @@ $lang->install->workingList['onlyTask'] = 'Only Task Management';
$lang->install->errorConnectDB = 'Connection to the database Failed. ';
$lang->install->errorDBName = 'Database name should exclude “.” ';
$lang->install->errorCreateDB = 'Failed to create the database.';
$lang->install->errorTableExists = 'The data table has existed. If ZenTao has been installed before, please return to last step and clear data. Then continue the installation.';
$lang->install->errorTableExists = 'The data table has existed. If ZenTao has been installed before, please return to the previous step and clear data, then continue the installation.';
$lang->install->errorCreateTable = 'Failed to create the table.';
$lang->install->errorImportDemoData = 'Failed to import demo data.';
$lang->install->errorImportDemoData = 'Failed to import the demo data.';
$lang->install->setConfig = 'Create configuration file';
$lang->install->setConfig = 'Create config file';
$lang->install->key = 'Item';
$lang->install->value = 'Value';
$lang->install->saveConfig = 'Save config';
$lang->install->saveConfig = 'Save config file';
$lang->install->save2File = '<div class="alert alert-warning">Copy the content in the text box above and save it to "<strong> %s </strong>". You can change this configuration file later.</div>';
$lang->install->saved2File = 'The configuration file has been saved to " <strong>%s</strong> ". You can change this file later.';
$lang->install->errorNotSaveConfig = 'The configuration file is not saved.';
@@ -161,32 +161,32 @@ $lang->install->cronList['moduleName=report&methodName=remind'] = 'Daily T
$lang->install->cronList['moduleName=svn&methodName=run'] = 'Synchronize SVN';
$lang->install->cronList['moduleName=git&methodName=run'] = 'Synchronize GIT';
$lang->install->cronList['moduleName=backup&methodName=backup'] = 'Backup Data';
$lang->install->cronList['moduleName=mail&methodName=asyncSend'] = 'Asynchronize sending Message';
$lang->install->cronList['moduleName=webhook&methodName=asyncSend'] = 'Asynchronize sending Webhook';
$lang->install->cronList['moduleName=admin&methodName=deleteLog'] = 'Delete overdue logs';
$lang->install->cronList['moduleName=mail&methodName=asyncSend'] = 'Asynchronize sending message';
$lang->install->cronList['moduleName=webhook&methodName=asyncSend'] = 'Asynchronize sending webhook';
$lang->install->cronList['moduleName=admin&methodName=deleteLog'] = 'Delete expired logs';
$lang->install->cronList['moduleName=todo&methodName=createCycle'] = 'Create recurring todos';
$lang->install->cronList['moduleName=ci&methodName=initQueue'] = 'Create recurring jenkins';
$lang->install->cronList['moduleName=ci&methodName=initQueue'] = 'Create recurring Jenkins';
$lang->install->cronList['moduleName=ci&methodName=checkBuildStatus'] = 'Synchronize Jenkins Status';
$lang->install->cronList['moduleName=ci&methodName=exec'] = 'Execute Jenkins';
$lang->install->success = "Installed!";
$lang->install->login = 'Login ZenTao';
$lang->install->register = 'Register in ZenTao Community';
$lang->install->login = 'ZenTao Login';
$lang->install->register = 'ZenTao Community Signup';
$lang->install->joinZentao = <<<EOT
<p>You have installed ZenTao %s.<strong class='text-danger'> Please delete install.php asap</strong>.</p><p>Note: In order to get the latest news of ZenTao, please register on ZenTao(<a href='https://www.zentao.pm' class='alert-link' target='_blank'>www.zentao.pm</a>).</p>
<p>You have installed ZenTao %s.<strong class='text-danger'> Please delete install.php</strong>.</p><p>Note: In order to get the latest news of ZenTao, please sign up on ZenTao Community(<a href='https://www.zentao.pm' class='alert-link' target='_blank'>www.zentao.pm</a>).</p>
EOT;
$lang->install->product = array('chanzhi', 'ranzhi', 'ydisk', 'meshiot');
$lang->install->promotion = "Products also from Nature Easy Soft:";
$lang->install->promotion = "Products also from EasyCorp:";
$lang->install->chanzhi = new stdclass();
$lang->install->chanzhi->name = 'ZSITE';
$lang->install->chanzhi->logo = 'images/main/chanzhi.ico';
$lang->install->chanzhi->url = 'http://www.zsite.net';
$lang->install->chanzhi->desc = <<<EOD
<ul>
<li>Article, Blog, Manual, Member, Shop, Forum, Feedback……</li>
<li>Article, Blog, Manual, Member, Shop, Forum, Feedback</li>
<li>Customize page at will by Theme, Effect, Widget, CSS, JS and layout</li>
<li>Support both desktop and mobile in one system</li>
<li>Highly optimized for search engines</li>
@@ -200,8 +200,8 @@ $lang->install->ranzhi->url = 'http://www.zdoo.org';
$lang->install->ranzhi->desc = <<<EOD
<ul>
<li>CRM: Customer Management and Order Tracking</li>
<li>OA: Approve, Announce, Trip, Leave and so on. </li>
<li>Project,Task and Document management </li>
<li>OA: Approve, Announce, Trip, Leave and more </li>
<li>Project, Task and Document management </li>
<li>Cash: Income, Expense, Transfer, Invest and Debt</li>
</ul>
EOD;
@@ -220,7 +220,7 @@ EOD;
$lang->install->ydisk = new stdclass();
$lang->install->ydisk->name = 'Y Disk-Free NetDisk';
$lang->install->ydisk->name = 'YDisk';
$lang->install->ydisk->logo = 'images/main/ydisk.ico';
$lang->install->ydisk->url = 'http://www.ydisk.cn';
$lang->install->ydisk->desc = <<<EOD
+3 -3
View File
@@ -1,6 +1,6 @@
<?php
$lang->jenkins->common = 'Jenkins';
$lang->jenkins->browse = 'Browse Jenkins';
$lang->jenkins->browse = 'Jenkins';
$lang->jenkins->create = 'Create Jenkins';
$lang->jenkins->edit = 'Edit Jenkins';
$lang->jenkins->delete = 'Delete';
@@ -8,9 +8,9 @@ $lang->jenkins->confirmDelete = 'Do you want to delete this Jenkins server?';
$lang->jenkins->id = 'ID';
$lang->jenkins->name = 'Name';
$lang->jenkins->url = 'Service URL';
$lang->jenkins->url = 'URL';
$lang->jenkins->token = 'Token';
$lang->jenkins->account = 'UserName';
$lang->jenkins->account = 'Username';
$lang->jenkins->password = 'Password';
$lang->jenkins->lblCreate = 'Create Jenkins Server';
+1
View File
@@ -72,6 +72,7 @@ $lang->misc->tableStatus = "状态";
$lang->misc->novice = "您可能初次使用禅道,是否进入新手模式?";
$lang->misc->showAnnual = '新增年度总结功能';
$lang->misc->annualDesc = '12.0版本后,新增年度总结功能,可以到『统计->年度总结』页面查看。 是否现在<a href="%s" target="_blank" id="showAnnual" class="btn btn-mini btn-primary">查看</a>';
$lang->misc->remind = '新功能提醒';
$lang->misc->noticeRepair = "<h5>普通用户请联系管理员进行修复</h5>
<h5>管理员请登录禅道所在的服务器,创建<span>%s</span>文件。</h5>
+18
View File
@@ -42,4 +42,22 @@ class miscModel extends model
}
return $tables;
}
/**
* Get remind.
*
* @access public
* @return string
*/
public function getRemind()
{
$remind = '';
if(!empty($this->config->global->showAnnual) and empty($this->config->global->annualShowed))
{
$remind = '<h4>' . $this->lang->misc->showAnnual . '</h4>';
$remind .= '<p>' . sprintf($this->lang->misc->annualDesc, helper::createLink('report', 'annualData')) . '</p>';
$this->loadModel('setting')->setItem("{$this->app->user->account}.common.global.annualShowed", 1);
}
return $remind;
}
}
+2 -2
View File
@@ -14,13 +14,13 @@ $lang->my->requirement = 'My Requirements';
$lang->my->myProject = "My {$lang->projectCommon}s";
$lang->my->profile = 'My Profile';
$lang->my->dynamic = 'My Dynamics';
$lang->my->editProfile = 'Edit Profile';
$lang->my->editProfile = 'Edit';
$lang->my->changePassword = 'Edit Password';
$lang->my->unbind = 'Unbind from Zdoo';
$lang->my->manageContacts = 'Manage Contact';
$lang->my->deleteContacts = 'Delete Contact';
$lang->my->shareContacts = 'Public';
$lang->my->limited = 'Limited Actions (Users can only edit the content that is involved themselves.)';
$lang->my->limited = 'Limited Actions (Users can only edit what involves them.)';
$lang->my->score = 'My Points';
$lang->my->scoreRule = 'Point Rules';
$lang->my->noTodo = 'No todos yet. ';
+19 -2
View File
@@ -986,6 +986,7 @@ class productModel extends model
$totalEstimate = 0.0;
$storyIdList = array();
$count = 0;
foreach($stories as $key => $story)
{
$totalEstimate += $story->estimate;
@@ -997,12 +998,28 @@ class productModel extends model
{
$storyIdList[] = $story->id;
}
$count ++;
if(!empty($story->children))
{
foreach($story->children as $child)
{
if(
$child->status != 'closed' or
($child->status == 'closed' and ($child->closedReason == 'done' or $child->closedReason == 'postponed'))
)
{
$storyIdList[] = $child->id;
}
$count ++;
}
}
}
$cases = $this->dao->select('DISTINCT story')->from(TABLE_CASE)->where('story')->in($storyIdList)->andWhere('deleted')->eq(0)->fetchAll();
$rate = count($stories) == 0 ? 0 : round(count($cases) / count($stories), 2);
$rate = count($stories) == 0 ? 0 : round(count($cases) / $count, 2);
return sprintf($this->lang->product->storySummary, count($stories), $totalEstimate, $rate * 100 . "%");
return sprintf($this->lang->product->storySummary, $count, $totalEstimate, $rate * 100 . "%");
}
/**
+3
View File
@@ -270,8 +270,11 @@ class productplan extends control
foreach($order as $id)
{
if(empty($id)) continue;
if(!isset($planStories[$id])) continue;
$stories[$id] = $planStories[$id];
unset($planStories[$id]);
}
if($planStories) $stories += $planStories;
$planStories = $stories;
unset($stories);
}
+1
View File
@@ -2,6 +2,7 @@
#mainMenu .pull-left .divider{display: none}
#mainMenu .pull-right{display: none}
#mainContent .col-4{display: none}
#main{margin-bottom: 40px;}
.main-actions{display:none;}
.col-8>.cell{min-height: 300px}
.modal-dialog{width: 90%}
+8
View File
@@ -2062,6 +2062,14 @@ class storyModel extends model
->fetchAll();
}
/**
* Get parent story pairs.
*
* @param int $productID
* @param string $append
* @access public
* @return void
*/
public function getParentStoryPairs($productID, $append = '')
{
$stories = $this->dao->select('id, title')->from(TABLE_STORY)
+1
View File
@@ -2,6 +2,7 @@
#mainMenu .pull-left .divider{display: none}
#mainMenu .pull-right{display: none}
#mainContent .col-4{display: none}
#main{margin-bottom: 40px;}
.main-actions{display:none;}
.col-8>.cell{min-height: 300px}
.modal-dialog{width: 90%}
+13 -6
View File
@@ -579,6 +579,7 @@ class taskModel extends model
$currentTask = !empty($task) ? $task : new stdclass();
if(!isset($currentTask->status)) $currentTask->status = $oldTask->status;
$currentTask->assignedTo = $oldTask->assignedTo;
if(!empty($this->post->assignedTo))
{
$currentTask->assignedTo = $this->post->assignedTo;
@@ -1155,8 +1156,8 @@ class taskModel extends model
$estimate = new stdclass();
$estimate->date = zget($task, 'realStarted', date(DT_DATE1));
$estimate->task = $taskID;
$estimate->consumed = zget($task, 'consumed', 0);
$estimate->left = zget($task, 'left', 0);
$estimate->consumed = zget($_POST, 'consumed', 0);
$estimate->left = zget($_POST, 'left', 0);
$estimate->work = zget($task, 'work', '');
$estimate->account = $this->app->user->account;
$estimate->consumed = $estimate->consumed - $oldTask->consumed;
@@ -1378,14 +1379,20 @@ class taskModel extends model
}
$estimate = new stdclass();
$estimate->date = zget($task, 'finishedDate', date(DT_DATE1));
$estimate->date = zget($_POST, 'finishedDate', date(DT_DATE1));
$estimate->task = $taskID;
$estimate->consumed = zget($task, 'consumed', 0);
$estimate->left = zget($task, 'left', 0);
$estimate->left = 0;
$estimate->work = zget($task, 'work', '');
$estimate->account = $this->app->user->account;
$estimate->consumed = $consumed;
if(!empty($oldTask->team))
{
foreach($oldTask->team as $teamAccount => $team)
{
if($teamAccount == $this->app->user->account) continue;
$estimate->left += $team->left;
}
}
if($estimate->consumed) $this->addTaskEstimate($estimate);
if(!empty($oldTask->team))
-24
View File
@@ -101,7 +101,6 @@
</tr>
</thead>
<tbody>
<?php $i = 0;?>
<?php foreach($stories as $storyID => $storyTitle):?>
<?php if(empty($storyID) or isset($testStoryIdList[$storyID])) continue;?>
<tr>
@@ -123,30 +122,7 @@
</div>
</td>
</tr>
<?php $i++;?>
<?php if($i >= 5) break;?>
<?php endforeach;?>
<?php if($i == 0):?>
<tr>
<td><?php echo html::select("testStory[]", $stories, '', "class='form-control chosen'");?></td>
<td><?php echo html::select("testPri[]", $lang->task->priList, $task->pri, "class='form-control chosen'");?></td>
<td>
<div class='input-group'>
<?php echo html::input("testEstStarted[]", $task->estStarted, "class='form-control form-date' placeholder='{$lang->task->estStarted}'");?>
<span class='input-group-addon fix-border'>~</span>
<?php echo html::input("testDeadline[]", $task->deadline, "class='form-control form-date' placeholder='{$lang->task->deadline}'");?>
</div>
</td>
<td><?php echo html::select("testAssignedTo[]", $members, $task->assignedTo, "class='form-control chosen'");?></td>
<td><?php echo html::input("testEstimate[]", '', "class='form-control'");?></td>
<td class='text-center'>
<div class="btn-group">
<button type="button" class="btn btn-sm" tabindex="-1" onclick='addItem(this)'><i class="icon icon-plus"></i></button>
<button type="button" class="btn btn-sm" tabindex="-1" onclick='removeItem(this)'><i class="icon icon-close"></i></button>
</div>
</td>
</tr>
<?php endif;?>
</tbody>
</table>
</td>
+1
View File
@@ -1,4 +1,5 @@
.side-col.col-4{display:none;}
#main{margin-bottom: 40px;}
#mainMenu{margin-top:0px;}
#mainMenu .btn{display:none;}
#mainMenu .divider{display:none;}
+1 -1
View File
@@ -1668,7 +1668,7 @@ class treeModel extends model
$createdVersion = $this->dao->select($versionField)->from($table)->where('id')->eq($rootID)->fetch($versionField);
if($createdVersion)
{
if(is_numeric($createdVersion{0}) and version_compare($createdVersion, '4.1', '<=')) return false;
if(is_numeric($createdVersion[0]) and version_compare($createdVersion, '4.1', '<=')) return false;
return true;
}
}
+13
View File
@@ -568,6 +568,19 @@ class upgradeModel extends model
$this->execSQL($this->getUpgradeFile('12.0.1'));
$this->importRepoFromConfig();
$this->appendExec('12_0_1');
case '12_1':
$this->saveLogs('Execute 12_1');
if(!isset($this->config->isINT) or !($this->config->isINT))
{
if(!$executeXuanxuan)
{
$xuanxuanSql = $this->app->getAppRoot() . 'db' . DS . 'upgradexuanxuan3.1.1.sql';
$this->execSQL($xuanxuanSql);
}
}
$this->appendExec('12_1');
}
$this->deletePatch();
+1 -1
View File
@@ -43,7 +43,7 @@ if(isset($_GET['mode']) and $_GET['mode'] == 'getconfig') die(helper::removeUTF8
/* Check for need upgrade. */
$config->installedVersion = $common->loadModel('setting')->getVersion();
if(((is_numeric($config->version{0}) and is_numeric($config->installedVersion{0})) or $config->version{0} == $config->installedVersion{0}) and version_compare($config->version, $config->installedVersion, '>')) die(header('location: upgrade.php'));
if(((is_numeric($config->version[0]) and is_numeric($config->installedVersion[0])) or $config->version[0] == $config->installedVersion[0]) and version_compare($config->version, $config->installedVersion, '>')) die(header('location: upgrade.php'));
/* Remove install.php and upgrade.php. */
if(file_exists('install.php') or file_exists('upgrade.php'))
+5 -5
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -56,7 +56,7 @@ $app->setDebug();
/* Check the installed version is the latest or not. */
$config->installedVersion = $common->loadModel('setting')->getVersion();
if(($config->version{0} == $config->installedVersion{0} or (is_numeric($config->version{0}) and is_numeric($config->installedVersion{0}))) and version_compare($config->version, $config->installedVersion) <= 0) die(header('location: index.php'));
if(($config->version[0] == $config->installedVersion[0] or (is_numeric($config->version[0]) and is_numeric($config->installedVersion[0]))) and version_compare($config->version, $config->installedVersion) <= 0) die(header('location: index.php'));
/* Run it. */
$app->parseRequest();
+2
View File
@@ -4,3 +4,5 @@ $filter->default->get['display'] = 'code';
$filter->entry = new stdclass();
$filter->entry->visit = new stdclass();
$filter->entry->visit->get['referer'] = 'reg::any';
$config->owt = new stdclass();
@@ -1,19 +0,0 @@
<script>
<?php
$this->app->loadLang('im');
$account = str_replace('.', '_', $this->app->user->account);
$xxInstalled = $account . 'installed';
?>
<?php if(!$showedModal and isset($config->xxserver->installed) and $config->xuanxuan->turnon and !isset($config->xxclient->$xxInstalled) and $config->global->flow == 'full' ):?>
var myModalTrigger = new $.zui.ModalTrigger({custom: '<?php echo $lang->im->xxClientConfirm;?>', title: '<?php echo $lang->im->zentaoClient;?>'});
var result = myModalTrigger.show();
<?php $this->loadModel('setting')->setItem("system.common.xxclient.{$account}installed", 1);?>
<?php $showedModal = true;?>
<?php endif;?>
<?php if(!$showedModal and !isset($config->xxserver->noticed) and $this->app->user->admin and $config->global->flow == 'full' and $config->$module->block->initVersion >= '2'):?>
var myModalTrigger = new $.zui.ModalTrigger({custom: '<?php echo $lang->im->xxServerConfirm;?>', title: '<?php echo $lang->im->zentaoClient;?>'});
var result = myModalTrigger.show();
<?php $this->loadModel('setting')->setItem("system.common.xxserver.noticed", 1);?>
<?php endif;?>
</script>
@@ -20,12 +20,13 @@ class xuanxuanMessage extends messageModel
$onlybody = isset($_GET['onlybody']) ? $_GET['onlybody'] : '';
unset($_GET['onlybody']);
$url = $server . helper::createLink($objectType, 'view', "id=$objectID", 'html');
$url = "xxc:openInApp/zentao-integrated/" . urlencode($url);
$target = '';
if(!empty($object->assignedTo)) $target .= $object->assignedTo;
if(!empty($object->mailto)) $target .= ",{$object->mailto}";
$target = trim($target, ',');
$target = $this->dao->select('id')->from(TABLE_USER)->where('account')->in($target)->fetchAll('id');
$target = $this->dao->select('id')->from(TABLE_USER)->where('account')->in($target)->andWhere('account')->ne($this->app->user->account)->fetchAll('id');
$target = array_keys($target);
if($target) $this->loadModel('im')->messageCreateNotify($target, $text, '', '', 'text', $url, array(), array('id' => 'zentao', 'realname' => $this->lang->message->sender, 'name' => $this->lang->message->sender));
@@ -23,6 +23,8 @@ class myMisc extends misc
$loginInfo->ui->defaultUser = new stdclass();
$loginInfo->ui->defaultUser->server = common::getSysURL();;
$loginInfo->ui->defaultUser->account = $this->app->user->account;
$loginInfo->ui->defaultUser->lock = false;
$loginInfo->ui->defaultUser->ldap = true;
$loginInfo = json_encode($loginInfo);
$loginFile = $clientDir . 'config.json';
@@ -56,6 +56,27 @@ class myMisc extends misc
if(strpos($agentOS, 'Mac') !== false) $os = 'mac64';
$this->view->os = $os;
/* Finish task #6990. */
$releasedInDB = $this->dao->select('*')->from(TABLE_IM_CLIENT)->where('version')->eq($this->config->xuanxuan->version)->andWhere('status')->eq('released')->fetch();
if($releasedInDB)
{
foreach(json_decode($releasedInDB->downloads) as $osKey => $link)
{
if(empty($link))
{
$osKey = strtolower(str_replace('zip', '', $osKey));
if(isset($this->lang->misc->client->osList[$osKey]))
{
unset($this->lang->misc->client->osList[$osKey]);
}
elseif(strpos($osKey, 'mac') === 0)
{
unset($this->lang->misc->client->osList['mac64']);
}
}
}
}
}
if($action == 'getPackage')
@@ -0,0 +1,24 @@
<?php
public function getRemind()
{
$remind = parent::getRemind();
$this->app->loadLang('im');
$account = str_replace('.', '_', $this->app->user->account);
$xxInstalled = $account . 'installed';
if(isset($this->config->xxserver->installed) and $this->config->xuanxuan->turnon and !isset($this->config->xxclient->$xxInstalled) and $this->config->global->flow == 'full')
{
$remind .= '<h4>' . $this->lang->im->zentaoClient . '</h4>';
$remind .= '<p>' . $this->lang->im->xxClientConfirm . '</p>';
$this->loadModel('setting')->setItem("system.common.xxclient.{$account}installed", 1);
}
elseif(!isset($this->config->xxserver->noticed) and $this->app->user->admin and $this->config->global->flow == 'full' and $this->config->$module->block->initVersion >= '2')
{
$remind .= '<h4>' . $this->lang->im->zentaoClient . '</h4>';
$remind .= '<p>' . $this->lang->im->xxServerConfirm . '</p>';
$this->loadModel('setting')->setItem("system.common.xxserver.noticed", 1);
}
return $remind;
}
@@ -24,9 +24,9 @@ class setting extends control
if(empty($setting->sslkey)) $errors['sslkey'] = $this->lang->im->errorSSLKey;
}
if($setting->turnon and strpos($setting->server, '127.0.0.1') !== false) $errors[] = $this->lang->im->xxdServerError;
if(strpos($setting->server, 'https://') !== 0 and strpos($setting->server, 'http://') !== 0) $errors[] = $this->lang->im->xxdSchemeError;
if(empty($setting->server)) $errors[] = $this->lang->im->xxdServerEmpty;
if($setting->turnon and strpos($setting->server, '127.0.0.1') !== false) $errors['server'] = $this->lang->im->xxdServerError;
if(strpos($setting->server, 'https://') !== 0 and strpos($setting->server, 'http://') !== 0) $errors['server'] = $this->lang->im->xxdSchemeError;
if(empty($setting->server)) $errors['server'] = $this->lang->im->xxdServerEmpty;
if($errors) $this->send(array('result' => 'fail', 'message' => $errors));