diff --git a/Makefile b/Makefile index 8b25a6594f..f511627ccc 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/VERSION b/VERSION index 3ab8e9b749..257b829d27 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -11.1.stable +11.2.stable diff --git a/config/config.php b/config/config.php index cade32ee6b..487ba25ffd 100644 --- a/config/config.php +++ b/config/config.php @@ -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. diff --git a/db/standard/zentao11.2.sql b/db/standard/zentao11.2.sql new file mode 100644 index 0000000000..d99f028edc --- /dev/null +++ b/db/standard/zentao11.2.sql @@ -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; diff --git a/db/zentao.sql b/db/zentao.sql index 95ef0d351b..cc2fadefda 100644 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -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, diff --git a/doc/CHANGELOG b/doc/CHANGELOG index ff123d3647..ab3e0d6a5e 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -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 后台自定义存在注入问题 diff --git a/lib/base/front/front.class.php b/lib/base/front/front.class.php index a3c1629753..6fbe58ac12 100644 --- a/lib/base/front/front.class.php +++ b/lib/base/front/front.class.php @@ -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; } diff --git a/lib/pclzip/pclzip.class.php b/lib/pclzip/pclzip.class.php index 2d0e71e7a7..8c8614982f 100644 --- a/lib/pclzip/pclzip.class.php +++ b/lib/pclzip/pclzip.class.php @@ -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; diff --git a/module/action/model.php b/module/action/model.php index 5a67dbab75..9dfe977eb5 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -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 diff --git a/module/backup/control.php b/module/backup/control.php index b56fd98267..67d58a26db 100644 --- a/module/backup/control.php +++ b/module/backup/control.php @@ -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); } diff --git a/module/backup/model.php b/module/backup/model.php index 25555b8c87..f275209f1c 100644 --- a/module/backup/model.php +++ b/module/backup/model.php @@ -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; + } } diff --git a/module/block/model.php b/module/block/model.php index 222ca80d9d..c01fc354a2 100644 --- a/module/block/model.php +++ b/module/block/model.php @@ -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')") diff --git a/module/bug/control.php b/module/bug/control.php index 3cb4c63b8a..8fde4f0b4d 100644 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -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 = ''); diff --git a/module/bug/model.php b/module/bug/model.php index a86dc4f60c..9d2c90a7d7 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -2667,7 +2667,7 @@ class bugModel extends model $assignToLink = helper::createLink('bug', 'assignTo', "bugID=$bug->id", '', true); $assignToHtml = html::a($assignToLink, " {$assignedToText}", '', "class='$btnClass'"); - echo !common::hasPriv('bug', 'assignTo') ? "{$assignedToText}" : $assignToHtml; + echo !common::hasPriv('bug', 'assignTo', $bug) ? "{$assignedToText}" : $assignToHtml; } /** diff --git a/module/bug/view/view.html.php b/module/bug/view/view.html.php index 72c51ad4de..3810f677fd 100644 --- a/module/bug/view/view.html.php +++ b/module/bug/view/view.html.php @@ -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¶m=$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¶m=$module->id", $module->name)) echo $module->name; + if(isset($modulePath[$key + 1])) + { + $moduleTitle .= '/'; + echo $lang->arrow; + } + } } $printModule = ob_get_contents(); ob_end_clean(); diff --git a/module/common/lang/en.php b/module/common/lang/en.php index 4454234b3b..8fb5cc38cd 100644 --- a/module/common/lang/en.php +++ b/module/common/lang/en.php @@ -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' => ' 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']); +} diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index f88b2841b0..240b020a93 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -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(); diff --git a/module/common/lang/zh-tw.php b/module/common/lang/zh-tw.php index 66872d8084..da2fcb11c3 100644 --- a/module/common/lang/zh-tw.php +++ b/module/common/lang/zh-tw.php @@ -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' => ' 添加檔案夾|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 = '您沒有訪問權限'; diff --git a/module/common/model.php b/module/common/model.php index b93cb7b4ea..14ff08a922 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -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 .= "
  • " . html::a($subLink, $subLabel) . '
  • '; } - if($subMenu) - { - $label .= ""; - $subMenu = ""; - } + if(empty($subMenu)) continue; + + $label .= ""; + $subMenu = ""; } $menuItemHtml = "
  • " . html::a($link, $label, $target) . $subMenu . "
  • \n"; diff --git a/module/dept/view/edit.html.php b/module/dept/view/edit.html.php index 11dae74392..f75b7a2dc9 100644 --- a/module/dept/view/edit.html.php +++ b/module/dept/view/edit.html.php @@ -14,7 +14,6 @@ $webRoot = $this->app->getWebRoot(); $jsRoot = $webRoot . "js/"; ?> - + diff --git a/module/dev/config.php b/module/dev/config.php index 0a7c96ad59..1cde5d1427 100644 --- a/module/dev/config.php +++ b/module/dev/config.php @@ -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'; diff --git a/module/dev/lang/zh-tw.php b/module/dev/lang/zh-tw.php index 842b4f8f46..8f06049a30 100644 --- a/module/dev/lang/zh-tw.php +++ b/module/dev/lang/zh-tw.php @@ -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'] = '序號'; diff --git a/module/doc/model.php b/module/doc/model.php index 1be0ab67dc..2bf2150008 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -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) diff --git a/module/doc/view/alllibs.html.php b/module/doc/view/alllibs.html.php index b0305765d1..e88ea1faf2 100644 --- a/module/doc/view/alllibs.html.php +++ b/module/doc/view/alllibs.html.php @@ -52,7 +52,9 @@
    collector, ',' . $this->app->user->account . ',') !== false ? 'icon-star text-yellow' : 'icon-star-empty';?> collector, ',' . $this->app->user->account . ',') !== false ? $lang->doc->cancelCollection : $lang->doc->collect;?> + id&objectType=doclib");?>" title="" class='btn btn-link ajaxCollect'> + id", "", '', "title='{$lang->edit}' class='btn btn-link iframe'")?> id", "", 'hiddenwin', "title='{$lang->delete}' class='btn btn-link'")?> id&type=doc", "", '', "title='{$lang->doc->manageType}' class='btn btn-link'")?> diff --git a/module/doc/view/alllibsbylist.html.php b/module/doc/view/alllibsbylist.html.php index 7c3658bf54..c84481608e 100644 --- a/module/doc/view/alllibsbylist.html.php +++ b/module/doc/view/alllibsbylist.html.php @@ -47,7 +47,9 @@ collector, ',' . $this->app->user->account . ',') !== false ? 'icon-star text-yellow' : 'icon-star-empty';?> collector, ',' . $this->app->user->account . ',') !== false ? $lang->doc->cancelCollection : $lang->doc->collect;?> + id&objectType=doclib");?>" title="" class='btn btn-link ajaxCollect'> + id", "", '', "title='{$lang->edit}' class='btn btn-link iframe'")?> id", "", 'hiddenwin', "title='{$lang->delete}' class='btn btn-link'")?> id&type=doc", "", '', "title='{$lang->doc->manageType}' class='btn btn-link'")?> diff --git a/module/doc/view/browse.html.php b/module/doc/view/browse.html.php index 681f0cc1ea..a390fffaeb 100644 --- a/module/doc/view/browse.html.php +++ b/module/doc/view/browse.html.php @@ -104,7 +104,9 @@ var browseType = ''; + id&objectType=doclib");?>" title="" class='btn btn-link ajaxCollect'> + id", "", '', "title='{$lang->edit}' class='btn btn-link iframe'")?> id&type=doc", "", '', "title='{$lang->tree->manage}' class='btn btn-link'")?> @@ -138,7 +140,9 @@ var browseType = ''; + id&objectType=module");?>" title="" class='btn btn-link ajaxCollect'> + @@ -153,7 +157,9 @@ var browseType = ''; addedDate, 'm-d H:i');?> editedDate, 'm-d H:i');?> + id&objectType=doc");?>" title="" class='btn btn-link ajaxCollect'> + id", "", '', "title='{$lang->edit}' class='btn btn-link'")?> id", "", 'hiddenwin', "title='{$lang->delete}' class='btn btn-link'")?> diff --git a/module/doc/view/browsebygrid.html.php b/module/doc/view/browsebygrid.html.php index fafd7fc8d3..bb3a3d3565 100644 --- a/module/doc/view/browsebygrid.html.php +++ b/module/doc/view/browsebygrid.html.php @@ -65,7 +65,9 @@
    id, 0) . $lang->doc->item;?>
    + id&objectType=doclib");?>" title="" class='btn btn-link ajaxCollect'> + id", "", '', "title='{$lang->edit}' class='btn btn-link iframe'")?>
    @@ -105,7 +107,9 @@
    docCount . $lang->doc->item;?>
    - id}&objectType=module", "", 'hiddenwin', "title='{$lang->doc->collect}' class='btn btn-link'");?> + + id}&objectType=module");?>" title="doc->collect;?>" class='btn btn-link ajaxCollect'> +
    @@ -120,7 +124,9 @@
    addedBy);?>
    + id}&objectType=doc");?>" title="" class='btn btn-link ajaxCollect'> + id}", "", '', "title='{$lang->edit}' class='btn btn-link'")?> id}", "", '', "title='{$lang->delete}' class='btn btn-link'")?>
    diff --git a/module/doc/view/objectlibs.html.php b/module/doc/view/objectlibs.html.php index eb753835a3..107d2d4f5e 100644 --- a/module/doc/view/objectlibs.html.php +++ b/module/doc/view/objectlibs.html.php @@ -57,7 +57,9 @@ collector, ',' . $this->app->user->account . ',') !== false ? 'icon-star text-yellow' : 'icon-star-empty';?> collector, ',' . $this->app->user->account . ',') !== false ? $lang->doc->cancelCollection : $lang->doc->collect;?>
    + " title="" class='btn btn-link ajaxCollect'> + ", '', "title='{$lang->edit}' class='btn btn-link iframe'")?> main)) common::printLink('doc', 'deleteLib', "libID=$libID", "", 'hiddenwin', "title='{$lang->delete}' class='btn btn-link'")?> ", '', "title='{$lang->doc->manageType}' class='btn btn-link'")?> diff --git a/module/doc/view/objectlibsbylist.html.php b/module/doc/view/objectlibsbylist.html.php index d87a7878c3..6d7b963501 100644 --- a/module/doc/view/objectlibsbylist.html.php +++ b/module/doc/view/objectlibsbylist.html.php @@ -35,7 +35,9 @@ collector, ',' . $this->app->user->account . ',') !== false ? 'icon-star text-yellow' : 'icon-star-empty';?> collector, ',' . $this->app->user->account . ',') !== false ? $lang->doc->cancelCollection : $lang->doc->collect;?> + " title="" class='btn btn-link ajaxCollect'> + ", '', "title='{$lang->edit}' class='btn btn-link iframe'")?> main)) common::printLink('doc', 'deleteLib', "libID=$libID", "", 'hiddenwin', "title='{$lang->delete}' class='btn btn-link'")?> ", '', "title='{$lang->doc->manageType}' class='btn btn-link'")?> diff --git a/module/git/lang/en.php b/module/git/lang/en.php index fb1becaa0d..27dfeac017 100644 --- a/module/git/lang/en.php +++ b/module/git/lang/en.php @@ -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'; diff --git a/module/git/lang/zh-tw.php b/module/git/lang/zh-tw.php index 504e5f147f..9e52166dcc 100644 --- a/module/git/lang/zh-tw.php +++ b/module/git/lang/zh-tw.php @@ -10,7 +10,6 @@ * @link http://www.zentao.net */ /* 方法列表。*/ -$lang->git = new stdclass(); $lang->git->common = 'Git'; $lang->git->cat = '查看原始碼'; $lang->git->diff = '比較原始碼'; diff --git a/module/git/model.php b/module/git/model.php index 496f425851..5f4efab6f7 100644 --- a/module/git/model.php +++ b/module/git/model.php @@ -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); diff --git a/module/group/css/browse.css b/module/group/css/browse.css index 1cb346bdb5..fd03a05ba4 100644 --- a/module/group/css/browse.css +++ b/module/group/css/browse.css @@ -1 +1,3 @@ .user {display:block; width:80px; float:left; overflow:hidden} + +#groupList tbody tr.even td{word-wrap:break-word;} diff --git a/module/misc/control.php b/module/misc/control.php index cb0a5ad12c..ec78640a24 100644 --- a/module/misc/control.php +++ b/module/misc/control.php @@ -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. * diff --git a/module/misc/lang/en.php b/module/misc/lang/en.php index 58f3cc5233..15a735b4c2 100644 --- a/module/misc/lang/en.php +++ b/module/misc/lang/en.php @@ -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 %s does not exist. Create it.'; -$lang->misc->client->errorInfo->dirNotWritable = 'The dir %s is not writable.
    Please exec:sudo chmod 777 %s 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' => '

    Add upgrade logs and database checkup after upgrading

    Fixed ZenTao client and other bugs, and optimized details.

    '); + $lang->misc->feature->all['11.1.stable'][] = array('title'=>'Fix Bug.'); $lang->misc->feature->all['11.0.stable'][] = array('title'=>'ZenTao integrate Xuanxuan'); diff --git a/module/misc/lang/zh-cn.php b/module/misc/lang/zh-cn.php index fc9bf03f6f..c8f9cfab5a 100644 --- a/module/misc/lang/zh-cn.php +++ b/module/misc/lang/zh-cn.php @@ -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 = '客户端下载存储路径 %s 不存在,请创建该目录。'; -$lang->misc->client->errorInfo->dirNotWritable = '客户端下载存储路径 %s 不可写
    linux下面请执行命令:sudo chmod 777 %s来修正'; - $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' => '

    增加升级日志和升级后数据库检查的功能

    修复禅道集成客户端和其他若干bug,完善细节

    '); + $lang->misc->feature->all['11.1.stable'][] = array('title'=>'主要修复Bug。'); $lang->misc->feature->all['11.0.stable'][] = array('title'=>'禅道集成喧喧'); diff --git a/module/misc/lang/zh-tw.php b/module/misc/lang/zh-tw.php index 805c2ec805..5a0d901f66 100644 --- a/module/misc/lang/zh-tw.php +++ b/module/misc/lang/zh-tw.php @@ -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 = '客戶端下載存儲路徑 %s 不存在,請創建該目錄。'; -$lang->misc->client->errorInfo->dirNotWritable = '客戶端下載存儲路徑 %s 不可寫
    linux下面請執行命令:sudo chmod 777 %s來修正'; - $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' => '

    增加升級日誌和升級後資料庫檢查的功能

    修復禪道整合客戶端和其他若干bug,完善細節

    '); + $lang->misc->feature->all['11.1.stable'][] = array('title'=>'主要修復Bug。'); $lang->misc->feature->all['11.0.stable'][] = array('title'=>'禪道整合喧喧'); diff --git a/module/misc/view/checkupdate.html.php b/module/misc/view/checkupdate.html.php index 1d2c232160..a382cecefd 100644 --- a/module/misc/view/checkupdate.html.php +++ b/module/misc/view/checkupdate.html.php @@ -1,7 +1,7 @@ - style='color:white; font-size:13px; text-align:center'> +server->http_user_agen, 'opera') === false) echo "bgcolor='transparent'";?> style='color:white; font-size:13px; text-align:center'> diff --git a/module/product/model.php b/module/product/model.php index 8ea051a61a..c971f6294f 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -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; } /** diff --git a/module/product/view/ajaxgetdropmenu.html.php b/module/product/view/ajaxgetdropmenu.html.php index 502d23577c..8b46a8995a 100644 --- a/module/product/view/ajaxgetdropmenu.html.php +++ b/module/product/view/ajaxgetdropmenu.html.php @@ -74,8 +74,8 @@ foreach($products as $product) ?>
    diff --git a/module/project/view/ajaxgetdropmenu.html.php b/module/project/view/ajaxgetdropmenu.html.php index d30fc29ad3..af3f7981f7 100644 --- a/module/project/view/ajaxgetdropmenu.html.php +++ b/module/project/view/ajaxgetdropmenu.html.php @@ -49,8 +49,8 @@ foreach($projects as $project) ?>
    diff --git a/module/project/view/grouptask.html.php b/module/project/view/grouptask.html.php index 41b68c4266..7e0505fe07 100644 --- a/module/project/view/grouptask.html.php +++ b/module/project/view/grouptask.html.php @@ -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++; diff --git a/module/project/view/kanban.html.php b/module/project/view/kanban.html.php index ecb6bf0ad9..2806e366be 100644 --- a/module/project/view/kanban.html.php +++ b/module/project/view/kanban.html.php @@ -159,7 +159,7 @@ $account = $this->app->user->account;
    " . zget($realnames, $bug->assignedTo) . ""; - if(empty($task->assignedTo)) $assignedToRealName = "{$lang->task->noAssigned}"; + if(empty($bug->assignedTo)) $assignedToRealName = "{$lang->task->noAssigned}"; echo html::a($this->createLink('bug', 'assignTo', "bugID={$bug->id}", '', true), ' ' . $assignedToRealName, '', 'class="btn btn-icon-left kanbaniframe bug-assignedTo"');?> bug->statusList, $bug->status);?>
    diff --git a/module/release/model.php b/module/release/model.php index b84cd02dfa..bb22044618 100644 --- a/module/release/model.php +++ b/module/release/model.php @@ -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(); diff --git a/module/release/view/browse.html.php b/module/release/view/browse.html.php index ebe663e5b0..b8bfd9d52a 100644 --- a/module/release/view/browse.html.php +++ b/module/release/view/browse.html.php @@ -55,8 +55,8 @@ id"), sprintf('%03d', $release->id));?> marker ? "" . $release->name : $release->name; - echo html::a(inlink('view', "release=$release->id"), $releaseName); + $flagIcon = $release->marker ? " " : ''; + echo $flagIcon . html::a(inlink('view', "release=$release->id"), $release->name); ?> createLink('build', 'view', "buildID=$release->buildID"), $release->buildName);?> diff --git a/module/release/view/view.html.php b/module/release/view/view.html.php index 6bac17fa8c..c2e019edfe 100644 --- a/module/release/view/view.html.php +++ b/module/release/view/view.html.php @@ -21,8 +21,8 @@
    id;?> - marker ? "" . $release->name : $release->name;?> - + marker ? " " : '';?> + name;?> deleted):?> release->deleted;?> diff --git a/module/report/model.php b/module/report/model.php index fdaa2aa2f0..0e249dd78d 100644 --- a/module/report/model.php +++ b/module/report/model.php @@ -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; diff --git a/module/story/control.php b/module/story/control.php index 5f98473209..cb614ef09c 100644 --- a/module/story/control.php +++ b/module/story/control.php @@ -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); } diff --git a/module/story/view/view.html.php b/module/story/view/view.html.php index 21df901cfa..ce2a273682 100644 --- a/module/story/view/view.html.php +++ b/module/story/view/view.html.php @@ -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; diff --git a/module/svn/lang/en.php b/module/svn/lang/en.php index 8031ede3e0..d109ef2b4e 100644 --- a/module/svn/lang/en.php +++ b/module/svn/lang/en.php @@ -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'; diff --git a/module/svn/lang/zh-tw.php b/module/svn/lang/zh-tw.php index 3619d90b30..285ed2e212 100644 --- a/module/svn/lang/zh-tw.php +++ b/module/svn/lang/zh-tw.php @@ -10,7 +10,6 @@ * @link http://www.zentao.net */ /* 方法列表。*/ -$lang->svn = new stdclass(); $lang->svn->common = 'Subversion'; $lang->svn->cat = '查看原始碼'; $lang->svn->diff = '比較原始碼'; diff --git a/module/task/css/create.css b/module/task/css/create.css index d9e30cfcb3..d63830043b 100644 --- a/module/task/css/create.css +++ b/module/task/css/create.css @@ -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%;} diff --git a/module/task/js/create.js b/module/task/js/create.js index 576d6d7545..0c67732bcd 100644 --- a/module/task/js/create.js +++ b/module/task/js/create.js @@ -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; } diff --git a/module/task/model.php b/module/task/model.php index a94af1c135..70e5fab50e 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -2646,7 +2646,7 @@ class taskModel extends model $assignToLink = helper::createLink('task', 'assignTo', "projectID=$task->project&taskID=$task->id", '', true); $assignToHtml = html::a($assignToLink, " {$assignedToText}", '', "class='$btnClass'"); - echo !common::hasPriv('task', 'assignTo') ? "{$assignedToText}" : $assignToHtml; + echo !common::hasPriv('task', 'assignTo', $task) ? "{$assignedToText}" : $assignToHtml; } /** diff --git a/module/testcase/control.php b/module/testcase/control.php index ce98ec767a..ec65893fe0 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -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(); } diff --git a/module/testcase/js/batchcreate.js b/module/testcase/js/batchcreate.js index 6ce0166461..8f04e467a7 100644 --- a/module/testcase/js/batchcreate.js +++ b/module/testcase/js/batchcreate.js @@ -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'); diff --git a/module/testcase/lang/en.php b/module/testcase/lang/en.php index 7479b0c541..a89a21d2e9 100644 --- a/module/testcase/lang/en.php +++ b/module/testcase/lang/en.php @@ -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'; diff --git a/module/testcase/lang/zh-cn.php b/module/testcase/lang/zh-cn.php index dc74f6d72d..8983c59994 100644 --- a/module/testcase/lang/zh-cn.php +++ b/module/testcase/lang/zh-cn.php @@ -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'] = '正常'; diff --git a/module/testcase/lang/zh-tw.php b/module/testcase/lang/zh-tw.php index b40c77db18..c96cfc4a3d 100644 --- a/module/testcase/lang/zh-tw.php +++ b/module/testcase/lang/zh-tw.php @@ -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'] = '正常'; diff --git a/module/testcase/view/caseheader.html.php b/module/testcase/view/caseheader.html.php index 5e7d41e261..acefe66d7a 100644 --- a/module/testcase/view/caseheader.html.php +++ b/module/testcase/view/caseheader.html.php @@ -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 "
    "; - echo html::a('javascript:;', "{$current}" . " ", '', "class='btn btn-link {$active}' data-toggle='dropdown'"); - echo "
    '; + echo html::a($this->createLink('testcase', 'groupCase', "productID=$productID&branch=$branch&groupBy=story"), "{$lang->testcase->groupByStories}", '', "class='btn btn-link $active'"); + echo '
    '; } elseif($hasZeroPriv and $menuType == 'zerocase') { diff --git a/module/testcase/view/create.html.php b/module/testcase/view/create.html.php index 0677028730..b300f59685 100644 --- a/module/testcase/view/create.html.php +++ b/module/testcase/view/create.html.php @@ -70,7 +70,7 @@ searchMore . '"');?> - + createLink('story', 'view', "storyID=$storyID", '', true), $lang->preview, '', "class='btn' id='preview'");?> diff --git a/module/testcase/view/view.html.php b/module/testcase/view/view.html.php index f8e739eebe..09317f79cc 100644 --- a/module/testcase/view/view.html.php +++ b/module/testcase/view/view.html.php @@ -156,11 +156,16 @@ } else { - foreach($modulePath as $key => $module) - { - if(!common::printLink('testcase', 'browse', "productID=$case->product&branch=$module->branch&browseType=byModule¶m=$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¶m=$module->id", $module->name)) echo $module->name; + if(isset($modulePath[$key + 1])) echo $lang->arrow; + } } ?> diff --git a/module/testtask/control.php b/module/testtask/control.php index 8a18e5c109..fb6e695005 100644 --- a/module/testtask/control.php +++ b/module/testtask/control.php @@ -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"); diff --git a/module/testtask/js/runcase.js b/module/testtask/js/runcase.js index 27843e6918..ca33d440ee 100644 --- a/module/testtask/js/runcase.js +++ b/module/testtask/js/runcase.js @@ -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() { diff --git a/module/todo/view/view.html.php b/module/todo/view/view.html.php index 72240e1a13..6c55be83c7 100644 --- a/module/todo/view/view.html.php +++ b/module/todo/view/view.html.php @@ -45,7 +45,7 @@ common::printLink('todo', 'edit', "todoID=$todo->id", "", '', "title='{$lang->todo->edit}' class='btn showinonlybody'"); common::printLink('todo', 'delete', "todoID=$todo->id", "", 'hiddenwin', "title='{$lang->todo->delete}' class='btn showinonlybody'"); - echo html::a('#commentModal', '', '', "title='{$lang->comment}' data-toggle='modal' class='btn'"); + if(common::hasPriv('action', 'comment', $todo)) echo html::a('#commentModal', '', '', "title='{$lang->comment}' data-toggle='modal' class='btn'"); if($this->session->todoList) { diff --git a/module/tree/model.php b/module/tree/model.php index a78b4652ce..dc77d905da 100644 --- a/module/tree/model.php +++ b/module/tree/model.php @@ -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] = "
  • $branchName
      {$treeMenu[0]}
  • "; $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 . ''; @@ -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); diff --git a/module/tree/view/browse.html.php b/module/tree/view/browse.html.php index 2b9c0fe1ab..e5d8051558 100644 --- a/module/tree/view/browse.html.php +++ b/module/tree/view/browse.html.php @@ -107,9 +107,7 @@
    id]", $branches, $sonModule->branch, 'class="form-control" disabled');?>
    id]", $sonModule->short, "class='form-control' placeholder='{$lang->tree->short}' $disabled autocomplete='off'") . html::hidden("order[id$sonModule->id]", $sonModule->order);?>
    -
    - -
    +
    @@ -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') { diff --git a/module/tree/view/browsetask.html.php b/module/tree/view/browsetask.html.php index 2f1e4f2edb..6319d43031 100644 --- a/module/tree/view/browsetask.html.php +++ b/module/tree/view/browsetask.html.php @@ -75,9 +75,7 @@ echo html::hidden("order[id$sonModule->id]", $sonModule->order); ?> -
    - -
    +
    @@ -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') { diff --git a/module/tree/view/edit.html.php b/module/tree/view/edit.html.php index 1bcd06b5c1..abaf173532 100644 --- a/module/tree/view/edit.html.php +++ b/module/tree/view/edit.html.php @@ -15,7 +15,6 @@ $webRoot = $this->app->getWebRoot(); $jsRoot = $webRoot . "js/"; js::set('type', $type); ?> -