This commit is contained in:
reneeteng
2019-01-31 13:48:24 +08:00
104 changed files with 1815 additions and 663 deletions
+6 -1
View File
@@ -63,11 +63,13 @@ zentaoxx:
cp -r xuanxuan/config/* zentaoxx/config/
cp -r xuanxuan/module/* zentaoxx/module/
cp -r xuanxuan/www/* zentaoxx/www/
mv zentaoxx/www/xuanxuan.php zentaoxx/www/x.php
sed -i 's/site,//' zentaoxx/module/chat/model.php
sed -i 's/admin, g/g/' zentaoxx/module/chat/model.php
sed -i '/password = md5/d' zentaoxx/module/chat/control.php
sed -i '/getSignedTime/d' zentaoxx/module/chat/control.php
sed -i 's/tree/dept/' zentaoxx/module/chat/control.php
sed -i 's/tree/dept/' zentaoxx/module/chat/model.php
sed -i "s/, 'sys'//" zentaoxx/module/chat/control.php
sed -i 's/system.sys/system/' zentaoxx/module/chat/control.php
sed -i 's/&app=sys//' zentaoxx/module/chat/control.php
@@ -77,6 +79,8 @@ zentaoxx:
sed -i 's/sys_user/zt_user/' zentaoxx/db/*.sql
sed -i 's/sys_file/zt_file/' zentaoxx/db/*.sql
sed -i '/sys_entry/d' zentaoxx/db/*.sql
mkdir zentaoxx/tools; cp tools/cn2tw.php zentaoxx/tools; cd zentaoxx/tools; php cn2tw.php
rm -rf zentaopms/tools
zip -rqm -9 zentaoxx.$(VERSION).zip zentaoxx/*
rm -rf xuan.zip xuan zentaoxx
package:
@@ -90,7 +94,8 @@ package:
if [ ! -d "zentaopms/config/ext" ]; then mkdir zentaopms/config/ext; fi
for module in `ls zentaopms/module/`; do if [ ! -d "zentaopms/module/$$module/ext" ]; then mkdir zentaopms/module/$$module/ext; fi done
find zentaopms/ -name ext |xargs chmod -R 777
tools/cn2tw.php
mkdir zentaopms/tools; cp tools/cn2tw.php zentaopms/tools; cd zentaopms/tools; php cn2tw.php
rm -rf zentaopms/tools
pms:
make common
make zentaoxx
+1 -1
View File
@@ -1 +1 @@
11.1.stable
11.2.stable
+1 -1
View File
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
if(!function_exists('getWebRoot')){function getWebRoot(){}}
/* 基本设置。Basic settings. */
$config->version = '11.1'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->version = '11.2'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP.
$config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time.
$config->timezone = 'Asia/Shanghai'; // 时区设置。 The time zone setting, for more see http://www.php.net/manual/en/timezones.php.
+955
View File
@@ -0,0 +1,955 @@
DROP TABLE IF EXISTS `zt_action`;
CREATE TABLE `zt_action` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`objectType` varchar(30) NOT NULL DEFAULT '',
`objectID` mediumint(8) unsigned NOT NULL DEFAULT '0',
`product` varchar(255) NOT NULL,
`project` mediumint(9) NOT NULL,
`actor` varchar(30) NOT NULL DEFAULT '',
`action` varchar(30) NOT NULL DEFAULT '',
`date` datetime NOT NULL,
`comment` text NOT NULL,
`extra` text NOT NULL,
`read` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `date` (`date`),
KEY `actor` (`actor`),
KEY `project` (`project`),
KEY `objectID` (`objectID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_block`;
CREATE TABLE `zt_block` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`account` char(30) NOT NULL,
`module` varchar(20) NOT NULL,
`title` varchar(100) NOT NULL,
`source` varchar(20) NOT NULL,
`block` varchar(20) NOT NULL,
`params` text NOT NULL,
`order` tinyint(3) unsigned NOT NULL DEFAULT '0',
`grid` tinyint(3) unsigned NOT NULL DEFAULT '0',
`height` smallint(5) unsigned NOT NULL DEFAULT '0',
`hidden` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `accountModuleOrder` (`account`,`module`,`order`),
KEY `account` (`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_branch`;
CREATE TABLE `zt_branch` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`order` smallint(5) unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_bug`;
CREATE TABLE `zt_bug` (
`id` mediumint(8) NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` mediumint(8) unsigned NOT NULL DEFAULT '0',
`project` mediumint(8) unsigned NOT NULL DEFAULT '0',
`plan` mediumint(8) unsigned NOT NULL DEFAULT '0',
`story` mediumint(8) unsigned NOT NULL DEFAULT '0',
`storyVersion` smallint(6) NOT NULL DEFAULT '1',
`task` mediumint(8) unsigned NOT NULL DEFAULT '0',
`toTask` mediumint(8) unsigned NOT NULL DEFAULT '0',
`toStory` mediumint(8) NOT NULL DEFAULT '0',
`title` varchar(255) NOT NULL,
`keywords` varchar(255) NOT NULL,
`severity` tinyint(4) NOT NULL DEFAULT '0',
`pri` tinyint(3) unsigned NOT NULL,
`type` varchar(30) NOT NULL DEFAULT '',
`os` varchar(30) NOT NULL DEFAULT '',
`browser` varchar(30) NOT NULL DEFAULT '',
`hardware` varchar(30) NOT NULL,
`found` varchar(30) NOT NULL DEFAULT '',
`steps` text NOT NULL,
`status` enum('active','resolved','closed') NOT NULL DEFAULT 'active',
`color` char(7) NOT NULL,
`confirmed` tinyint(1) NOT NULL DEFAULT '0',
`activatedCount` smallint(6) NOT NULL,
`activatedDate` datetime NOT NULL,
`mailto` text,
`openedBy` varchar(30) NOT NULL DEFAULT '',
`openedDate` datetime NOT NULL,
`openedBuild` varchar(255) NOT NULL,
`assignedTo` varchar(30) NOT NULL DEFAULT '',
`assignedDate` datetime NOT NULL,
`deadline` date NOT NULL,
`resolvedBy` varchar(30) NOT NULL DEFAULT '',
`resolution` varchar(30) NOT NULL DEFAULT '',
`resolvedBuild` varchar(30) NOT NULL DEFAULT '',
`resolvedDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL DEFAULT '',
`closedDate` datetime NOT NULL,
`duplicateBug` mediumint(8) unsigned NOT NULL,
`linkBug` varchar(255) NOT NULL,
`case` mediumint(8) unsigned NOT NULL,
`caseVersion` smallint(6) NOT NULL DEFAULT '1',
`result` mediumint(8) unsigned NOT NULL,
`testtask` mediumint(8) unsigned NOT NULL,
`lastEditedBy` varchar(30) NOT NULL DEFAULT '',
`lastEditedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `project` (`project`),
KEY `status` (`status`),
KEY `plan` (`plan`),
KEY `story` (`story`),
KEY `case` (`case`),
KEY `assignedTo` (`assignedTo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_build`;
CREATE TABLE `zt_build` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`project` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` char(150) NOT NULL,
`scmPath` char(255) NOT NULL,
`filePath` char(255) NOT NULL,
`date` date NOT NULL,
`stories` text NOT NULL,
`bugs` text NOT NULL,
`builder` char(30) NOT NULL DEFAULT '',
`desc` text NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `project` (`project`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_burn`;
CREATE TABLE `zt_burn` (
`project` mediumint(8) unsigned NOT NULL,
`date` date NOT NULL,
`estimate` float NOT NULL,
`left` float NOT NULL,
`consumed` float NOT NULL,
PRIMARY KEY (`project`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_case`;
CREATE TABLE `zt_case` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`lib` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` mediumint(8) unsigned NOT NULL DEFAULT '0',
`path` mediumint(8) unsigned NOT NULL DEFAULT '0',
`story` mediumint(30) unsigned NOT NULL DEFAULT '0',
`storyVersion` smallint(6) NOT NULL DEFAULT '1',
`title` varchar(255) NOT NULL,
`precondition` text NOT NULL,
`keywords` varchar(255) NOT NULL,
`pri` tinyint(3) unsigned NOT NULL DEFAULT '3',
`type` char(30) NOT NULL DEFAULT '1',
`stage` varchar(255) NOT NULL,
`howRun` varchar(30) NOT NULL,
`scriptedBy` varchar(30) NOT NULL,
`scriptedDate` date NOT NULL,
`scriptStatus` varchar(30) NOT NULL,
`scriptLocation` varchar(255) NOT NULL,
`status` char(30) NOT NULL DEFAULT '1',
`color` char(7) NOT NULL,
`frequency` enum('1','2','3') NOT NULL DEFAULT '1',
`order` tinyint(30) unsigned NOT NULL DEFAULT '0',
`openedBy` char(30) NOT NULL DEFAULT '',
`openedDate` datetime NOT NULL,
`reviewedBy` varchar(255) NOT NULL,
`reviewedDate` date NOT NULL,
`lastEditedBy` char(30) NOT NULL DEFAULT '',
`lastEditedDate` datetime NOT NULL,
`version` tinyint(3) unsigned NOT NULL DEFAULT '0',
`linkCase` varchar(255) NOT NULL,
`fromBug` mediumint(8) unsigned NOT NULL,
`fromCaseID` mediumint(8) unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
`lastRunner` varchar(30) NOT NULL,
`lastRunDate` datetime NOT NULL,
`lastRunResult` char(30) NOT NULL,
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `story` (`story`),
KEY `module` (`module`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_casestep`;
CREATE TABLE `zt_casestep` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`parent` mediumint(8) unsigned NOT NULL DEFAULT '0',
`case` mediumint(8) unsigned NOT NULL DEFAULT '0',
`version` smallint(3) unsigned NOT NULL DEFAULT '0',
`type` varchar(10) NOT NULL DEFAULT 'step',
`desc` text NOT NULL,
`expect` text NOT NULL,
PRIMARY KEY (`id`),
KEY `case` (`case`),
KEY `version` (`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_company`;
CREATE TABLE `zt_company` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` char(120) DEFAULT NULL,
`phone` char(20) DEFAULT NULL,
`fax` char(20) DEFAULT NULL,
`address` char(120) DEFAULT NULL,
`zipcode` char(10) DEFAULT NULL,
`website` char(120) DEFAULT NULL,
`backyard` char(120) DEFAULT NULL,
`guest` enum('1','0') NOT NULL DEFAULT '0',
`admins` char(255) DEFAULT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_config`;
CREATE TABLE `zt_config` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`owner` char(30) NOT NULL DEFAULT '',
`module` varchar(30) NOT NULL,
`section` char(30) NOT NULL DEFAULT '',
`key` char(30) NOT NULL DEFAULT '',
`value` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique` (`owner`,`module`,`section`,`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_cron`;
CREATE TABLE `zt_cron` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`m` varchar(20) NOT NULL,
`h` varchar(20) NOT NULL,
`dom` varchar(20) NOT NULL,
`mon` varchar(20) NOT NULL,
`dow` varchar(20) NOT NULL,
`command` text NOT NULL,
`remark` varchar(255) NOT NULL,
`type` varchar(20) NOT NULL,
`buildin` tinyint(1) NOT NULL DEFAULT '0',
`status` varchar(20) NOT NULL,
`lastTime` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `lastTime` (`lastTime`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_dept`;
CREATE TABLE `zt_dept` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` char(60) NOT NULL,
`parent` mediumint(8) unsigned NOT NULL DEFAULT '0',
`path` char(255) NOT NULL DEFAULT '',
`grade` tinyint(3) unsigned NOT NULL DEFAULT '0',
`order` tinyint(3) unsigned NOT NULL DEFAULT '0',
`position` char(30) NOT NULL DEFAULT '',
`function` char(255) NOT NULL DEFAULT '',
`manager` char(30) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
KEY `path` (`path`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_doc`;
CREATE TABLE `zt_doc` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`project` mediumint(8) unsigned NOT NULL,
`lib` varchar(30) NOT NULL,
`module` varchar(30) NOT NULL,
`title` varchar(255) NOT NULL,
`keywords` varchar(255) NOT NULL,
`type` varchar(30) NOT NULL,
`views` smallint(5) unsigned NOT NULL,
`collector` text NOT NULL,
`addedBy` varchar(30) NOT NULL,
`addedDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`acl` varchar(10) NOT NULL DEFAULT 'open',
`groups` varchar(255) NOT NULL,
`users` text NOT NULL,
`version` smallint(5) unsigned NOT NULL DEFAULT '1',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `project` (`project`),
KEY `lib` (`lib`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_doccontent`;
CREATE TABLE `zt_doccontent` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`doc` mediumint(8) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`digest` varchar(255) NOT NULL,
`content` text NOT NULL,
`files` text NOT NULL,
`type` varchar(10) NOT NULL,
`version` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `doc_version` (`doc`,`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_doclib`;
CREATE TABLE `zt_doclib` (
`id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`type` varchar(30) NOT NULL,
`product` mediumint(8) unsigned NOT NULL,
`project` mediumint(8) unsigned NOT NULL,
`name` varchar(60) NOT NULL,
`acl` varchar(10) NOT NULL DEFAULT 'open',
`groups` varchar(255) NOT NULL,
`users` text NOT NULL,
`main` enum('0','1') NOT NULL DEFAULT '0',
`collector` text NOT NULL,
`order` tinyint(5) unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `project` (`project`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_effort`;
CREATE TABLE `zt_effort` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`user` char(30) NOT NULL DEFAULT '',
`todo` enum('1','0') NOT NULL DEFAULT '1',
`date` date NOT NULL,
`begin` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`end` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`type` enum('1','2','3') NOT NULL DEFAULT '1',
`idvalue` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` char(30) NOT NULL DEFAULT '',
`desc` char(255) NOT NULL DEFAULT '',
`status` enum('1','2','3') NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `user` (`user`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_entry`;
CREATE TABLE `zt_entry` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`account` varchar(30) NOT NULL DEFAULT '',
`code` varchar(20) NOT NULL,
`key` varchar(32) NOT NULL,
`ip` varchar(100) NOT NULL,
`desc` text NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_extension`;
CREATE TABLE `zt_extension` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(150) NOT NULL,
`code` varchar(30) NOT NULL,
`version` varchar(50) NOT NULL,
`author` varchar(100) NOT NULL,
`desc` text NOT NULL,
`license` text NOT NULL,
`type` varchar(20) NOT NULL DEFAULT 'extension',
`site` varchar(150) NOT NULL,
`zentaoCompatible` varchar(100) NOT NULL,
`installedTime` datetime NOT NULL,
`depends` varchar(100) NOT NULL,
`dirs` mediumtext NOT NULL,
`files` mediumtext NOT NULL,
`status` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `code` (`code`),
KEY `name` (`name`),
KEY `installedTime` (`installedTime`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_file`;
CREATE TABLE `zt_file` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`pathname` char(50) NOT NULL,
`title` char(255) NOT NULL,
`extension` char(30) NOT NULL,
`size` int(10) unsigned NOT NULL DEFAULT '0',
`objectType` char(30) NOT NULL,
`objectID` mediumint(9) NOT NULL,
`addedBy` char(30) NOT NULL DEFAULT '',
`addedDate` datetime NOT NULL,
`downloads` mediumint(8) unsigned NOT NULL DEFAULT '0',
`extra` varchar(255) NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `objectType` (`objectType`),
KEY `objectID` (`objectID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_group`;
CREATE TABLE `zt_group` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` char(30) NOT NULL,
`role` char(30) NOT NULL DEFAULT '',
`desc` char(255) NOT NULL DEFAULT '',
`acl` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_grouppriv`;
CREATE TABLE `zt_grouppriv` (
`group` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` char(30) NOT NULL DEFAULT '',
`method` char(30) NOT NULL DEFAULT '',
UNIQUE KEY `group` (`group`,`module`,`method`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_history`;
CREATE TABLE `zt_history` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`action` mediumint(8) unsigned NOT NULL DEFAULT '0',
`field` varchar(30) NOT NULL DEFAULT '',
`old` text NOT NULL,
`new` text NOT NULL,
`diff` mediumtext NOT NULL,
PRIMARY KEY (`id`),
KEY `action` (`action`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_lang`;
CREATE TABLE `zt_lang` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`lang` varchar(30) NOT NULL,
`module` varchar(30) NOT NULL,
`section` varchar(30) NOT NULL,
`key` varchar(60) NOT NULL,
`value` text NOT NULL,
`system` enum('0','1') NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
UNIQUE KEY `lang` (`lang`,`module`,`section`,`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_log`;
CREATE TABLE `zt_log` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`objectType` varchar(30) NOT NULL,
`objectID` mediumint(8) unsigned NOT NULL,
`action` mediumint(8) unsigned NOT NULL,
`date` datetime NOT NULL,
`url` varchar(255) NOT NULL,
`contentType` varchar(30) NOT NULL,
`data` text NOT NULL,
`result` text NOT NULL,
PRIMARY KEY (`id`),
KEY `objectType` (`objectType`),
KEY `obejctID` (`objectID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_module`;
CREATE TABLE `zt_module` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`root` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` char(60) NOT NULL DEFAULT '',
`parent` mediumint(8) unsigned NOT NULL DEFAULT '0',
`path` char(255) NOT NULL DEFAULT '',
`grade` tinyint(3) unsigned NOT NULL DEFAULT '0',
`order` smallint(5) unsigned NOT NULL DEFAULT '0',
`type` char(30) NOT NULL,
`owner` varchar(30) NOT NULL,
`collector` text NOT NULL,
`short` varchar(30) NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `root` (`root`),
KEY `type` (`type`),
KEY `path` (`path`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_notify`;
CREATE TABLE `zt_notify` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`objectType` varchar(50) NOT NULL,
`objectID` mediumint(8) unsigned NOT NULL,
`action` mediumint(9) NOT NULL,
`toList` varchar(255) NOT NULL,
`ccList` text NOT NULL,
`subject` varchar(255) NOT NULL,
`data` text NOT NULL,
`createdBy` char(30) NOT NULL,
`createdDate` datetime NOT NULL,
`sendTime` datetime NOT NULL,
`status` varchar(10) NOT NULL DEFAULT 'wait',
`failReason` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_product`;
CREATE TABLE `zt_product` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(90) NOT NULL,
`code` varchar(45) NOT NULL,
`line` mediumint(8) NOT NULL,
`type` varchar(30) NOT NULL DEFAULT 'normal',
`status` varchar(30) NOT NULL DEFAULT '',
`desc` text NOT NULL,
`PO` varchar(30) NOT NULL,
`QD` varchar(30) NOT NULL,
`RD` varchar(30) NOT NULL,
`acl` enum('open','private','custom') NOT NULL DEFAULT 'open',
`whitelist` text NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`createdVersion` varchar(20) NOT NULL,
`order` mediumint(8) unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `order` (`order`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_productplan`;
CREATE TABLE `zt_productplan` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`branch` mediumint(8) unsigned NOT NULL,
`title` varchar(90) NOT NULL,
`desc` text NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
`order` text NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `end` (`end`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_project`;
CREATE TABLE `zt_project` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`isCat` enum('1','0') NOT NULL DEFAULT '0',
`catID` mediumint(8) unsigned NOT NULL,
`type` varchar(20) NOT NULL DEFAULT 'sprint',
`parent` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` varchar(90) NOT NULL,
`code` varchar(45) NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
`days` smallint(5) unsigned NOT NULL,
`status` varchar(10) NOT NULL,
`statge` enum('1','2','3','4','5') NOT NULL DEFAULT '1',
`pri` enum('1','2','3','4') NOT NULL DEFAULT '1',
`desc` text NOT NULL,
`openedBy` varchar(30) NOT NULL DEFAULT '',
`openedDate` datetime NOT NULL,
`openedVersion` varchar(20) NOT NULL,
`closedBy` varchar(30) NOT NULL DEFAULT '',
`closedDate` datetime NOT NULL,
`canceledBy` varchar(30) NOT NULL DEFAULT '',
`canceledDate` datetime NOT NULL,
`PO` varchar(30) NOT NULL DEFAULT '',
`PM` varchar(30) NOT NULL DEFAULT '',
`QD` varchar(30) NOT NULL DEFAULT '',
`RD` varchar(30) NOT NULL DEFAULT '',
`team` varchar(90) NOT NULL,
`acl` enum('open','private','custom') NOT NULL DEFAULT 'open',
`whitelist` text NOT NULL,
`order` mediumint(8) unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
KEY `begin` (`begin`),
KEY `end` (`end`),
KEY `status` (`status`),
KEY `order` (`order`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_projectproduct`;
CREATE TABLE `zt_projectproduct` (
`project` mediumint(8) unsigned NOT NULL,
`product` mediumint(8) unsigned NOT NULL,
`branch` mediumint(8) unsigned NOT NULL,
`plan` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`project`,`product`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_projectstory`;
CREATE TABLE `zt_projectstory` (
`project` mediumint(8) unsigned NOT NULL DEFAULT '0',
`product` mediumint(8) unsigned NOT NULL,
`story` mediumint(8) unsigned NOT NULL DEFAULT '0',
`version` smallint(6) NOT NULL DEFAULT '1',
`order` smallint(6) unsigned NOT NULL,
UNIQUE KEY `project` (`project`,`story`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_release`;
CREATE TABLE `zt_release` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`build` mediumint(8) unsigned NOT NULL,
`name` varchar(255) NOT NULL DEFAULT '',
`marker` enum('0','1') NOT NULL DEFAULT '0',
`date` date NOT NULL,
`stories` text NOT NULL,
`bugs` text NOT NULL,
`leftBugs` text NOT NULL,
`desc` text NOT NULL,
`status` varchar(20) NOT NULL DEFAULT 'normal',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `build` (`build`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_score`;
CREATE TABLE `zt_score` (
`id` bigint(12) unsigned NOT NULL AUTO_INCREMENT,
`account` varchar(30) NOT NULL,
`module` varchar(30) NOT NULL DEFAULT '',
`method` varchar(30) NOT NULL,
`desc` varchar(250) NOT NULL DEFAULT '',
`before` int(11) NOT NULL DEFAULT '0',
`score` int(11) NOT NULL DEFAULT '0',
`after` int(11) NOT NULL DEFAULT '0',
`time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `account` (`account`),
KEY `model` (`module`),
KEY `method` (`method`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_story`;
CREATE TABLE `zt_story` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` mediumint(8) unsigned NOT NULL DEFAULT '0',
`plan` text,
`source` varchar(20) NOT NULL,
`sourceNote` varchar(255) NOT NULL,
`fromBug` mediumint(8) unsigned NOT NULL DEFAULT '0',
`title` varchar(255) NOT NULL,
`keywords` varchar(255) NOT NULL,
`type` varchar(30) NOT NULL DEFAULT '',
`pri` tinyint(3) unsigned NOT NULL DEFAULT '3',
`estimate` float unsigned NOT NULL,
`status` enum('','changed','active','draft','closed') NOT NULL DEFAULT '',
`color` char(7) NOT NULL,
`stage` enum('','wait','planned','projected','developing','developed','testing','tested','verified','released','closed') NOT NULL DEFAULT 'wait',
`mailto` text,
`openedBy` varchar(30) NOT NULL DEFAULT '',
`openedDate` datetime NOT NULL,
`assignedTo` varchar(30) NOT NULL DEFAULT '',
`assignedDate` datetime NOT NULL,
`lastEditedBy` varchar(30) NOT NULL DEFAULT '',
`lastEditedDate` datetime NOT NULL,
`reviewedBy` varchar(255) NOT NULL,
`reviewedDate` date NOT NULL,
`closedBy` varchar(30) NOT NULL DEFAULT '',
`closedDate` datetime NOT NULL,
`closedReason` varchar(30) NOT NULL,
`toBug` mediumint(9) NOT NULL,
`childStories` varchar(255) NOT NULL,
`linkStories` varchar(255) NOT NULL,
`duplicateStory` mediumint(8) unsigned NOT NULL,
`version` smallint(6) NOT NULL DEFAULT '1',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `status` (`status`),
KEY `assignedTo` (`assignedTo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_storyspec`;
CREATE TABLE `zt_storyspec` (
`story` mediumint(9) NOT NULL,
`version` smallint(6) NOT NULL,
`title` varchar(255) NOT NULL,
`spec` text NOT NULL,
`verify` text NOT NULL,
UNIQUE KEY `story` (`story`,`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_storystage`;
CREATE TABLE `zt_storystage` (
`story` mediumint(8) unsigned NOT NULL,
`branch` mediumint(8) unsigned NOT NULL,
`stage` varchar(50) NOT NULL,
KEY `story` (`story`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_suitecase`;
CREATE TABLE `zt_suitecase` (
`suite` mediumint(8) unsigned NOT NULL,
`product` mediumint(8) unsigned NOT NULL,
`case` mediumint(8) unsigned NOT NULL,
`version` smallint(5) unsigned NOT NULL,
UNIQUE KEY `suitecase` (`suite`,`case`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_task`;
CREATE TABLE `zt_task` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`parent` mediumint(8) NOT NULL DEFAULT '0',
`project` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` mediumint(8) unsigned NOT NULL DEFAULT '0',
`story` mediumint(8) unsigned NOT NULL DEFAULT '0',
`storyVersion` smallint(6) NOT NULL DEFAULT '1',
`fromBug` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`type` varchar(20) NOT NULL,
`pri` tinyint(3) unsigned NOT NULL DEFAULT '0',
`estimate` float unsigned NOT NULL,
`consumed` float unsigned NOT NULL,
`left` float unsigned NOT NULL,
`deadline` date NOT NULL,
`status` enum('wait','doing','done','pause','cancel','closed') NOT NULL DEFAULT 'wait',
`color` char(7) NOT NULL,
`mailto` text,
`desc` text NOT NULL,
`openedBy` varchar(30) NOT NULL,
`openedDate` datetime NOT NULL,
`assignedTo` varchar(30) NOT NULL,
`assignedDate` datetime NOT NULL,
`estStarted` date NOT NULL,
`realStarted` date NOT NULL,
`finishedBy` varchar(30) NOT NULL,
`finishedDate` datetime NOT NULL,
`finishedList` text NOT NULL,
`canceledBy` varchar(30) NOT NULL,
`canceledDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL,
`closedDate` datetime NOT NULL,
`closedReason` varchar(30) NOT NULL,
`lastEditedBy` varchar(30) NOT NULL,
`lastEditedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `project` (`project`),
KEY `story` (`story`),
KEY `assignedTo` (`assignedTo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_taskestimate`;
CREATE TABLE `zt_taskestimate` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`task` mediumint(8) unsigned NOT NULL DEFAULT '0',
`date` date NOT NULL,
`left` float unsigned NOT NULL DEFAULT '0',
`consumed` float unsigned NOT NULL,
`account` char(30) NOT NULL DEFAULT '',
`work` text,
PRIMARY KEY (`id`),
KEY `task` (`task`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_team`;
CREATE TABLE `zt_team` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`root` mediumint(8) unsigned NOT NULL DEFAULT '0',
`type` enum('project','task') NOT NULL DEFAULT 'project',
`account` char(30) NOT NULL DEFAULT '',
`role` char(30) NOT NULL DEFAULT '',
`limited` char(8) NOT NULL DEFAULT 'no',
`join` date NOT NULL DEFAULT '0000-00-00',
`days` smallint(5) unsigned NOT NULL,
`hours` float(2,1) unsigned NOT NULL DEFAULT '0.0',
`estimate` decimal(12,2) unsigned NOT NULL DEFAULT '0.00',
`consumed` decimal(12,2) unsigned NOT NULL DEFAULT '0.00',
`left` decimal(12,2) unsigned NOT NULL DEFAULT '0.00',
`order` tinyint(3) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `team` (`root`,`type`,`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_testreport`;
CREATE TABLE `zt_testreport` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`project` mediumint(8) unsigned NOT NULL,
`tasks` varchar(255) NOT NULL,
`builds` varchar(255) NOT NULL,
`title` varchar(255) NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
`owner` char(30) NOT NULL,
`members` text NOT NULL,
`stories` text NOT NULL,
`bugs` text NOT NULL,
`cases` text NOT NULL,
`report` text NOT NULL,
`objectType` varchar(20) NOT NULL,
`objectID` mediumint(8) unsigned NOT NULL,
`createdBy` char(30) NOT NULL,
`createdDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_testresult`;
CREATE TABLE `zt_testresult` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`run` mediumint(8) unsigned NOT NULL,
`case` mediumint(8) unsigned NOT NULL,
`version` smallint(5) unsigned NOT NULL,
`caseResult` char(30) NOT NULL,
`stepResults` text NOT NULL,
`lastRunner` varchar(30) NOT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `case` (`case`),
KEY `version` (`version`),
KEY `run` (`run`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_testrun`;
CREATE TABLE `zt_testrun` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`task` mediumint(8) unsigned NOT NULL DEFAULT '0',
`case` mediumint(8) unsigned NOT NULL DEFAULT '0',
`version` tinyint(3) unsigned NOT NULL DEFAULT '0',
`assignedTo` char(30) NOT NULL DEFAULT '',
`lastRunner` varchar(30) NOT NULL,
`lastRunDate` datetime NOT NULL,
`lastRunResult` char(30) NOT NULL,
`status` char(30) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `task` (`task`,`case`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_testsuite`;
CREATE TABLE `zt_testsuite` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`desc` text NOT NULL,
`type` varchar(20) NOT NULL,
`addedBy` char(30) NOT NULL,
`addedDate` datetime NOT NULL,
`lastEditedBy` char(30) NOT NULL,
`lastEditedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL,
PRIMARY KEY (`id`),
KEY `product` (`product`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_testtask`;
CREATE TABLE `zt_testtask` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` char(90) NOT NULL,
`product` mediumint(8) unsigned NOT NULL,
`project` mediumint(8) unsigned NOT NULL DEFAULT '0',
`build` char(30) NOT NULL,
`owner` varchar(30) NOT NULL,
`pri` tinyint(3) unsigned NOT NULL DEFAULT '0',
`begin` date NOT NULL,
`end` date NOT NULL,
`mailto` text,
`desc` text NOT NULL,
`report` text NOT NULL,
`status` enum('blocked','doing','wait','done') NOT NULL DEFAULT 'wait',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `build` (`build`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_todo`;
CREATE TABLE `zt_todo` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`account` char(30) NOT NULL,
`date` date NOT NULL,
`begin` smallint(4) unsigned zerofill NOT NULL,
`end` smallint(4) unsigned zerofill NOT NULL,
`type` char(10) NOT NULL,
`cycle` tinyint(3) unsigned NOT NULL DEFAULT '0',
`idvalue` mediumint(8) unsigned NOT NULL DEFAULT '0',
`pri` tinyint(3) unsigned NOT NULL,
`name` char(150) NOT NULL,
`desc` text NOT NULL,
`status` enum('wait','doing','done','closed') NOT NULL DEFAULT 'wait',
`private` tinyint(1) NOT NULL,
`config` varchar(255) NOT NULL,
`assignedTo` varchar(30) NOT NULL DEFAULT '',
`assignedBy` varchar(30) NOT NULL DEFAULT '',
`assignedDate` datetime NOT NULL,
`finishedBy` varchar(30) NOT NULL DEFAULT '',
`finishedDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL DEFAULT '',
`closedDate` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `account` (`account`),
KEY `assignedTo` (`assignedTo`),
KEY `finishedBy` (`finishedBy`),
KEY `date` (`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_user`;
CREATE TABLE `zt_user` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`dept` mediumint(8) unsigned NOT NULL DEFAULT '0',
`account` char(30) NOT NULL DEFAULT '',
`password` char(32) NOT NULL DEFAULT '',
`role` char(10) NOT NULL DEFAULT '',
`realname` varchar(100) NOT NULL DEFAULT '',
`nickname` char(60) NOT NULL DEFAULT '',
`commiter` varchar(100) NOT NULL,
`avatar` char(30) NOT NULL DEFAULT '',
`birthday` date NOT NULL DEFAULT '0000-00-00',
`gender` enum('f','m') NOT NULL DEFAULT 'f',
`email` char(90) NOT NULL DEFAULT '',
`skype` char(90) NOT NULL DEFAULT '',
`qq` char(20) NOT NULL DEFAULT '',
`yahoo` char(90) NOT NULL DEFAULT '',
`gtalk` char(90) NOT NULL DEFAULT '',
`wangwang` char(90) NOT NULL DEFAULT '',
`mobile` char(11) NOT NULL DEFAULT '',
`phone` char(20) NOT NULL DEFAULT '',
`address` char(120) NOT NULL DEFAULT '',
`zipcode` char(10) NOT NULL DEFAULT '',
`join` date NOT NULL DEFAULT '0000-00-00',
`visits` mediumint(8) unsigned NOT NULL DEFAULT '0',
`ip` char(15) NOT NULL DEFAULT '',
`last` int(10) unsigned NOT NULL DEFAULT '0',
`fails` tinyint(5) NOT NULL DEFAULT '0',
`locked` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`ranzhi` char(30) NOT NULL DEFAULT '',
`score` int(11) NOT NULL DEFAULT '0',
`scoreLevel` int(11) NOT NULL DEFAULT '0',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `account` (`account`),
KEY `dept` (`dept`),
KEY `email` (`email`),
KEY `commiter` (`commiter`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_usercontact`;
CREATE TABLE `zt_usercontact` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`account` char(30) NOT NULL,
`listName` varchar(60) NOT NULL,
`userList` text NOT NULL,
PRIMARY KEY (`id`),
KEY `account` (`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_usergroup`;
CREATE TABLE `zt_usergroup` (
`account` char(30) NOT NULL DEFAULT '',
`group` mediumint(8) unsigned NOT NULL DEFAULT '0',
UNIQUE KEY `account` (`account`,`group`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_userquery`;
CREATE TABLE `zt_userquery` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`account` char(30) NOT NULL,
`module` varchar(30) NOT NULL,
`title` varchar(90) NOT NULL,
`form` text NOT NULL,
`sql` text NOT NULL,
`shortcut` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `account` (`account`),
KEY `module` (`module`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_usertpl`;
CREATE TABLE `zt_usertpl` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`account` char(30) NOT NULL,
`type` char(30) NOT NULL,
`title` varchar(150) NOT NULL,
`content` text NOT NULL,
`public` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `account` (`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_userview`;
CREATE TABLE `zt_userview` (
`account` char(30) NOT NULL,
`products` mediumtext NOT NULL,
`projects` mediumtext NOT NULL,
UNIQUE KEY `account` (`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `zt_webhook`;
CREATE TABLE `zt_webhook` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`type` varchar(10) NOT NULL DEFAULT 'default',
`name` varchar(50) NOT NULL,
`url` varchar(255) NOT NULL,
`domain` varchar(255) NOT NULL,
`contentType` varchar(30) NOT NULL DEFAULT 'application/json',
`sendType` enum('sync','async') NOT NULL DEFAULT 'sync',
`products` text NOT NULL,
`projects` text NOT NULL,
`params` varchar(100) NOT NULL,
`actions` text NOT NULL,
`desc` text NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+1 -1
View File
@@ -533,7 +533,7 @@ CREATE TABLE IF NOT EXISTS `zt_release` (
`product` mediumint(8) unsigned NOT NULL default '0',
`branch` mediumint(8) unsigned NOT NULL default '0',
`build` mediumint(8) unsigned NOT NULL,
`name` char(30) NOT NULL default '',
`name` varchar(255) NOT NULL default '',
`marker` enum('0','1') NOT NULL default '0',
`date` date NOT NULL,
`stories` text NOT NULL,
+63
View File
@@ -1,3 +1,66 @@
2019-01-29 11.2.stable
完成的需求
3553 集成喧喧2.4版本,国际版企业版集成喧喧2.4,国内和国际的版本升级程序要区分处理
3552 升级执行sql后需要进行数据库结构的检查
3542 通过配置的方式定义各个对象的创建和编辑接口需要传入的参数
3541 移除禅道里配置喧喧和下载xxd与xxd配置文件的相关代码,不同的地方通过扩展来处理
3540 调整需求和任务,bug优先级的样式
3537 增强用户录入操作的提示
3531 dockerfile启动命令中增加修复目录权限的功能
3530 在创建需求、bug时产品下拉菜单保持和导航里面一致
3529 发布列表页面增加里程碑的显示
3527 zbox启动的时候自动修复目录权限
3526 内嵌禅道手册都是用https协议的
3460 计划关联bug的时候将已经转为任务的也计算在内
3060 增加升级日志功能
修复的Bug
2008 文档收藏按钮无效
2061 用户密码包含#时,配置单点登录提示密码错误
2234 自定义用户职位后,项目团队中添加成员时角色不会带出自定义添加的职位
2235 自定义已有用户职位,项目团队中添加成员时角色还是显示原来职位
2246 edge浏览器下载附件的名称乱码
2314 需求分组统计错误
2334 大文件备份异常
2347 新建用例查看需求页面无法返回
2354 受限权限分组用户可以在列表对数据进行指派
2355 编辑部门的负责人支持检索
2359 没有备注权限在待办中还可以看到备注按钮
2361 客户端创建需求提示错误
2363 批量创建用例所属模块修改后不能选择相应模块下的需求
2364 项目没有关联产品下需求,在维护项目模块时可以显示产品下模块
2366 禅道的客户端修改密码后不能登录
2367 计划需求列表移除需求之后,底部的统计结果并没有重新计算
2368 弹窗录入信息后右上角的差号消失
2369 批量分解需求时会把html实体转义
2370 文档库访问权限设置后再清空保存不生效
2371 关闭的项目可以在搜索栏访问
2373 我的地盘总览bug数和我的地盘bug列表数不一致
2374 员工负载表对多人任务统计不准确
2375 客户端上访问禅道的不能正常添加用户
2376 在已有模块中插入模块保存后新模块会排序到最后
2377 批量编辑用户不能修改职位为空
2378 执行用例结果选择失败不会转到下个用例
2379 客户端在浏览器窗口中打开链接导致无限循环请求
2380 测试用例下不应该显示指派分组
2382 客户端修改禅道用户信息无法保存
2383 下载客户端弹窗页面需要优化
2384 自定义导航公共无法保存
2386 客户端服务器设置页面,提示文案修改
2389 自定义列出删除用户无法保存
2390 移动文档库分类文档不能同步移动
2391 多分支多平台产品提bug提用例所属模块问题
2392 地盘区块中的项目数量与地盘项目列表中的数量不一致
2393 IE11富文本编辑器兼容问题
2394 动态如果没有权限查看就全都不显示
2396 计划任务备份报错
2397 禅道升级功能优化
2398 组织权限用户列表样式重叠
2400 自定义导航栏问题
2402 没有文档的访问权限也可以在附件库中下载文档中的附件
2403 创建项目页面导航栏显示的是测试
2404 修改集成客户端中的禅道服务器,发信配置中的禅道域名会同步修改
2406 需求页面建用例不能同步
2019-01-04 11.1.stable
解决的Bug
2362 后台自定义存在注入问题
+9 -1
View File
@@ -980,7 +980,15 @@ EOT;
static public function reload($window = 'self')
{
$js = self::start();
$js .= "$window.location.reload(true);\n";
// See bug #2379 http://pms.zentao.net/bug-view-2379.html
if($window !== 'self' && $window !== 'window')
{
$js .= "if($window !== window) $window.location.reload(true);\n";
}
else
{
$js .= "$window.location.reload(true);\n";
}
$js .= self::end();
return $js;
}
+2 -1
View File
@@ -1836,7 +1836,8 @@
$v_memory_limit = ini_get('memory_limit');
$v_memory_limit = trim($v_memory_limit);
$last = strtolower(substr($v_memory_limit, -1));
$v_memory_limit = (int)$v_memory_limit;
if($last == 'g')
//$v_memory_limit = $v_memory_limit*1024*1024*1024;
$v_memory_limit = $v_memory_limit*1073741824;
+7 -4
View File
@@ -750,7 +750,7 @@ class actionModel extends model
}
$objectNames['user'][0] = 'guest'; // Add guest account.
foreach($actions as $action)
foreach($actions as $i => $action)
{
/* Add name field to the actions. */
$action->objectName = isset($objectNames[$action->objectType][$action->objectID]) ? $objectNames[$action->objectType][$action->objectID] : '';
@@ -779,11 +779,14 @@ class actionModel extends model
{
list($objectLabel, $moduleName, $methodName, $vars) = explode('|', $action->objectLabel);
$action->objectLink = '';
if(common::hasPriv($moduleName, $methodName))
if(!common::hasPriv($moduleName, $methodName))
{
$action->objectLink = helper::createLink($moduleName, $methodName, sprintf($vars, $action->objectID));
if($action->objectType == 'user') $action->objectLink = helper::createLink($moduleName, $methodName, sprintf($vars, $action->actor));
unset($actions[$i]);
continue;
}
$action->objectLink = helper::createLink($moduleName, $methodName, sprintf($vars, $action->objectID));
if($action->objectType == 'user') $action->objectLink = helper::createLink($moduleName, $methodName, sprintf($vars, $action->actor));
$action->objectLabel = $objectLabel;
}
else
+7 -9
View File
@@ -30,6 +30,7 @@ class backup extends control
{
if(!is_writable($this->backupPath)) $this->view->error = sprintf($this->lang->backup->error->noWritable, $this->backupPath);
}
if(!is_writable($this->app->getTmpRoot())) $this->view->error = sprintf($this->lang->backup->error->noWritable, $this->app->getTmpRoot());
}
/**
@@ -81,7 +82,7 @@ class backup extends control
public function backup($reload = 'no')
{
if($reload == 'yes') session_write_close();
set_time_limit(7200);
set_time_limit(0);
$nozip = strpos($this->config->backup->setting, 'nozip') !== false;
$nofile = strpos($this->config->backup->setting, 'nofile') !== false;
$nosafe = strpos($this->config->backup->setting, 'nosafe') !== false;
@@ -147,7 +148,7 @@ class backup extends control
}
/* Delete expired backup. */
$backupFiles = glob("{$this->backupPath}*.php");
$backupFiles = glob("{$this->backupPath}*.*");
if(!empty($backupFiles))
{
$time = time();
@@ -179,7 +180,7 @@ class backup extends control
{
if($confirm == 'no') $this->send(array('result' => 'fail', 'message' => $this->lang->backup->confirmRestore));
set_time_limit(7200);
set_time_limit(0);
/* Restore database. */
if(file_exists("{$this->backupPath}{$fileName}.sql.php"))
@@ -373,24 +374,21 @@ class backup extends control
if($sqlFileName)
{
$fileSize = $this->backup->getBackupSize($sqlFileName);
$fileSize = $fileSize / 1024 >= 1024 ? round($fileSize / 1024 / 1024, 2) . 'MB' : round($fileSize / 1024, 2) . 'KB';
$message = sprintf($this->lang->backup->progressSQL, $fileSize);
$message = sprintf($this->lang->backup->progressSQL, $this->backup->processFileSize($fileSize));
}
$attachFileName = $this->backup->getBackupFile($fileName, 'file');
if($attachFileName)
{
$fileSize = $this->backup->getBackupSize($attachFileName);
$fileSize = $fileSize / 1024 >= 1024 ? round($fileSize / 1024 / 1024, 2) . 'MB' : round($fileSize / 1024, 2) . 'KB';
$message = sprintf($this->lang->backup->progressAttach, $fileSize);
$message = sprintf($this->lang->backup->progressAttach, $this->backup->processFileSize($fileSize));
}
$codeFileName = $this->backup->getBackupFile($fileName, 'code');
if($codeFileName)
{
$fileSize = $this->backup->getBackupSize($codeFileName);
$fileSize = $fileSize / 1024 >= 1024 ? round($fileSize / 1024 / 1024, 2) . 'MB' : round($fileSize / 1024, 2) . 'KB';
$message = sprintf($this->lang->backup->progressCode, $fileSize);
$message = sprintf($this->lang->backup->progressCode, $this->backup->processFileSize($fileSize));
}
die($message);
}
+27 -1
View File
@@ -283,7 +283,8 @@ class backupModel extends model
*/
public function getBackupPath()
{
return empty($this->config->backup->settingDir) ? $this->app->getTmpRoot() . 'backup' . DS : $this->config->backup->settingDir;
$backupPath = empty($this->config->backup->settingDir) ? $this->app->getTmpRoot() . 'backup' . DS : $this->config->backup->settingDir;
return rtrim(str_replace('\\', '/', $backupPath), '/') . '/';
}
/**
@@ -311,4 +312,29 @@ class backupModel extends model
return false;
}
/**
* Process filesize.
*
* @param int $fileSize
* @access public
* @return string
*/
public function processFileSize($fileSize)
{
$bit = 'KB';
$fileSize = round($fileSize / 1024, 2);
if($fileSize >= 1024)
{
$bit = 'MB';
$fileSize = round($fileSize / 1024, 2);
}
if($fileSize >= 1024)
{
$bit = 'GB';
$fileSize = round($fileSize / 1024, 2);
}
return $fileSize . $bit;
}
}
+5 -1
View File
@@ -158,7 +158,11 @@ class blockModel extends model
$data = array();
$data['tasks'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_TASK)->where('assignedTo')->eq($this->app->user->account)->andWhere('status')->ne('closed')->andWhere('deleted')->eq(0)->fetch('count');
$data['bugs'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_BUG)->where('assignedTo')->eq($this->app->user->account)->andWhere('deleted')->eq(0)->fetch('count');
$data['bugs'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_BUG)
->where('assignedTo')->eq($this->app->user->account)
->beginIF(!$this->app->user->admin)->andWhere('project')->in('0,' . $this->app->user->view->projects)->fi() //Fix bug #2373.
->andWhere('deleted')->eq(0)
->fetch('count');
$data['stories'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_STORY)->where('assignedTo')->eq($this->app->user->account)->andWhere('deleted')->eq(0)->fetch('count');
$data['projects'] = (int)$this->dao->select('count(*) AS count')->from(TABLE_PROJECT)
->where("(status='wait' or status='doing')")
+9 -1
View File
@@ -22,6 +22,7 @@ class bug extends control
public function __construct($moduleName = '', $methodName = '')
{
parent::__construct($moduleName, $methodName);
$products = array();
$this->loadModel('product');
$this->loadModel('tree');
$this->loadModel('user');
@@ -393,6 +394,9 @@ class bug extends control
$moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $branch);
if(empty($moduleOptionMenu)) die(js::locate(helper::createLink('tree', 'browse', "productID=$productID&view=story")));
$productList = $this->loadModel('block')->getProducts('noclosed', '');
foreach($productList as $product) $products[$product->id] = $product->name;
/* Set custom. */
foreach(explode(',', $this->config->bug->list->customCreateFields) as $field) $customFields[$field] = $this->lang->bug->$field;
$this->view->customFields = $customFields;
@@ -402,6 +406,7 @@ class bug extends control
$this->view->position[] = html::a($this->createLink('bug', 'browse', "productID=$productID"), $this->products[$productID]);
$this->view->position[] = $this->lang->bug->create;
$this->view->products = $products;
$this->view->productID = $productID;
$this->view->productName = $this->products[$productID];
$this->view->moduleOptionMenu = $moduleOptionMenu;
@@ -545,6 +550,7 @@ class bug extends control
/* Get product info. */
$productID = $bug->product;
$productName = $this->products[$productID];
$branches = $this->session->currentProductType == 'normal' ? array() : $this->loadModel('branch')->getPairs($bug->product);
/* Header and positon. */
$this->view->title = "BUG #$bug->id $bug->title - " . $this->products[$productID];
@@ -554,9 +560,11 @@ class bug extends control
/* Assign. */
$this->view->productID = $productID;
$this->view->productName = $productName;
$this->view->branches = $branches;
$this->view->modulePath = $this->tree->getParents($bug->module);
$this->view->bugModule = empty($bug->module) ? '' : $this->tree->getById($bug->module);
$this->view->bug = $bug;
$this->view->branchName = $this->session->currentProductType == 'normal' ? '' : $this->loadModel('branch')->getById($bug->branch, $bug->product);
$this->view->branchName = $this->session->currentProductType == 'normal' ? '' : zget($branches, $bug->branch, '');
$this->view->users = $this->user->getPairs('noletter');
$this->view->actions = $this->action->getList('bug', $bugID);
$this->view->builds = $this->loadModel('build')->getProductBuildPairs($productID, $branch = 0, $params = '');
+1 -1
View File
@@ -2667,7 +2667,7 @@ class bugModel extends model
$assignToLink = helper::createLink('bug', 'assignTo', "bugID=$bug->id", '', true);
$assignToHtml = html::a($assignToLink, "<i class='icon icon-hand-right'></i> <span title='$bug->assignedTo' class='{$btnTextClass}'>{$assignedToText}</span>", '', "class='$btnClass'");
echo !common::hasPriv('bug', 'assignTo') ? "<span style='padding-left: 21px' class='{$btnTextClass}'>{$assignedToText}</span>" : $assignToHtml;
echo !common::hasPriv('bug', 'assignTo', $bug) ? "<span style='padding-left: 21px' class='{$btnTextClass}'>{$assignedToText}</span>" : $assignToHtml;
}
/**
+16 -10
View File
@@ -123,16 +123,22 @@
}
else
{
foreach($modulePath as $key => $module)
{
$moduleTitle .= $module->name;
if(!common::printLink('bug', 'browse', "productID=$bug->product&branch=$module->branch&browseType=byModule&param=$module->id", $module->name)) echo $module->name;
if(isset($modulePath[$key + 1]))
{
$moduleTitle .= '/';
echo $lang->arrow;
}
}
if($bugModule->branch and isset($branches[$bugModule->branch]))
{
$moduleTitle .= $branches[$bugModule->branch] . '/';
echo $branches[$bugModule->branch] . $lang->arrow;
}
foreach($modulePath as $key => $module)
{
$moduleTitle .= $module->name;
if(!common::printLink('bug', 'browse', "productID=$bug->product&branch=$module->branch&browseType=byModule&param=$module->id", $module->name)) echo $module->name;
if(isset($modulePath[$key + 1]))
{
$moduleTitle .= '/';
echo $lang->arrow;
}
}
}
$printModule = ob_get_contents();
ob_end_clean();
+5 -1
View File
@@ -262,7 +262,7 @@ $lang->task = new stdclass();
$lang->build = new stdclass();
$lang->task->menu = $lang->project->menu;
$lang->build->menu = $lang->project->menu;
$lang->build->menu->qa = array('link' => 'Test|project|build|projectID=%s', 'subModule' => 'bug,build,testtask', 'alias' => 'build,testtask', 'class' => 'dropdown dropdown-hover');
$lang->build->menu->qa = array('link' => 'Build|project|build|projectID=%s', 'subModule' => 'bug,build,testtask', 'alias' => 'build,testtask', 'class' => 'dropdown dropdown-hover');
/* QA menu settings. */
$lang->qa = new stdclass();
@@ -335,6 +335,9 @@ $lang->doc = new stdclass();
$lang->doc->menu = new stdclass();
//$lang->doc->menu->createLib = array('link' => '<i class="icon icon-folder-plus"></i>&nbsp;Add Library|doc|createLib', 'float' => 'right');
$lang->svn = new stdclass();
$lang->git = new stdclass();
/* Report menu settings. */
$lang->report = new stdclass();
$lang->report->menu = new stdclass();
@@ -865,3 +868,4 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTest')
unset($lang->searchObjects['release']);
unset($lang->searchObjects['project']);
unset($lang->searchObjects['productplan']);
}
+1 -1
View File
@@ -262,7 +262,7 @@ $lang->task = new stdclass();
$lang->build = new stdclass();
$lang->task->menu = $lang->project->menu;
$lang->build->menu = $lang->project->menu;
$lang->build->menu->qa = array('link' => '测试|project|build|projectID=%s', 'subModule' => 'bug,build,testtask', 'alias' => 'build,testtask', 'class' => 'dropdown dropdown-hover');
$lang->build->menu->qa = array('link' => '版本|project|build|projectID=%s', 'subModule' => 'bug,build,testtask', 'alias' => 'build,testtask', 'class' => 'dropdown dropdown-hover');
/* QA视图菜单设置。*/
$lang->qa = new stdclass();
+5 -2
View File
@@ -262,7 +262,7 @@ $lang->task = new stdclass();
$lang->build = new stdclass();
$lang->task->menu = $lang->project->menu;
$lang->build->menu = $lang->project->menu;
$lang->build->menu->qa = array('link' => '測試|project|build|projectID=%s', 'subModule' => 'bug,build,testtask', 'alias' => 'build,testtask', 'class' => 'dropdown dropdown-hover');
$lang->build->menu->qa = array('link' => '版本|project|build|projectID=%s', 'subModule' => 'bug,build,testtask', 'alias' => 'build,testtask', 'class' => 'dropdown dropdown-hover');
/* QA視圖菜單設置。*/
$lang->qa = new stdclass();
@@ -335,6 +335,9 @@ $lang->doc = new stdclass();
$lang->doc->menu = new stdclass();
//$lang->doc->menu->createLib = array('link' => '<i class="icon icon-folder-plus"></i>&nbsp;添加檔案夾|doc|createLib', 'float' => 'right');
$lang->svn = new stdclass();
$lang->git = new stdclass();
/* 統計視圖菜單設置。*/
$lang->report = new stdclass();
$lang->report->menu = new stdclass();
@@ -479,7 +482,7 @@ $lang->error->email = "『%s』應當為合法的EMAIL。";
$lang->error->date = "『%s』應當為合法的日期。";
$lang->error->datetime = "『%s』應當為合法的日期。";
$lang->error->code = "『%s』應當為字母或數字的組合。";
$lang->error->account = "『%s』應當為合法的用戶名";
$lang->error->account = "『%s』只能是字母和數字的組合三位以上";
$lang->error->passwordsame = "兩次密碼應當相等。";
$lang->error->passwordrule = "密碼應該符合規則,長度至少為六位。";
$lang->error->accessDenied = '您沒有訪問權限';
+5 -6
View File
@@ -167,7 +167,7 @@ class commonModel extends model
if($this->loadModel('user')->isLogon() or ($this->app->company->guest and $this->app->user->account == 'guest'))
{
if(stripos($method, 'ajax') !== false) return true;
if(stripos($method, 'downloadClient') !== false) return true;
if($module == 'misc' and $method == 'downloadClient') return true;
if($module == 'block' and $method == 'main') return true;
if($module == 'misc' and $method == 'changelog') return true;
if($module == 'tutorial') return true;
@@ -615,11 +615,10 @@ class commonModel extends model
$subMenu .= "<li class='$subActive' data-id='$subMenuItem->name'>" . html::a($subLink, $subLabel) . '</li>';
}
if($subMenu)
{
$label .= "<span class='caret'></span>";
$subMenu = "<ul class='dropdown-menu'>{$subMenu}</ul>";
}
if(empty($subMenu)) continue;
$label .= "<span class='caret'></span>";
$subMenu = "<ul class='dropdown-menu'>{$subMenu}</ul>";
}
$menuItemHtml = "<li class='$class $active' data-id='$menuItem->name'>" . html::a($link, $label, $target) . $subMenu . "</li>\n";
+3 -1
View File
@@ -14,7 +14,6 @@
$webRoot = $this->app->getWebRoot();
$jsRoot = $webRoot . "js/";
?>
<?php include '../../common/view/chosen.html.php';?>
<div class='modal-dialog w-500px'>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><i class="icon icon-close"></i></button>
@@ -44,3 +43,6 @@ $jsRoot = $webRoot . "js/";
</form>
</div>
</div>
<script>
$('#dataform .chosen').chosen();
</script>
+40
View File
@@ -99,6 +99,21 @@ $config->dev->tableMap['config'] = 'custom';
$config->dev->tableMap['module'] = 'tree';
$config->dev->tableMap['suitecase'] = 'testcase';
$config->dev->postParams['story']['create']['product'] = 'int';
$config->dev->postParams['story']['create']['title'] = 'string';
$config->dev->postParams['story']['create']['module'] = 'int';
$config->dev->postParams['story']['create']['plan'] = 'int';
$config->dev->postParams['story']['create']['source'] = 'string';
$config->dev->postParams['story']['create']['sourceNote'] = 'string';
$config->dev->postParams['story']['create']['reviewedBy'] = 'string';
$config->dev->postParams['story']['create']['pri'] = 'string';
$config->dev->postParams['story']['create']['estimate'] = 'date';
$config->dev->postParams['story']['create']['spec'] = 'string';
$config->dev->postParams['story']['create']['verify'] = 'string';
$config->dev->postParams['story']['create']['color'] = 'string';
$config->dev->postParams['story']['create']['mailto'] = 'string';
$config->dev->postParams['story']['create']['keywords'] = 'string';
$config->dev->postParams['bug']['create']['product'] = 'int';
$config->dev->postParams['bug']['create']['title'] = 'string';
$config->dev->postParams['bug']['create']['openedBuild'] = 'int|trunk';
@@ -116,3 +131,28 @@ $config->dev->postParams['bug']['create']['pri'] = 'int';
$config->dev->postParams['bug']['create']['steps'] = 'string';
$config->dev->postParams['bug']['create']['mailto'] = 'string';
$config->dev->postParams['bug']['create']['keywords'] = 'string';
$config->dev->postParams['task']['create']['project'] = 'int';
$config->dev->postParams['task']['create']['type'] = 'string';
$config->dev->postParams['task']['create']['name'] = 'string';
$config->dev->postParams['task']['create']['module'] = 'int';
$config->dev->postParams['task']['create']['assignedTo'] = 'string';
$config->dev->postParams['task']['create']['story'] = 'int';
$config->dev->postParams['task']['create']['pri'] = 'int';
$config->dev->postParams['task']['create']['color'] = 'string';
$config->dev->postParams['task']['create']['desc'] = 'string';
$config->dev->postParams['task']['create']['mailto'] = 'string';
$config->dev->postParams['testcase']['create']['product'] = 'int';
$config->dev->postParams['testcase']['create']['title'] = 'string';
$config->dev->postParams['testcase']['create']['type'] = 'string';
$config->dev->postParams['testcase']['create']['module'] = 'int';
$config->dev->postParams['testcase']['create']['story'] = 'int';
$config->dev->postParams['testcase']['create']['stage'] = 'string';
$config->dev->postParams['testcase']['create']['pri'] = 'int';
$config->dev->postParams['testcase']['create']['color'] = 'string';
$config->dev->postParams['testcase']['create']['precondition'] = 'string';
$config->dev->postParams['testcase']['create']['steps'] = 'string';
$config->dev->postParams['testcase']['create']['expect'] = 'string';
$config->dev->postParams['testcase']['create']['mailto'] = 'string';
$config->dev->postParams['testcase']['create']['keywords'] = 'string';
+6
View File
@@ -9,6 +9,12 @@ $lang->dev->params = '參數列表';
$lang->dev->type = '類型';
$lang->dev->desc = '描述';
$lang->dev->noParams = '無參數';
$lang->dev->post = 'POST參數';
$lang->dev->paramRange = '取值範圍:%s';
$lang->dev->paramDate = '日期格式:YY-mm-dd,如:2019-01-01';
$lang->dev->paramColor = '顏色格式:#RGB,如:#3da7f5';
$lang->dev->paramMailto = "填寫帳號,多個賬號用','分隔。";
$lang->dev->fields = array();
$lang->dev->fields['id'] = '序號';
+20 -8
View File
@@ -262,7 +262,12 @@ class docModel extends model
{
$libID = (int)$libID;
$oldLib = $this->getLibById($libID);
$lib = fixer::input('post')->join('groups', ',')->join('users', ',')->get();
$lib = fixer::input('post')
->setIF(!$this->post->users, 'users', '')
->setIF(!$this->post->groups, 'groups', '')
->join('groups', ',')
->join('users', ',')
->get();
if($lib->acl == 'private')
{
$libCreatedBy = $this->dao->select('*')->from(TABLE_ACTION)->where('objectType')->eq('doclib')->andWhere('objectID')->eq($libID)->andWhere('action')->eq('created')->fetch('actor');
@@ -1259,14 +1264,21 @@ class docModel extends model
{
if($type != 'project' and $type != 'product') return true;
$this->loadModel('file');
$docIdList = $this->dao->select('id')->from(TABLE_DOC)->where($type)->eq($objectID)->get();
$docs = $this->dao->select('*')->from(TABLE_DOC)->where($type)->eq($objectID)->fetchAll('id');
foreach($docs as $id => $doc)
{
if(!$this->checkPrivDoc($doc)) unset($docs[$id]);
}
$idList = array_keys($docs);
$docIdList = $this->dao->select('id')->from(TABLE_DOC)->where($type)->eq($objectID)->andWhere('id')->in($idList)->get();
$searchTitle = $this->get->title;
if($type == 'product')
{
$storyIdList = $this->dao->select('id')->from(TABLE_STORY)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->get();
$bugIdList = $this->dao->select('id')->from(TABLE_BUG)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->get();
$releaseIdList = $this->dao->select('id')->from(TABLE_RELEASE)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->get();
$planIdList = $this->dao->select('id')->from(TABLE_PRODUCTPLAN)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->get();
$storyIdList = $this->dao->select('id')->from(TABLE_STORY)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('product')->in($this->app->user->view->products)->get();
$bugIdList = $this->dao->select('id')->from(TABLE_BUG)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('product')->in($this->app->user->view->products)->get();
$releaseIdList = $this->dao->select('id')->from(TABLE_RELEASE)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('product')->in($this->app->user->view->products)->get();
$planIdList = $this->dao->select('id')->from(TABLE_PRODUCTPLAN)->where('product')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('product')->in($this->app->user->view->products)->get();
$files = $this->dao->select('*')->from(TABLE_FILE)->alias('t1')
->where('size')->gt('0')
->andWhere("(objectType = 'product' and objectID = $objectID)", true)
@@ -1283,8 +1295,8 @@ class docModel extends model
}
elseif($type == 'project')
{
$taskIdList = $this->dao->select('id')->from(TABLE_TASK)->where('project')->eq($objectID)->andWhere('deleted')->eq('0')->get();
$buildIdList = $this->dao->select('id')->from(TABLE_BUILD)->where('project')->eq($objectID)->andWhere('deleted')->eq('0')->get();
$taskIdList = $this->dao->select('id')->from(TABLE_TASK)->where('project')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('project')->in($this->app->user->view->projects)->get();
$buildIdList = $this->dao->select('id')->from(TABLE_BUILD)->where('project')->eq($objectID)->andWhere('deleted')->eq('0')->andWhere('project')->in($this->app->user->view->projects)->get();
$files = $this->dao->select('*')->from(TABLE_FILE)->alias('t1')
->where('size')->gt('0')
->andWhere("(objectType = 'project' and objectID = $objectID)", true)
+2
View File
@@ -52,7 +52,9 @@
<div class="actions">
<?php $star = strpos($lib->collector, ',' . $this->app->user->account . ',') !== false ? 'icon-star text-yellow' : 'icon-star-empty';?>
<?php $collectTitle = strpos($lib->collector, ',' . $this->app->user->account . ',') !== false ? $lang->doc->cancelCollection : $lang->doc->collect;?>
<?php if(common::hasPriv('doc', 'collect')):?>
<a data-url="<?php echo $this->createLink('doc', 'collect', "objectID=$lib->id&objectType=doclib");?>" title="<?php echo $collectTitle;?>" class='btn btn-link ajaxCollect'><i class='icon <?php echo $star;?>'></i></a>
<?php endif;?>
<?php common::printLink('doc', 'editLib', "libID=$lib->id", "<i class='icon icon-edit'></i>", '', "title='{$lang->edit}' class='btn btn-link iframe'")?>
<?php common::printLink('doc', 'deleteLib', "libID=$lib->id", "<i class='icon icon-close'></i>", 'hiddenwin', "title='{$lang->delete}' class='btn btn-link'")?>
<?php common::printLink('tree', 'browse', "rootID=$lib->id&type=doc", "<i class='icon icon-cog'></i>", '', "title='{$lang->doc->manageType}' class='btn btn-link'")?>
+2
View File
@@ -47,7 +47,9 @@
<td class="c-actions">
<?php $star = strpos($lib->collector, ',' . $this->app->user->account . ',') !== false ? 'icon-star text-yellow' : 'icon-star-empty';?>
<?php $collectTitle = strpos($lib->collector, ',' . $this->app->user->account . ',') !== false ? $lang->doc->cancelCollection : $lang->doc->collect;?>
<?php if(common::hasPriv('doc', 'collect')):?>
<a data-url="<?php echo $this->createLink('doc', 'collect', "objectID=$lib->id&objectType=doclib");?>" title="<?php echo $collectTitle;?>" class='btn btn-link ajaxCollect'><i class='icon <?php echo $star;?>'></i></a>
<?php endif;?>
<?php common::printLink('doc', 'editLib', "libID=$lib->id", "<i class='icon icon-edit'></i>", '', "title='{$lang->edit}' class='btn btn-link iframe'")?>
<?php common::printLink('doc', 'deleteLib', "libID=$lib->id", "<i class='icon icon-close'></i>", 'hiddenwin', "title='{$lang->delete}' class='btn btn-link'")?>
<?php common::printLink('tree', 'browse', "rootID=$lib->id&type=doc", "<i class='icon icon-cog'></i>", '', "title='{$lang->doc->manageType}' class='btn btn-link'")?>
+6
View File
@@ -104,7 +104,9 @@ var browseType = '<?php echo $browseType;?>';
<td class="c-datetime"></td>
<td class="c-datetime"></td>
<td>
<?php if(common::hasPriv('doc', 'collect')):?>
<a data-url="<?php echo $this->createLink('doc', 'collect', "objectID=$lib->id&objectType=doclib");?>" title="<?php echo $collectTitle;?>" class='btn btn-link ajaxCollect'><i class='icon <?php echo $star;?>'></i></a>
<?php endif;?>
<?php common::printLink('doc', 'editLib', "libID=$lib->id", "<i class='icon icon-edit'></i>", '', "title='{$lang->edit}' class='btn btn-link iframe'")?>
<?php common::printLink('tree', 'browse', "rootID=$lib->id&type=doc", "<i class='icon icon-cog'></i>", '', "title='{$lang->tree->manage}' class='btn btn-link'")?>
</td>
@@ -138,7 +140,9 @@ var browseType = '<?php echo $browseType;?>';
<td class="c-datetime"></td>
<td class="c-datetime"></td>
<td class="c-actions">
<?php if(common::hasPriv('doc', 'collect')):?>
<a data-url="<?php echo $this->createLink('doc', 'collect', "objectID=$module->id&objectType=module");?>" title="<?php echo $collectTitle;?>" class='btn btn-link ajaxCollect'><i class='icon <?php echo $star;?>'></i></a>
<?php endif;?>
</td>
</tr>
<?php endforeach;?>
@@ -153,7 +157,9 @@ var browseType = '<?php echo $browseType;?>';
<td class="c-datetime"><?php echo formatTime($doc->addedDate, 'm-d H:i');?></td>
<td class="c-datetime"><?php echo formatTime($doc->editedDate, 'm-d H:i');?></td>
<td class="c-actions">
<?php if(common::hasPriv('doc', 'collect')):?>
<a data-url="<?php echo $this->createLink('doc', 'collect', "objectID=$doc->id&objectType=doc");?>" title="<?php echo $collectTitle;?>" class='btn btn-link ajaxCollect'><i class='icon <?php echo $star;?>'></i></a>
<?php endif;?>
<?php common::printLink('doc', 'edit', "docID=$doc->id", "<i class='icon icon-edit'></i>", '', "title='{$lang->edit}' class='btn btn-link'")?>
<?php common::printLink('doc', 'delete', "docID=$doc->id", "<i class='icon icon-close'></i>", 'hiddenwin', "title='{$lang->delete}' class='btn btn-link'")?>
</td>
+7 -1
View File
@@ -65,7 +65,9 @@
<div class="text-primary file-info"><?php echo zget($itemCounts, $lib->id, 0) . $lang->doc->item;?></div>
</a>
<div class="actions">
<?php if(common::hasPriv('doc', 'collect')):?>
<a data-url="<?php echo $this->createLink('doc', 'collect', "objectID=$lib->id&objectType=doclib");?>" title="<?php echo $collectTitle;?>" class='btn btn-link ajaxCollect'><i class='icon <?php echo $star;?>'></i></a>
<?php endif;?>
<?php common::printLink('doc', 'editLib', "libID=$lib->id", "<i class='icon icon-edit'></i>", '', "title='{$lang->edit}' class='btn btn-link iframe'")?>
</div>
</div>
@@ -105,7 +107,9 @@
<div class="text-primary file-info"><?php echo $module->docCount . $lang->doc->item;?></div>
</a>
<div class="actions">
<?php common::printLink('doc', 'collect', "objectID={$module->id}&objectType=module", "<i class='icon {$star}'></i>", 'hiddenwin', "title='{$lang->doc->collect}' class='btn btn-link'");?>
<?php if(common::hasPriv('doc', 'collect')):?>
<a data-url="<?php echo $this->createLink('doc', 'collect', "objectID={$module->id}&objectType=module");?>" title="<?php echo $lang->doc->collect;?>" class='btn btn-link ajaxCollect'><i class='icon <?php echo $star;?>'></i></a>
<?php endif;?>
</div>
</div>
<?php endforeach;?>
@@ -120,7 +124,9 @@
<div class="text-primary file-info"><?php echo zget($users, $doc->addedBy);?></div>
</a>
<div class="actions">
<?php if(common::hasPriv('doc', 'collect')):?>
<a data-url="<?php echo $this->createLink('doc', 'collect', "objectID={$doc->id}&objectType=doc");?>" title="<?php echo $collectTitle;?>" class='btn btn-link ajaxCollect'><i class='icon <?php echo $star;?>'></i></a>
<?php endif;?>
<?php common::printLink('doc', 'edit', "docID={$doc->id}", "<i class='icon icon-edit'></i>", '', "title='{$lang->edit}' class='btn btn-link'")?>
<?php common::printLink('doc', 'delete', "docID={$doc->id}", "<i class='icon icon-close'></i>", '', "title='{$lang->delete}' class='btn btn-link'")?>
</div>
+2
View File
@@ -57,7 +57,9 @@
<?php $star = strpos($lib->collector, ',' . $this->app->user->account . ',') !== false ? 'icon-star text-yellow' : 'icon-star-empty';?>
<?php $collectTitle = strpos($lib->collector, ',' . $this->app->user->account . ',') !== false ? $lang->doc->cancelCollection : $lang->doc->collect;?>
<div class="actions">
<?php if(common::hasPriv('doc', 'collect')):?>
<a data-url="<?php echo $this->createLink('doc', 'collect', "objectID=$libID&objectType=doclib");?>" title="<?php echo $collectTitle;?>" class='btn btn-link ajaxCollect'><i class='icon <?php echo $star;?>'></i></a>
<?php endif;?>
<?php common::printLink('doc', 'editLib', "libID=$libID", "<i class='icon icon-edit'></i>", '', "title='{$lang->edit}' class='btn btn-link iframe'")?>
<?php if(empty($lib->main)) common::printLink('doc', 'deleteLib', "libID=$libID", "<i class='icon icon-close'></i>", 'hiddenwin', "title='{$lang->delete}' class='btn btn-link'")?>
<?php common::printLink('tree', 'browse', "rootID=$libID&type=doc", "<i class='icon icon-cog'></i>", '', "title='{$lang->doc->manageType}' class='btn btn-link'")?>
@@ -35,7 +35,9 @@
<?php if($libID != 'project' and $libID != 'files'):?>
<?php $star = strpos($lib->collector, ',' . $this->app->user->account . ',') !== false ? 'icon-star text-yellow' : 'icon-star-empty';?>
<?php $collectTitle = strpos($lib->collector, ',' . $this->app->user->account . ',') !== false ? $lang->doc->cancelCollection : $lang->doc->collect;?>
<?php if(common::hasPriv('doc', 'collect')):?>
<a data-url="<?php echo $this->createLink('doc', 'collect', "objectID=$libID&objectType=doclib");?>" title="<?php echo $collectTitle;?>" class='btn btn-link ajaxCollect'><i class='icon <?php echo $star;?>'></i></a>
<?php endif;?>
<?php common::printLink('doc', 'editLib', "libID=$libID", "<i class='icon icon-edit'></i>", '', "title='{$lang->edit}' class='btn btn-link iframe'")?>
<?php if(empty($lib->main)) common::printLink('doc', 'deleteLib', "libID=$libID", "<i class='icon icon-close'></i>", 'hiddenwin', "title='{$lang->delete}' class='btn btn-link'")?>
<?php common::printLink('tree', 'browse', "rootID=$libID&type=doc", "<i class='icon icon-cog'></i>", '', "title='{$lang->doc->manageType}' class='btn btn-link'")?>
-1
View File
@@ -10,7 +10,6 @@
* @link http://www.zentao.net
*/
/* Methods. */
$lang->git = new stdclass();
$lang->git->common = 'Git';
$lang->git->cat = 'View Code';
$lang->git->diff = 'Diff Code';
-1
View File
@@ -10,7 +10,6 @@
* @link http://www.zentao.net
*/
/* 方法列表。*/
$lang->git = new stdclass();
$lang->git->common = 'Git';
$lang->git->cat = '查看原始碼';
$lang->git->diff = '比較原始碼';
+1 -1
View File
@@ -324,7 +324,7 @@ class gitModel extends model
list($hash, $account, $date) = $log;
$account = preg_replace('/^Author:/', '', $account);
$account = trim(preg_replace('/<[\w\-\.]+@([\w\-]+\.)+\w+>/', '', $account));
$account = trim(preg_replace('/<[\w\-\.]+@[\w\-]+>/', '', $account));
$date = trim(preg_replace('/^Date:/', '', $date));
$count = count($log);
+2
View File
@@ -1 +1,3 @@
.user {display:block; width:80px; float:left; overflow:hidden}
#groupList tbody tr.even td{word-wrap:break-word;}
+5 -255
View File
@@ -59,16 +59,15 @@ class misc extends control
/**
* Check current version is latest or not.
*
* @param string $sn
* @access public
* @return void
*/
public function checkUpdate()
public function checkUpdate($sn)
{
$note = isset($_GET['note']) ? $_GET['note'] : '';
$browser = isset($_GET['browser']) ? $_GET['browser'] : '';
$this->view->note = urldecode(helper::safe64Decode($note));
$this->view->browser = $browser;
session_write_close();
$link = $this->lang->misc->api . "/updater-isLatest-{$this->config->version}-{$sn}.html?lang=" . str_replace('-', '_', $this->app->getClientLang());
$this->view->note = file_get_contents($link);
$this->display();
}
@@ -84,255 +83,6 @@ class misc extends control
echo $this->misc->hello2();
}
/**
* Download zentao client.
*
* @access public
* @param string $action
* @param string $os
* @return void
*/
public function downloadClient($action = 'check', $os = '')
{
if($_POST)
{
$os = $this->post->os;
die(js::locate($this->createLink('misc', 'downloadClient', "action=getPackage&os=$os"), 'parent'));
}
if($action == 'check')
{
$error = false;
$errorInfo = '';
$cacheDir = $this->app->getBasePath() . 'tmp/cache/';
if(!is_dir($cacheDir))
{
$result = mkdir($cacheDir, 0755, true);
if($result == false)
{
$error = true;
$errorInfo = sprintf($this->lang->misc->client->errorInfo->dirNotExist, $cacheDir, $cacheDir);
}
}
if(!is_writable($cacheDir))
{
$error = true;
$errorInfo = sprintf($this->lang->misc->client->errorInfo->dirNotWritable, $cacheDir, $cacheDir);
}
$this->view->error = $error;
$this->view->errorInfo = $errorInfo;
if(!$error) die(js::locate($this->createLink('misc', 'downloadClient', "action=selectPackage")));
}
if($action == 'selectPackage')
{
$os = 'win64';
$agentOS = helper::getOS();
if(strpos($agentOS, 'Windows') !== false) $os = 'win64';
if(strpos($agentOS, 'Linux') !== false) $os = 'linux64';
if(strpos($agentOS, 'Mac') !== false) $os = 'mac';
$this->view->os = $os;
}
if($action == 'getPackage')
{
$this->view->os = $os;
$this->view->account = $this->app->user->account;
}
if($action == 'clearTmpPackage')
{
$account = $this->app->user->account;
$tmpDir = $this->app->getBasePath() . 'tmp/cache/client/' . "$account/";
if(is_dir($tmpDir))
{
$zfile = $this->app->loadClass('zfile');
$zfile->removeDir($tmpDir);
}
die(js::closeModal('parent.parent', 'this'));
}
if($action == 'downloadPackage')
{
$account = $this->app->user->account;
$clientDir = $this->app->getBasePath() . 'tmp/cache/client/' . "$account/";
$clientFile = $clientDir . 'zentaoclient.zip';
$zipContent = file_get_contents($clientFile);
if(is_dir($clientDir))
{
$zfile = $this->app->loadClass('zfile');
$zfile->removeDir($clientDir);
}
$this->fetch('file', 'sendDownHeader', array('fileName' => "zentao_chat_client." . $os . '.zip', 'zip', $zipContent));
}
$this->view->action = $action;
$this->display();
}
/**
* Ajax get client package.
*
* @param string $os
* @access public
* @return void
*/
public function ajaxGetClientPackage($os = '')
{
set_time_limit (0);
session_write_close();
$response = array();
$response['result'] = 'success';
$response['message'] = '';
$clientDir = $this->app->getBasePath() . 'tmp/cache/client/';
if(!is_dir($clientDir)) mkdir($clientDir, 0755, true);
$version = $this->config->xuanxuan->version;
$packageDir = $clientDir . "/$version/";
if(!is_dir($packageDir)) mkdir($packageDir, 0755, true);
$account = $this->app->user->account;
$tmpDir = $clientDir . "/$account/";
if(!is_dir($tmpDir)) mkdir($tmpDir, 0755, true);
$needCache = false;
$clientName = "zentaoclient." . $os . ".zip";
$packageFile = $packageDir . $clientName;
if(!file_exists($packageFile))
{
$url = "http://dl.cnezsoft.com/zentaoclient/$version/";
$xxFile = $url . $clientName . "?t=" . rand();
$needCache = true;
}
else
{
$xxFile = $packageFile;
}
$clientFile = $tmpDir . 'zentaoclient.zip';
if($xxHd = fopen($xxFile, "rb"))
{
if($clientHd = fopen($clientFile, "wb"))
{
while(!feof($xxHd))
{
$result = fwrite($clientHd, fread($xxHd, 1024 * 8 ), 1024 * 8 );
if($result == false)
{
$response['result'] = 'fail';
$response['message'] = sprintf($this->lang->misc->client->errorInfo->manualOpt, $xxFile);
$this->send($response);
}
}
}
else
{
$response['result'] = 'fail';
$response['message'] = sprintf($this->lang->misc->client->errorInfo->manualOpt, $xxFile);
$this->send($response);
}
fclose($xxHd);
fclose($clientHd);
}
else
{
$response['result'] = 'fail';
$response['message'] = sprintf($this->lang->misc->client->errorInfo->manualOpt, $xxFile);
$this->send($response);
}
if($needCache) file_put_contents($packageFile, file_get_contents($clientFile));
$this->send($response);
}
/**
* Ajax set client config to client package.
*
* @param string $os
* @access public
* @return void
*/
public function ajaxSetClientConfig($os = '')
{
$response['result'] = 'success';
$account = $this->app->user->account;
$clientDir = $this->app->getBasePath() . 'tmp/cache/client/' . "$account/";
if(!is_dir($clientDir)) mkdir($clientDir, 0755, true);
/* write login info into config file. */
$loginInfo = new stdclass();
$loginInfo->ui = new stdclass();
$loginInfo->ui->defaultUser = new stdclass();
$loginInfo->ui->defaultUser->server = common::getSysURL();;
$loginInfo->ui->defaultUser->account = $this->app->user->account;
$loginInfo = json_encode($loginInfo);
$loginFile = $clientDir . 'config.json';
file_put_contents($loginFile, $loginInfo);
define('PCLZIP_TEMPORARY_DIR', $clientDir);
$this->app->loadClass('pclzip', true);
$clientFile = $clientDir . 'zentaoclient.zip';
$archive = new pclzip($clientFile);
if($os == 'mac')
{
$result = $archive->add($loginFile, PCLZIP_OPT_REMOVE_ALL_PATH, PCLZIP_OPT_ADD_PATH, 'zentaoclient/xuanxuan.app/Contents/Resouces');
}
else
{
$result = $archive->add($loginFile, PCLZIP_OPT_REMOVE_ALL_PATH, PCLZIP_OPT_ADD_PATH, 'zentaoclient/resources/build-in');
}
if($result == 0)
{
$response['result'] = 'fail';
$response['message'] = $archive->errorInfo(true);
$this->send($response);
}
$this->send($response);
}
/**
* Ajax get client package size.
*
* @access public
* @return void
*/
public function ajaxGetPackageSize()
{
$account = $this->app->user->account;
$packageFile = $this->app->getBasePath() . 'tmp/cache/client/' . $account . '/zentaoclient.zip';
$size = 0;
if(file_exists($packageFile))
{
$size = filesize($packageFile);
$size = $size ? round($size / 1048576, 2) : 0;
}
$response = array();
$response['result'] = 'success';
$response['size'] = $size;
$this->send($response);
}
/**
* Down notify.
*
+3 -22
View File
@@ -15,28 +15,6 @@ $lang->misc->ping = 'Ping';
$lang->misc->api = 'https://api.zentao.net';
$lang->misc->enApi = 'http://api.zentao.pm';
$lang->misc->client = new stdclass();
$lang->misc->client->version = 'Client Version';
$lang->misc->client->os = 'Select OS';
$lang->misc->client->download = 'Download';
$lang->misc->client->downloading = 'Downloading:';
$lang->misc->client->downloaded = 'Downloaded!';
$lang->misc->client->setting = 'Setting';
$lang->misc->client->setted = 'Setting is done!';
$lang->misc->client->osList['win64'] = 'Windows 64';
$lang->misc->client->osList['win32'] = 'Windows 32';
$lang->misc->client->osList['linux64'] = 'Linux 64';
$lang->misc->client->osList['linux32'] = 'Linux 32';
$lang->misc->client->osList['mac'] = 'Mac';
$lang->misc->client->errorInfo = new stdclass();
$lang->misc->client->errorInfo->downloadError = 'Failed to download package!';
$lang->misc->client->errorInfo->configError = 'Failed to set up!';
$lang->misc->client->errorInfo->manualOpt = 'Please get client package from %s .';
$lang->misc->client->errorInfo->dirNotExist = 'The dir <span class="code text-red">%s</span> does not exist. Create it.';
$lang->misc->client->errorInfo->dirNotWritable = 'The dir <span class="code text-red">%s</span> is not writable. <br /> Please exec:<span class="code text-red">sudo chmod 777 %s</span> in Linux.';
$lang->misc->zentao = new stdclass();
$lang->misc->zentao->version = 'Version %s';
$lang->misc->zentao->labels['about'] = 'About';
@@ -98,6 +76,7 @@ $lang->misc->feature = new stdclass();
$lang->misc->feature->lastest = 'Latest Version';
$lang->misc->feature->detailed = 'Details';
$lang->misc->releaseDate['11.2.stable'] = '2019-01-30';
$lang->misc->releaseDate['11.1.stable'] = '2019-01-04';
$lang->misc->releaseDate['11.0.stable'] = '2018-12-21';
$lang->misc->releaseDate['10.6.stable'] = '2018-11-20';
@@ -120,6 +99,8 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['11.2.stable'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '<p>Add upgrade logs and database checkup after upgrading</p><p>Fixed ZenTao client and other bugs, and optimized details.</p>');
$lang->misc->feature->all['11.1.stable'][] = array('title'=>'Fix Bug.');
$lang->misc->feature->all['11.0.stable'][] = array('title'=>'ZenTao integrate Xuanxuan');
+3 -22
View File
@@ -15,28 +15,6 @@ $lang->misc->ping = '防超时';
$lang->misc->api = 'https://api.zentao.net';
$lang->misc->enApi = 'http://api.zentao.pm';
$lang->misc->client = new stdclass();
$lang->misc->client->version = '客户端版本';
$lang->misc->client->os = '操作系统';
$lang->misc->client->download = '下载';
$lang->misc->client->downloading = '正在获取安装包:';
$lang->misc->client->downloaded = '成功获取安装包';
$lang->misc->client->setting = '正在设置配置信息';
$lang->misc->client->setted = '成功设置配置信息';
$lang->misc->client->osList['win64'] = 'Windows 64位';
$lang->misc->client->osList['win32'] = 'Windows 32位';
$lang->misc->client->osList['linux64'] = 'Linux 64位';
$lang->misc->client->osList['linux32'] = 'Linux 32位';
$lang->misc->client->osList['mac'] = 'Mac版';
$lang->misc->client->errorInfo = new stdclass();
$lang->misc->client->errorInfo->downloadError = '获取安装包失败';
$lang->misc->client->errorInfo->configError = '配置用户信息失败';
$lang->misc->client->errorInfo->manualOpt = '请从 %s 手动获取安装包。';
$lang->misc->client->errorInfo->dirNotExist = '客户端下载存储路径 <span class="code text-red">%s</span> 不存在,请创建该目录。';
$lang->misc->client->errorInfo->dirNotWritable = '客户端下载存储路径 <span class="code text-red">%s</span> 不可写 <br />linux下面请执行命令:<span class="code text-red">sudo chmod 777 %s</span>来修正';
$lang->misc->zentao = new stdclass();
$lang->misc->zentao->version = '版本%s';
$lang->misc->zentao->labels['about'] = '关于禅道';
@@ -98,6 +76,7 @@ $lang->misc->feature = new stdclass();
$lang->misc->feature->lastest = '最新版本';
$lang->misc->feature->detailed = '详情';
$lang->misc->releaseDate['11.2.stable'] = '2019-01-30';
$lang->misc->releaseDate['11.1.stable'] = '2019-01-04';
$lang->misc->releaseDate['11.0.stable'] = '2018-12-21';
$lang->misc->releaseDate['10.6.stable'] = '2018-11-20';
@@ -120,6 +99,8 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['11.2.stable'][] = array('title'=>'完善细节,修复Bug', 'desc' => '<p>增加升级日志和升级后数据库检查的功能</p><p>修复禅道集成客户端和其他若干bug,完善细节</p>');
$lang->misc->feature->all['11.1.stable'][] = array('title'=>'主要修复Bug。');
$lang->misc->feature->all['11.0.stable'][] = array('title'=>'禅道集成喧喧');
+3 -22
View File
@@ -15,28 +15,6 @@ $lang->misc->ping = '防超時';
$lang->misc->api = 'https://api.zentao.net';
$lang->misc->enApi = 'http://api.zentao.pm';
$lang->misc->client = new stdclass();
$lang->misc->client->version = '客戶端版本';
$lang->misc->client->os = '操作系統';
$lang->misc->client->download = '下載';
$lang->misc->client->downloading = '正在獲取安裝包:';
$lang->misc->client->downloaded = '成功獲取安裝包';
$lang->misc->client->setting = '正在設置配置信息';
$lang->misc->client->setted = '成功設置配置信息';
$lang->misc->client->osList['win64'] = 'Windows 64位';
$lang->misc->client->osList['win32'] = 'Windows 32位';
$lang->misc->client->osList['linux64'] = 'Linux 64位';
$lang->misc->client->osList['linux32'] = 'Linux 32位';
$lang->misc->client->osList['mac'] = 'Mac版';
$lang->misc->client->errorInfo = new stdclass();
$lang->misc->client->errorInfo->downloadError = '獲取安裝包失敗';
$lang->misc->client->errorInfo->configError = '配置用戶信息失敗';
$lang->misc->client->errorInfo->manualOpt = '請從 %s 手動獲取安裝包。';
$lang->misc->client->errorInfo->dirNotExist = '客戶端下載存儲路徑 <span class="code text-red">%s</span> 不存在,請創建該目錄。';
$lang->misc->client->errorInfo->dirNotWritable = '客戶端下載存儲路徑 <span class="code text-red">%s</span> 不可寫 <br />linux下面請執行命令:<span class="code text-red">sudo chmod 777 %s</span>來修正';
$lang->misc->zentao = new stdclass();
$lang->misc->zentao->version = '版本%s';
$lang->misc->zentao->labels['about'] = '關於禪道';
@@ -98,6 +76,7 @@ $lang->misc->feature = new stdclass();
$lang->misc->feature->lastest = '最新版本';
$lang->misc->feature->detailed = '詳情';
$lang->misc->releaseDate['11.2.stable'] = '2019-01-30';
$lang->misc->releaseDate['11.1.stable'] = '2019-01-04';
$lang->misc->releaseDate['11.0.stable'] = '2018-12-21';
$lang->misc->releaseDate['10.6.stable'] = '2018-11-20';
@@ -120,6 +99,8 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['11.2.stable'][] = array('title'=>'完善細節,修復Bug', 'desc' => '<p>增加升級日誌和升級後資料庫檢查的功能</p><p>修復禪道整合客戶端和其他若干bug,完善細節</p>');
$lang->misc->feature->all['11.1.stable'][] = array('title'=>'主要修復Bug。');
$lang->misc->feature->all['11.0.stable'][] = array('title'=>'禪道整合喧喧');
+1 -1
View File
@@ -1,7 +1,7 @@
<?php error_reporting(0);?>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /></head>
<body <?php if($browser != 'opera') echo "bgcolor='transparent'";?> style='color:white; font-size:13px; text-align:center'>
<body <?php if(strpos($this->server->http_user_agen, 'opera') === false) echo "bgcolor='transparent'";?> style='color:white; font-size:13px; text-align:center'>
<?php if($note):?>
<?php echo $note;?>
<script>window.parent.document.getElementById('updater').className=''</script>
+4 -23
View File
@@ -291,33 +291,14 @@ class productModel extends model
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getProductPairs();
$orderBy = !empty($this->config->product->orderBy) ? $this->config->product->orderBy : 'isClosed';
$products = $this->dao->select('id,name,line, IF(INSTR(" closed", status) < 2, 0, 1) AS isClosed')
$products = $this->dao->select('*, IF(INSTR(" closed", status) < 2, 0, 1) AS isClosed')
->from(TABLE_PRODUCT)
->where('deleted')->eq(0)
->beginIF(strpos($mode, 'noclosed') !== false)->andWhere('status')->ne('closed')->fi()
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->products)->fi()
->orderBy('order_desc')
->fetchAll('id');
$lines = $this->loadModel('tree')->getLinePairs();
$linePairs = array();
foreach($lines as $id => $name)
{
foreach($products as $key => $product)
{
if($product->line == $id)
{
$linePairs[$product->id] = $name . '/' . $product->name;
unset($products[$key]);
}
}
}
$productPairs = array();
foreach($products as $id => $product) $productPairs[$product->id] = $product->name;
$productPairs = $linePairs + $productPairs;
return $productPairs;
->orderBy($orderBy)
->fetchPairs('id', 'name');
return $products;
}
/**
+2 -2
View File
@@ -74,8 +74,8 @@ foreach($products as $product)
?>
</div>
<div class="col-footer">
<?php echo html::a(helper::createLink('product', 'all'), '<i class="icon icon-cards-view muted"></i> ' . $lang->product->all); ?>
<a class='pull-right toggle-right-col'><?php echo $lang->product->closed?><i class='icon icon-angle-right'></i></a>
<?php echo html::a(helper::createLink('product', 'all'), '<i class="icon icon-cards-view muted"></i> ' . $lang->product->all, '', 'class="not-list-item"'); ?>
<a class='pull-right toggle-right-col not-list-item'><?php echo $lang->product->closed?><i class='icon icon-angle-right'></i></a>
</div>
</div>
<div class="table-col col-right">
+2 -2
View File
@@ -49,8 +49,8 @@ foreach($projects as $project)
?>
</div>
<div class="col-footer">
<?php echo html::a(helper::createLink('project', 'all'), '<i class="icon icon-cards-view muted"></i> ' . $lang->project->all); ?>
<a class='pull-right toggle-right-col'><?php echo $lang->project->doneProjects?><i class='icon icon-angle-right'></i></a>
<?php echo html::a(helper::createLink('project', 'all'), '<i class="icon icon-cards-view muted"></i> ' . $lang->project->all, '', 'class="not-list-item"'); ?>
<a class='pull-right toggle-right-col not-list-item'><?php echo $lang->project->doneProjects?><i class='icon icon-angle-right'></i></a>
</div>
</div>
<div class="table-col col-right">
+7 -5
View File
@@ -147,7 +147,7 @@
{
if($groupBy == 'story')
{
if(!$task->parent)
if($task->parent <= 0)
{
$groupEstimate += $task->estimate;
$groupConsumed += $task->consumed;
@@ -156,10 +156,12 @@
}
else
{
$groupEstimate += $task->estimate;
$groupConsumed += $task->consumed;
if($groupBy == 'status' || ($task->status != 'cancel' && $task->status != 'closed')) $groupLeft += $task->left;
if($task->parent <= 0)
{
$groupEstimate += $task->estimate;
$groupConsumed += $task->consumed;
if($groupBy == 'status' || ($task->status != 'cancel' && $task->status != 'closed')) $groupLeft += $task->left;
}
}
if($task->status == 'wait') $groupWait++;
+1 -1
View File
@@ -159,7 +159,7 @@ $account = $this->app->user->account;
<div class='info'>
<?php
$assignedToRealName = "<span>" . zget($realnames, $bug->assignedTo) . "</span>";
if(empty($task->assignedTo)) $assignedToRealName = "<span class='text-primary text'>{$lang->task->noAssigned}</span>";
if(empty($bug->assignedTo)) $assignedToRealName = "<span class='text-primary text'>{$lang->task->noAssigned}</span>";
echo html::a($this->createLink('bug', 'assignTo', "bugID={$bug->id}", '', true), '<i class="icon icon-hand-right"></i> ' . $assignedToRealName, '', 'class="btn btn-icon-left kanbaniframe bug-assignedTo"');?>
<span class='status-bug status-<?php echo $bug->status;?>' title='<?php echo $lang->bug->status?>'><span class="label label-dot"></span> <?php echo zget($lang->bug->statusList, $bug->status);?></span>
</div>
+1
View File
@@ -195,6 +195,7 @@ class releaseModel extends model
$release = fixer::input('post')->stripTags($this->config->release->editor->edit['id'], $this->config->allowedTags)
->add('branch', (int)$branch)
->setIF(!$this->post->marker, 'marker', 0)
->cleanInt('product')
->remove('files,labels,allchecker,uid')
->get();
+2 -2
View File
@@ -55,8 +55,8 @@
<td><?php echo html::a(helper::createLink('release', 'view', "releaseID=$release->id"), sprintf('%03d', $release->id));?></td>
<td>
<?php
$releaseName = $release->marker ? "<icon class='icon-flag'></icon>" . $release->name : $release->name;
echo html::a(inlink('view', "release=$release->id"), $releaseName);
$flagIcon = $release->marker ? "<icon class='icon icon-flag-alt'></icon> " : '';
echo $flagIcon . html::a(inlink('view', "release=$release->id"), $release->name);
?>
</td>
<td title='<?php echo $release->buildName?>'><?php echo html::a($this->createLink('build', 'view', "buildID=$release->buildID"), $release->buildName);?></td>
+2 -2
View File
@@ -21,8 +21,8 @@
<div class='divider'></div>
<div class='page-title'>
<span class='label label-id'><?php echo $release->id;?></span>
<?php $releaseName = $release->marker ? "<icon class='icon-flag'></icon>" . $release->name : $release->name;?>
<span class='text' title='<?php echo $release->name;?>'><?php echo $releaseName;?></span>
<?php $flagIcon = $release->marker ? "<icon class='icon icon-flag-alt'></icon> " : '';?>
<span class='text' title='<?php echo $release->name;?>'><?php echo $flagIcon . $release->name;?></span>
<?php if($release->deleted):?>
<span class='label label-danger'><?php echo $lang->release->deleted;?></span>
<?php endif; ?>
+1 -1
View File
@@ -313,7 +313,7 @@ class reportModel extends model
{
foreach($multiTasks as $task)
{
$userTask = $allTasks[$task->root];
$userTask = clone $allTasks[$task->root];
$userTask->estimate = $task->estimate;
$userTask->consumed = $task->consumed;
$userTask->left = $task->left;
+24 -19
View File
@@ -141,7 +141,9 @@ class story extends control
}
else
{
$products = $this->product->getPairs('noclosed');
$products = array();
$productList = $this->loadModel('block')->getProducts('noclosed', '');
foreach($productList as $product) $products[$product->id] = $product->name;
$product = $this->product->getById($productID ? $productID : key($products));
if(!isset($products[$product->id])) $products[$product->id] = $product->name;
}
@@ -681,6 +683,7 @@ class story extends control
$fromBug = $this->dao->select('id,title')->from(TABLE_BUG)->where('toStory')->eq($storyID)->fetch();
$cases = $this->dao->select('id,title')->from(TABLE_CASE)->where('story')->eq($storyID)->andWhere('deleted')->eq(0)->fetchAll();
$modulePath = $this->tree->getParents($story->module);
$storyModule = empty($story->module) ? '' : $this->tree->getById($story->module);
$users = $this->user->getPairs('noletter');
/* Set the menu. */
@@ -697,23 +700,24 @@ class story extends control
$position[] = $this->lang->story->common;
$position[] = $this->lang->story->view;
$this->view->title = $title;
$this->view->position = $position;
$this->view->product = $product;
$this->view->branches = $product->type == 'normal' ? array() : $this->loadModel('branch')->getPairs($product->id);
$this->view->plan = $plan;
$this->view->bugs = $bugs;
$this->view->fromBug = $fromBug;
$this->view->cases = $cases;
$this->view->story = $story;
$this->view->users = $users;
$this->view->projects = $this->loadModel('project')->getPairs('nocode');
$this->view->actions = $this->action->getList('story', $storyID);
$this->view->modulePath = $modulePath;
$this->view->version = $version == 0 ? $story->version : $version;
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('story', $storyID);
$this->view->from = $from;
$this->view->param = $param;
$this->view->title = $title;
$this->view->position = $position;
$this->view->product = $product;
$this->view->branches = $product->type == 'normal' ? array() : $this->loadModel('branch')->getPairs($product->id);
$this->view->plan = $plan;
$this->view->bugs = $bugs;
$this->view->fromBug = $fromBug;
$this->view->cases = $cases;
$this->view->story = $story;
$this->view->users = $users;
$this->view->projects = $this->loadModel('project')->getPairs('nocode');
$this->view->actions = $this->action->getList('story', $storyID);
$this->view->storyModule = $storyModule;
$this->view->modulePath = $modulePath;
$this->view->version = $version == 0 ? $story->version : $version;
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('story', $storyID);
$this->view->from = $from;
$this->view->param = $param;
$this->display();
}
@@ -1322,7 +1326,8 @@ class story extends control
$storyInfo['moduleID'] = $story->module;
$storyInfo['estimate'] = $story->estimate;
$storyInfo['pri'] = $story->pri;
$storyInfo['spec'] = $story->spec;
$storyInfo['spec'] = html_entity_decode($story->spec);
echo json_encode($storyInfo);
}
+6
View File
@@ -144,6 +144,12 @@
}
else
{
if($storyModule->branch and isset($branches[$storyModule->branch]))
{
$moduleTitle .= $branches[$storyModule->branch] . '/';
echo $branches[$storyModule->branch] . $lang->arrow;
}
foreach($modulePath as $key => $module)
{
$moduleTitle .= $module->name;
-1
View File
@@ -10,7 +10,6 @@
* @link http://www.zentao.net
*/
/* Methods. */
$lang->svn = new stdclass();
$lang->svn->common = 'Subversion';
$lang->svn->cat = 'View Code';
$lang->svn->diff = 'Diff Code';
-1
View File
@@ -10,7 +10,6 @@
* @link http://www.zentao.net
*/
/* 方法列表。*/
$lang->svn = new stdclass();
$lang->svn->common = 'Subversion';
$lang->svn->cat = '查看原始碼';
$lang->svn->diff = '比較原始碼';
+1
View File
@@ -2,6 +2,7 @@
.title-group.required:after {display: none;}
.title-group.required > .required:after {display: block; right: 29px; top: 5px;}
#copyStory-input:after {display: block; right: 85px; top: 5px;}
#pri + .chosen-container > .chosen-single {border-top-left-radius: 0!important; border-bottom-left-radius: 0!important;}
.pri-selector > .btn {padding: 5px 8px!important; width: 100%;}
+2
View File
@@ -146,6 +146,7 @@ function setPreview()
$('#preview').addClass('hidden');
$('#copyButton').addClass('hidden');
$('div.colorpicker').css('right', '1px');//Adjust for task #4151;
$('.title-group.required > div').removeAttr('id', 'copyStory-input').addClass('.required');
}
else
{
@@ -155,6 +156,7 @@ function setPreview()
$('#preview').removeClass('hidden');
$('#preview a').attr('href', storyLink);
$('#copyButton').removeClass('hidden');
$('.title-group.required > div').attr('id', 'copyStory-input').removeClass('.required');
$('div.colorpicker').css('right', '57px');//Adjust for task #4151;
}
+1 -1
View File
@@ -2646,7 +2646,7 @@ class taskModel extends model
$assignToLink = helper::createLink('task', 'assignTo', "projectID=$task->project&taskID=$task->id", '', true);
$assignToHtml = html::a($assignToLink, "<i class='icon icon-hand-right'></i> <span class='{$btnTextClass}'>{$assignedToText}</span>", '', "class='$btnClass'");
echo !common::hasPriv('task', 'assignTo') ? "<span style='padding-left: 21px' class='{$btnTextClass}'>{$assignedToText}</span>" : $assignToHtml;
echo !common::hasPriv('task', 'assignTo', $task) ? "<span style='padding-left: 21px' class='{$btnTextClass}'>{$assignedToText}</span>" : $assignToHtml;
}
/**
+15 -9
View File
@@ -252,15 +252,9 @@ class testcase extends control
}
if(empty($this->products)) $this->locate($this->createLink('product', 'create'));
/* Set productID and currentModuleID. */
/* Set productID and branch. */
$productID = $this->product->saveState($productID, $this->products);
if($branch === '') $branch = (int)$this->cookie->preBranch;
if($storyID and empty($moduleID))
{
$story = $this->loadModel('story')->getByID($storyID);
$moduleID = $story->module;
}
$currentModuleID = (int)$moduleID;
/* Set menu. */
$this->testcase->setMenu($this->products, $productID, $branch);
@@ -319,6 +313,14 @@ class testcase extends control
$position[] = $this->lang->testcase->common;
$position[] = $this->lang->testcase->create;
/* Set story and currentModuleID. */
if($storyID and empty($moduleID))
{
$story = $this->loadModel('story')->getByID($storyID);
$moduleID = $story->module;
}
$currentModuleID = (int)$moduleID;
/* Get the status of stories are not closed. */
$storyStatus = $this->lang->story->statusList;
$modules = array();
@@ -328,6 +330,7 @@ class testcase extends control
$modules = $this->tree->getAllChildID($modules);
}
$stories = $this->story->getProductStoryPairs($productID, $branch, $modules, array_keys($storyStatus), 'id_desc', 50);
if($storyID and !isset($stories[$storyID])) $stories = $this->story->formatStories(array($storyID => $story)) + $stories;//Fix bug #2406.
/* Set custom. */
foreach(explode(',', $this->config->testcase->customCreateFields) as $field) $customFields[$field] = $this->lang->testcase->$field;
@@ -339,7 +342,7 @@ class testcase extends control
$this->view->productID = $productID;
$this->view->productName = $this->products[$productID];
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'case', $startModuleID = 0, $branch);
$this->view->currentModuleID = $currentModuleID ? $currentModuleID : (isset($story->module) ? $story->module : 0);
$this->view->currentModuleID = $currentModuleID;
$this->view->stories = $stories;
$this->view->caseTitle = $caseTitle;
$this->view->color = $color;
@@ -484,6 +487,7 @@ class testcase extends control
if(!$case) die(js::error($this->lang->notFound) . js::locate('back'));
if($from == 'testtask') $run = $this->loadModel('testtask')->getRunByCase($taskID, $caseID);
$branches = $this->session->currentProductType == 'normal' ? array() : $this->loadModel('branch')->getPairs($case->product);
$isLibCase = ($case->lib and empty($case->product));
if($isLibCase)
{
@@ -505,7 +509,7 @@ class testcase extends control
$this->view->position[] = html::a($this->createLink('testcase', 'browse', "productID=$productID"), $this->products[$productID]);
$this->view->productName = $this->products[$productID];
$this->view->branchName = $this->session->currentProductType == 'normal' ? '' : $this->loadModel('branch')->getById($case->branch);
$this->view->branchName = $this->session->currentProductType == 'normal' ? '' : zget($branches, $case->branch, '');
}
$caseFails = $this->dao->select('COUNT(*) AS count')->from(TABLE_TESTRESULT)
@@ -523,12 +527,14 @@ class testcase extends control
$this->view->taskID = $taskID;
$this->view->version = $version ? $version : $case->version;
$this->view->modulePath = $this->tree->getParents($case->module);
$this->view->caseModule = empty($case->module) ? '' : $this->tree->getById($case->module);
$this->view->users = $this->user->getPairs('noletter');
$this->view->actions = $this->loadModel('action')->getList('case', $caseID);
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('testcase', $caseID);
$this->view->runID = $from == 'testcase' ? 0 : $run->id;
$this->view->isLibCase = $isLibCase;
$this->view->caseFails = $caseFails;
$this->view->branches = $branches;
$this->display();
}
+1 -1
View File
@@ -3,7 +3,7 @@ $(document).ready(function()
removeDitto();//Remove 'ditto' in first row.
if($('#batchCreateForm table thead tr th.c-title').width() < 150) $('#batchCreateForm table thead tr th.c-title').width('150');
$(document).on('click', '.chosen-with-drop', function()
$(document).on('mouseup', '.chosen-with-drop', function()
{
var select = $(this).prev('select');
var id = $(select).attr('id');
+1 -4
View File
@@ -83,6 +83,7 @@ $lang->testcase->edit = "Edit";
$lang->testcase->batchEdit = "Batch Edit ";
$lang->testcase->batchChangeModule = "Batch Change Module";
$lang->testcase->batchChangeBranch = "Batch Change Branch";
$lang->testcase->groupByStories = 'Group by Story';
$lang->testcase->delete = "Delete";
$lang->testcase->batchDelete = "Batch Delete ";
$lang->testcase->batchConfirmStoryChange = "Batch Confirm";
@@ -170,10 +171,6 @@ $lang->testcase->reviewResultList[''] = '';
$lang->testcase->reviewResultList['pass'] = 'Pass';
$lang->testcase->reviewResultList['clarify'] = 'Clarify';
$lang->testcase->groups[''] = 'Group ';
$lang->testcase->groups['story'] = 'Group by Story';
$lang->testcase->groups['assignedTo'] = 'Group by Assignee';
$lang->testcase->statusList[''] = '';
$lang->testcase->statusList['wait'] = 'Wait';
$lang->testcase->statusList['normal'] = 'Normal';
+1 -4
View File
@@ -83,6 +83,7 @@ $lang->testcase->edit = "编辑";
$lang->testcase->batchEdit = "批量编辑 ";
$lang->testcase->batchChangeModule = "批量修改模块";
$lang->testcase->batchChangeBranch = "批量修改分支";
$lang->testcase->groupByStories = '需求分组';
$lang->testcase->delete = "删除";
$lang->testcase->batchDelete = "批量删除 ";
$lang->testcase->batchConfirmStoryChange = "批量确认变更";
@@ -170,10 +171,6 @@ $lang->testcase->reviewResultList[''] = '';
$lang->testcase->reviewResultList['pass'] = '确认通过';
$lang->testcase->reviewResultList['clarify'] = '继续完善';
$lang->testcase->groups[''] = '分组查看';
$lang->testcase->groups['story'] = '需求分组';
$lang->testcase->groups['assignedTo'] = '指派分组';
$lang->testcase->statusList[''] = '';
$lang->testcase->statusList['wait'] = '待评审';
$lang->testcase->statusList['normal'] = '正常';
+1 -4
View File
@@ -83,6 +83,7 @@ $lang->testcase->edit = "編輯";
$lang->testcase->batchEdit = "批量編輯 ";
$lang->testcase->batchChangeModule = "批量修改模組";
$lang->testcase->batchChangeBranch = "批量修改分支";
$lang->testcase->groupByStories = '需求分組';
$lang->testcase->delete = "刪除";
$lang->testcase->batchDelete = "批量刪除 ";
$lang->testcase->batchConfirmStoryChange = "批量確認變更";
@@ -170,10 +171,6 @@ $lang->testcase->reviewResultList[''] = '';
$lang->testcase->reviewResultList['pass'] = '確認通過';
$lang->testcase->reviewResultList['clarify'] = '繼續完善';
$lang->testcase->groups[''] = '分組查看';
$lang->testcase->groups['story'] = '需求分組';
$lang->testcase->groups['assignedTo'] = '指派分組';
$lang->testcase->statusList[''] = '';
$lang->testcase->statusList['wait'] = '待評審';
$lang->testcase->statusList['normal'] = '正常';
+2 -14
View File
@@ -89,22 +89,10 @@
{
$groupBy = isset($groupBy) ? $groupBy : '';
$active = !empty($groupBy) ? 'btn-active-text' : '';
$current = zget($lang->testcase->groups, isset($groupBy) ? $groupBy : '', '');
if(empty($current)) $current = $lang->testcase->groups[''];
echo "<div id='groupTab' class='btn-group'>";
echo html::a('javascript:;', "<span class='text'>{$current}</span>" . " <span class='caret'></span>", '', "class='btn btn-link {$active}' data-toggle='dropdown'");
echo "<ul class='dropdown-menu'>";
foreach($lang->testcase->groups as $key => $value)
{
if($key == '') continue;
echo '<li' . ($key == $groupBy ? " class='active'" : '') . '>';
echo html::a($this->createLink('testcase', 'groupCase', "productID=$productID&branch=$branch&groupBy=$key"), $value);
echo "</li>";
}
echo '</ul></div>';
echo html::a($this->createLink('testcase', 'groupCase', "productID=$productID&branch=$branch&groupBy=story"), "<span class='text'>{$lang->testcase->groupByStories}</span>", '', "class='btn btn-link $active'");
echo '</div>';
}
elseif($hasZeroPriv and $menuType == 'zerocase')
{
+1 -1
View File
@@ -70,7 +70,7 @@
<?php echo html::select('story', $stories, $storyID, 'class="form-control chosen" onchange="setPreview();" data-no_results_text="' . $lang->searchMore . '"');?>
<span class='input-group-btn' style='width: 0.01%'>
<?php if($storyID == 0): ?>
<a href='' id='preview' class='btn iframe hidden'><?php echo $lang->preview;?></a>
<a href='' id='preview' class='btn hidden'><?php echo $lang->preview;?></a>
<?php else:?>
<?php echo html::a($this->createLink('story', 'view', "storyID=$storyID", '', true), $lang->preview, '', "class='btn' id='preview'");?>
<?php endif;?>
+10 -5
View File
@@ -156,11 +156,16 @@
}
else
{
foreach($modulePath as $key => $module)
{
if(!common::printLink('testcase', 'browse', "productID=$case->product&branch=$module->branch&browseType=byModule&param=$module->id", $module->name)) echo $module->name;
if(isset($modulePath[$key + 1])) echo $lang->arrow;
}
if($caseModule->branch and isset($branches[$caseModule->branch]))
{
echo $branches[$caseModule->branch] . $lang->arrow;
}
foreach($modulePath as $key => $module)
{
if(!common::printLink('testcase', 'browse', "productID=$case->product&branch=$module->branch&browseType=byModule&param=$module->id", $module->name)) echo $module->name;
if(isset($modulePath[$key + 1])) echo $lang->arrow;
}
}
?>
</td>
+1 -1
View File
@@ -831,7 +831,7 @@ class testtask extends control
$caseResult = $this->testtask->createResult($runID);
if(dao::isError()) die(js::error(dao::getError()));
if('fail' == $caseResult) {
if($caseResult == 'fail') {
$response['result'] = 'success';
$response['locate'] = $this->createLink('testtask', 'results',"runID=$runID&caseID=$caseID&version=$version");
+37 -31
View File
@@ -52,46 +52,52 @@ function loadFilesName()
$(document).ready(function()
{
// First unbind ajaxForm for form.
$("form[data-type='ajax']").unbind('submit');
$("#dataform").unbind('submit');
// Bind ajaxForm for form again.
$.ajaxForm("form[data-type='ajax']", function(response)
{
if(response.locate)
$('#dataform').ajaxForm(
{
finish:function(response)
{
if(response.locate == 'reload' && response.target == 'parent')
if(response.locate)
{
parent.$.cookie('selfClose', 1);
parent.$.closeModal(null, 'this');
} else if(response.next) {
location.href = response.locate;
} else {
// Get cases result
$('#resultsContainer').load(response.locate + " #casesResults", function()
if(response.locate == 'reload' && response.target == 'parent')
{
$('tr:first').addClass("show-detail");
$('#tr-detail_1').removeClass("hide");
$('.result-item').click(function()
parent.$.cookie('selfClose', 1);
parent.$.closeModal(null, 'this');
}
else if(response.next)
{
location.href = response.locate;
}
else
{
// Get cases result
$('#resultsContainer').load(response.locate + " #casesResults", function()
{
var $this = $(this);
$this.toggleClass('show-detail');
var show = $this.hasClass('show-detail');
$this.next('.result-detail').toggleClass('hide', !show);
$this.find('.collapse-handle').toggleClass('icon-chevron-down', !show).toggleClass('icon-chevron-up', show);
$('tr:first').addClass("show-detail");
$('#tr-detail_1').removeClass("hide");
$('.result-item').click(function()
{
var $this = $(this);
$this.toggleClass('show-detail');
var show = $this.hasClass('show-detail');
$this.next('.result-detail').toggleClass('hide', !show);
$this.find('.collapse-handle').toggleClass('icon-chevron-down', !show).toggleClass('icon-chevron-up', show);
});
$('#casesResults table caption .result-tip').html($('#resultTip').html());
$("#submit").text(caseResultSave);
$("#submit").attr({"disabled":"disabled"});
});
}
}
$('#casesResults table caption .result-tip').html($('#resultTip').html());
$("#submit").text(caseResultSave);
$("#submit").attr({"disabled":"disabled"});
});
}
return false;
}
return false;
});
});
$(document).on('click', ".step-group input[type='checkbox']", function()
{
+1 -1
View File
@@ -45,7 +45,7 @@
common::printLink('todo', 'edit', "todoID=$todo->id", "<i class='icon icon-edit'></i>", '', "title='{$lang->todo->edit}' class='btn showinonlybody'");
common::printLink('todo', 'delete', "todoID=$todo->id", "<i class='icon icon-close'></i>", 'hiddenwin', "title='{$lang->todo->delete}' class='btn showinonlybody'");
echo html::a('#commentModal', '<i class="icon-chat-line"></i>', '', "title='{$lang->comment}' data-toggle='modal' class='btn'");
if(common::hasPriv('action', 'comment', $todo)) echo html::a('#commentModal', '<i class="icon-chat-line"></i>', '', "title='{$lang->comment}' data-toggle='modal' class='btn'");
if($this->session->todoList)
{
+6 -15
View File
@@ -444,12 +444,7 @@ class treeModel extends model
->orderBy('grade desc, type, `order`')
->get();
$stmt = $this->dbh->query($query);
while($module = $stmt->fetch())
{
/* if not manage, ignore unused modules. */
if(!$manage and !isset($projectModules[$module->id])) continue;
$this->buildTree($treeMenu, $module, 'task', $userFunc, $extra);
}
while($module = $stmt->fetch()) $this->buildTree($treeMenu, $module, 'task', $userFunc, $extra);
if(isset($treeMenu[0]) and $branch) $treeMenu[0] = "<li><a>$branchName</a><ul>{$treeMenu[0]}</ul></li>";
$tree .= isset($treeMenu[0]) ? $treeMenu[0] : '';
}
@@ -465,12 +460,7 @@ class treeModel extends model
$treeMenu = array();
$query = $this->dao->select('*')->from(TABLE_MODULE)->where("root = '" . (int)$rootID . "' and type = 'task'")->andWhere('deleted')->eq(0)->orderBy('grade desc, type, `order`')->get();
$stmt = $this->dbh->query($query);
while($module = $stmt->fetch())
{
/* if not manage, ignore unused modules. */
if(!$manage and !isset($projectModules[$module->id])) continue;
$this->buildTree($treeMenu, $module, 'task', $userFunc, $extra);
}
while($module = $stmt->fetch()) $this->buildTree($treeMenu, $module, 'task', $userFunc, $extra);
$tree = isset($treeMenu[0]) ? $treeMenu[0] : '';
$menu .= $tree . '</li>';
@@ -508,7 +498,7 @@ class treeModel extends model
$fullTrees = array();
foreach($products as $id => $product)
{
$productInfo = $this->product->getById($id);
$productInfo = $this->product->getById($id);
/* tree menu. */
$productTree = array();
$branchTrees = array();
@@ -520,10 +510,10 @@ class treeModel extends model
->orderBy('grade desc, type, `order`')
->get();
$stmt = $this->dbh->query($query);
if($branch == 0) $productTree = $this->getDataStructure($stmt, 'task', $projectModules);
if($branch == 0) $productTree = $this->getDataStructure($stmt, 'task');
if($branch != 0)
{
$children = $this->getDataStructure($stmt, 'task', $projectModules);
$children = $this->getDataStructure($stmt, 'task');
if($children) $branchTrees[] = array('name' => $branchName, 'root' => $id, 'type' => 'branch', 'actions' => false, 'children' => $children);
}
}
@@ -1335,6 +1325,7 @@ class treeModel extends model
{
$this->dao->update(TABLE_MODULE)->set('root')->eq($module->root)->where('id')->in($childs)->exec();
$this->dao->update(TABLE_MODULE)->set('branch')->eq(0)->where('id')->in($childs)->exec();
if($self->type == 'doc') $this->dao->update(TABLE_DOC)->set('`lib`')->eq($module->root)->where('module')->eq($moduleID)->exec();
}
$this->fixModulePath(isset($module->root) ? $module->root : $self->root, $self->type);
if(isset($module->root) and $module->root != $self->root) $this->changeRoot($moduleID, $self->root, $module->root, $self->type);
+2 -4
View File
@@ -107,9 +107,7 @@
<div class="table-col col-module"><?php echo html::select("branch[id$sonModule->id]", $branches, $sonModule->branch, 'class="form-control" disabled');?></div>
<?php endif;?>
<div class="table-col col-shorts"><?php echo html::input("shorts[id$sonModule->id]", $sonModule->short, "class='form-control' placeholder='{$lang->tree->short}' $disabled autocomplete='off'") . html::hidden("order[id$sonModule->id]", $sonModule->order);?></div>
<div class="table-col col-actions">
<button type="button" class="btn btn-link btn-icon btn-add" onclick="addItem(this)"><i class="icon icon-plus"></i></button>
</div>
<div class="table-col col-actions"> </div>
</div>
<?php endforeach;?>
<?php for($i = 0; $i < TREE::NEW_CHILD_COUNT ; $i ++):?>
@@ -228,7 +226,7 @@ $(function()
}
else if(action.type === 'delete')
{
window.open(action.linkTemplate.format(item.id), 'hiddenwin');
hiddenwin.location.href = action.linkTemplate.format(item.id);
}
else if(action.type === 'sort')
{
+2 -4
View File
@@ -75,9 +75,7 @@
echo html::hidden("order[id$sonModule->id]", $sonModule->order);
?>
</div>
<div class="table-col col-actions">
<button type="button" class="btn btn-link btn-icon btn-add" onclick="addItem(this)"><i class="icon icon-plus"></i></button>
</div>
<div class="table-col col-actions"> </div>
</div>
<?php endforeach;?>
<?php for($i = 0; $i < TREE::NEW_CHILD_COUNT ; $i ++):?>
@@ -186,7 +184,7 @@ $(function()
}
else if(action.type === 'delete')
{
window.open(action.linkTemplate.format(item.id), 'hiddenwin');
hiddenwin.location.href = action.linkTemplate.format(item.id);
}
else if(action.type === 'add')
{
-1
View File
@@ -15,7 +15,6 @@ $webRoot = $this->app->getWebRoot();
$jsRoot = $webRoot . "js/";
js::set('type', $type);
?>
<?php include '../../common/view/chosen.html.php';?>
<div class='modal-dialog w-500px'>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><i class="icon icon-close"></i></button>
+4
View File
@@ -57,6 +57,8 @@ class upgrade extends control
*/
public function backup()
{
$this->session->set('upgrading', true);
$this->view->title = $this->lang->upgrade->common;
$this->display();
}
@@ -166,6 +168,7 @@ class upgrade extends control
@unlink($this->app->getAppRoot() . 'www/install.php');
@unlink($this->app->getAppRoot() . 'www/upgrade.php');
unset($_SESSION['upgrading']);
}
}
@@ -245,6 +248,7 @@ class upgrade extends control
*/
public function ajaxUpdateFile($type = '', $lastID = 0)
{
set_time_limit(0);
$result = $this->upgrade->updateFileObjectID($type, $lastID);
$response = array();
if($result['type'] == 'finish')
+4
View File
@@ -0,0 +1,4 @@
$(function()
{
setTimeout('setPing()', 1000 * 60 * 10);
});
+1
View File
@@ -101,3 +101,4 @@ $lang->upgrade->fromVersions['10_5'] = '10.5';
$lang->upgrade->fromVersions['10_5_1'] = '10.5.1';
$lang->upgrade->fromVersions['10_6'] = '10.6';
$lang->upgrade->fromVersions['11_0'] = '11.0';
$lang->upgrade->fromVersions['11_1'] = '11.1';
+1 -1
View File
@@ -35,7 +35,7 @@ $lang->upgrade->setStatusFile = '<h4>升级之前请先完成下面的操
<li>%s</li>
<li>或者删掉"<strong style="color:#ed980f">%s</strong>" 这个文件 ,重新创建一个<strong style="color:#ed980f">ok.txt</strong>文件,不需要内容。</li>
</ul>
<p><strong style="color:red">我已经仔细阅读上面提示且完成上述工作,<a href="upgrade.php">继续更新</a></strong></p>';
<p><strong style="color:red">我已经仔细阅读上面提示且完成上述工作,<a href="#" onclick="location.reload()">继续更新</a></strong></p>';
$lang->upgrade->selectVersion = '选择版本';
$lang->upgrade->continue = '继续';
$lang->upgrade->noteVersion = "务必选择正确的版本,否则会造成数据丢失。";
+1 -1
View File
@@ -35,7 +35,7 @@ $lang->upgrade->setStatusFile = '<h4>升級之前請先完成下面的操
<li>%s</li>
<li>或者刪掉"<strong style="color:#ed980f">%s</strong>" 這個檔案 ,重新創建一個<strong style="color:#ed980f">ok.txt</strong>檔案,不需要內容。</li>
</ul>
<p><strong style="color:red">我已經仔細閲讀上面提示且完成上述工作,<a href="upgrade.php">繼續更新</a></strong></p>';
<p><strong style="color:red">我已經仔細閲讀上面提示且完成上述工作,<a href="#" onclick="location.reload()">繼續更新</a></strong></p>';
$lang->upgrade->selectVersion = '選擇版本';
$lang->upgrade->continue = '繼續';
$lang->upgrade->noteVersion = "務必選擇正確的版本,否則會造成數據丟失。";
+29 -5
View File
@@ -37,6 +37,7 @@ class upgradeModel extends model
public function execute($fromVersion)
{
set_time_limit(0);
$executeXuanxuan = false;
switch($fromVersion)
{
case '0_3beta':
@@ -322,6 +323,7 @@ class upgradeModel extends model
$this->saveLogs('Execute 10_1');
$xuanxuanSql = $this->app->getAppRoot() . 'db' . DS . 'xuanxuan.sql';
$this->execSQL($xuanxuanSql);
$executeXuanxuan = true;
case '10_2': $this->saveLogs('Execute 10_2');
case '10_3': $this->saveLogs('Execute 10_3');
case '10_3_1':
@@ -339,12 +341,28 @@ class upgradeModel extends model
$this->execSQL($this->getUpgradeFile('10.5.1'));
case '10_6':
$this->saveLogs('Execute 10_6');
$xuanxuanSql = $this->app->getAppRoot() . 'db' . DS . 'upgradexuanxuan2.1.0.sql';
$this->execSQL($xuanxuanSql);
$xuanxuanSql = $this->app->getAppRoot() . 'db' . DS . 'upgradexuanxuan2.2.0.sql';
$this->execSQL($xuanxuanSql);
if(!$executeXuanxuan)
{
$xuanxuanSql = $this->app->getAppRoot() . 'db' . DS . 'upgradexuanxuan2.1.0.sql';
$this->execSQL($xuanxuanSql);
$xuanxuanSql = $this->app->getAppRoot() . 'db' . DS . 'upgradexuanxuan2.2.0.sql';
$this->execSQL($xuanxuanSql);
}
$this->initXuanxuan();
case '11_0': $this->saveLogs('Execute 11_0');
case '11_1':
$this->saveLogs('Execute 11_1');
$this->execSQL($this->getUpgradeFile('11.1'));
if(!isset($this->config->isINT) or !($this->config->isINT))
{
if(!$executeXuanxuan)
{
$xuanxuanSql = $this->app->getAppRoot() . 'db' . DS . 'upgradexuanxuan2.3.0.sql';
$this->execSQL($xuanxuanSql);
}
$this->dao->update(TABLE_CONFIG)->set('value')->eq('off')->where('`key`')->eq('isHttps')->andWhere('`section`')->eq('xuanxuan')->andWhere('`value`')->eq('0')->exec();
$this->dao->update(TABLE_CONFIG)->set('value')->eq('on')->where('`key`')->eq('isHttps')->andWhere('`section`')->eq('xuanxuan')->andWhere('`value`')->eq('1')->exec();
}
}
$this->deletePatch();
@@ -467,6 +485,12 @@ class upgradeModel extends model
$confirmContent .= file_get_contents($this->app->getAppRoot() . 'db' . DS . 'upgradexuanxuan2.1.0.sql');
$confirmContent .= file_get_contents($this->app->getAppRoot() . 'db' . DS . 'upgradexuanxuan2.2.0.sql');
case '11_0':
case '11_1':
if(!isset($this->config->isINT) or !($this->config->isINT))
{
$xuanxuanSql = $this->app->getAppRoot() . 'db' . DS . 'upgradexuanxuan2.3.0.sql';
$confirmContent .= file_get_contents($xuanxuanSql);
}
}
return str_replace('zt_', $this->config->db->prefix, $confirmContent);
}
@@ -2220,7 +2244,7 @@ class upgradeModel extends model
*/
public function checkSafeFile()
{
if($this->app->getModuleName() == 'upgrade' and $this->app->getMethodName() == 'ajaxupdatefile') return false;
if($this->app->getModuleName() == 'upgrade' and $this->session->upgrading) return false;
$statusFile = $this->app->getAppRoot() . 'www' . DIRECTORY_SEPARATOR . 'ok.txt';
return (!file_exists($statusFile) or (time() - filemtime($statusFile)) > 3600) ? $statusFile : false;
}
+1 -2
View File
@@ -42,8 +42,7 @@
<script>
<?php
foreach($needProcess as $processKey => $value) echo 'var ' . $processKey . "Finish = false;\n";
$needUpdateFile = strpos($config->installedVersion, 'pro') === false ? version_compare($config->installedVersion, '8.3', '<') : version_compare($config->installedVersion, 'pro5.4', '<');
if($needUpdateFile):?>
if(isset($needProcess['updateFile'])):?>
$(function()
{
$('a#tohome').closest('.alert').hide();
-2
View File
@@ -16,5 +16,3 @@ $config->user->custom->batchEditFields = 'dept,join,email,commiter';
$config->user->failTimes = 6;
$config->user->lockMinutes = 10;
$config->user->batchCreate = 10;
$config->user->showDeleted = 0;
-1
View File
@@ -146,7 +146,6 @@ $lang->user->error->accountDupl = "ID %saccount has been used.";
$lang->user->error->realname = "ID %smust be real name";
$lang->user->error->password = "ID %spassword must be 6 characters at least.";
$lang->user->error->mail = "ID %splease enter valid Email address";
$lang->user->error->role = "ID %srole cannot be null.";
$lang->user->error->reserved = "ID %saccount is reserved.";
$lang->user->error->verifyPassword = "Verification failed. Please enter your Login Password.";
-1
View File
@@ -146,7 +146,6 @@ $lang->user->error->accountDupl = "【ID %s】的用户名已经存在";
$lang->user->error->realname = "【ID %s】的真实姓名必须填写";
$lang->user->error->password = "【ID %s】的密码必须为六位以上";
$lang->user->error->mail = "【ID %s】的邮箱地址不正确";
$lang->user->error->role = "【ID %s】的职位不能为空";
$lang->user->error->reserved = "【ID %s】的用户名已被系统预留";
$lang->user->error->verifyPassword = "验证失败,请检查您的系统登录密码是否正确";
-1
View File
@@ -146,7 +146,6 @@ $lang->user->error->accountDupl = "【ID %s】的用戶名已經存在";
$lang->user->error->realname = "【ID %s】的真實姓名必須填寫";
$lang->user->error->password = "【ID %s】的密碼必須為六位以上";
$lang->user->error->mail = "【ID %s】的郵箱地址不正確";
$lang->user->error->role = "【ID %s】的職位不能為空";
$lang->user->error->reserved = "【ID %s】的用戶名已被系統預留";
$lang->user->error->verifyPassword = "驗證失敗,請檢查您的系統登錄密碼是否正確";
+1 -1
View File
@@ -159,6 +159,7 @@ class userModel extends model
*/
public function getUserRoles($users)
{
$this->app->loadLang('user');
$users = $this->dao->select('account, role')->from(TABLE_USER)->where('account')->in($users)->fetchPairs();
if(!$users) return array();
@@ -500,7 +501,6 @@ class userModel extends model
if(!validater::checkAccount($users[$id]['account'])) die(js::error(sprintf($this->lang->user->error->account, $id)));
if($users[$id]['realname'] == '') die(js::error(sprintf($this->lang->user->error->realname, $id)));
if($users[$id]['email'] and !validater::checkEmail($users[$id]['email'])) die(js::error(sprintf($this->lang->user->error->mail, $id)));
if(empty($users[$id]['role'])) die(js::error(sprintf($this->lang->user->error->role, $id)));
$accounts[$id] = $account;
$prev['dept'] = $users[$id]['dept'];
+1 -2
View File
@@ -82,8 +82,7 @@ if(empty($config->notMd5Pwd))js::import($jsRoot . 'md5.js');
<div class="table-col text-middle text-center">
<div id="poweredby">
<?php if($config->checkVersion):?>
<?php $siteURL = 'https://api.zentao.net';?>
<iframe id='updater' class='hidden' frameborder='0' width='100%' scrolling='no' allowtransparency='true' src="<?php echo $siteURL;?>/updater-isLatest-<?php echo $config->version;?>-<?php echo $s;?>.html?lang=<?php echo str_replace('-', '_', $this->app->getClientLang())?>"></iframe>
<iframe id='updater' class='hidden' frameborder='0' width='100%' height='45' scrolling='no' allowtransparency='true' src="<?php echo $this->createLink('misc', 'checkUpdate', "sn=$s");?>"></iframe>
<?php endif;?>
</div>
</div>
+27 -9
View File
@@ -3,16 +3,34 @@
$langType = 'zh-tw';
$langDesc = 'zh-tw';
if(empty($langType)) die('lang') . "\n";
foreach(glob('../module/*') as $moduleName)
foreach(array('../module/') as $subModuleRoot)
{
$moduleLangPath = realpath($moduleName) . '/lang/';
$defaultLangFile = $moduleLangPath . 'zh-cn.php';
$targetLangFile = $moduleLangPath . $langType . '.php';
if(!file_exists($defaultLangFile)) continue;
foreach(glob($subModuleRoot . '*') as $moduleName)
{
$realModulePath = realpath($moduleName);
$moduleLangPath = $realModulePath . '/lang/';
$defaultLangFile = $moduleLangPath . 'zh-cn.php';
$targetLangFile = $moduleLangPath . $langType . '.php';
if(file_exists($defaultLangFile))
{
system("cconv -f utf-8 -t UTF8-TW $defaultLangFile > $targetLangFile");
$defaultLang = file_get_contents($targetLangFile);
$targetLang = str_replace('zh-cn', $langDesc, $defaultLang);
file_put_contents($targetLangFile, $targetLang);
}
system("cconv -f utf-8 -t UTF8-TW $defaultLangFile > $targetLangFile");
$defaultLang = file_get_contents($targetLangFile);
$targetLang = str_replace('zh-cn', $langDesc, $defaultLang);
file_put_contents($targetLangFile, $targetLang);
$extModuleLangPath = $realModulePath . '/ext/lang/zh-cn/*.php';
foreach(glob($extModuleLangPath) as $extModuleLang)
{
$fileName = basename($extModuleLang);
if(!is_dir("{$realModulePath}/ext/lang/{$langType}/")) `mkdir -p {$realModulePath}/ext/lang/{$langType}/`;
$targetLangFile = $realModulePath . "/ext/lang/{$langType}/" . $fileName;
system("cconv -f utf-8 -t UTF8-TW $extModuleLang > $targetLangFile");
$defaultLang = file_get_contents($targetLangFile);
$targetLang = str_replace('zh-cn', $langDesc, $defaultLang);
file_put_contents($targetLangFile, $targetLang);
}
}
}
?>
+3 -3
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -17,7 +17,7 @@ class admin extends control
if(!is_numeric($setting->chatPort) or (int)$setting->chatPort <= 0 or (int)$setting->chatPort > 65535) $errors['chatPort'] = $this->lang->chat->xxdPortError;
if(!is_numeric($setting->commonPort) or (int)$setting->commonPort <= 0 or (int)$setting->commonPort > 65535) $errors['commonPort'] = $this->lang->chat->xxdPortError;
if($setting->isHttps)
if($setting->isHttps == 'on')
{
if(empty($setting->sslcrt)) $errors['sslcrt'] = $this->lang->chat->errorSSLCrt;
if(empty($setting->sslkey)) $errors['sslkey'] = $this->lang->chat->errorSSLKey;
@@ -29,9 +29,7 @@ class admin extends control
if($errors) $this->send(array('result' => 'fail', 'message' => $errors));
$result = $this->loadModel('setting')->setItems('system.common.xuanxuan', $setting);
$this->setting->setItem('system.mail.domain', $setting->server);
if(!$result) $this->send(array('result' => 'fail', 'message' => dao::getError()));
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('xuanxuan')));
}
@@ -22,7 +22,7 @@ $(function()
{
var value = $(this).val();
$('#isHttps').val(value);
if(value == 1)
if(value == 'on')
{
$('.sslTR').show();
}
@@ -87,12 +87,12 @@
<td></td>
</tr>
<?php endif;?>
<tr class='sslTR <?php if($isHttps == 0 || empty($type)) echo 'hide';?>'>
<tr class='sslTR <?php if($isHttps == 'off' || empty($type)) echo 'hide';?>'>
<th><?php echo $lang->chat->xxd->sslcrt;?></th>
<td><?php echo html::textarea('sslcrt', zget($config->xuanxuan, 'sslcrt', ''), "placeholder='{$lang->chat->placeholder->xxd->sslcrt}' class='form-control'");?></td>
<td></td>
</tr>
<tr class='sslTR <?php if($isHttps == 0 || empty($type)) echo 'hide';?>'>
<tr class='sslTR <?php if($isHttps == 'off' || empty($type)) echo 'hide';?>'>
<th><?php echo $lang->chat->xxd->sslkey;?></th>
<td><?php echo html::textarea('sslkey', zget($config->xuanxuan, 'sslkey', ''), "placeholder='{$lang->chat->placeholder->xxd->sslkey}' class='form-control'");?></td>
<td></td>
@@ -7,6 +7,9 @@ $lang->chat->xxdServer = 'ZenTao Server';
$lang->chat->downloadXXD = 'Download XXD';
$lang->chat->zentaoIntegrate = 'Zentao Integrated';
$lang->chat->zentaoClient = 'ZenTao Client is added!';
$lang->chat->getChatUsers = 'Get Chat Users';
$lang->chat->getChatGroups = 'Get Chat Groups';
$lang->chat->notifyMSG = 'Notify';
$lang->chat->turnonList = array();
$lang->chat->turnonList[1] = 'Enable';
@@ -7,6 +7,9 @@ $lang->chat->xxdServer = '禅道服务器';
$lang->chat->downloadXXD = '下载喧喧服务端';
$lang->chat->zentaoIntegrate = '禅道集成';
$lang->chat->zentaoClient = '新增禅道客户端!';
$lang->chat->getChatUsers = '获取用户';
$lang->chat->getChatGroups = '获取讨论组';
$lang->chat->notifyMSG = '消息通知';
$lang->chat->turnonList = array();
$lang->chat->turnonList[1] = '是';
@@ -26,11 +26,11 @@ class xuanxuanChat extends chatModel
$libID = isset($libIdList[0]) ? $libIdList[0] : 1;
$actions = new stdclass();
if(common::hasPriv('bug', 'create') and !empty($products)) $actions->createBug = array('title' => $this->lang->chat->createBug, 'url' => $baseURL . str_replace('/xuanxuan.php', '/index.php', helper::createLink('bug', 'create', "product=$productID", 'xhtml')), 'height' => "600px", 'width' => "800px");
if(common::hasPriv('doc', 'create') and !empty($libIdList))$actions->createDoc = array('title' => $this->lang->chat->createDoc, 'url' => $baseURL . str_replace('/xuanxuan.php', '/index.php', helper::createLink('doc', 'create', "libID=$libID", 'xhtml')), 'height' => "600px", 'width' => "800px");
if(common::hasPriv('story', 'create') and !empty($products)) $actions->createStory = array('title' => $this->lang->chat->createStory, 'url' => $baseURL . str_replace('/xuanxuan.php', '/index.php', helper::createLink('story', 'create', "product=$productID", 'xhtml')), 'height' => "600px", 'width' => "800px");
if(common::hasPriv('task', 'create') and !empty($projects)) $actions->createTask = array('title' => $this->lang->chat->createTask, 'url' => $baseURL . str_replace('/xuanxuan.php', '/index.php', helper::createLink('task', 'create', "project=$projectID", 'xhtml')), 'height' => "600px", 'width' => "800px");
if(common::hasPriv('todo', 'create')) $actions->createTodo = array('title' => $this->lang->chat->createTodo, 'url' => $baseURL . str_replace('/xuanxuan.php', '/index.php', helper::createLink('todo', 'create', '', 'xhtml')), 'height' => "600px", 'width' => "800px");
if(common::hasPriv('bug', 'create') and !empty($products)) $actions->createBug = array('title' => $this->lang->chat->createBug, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('bug', 'create', "product=$productID", 'xhtml')), 'height' => "600px", 'width' => "800px");
if(common::hasPriv('doc', 'create') and !empty($libIdList))$actions->createDoc = array('title' => $this->lang->chat->createDoc, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('doc', 'create', "libID=$libID", 'xhtml')), 'height' => "600px", 'width' => "800px");
if(common::hasPriv('story', 'create') and !empty($products)) $actions->createStory = array('title' => $this->lang->chat->createStory, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('story', 'create', "product=$productID", 'xhtml')), 'height' => "600px", 'width' => "800px");
if(common::hasPriv('task', 'create') and !empty($projects)) $actions->createTask = array('title' => $this->lang->chat->createTask, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('task', 'create', "project=$projectID", 'xhtml')), 'height' => "600px", 'width' => "800px");
if(common::hasPriv('todo', 'create')) $actions->createTodo = array('title' => $this->lang->chat->createTodo, 'url' => $baseURL . str_replace('/x.php', '/index.php', helper::createLink('todo', 'create', '', 'xhtml')), 'height' => "600px", 'width' => "800px");
$urls = array();
foreach($this->config->chat->cards as $moduleName => $methods)
@@ -65,4 +65,29 @@ class xuanxuanChat extends chatModel
unset($_SESSION['user']);
return $entries;
}
public function editUser($user = null)
{
if(empty($user->id)) return null;
$data = array();
foreach($this->config->chat->user->canEditFields as $field)
{
if(!empty($user->$field)) $data[$field] = $user->$field;
}
if(!empty($user->account) && !empty($user->password)) $data['password'] = $user->password;
if(!$data) return null;
$data['clientLang'] = $this->app->getClientLang();
$this->dao->update(TABLE_USER)->data($data)->where('id')->eq($user->id)->exec();
return $this->getUserByUserID($user->id);
}
public function getServer($backend = 'xxb')
{
$server = commonModel::getSysURL();
if(!empty($this->config->xuanxuan->server)) $server = $this->config->xuanxuan->server;
return $server;
}
}
+6 -29
View File
@@ -4,35 +4,12 @@ public function getExtensionList($userID)
return $this->loadExtension('xuanxuan')->getExtensionList($userID);
}
public function getUserListOutput($idList = array(), $userID)
public function editUser($user = null)
{
$output = new stdclass();
$output->module = 'chat';
$output->method = 'userGetList';
return $this->loadExtension('xuanxuan')->editUser($user);
}
$users = $this->getUserList($status = '', $idList, $idAsKey = false);
if(dao::isError())
{
$output->result = 'fail';
$output->message = 'Get userlist failed.';
}
else
{
$output->result = 'success';
$output->users = !empty($userID) ? array($userID) : array();
$output->data = $users;
$this->app->loadLang('user', 'sys');
$roles = $this->lang->user->roleList;
$allDepts = $this->loadModel('dept')->getListByType('dept');
$depts = array();
foreach($allDepts as $id => $dept)
{
$depts[$id] = array('name' => $dept->name, 'order' => (int)$dept->order, 'parent' => (int)$dept->parent);
}
$output->roles = $roles;
$output->depts = $depts;
}
return $output;
public function getServer($backend = 'xxb')
{
return $this->loadExtension('xuanxuan')->getServer($backend);
}
+1 -2
View File
@@ -15,7 +15,7 @@ class entry extends control
$referer = !empty($_GET['referer']) ? $this->get->referer : $referer;
$server = $this->loadModel('chat')->getServer('zentao');
if(empty($referer)) $referer = $server . str_replace('/xuanxuan.php', '/index.php', $this->createLink('my', 'index', '', 'html'));
if(empty($referer)) $referer = $server . str_replace('/x.php', '/index.php', $this->createLink('my', 'index', '', 'html'));
$output = new stdclass();
$output->module = $this->moduleName;
@@ -45,7 +45,6 @@ class entry extends control
$this->loadModel('user');
$user = $this->dao->select('*')->from(TABLE_USER)->where('id')->eq($this->session->userID)->fetch();
unset($user->password);
$this->user->cleanLocked($user->account);
$user->admin = strpos($this->app->company->admins, ",{$user->account},") !== false;
@@ -4,3 +4,8 @@ $lang->resource->admin->downloadxxd = 'downloadXXD';
$lang->admin->methodOrder[25] = 'xuanxuan';
$lang->admin->methodOrder[30] = 'downloadxxd';
$lang->resource->chat = new stdclass();
$lang->resource->chat->getChatUsers = 'getChatUsers';
$lang->resource->chat->getChatGroups = 'getChatGroups';
$lang->resource->chat->notifyMSG = 'notifyMSG';
@@ -4,3 +4,8 @@ $lang->resource->admin->downloadxxd = 'downloadXXD';
$lang->admin->methodOrder[25] = 'xuanxuan';
$lang->admin->methodOrder[30] = 'downloadxxd';
$lang->resource->chat = new stdclass();
$lang->resource->chat->getChatUsers = 'getChatUsers';
$lang->resource->chat->getChatGroups = 'getChatGroups';
$lang->resource->chat->notifyMSG = 'notifyMSG';
@@ -1,43 +0,0 @@
<?php
include '../../control.php';
class myMessage extends message
{
public function notify()
{
$response = array();
$response['result'] = true;
$response['message'] = '';
if(empty($_POST['userList']))
{
$response['result'] = false;
$response['message'] = $this->lang->message->error->noUserList;
die(json_encode($response));
}
if(empty($_POST['sender']))
{
$response['result'] = false;
$response['message'] = $this->lang->message->error->noSender;
die(json_encode($response));
}
$userList = empty($_POST['userList']) ? '' : $this->post->userList;
$title = empty($_POST['title']) ? '' : $this->post->title;
$subtitle = empty($_POST['subtitle']) ? '' : $this->post->subtitle;
$content = empty($_POST['content']) ? '' : $this->post->content;
$contentType = empty($_POST['contentType']) ? 'text' : $this->post->contentType;
$url = empty($_POST['url']) ? '' : $this->post->url;
$actions = empty($_POST['actions']) ? array() : $this->post->actions;
$sender = empty($_POST['sender']) ? 0 : $this->post->sender;
$result = $this->loadModel('chat')->createNotify($userList, $title, $subtitle, $content, $contentType, $url, $actions, $sender);
if(!$result)
{
$response['result'] = false;
$response['message'] = dao::getError();
}
die(json_encode($response));
}
}
@@ -2,7 +2,3 @@
$lang->message->typeList['xuanxuan'] = 'Client';
$lang->message->sender = 'ZenTao';
if(!isset($lang->message->error)) $lang->message->error = new stdclass();
$lang->message->error->noUserList = 'User ID list is not set.';
$lang->message->error->noSender = 'Sender information is not set.';
@@ -2,7 +2,3 @@
$lang->message->typeList['xuanxuan'] = '客户端';
$lang->message->sender = '禅道项目管理';
if(!isset($lang->message->error)) $lang->message->error = new stdclass();
$lang->message->error->noUserList = '没有设置消息发送用户列表';
$lang->message->error->noSender = '没有设置发送方信息';
@@ -0,0 +1,82 @@
<?php
include '../../control.php';
class myMisc extends misc
{
/**
* Ajax get client package.
*
* @param string $os
* @access public
* @return void
*/
public function ajaxGetClientPackage($os = '')
{
set_time_limit (0);
session_write_close();
$response = array();
$response['result'] = 'success';
$response['message'] = '';
$clientDir = $this->app->getBasePath() . 'tmp/cache/client/';
if(!is_dir($clientDir)) mkdir($clientDir, 0755, true);
$version = $this->config->xuanxuan->version;
$packageDir = $clientDir . "/$version/";
if(!is_dir($packageDir)) mkdir($packageDir, 0755, true);
$account = $this->app->user->account;
$tmpDir = $clientDir . "/$account/";
if(!is_dir($tmpDir)) mkdir($tmpDir, 0755, true);
$needCache = false;
$clientName = "zentaoclient." . $os . ".zip";
$packageFile = $packageDir . $clientName;
if(!file_exists($packageFile))
{
$url = "http://dl.cnezsoft.com/zentaoclient/$version/";
$xxFile = $url . $clientName . "?t=" . rand();
$needCache = true;
}
else
{
$xxFile = $packageFile;
}
$clientFile = $tmpDir . 'zentaoclient.zip';
if($xxHd = fopen($xxFile, "rb"))
{
if($clientHd = fopen($clientFile, "wb"))
{
while(!feof($xxHd))
{
$result = fwrite($clientHd, fread($xxHd, 1024 * 8 ), 1024 * 8 );
if($result == false)
{
$response['result'] = 'fail';
$response['message'] = sprintf($this->lang->misc->client->errorInfo->manualOpt, $xxFile);
$this->send($response);
}
}
}
else
{
$response['result'] = 'fail';
$response['message'] = sprintf($this->lang->misc->client->errorInfo->manualOpt, $xxFile);
$this->send($response);
}
fclose($xxHd);
fclose($clientHd);
}
else
{
$response['result'] = 'fail';
$response['message'] = sprintf($this->lang->misc->client->errorInfo->manualOpt, $xxFile);
$this->send($response);
}
if($needCache) file_put_contents($packageFile, file_get_contents($clientFile));
$this->send($response);
}
}
@@ -0,0 +1,29 @@
<?php
include '../../control.php';
class myMisc extends misc
{
/**
* Ajax get client package size.
*
* @access public
* @return void
*/
public function ajaxGetPackageSize()
{
$account = $this->app->user->account;
$packageFile = $this->app->getBasePath() . 'tmp/cache/client/' . $account . '/zentaoclient.zip';
$size = 0;
if(file_exists($packageFile))
{
$size = filesize($packageFile);
$size = $size ? round($size / 1048576, 2) : 0;
}
$response = array();
$response['result'] = 'success';
$response['size'] = $size;
$this->send($response);
}
}

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