Merge branch 'master' of https://github.com/easysoft/zentaopms
This commit is contained in:
+1
-1
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
|
||||
if(!function_exists('getWebRoot')){function getWebRoot(){}}
|
||||
|
||||
/* 基本设置。Basic settings. */
|
||||
$config->version = '11.6.2'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
|
||||
$config->version = '11.6.3'; // 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.
|
||||
|
||||
@@ -0,0 +1,937 @@
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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',
|
||||
`subStatus` varchar(30) NOT NULL DEFAULT '',
|
||||
`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;
|
||||
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;
|
||||
CREATE TABLE `zt_burn` (
|
||||
`project` mediumint(8) unsigned NOT NULL,
|
||||
`task` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
`date` date NOT NULL,
|
||||
`estimate` float NOT NULL,
|
||||
`left` float NOT NULL,
|
||||
`consumed` float NOT NULL,
|
||||
PRIMARY KEY (`project`,`date`,`task`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
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',
|
||||
`subStatus` varchar(30) NOT NULL DEFAULT '',
|
||||
`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,
|
||||
`fromCaseVersion` 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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
CREATE TABLE IF NOT EXISTS `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,
|
||||
`freePasswd` enum('0','1') NOT NULL DEFAULT '0',
|
||||
`ip` varchar(100) NOT NULL,
|
||||
`desc` text NOT NULL,
|
||||
`createdBy` varchar(30) NOT NULL,
|
||||
`createdDate` datetime NOT NULL,
|
||||
`calledTime` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`editedBy` varchar(30) NOT NULL,
|
||||
`editedDate` datetime NOT NULL,
|
||||
`deleted` enum('0', '1') NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY `id` (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
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;
|
||||
CREATE TABLE `zt_file` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`pathname` char(100) 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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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 '',
|
||||
`subStatus` 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;
|
||||
CREATE TABLE `zt_productplan` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`product` mediumint(8) unsigned NOT NULL,
|
||||
`branch` mediumint(8) unsigned NOT NULL,
|
||||
`parent` mediumint(9) NOT NULL DEFAULT '0',
|
||||
`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;
|
||||
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,
|
||||
`subStatus` varchar(30) NOT NULL DEFAULT '',
|
||||
`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;
|
||||
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;
|
||||
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;
|
||||
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',
|
||||
`subStatus` varchar(30) NOT NULL DEFAULT '',
|
||||
`deleted` enum('0','1') NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `product` (`product`),
|
||||
KEY `build` (`build`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
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;
|
||||
CREATE TABLE IF NOT EXISTS `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 '',
|
||||
`subStatus` varchar(30) NOT NULL DEFAULT '',
|
||||
`color` char(7) NOT NULL,
|
||||
`stage` enum('','wait','planned','projected','developing','developed','testing','tested','verified','released', 'closed') NOT NULL DEFAULT 'wait',
|
||||
`stagedBy` char(30) NOT NULL,
|
||||
`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(8) unsigned 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;
|
||||
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;
|
||||
CREATE TABLE IF NOT EXISTS `zt_storystage` (
|
||||
`story` mediumint(8) unsigned NOT NULL,
|
||||
`branch` mediumint(8) unsigned NOT NULL,
|
||||
`stage` varchar(50) NOT NULL,
|
||||
`stagedBy` char(30) NOT NULL,
|
||||
UNIQUE KEY `story_branch` (`story`,`branch`),
|
||||
KEY `story` (`story`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
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;
|
||||
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',
|
||||
`subStatus` varchar(30) NOT NULL DEFAULT '',
|
||||
`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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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',
|
||||
`subStatus` varchar(30) NOT NULL DEFAULT '',
|
||||
`deleted` enum('0','1') NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `product` (`product`),
|
||||
KEY `build` (`build`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
CREATE TABLE `zt_translation` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`lang` varchar(30) NOT NULL,
|
||||
`module` varchar(30) NOT NULL,
|
||||
`key` varchar(100) NOT NULL,
|
||||
`value` text NOT NULL,
|
||||
`referer` text NOT NULL,
|
||||
`status` varchar(30) NOT NULL,
|
||||
`translator` char(30) NOT NULL,
|
||||
`translatedTime` datetime NOT NULL,
|
||||
`reviewer` char(30) NOT NULL,
|
||||
`reviewedTime` datetime NOT NULL,
|
||||
`reason` text NOT NULL,
|
||||
`version` varchar(20) NOT NULL,
|
||||
`mode` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `lang_module_key_mode` (`lang`,`module`,`key`,`mode`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
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;
|
||||
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 '',
|
||||
`mobile` char(11) NOT NULL DEFAULT '',
|
||||
`phone` char(20) NOT NULL DEFAULT '',
|
||||
`weixin` varchar(90) NOT NULL DEFAULT '',
|
||||
`dingding` varchar(90) NOT NULL DEFAULT '',
|
||||
`slack` varchar(90) NOT NULL DEFAULT '',
|
||||
`whatsapp` varchar(90) 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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
@@ -1026,7 +1026,6 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(1, 'admin', 'index'),
|
||||
(1, 'admin', 'safe'),
|
||||
(1, 'api', 'debug'),
|
||||
(1, 'api', 'getModel'),
|
||||
(1, 'api', 'sql'),
|
||||
(1, 'backup', 'backup'),
|
||||
(1, 'backup', 'change'),
|
||||
@@ -1433,7 +1432,6 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(1, 'user', 'view'),
|
||||
(1, 'user', 'unbind'),
|
||||
(2, 'action', 'editComment'),
|
||||
(2, 'api', 'getModel'),
|
||||
(2, 'bug', 'activate'),
|
||||
(2, 'bug', 'assignTo'),
|
||||
(2, 'bug', 'batchAssignTo'),
|
||||
@@ -1620,7 +1618,6 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(2, 'user', 'todo'),
|
||||
(2, 'user', 'view'),
|
||||
(3, 'action', 'editComment'),
|
||||
(3, 'api', 'getModel'),
|
||||
(3, 'bug', 'activate'),
|
||||
(3, 'bug', 'assignTo'),
|
||||
(3, 'bug', 'batchClose'),
|
||||
@@ -1847,7 +1844,6 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(4, 'action', 'trash'),
|
||||
(4, 'action', 'undelete'),
|
||||
(4, 'admin', 'index'),
|
||||
(4, 'api', 'getModel'),
|
||||
(4, 'bug', 'activate'),
|
||||
(4, 'bug', 'assignTo'),
|
||||
(4, 'bug', 'batchAssignTo'),
|
||||
@@ -2086,7 +2082,6 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(5, 'action', 'trash'),
|
||||
(5, 'action', 'undelete'),
|
||||
(5, 'admin', 'index'),
|
||||
(5, 'api', 'getModel'),
|
||||
(5, 'bug', 'activate'),
|
||||
(5, 'bug', 'assignTo'),
|
||||
(5, 'bug', 'batchAssignTo'),
|
||||
@@ -2351,7 +2346,6 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(6, 'action', 'trash'),
|
||||
(6, 'action', 'undelete'),
|
||||
(6, 'admin', 'index'),
|
||||
(6, 'api', 'getModel'),
|
||||
(6, 'bug', 'activate'),
|
||||
(6, 'bug', 'assignTo'),
|
||||
(6, 'bug', 'batchAssignTo'),
|
||||
@@ -2588,7 +2582,6 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(7, 'action', 'trash'),
|
||||
(7, 'action', 'undelete'),
|
||||
(7, 'admin', 'index'),
|
||||
(7, 'api', 'getModel'),
|
||||
(7, 'bug', 'activate'),
|
||||
(7, 'bug', 'assignTo'),
|
||||
(7, 'bug', 'batchClose'),
|
||||
@@ -2838,7 +2831,6 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(8, 'action', 'trash'),
|
||||
(8, 'action', 'undelete'),
|
||||
(8, 'admin', 'index'),
|
||||
(8, 'api', 'getModel'),
|
||||
(8, 'bug', 'activate'),
|
||||
(8, 'bug', 'assignTo'),
|
||||
(8, 'bug', 'batchAssignTo'),
|
||||
@@ -3098,7 +3090,6 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(9, 'action', 'trash'),
|
||||
(9, 'action', 'undelete'),
|
||||
(9, 'admin', 'index'),
|
||||
(9, 'api', 'getModel'),
|
||||
(9, 'bug', 'browse'),
|
||||
(9, 'bug', 'export'),
|
||||
(9, 'bug', 'index'),
|
||||
@@ -3266,7 +3257,6 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(9, 'user', 'view'),
|
||||
(9, 'user', 'unbind'),
|
||||
(10, 'action', 'editComment'),
|
||||
(10, 'api', 'getModel'),
|
||||
(10, 'bug', 'activate'),
|
||||
(10, 'bug', 'browse'),
|
||||
(10, 'bug', 'close'),
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
2019-09-24 11.6.3
|
||||
修复的Bug:
|
||||
2722 多人任务轮流完成之后状态异常
|
||||
2755 项目下需求页面搜索异常
|
||||
2766 导入用例时解析了js代码
|
||||
|
||||
2019-09-06 11.6.2
|
||||
完成的需求:
|
||||
4346 执行 init.sh生成的脚本和后台计划任务保持一致
|
||||
|
||||
@@ -96,7 +96,8 @@ class helper extends baseHelper
|
||||
if($position !== false) $toEncoding = substr($toEncoding, 0, $position);
|
||||
|
||||
/* Check string encoding. */
|
||||
$encoding = strtolower(mb_detect_encoding($string, array('ASCII','UTF-8','GB2312','GBK','BIG5')));
|
||||
$encodings = array_merge(array('GB2312','GBK','BIG5'), mb_list_encodings());
|
||||
$encoding = strtolower(mb_detect_encoding($string, $encodings));
|
||||
if($encoding == $toEncoding) return $string;
|
||||
return mb_convert_encoding($string, $toEncoding, $encoding);
|
||||
}
|
||||
@@ -178,4 +179,4 @@ function autoloader($class)
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register('autoloader');
|
||||
spl_autoload_register('autoloader');
|
||||
|
||||
@@ -99,7 +99,7 @@ class ztclient
|
||||
$controlAPI = $this->zentao->root . $module . $this->zentao->requestFix . $method . $this->zentao->requestFix;
|
||||
if($vars)
|
||||
{
|
||||
$vars = parse_str($vars);
|
||||
parse_str($vars, $vars);
|
||||
foreach($vars as $var) $controlAPI .= $var . $this->zentao->requestFix;
|
||||
}
|
||||
$controlAPI = rtrim($controlAPI, $this->zentao->requestFix) . '.json';
|
||||
|
||||
@@ -137,6 +137,7 @@ $lang->action->desc->linkchildtask = '$date, <strong>$actor</strong> linked
|
||||
$lang->action->desc->unlinkchildrentask = '$date, <strong>$actor</strong> unlinked a child task <strong>$extra</strong>。' . "\n";
|
||||
$lang->action->desc->linkparenttask = '$date, <strong>$actor</strong> linked to a parent task <strong>$extra</strong>。' . "\n";
|
||||
$lang->action->desc->unlinkparenttask = '$date, <strong>$actor</strong> unlinked a parent task <strong>$extra</strong>。' . "\n";
|
||||
$lang->action->desc->deletechildrentask = '$date, <strong>$actor</strong> deleted a child task <strong>$extra</strong>。' . "\n";
|
||||
|
||||
/* Historical record of actions when associating and removing cases. */
|
||||
$lang->action->desc->linkrelatedcase = '$date, <strong>$actor</strong> linked a case <strong>$extra</strong>.' . "\n";
|
||||
@@ -209,6 +210,7 @@ $lang->action->label->unlinkparenttask = "unlink from parent task";
|
||||
$lang->action->label->batchcreate = "batch created tasks";
|
||||
$lang->action->label->createchildren = "create child tasks";
|
||||
$lang->action->label->managed = "managed";
|
||||
$lang->action->label->deletechildrentask = "delete children task";
|
||||
|
||||
/* Dynamic information is grouped by object. */
|
||||
$lang->action->dynamicAction = new stdclass;
|
||||
@@ -281,6 +283,7 @@ $lang->action->dynamicAction->task['canceled'] = 'Cancel Task';
|
||||
$lang->action->dynamicAction->task['activated'] = 'Activate Task';
|
||||
$lang->action->dynamicAction->task['createchildren'] = 'Create Child Task';
|
||||
$lang->action->dynamicAction->task['unlinkparenttask'] = 'Unlink Parent Task';
|
||||
$lang->action->dynamicAction->task['deletechildrentask'] = 'Delete children task';
|
||||
$lang->action->dynamicAction->task['linkparenttask'] = 'Link Parent Task';
|
||||
$lang->action->dynamicAction->task['linkchildtask'] = 'Link Child Task';
|
||||
$lang->action->dynamicAction->task['undeleted'] = 'Restore Task';
|
||||
|
||||
@@ -137,6 +137,7 @@ $lang->action->desc->linkchildtask = '$date, 由 <strong>$actor</strong>
|
||||
$lang->action->desc->unlinkchildrentask = '$date, 由 <strong>$actor</strong> 移除子任务 <strong>$extra</strong>。' . "\n";
|
||||
$lang->action->desc->linkparenttask = '$date, 由 <strong>$actor</strong> 关联到父任务 <strong>$extra</strong>。' . "\n";
|
||||
$lang->action->desc->unlinkparenttask = '$date, 由 <strong>$actor</strong> 从父任务<strong>$extra</strong>取消关联。' . "\n";
|
||||
$lang->action->desc->deletechildrentask = '$date, 由 <strong>$actor</strong> 删除子任务<strong>$extra</strong>。' . "\n";
|
||||
|
||||
/* 关联用例和移除用例时的历史操作记录。*/
|
||||
$lang->action->desc->linkrelatedcase = '$date, 由 <strong>$actor</strong> 关联相关用例 <strong>$extra</strong>。' . "\n";
|
||||
@@ -209,6 +210,7 @@ $lang->action->label->unlinkparenttask = "从父任务取消关联";
|
||||
$lang->action->label->batchcreate = "批量创建任务";
|
||||
$lang->action->label->createchildren = "创建子任务";
|
||||
$lang->action->label->managed = "维护";
|
||||
$lang->action->label->deletechildrentask = "删除子任务";
|
||||
|
||||
/* 动态信息按照对象分组 */
|
||||
$lang->action->dynamicAction = new stdclass();
|
||||
@@ -281,6 +283,7 @@ $lang->action->dynamicAction->task['canceled'] = '取消任务';
|
||||
$lang->action->dynamicAction->task['activated'] = '激活任务';
|
||||
$lang->action->dynamicAction->task['createchildren'] = '创建子任务';
|
||||
$lang->action->dynamicAction->task['unlinkparenttask'] = '从父任务取消关联';
|
||||
$lang->action->dynamicAction->task['deletechildrentask'] = '删除子任务';
|
||||
$lang->action->dynamicAction->task['linkparenttask'] = '关联到父任务';
|
||||
$lang->action->dynamicAction->task['linkchildtask'] = '关联子任务';
|
||||
$lang->action->dynamicAction->task['undeleted'] = '还原任务';
|
||||
|
||||
@@ -303,7 +303,7 @@ class actionModel extends model
|
||||
}
|
||||
$action->extra = trim(trim($action->extra), ',');
|
||||
}
|
||||
elseif($actionName == 'totask' or $actionName == 'linkchildtask' or $actionName == 'unlinkchildrentask' or $actionName == 'linkparenttask' or $actionName == 'unlinkparenttask')
|
||||
elseif($actionName == 'totask' or $actionName == 'linkchildtask' or $actionName == 'unlinkchildrentask' or $actionName == 'linkparenttask' or $actionName == 'unlinkparenttask' or $actionName == 'deletechildrentask')
|
||||
{
|
||||
$name = $this->dao->select('name')->from(TABLE_TASK)->where('id')->eq($action->extra)->fetch('name');
|
||||
if($name) $action->extra = common::hasPriv('task', 'view') ? html::a(helper::createLink('task', 'view', "taskID=$action->extra"), "#$action->extra " . $name) : "#$action->extra " . $name;
|
||||
@@ -838,7 +838,7 @@ class actionModel extends model
|
||||
}
|
||||
|
||||
$action->objectLink = helper::createLink($moduleName, $methodName, sprintf($vars, $action->objectID));
|
||||
if($action->objectType == 'user') $action->objectLink = helper::createLink($moduleName, $methodName, sprintf($vars, $action->actor));
|
||||
if($action->objectType == 'user') $action->objectLink = helper::createLink($moduleName, $methodName, sprintf($vars, $action->objectName));
|
||||
$action->objectLabel = $objectLabel;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -105,8 +105,9 @@ class api extends control
|
||||
*/
|
||||
public function sql($keyField = '')
|
||||
{
|
||||
$sql = isset($_POST['sql']) ? $this->post->sql : '';
|
||||
$this->view->results = $this->api->sql($sql, $keyField);
|
||||
die($this->display());
|
||||
die();
|
||||
//$sql = isset($_POST['sql']) ? $this->post->sql : '';
|
||||
//$this->view->results = $this->api->sql($sql, $keyField);
|
||||
//die($this->display());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ class block extends control
|
||||
}
|
||||
else
|
||||
{
|
||||
$html = "<div class='panel-body'><div class='article-content'>" . htmlspecialchars_decode($block->params->html) .'</div></div>';
|
||||
$html = "<div class='panel-body'><div class='article-content'>" . $block->params->html . '</div></div>';
|
||||
}
|
||||
}
|
||||
elseif($block->source != '')
|
||||
@@ -713,8 +713,20 @@ class block extends control
|
||||
$pager = pager::init(0, $num , 1);
|
||||
|
||||
$productStats = $this->loadModel('product')->getStats('order_desc', $this->viewType != 'json' ? $pager : '', $type);
|
||||
$projects = $this->loadModel('project')->getPairs();
|
||||
$productIdList = array();
|
||||
foreach($productStats as $product) $productIdList[] = $product->id;
|
||||
$this->loadModel('action');
|
||||
foreach($productStats as $product)
|
||||
{
|
||||
$currentProjectID = $this->dao->select('objectID')->from(TABLE_ACTION)
|
||||
->where('objectType')->eq('project')
|
||||
->andWhere('action')->eq('managed')
|
||||
->andWhere("CONCAT(extra, ',,')")->like("%$product->id,,")
|
||||
->orderBy('id_desc')
|
||||
->fetch('objectID');
|
||||
$product->currentProject = zget($projects, $currentProjectID, '');
|
||||
$productIdList[] = $product->id;
|
||||
}
|
||||
|
||||
$this->view->projects = $this->dao->select('t1.product,t2.name')->from(TABLE_PROJECTPRODUCT)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id')
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
<tr class='text-center' data-url='<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink); ?>' <?php echo $appid?>>
|
||||
<td class='c-name text-left' title='<?php echo $product->name?>'><?php echo $product->name?></td>
|
||||
<?php if($longBlock):?>
|
||||
<?php $projectName = zget($projects, $product->id, '');?>
|
||||
<td class='c-name c-project text-left' title='<?php echo $projectName;?>'><?php echo zget($projects, $product->id, '');?></td>
|
||||
<?php $projectName = $product->currentProject ? $product->currentProject : zget($projects, $product->id, '');?>
|
||||
<td class='c-name c-project text-left' title='<?php echo $projectName;?>'><?php echo $projectName;?></td>
|
||||
<?php endif;?>
|
||||
<td class="c-num"><?php echo $product->plans?></td>
|
||||
<td class="c-num"><?php echo $product->releases?></td>
|
||||
|
||||
@@ -258,7 +258,7 @@ class bug extends control
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = '';
|
||||
$response['message'] = $this->lang->saveSuccess;
|
||||
|
||||
/* Set from param if there is a object to transfer bug. */
|
||||
$bugResult = $this->bug->create($from = isset($fromObjectIDKey) ? $fromObjectIDKey : '');
|
||||
@@ -408,7 +408,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->products = $products;
|
||||
$this->view->productID = $productID;
|
||||
$this->view->productName = $this->products[$productID];
|
||||
$this->view->moduleOptionMenu = $moduleOptionMenu;
|
||||
|
||||
@@ -41,4 +41,6 @@ html[lang='en'] #deadlineTd .input-group-addon{padding: 5px 18px}
|
||||
#mainContent .center-block{padding-bottom:40px;}
|
||||
|
||||
#typeBox {width:180px;}
|
||||
#typeBox .required:after {right: 1px;}
|
||||
#osBox .required:after {right: 1px;}
|
||||
#osBox {width:190px;}
|
||||
|
||||
@@ -632,6 +632,7 @@ class bugModel extends model
|
||||
->setIF($this->post->resolution == '' and $this->post->resolvedDate =='', 'status', 'active')
|
||||
->setIF($this->post->resolution != '', 'confirmed', 1)
|
||||
->setIF($this->post->story != false and $this->post->story != $oldBug->story, 'storyVersion', $this->loadModel('story')->getVersion($this->post->story))
|
||||
->setIF(!$this->post->linkBug, 'linkBug', '')
|
||||
->remove('comment,files,labels,uid,contactListMenu')
|
||||
->get();
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ js::set('flow', $config->global->flow);
|
||||
<td class='w-600px'>
|
||||
<div class='input-group'>
|
||||
<?php echo html::select('product', $products, $productID, "onchange='loadAll(this.value);' class='form-control chosen control-product'");?>
|
||||
<?php if($this->session->currentProductType != 'normal'):?>
|
||||
<?php if($this->session->currentProductType != 'normal' and isset($products[$productID])):?>
|
||||
<?php echo html::select('branch', $branches, $branch, "onchange='loadBranch()' class='form-control chosen control-branch'");?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
$config->caselib = new stdclass();
|
||||
$config->caselib->create = new stdclass();
|
||||
$config->caselib->createcase = new stdclass();
|
||||
$config->caselib->create->requiredFields = 'name';
|
||||
$config->caselib->createcase->requiredFields = 'title,type';
|
||||
|
||||
$config->caselib->editor = new stdclass();
|
||||
$config->caselib->editor->create = array('id' => 'desc', 'tools' => 'simpleTools');
|
||||
|
||||
$config->caselib->datatable = new stdclass();
|
||||
$config->caselib->datatable->defaultField = array('id', 'pri', 'title', 'type', 'assignedTo', 'lastRunner', 'lastRunDate', 'lastRunResult', 'status', 'bugs', 'results', 'actions');
|
||||
|
||||
$config->caselib->custom = new stdclass();
|
||||
$config->caselib->custom->createFields = 'stage,pri,keywords';
|
||||
$config->caselib->customCreateFields = 'stage,pri,keywords';
|
||||
@@ -0,0 +1,737 @@
|
||||
<?php
|
||||
/**
|
||||
* The control file of caselib module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package caselib
|
||||
* @version $Id: control.php 5114 2013-07-12 06:02:59Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
class caselib extends control
|
||||
{
|
||||
public $products = array();
|
||||
|
||||
/**
|
||||
* Index page, header to browse.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->locate($this->createLink('caselib', 'browse'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create lib
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = $this->lang->saveSuccess;
|
||||
$libID = $this->caselib->create();
|
||||
if(dao::isError())
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = dao::getError();
|
||||
$this->send($response);
|
||||
}
|
||||
$this->loadModel('action')->create('caselib', $libID, 'opened');
|
||||
$response['locate'] = $this->createLink('caselib', 'browse', "libID=$libID");
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
/* Set menu. */
|
||||
$libraries = $this->caselib->getLibraries();
|
||||
$libID = $this->caselib->saveLibState(0, $libraries);
|
||||
$this->caselib->setLibMenu($libraries, $libID);
|
||||
|
||||
$this->view->title = $this->lang->caselib->common . $this->lang->colon . $this->lang->caselib->create;
|
||||
$this->view->position[] = $this->lang->caselib->common;
|
||||
$this->view->position[] = $this->lang->caselib->create;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a case lib.
|
||||
*
|
||||
* @param int $lib
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function edit($libID)
|
||||
{
|
||||
$lib = $this->caselib->getById($libID);
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = $this->lang->saveSuccess;
|
||||
$changes = $this->caselib->update($libID);
|
||||
if(dao::isError())
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = dao::getError();
|
||||
$this->send($response);
|
||||
}
|
||||
if($changes)
|
||||
{
|
||||
$actionID = $this->loadModel('action')->create('caselib', $libID, 'edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
$this->executeHooks($libID);
|
||||
|
||||
$response['locate'] = inlink('view', "libID=$libID");
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
/* Set lib menu. */
|
||||
$libraries = $this->caselib->getLibraries();
|
||||
$libID = $this->caselib->saveLibState($libID, $libraries);
|
||||
$this->caselib->setLibMenu($libraries, $libID);
|
||||
|
||||
$this->view->title = $libraries[$libID] . $this->lang->colon . $this->lang->caselib->edit;
|
||||
$this->view->position[] = html::a($this->createLink('caselib', 'browse', "libID=$libID"), $libraries[$libID]);
|
||||
$this->view->position[] = $this->lang->caselib->common;
|
||||
$this->view->position[] = $this->lang->caselib->edit;
|
||||
|
||||
$this->view->lib = $lib;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a case lib.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param string $confirm yes|no
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function delete($libID, $confirm = 'no')
|
||||
{
|
||||
if($confirm == 'no')
|
||||
{
|
||||
die(js::confirm($this->lang->caselib->libraryDelete, inlink('delete', "libID=$libID&confirm=yes")));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->caselib->delete($libID);
|
||||
|
||||
$this->executeHooks($libID);
|
||||
|
||||
/* if ajax request, send result. */
|
||||
if($this->server->ajax)
|
||||
{
|
||||
if(dao::isError())
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = dao::getError();
|
||||
}
|
||||
else
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = '';
|
||||
}
|
||||
$this->send($response);
|
||||
}
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show library case.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param string $browseType
|
||||
* @param int $param
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browse($libID = 0, $browseType = 'all', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
/* Set browse type. */
|
||||
$browseType = strtolower($browseType);
|
||||
|
||||
$libraries = $this->caselib->getLibraries();
|
||||
if(empty($libraries)) $this->locate(inlink('create'));
|
||||
|
||||
/* Save session. */
|
||||
$this->session->set('caseList', $this->app->getURI(true));
|
||||
|
||||
/* Set menu. */
|
||||
$libID = $this->caselib->saveLibState($libID, $libraries);
|
||||
setcookie('preCaseLibID', $libID, $this->config->cookieLife, $this->config->webRoot);
|
||||
if($this->cookie->preCaseLibID != $libID)
|
||||
{
|
||||
$_COOKIE['libCaseModule'] = 0;
|
||||
setcookie('libCaseModule', 0, 0, $this->config->webRoot);
|
||||
}
|
||||
|
||||
if($browseType == 'bymodule') setcookie('libCaseModule', (int)$param, 0, $this->config->webRoot);
|
||||
if($browseType != 'bymodule') $this->session->set('libBrowseType', $browseType);
|
||||
$moduleID = ($browseType == 'bymodule') ? (int)$param : ($browseType == 'bysearch' ? 0 : ($this->cookie->libCaseModule ? $this->cookie->libCaseModule : 0));
|
||||
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
|
||||
|
||||
/* Set lib menu. */
|
||||
$this->caselib->setLibMenu($libraries, $libID, $moduleID);
|
||||
|
||||
/* Load pager. */
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = pager::init($recTotal, $recPerPage, $pageID);
|
||||
|
||||
/* Build the search form. */
|
||||
$this->loadModel('testcase');
|
||||
$actionURL = $this->createLink('caselib', 'browse', "libID=$libID&browseType=bySearch&queryID=myQueryID");
|
||||
$this->caselib->buildSearchForm($libID, $libraries, $queryID, $actionURL);
|
||||
|
||||
/* Append id for secend sort. */
|
||||
$sort = $this->loadModel('common')->appendOrder($orderBy);
|
||||
|
||||
/* save session .*/
|
||||
$cases = $this->caselib->getLibCases($libID, $browseType, $queryID, $moduleID, $sort, $pager);
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', true);
|
||||
|
||||
$this->loadModel('datatable');
|
||||
$this->loadModel('tree');
|
||||
$showModule = !empty($this->config->datatable->caselibLibrary->showModule) ? $this->config->datatable->caselibLibrary->showModule : '';
|
||||
$this->view->modulePairs = $showModule ? $this->tree->getModulePairs($libID, 'caselib', $showModule) : array();
|
||||
|
||||
$this->view->title = $this->lang->caselib->common . $this->lang->colon . $libraries[$libID];
|
||||
$this->view->position[] = html::a($this->createLink('caselib', 'browse', "libID=$libID"), $libraries[$libID]);
|
||||
|
||||
$this->view->libID = $libID;
|
||||
$this->view->libName = $libraries[$libID];
|
||||
$this->view->cases = $cases;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter');
|
||||
$this->view->modules = $this->tree->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0);
|
||||
$this->view->moduleTree = $this->tree->getTreeMenu($libID, $viewType = 'caselib', $startModuleID = 0, array('treeModel', 'createCaseLibLink'));
|
||||
$this->view->pager = $pager;
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->moduleID = $moduleID;
|
||||
$this->view->moduleName = $moduleID ? $this->tree->getById($moduleID)->name : $this->lang->tree->all;
|
||||
$this->view->param = $param;
|
||||
$this->view->setShowModule = true;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create case for library.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param int $moduleID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createCase($libID, $moduleID = 0, $param = 0)
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
$this->config->testcase->create->requiredFields = $this->config->caselib->createcase->requiredFields;
|
||||
$caseResult = $this->testcase->create($bugID = 0);
|
||||
if(!$caseResult or dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
$caseID = $caseResult['id'];
|
||||
if($caseResult['status'] == 'exists')
|
||||
{
|
||||
echo js::alert(sprintf($this->lang->duplicate, $this->lang->testcase->common));
|
||||
die(js::locate($this->createLink('testcase', 'view', "caseID=$caseID"), 'parent'));
|
||||
}
|
||||
|
||||
$this->loadModel('action')->create('case', $caseID, 'Opened');
|
||||
|
||||
/* If link from no head then reload. */
|
||||
if(isonlybody()) die(js::reload('parent'));
|
||||
die(js::locate($this->createLink('caselib', 'browse', "libID={$libID}&browseType=byModule¶m={$_POST['module']}"), 'parent'));
|
||||
}
|
||||
/* Set lib menu. */
|
||||
$libraries = $this->caselib->getLibraries();
|
||||
$libID = $this->caselib->saveLibState($libID, $libraries);
|
||||
$this->caselib->setLibMenu($libraries, $libID);
|
||||
|
||||
$type = 'feature';
|
||||
$stage = '';
|
||||
$pri = 3;
|
||||
$caseTitle = '';
|
||||
$precondition = '';
|
||||
$keywords = '';
|
||||
$steps = array();
|
||||
|
||||
$this->loadModel('testcase');
|
||||
if($param)
|
||||
{
|
||||
$testcase = $this->testcase->getById((int)$param);
|
||||
$type = $testcase->type ? $testcase->type : 'feature';
|
||||
$stage = $testcase->stage;
|
||||
$pri = $testcase->pri;
|
||||
$storyID = $testcase->story;
|
||||
$caseTitle = $testcase->title;
|
||||
$precondition = $testcase->precondition;
|
||||
$keywords = $testcase->keywords;
|
||||
$steps = $testcase->steps;
|
||||
}
|
||||
|
||||
if(count($steps) < $this->config->testcase->defaultSteps)
|
||||
{
|
||||
$paddingCount = $this->config->testcase->defaultSteps - count($steps);
|
||||
$step = new stdclass();
|
||||
$step->type = 'item';
|
||||
$step->desc = '';
|
||||
$step->expect = '';
|
||||
for($i = 1; $i <= $paddingCount; $i ++) $steps[] = $step;
|
||||
}
|
||||
|
||||
$this->view->title = $libraries[$libID] . $this->lang->colon . $this->lang->testcase->create;
|
||||
$this->view->position[] = html::a($this->createLink('caselib', 'browse', "libID=$libID"), $libraries[$libID]);
|
||||
$this->view->position[] = $this->lang->caselib->common;
|
||||
$this->view->position[] = $this->lang->testcase->create;
|
||||
|
||||
foreach(explode(',', $this->config->caselib->customCreateFields) as $field) $customFields[$field] = $this->lang->testcase->$field;
|
||||
$this->view->showFields = $this->config->caselib->custom->createFields;
|
||||
$this->view->customFields = $customFields;
|
||||
$this->view->libraries = $libraries;
|
||||
$this->view->libID = $libID;
|
||||
$this->view->currentModuleID = (int)$moduleID;
|
||||
$this->view->caseTitle = $caseTitle;
|
||||
$this->view->type = $type;
|
||||
$this->view->stage = $stage;
|
||||
$this->view->pri = $pri;
|
||||
$this->view->precondition = $precondition;
|
||||
$this->view->keywords = $keywords;
|
||||
$this->view->steps = $steps;
|
||||
$this->view->moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch create case.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param int $moduleID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function batchCreateCase($libID, $moduleID = 0)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$caseID = $this->caselib->batchCreateCase($libID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
if(isonlybody()) die(js::closeModal('parent.parent', 'this'));
|
||||
die(js::locate($this->createLink('caselib', 'browse', "libID=$libID&browseType=byModule¶m=$moduleID"), 'parent'));
|
||||
}
|
||||
|
||||
$libraries = $this->caselib->getLibraries();
|
||||
if(empty($libraries)) $this->locate(inlink('create'));
|
||||
|
||||
/* Set lib menu. */
|
||||
$this->caselib->setLibMenu($libraries, $libID);
|
||||
|
||||
$currentModuleID = (int)$moduleID;
|
||||
|
||||
/* Set module option menu. */
|
||||
$moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0);
|
||||
$moduleOptionMenu['ditto'] = $this->lang->testcase->ditto;
|
||||
|
||||
$this->view->title = $libraries[$libID] . $this->lang->colon . $this->lang->testcase->batchCreate;
|
||||
$this->view->position[] = html::a($this->createLink('caselib', 'browse', "libID=$libID"), $libraries[$libID]);
|
||||
$this->view->position[] = $this->lang->testcase->batchCreate;
|
||||
$this->view->libID = $libID;
|
||||
$this->view->moduleOptionMenu = $moduleOptionMenu;
|
||||
$this->view->currentModuleID = $currentModuleID;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* View library
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function view($libID)
|
||||
{
|
||||
$lib = $this->caselib->getById($libID, true);
|
||||
|
||||
/* Set lib menu. */
|
||||
$libraries = $this->caselib->getLibraries();
|
||||
$this->caselib->setLibMenu($libraries, $libID);
|
||||
|
||||
$this->loadModel('testcase');
|
||||
$this->view->title = $lib->name . $this->lang->colon . $this->lang->caselib->view;
|
||||
$this->view->position[] = html::a($this->createLink('caselib', 'browse', "libID=$libID"), $lib->name);
|
||||
$this->view->position[] = $this->lang->caselib->common;
|
||||
$this->view->position[] = $this->lang->caselib->view;
|
||||
|
||||
$this->view->lib = $lib;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter');
|
||||
$this->view->actions = $this->loadModel('action')->getList('caselib', $libID);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get drop menu.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @param string $extra
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetDropMenu($libID, $module, $method, $extra = '')
|
||||
{
|
||||
$this->view->link = $this->caselib->getLibLink($module, $method, $extra);
|
||||
$this->view->libID = $libID;
|
||||
$this->view->module = $module;
|
||||
$this->view->method = $method;
|
||||
$this->view->extra = $extra;
|
||||
|
||||
$libraries = $this->caselib->getLibraries();
|
||||
|
||||
$this->view->libraries = $libraries;
|
||||
$this->view->librariesPinyin = common::convert2Pinyin($libraries);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* The results page of search.
|
||||
*
|
||||
* @param string $keywords
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @param mix $extra
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetMatchedItems($keywords, $module, $method, $extra)
|
||||
{
|
||||
$libraries = $this->dao->select('*')->from(TABLE_TESTSUITE)->where('deleted')->eq(0)->andWhere('name')->like("%$keywords%")->andWhere('type')->eq('library')->orderBy('`id` desc')->fetchAll();
|
||||
$this->view->link = $this->caselib->getLibLink($module, $method, $extra);
|
||||
$this->view->libraries = $libraries;
|
||||
$this->view->keywords = $keywords;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Export templet.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function exportTemplet($libID)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
if($_POST)
|
||||
{
|
||||
$fields['module'] = $this->lang->testcase->module;
|
||||
$fields['title'] = $this->lang->testcase->title;
|
||||
$fields['precondition'] = $this->lang->testcase->precondition;
|
||||
$fields['stepDesc'] = $this->lang->testcase->stepDesc;
|
||||
$fields['stepExpect'] = $this->lang->testcase->stepExpect;
|
||||
$fields['keywords'] = $this->lang->testcase->keywords;
|
||||
$fields['pri'] = $this->lang->testcase->pri;
|
||||
$fields['type'] = $this->lang->testcase->type;
|
||||
$fields['stage'] = $this->lang->testcase->stage;
|
||||
|
||||
$fields[''] = '';
|
||||
$fields['typeValue'] = $this->lang->testcase->lblTypeValue;
|
||||
$fields['stageValue'] = $this->lang->testcase->lblStageValue;
|
||||
|
||||
$modules = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0);
|
||||
$rows = array();
|
||||
$num = (int)$this->post->num;
|
||||
for($i = 0; $i < $num; $i++)
|
||||
{
|
||||
foreach($modules as $moduleID => $module)
|
||||
{
|
||||
$row = new stdclass();
|
||||
$row->module = $module . "(#$moduleID)";
|
||||
$row->stepDesc = "1. \n2. \n3.";
|
||||
$row->stepExpect = "1. \n2. \n3.";
|
||||
|
||||
if(empty($rows))
|
||||
{
|
||||
$row->typeValue = join("\n", $this->lang->testcase->typeList);
|
||||
$row->stageValue = join("\n", $this->lang->testcase->stageList);
|
||||
}
|
||||
$rows[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
$this->post->set('fields', $fields);
|
||||
$this->post->set('kind', 'testcase');
|
||||
$this->post->set('rows', $rows);
|
||||
$this->post->set('extraNum', $num);
|
||||
$this->post->set('fileName', 'templet');
|
||||
$this->fetch('file', 'export2csv', $_POST);
|
||||
}
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Import case csv file.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function import($libID)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
if($_FILES)
|
||||
{
|
||||
$file = $this->loadModel('file')->getUpload('file');
|
||||
$file = $file[0];
|
||||
|
||||
$fileName = $this->file->savePath . $this->file->getSaveName($file['pathname']);
|
||||
move_uploaded_file($file['tmpname'], $fileName);
|
||||
|
||||
$rows = $this->file->parseCSV($fileName);
|
||||
$fields = $this->testcase->getImportFields($productID);
|
||||
$fields = array_flip($fields);
|
||||
$header = array();
|
||||
foreach($rows[0] as $i => $rowValue)
|
||||
{
|
||||
if(empty($rowValue)) break;
|
||||
$header[$i] = $rowValue;
|
||||
}
|
||||
unset($rows[0]);
|
||||
|
||||
$columnKey = array();
|
||||
foreach($header as $title)
|
||||
{
|
||||
if(!isset($fields[$title])) continue;
|
||||
$columnKey[] = $fields[$title];
|
||||
}
|
||||
|
||||
if(count($columnKey) != count($header) or $this->post->encode != 'utf-8')
|
||||
{
|
||||
$fc = file_get_contents($fileName);
|
||||
$encode = $this->post->encode != "utf-8" ? $this->post->encode : 'gbk';
|
||||
$fc = helper::convertEncoding($fc, $encode, 'utf-8');
|
||||
file_put_contents($fileName, $fc);
|
||||
|
||||
$rows = $this->file->parseCSV($fileName);
|
||||
$columnKey = array();
|
||||
$header = array();
|
||||
foreach($rows[0] as $i => $rowValue)
|
||||
{
|
||||
if(empty($rowValue)) break;
|
||||
$header[$i] = $rowValue;
|
||||
}
|
||||
unset($rows[0]);
|
||||
foreach($header as $title)
|
||||
{
|
||||
if(!isset($fields[$title])) continue;
|
||||
$columnKey[] = $fields[$title];
|
||||
}
|
||||
if(count($columnKey) != count($header)) die(js::alert($this->lang->testcase->errorEncode));
|
||||
}
|
||||
|
||||
$this->session->set('importFile', $fileName);
|
||||
|
||||
die(js::locate(inlink('showImport', "libID=$libID"), 'parent.parent'));
|
||||
}
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show import case.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function showImport($libID)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
if($_POST)
|
||||
{
|
||||
$this->caselib->createFromImport($libID);
|
||||
die(js::locate(inlink('browse', "libID=$libID"), 'parent'));
|
||||
}
|
||||
|
||||
$libraries = $this->caselib->getLibraries();
|
||||
if(empty($libraries)) $this->locate(inlink('create'));
|
||||
|
||||
$this->caselib->setLibMenu($libraries, $libID);
|
||||
|
||||
$file = $this->session->importFile;
|
||||
$caseLang = $this->lang->testcase;
|
||||
$caseConfig = $this->config->testcase;
|
||||
$modules = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0);
|
||||
|
||||
$fields = explode(',', $caseConfig->exportFields);
|
||||
foreach($fields as $key => $fieldName)
|
||||
{
|
||||
$fieldName = trim($fieldName);
|
||||
$fields[$fieldName] = isset($caseLang->$fieldName) ? $caseLang->$fieldName : $fieldName;
|
||||
unset($fields[$key]);
|
||||
}
|
||||
|
||||
$fields = array_flip($fields);
|
||||
$rows = $this->loadModel('file')->parseCSV($file);
|
||||
$header = array();
|
||||
foreach($rows[0] as $i => $rowValue)
|
||||
{
|
||||
if(empty($rowValue)) break;
|
||||
$header[$i] = $rowValue;
|
||||
}
|
||||
unset($rows[0]);
|
||||
|
||||
foreach($header as $title)
|
||||
{
|
||||
if(!isset($fields[$title])) continue;
|
||||
$columnKey[] = $fields[$title];
|
||||
}
|
||||
|
||||
$endField = end($fields);
|
||||
$caseData = array();
|
||||
$stepData = array();
|
||||
$stepVars = 0;
|
||||
foreach($rows as $row => $data)
|
||||
{
|
||||
$case = new stdclass();
|
||||
foreach($columnKey as $key => $field)
|
||||
{
|
||||
if(!isset($data[$key])) continue;
|
||||
$cellValue = $data[$key];
|
||||
if($field == 'module')
|
||||
{
|
||||
$case->$field = 0;
|
||||
if(strrpos($cellValue, '(#') !== false)
|
||||
{
|
||||
$id = trim(substr($cellValue, strrpos($cellValue,'(#') + 2), ')');
|
||||
$case->$field = $id;
|
||||
}
|
||||
}
|
||||
elseif(in_array($field, $caseConfig->export->listFields))
|
||||
{
|
||||
if($field == 'stage')
|
||||
{
|
||||
$stages = explode("\n", $cellValue);
|
||||
foreach($stages as $stage) $case->stage[] = array_search($stage, $caseLang->{$field . 'List'});
|
||||
$case->stage = join(',', $case->stage);
|
||||
}
|
||||
else
|
||||
{
|
||||
$case->$field = array_search($cellValue, $caseLang->{$field . 'List'});
|
||||
}
|
||||
}
|
||||
elseif($field != 'stepDesc' and $field != 'stepExpect')
|
||||
{
|
||||
$case->$field = $cellValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
$steps = (array)$cellValue;
|
||||
if(strpos($cellValue, "\n"))
|
||||
{
|
||||
$steps = explode("\n", $cellValue);
|
||||
}
|
||||
elseif(strpos($cellValue, "\r"))
|
||||
{
|
||||
$steps = explode("\r", $cellValue);
|
||||
}
|
||||
|
||||
$stepKey = str_replace('step', '', strtolower($field));
|
||||
$caseStep = array();
|
||||
|
||||
foreach($steps as $step)
|
||||
{
|
||||
$step = trim($step);
|
||||
if(empty($step)) continue;
|
||||
if(preg_match('/^(([0-9]+)\.[0-9]+)([.、]{1})/U', $step, $out))
|
||||
{
|
||||
$num = $out[1];
|
||||
$parent = $out[2];
|
||||
$sign = $out[3];
|
||||
$signbit = $sign == '.' ? 1 : 3;
|
||||
$step = trim(substr($step, strlen($num) + $signbit));
|
||||
if(!empty($step)) $caseStep[$num]['content'] = $step;
|
||||
$caseStep[$num]['type'] = 'item';
|
||||
$caseStep[$parent]['type'] = 'group';
|
||||
}
|
||||
elseif(preg_match('/^([0-9]+)([.、]{1})/U', $step, $out))
|
||||
{
|
||||
$num = $out[1];
|
||||
$sign = $out[2];
|
||||
$signbit = $sign == '.' ? 1 : 3;
|
||||
$step = trim(substr($step, strlen($num) + $signbit));
|
||||
if(!empty($step)) $caseStep[$num]['content'] = $step;
|
||||
$caseStep[$num]['type'] = 'step';
|
||||
}
|
||||
elseif(isset($num))
|
||||
{
|
||||
if(!isset($caseStep[$num]['content'])) $caseStep[$num]['content'] = '';
|
||||
$caseStep[$num]['content'] .= "\n" . $step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($field == 'stepDesc')
|
||||
{
|
||||
$num = 1;
|
||||
$caseStep[$num]['content'] = $step;
|
||||
$caseStep[$num]['type'] = 'step';
|
||||
}
|
||||
if($field == 'stepExpect' and isset($stepData[$row]['desc']))
|
||||
{
|
||||
end($stepData[$row]['desc']);
|
||||
$num = key($stepData[$row]['desc']);
|
||||
$caseStep[$num]['content'] = $step;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($num);
|
||||
unset($sign);
|
||||
$stepVars += count($caseStep, COUNT_RECURSIVE) - count($caseStep);
|
||||
$stepData[$row][$stepKey] = $caseStep;
|
||||
}
|
||||
}
|
||||
|
||||
$caseData[$row] = $case;
|
||||
unset($case);
|
||||
}
|
||||
|
||||
if(empty($caseData))
|
||||
{
|
||||
unlink($this->session->importFile);
|
||||
unset($_SESSION['importFile']);
|
||||
echo js::alert($this->lang->error->noData);
|
||||
die(js::locate($this->createLink('caselib', 'browse', "libID=$libID")));
|
||||
}
|
||||
|
||||
/* Judge whether the editedTasks is too large and set session. */
|
||||
$countInputVars = count($caseData) * 9 + $stepVars;
|
||||
$showSuhosinInfo = common::judgeSuhosinSetting($countInputVars);
|
||||
if($showSuhosinInfo) $this->view->suhosinInfo = extension_loaded('suhosin') ? sprintf($this->lang->suhosinInfo, $countInputVars) : sprintf($this->lang->maxVarsInfo, $countInputVars);
|
||||
|
||||
$this->view->title = $this->lang->caselib->common . $this->lang->colon . $this->lang->testcase->showImport;
|
||||
$this->view->position[] = $this->lang->testcase->showImport;
|
||||
|
||||
$this->view->modules = $modules;
|
||||
$this->view->cases = $this->dao->select('id,module,stage,status,pri,type')->from(TABLE_CASE)->where('lib')->eq($libID)->andWhere('deleted')->eq(0)->andWhere('product')->eq(0)->fetchAll('id');
|
||||
$this->view->caseData = $caseData;
|
||||
$this->view->stepData = $stepData;
|
||||
$this->view->libID = $libID;
|
||||
$this->display();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* The caselib module en file of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package caselib
|
||||
* @version $Id: zh-cn.php 4490 2013-02-27 03:27:05Z wyd621@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
$lang->caselib->common = 'Case Library';
|
||||
$lang->caselib->all = 'All Case Libraries';
|
||||
|
||||
$lang->caselib->index = "Library Home";
|
||||
$lang->caselib->create = "Create Case Library";
|
||||
$lang->caselib->edit = 'Edit Case Library';
|
||||
$lang->caselib->browse = 'View Cases in Library';
|
||||
$lang->caselib->view = 'Library Detail';
|
||||
$lang->caselib->createCase = 'Create Case';
|
||||
$lang->caselib->delete = "Delete Suite";
|
||||
$lang->caselib->linkVersion = "Version";
|
||||
$lang->caselib->deleted = 'Deleted';
|
||||
$lang->caselib->exportTemplet = 'Export Template';
|
||||
$lang->caselib->batchCreateCase = 'Batch Create';
|
||||
$lang->caselib->import = 'Import';
|
||||
$lang->caselib->importAction = 'Import Case';
|
||||
$lang->caselib->showImport = 'Imported Data';
|
||||
|
||||
$lang->caselib->id = 'ID';
|
||||
$lang->caselib->name = 'Name';
|
||||
$lang->caselib->desc = 'Description';
|
||||
|
||||
$lang->caselib->legendDesc = 'Description';
|
||||
|
||||
$lang->caselib->libraryDelete = 'Do you want to delete this library?';
|
||||
$lang->caselib->noModule = '<div>You have no modules.</div><div>Manage it now.</div>';
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* The caselib module zh-cn file of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package caselib
|
||||
* @version $Id: zh-cn.php 4490 2013-02-27 03:27:05Z wyd621@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
$lang->caselib->common = '用例库';
|
||||
$lang->caselib->all = '所有用例库';
|
||||
|
||||
$lang->caselib->index = "用例库首页";
|
||||
$lang->caselib->create = "创建用例库";
|
||||
$lang->caselib->edit = '编辑用例库';
|
||||
$lang->caselib->browse = '浏览库用例';
|
||||
$lang->caselib->view = '查看库概况';
|
||||
$lang->caselib->createCase = '创建用例';
|
||||
$lang->caselib->delete = "删除";
|
||||
$lang->caselib->linkVersion = "版本";
|
||||
$lang->caselib->deleted = '已删除';
|
||||
$lang->caselib->exportTemplet = '导出模板';
|
||||
$lang->caselib->batchCreateCase = '批量创建用例';
|
||||
$lang->caselib->import = '导入';
|
||||
$lang->caselib->importAction = '导入用例';
|
||||
$lang->caselib->showImport = '显示导入数据';
|
||||
|
||||
$lang->caselib->id = '编号';
|
||||
$lang->caselib->name = '名称';
|
||||
$lang->caselib->desc = '描述';
|
||||
|
||||
$lang->caselib->legendDesc = '描述';
|
||||
|
||||
$lang->caselib->libraryDelete = '您确认要删除该用例库吗?';
|
||||
$lang->caselib->noModule = '<div>您现在还没有模块信息</div><div>请维护用例库模块</div>';
|
||||
@@ -0,0 +1,640 @@
|
||||
<?php
|
||||
/**
|
||||
* The model file of caselib module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package caselib
|
||||
* @version $Id: model.php 5114 2013-07-12 06:02:59Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php
|
||||
class caselibModel extends model
|
||||
{
|
||||
/**
|
||||
* Set library menu.
|
||||
*
|
||||
* @param array $libraries
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function setLibMenu($libraries, $libID, $moduleID = 0)
|
||||
{
|
||||
$currentLibName = zget($libraries, $libID, '');
|
||||
$isMobile = $this->app->viewType == 'mhtml';
|
||||
$selectHtml = '';
|
||||
if(!empty($libraries))
|
||||
{
|
||||
if($isMobile)
|
||||
{
|
||||
$selectHtml = "<a id='currentItem' href=\"javascript:showSearchMenu('caselib', '$libID', 'caselib', 'browse', '')\">{$currentLibName} <span class='icon-caret-down'></span></a><div id='currentItemDropMenu' class='hidden affix enter-from-bottom layer'></div>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$dropMenuLink = helper::createLink('caselib', 'ajaxGetDropMenu', "objectID=$libID&module=caselib&method=browse");
|
||||
$selectHtml = "<div class='btn-group angle-btn'><div class='btn-group'><button data-toggle='dropdown' type='button' class='btn btn-limit' id='currentItem'>{$currentLibName} <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
|
||||
$selectHtml .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
|
||||
$selectHtml .= "</div></div></div>";
|
||||
}
|
||||
}
|
||||
|
||||
if($this->config->global->flow == 'onlyTest')
|
||||
{
|
||||
$modules = $this->loadModel('tree')->getModulePairs($libID, 'caselib');
|
||||
$moduleName = ($moduleID && isset($modules[$moduleID])) ? $modules[$moduleID] : $this->lang->tree->all;
|
||||
|
||||
if(!$isMobile)
|
||||
{
|
||||
$dropMenuLink = helper::createLink('tree', 'ajaxGetDropMenu', "objectID=$libID&module=caselib&method=browse");
|
||||
$selectHtml .= "<div class='btn-group'><button id='currentModule' data-toggle='dropdown' type='button' class='btn btn-limit'>{$moduleName} <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
|
||||
$selectHtml .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
|
||||
$selectHtml .= "</div></div>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$selectHtml .= "<a id='currentModule' href=\"javascript:showSearchMenu('tree', '$libID', 'caselib', 'browse', '')\">{$moduleName} <span class='icon-caret-down'></span></a><div id='currentBranchDropMenu' class='hidden affix enter-from-bottom layer'></div>";
|
||||
}
|
||||
}
|
||||
|
||||
setCookie("lastCaseLib", $libID, $this->config->cookieLife, $this->config->webRoot);
|
||||
|
||||
$pageNav = '';
|
||||
$pageActions = '';
|
||||
$isMobile = $this->app->viewType == 'mhtml';
|
||||
if($isMobile)
|
||||
{
|
||||
$this->app->loadLang('qa');
|
||||
$pageNav = html::a(helper::createLink('qa', 'index'), $this->lang->qa->index) . $this->lang->colon;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->config->global->flow == 'full')
|
||||
{
|
||||
$this->app->loadLang('qa');
|
||||
$pageNav .= '<div class="btn-group angle-btn"><div class="btn-group"><button data-toggle="dropdown" type="button" class="btn">' . $this->lang->qa->index . ' <span class="caret"></span></button>';
|
||||
$pageNav .= '<ul class="dropdown-menu">';
|
||||
if(common::hasPriv('caselib', 'create')) $pageNav .= '<li>' . html::a(helper::createLink('caselib', 'create'), '<i class="icon icon-plus"></i> ' . $this->lang->caselib->create) . '</li>';
|
||||
$pageNav .= '</ul></div></div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->app->loadLang('testcase');
|
||||
$pageActions .= "<div class='btn-group'>";
|
||||
if(common::hasPriv('caselib', 'exportTemplet'))
|
||||
{
|
||||
$link = helper::createLink('caselib', 'exportTemplet', "libID=$libID");
|
||||
$pageActions .= html::a($link, "<i class='icon icon-export muted'> </i>" . $this->lang->caselib->exportTemplet, '', "class='btn btn-link export'");
|
||||
}
|
||||
if(common::hasPriv('caselib', 'import'))
|
||||
{
|
||||
$link = helper::createLink('caselib', 'import', "libID=$libID");
|
||||
$pageActions .= html::a($link, "<i class='icon muted icon-import'> </i>" . $this->lang->testcase->importFile, '', "class='btn btn-link export'");
|
||||
}
|
||||
$pageActions .= '</div>';
|
||||
$params = "libID=$libID&moduleID=" . (isset($moduleID) ? $moduleID : 0);
|
||||
if(common::hasPriv('caselib', 'batchCreateCase'))
|
||||
{
|
||||
$link = helper::createLink('caselib', 'batchCreateCase', $params);
|
||||
$pageActions .= html::a($link, "<i class='icon-plus'></i>" . $this->lang->testcase->batchCreate, '', "class='btn btn-secondary'");
|
||||
}
|
||||
if(common::hasPriv('caselib', 'createCase'))
|
||||
{
|
||||
$link = helper::createLink('caselib', 'createCase', $params);
|
||||
$pageActions .= html::a($link, "<i class='icon-plus'></i>" . $this->lang->testcase->create, '', "class='btn btn-primary'");
|
||||
}
|
||||
if(common::hasPriv('caselib', 'create'))
|
||||
{
|
||||
$link = helper::createLink('caselib', 'create');
|
||||
$pageActions .= html::a($link, "<i class='icon-plus'></i>" . $this->lang->caselib->create, '', "class='btn btn-primary'");
|
||||
}
|
||||
}
|
||||
}
|
||||
$pageNav .= $selectHtml;
|
||||
|
||||
$this->lang->modulePageNav = $pageNav;
|
||||
$this->lang->modulePageActions = $pageActions;
|
||||
foreach($this->lang->caselib->menu as $key => $value)
|
||||
{
|
||||
$replace = '';
|
||||
if($this->config->global->flow == 'onlyTest') $replace = $libID;
|
||||
common::setMenuVars($this->lang->caselib->menu, $key, $replace);
|
||||
}
|
||||
if($this->config->global->flow != 'full' && $this->app->getMethodName() != 'view') $this->lang->caselib->menu->bysearch = "<a class='querybox-toggle' id='bysearchTab'><i class='icon icon-search muted'> </i>{$this->lang->testcase->bySearch}</a>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Save lib state.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param array $libraries
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function saveLibState($libID = 0, $libraries = array())
|
||||
{
|
||||
if($libID > 0) $this->session->set('caseLib', (int)$libID);
|
||||
if($libID == 0 and $this->cookie->lastCaseLib) $this->session->set('caseLib', $this->cookie->lastCaseLib);
|
||||
if($libID == 0 and $this->session->caseLib == '') $this->session->set('caseLib', key($libraries));
|
||||
if(!isset($libraries[$this->session->caseLib]))
|
||||
{
|
||||
$this->session->set('caseLib', key($libraries));
|
||||
$libID = $this->session->caseLib;
|
||||
}
|
||||
return $this->session->caseLib;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get caselib info by id.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param bool $setImgSize
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getById($libID, $setImgSize = false)
|
||||
{
|
||||
$lib = $this->dao->select('*')->from(TABLE_TESTSUITE)->where('id')->eq((int)$libID)->fetch();
|
||||
$lib = $this->loadModel('file')->replaceImgURL($lib, 'desc');
|
||||
if($setImgSize) $lib->desc = $this->file->setImgSize($lib->desc);
|
||||
return $lib;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a caselib.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return bool|array
|
||||
*/
|
||||
public function update($libID)
|
||||
{
|
||||
$oldLib = $this->dao->select("*")->from(TABLE_TESTSUITE)->where('id')->eq((int)$libID)->fetch();
|
||||
$lib = fixer::input('post')
|
||||
->stripTags($this->config->caselib->editor->edit['id'], $this->config->allowedTags)
|
||||
->add('lastEditedBy', $this->app->user->account)
|
||||
->add('lastEditedDate', helper::now())
|
||||
->remove('uid')
|
||||
->get();
|
||||
$lib = $this->loadModel('file')->processImgURL($lib, $this->config->caselib->editor->edit['id'], $this->post->uid);
|
||||
$this->dao->update(TABLE_TESTSUITE)->data($lib)
|
||||
->autoCheck()
|
||||
->batchcheck($this->config->caselib->edit->requiredFields, 'notempty')
|
||||
->where('id')->eq($libID)
|
||||
->exec();
|
||||
if(!dao::isError())
|
||||
{
|
||||
$this->file->updateObjectID($this->post->uid, $libID, 'caselib');
|
||||
return common::createChanges($oldLib, $lib);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete library.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param string $table
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($libID, $table = '')
|
||||
{
|
||||
$this->dao->update(TABLE_TESTSUITE)->set('deleted')->eq(1)->where('id')->eq($libID)->exec();
|
||||
|
||||
$this->loadModel('action');
|
||||
$this->action->create('caselib', $libID, 'deleted', '', ACTIONMODEL::CAN_UNDELETED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get libraries.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getLibraries()
|
||||
{
|
||||
return $this->dao->select("id,name")->from(TABLE_TESTSUITE)
|
||||
->where('product')->eq(0)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('type')->eq('library')
|
||||
->orderBy('id_desc')
|
||||
->fetchPairs('id', 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create lib.
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$lib = fixer::input('post')
|
||||
->stripTags($this->config->caselib->editor->create['id'], $this->config->allowedTags)
|
||||
->setForce('type', 'library')
|
||||
->add('addedBy', $this->app->user->account)
|
||||
->add('addedDate', helper::now())
|
||||
->remove('uid')
|
||||
->get();
|
||||
$lib = $this->loadModel('file')->processImgURL($lib, $this->config->caselib->editor->create['id'], $this->post->uid);
|
||||
$this->dao->insert(TABLE_TESTSUITE)->data($lib)
|
||||
->batchcheck($this->config->caselib->create->requiredFields, 'notempty')
|
||||
->check('name', 'unique', "deleted = '0'")
|
||||
->exec();
|
||||
if(!dao::isError())
|
||||
{
|
||||
$libID = $this->dao->lastInsertID();
|
||||
$this->file->updateObjectID($this->post->uid, $libID, 'caselib');
|
||||
return $libID;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lib cases.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param string $browseType
|
||||
* @param int $queryID
|
||||
* @param int $moduleID
|
||||
* @param string $sort
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getLibCases($libID, $browseType, $queryID = 0, $moduleID = 0, $sort = 'id_desc', $pager = null)
|
||||
{
|
||||
$moduleIdList = $moduleID ? $this->loadModel('tree')->getAllChildId($moduleID) : '0';
|
||||
$browseType = ($browseType == 'bymodule' and $this->session->libBrowseType and $this->session->libBrowseType != 'bysearch') ? $this->session->libBrowseType : $browseType;
|
||||
|
||||
$cases = array();
|
||||
if($browseType == 'bymodule' or $browseType == 'all' or $browseType == 'wait')
|
||||
{
|
||||
$cases = $this->dao->select('*')->from(TABLE_CASE)
|
||||
->where('lib')->eq((int)$libID)
|
||||
->andWhere('product')->eq(0)
|
||||
->beginIF($moduleIdList)->andWhere('module')->in($moduleIdList)->fi()
|
||||
->beginIF($browseType == 'wait')->andWhere('status')->eq($browseType)->fi()
|
||||
->andWhere('deleted')->eq('0')
|
||||
->orderBy($sort)->page($pager)->fetchAll('id');
|
||||
}
|
||||
/* By search. */
|
||||
elseif($browseType == 'bysearch')
|
||||
{
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
$this->session->set('caselibQuery', ' 1 = 1');
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('caselibQuery', $query->sql);
|
||||
$this->session->set('caselibForm', $query->form);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->caselibQuery == false) $this->session->set('caselibQuery', ' 1 = 1');
|
||||
}
|
||||
|
||||
$queryLibID = $libID;
|
||||
$allLib = "`lib` = 'all'";
|
||||
$caseQuery = '(' . $this->session->caselibQuery;
|
||||
if(strpos($this->session->caselibQuery, $allLib) !== false)
|
||||
{
|
||||
$caseQuery = str_replace($allLib, '1', $caseQuery);
|
||||
$queryLibID = 'all';
|
||||
}
|
||||
$caseQuery .= ')';
|
||||
|
||||
$cases = $this->dao->select('*')->from(TABLE_CASE)->where($caseQuery)
|
||||
->beginIF($queryLibID != 'all')->andWhere('lib')->eq((int)$libID)->fi()
|
||||
->andWhere('product')->eq(0)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->orderBy($sort)->page($pager)->fetchAll();
|
||||
|
||||
}
|
||||
return $cases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param array $libraries
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildSearchForm($libID, $libraries, $queryID, $actionURL)
|
||||
{
|
||||
$this->config->testcase->search['fields']['lib'] = $this->lang->testcase->lib;
|
||||
$this->config->testcase->search['params']['lib']['values'] = array('' => '', $libID => $libraries[$libID], 'all' => $this->lang->caselib->all);
|
||||
$this->config->testcase->search['params']['lib']['operator'] = '=';
|
||||
$this->config->testcase->search['params']['lib']['control'] = 'select';
|
||||
$this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib');
|
||||
if(!$this->config->testcase->needReview) unset($this->config->testcase->search['params']['status']['values']['wait']);
|
||||
unset($this->config->testcase->search['fields']['product']);
|
||||
unset($this->config->testcase->search['params']['product']);
|
||||
unset($this->config->testcase->search['fields']['branch']);
|
||||
unset($this->config->testcase->search['params']['branch']);
|
||||
unset($this->config->testcase->search['fields']['lastRunner']);
|
||||
unset($this->config->testcase->search['params']['lastRunner']);
|
||||
unset($this->config->testcase->search['fields']['lastRunResult']);
|
||||
unset($this->config->testcase->search['params']['lastRunResult']);
|
||||
unset($this->config->testcase->search['fields']['lastRunDate']);
|
||||
unset($this->config->testcase->search['params']['lastRunDate']);
|
||||
|
||||
$this->config->testcase->search['module'] = 'caselib';
|
||||
$this->config->testcase->search['actionURL'] = $actionURL;
|
||||
$this->config->testcase->search['queryID'] = $queryID;
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->testcase->search);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lib link.
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @param string $extra
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getLibLink($module, $method, $extra)
|
||||
{
|
||||
$link = '';
|
||||
if($module == 'caselib')
|
||||
{
|
||||
if($module == 'caselib' && ($method == 'create'))
|
||||
{
|
||||
$link = helper::createLink($module, 'browse', "libID=%s");
|
||||
}
|
||||
else
|
||||
{
|
||||
$link = helper::createLink($module, $method, "libID=%s");
|
||||
}
|
||||
}
|
||||
else if($module == 'tree')
|
||||
{
|
||||
$link = helper::createLink($module, $method, "libID=%s&type=caselib¤tModuleID=0");
|
||||
}
|
||||
else
|
||||
{
|
||||
$link = helper::createLink('caselib', 'browse', "libID=%s");
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create from import.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createFromImport($libID)
|
||||
{
|
||||
$this->loadModel('action');
|
||||
$this->loadModel('testcase');
|
||||
$this->loadModel('file');
|
||||
$now = helper::now();
|
||||
$data = fixer::input('post')->get();
|
||||
|
||||
if(!empty($_POST['id']))
|
||||
{
|
||||
$oldSteps = $this->dao->select('t2.*')->from(TABLE_CASE)->alias('t1')
|
||||
->leftJoin(TABLE_CASESTEP)->alias('t2')->on('t1.id = t2.case')
|
||||
->where('t1.id')->in(($_POST['id']))
|
||||
->andWhere('t1.version=t2.version')
|
||||
->orderBy('t2.id')
|
||||
->fetchGroup('case');
|
||||
$oldCases = $this->dao->select('*')->from(TABLE_CASE)->where('id')->in($_POST['id'])->fetchAll('id');
|
||||
}
|
||||
|
||||
$cases = array();
|
||||
foreach($data->lib as $key => $lib)
|
||||
{
|
||||
$caseData = new stdclass();
|
||||
|
||||
$caseData->lib = $lib;
|
||||
$caseData->module = $data->module[$key];
|
||||
$caseData->title = $data->title[$key];
|
||||
$caseData->pri = (int)$data->pri[$key];
|
||||
$caseData->type = $data->type[$key];
|
||||
$caseData->status = $data->status[$key];
|
||||
$caseData->stage = join(',', $data->stage[$key]);
|
||||
$caseData->keywords = $data->keywords[$key];
|
||||
$caseData->frequency = 1;
|
||||
$caseData->precondition = $data->precondition[$key];
|
||||
|
||||
if(isset($this->config->testcase->create->requiredFields))
|
||||
{
|
||||
$requiredFields = explode(',', $this->config->testcase->create->requiredFields);
|
||||
foreach($requiredFields as $requiredField)
|
||||
{
|
||||
$requiredField = trim($requiredField);
|
||||
if(empty($caseData->$requiredField)) dao::$errors[] = sprintf($this->lang->testcase->noRequire, $key, $this->lang->testcase->$requiredField);
|
||||
}
|
||||
}
|
||||
|
||||
$cases[$key] = $caseData;
|
||||
}
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
$forceNotReview = $this->testcase->forceNotReview();
|
||||
foreach($cases as $key => $caseData)
|
||||
{
|
||||
if(!empty($_POST['id'][$key]) and empty($_POST['insert']))
|
||||
{
|
||||
$caseID = $data->id[$key];
|
||||
$stepChanged = false;
|
||||
$steps = array();
|
||||
$oldStep = isset($oldSteps[$caseID]) ? $oldSteps[$caseID] : array();
|
||||
$oldCase = $oldCases[$caseID];
|
||||
|
||||
/* Remove the empty setps in post. */
|
||||
$steps = array();
|
||||
if(isset($_POST['desc'][$key]))
|
||||
{
|
||||
foreach($data->desc[$key] as $id => $desc)
|
||||
{
|
||||
$desc = trim($desc);
|
||||
if(empty($desc)) continue;
|
||||
$step = new stdclass();
|
||||
$step->type = $data->stepType[$key][$id];
|
||||
$step->desc = $desc;
|
||||
$step->expect = trim($data->expect[$key][$id]);
|
||||
|
||||
$steps[] = $step;
|
||||
}
|
||||
}
|
||||
|
||||
/* If step count changed, case changed. */
|
||||
if((!$oldStep != !$steps) or (count($oldStep) != count($steps)))
|
||||
{
|
||||
$stepChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Compare every step. */
|
||||
foreach($oldStep as $id => $oldStep)
|
||||
{
|
||||
if(trim($oldStep->desc) != trim($steps[$id]->desc) or trim($oldStep->expect) != $steps[$id]->expect)
|
||||
{
|
||||
$stepChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$version = $stepChanged ? $oldCase->version + 1 : $oldCase->version;
|
||||
$caseData->version = $version;
|
||||
$changes = common::createChanges($oldCase, $caseData);
|
||||
if(!$changes and !$stepChanged) continue;
|
||||
|
||||
if($changes or $stepChanged)
|
||||
{
|
||||
$caseData->lastEditedBy = $this->app->user->account;
|
||||
$caseData->lastEditedDate = $now;
|
||||
if($stepChanged and !$forceNotReview) $caseData->status = 'wait';
|
||||
$this->dao->update(TABLE_CASE)->data($caseData)->where('id')->eq($caseID)->autoCheck()->exec();
|
||||
if($stepChanged)
|
||||
{
|
||||
$parentStepID = 0;
|
||||
foreach($steps as $id => $step)
|
||||
{
|
||||
$step = (array)$step;
|
||||
if(empty($step['desc'])) continue;
|
||||
$stepData = new stdclass();
|
||||
$stepData->type = ($step['type'] == 'item' and $parentStepID == 0) ? 'step' : $step['type'];
|
||||
$stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0;
|
||||
$stepData->case = $caseID;
|
||||
$stepData->version = $version;
|
||||
$stepData->desc = $step['desc'];
|
||||
$stepData->expect = $step['expect'];
|
||||
$this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec();
|
||||
if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID();
|
||||
if($stepData->type == 'step') $parentStepID = 0;
|
||||
}
|
||||
}
|
||||
$oldCase->steps = $this->testcase->joinStep($oldStep);
|
||||
$caseData->steps = $this->testcase->joinStep($steps);
|
||||
$changes = common::createChanges($oldCase, $caseData);
|
||||
$actionID = $this->action->create('case', $caseID, 'Edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$caseData->version = 1;
|
||||
$caseData->openedBy = $this->app->user->account;
|
||||
$caseData->openedDate = $now;
|
||||
$caseData->status = $forceNotReview ? 'normal' : 'wait';
|
||||
$this->dao->insert(TABLE_CASE)->data($caseData)->autoCheck()->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$caseID = $this->dao->lastInsertID();
|
||||
$parentStepID = 0;
|
||||
foreach($data->desc[$key] as $id => $desc)
|
||||
{
|
||||
$desc = trim($desc);
|
||||
if(empty($desc)) continue;
|
||||
$stepData = new stdclass();
|
||||
$stepData->type = ($data->stepType[$key][$id] == 'item' and $parentStepID == 0) ? 'step' : $data->stepType[$key][$id];
|
||||
$stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0;
|
||||
$stepData->case = $caseID;
|
||||
$stepData->version = 1;
|
||||
$stepData->desc = $desc;
|
||||
$stepData->expect = $data->expect[$key][$id];
|
||||
$this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec();
|
||||
if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID();
|
||||
if($stepData->type == 'step') $parentStepID = 0;
|
||||
}
|
||||
$this->action->create('case', $caseID, 'Opened');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unlink($this->session->importFile);
|
||||
unset($_SESSION['importFile']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch create case for lib.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function batchCreateCase($libID)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
$this->loadModel('action');
|
||||
|
||||
$now = helper::now();
|
||||
$cases = fixer::input('post')->get();
|
||||
$batchNum = count(reset($cases));
|
||||
|
||||
$result = $this->loadModel('common')->removeDuplicate('case', $cases, "lib={$libID}");
|
||||
$cases = $result['data'];
|
||||
|
||||
for($i = 0; $i < $batchNum; $i++)
|
||||
{
|
||||
if(!empty($cases->title[$i]) and empty($cases->type[$i])) die(js::alert(sprintf($this->lang->error->notempty, $this->lang->testcase->type)));
|
||||
}
|
||||
|
||||
$module = 0;
|
||||
$type = '';
|
||||
$pri = 3;
|
||||
for($i = 0; $i < $batchNum; $i++)
|
||||
{
|
||||
$module = $cases->module[$i] == 'ditto' ? $module : $cases->module[$i];
|
||||
$type = $cases->type[$i] == 'ditto' ? $type : $cases->type[$i];
|
||||
$pri = $cases->pri[$i] == 'ditto' ? $pri : $cases->pri[$i];
|
||||
$cases->module[$i] = (int)$module;
|
||||
$cases->type[$i] = $type;
|
||||
$cases->pri[$i] = $pri;
|
||||
}
|
||||
|
||||
$forceNotReview = $this->testcase->forceNotReview();
|
||||
for($i = 0; $i < $batchNum; $i++)
|
||||
{
|
||||
if($cases->type[$i] != '' and $cases->title[$i] != '')
|
||||
{
|
||||
$data[$i] = new stdclass();
|
||||
$data[$i]->lib = $libID;
|
||||
$data[$i]->module = $cases->module[$i];
|
||||
$data[$i]->type = $cases->type[$i];
|
||||
$data[$i]->pri = $cases->pri[$i];
|
||||
$data[$i]->stage = empty($cases->stage[$i]) ? '' : implode(',', $cases->stage[$i]);
|
||||
$data[$i]->color = $cases->color[$i];
|
||||
$data[$i]->title = $cases->title[$i];
|
||||
$data[$i]->precondition = $cases->precondition[$i];
|
||||
$data[$i]->keywords = $cases->keywords[$i];
|
||||
$data[$i]->openedBy = $this->app->user->account;
|
||||
$data[$i]->openedDate = $now;
|
||||
$data[$i]->status = $forceNotReview ? 'normal' : 'wait';
|
||||
$data[$i]->version = 1;
|
||||
|
||||
$this->dao->insert(TABLE_CASE)->data($data[$i])
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->testcase->create->requiredFields, 'notempty')
|
||||
->exec();
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
echo js::error(dao::getError());
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
|
||||
$caseID = $this->dao->lastInsertID();
|
||||
$actionID = $this->action->create('case', $caseID, 'Opened');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* The batch create case view of testsuite module of ZenTaoPMS.
|
||||
* The batch create case view of caselib module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package testsuite
|
||||
* @package caselib
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* The library view file of testsuite module of ZenTaoPMS.
|
||||
* The library view file of caselib module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package testsuite
|
||||
* @package caselib
|
||||
* @version $Id: library.html.php 5108 2013-07-12 01:59:04Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
@@ -15,7 +15,7 @@ include '../../common/view/header.html.php';
|
||||
include '../../common/view/datatable.fix.html.php';
|
||||
js::set('browseType', $browseType);
|
||||
js::set('moduleID', $moduleID);
|
||||
js::set('confirmDelete', $lang->testsuite->confirmDelete);
|
||||
js::set('confirmDelete', $lang->testcase->confirmDelete);
|
||||
js::set('batchDelete', $lang->testcase->confirmBatchDelete);
|
||||
js::set('flow', $config->global->flow);
|
||||
?>
|
||||
@@ -36,29 +36,29 @@ js::set('flow', $config->global->flow);
|
||||
</div>
|
||||
<div class='btn-toolbar pull-left'>
|
||||
<?php
|
||||
if(common::hasPriv('testsuite', 'library'))
|
||||
if(common::hasPriv('caselib', 'browse'))
|
||||
{
|
||||
echo html::a($this->inlink('library', "libID=$libID&browseType=all"), "<span class='text'>{$lang->testcase->allCases}</span>", '', "id='allTab' class='btn btn-link'");
|
||||
echo html::a($this->inlink('browse', "libID=$libID&browseType=all"), "<span class='text'>{$lang->testcase->allCases}</span>", '', "id='allTab' class='btn btn-link'");
|
||||
if($config->testcase->needReview or !empty($config->testcase->forceReview)) echo html::a($this->inlink('library', "libID=$libID&browseType=wait"), "<span class='text'>" . $lang->testcase->statusList['wait'] . "</span>", '', "id='waitTab' class='btn btn-link'");
|
||||
}
|
||||
?>
|
||||
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->testcase->bySearch;?></a>
|
||||
<?php
|
||||
if(common::hasPriv('testsuite', 'libView'))
|
||||
if(common::hasPriv('caselib', 'view'))
|
||||
{
|
||||
$link = helper::createLink('testsuite', 'libView', "libID=$libID");
|
||||
echo html::a($link, "<i class='icon icon-list-alt muted'> </i>" . $this->lang->testsuite->libView, '', "class='btn btn-link'");
|
||||
$link = helper::createLink('caselib', 'view', "libID=$libID");
|
||||
echo html::a($link, "<i class='icon icon-list-alt muted'> </i>" . $this->lang->caselib->view, '', "class='btn btn-link'");
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<div class='btn-group'>
|
||||
<?php common::printLink('testsuite', 'exportTemplet', "libID=$libID", "<i class='icon icon-export muted'> </i>" . $lang->testsuite->exportTemplet, '', "class='btn btn-link export' data-width='35%'");?>
|
||||
<?php common::printLink('testsuite', 'import', "libID=$libID", "<i class='icon muted icon-import'> </i>" . $lang->testcase->importFile, '', "class='btn btn-link export'");?>
|
||||
<?php common::printLink('caselib', 'exportTemplet', "libID=$libID", "<i class='icon icon-export muted'> </i>" . $lang->caselib->exportTemplet, '', "class='btn btn-link export' data-width='35%'");?>
|
||||
<?php common::printLink('caselib', 'import', "libID=$libID", "<i class='icon muted icon-import'> </i>" . $lang->testcase->importFile, '', "class='btn btn-link export'");?>
|
||||
</div>
|
||||
<?php $params = "libID=$libID&moduleID=" . (isset($moduleID) ? $moduleID : 0);?>
|
||||
<?php common::printLink('testsuite', 'batchCreateCase', $params, "<i class='icon-plus'></i>" . $lang->testcase->batchCreate, '', "class='btn btn-secondary'");?>
|
||||
<?php common::printLink('testsuite', 'createCase', $params, "<i class='icon-plus'></i>" . $lang->testcase->create, '', "class='btn btn-primary'");?>
|
||||
<?php common::printLink('caselib', 'batchCreateCase', $params, "<i class='icon-plus'></i>" . $lang->testcase->batchCreate, '', "class='btn btn-secondary'");?>
|
||||
<?php common::printLink('caselib', 'createCase', $params, "<i class='icon-plus'></i>" . $lang->testcase->create, '', "class='btn btn-primary'");?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
@@ -69,7 +69,7 @@ js::set('flow', $config->global->flow);
|
||||
<?php if(!$moduleTree):?>
|
||||
<hr class="space">
|
||||
<div class="text-center text-muted">
|
||||
<?php echo $lang->testsuite->noModule;?>
|
||||
<?php echo $lang->caselib->noModule;?>
|
||||
</div>
|
||||
<hr class="space">
|
||||
<?php endif;?>
|
||||
@@ -86,8 +86,8 @@ js::set('flow', $config->global->flow);
|
||||
<div class="table-empty-tip">
|
||||
<p>
|
||||
<span class="text-muted"><?php echo $lang->testcase->noCase;?></span>
|
||||
<?php if(common::hasPriv('testsuite', 'createCase')):?>
|
||||
<?php echo html::a($this->createLink('testsuite', 'createCase', "libID=$libID&moduleID=" . (isset($moduleID) ? $moduleID : 0)), "<i class='icon icon-plus'></i> " . $lang->testcase->create, '', "class='btn btn-info'");?>
|
||||
<?php if(common::hasPriv('caselib', 'createCase')):?>
|
||||
<?php echo html::a($this->createLink('caselib', 'createCase', "libID=$libID&moduleID=" . (isset($moduleID) ? $moduleID : 0)), "<i class='icon icon-plus'></i> " . $lang->testcase->create, '', "class='btn btn-info'");?>
|
||||
<?php endif;?>
|
||||
</p>
|
||||
</div>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* The createlib view of testsuite module of ZenTaoPMS.
|
||||
* The createlib view of caselib module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package testsuite
|
||||
* @package caselib
|
||||
* @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
@@ -15,16 +15,16 @@
|
||||
<div id="mainContent" class="main-content">
|
||||
<div class="center-block">
|
||||
<div class="main-header">
|
||||
<h2><?php echo $lang->testsuite->createLib;?></h2>
|
||||
<h2><?php echo $lang->caselib->create;?></h2>
|
||||
</div>
|
||||
<form class="load-indicator main-form form-ajax" id="createForm" method="post" target='hiddenwin'>
|
||||
<table class="table table-form">
|
||||
<tr>
|
||||
<th><?php echo $lang->testsuite->name;?></th>
|
||||
<th><?php echo $lang->caselib->name;?></th>
|
||||
<td><?php echo html::input('name', '', "class='form-control'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->testsuite->desc;?></th>
|
||||
<th><?php echo $lang->caselib->desc;?></th>
|
||||
<td><?php echo html::textarea('desc', '', "rows=10 class='form-control'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* The create case view of testsuite module of ZenTaoPMS.
|
||||
* The create case view of caselib module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package testsuite
|
||||
* @package caselib
|
||||
* @version $Id: createcase.html.php 4904 2013-06-26 05:37:45Z wyd621@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->testcase->create;?></h2>
|
||||
<div class="pull-right btn-toolbar">
|
||||
<?php $customLink = $this->createLink('custom', 'ajaxSaveCustomFields', 'module=testsuite§ion=custom&key=createFields');?>
|
||||
<?php $customLink = $this->createLink('custom', 'ajaxSaveCustomFields', 'module=caselib§ion=custom&key=createFields');?>
|
||||
<?php include '../../common/view/customfield.html.php';?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* The edit view of caselib module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package caselib
|
||||
* @version $Id: edit.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/kindeditor.html.php';?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->caselib->edit;?></h2>
|
||||
</div>
|
||||
<form class='load-indicator main-form form-ajax' method='post' target='hiddenwin' id='dataform'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th><?php echo $lang->caselib->name;?></th>
|
||||
<td><?php echo html::input('name', $lib->name, "class='form-control'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->caselib->desc;?></th>
|
||||
<td><?php echo html::textarea('desc', htmlspecialchars($lib->desc), "rows=10 class='form-control'");?></td>
|
||||
</tr>
|
||||
<?php $this->printExtendFields($lib, 'table');?>
|
||||
<tr>
|
||||
<td class='text-center form-actions' colspan='2'>
|
||||
<?php echo html::submitButton();?>
|
||||
<?php echo html::backButton();?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
@@ -7,7 +7,7 @@
|
||||
<?php else:?>
|
||||
<div id="mainContent" class="main-content">
|
||||
<div class="main-header">
|
||||
<h2><?php echo $lang->testsuite->import;?></h2>
|
||||
<h2><?php echo $lang->caselib->import;?></h2>
|
||||
</div>
|
||||
<form target='hiddenwin' method='post'>
|
||||
<table class='table active-disabled table-form table-striped'>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* The view lib file of testsuite module of ZenTaoPMS.
|
||||
* The view lib file of caselib module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package testsuite
|
||||
* @package caselib
|
||||
* @version $Id: view.html.php 4141 2013-01-18 06:15:13Z zhujinyonging@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
@@ -13,14 +13,14 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='btn-toolbar pull-left'>
|
||||
<?php $browseLink = $this->session->caseList ? $this->session->caseList : $this->createLink('testsuite', 'library', "libID=$lib->id");?>
|
||||
<?php $browseLink = $this->session->caseList ? $this->session->caseList : $this->createLink('caselib', 'browse', "libID=$lib->id");?>
|
||||
<?php common::printBack($browseLink, 'btn btn-secondary');?>
|
||||
<div class='divider'></div>
|
||||
<div class='page-title'>
|
||||
<span class='label label-id'><?php echo $lib->id;?></span>
|
||||
<span class='text' title='<?php echo $lib->name;?>'><?php echo $lib->name;?></span>
|
||||
<?php if($lib->deleted):?>
|
||||
<span class='label label-danger'><?php echo $lang->testsuite->deleted;?></span>
|
||||
<span class='label label-danger'><?php echo $lang->caselib->deleted;?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -28,7 +28,7 @@
|
||||
<div id='mainContent'>
|
||||
<div class='cell'>
|
||||
<div class='detail'>
|
||||
<div class='detail-title'><?php echo $lang->testsuite->legendDesc;?></div>
|
||||
<div class='detail-title'><?php echo $lang->caselib->legendDesc;?></div>
|
||||
<div class='detail-content article-content'><?php echo $lib->desc;?></div>
|
||||
</div>
|
||||
<?php include '../../common/view/action.html.php';?>
|
||||
@@ -42,8 +42,8 @@
|
||||
if(!$lib->deleted)
|
||||
{
|
||||
echo "<div class='divider'></div>";
|
||||
common::printIcon('testsuite', 'edit', "libID=$lib->id");
|
||||
common::printIcon('testsuite', 'delete', "libID=$lib->id", '', 'button', 'trash', 'hiddenwin');
|
||||
common::printIcon('caselib', 'edit', "libID=$lib->id");
|
||||
common::printIcon('caselib', 'delete', "libID=$lib->id", '', 'button', 'trash', 'hiddenwin');
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
+15
-12
@@ -142,7 +142,7 @@ $lang->searchObjects['release'] = 'Release';
|
||||
$lang->searchObjects['productplan'] = $lang->productCommon . 'Plan';
|
||||
$lang->searchObjects['testtask'] = 'Request';
|
||||
$lang->searchObjects['doc'] = 'Document';
|
||||
$lang->searchObjects['testsuite'] = 'Case Library';
|
||||
$lang->searchObjects['caselib'] = 'Case Library';
|
||||
$lang->searchObjects['testreport'] = 'Test Report';
|
||||
$lang->searchTips = 'ID (ctrl+g)';
|
||||
|
||||
@@ -273,7 +273,7 @@ $lang->qa->menu->testcase = array('link' => 'Case|testcase|browse|productID=%s'
|
||||
$lang->qa->menu->testtask = array('link' => 'Request|testtask|browse|productID=%s');
|
||||
$lang->qa->menu->testsuite = array('link' => 'Suite|testsuite|browse|productID=%s');
|
||||
$lang->qa->menu->report = array('link' => 'Report|testreport|browse|productID=%s');
|
||||
$lang->qa->menu->caselib = array('link' => 'Case Library|testsuite|library');
|
||||
$lang->qa->menu->caselib = array('link' => 'Case Library|caselib|browse');
|
||||
|
||||
$lang->bug = new stdclass();
|
||||
$lang->bug->menu = new stdclass();
|
||||
@@ -283,7 +283,7 @@ $lang->bug->menu->testcase = array('link' => 'Case|testcase|browse|productID=%s
|
||||
$lang->bug->menu->testtask = array('link' => 'Request|testtask|browse|productID=%s');
|
||||
$lang->bug->menu->testsuite = array('link' => 'Suite|testsuite|browse|productID=%s');
|
||||
$lang->bug->menu->report = array('link' => 'Report|testreport|browse|productID=%s');
|
||||
$lang->bug->menu->caselib = array('link' => 'Case Library|testsuite|library');
|
||||
$lang->bug->menu->caselib = array('link' => 'Case Library|caselib|browse');
|
||||
|
||||
$lang->testcase = new stdclass();
|
||||
$lang->testcase->menu = new stdclass();
|
||||
@@ -292,7 +292,7 @@ $lang->testcase->menu->testcase = array('link' => 'Case|testcase|browse|product
|
||||
$lang->testcase->menu->testtask = array('link' => 'Request|testtask|browse|productID=%s');
|
||||
$lang->testcase->menu->testsuite = array('link' => 'Suite|testsuite|browse|productID=%s');
|
||||
$lang->testcase->menu->report = array('link' => 'Report|testreport|browse|productID=%s');
|
||||
$lang->testcase->menu->caselib = array('link' => 'Case Library|testsuite|library');
|
||||
$lang->testcase->menu->caselib = array('link' => 'Case Library|caselib|browse');
|
||||
|
||||
$lang->testtask = new stdclass();
|
||||
$lang->testtask->menu = new stdclass();
|
||||
@@ -301,7 +301,7 @@ $lang->testtask->menu->testcase = array('link' => 'Case|testcase|browse|product
|
||||
$lang->testtask->menu->testtask = array('link' => 'Request|testtask|browse|productID=%s', 'alias' => 'view,create,edit,linkcase,cases,start,close,batchrun,groupcase,report');
|
||||
$lang->testtask->menu->testsuite = array('link' => 'Suite|testsuite|browse|productID=%s');
|
||||
$lang->testtask->menu->report = array('link' => 'Report|testreport|browse|productID=%s');
|
||||
$lang->testtask->menu->caselib = array('link' => 'Case Library|testsuite|library');
|
||||
$lang->testtask->menu->caselib = array('link' => 'Case Library|caselib|browse');
|
||||
|
||||
$lang->testsuite = new stdclass();
|
||||
$lang->testsuite->menu = new stdclass();
|
||||
@@ -310,7 +310,7 @@ $lang->testsuite->menu->testcase = array('link' => 'Case|testcase|browse|produc
|
||||
$lang->testsuite->menu->testtask = array('link' => 'Request|testtask|browse|productID=%s');
|
||||
$lang->testsuite->menu->testsuite = array('link' => 'Suite|testsuite|browse|productID=%s', 'alias' => 'view,create,edit,linkcase');
|
||||
$lang->testsuite->menu->report = array('link' => 'Report|testreport|browse|productID=%s');
|
||||
$lang->testsuite->menu->caselib = array('link' => 'Case Library|testsuite|library');
|
||||
$lang->testsuite->menu->caselib = array('link' => 'Case Library|caselib|browse');
|
||||
|
||||
$lang->testreport = new stdclass();
|
||||
$lang->testreport->menu = new stdclass();
|
||||
@@ -319,7 +319,7 @@ $lang->testreport->menu->testcase = array('link' => 'Case|testcase|browse|produ
|
||||
$lang->testreport->menu->testtask = array('link' => 'Request|testtask|browse|productID=%s');
|
||||
$lang->testreport->menu->testsuite = array('link' => 'Suite|testsuite|browse|productID=%s');
|
||||
$lang->testreport->menu->report = array('link' => 'Report|testreport|browse|productID=%s', 'alias' => 'view,create,edit');
|
||||
$lang->testreport->menu->caselib = array('link' => 'Case Library|testsuite|library');
|
||||
$lang->testreport->menu->caselib = array('link' => 'Case Library|caselib|browse');
|
||||
|
||||
$lang->caselib = new stdclass();
|
||||
$lang->caselib->menu = new stdclass();
|
||||
@@ -328,7 +328,7 @@ $lang->caselib->menu->testcase = array('link' => 'Case|testcase|browse|');
|
||||
$lang->caselib->menu->testtask = array('link' => 'Request|testtask|browse|');
|
||||
$lang->caselib->menu->testsuite = array('link' => 'Suite|testsuite|browse|');
|
||||
$lang->caselib->menu->report = array('link' => 'Report|testreport|browse|');
|
||||
$lang->caselib->menu->caselib = array('link' => 'Case Library|testsuite|library', 'alias' => 'createlib,createcase,libview,edit,batchcreatecase,showimport', 'subModule' => 'tree,testcase');
|
||||
$lang->caselib->menu->caselib = array('link' => 'Case Library|caselib|browse', 'alias' => 'create,createcase,view,edit,batchcreatecase,showimport', 'subModule' => 'tree,testcase');
|
||||
|
||||
/* Doc menu settings. */
|
||||
$lang->doc = new stdclass();
|
||||
@@ -691,6 +691,7 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyStory')
|
||||
unset($lang->searchObjects['build']);
|
||||
unset($lang->searchObjects['testtask']);
|
||||
unset($lang->searchObjects['testsuite']);
|
||||
unset($lang->searchObjects['caselib']);
|
||||
unset($lang->searchObjects['testreport']);
|
||||
}
|
||||
|
||||
@@ -727,6 +728,7 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTask')
|
||||
unset($lang->searchObjects['release']);
|
||||
unset($lang->searchObjects['productplan']);
|
||||
unset($lang->searchObjects['testsuite']);
|
||||
unset($lang->searchObjects['caselib']);
|
||||
unset($lang->searchObjects['testreport']);
|
||||
}
|
||||
|
||||
@@ -760,7 +762,7 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTest')
|
||||
$lang->menu->testcase = 'Case|testcase|index';
|
||||
$lang->menu->testsuite = 'Suite|testsuite|index';
|
||||
$lang->menu->testtask = 'Request|testtask|index';
|
||||
$lang->menu->caselib = 'Case Library|testsuite|library';
|
||||
$lang->menu->caselib = 'Case Library|caselib|browse';
|
||||
|
||||
$lang->menuOrder[6] = 'bug';
|
||||
$lang->menuOrder[7] = 'testcase';
|
||||
@@ -847,9 +849,9 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTest')
|
||||
|
||||
/* Adjust sub menu of caselib module. */
|
||||
$lang->caselib->menu = new stdclass();
|
||||
$lang->caselib->menu->all = 'All|testsuite|library|libID=%s&browseType=all';
|
||||
$lang->caselib->menu->wait = 'Waiting|testsuite|library|libID=%s&browseType=wait';
|
||||
$lang->caselib->menu->view = 'View|testsuite|libview|libID=%s';
|
||||
$lang->caselib->menu->all = 'All|caselib|browse|libID=%s&browseType=all';
|
||||
$lang->caselib->menu->wait = 'Waiting|caselib|browse|libID=%s&browseType=wait';
|
||||
$lang->caselib->menu->view = 'View|caselib|view|libID=%s';
|
||||
|
||||
$lang->caselib->menuOrder[5] = 'lib';
|
||||
$lang->caselib->menuOrder[10] = 'all';
|
||||
@@ -881,6 +883,7 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTest')
|
||||
$lang->menugroup->testcase = 'testcase';
|
||||
$lang->menugroup->testtask = 'testtask';
|
||||
$lang->menugroup->testsuite = 'testsuite';
|
||||
$lang->menugroup->caselib = 'caselib';
|
||||
$lang->menugroup->testreport = 'testtask';
|
||||
$lang->menugroup->build = 'product';
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ $lang->bug->menuOrder = $lang->qa->menuOrder;
|
||||
$lang->testcase->menuOrder = $lang->bug->menuOrder;
|
||||
$lang->testtask->menuOrder = $lang->testcase->menuOrder;
|
||||
$lang->testsuite->menuOrder = $lang->testcase->menuOrder;
|
||||
$lang->caselib->menuOrder = $lang->testcase->menuOrder;
|
||||
$lang->testreport->menuOrder = $lang->testcase->menuOrder;
|
||||
|
||||
/* doc menu order. */
|
||||
|
||||
@@ -142,7 +142,7 @@ $lang->searchObjects['release'] = '发布';
|
||||
$lang->searchObjects['productplan'] = $lang->productCommon . '计划';
|
||||
$lang->searchObjects['testtask'] = '测试单';
|
||||
$lang->searchObjects['doc'] = '文档';
|
||||
$lang->searchObjects['testsuite'] = '用例库';
|
||||
$lang->searchObjects['caselib'] = '用例库';
|
||||
$lang->searchObjects['testreport'] = '测试报告';
|
||||
$lang->searchTips = '编号(ctrl+g)';
|
||||
|
||||
@@ -273,7 +273,7 @@ $lang->qa->menu->testcase = array('link' => '用例|testcase|browse|productID=%
|
||||
$lang->qa->menu->testtask = array('link' => '测试单|testtask|browse|productID=%s');
|
||||
$lang->qa->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s');
|
||||
$lang->qa->menu->report = array('link' => '报告|testreport|browse|productID=%s');
|
||||
$lang->qa->menu->caselib = array('link' => '用例库|testsuite|library');
|
||||
$lang->qa->menu->caselib = array('link' => '用例库|caselib|browse');
|
||||
|
||||
$lang->bug = new stdclass();
|
||||
$lang->bug->menu = new stdclass();
|
||||
@@ -283,7 +283,7 @@ $lang->bug->menu->testcase = array('link' => '用例|testcase|browse|productID=
|
||||
$lang->bug->menu->testtask = array('link' => '测试单|testtask|browse|productID=%s');
|
||||
$lang->bug->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s');
|
||||
$lang->bug->menu->report = array('link' => '报告|testreport|browse|productID=%s');
|
||||
$lang->bug->menu->caselib = array('link' => '用例库|testsuite|library');
|
||||
$lang->bug->menu->caselib = array('link' => '用例库|caselib|browse');
|
||||
|
||||
$lang->testcase = new stdclass();
|
||||
$lang->testcase->menu = new stdclass();
|
||||
@@ -292,7 +292,7 @@ $lang->testcase->menu->testcase = array('link' => '用例|testcase|browse|produ
|
||||
$lang->testcase->menu->testtask = array('link' => '测试单|testtask|browse|productID=%s');
|
||||
$lang->testcase->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s');
|
||||
$lang->testcase->menu->report = array('link' => '报告|testreport|browse|productID=%s');
|
||||
$lang->testcase->menu->caselib = array('link' => '用例库|testsuite|library');
|
||||
$lang->testcase->menu->caselib = array('link' => '用例库|caselib|browse');
|
||||
|
||||
$lang->testtask = new stdclass();
|
||||
$lang->testtask->menu = new stdclass();
|
||||
@@ -301,7 +301,7 @@ $lang->testtask->menu->testcase = array('link' => '用例|testcase|browse|produ
|
||||
$lang->testtask->menu->testtask = array('link' => '测试单|testtask|browse|productID=%s', 'alias' => 'view,create,edit,linkcase,cases,start,close,batchrun,groupcase,report');
|
||||
$lang->testtask->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s');
|
||||
$lang->testtask->menu->report = array('link' => '报告|testreport|browse|productID=%s');
|
||||
$lang->testtask->menu->caselib = array('link' => '用例库|testsuite|library');
|
||||
$lang->testtask->menu->caselib = array('link' => '用例库|caselib|browse');
|
||||
|
||||
$lang->testsuite = new stdclass();
|
||||
$lang->testsuite->menu = new stdclass();
|
||||
@@ -310,7 +310,7 @@ $lang->testsuite->menu->testcase = array('link' => '用例|testcase|browse|prod
|
||||
$lang->testsuite->menu->testtask = array('link' => '测试单|testtask|browse|productID=%s');
|
||||
$lang->testsuite->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s', 'alias' => 'view,create,edit,linkcase');
|
||||
$lang->testsuite->menu->report = array('link' => '报告|testreport|browse|productID=%s');
|
||||
$lang->testsuite->menu->caselib = array('link' => '用例库|testsuite|library');
|
||||
$lang->testsuite->menu->caselib = array('link' => '用例库|caselib|browse');
|
||||
|
||||
$lang->testreport = new stdclass();
|
||||
$lang->testreport->menu = new stdclass();
|
||||
@@ -319,7 +319,7 @@ $lang->testreport->menu->testcase = array('link' => '用例|testcase|browse|pro
|
||||
$lang->testreport->menu->testtask = array('link' => '测试单|testtask|browse|productID=%s');
|
||||
$lang->testreport->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s');
|
||||
$lang->testreport->menu->report = array('link' => '报告|testreport|browse|productID=%s', 'alias' => 'view,create,edit');
|
||||
$lang->testreport->menu->caselib = array('link' => '用例库|testsuite|library');
|
||||
$lang->testreport->menu->caselib = array('link' => '用例库|caselib|browse');
|
||||
|
||||
$lang->caselib = new stdclass();
|
||||
$lang->caselib->menu = new stdclass();
|
||||
@@ -328,7 +328,7 @@ $lang->caselib->menu->testcase = array('link' => '用例|testcase|browse|');
|
||||
$lang->caselib->menu->testtask = array('link' => '测试单|testtask|browse|');
|
||||
$lang->caselib->menu->testsuite = array('link' => '套件|testsuite|browse|');
|
||||
$lang->caselib->menu->report = array('link' => '报告|testreport|browse|');
|
||||
$lang->caselib->menu->caselib = array('link' => '用例库|testsuite|library', 'alias' => 'createlib,createcase,libview,edit,batchcreatecase,showimport', 'subModule' => 'tree,testcase');
|
||||
$lang->caselib->menu->caselib = array('link' => '用例库|caselib|browse', 'alias' => 'create,createcase,view,edit,batchcreatecase,showimport', 'subModule' => 'tree,testcase');
|
||||
|
||||
/* 文档视图菜单设置。*/
|
||||
$lang->doc = new stdclass();
|
||||
@@ -691,6 +691,7 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyStory')
|
||||
unset($lang->searchObjects['build']);
|
||||
unset($lang->searchObjects['testtask']);
|
||||
unset($lang->searchObjects['testsuite']);
|
||||
unset($lang->searchObjects['caselib']);
|
||||
unset($lang->searchObjects['testreport']);
|
||||
}
|
||||
|
||||
@@ -727,6 +728,7 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTask')
|
||||
unset($lang->searchObjects['release']);
|
||||
unset($lang->searchObjects['productplan']);
|
||||
unset($lang->searchObjects['testsuite']);
|
||||
unset($lang->searchObjects['caselib']);
|
||||
unset($lang->searchObjects['testreport']);
|
||||
}
|
||||
|
||||
@@ -760,7 +762,7 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTest')
|
||||
$lang->menu->testcase = '用例|testcase|index';
|
||||
$lang->menu->testsuite = '套件|testsuite|index';
|
||||
$lang->menu->testtask = '测试单|testtask|index';
|
||||
$lang->menu->caselib = '用例库|testsuite|library';
|
||||
$lang->menu->caselib = '用例库|caselib|browse';
|
||||
|
||||
$lang->menuOrder[6] = 'bug';
|
||||
$lang->menuOrder[7] = 'testcase';
|
||||
@@ -847,9 +849,9 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTest')
|
||||
|
||||
/* Adjust sub menu of caselib module. */
|
||||
$lang->caselib->menu = new stdclass();
|
||||
$lang->caselib->menu->all = '所有|testsuite|library|libID=%s&browseType=all';
|
||||
$lang->caselib->menu->wait = '待评审|testsuite|library|libID=%s&browseType=wait';
|
||||
$lang->caselib->menu->view = '概况|testsuite|libview|libID=%s';
|
||||
$lang->caselib->menu->all = '所有|caselib|browse|libID=%s&browseType=all';
|
||||
$lang->caselib->menu->wait = '待评审|caselib|browse|libID=%s&browseType=wait';
|
||||
$lang->caselib->menu->view = '概况|caselib|view|libID=%s';
|
||||
|
||||
$lang->caselib->menuOrder[5] = 'lib';
|
||||
$lang->caselib->menuOrder[10] = 'all';
|
||||
@@ -882,6 +884,7 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTest')
|
||||
$lang->menugroup->case = 'testcase';
|
||||
$lang->menugroup->testtask = 'testtask';
|
||||
$lang->menugroup->testsuite = 'testsuite';
|
||||
$lang->menugroup->caselib = 'caselib';
|
||||
$lang->menugroup->testreport = 'testtask';
|
||||
$lang->menugroup->build = 'product';
|
||||
|
||||
|
||||
+12
-6
@@ -596,10 +596,10 @@ class commonModel extends model
|
||||
/* Avoid user thinking the page is shaking when the menu toggle class 'active' */
|
||||
if($config->global->flow == 'onlyTest')
|
||||
{
|
||||
if($currentModule == 'bug' && $currentMethod == 'browse') $active = '';
|
||||
if($currentModule == 'testcase' && $currentMethod == 'browse') $active = '';
|
||||
if($currentModule == 'testtask' && $currentMethod == 'browse') $active = '';
|
||||
if($currentModule == 'testsuite' && $currentMethod == 'library') $active = '';
|
||||
if($currentModule == 'bug' && $currentMethod == 'browse') $active = '';
|
||||
if($currentModule == 'testcase' && $currentMethod == 'browse') $active = '';
|
||||
if($currentModule == 'testtask' && $currentMethod == 'browse') $active = '';
|
||||
if($currentModule == 'caselib' && $currentMethod == 'browse') $active = '';
|
||||
}
|
||||
|
||||
$label = $menuItem->text;
|
||||
@@ -1716,6 +1716,8 @@ EOD;
|
||||
$user->admin = strpos($this->app->company->admins, ",{$user->account},") !== false;
|
||||
$this->session->set('user', $user);
|
||||
$this->app->user = $user;
|
||||
$this->loadModel('action')->create('user', $user->id, 'login');
|
||||
$this->loadModel('score')->create('user', 'login');
|
||||
|
||||
if($isFreepasswd) die(js::locate($this->config->webRoot));
|
||||
|
||||
@@ -1750,11 +1752,15 @@ EOD;
|
||||
/* Change for task #5384. */
|
||||
if(isset($queryString['time']))
|
||||
{
|
||||
$timestamp = $queryString['time'];
|
||||
if(strlen($timestamp) > 10) $timestamp = substr($timestamp, 0, 10);
|
||||
if(strlen($timestamp) != 10 or $timestamp{0} >= '4') $this->response('ERROR_TIMESTAMP');
|
||||
|
||||
$result = $this->get->token == md5($entry->code . $entry->key . $queryString['time']);
|
||||
if($result)
|
||||
{
|
||||
if($queryString['time'] <= $entry->calledTime) $this->response('CALLED_TIME');
|
||||
$this->loadModel('entry')->updateTime($entry->code, $queryString['time']);
|
||||
if($timestamp <= $entry->calledTime) $this->response('CALLED_TIME');
|
||||
$this->loadModel('entry')->updateTime($entry->code, $timestamp);
|
||||
unset($_GET['time']);
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -64,9 +64,10 @@
|
||||
<?php if(!empty($action->comment)):?>
|
||||
<?php if($canEditComment):?>
|
||||
<?php echo html::commonButton('<i class="icon icon-pencil"></i>', "title='{$lang->action->editComment}'", 'btn btn-link btn-icon btn-sm btn-edit-comment');?>
|
||||
<style>.comment .comment-content{width: 98%}</style>
|
||||
<?php endif;?>
|
||||
<div class='article-content comment'>
|
||||
<?php echo strip_tags($action->comment) == $action->comment ? nl2br($action->comment) : $action->comment;?>
|
||||
<div class='comment-content'><?php echo strip_tags($action->comment) == $action->comment ? nl2br($action->comment) : $action->comment;?></div>
|
||||
</div>
|
||||
<?php if($canEditComment):?>
|
||||
<form method='post' class='comment-edit-form' action='<?php echo $this->createLink('action', 'editComment', "actionID=$action->id")?>'>
|
||||
|
||||
@@ -22,7 +22,8 @@ $config->custom->requiredModules[50] = 'bug';
|
||||
$config->custom->requiredModules[55] = 'testcase';
|
||||
$config->custom->requiredModules[60] = 'testsuite';
|
||||
$config->custom->requiredModules[65] = 'testreport';
|
||||
$config->custom->requiredModules[70] = 'testtask';
|
||||
$config->custom->requiredModules[70] = 'caselib';
|
||||
$config->custom->requiredModules[75] = 'testtask';
|
||||
|
||||
$config->custom->requiredModules[75] = 'doc';
|
||||
|
||||
@@ -50,6 +51,7 @@ $config->custom->fieldList['bug']['resolve'] = 'resolvedBuild,resolvedDa
|
||||
$config->custom->fieldList['testcase']['create'] = 'stage,story,pri,precondition,keywords';
|
||||
$config->custom->fieldList['testcase']['edit'] = 'stage,story,pri,precondition,keywords,status';
|
||||
$config->custom->fieldList['testsuite'] = 'desc';
|
||||
$config->custom->fieldList['caselib'] = 'desc';
|
||||
$config->custom->fieldList['testcase']['createcase'] = 'lib,stage,pri,precondition,keywords';
|
||||
$config->custom->fieldList['testreport'] = 'begin,end,members,report';
|
||||
$config->custom->fieldList['testtask'] = 'owner,pri,status,desc,comment';
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
|
||||
if($moduleName == 'doc' and $method == 'createlib') $method = 'createLib';
|
||||
if($moduleName == 'doc' and $method == 'editlib') $method = 'editLib';
|
||||
if($moduleName == 'testsuite' and $method == 'createlib') $method = 'createLib';
|
||||
if($moduleName == 'testsuite' and $method == 'createcase')
|
||||
if($moduleName == 'caselib' and $method == 'createcase')
|
||||
{
|
||||
$this->app->loadLang('testcase');
|
||||
$fields = $this->custom->getFormFields('testcase', $method);
|
||||
|
||||
@@ -41,7 +41,7 @@ class devModel extends model
|
||||
{
|
||||
if(isset($this->config->dev->tableMap[$module])) $aliasModule = $this->config->dev->tableMap[$module];
|
||||
if(strpos($aliasModule, '-') !== false) list($aliasModule, $subLang) = explode('-', $aliasModule);
|
||||
$this->app->loadLang($aliasModule ? $aliasModule : $module);
|
||||
if(strpos($module, 'im_') === false) $this->app->loadLang($aliasModule ? $aliasModule : $module);
|
||||
}
|
||||
catch(PDOException $e)
|
||||
{
|
||||
|
||||
@@ -364,7 +364,7 @@ class docModel extends model
|
||||
elseif($browseType == "bymodule")
|
||||
{
|
||||
$modules = 0;
|
||||
if($moduleID) $modules = $this->loadModel('tree')->getAllChildId($moduleID);
|
||||
if($moduleID) $modules = (strpos($this->config->doc->custom->showLibs, 'children') === false) ? array($moduleID => $moduleID) : $this->loadModel('tree')->getAllChildId($moduleID);
|
||||
$docs = $this->getDocs($libID, $modules, $sort, $pager);
|
||||
}
|
||||
elseif($browseType == "bygrid")
|
||||
@@ -508,7 +508,6 @@ class docModel extends model
|
||||
->beginIF(!empty($module) or strpos($this->config->doc->custom->showLibs, 'children') === false)->andWhere('module')->in($module)->fi()
|
||||
->query();
|
||||
|
||||
|
||||
$docIdList = array();
|
||||
while($doc = $stmt->fetch())
|
||||
{
|
||||
@@ -566,7 +565,7 @@ class docModel extends model
|
||||
$doc->content = isset($docContent->content) ? $docContent->content : '';
|
||||
$doc->contentType = isset($docContent->type) ? $docContent->type : '';
|
||||
|
||||
$doc = $this->loadModel('file')->replaceImgURL($doc, 'content');
|
||||
if($doc->type != 'url') $doc = $this->loadModel('file')->replaceImgURL($doc, 'content');
|
||||
if($setImgSize) $doc->content = $this->file->setImgSize($doc->content);
|
||||
$doc->files = $docFiles;
|
||||
|
||||
|
||||
@@ -16,3 +16,4 @@ $config->entry->errcode['ACCOUNT_UNBOUND'] = 403;
|
||||
$config->entry->errcode['EMPTY_ENTRY'] = 404;
|
||||
$config->entry->errcode['CALLED_TIME'] = 405;
|
||||
$config->entry->errcode['INVALID_ACCOUNT'] = 406;
|
||||
$config->entry->errcode['ERROR_TIMESTAMP'] = 407;
|
||||
|
||||
@@ -54,3 +54,5 @@ $lang->entry->errmsg['IP_DENIED'] = 'IP ist unzulässig.';
|
||||
$lang->entry->errmsg['ACCOUNT_UNBOUND'] = 'Account is not bound.';
|
||||
$lang->entry->errmsg['INVALID_ACCOUNT'] = 'Account is not exists';
|
||||
$lang->entry->errmsg['EMPTY_ENTRY'] = 'Key des Eintrags fehlt.';
|
||||
$lang->entry->errmsg['CALLED_TIME'] = 'Token has expired';
|
||||
$lang->entry->errmsg['ERROR_TIMESTAMP'] = 'Timestamp Error';
|
||||
|
||||
@@ -55,3 +55,4 @@ $lang->entry->errmsg['ACCOUNT_UNBOUND'] = 'Account is not bound.';
|
||||
$lang->entry->errmsg['INVALID_ACCOUNT'] = 'Invalid account.';
|
||||
$lang->entry->errmsg['EMPTY_ENTRY'] = 'Application does not exist.';
|
||||
$lang->entry->errmsg['CALLED_TIME'] = 'Token has expired';
|
||||
$lang->entry->errmsg['ERROR_TIMESTAMP'] = 'Timestamp Error';
|
||||
|
||||
@@ -55,3 +55,4 @@ $lang->entry->errmsg['ACCOUNT_UNBOUND'] = '未绑定用户';
|
||||
$lang->entry->errmsg['INVALID_ACCOUNT'] = '用户不存在';
|
||||
$lang->entry->errmsg['EMPTY_ENTRY'] = '应用不存在';
|
||||
$lang->entry->errmsg['CALLED_TIME'] = 'Token已失效';
|
||||
$lang->entry->errmsg['ERROR_TIMESTAMP'] = '错误的时间戳。';
|
||||
|
||||
@@ -55,3 +55,4 @@ $lang->entry->errmsg['ACCOUNT_UNBOUND'] = '未綁定用戶';
|
||||
$lang->entry->errmsg['INVALID_ACCOUNT'] = '用戶不存在';
|
||||
$lang->entry->errmsg['EMPTY_ENTRY'] = '應用不存在';
|
||||
$lang->entry->errmsg['CALLED_TIME'] = 'Token已失效';
|
||||
$lang->entry->errmsg['ERROR_TIMESTAMP'] = '錯誤的時間戳。';
|
||||
|
||||
@@ -510,6 +510,9 @@ class fileModel extends model
|
||||
*/
|
||||
public function parseCSV($fileName)
|
||||
{
|
||||
/* Parse file only in zentao. */
|
||||
if(strpos(realpath($fileName), $this->app->getBasePath()) !== 0) return array();
|
||||
|
||||
$content = file_get_contents($fileName);
|
||||
/* Fix bug #890. */
|
||||
$content = str_replace("\x82\x32", "\x10", $content);
|
||||
|
||||
@@ -213,7 +213,6 @@ class group extends control
|
||||
foreach($this->lang->resource as $module => $moduleActions)
|
||||
{
|
||||
$modules[$module] = $this->lang->$module->common;
|
||||
if($module == 'caselib') $module = 'testsuite';
|
||||
foreach($moduleActions as $action)
|
||||
{
|
||||
$actions[$module][$action] = $this->lang->$module->$action;
|
||||
|
||||
@@ -658,22 +658,22 @@ $lang->testsuite->methodOrder[35] = 'unlinkCase';
|
||||
$lang->testsuite->methodOrder[40] = 'batchUnlinkCases';
|
||||
|
||||
$lang->resource->caselib = new stdclass();
|
||||
$lang->resource->caselib->library = 'library';
|
||||
$lang->resource->caselib->createLib = 'createLib';
|
||||
$lang->resource->caselib->edit = 'editLib';
|
||||
$lang->resource->caselib->browse = 'browse';
|
||||
$lang->resource->caselib->create = 'create';
|
||||
$lang->resource->caselib->edit = 'edit';
|
||||
$lang->resource->caselib->createCase = 'createCase';
|
||||
$lang->resource->caselib->libView = 'libView';
|
||||
$lang->resource->caselib->view = 'view';
|
||||
$lang->resource->caselib->batchCreateCase = 'batchCreateCase';
|
||||
$lang->resource->caselib->exportTemplet = 'exportTemplet';
|
||||
$lang->resource->caselib->import = 'importAction';
|
||||
$lang->resource->caselib->showImport = 'showImport';
|
||||
|
||||
$lang->caselib->methodOrder[0] = 'library';
|
||||
$lang->caselib->methodOrder[5] = 'createLib';
|
||||
$lang->caselib->methodOrder[0] = 'browse';
|
||||
$lang->caselib->methodOrder[5] = 'create';
|
||||
$lang->caselib->methodOrder[10] = 'edit';
|
||||
$lang->caselib->methodOrder[15] = 'createCase';
|
||||
$lang->caselib->methodOrder[20] = 'batchCreateCase';
|
||||
$lang->caselib->methodOrder[25] = 'libView';
|
||||
$lang->caselib->methodOrder[25] = 'view';
|
||||
$lang->caselib->methodOrder[30] = 'exportTemplet';
|
||||
$lang->caselib->methodOrder[35] = 'import';
|
||||
$lang->caselib->methodOrder[40] = 'showImport';
|
||||
|
||||
@@ -420,7 +420,6 @@ class groupModel extends model
|
||||
public function checkMenuModule($menu, $moduleName)
|
||||
{
|
||||
if(empty($menu)) return true;
|
||||
if($menu == 'caselib' and $moduleName == 'testsuite') return true;
|
||||
if($menu == 'other' and (isset($this->lang->menugroup->$moduleName) or isset($this->lang->menu->$moduleName))) return false;
|
||||
if($menu != 'other' and !($moduleName == $menu or (isset($this->lang->menugroup->$moduleName) and $this->lang->menugroup->$moduleName == $menu))) return false;
|
||||
return true;
|
||||
|
||||
@@ -111,7 +111,6 @@
|
||||
<?php endif;?>
|
||||
<td id='<?php echo $moduleName;?>' class='pv-10px' colspan='<?php echo !empty($lang->$moduleName->menus) ? 1 : 2?>'>
|
||||
<?php $i = 1;?>
|
||||
<?php if($moduleName == 'caselib') $moduleName = 'testsuite';?>
|
||||
<?php foreach($moduleActions as $action => $actionLabel):?>
|
||||
<?php if(!empty($lang->$moduleName->menus) and $action == 'browse') continue;;?>
|
||||
<?php if(!empty($version) and strpos($changelogs, ",$moduleName-$actionLabel,") === false) continue;?>
|
||||
|
||||
@@ -46,7 +46,7 @@ $lang->misc->zentao->cowin['reportbug'] = "Bug melden ";
|
||||
$lang->misc->zentao->cowin['feedback'] = "Feedback";
|
||||
$lang->misc->zentao->cowin['recommend'] = "More";
|
||||
|
||||
$lang->misc->zentao->service['zentaotrain']= 'Zentao Train';
|
||||
$lang->misc->zentao->service['zentaotrain']= 'Zentao Training';
|
||||
$lang->misc->zentao->service['idc'] = 'Zentao Cloud';
|
||||
$lang->misc->zentao->service['custom'] = 'Zentao Custom';
|
||||
$lang->misc->zentao->service['servicemore']= 'Mehr';
|
||||
@@ -82,6 +82,7 @@ $lang->misc->feature = new stdclass();
|
||||
$lang->misc->feature->lastest = 'Letzte Version';
|
||||
$lang->misc->feature->detailed = 'Details';
|
||||
|
||||
$lang->misc->releaseDate['11.6.3'] = '2019-09-24';
|
||||
$lang->misc->releaseDate['11.6.2'] = '2019-09-06';
|
||||
$lang->misc->releaseDate['11.6.1'] = '2019-08-23';
|
||||
$lang->misc->releaseDate['11.6.stable'] = '2019-07-12';
|
||||
@@ -114,16 +115,15 @@ $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.6.2'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.6.1'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.3'][] = array('title'=>'Fix bug.', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.2'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.1'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.6.stable'][] = array('title'=>'Improving the International Edition Interface', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.stable'][] = array('title'=>'Add translate function', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.2'][] = array('title'=>'Increase the security of ZenTao and increase the login password for weak password check', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.1'][] = array('title'=>'Add a third-party authentication and fix bugs.', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.2'][] = array('title'=>'Increase the security of ZenTao and increase the login password for weak password check', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.1'][] = array('title'=>'Add a third-party authentication and fix bugs.', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.stable'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.stable'][] = array('title'=>'Added filters to Dynamics', 'desc' => '');
|
||||
|
||||
@@ -46,7 +46,7 @@ $lang->misc->zentao->cowin['reportbug'] = "Report Bug ";
|
||||
$lang->misc->zentao->cowin['feedback'] = "Feedback";
|
||||
$lang->misc->zentao->cowin['recommend'] = "More";
|
||||
|
||||
$lang->misc->zentao->service['zentaotrain']= 'Zentao Train';
|
||||
$lang->misc->zentao->service['zentaotrain']= 'Zentao Training';
|
||||
$lang->misc->zentao->service['idc'] = 'Zentao Cloud';
|
||||
$lang->misc->zentao->service['custom'] = 'Zentao Custom';
|
||||
$lang->misc->zentao->service['servicemore']= 'More';
|
||||
@@ -82,6 +82,7 @@ $lang->misc->feature = new stdclass();
|
||||
$lang->misc->feature->lastest = 'Latest Version';
|
||||
$lang->misc->feature->detailed = 'Detail';
|
||||
|
||||
$lang->misc->releaseDate['11.6.3'] = '2019-09-24';
|
||||
$lang->misc->releaseDate['11.6.2'] = '2019-09-06';
|
||||
$lang->misc->releaseDate['11.6.1'] = '2019-08-23';
|
||||
$lang->misc->releaseDate['11.6.stable'] = '2019-07-12';
|
||||
@@ -114,16 +115,15 @@ $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.6.2'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.6.1'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.3'][] = array('title'=>'Fix bug.', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.2'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.1'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.6.stable'][] = array('title'=>'Improving the International Edition Interface', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.stable'][] = array('title'=>'Add translate function', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.2'][] = array('title'=>'Increase the security of ZenTao and increase the login password for weak password check', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.1'][] = array('title'=>'Add a third-party authentication and fix bugs.', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.2'][] = array('title'=>'Increase the security of ZenTao and increase the login password for weak password check', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.1'][] = array('title'=>'Add a third-party authentication and fix bugs.', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.stable'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.stable'][] = array('title'=>'Added filters to Dynamics', 'desc' => '');
|
||||
|
||||
@@ -82,6 +82,7 @@ $lang->misc->feature = new stdclass();
|
||||
$lang->misc->feature->lastest = '最新版本';
|
||||
$lang->misc->feature->detailed = '详情';
|
||||
|
||||
$lang->misc->releaseDate['11.6.3'] = '2019-09-24';
|
||||
$lang->misc->releaseDate['11.6.2'] = '2019-09-06';
|
||||
$lang->misc->releaseDate['11.6.1'] = '2019-08-23';
|
||||
$lang->misc->releaseDate['11.6.stable'] = '2019-07-12';
|
||||
@@ -114,16 +115,15 @@ $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.6.2'][] = array('title'=>'完善细节,修复Bug', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.6.1'][] = array('title'=>'完善细节,修复Bug', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.3'][] = array('title'=>'修复Bug', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.2'][] = array('title'=>'完善细节,修复Bug', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.1'][] = array('title'=>'完善细节,修复Bug', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.6.stable'][] = array('title'=>'改善国际版界面', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.stable'][] = array('title'=>'添加翻译功能', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.2'][] = array('title'=>'增加禅道安全性,增加登录禅道弱口令检查', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.1'][] = array('title'=>'新增第三方应用免密登录禅道,修复Bug', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.2'][] = array('title'=>'增加禅道安全性,增加登录禅道弱口令检查', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.1'][] = array('title'=>'新增第三方应用免密登录禅道,修复Bug', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.stable'][] = array('title'=>'完善细节,修复Bug', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.stable'][] = array('title'=>'新增动态过滤机制', 'desc' => '');
|
||||
|
||||
@@ -82,6 +82,7 @@ $lang->misc->feature = new stdclass();
|
||||
$lang->misc->feature->lastest = '最新版本';
|
||||
$lang->misc->feature->detailed = '詳情';
|
||||
|
||||
$lang->misc->releaseDate['11.6.3'] = '2019-09-24';
|
||||
$lang->misc->releaseDate['11.6.2'] = '2019-09-06';
|
||||
$lang->misc->releaseDate['11.6.1'] = '2019-08-23';
|
||||
$lang->misc->releaseDate['11.6.stable'] = '2019-07-12';
|
||||
@@ -114,16 +115,15 @@ $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.6.2'][] = array('title'=>'完善細節,修復Bug', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.6.1'][] = array('title'=>'完善細節,修復Bug', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.3'][] = array('title'=>'修復Bug', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.2'][] = array('title'=>'完善細節,修復Bug', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.1'][] = array('title'=>'完善細節,修復Bug', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.6.stable'][] = array('title'=>'改善國際版界面', 'desc' => '');
|
||||
$lang->misc->feature->all['11.6.stable'][] = array('title'=>'添加翻譯功能', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.2'][] = array('title'=>'增加禪道安全性,增加登錄禪道弱口令檢查', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.1'][] = array('title'=>'新增第三方應用免密登錄禪道,修復Bug', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.2'][] = array('title'=>'增加禪道安全性,增加登錄禪道弱口令檢查', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.1'][] = array('title'=>'新增第三方應用免密登錄禪道,修復Bug', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['11.5.stable'][] = array('title'=>'完善細節,修復Bug', 'desc' => '');
|
||||
$lang->misc->feature->all['11.5.stable'][] = array('title'=>'新增動態過濾機制', 'desc' => '');
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
.release-line > li > a:before {border-color: #00da88;}
|
||||
.release-line > li:nth-child(even) > a {padding-bottom: 38px;}
|
||||
.release-link-line {pointer-events: none; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+YAAADiCAMAAAD0xy2eAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAABOUExURUdwTOXl5eXl5ebm5ufn5+rq6u7u7unp6eXl5f///+Xl5eXl5efn5+Xl5eXl5eXl5ebm5uXl5eXl5ebm5ubm5ubm5uXl5ebm5uXl5eXl5Uh6G7kAAAAZdFJOUwDuuVQtFQwg1gXH+Dpzoq1CmIV7aEuOX+MTWsN0AAAGrUlEQVQYGe3ACbaYOHRF0SuQkETfw5v/RPNdLpMZZKWez5buVQBcu8zmJACO1WOwcAqAZ7kx66MAeNa+ZncnAI51t1kvAK7F/hEAAAAAAACA/xP93gmAZ6tZOKsAODb2ZuUSAM/aYtZEAXCsTsFs7gTAse4eigD4lqMAAAAAAMD/D09/CYBrvVl/CYBjdXrN+lUAHOumYNavAuBYNwWzTQA866ZwCYBvnQAAAAD8V7RHEgDParHhzgLg2NqYDXMUAMfiPJg1qwA4lu/BbBMAz7rjvQTAtyoAAOBG1wmAb1O4swB4NptZcwmAY3EbzN4pCYBfaSpmwywAnl2NNQLgW44CAABuZAHwLQ1lSgLg2BjMhuUSAL9q25jZu2cB8CsfxcweAfBsnYcsAL51AgAAboxL2wmAZ5vZMF9VANxKZ29mYRsFwK98FDN7swA4Fvc3VAHwLQsAALgxlSMKgGeNmZU9CoBb9dqCmb33KABu1XV7zSwJgGfjPQsAALixHlEAXJvN3u3qBMCtdXvNbGjOLABuxaO3H1EAHEvPUgQAANwYlycLgGe7mZX76gTAq3wuwcyGZsoC4FUd997MLgHwLLVbJwB/j7UTANeyDf2+dgLgVuwHMxv6fa0C4FR37b39WATAse66+0kA/h45CYBvjZX5yQLg1xLsR1imsQqATzVOy2s/kgA4lp+tEYC/R9rOsRMAx1r7UebjygLgU57mMtgvswC4VeNzN++hT0oC4FDVZ7ehLPe55ioAPu3BfhseAXCqi+2xNa9d+rTnFTsB8KLqH7Xq09iPoTTzngXApXNrSrBfRn1i7ATAlS5e5570KWbD2y/b8XQC4NJSgv2W9RljrgLgR5fH9tznqk8ws1D6ZTs6AXCp6d/B/lH1Oc52jakKgBcpj+156FPtt1B6AXCp27elKcHMgj5d6Zdtn55rzALgRcpRn2x/vPrUMaYqAP9hVZ8a1/Y87rnpG32y/Qhv38y7ALiU+xIG+6Xok5r5Ps52jbkTABe6PF5Pq89ofxR9upg7AXAiXc+0b0tT3kaf0cyGtzTLdgqAS2N5B/tHo09ctn162jGmKgAedDmu7Xnp09ofjT5dTFUAnEjtedzz0pd30+cxs/D2zXy3AuBSW4L9tumzzvdxtmvMnQC40OXxes5Vn8n+2PTpkgC4EZ9p35amvMOuz2QWSr/M9zQKgEtTsH/t+qzH2a4xVQFwoaY4Xs+0r/rs9lsopwC4tO7b0pcwmJ367KVftn16rjEJgBddTvrM9sejT46pCoATKY7tedxz06/6zGYWSr9sexQAl+4S7LdLn3Z6rpirAHiR4tieR9ansX+E0o8C4NJzz015BzMb9bmX7TjbMXcC4EaXx06fYv8aogC4NLbnvi19CZb06Usz38dzjVkA/Kj6X8H+SPpUAfAjxfWZ9rnp36pPCKWZ7+m5ogC4VAf7o+rTCYAjKa7PdM9Nr0+1UJr5ntoxC4BLebB/BQFwKsX1me6lb/RJ89HGKgB+jfZLae5zFACX0nk3xX5pBMCvGttjnvRJWQB8myw0e5sFwK0p2C+h2aMAOJXbvQlm1gqAZ/k6sgD8PfpmXzsB8KuzX8rWZgFwKrV3P9iPIgB+1fFoQi8AziV9qgA4d4bljALg2GY/3vnJAuBVfubXfryrAPgVzyVYFgDfogD8Per8JAHwbDWzfh+rAHiVpmYws7CcWQC8qtddzOwWAM/yuawCAABu9HPbCYBj2cyG5swC4FacevtR9lEA3ErPEswWAfCsrncrAADgxraPAuBZN5i921oFwK31fs0szG0nAG7FvZhZLwCe5ak/BAAA3FizAPj2WjmyAPjVzcHMyhEFwK16zcHMyiQAftVrCzYLgGt1jQIAAG7MRxYAz7KZ9VMWALfqNQcz66ckAG7VdhnM7BYAx2q7DKcA+NZ1AgAAXtSyjQLg2WVm7x4FwK94v2ZWpiwAfo1bMLNJAByr1zyMAuBbJwAA4EYsUxYAzw4za55OANyq1zKYDctVBcCt7mnMLIwC4Fg+ytAJgG9ZAADAjWuPAuBaY9afSQD8GrdgNixXFQC3atuYWbirAPiVpmJFAHyLqwAAgBtjEgDX6jssVxUAv9IymIU7CoBfaSpm1p9JAPwat2A2C4BntW1WAQAAAPiPyGVKAuDZYTYslwD4VdvGzN49C4Bf6Shm1kQBcGydhyEJgGvdJQAA4EZOAuDbMiyrAHi2mNl7ZAHwKx2vmTVXFQC/1mUw6wXAszSVQwCcqwIAAG4cSQBcW4ckAK7lU/8D/a9fSZZlwxkAAAAASUVORK5CYII=); height: 196px; position: absolute; left: 10px; right: 100px; top: 97px; background-size: 100% 100%; background-repeat: no-repeat;}
|
||||
.release-line li .title{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
|
||||
|
||||
@@ -66,7 +66,8 @@
|
||||
<i class="icon icon-flag text-primary"></i>
|
||||
<?php endif;?>
|
||||
<div class="block">
|
||||
<span class="title"><?php echo isset($roadmap->build) ? $roadmap->name : $roadmap->title;?></span>
|
||||
<?php $roadmapTitle = isset($roadmap->build) ? $roadmap->name : $roadmap->title;?>
|
||||
<span class="title" title='<?php echo $roadmapTitle;?>'><?php echo $roadmapTitle;?></span>
|
||||
<span class="date"><?php echo isset($roadmap->build) ? $roadmap->date : ($roadmap->end == '2030-01-01' ? $lang->productplan->future : $roadmap->begin . '~' . $roadmap->end);?></span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -1101,7 +1101,11 @@ class project extends control
|
||||
|
||||
$this->executeHooks($projectID);
|
||||
|
||||
$planID = reset($_POST['plans']);
|
||||
$planID = '';
|
||||
foreach($_POST['plans'] as $planID)
|
||||
{
|
||||
if(!empty($planID)) break;
|
||||
}
|
||||
if(!empty($planID))
|
||||
{
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('create', "projectID=$projectID©ProjectID=&planID=$planID&confirm=no")));
|
||||
|
||||
@@ -1566,6 +1566,8 @@ class projectModel extends model
|
||||
$lastOrder = reset($linkedStories);
|
||||
foreach($stories as $key => $storyID)
|
||||
{
|
||||
$status = $this->dao->findById($storyID)->from(TABLE_STORY)->fetch('status');
|
||||
if($status == 'draft') continue;
|
||||
if(isset($linkedStories[$storyID])) continue;
|
||||
|
||||
$productID = (int)$products[$storyID];
|
||||
@@ -1599,6 +1601,7 @@ class projectModel extends model
|
||||
{
|
||||
foreach($plans as $planID => $productID)
|
||||
{
|
||||
if(empty($planID)) continue;
|
||||
$planStory = $this->loadModel('story')->getPlanStories($planID);
|
||||
if(!empty($planStory))
|
||||
{
|
||||
@@ -1716,6 +1719,7 @@ class projectModel extends model
|
||||
->where('t1.account')->eq($account)
|
||||
->andWhere('t1.root')->ne($currentProject)
|
||||
->andWhere('t1.type')->eq('project')
|
||||
->andWhere('t2.deleted')->eq('0')
|
||||
->groupBy('t1.root')
|
||||
->orderBy('t1.root DESC')
|
||||
->fetchPairs();
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="main-col">
|
||||
<div id='queryBox' class='cell <?php if($type =='bySearch') echo 'show';?>'></div>
|
||||
<div id='queryBox' class='cell <?php if($type =='bysearch') echo 'show';?>'></div>
|
||||
<?php if(empty($stories)):?>
|
||||
<div class="table-empty-tip">
|
||||
<p>
|
||||
|
||||
@@ -339,31 +339,31 @@ $(function()
|
||||
var setDateField = function(query, fieldNO)
|
||||
{
|
||||
var $period = $('#selectPeriod');
|
||||
if(!$period.length)
|
||||
{
|
||||
$period = $("<ul id='selectPeriod' class='dropdown-menu'><li class='dropdown-header'><?php echo $lang->datepicker->dpText->TEXT_OR . ' ' . $lang->datepicker->dpText->TEXT_DATE;?></li><li><a href='#lastWeek'><?php echo $lang->datepicker->dpText->TEXT_PREV_WEEK;?></a></li><li><a href='#thisWeek'><?php echo $lang->datepicker->dpText->TEXT_THIS_WEEK;?></a></li><li><a href='#yesterday'><?php echo $lang->datepicker->dpText->TEXT_YESTERDAY;?></a></li><li><a href='#today'><?php echo $lang->datepicker->dpText->TEXT_TODAY;?></a></li><li><a href='#lastMonth'><?php echo $lang->datepicker->dpText->TEXT_PREV_MONTH;?></a></li><li><a href='#thisMonth'><?php echo $lang->datepicker->dpText->TEXT_THIS_MONTH;?></a></li></ul>").appendTo('body');
|
||||
$period.find('li > a').click(function(event)
|
||||
{
|
||||
var target = $(query).closest('form').find('#' + $period.data('target'));
|
||||
if(target.length)
|
||||
{
|
||||
if(target.next('input[type=hidden]').length)
|
||||
{
|
||||
target.next('input[type=hidden]').val($(this).attr('href').replace('#', '$'));
|
||||
target.attr('placeholder', $(this).attr('href').replace('#', '$'));
|
||||
}
|
||||
else
|
||||
{
|
||||
target.val($(this).attr('href').replace('#', '$'));
|
||||
}
|
||||
if($period.length) $period.remove();
|
||||
|
||||
$(query).closest('form').find('#operator' + $period.data('fieldNO')).val('between');
|
||||
$period.hide();
|
||||
$period = $("<ul id='selectPeriod' class='dropdown-menu'><li class='dropdown-header'><?php echo $lang->datepicker->dpText->TEXT_OR . ' ' . $lang->datepicker->dpText->TEXT_DATE;?></li><li><a href='#lastWeek'><?php echo $lang->datepicker->dpText->TEXT_PREV_WEEK;?></a></li><li><a href='#thisWeek'><?php echo $lang->datepicker->dpText->TEXT_THIS_WEEK;?></a></li><li><a href='#yesterday'><?php echo $lang->datepicker->dpText->TEXT_YESTERDAY;?></a></li><li><a href='#today'><?php echo $lang->datepicker->dpText->TEXT_TODAY;?></a></li><li><a href='#lastMonth'><?php echo $lang->datepicker->dpText->TEXT_PREV_MONTH;?></a></li><li><a href='#thisMonth'><?php echo $lang->datepicker->dpText->TEXT_THIS_MONTH;?></a></li></ul>").appendTo('body');
|
||||
$period.find('li > a').click(function(event)
|
||||
{
|
||||
var target = $(query).closest('form').find('#' + $period.data('target'));
|
||||
if(target.length)
|
||||
{
|
||||
if(target.next('input[type=hidden]').length)
|
||||
{
|
||||
target.next('input[type=hidden]').val($(this).attr('href').replace('#', '$'));
|
||||
target.attr('placeholder', $(this).attr('href').replace('#', '$'));
|
||||
}
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
target.val($(this).attr('href').replace('#', '$'));
|
||||
}
|
||||
|
||||
$(query).closest('form').find('#operator' + $period.data('fieldNO')).val('between');
|
||||
$period.hide();
|
||||
}
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
|
||||
$(query).datetimepicker('remove').datepicker(dtOptions).on('show', function(e)
|
||||
{
|
||||
var $e = $(e.target);
|
||||
@@ -412,6 +412,7 @@ $(function()
|
||||
|
||||
if(typeof(params[fieldName]['class']) != undefined && params[fieldName]['class'] == 'date')
|
||||
{
|
||||
console.log($searchForm.find("#value" + fieldNO));
|
||||
setDateField($searchForm.find("#value" + fieldNO), fieldNO);
|
||||
$searchForm.find("#value" + fieldNO).addClass('date'); // Shortcut the width of the datepicker to make sure align with others.
|
||||
var maxNO = 2 * groupItems;
|
||||
|
||||
@@ -869,7 +869,6 @@ class storyModel extends model
|
||||
->setDefault('assignedDate', $now)
|
||||
->removeIF($this->post->closedReason != 'duplicate', 'duplicateStory')
|
||||
->removeIF($this->post->closedReason != 'subdivided', 'childStories')
|
||||
->setIF($this->post->closedReason != 'done', 'plan', 0)
|
||||
->remove('comment')
|
||||
->get();
|
||||
|
||||
@@ -1709,7 +1708,8 @@ class storyModel extends model
|
||||
{
|
||||
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getProjectStories();
|
||||
|
||||
if($type == 'bySearch')
|
||||
$type = strtolower($type);
|
||||
if($type == 'bysearch')
|
||||
{
|
||||
$queryID = (int)$param;
|
||||
$products = $this->loadModel('project')->getProducts($projectID);
|
||||
|
||||
+15
-4
@@ -90,7 +90,7 @@ class task extends control
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = '';
|
||||
$response['message'] = $this->lang->saveSuccess;
|
||||
|
||||
if($this->post->project) $projectID = $this->post->project;
|
||||
$tasksID = $this->task->create($projectID);
|
||||
@@ -173,11 +173,18 @@ class task extends control
|
||||
}
|
||||
|
||||
$users = $this->loadModel('user')->getPairs('noclosed|nodeleted');
|
||||
$moduleIdList = $this->tree->getAllChildID($moduleID);
|
||||
$stories = $this->story->getProjectStoryPairs($projectID, 0, 0, $moduleIdList);
|
||||
$members = $this->project->getTeamMemberPairs($projectID, 'nodeleted');
|
||||
$moduleOptionMenu = $this->tree->getTaskOptionMenu($projectID);
|
||||
|
||||
/* Fix bug #2737. When moduleID is not story module. */
|
||||
$moduleIdList = array();
|
||||
if($moduleID)
|
||||
{
|
||||
$moduleID = $this->tree->getStoryModule($moduleID);
|
||||
$moduleIdList = $this->tree->getAllChildID($moduleID);
|
||||
}
|
||||
$stories = $this->story->getProjectStoryPairs($projectID, 0, 0, $moduleIdList);
|
||||
|
||||
$title = $project->name . $this->lang->colon . $this->lang->task->create;
|
||||
$position[] = html::a($taskLink, $project->name);
|
||||
$position[] = $this->lang->task->common;
|
||||
@@ -1168,7 +1175,11 @@ class task extends control
|
||||
else
|
||||
{
|
||||
$this->task->delete(TABLE_TASK, $taskID);
|
||||
if($task->parent > 0) $this->task->updateParentStatus($task->id);
|
||||
if($task->parent > 0)
|
||||
{
|
||||
$this->task->updateParentStatus($task->id);
|
||||
$this->loadModel('action')->create('task', $task->parent, 'deleteChildrenTask', '', $taskID);
|
||||
}
|
||||
if($task->fromBug != 0) $this->dao->update(TABLE_BUG)->set('toTask')->eq(0)->where('id')->eq($task->fromBug)->exec();
|
||||
if($task->story) $this->loadModel('story')->setStage($task->story);
|
||||
|
||||
|
||||
@@ -199,6 +199,7 @@ $lang->task->cannotDeleteParent = 'Cannot delete parent task';
|
||||
$lang->task->error = new stdclass();
|
||||
$lang->task->error->consumedNumber = '"Current Cost" must be numbers.';
|
||||
$lang->task->error->estimateNumber = '"Estimates" must be numbers.';
|
||||
$lang->task->error->recordMinus = 'Work hours should not be negative number.';
|
||||
$lang->task->error->consumedSmall = '"Hours Cost" must be > the last number.';
|
||||
$lang->task->error->consumedThisTime = 'Please enter "Hours Cost"';
|
||||
$lang->task->error->left = 'Please enter "Hours Left"';
|
||||
@@ -207,6 +208,7 @@ $lang->task->error->skipClose = 'Task: %s is not "Finished” or “Cance
|
||||
$lang->task->error->consumed = 'Task: %s hour must be < 0. Ignore changes to this task.';
|
||||
$lang->task->error->assignedTo = 'Multi-user task in the current status cannot be assigned to a member who is not in the task team.';
|
||||
$lang->task->error->consumedEmpty = '"Current Cost" should not be empty.';
|
||||
$lang->task->error->deadlineSmall = '"Deadline" must be greater than "StartDate".';
|
||||
|
||||
/* Report. */
|
||||
$lang->task->report = new stdclass();
|
||||
|
||||
@@ -199,6 +199,7 @@ $lang->task->cannotDeleteParent = '不能删除父任务。';
|
||||
$lang->task->error = new stdclass();
|
||||
$lang->task->error->consumedNumber = '"本次消耗"必须为数字';
|
||||
$lang->task->error->estimateNumber = '"预计剩余"必须为数字';
|
||||
$lang->task->error->recordMinus = '工时不能为负数';
|
||||
$lang->task->error->consumedSmall = '"已经消耗"必须大于之前消耗';
|
||||
$lang->task->error->consumedThisTime = '请填写"工时"';
|
||||
$lang->task->error->left = '请填写"剩余"';
|
||||
@@ -207,6 +208,7 @@ $lang->task->error->skipClose = '任务:%s 不是“已完成”或“
|
||||
$lang->task->error->consumed = '任务:%s工时不能小于0,忽略该任务工时的改动';
|
||||
$lang->task->error->assignedTo = '当前状态的多人任务不能指派给任务团队外的成员。';
|
||||
$lang->task->error->consumedEmpty = '"本次消耗"不能为空';
|
||||
$lang->task->error->deadlineSmall = '"截止日期"必须大于"预计开始"';
|
||||
|
||||
/* Report. */
|
||||
$lang->task->report = new stdclass();
|
||||
|
||||
+30
-7
@@ -22,6 +22,11 @@ class taskModel extends model
|
||||
*/
|
||||
public function create($projectID)
|
||||
{
|
||||
if($this->post->estimate < 0)
|
||||
{
|
||||
dao::$errors[] = $this->lang->task->error->recordMinus;
|
||||
return false;
|
||||
}
|
||||
$taskIdList = array();
|
||||
$taskFiles = array();
|
||||
$this->loadModel('file');
|
||||
@@ -272,6 +277,12 @@ class taskModel extends model
|
||||
/* check data. */
|
||||
foreach($data as $i => $task)
|
||||
{
|
||||
|
||||
if($task->deadline != '0000-00-00' and $task->deadline <= $task->estStarted)
|
||||
{
|
||||
dao::$errors['message'][] = $this->lang->task->error->deadlineSmall;
|
||||
return false;
|
||||
}
|
||||
if($task->estimate and !preg_match("/^[0-9]+(.[0-9]{1,3})?$/", $task->estimate))
|
||||
{
|
||||
dao::$errors['message'][] = $this->lang->task->error->estimateNumber;
|
||||
@@ -413,6 +424,7 @@ class taskModel extends model
|
||||
if($parentID <= 0) return true;
|
||||
|
||||
$oldParentTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($parentID)->fetch();
|
||||
if($oldParentTask->parent != '-1') $this->dao->update(TABLE_TASK)->set('parent')->eq('-1')->where('id')->eq($parentID)->exec();
|
||||
$this->computeWorkingHours($parentID);
|
||||
|
||||
$childrenStatus = $this->dao->select('id,status')->from(TABLE_TASK)->where('parent')->eq($parentID)->andWhere('deleted')->eq(0)->fetchPairs('status', 'status');
|
||||
@@ -547,10 +559,11 @@ class taskModel extends model
|
||||
*
|
||||
* @param object $oldTask
|
||||
* @param object $task
|
||||
* @param bool $autoStatus
|
||||
* @access public
|
||||
* @return object|bool
|
||||
*/
|
||||
public function computeHours4Multiple($oldTask, $task = null, $team = array())
|
||||
public function computeHours4Multiple($oldTask, $task = null, $team = array(), $autoStatus = true)
|
||||
{
|
||||
if(!$oldTask) return false;
|
||||
|
||||
@@ -603,7 +616,7 @@ class taskModel extends model
|
||||
|
||||
if(!empty($task))
|
||||
{
|
||||
if($this->post->status) return $currentTask;
|
||||
if(!$autoStatus) return $currentTask;
|
||||
|
||||
if($currentTask->consumed == 0)
|
||||
{
|
||||
@@ -662,6 +675,11 @@ class taskModel extends model
|
||||
public function update($taskID)
|
||||
{
|
||||
$oldTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq((int)$taskID)->fetch();
|
||||
if($this->post->estimate < 0 or $this->post->left < 0 or $this->post->consumed < 0)
|
||||
{
|
||||
dao::$errors[] = $this->lang->task->error->recordMinus;
|
||||
return false;
|
||||
}
|
||||
if(!empty($_POST['lastEditedDate']) and $oldTask->lastEditedDate != $this->post->lastEditedDate)
|
||||
{
|
||||
dao::$errors[] = $this->lang->error->editedByOther;
|
||||
@@ -749,7 +767,7 @@ class taskModel extends model
|
||||
if(!empty($teams))
|
||||
{
|
||||
foreach($teams as $member) $this->dao->insert(TABLE_TEAM)->data($member)->autoCheck()->exec();
|
||||
$task = $this->computeHours4Multiple($oldTask, $task);
|
||||
$task = $this->computeHours4Multiple($oldTask, $task, array(), $autoStatus = false);
|
||||
if($task->status == 'wait')
|
||||
{
|
||||
reset($teams);
|
||||
@@ -1472,6 +1490,7 @@ class taskModel extends model
|
||||
|
||||
$this->dao->update(TABLE_TASK)->data($task)->autoCheck()->where('id')->eq((int)$taskID)->exec();
|
||||
if($oldTask->parent > 0) $this->updateParentStatus($taskID);
|
||||
if($oldTask->parent == '-1') $this->dao->update(TABLE_TASK)->data($task)->autoCheck()->where('parent')->eq((int)$taskID)->exec();
|
||||
if($oldTask->story) $this->loadModel('story')->setStage($oldTask->story);
|
||||
if(!dao::isError()) return common::createChanges($oldTask, $task);
|
||||
}
|
||||
@@ -1493,6 +1512,7 @@ class taskModel extends model
|
||||
}
|
||||
|
||||
$oldTask = $this->getById($taskID);
|
||||
if($oldTask->parent == '-1') $this->config->task->activate->requiredFields = '';
|
||||
$task = fixer::input('post')
|
||||
->setIF(is_numeric($this->post->left), 'left', (float)$this->post->left)
|
||||
->setDefault('left', 0)
|
||||
@@ -1529,6 +1549,12 @@ class taskModel extends model
|
||||
->exec();
|
||||
|
||||
if($oldTask->parent > 0) $this->updateParentStatus($taskID);
|
||||
if($oldTask->parent == '-1')
|
||||
{
|
||||
unset($task->left);
|
||||
$this->dao->update(TABLE_TASK)->data($task)->autoCheck()->where('parent')->eq((int)$taskID)->exec();
|
||||
$this->computeWorkingHours($taskID);
|
||||
}
|
||||
if($oldTask->story) $this->loadModel('story')->setStage($oldTask->story);
|
||||
if(!dao::isError()) return common::createChanges($oldTask, $task);
|
||||
}
|
||||
@@ -1647,7 +1673,6 @@ class taskModel extends model
|
||||
->leftJoin(TABLE_TEAM)->alias('t4')->on('t4.root = t1.id')
|
||||
->leftJoin(TABLE_MODULE)->alias('t5')->on('t1.module = t5.id')
|
||||
->where('t1.project')->eq((int)$projectID)
|
||||
->beginIF(($type == 'all' || is_array($type)) && $modules == 0)->andWhere('t1.parent')->lt(1)->fi()
|
||||
->beginIF($type == 'myinvolved')
|
||||
->andWhere("((t4.`account` = '{$this->app->user->account}' AND t4.`type` = 'task') OR t1.`assignedTo` = '{$this->app->user->account}' OR t1.`finishedby` = '{$this->app->user->account}')")
|
||||
->fi()
|
||||
@@ -2542,9 +2567,7 @@ class taskModel extends model
|
||||
|
||||
if($action == 'start' and !empty($task->children)) return false;
|
||||
if($action == 'finish' and !empty($task->children)) return false;
|
||||
if($action == 'cancel' and !empty($task->children)) return false;
|
||||
if($action == 'pause' and !empty($task->children)) return false;
|
||||
if($action == 'activate' and !empty($task->children)) return false;
|
||||
if($action == 'assignto' and !empty($task->children)) return false;
|
||||
if($action == 'close' and !empty($task->children)) return false;
|
||||
if($action == 'batchcreate' and !empty($task->team)) return false;
|
||||
@@ -2760,7 +2783,7 @@ class taskModel extends model
|
||||
case 'actions':
|
||||
if($storyChanged)
|
||||
{
|
||||
common::printIcon('task', 'confirmStoryChange', "taskid=$task->id", '', 'list', '', 'hiddenwin', 'btn-wide');
|
||||
common::printIcon('task', 'confirmStoryChange', "taskid=$task->id", '', 'list', '', 'hiddenwin');
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<td class='w-p25-f'><?php echo html::select('assignedTo', $members, $task->finishedBy, "class='form-control chosen'");?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<?php if($task->parent != '-1'):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->task->left;?></th>
|
||||
<td>
|
||||
@@ -40,6 +41,7 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr class='hide'>
|
||||
<th><?php echo $lang->task->status;?></th>
|
||||
<td><?php echo html::hidden('status', 'doing');?></td>
|
||||
|
||||
@@ -217,7 +217,7 @@ class testcase extends control
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = '';
|
||||
$response['message'] = $this->lang->saveSuccess;
|
||||
|
||||
$caseResult = $this->testcase->create($bugID);
|
||||
if(!$caseResult or dao::isError())
|
||||
@@ -320,6 +320,7 @@ class testcase extends control
|
||||
|
||||
/* Get the status of stories are not closed. */
|
||||
$storyStatus = $this->lang->story->statusList;
|
||||
unset($storyStatus['closed']);
|
||||
$modules = array();
|
||||
if($currentModuleID)
|
||||
{
|
||||
@@ -482,7 +483,15 @@ class testcase extends control
|
||||
{
|
||||
$case = $this->testcase->getById($caseID, $version);
|
||||
if(!$case) die(js::error($this->lang->notFound) . js::locate('back'));
|
||||
if($from == 'testtask') $run = $this->loadModel('testtask')->getRunByCase($taskID, $caseID);
|
||||
if($from == 'testtask')
|
||||
{
|
||||
$run = $this->loadModel('testtask')->getRunByCase($taskID, $caseID);
|
||||
$case->assignedTo = $run->assignedTo;
|
||||
$case->lastRunner = $run->lastRunner;
|
||||
$case->lastRunDate = $run->lastRunDate;
|
||||
$case->lastRunResult = $run->lastRunResult;
|
||||
$case->status = $run->status;
|
||||
}
|
||||
|
||||
$branches = $this->session->currentProductType == 'normal' ? array() : $this->loadModel('branch')->getPairs($case->product);
|
||||
$isLibCase = ($case->lib and empty($case->product));
|
||||
@@ -1077,6 +1086,7 @@ class testcase extends control
|
||||
if($product->type != 'normal') $this->lang->testcase->branch = $this->lang->product->branchName[$product->type];
|
||||
if($_POST)
|
||||
{
|
||||
$this->app->loadLang('testtask');
|
||||
$caseLang = $this->lang->testcase;
|
||||
$caseConfig = $this->config->testcase;
|
||||
|
||||
@@ -1122,6 +1132,7 @@ class testcase extends control
|
||||
$row->id = $caseID;
|
||||
}
|
||||
}
|
||||
if($taskID) $caseLang->statusList = $this->lang->testtask->statusList;
|
||||
|
||||
$stmt = $this->dao->select('t1.*')->from(TABLE_TESTRESULT)->alias('t1')
|
||||
->leftJoin(TABLE_TESTRUN)->alias('t2')->on('t1.run=t2.id')
|
||||
@@ -1173,7 +1184,7 @@ class testcase extends control
|
||||
$case->stepExpect = '';
|
||||
$case->real = '';
|
||||
$result = isset($results[$case->id]) ? $results[$case->id] : array();
|
||||
$case->real = $result[0]['real'];
|
||||
$case->real = empty($result) ? '' : $result[0]['real'];
|
||||
if(isset($relatedSteps[$case->id]))
|
||||
{
|
||||
$i = $childId = 0;
|
||||
@@ -1681,8 +1692,9 @@ class testcase extends control
|
||||
*/
|
||||
public function ajaxGetStatus($methodName, $caseID = 0)
|
||||
{
|
||||
$status = $this->testcase->getStatus($methodName, $caseID);
|
||||
|
||||
$case = $this->testcase->getByID($caseID);
|
||||
$status = $this->testcase->getStatus($methodName, $case);
|
||||
if($methodName == 'update') $status = zget($status, 1, '');
|
||||
die($status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ $(document).ready(function()
|
||||
{
|
||||
var index = id.substring(5);
|
||||
var moduleID = $('#module' + index).val();
|
||||
var branch = $('#branch' + index).val();
|
||||
var branch = $('#branch' + index).length > 0 ? $('#branch' + index).val() : 0;
|
||||
if(moduleID == 'ditto')
|
||||
{
|
||||
for(var i = index - 1; i >=0; i--)
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
$(document).on('change', '.moduleChange', function()
|
||||
$(document).on('mouseup', '[id^=story].chosen-with-drop', function()
|
||||
{
|
||||
var moduleID = $(this).val();
|
||||
if(typeof(moduleID) == 'undefined') moduleID = 0;
|
||||
var id = $(this).attr('id');
|
||||
var index = id.substring(6);
|
||||
link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID + '&branch=' + branch + '&moduleID=' + moduleID + '&storyID='+ '' + '&onlyOption=true&status=noclosed');
|
||||
$('#story' + index).load(link, function(){$(this).trigger("chosen:updated");});
|
||||
})
|
||||
|
||||
$(document).on('change', '.storyChange', function()
|
||||
{
|
||||
var storyID = $(this).val();
|
||||
if(typeof(storyID) == 'undefined') storyID = 0;
|
||||
var link = createLink('testcase', 'ajaxGetStoryModule', 'storyID=' + storyID);
|
||||
var id = $(this).attr('id');
|
||||
var index = id.substring(5);
|
||||
$.get(link, function(json)
|
||||
{
|
||||
var obj = JSON.parse(json);
|
||||
$("#module" + index).val(obj.moduleID);
|
||||
$('#module' + index).trigger("chosen:updated");
|
||||
})
|
||||
})
|
||||
var select = $(this).prev('select');
|
||||
var id = $(select).attr('id');
|
||||
var index = id.substring(5);
|
||||
var moduleID = $('#module' + index).val();
|
||||
var branch = $('#branch' + index).length > 0 ? $('#branch' + index).val() : 0;
|
||||
if(moduleID == 'ditto')
|
||||
{
|
||||
for(var i = index - 1; i >=0; i--)
|
||||
{
|
||||
if($('#module' + i).val() != 'ditto')
|
||||
{
|
||||
moduleID = $('#module' + i).val();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID + '&branch=' + branch + '&moduleID=' + moduleID + '&storyID='+ ($(select).val() || '0') + '&onlyOption=true&status=noclosed&limit=0&type=null');
|
||||
var $story = $('#story' + index);
|
||||
if($story.data('loadLink') !== link)
|
||||
{
|
||||
$story.load(link, function(){$story.data('loadLink', link).trigger("chosen:updated");});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1103,8 +1103,8 @@ class testcaseModel extends model
|
||||
if(empty($desc)) continue;
|
||||
$step = new stdclass();
|
||||
$step->type = $data->stepType[$key][$id];
|
||||
$step->desc = $desc;
|
||||
$step->expect = trim($this->post->expect[$key][$id]);
|
||||
$step->desc = htmlspecialchars($desc);
|
||||
$step->expect = htmlspecialchars(trim($this->post->expect[$key][$id]));
|
||||
|
||||
$steps[] = $step;
|
||||
}
|
||||
@@ -1152,7 +1152,7 @@ class testcaseModel extends model
|
||||
$stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0;
|
||||
$stepData->case = $caseID;
|
||||
$stepData->version = $version;
|
||||
$stepData->desc = $step['desc'];
|
||||
$stepData->desc = htmlspecialchars($step['desc']);
|
||||
$stepData->expect = htmlspecialchars($step['expect']);
|
||||
$this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec();
|
||||
if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID();
|
||||
@@ -1189,7 +1189,7 @@ class testcaseModel extends model
|
||||
$stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0;
|
||||
$stepData->case = $caseID;
|
||||
$stepData->version = 1;
|
||||
$stepData->desc = $desc;
|
||||
$stepData->desc = htmlspecialchars($desc);
|
||||
$stepData->expect = htmlspecialchars($this->post->expect[$key][$id]);
|
||||
$this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec();
|
||||
if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID();
|
||||
@@ -1592,7 +1592,7 @@ class testcaseModel extends model
|
||||
return false;
|
||||
}
|
||||
|
||||
$status = $this->post->status;
|
||||
$status = $this->post->status ? $this->post->status : $case->status;
|
||||
$stepChanged = false;
|
||||
$steps = array();
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ js::set('suiteID', $suiteID);
|
||||
|
||||
$actionLink = $this->createLink('testcase', 'batchDelete', "productID=$productID");
|
||||
$misc = common::hasPriv('testcase', 'batchDelete') ? "onclick=\"confirmBatchDelete('$actionLink')\"" : $class;
|
||||
echo "<li>" . html::a('#', $lang->delete, '', $misc) . "</li>";
|
||||
if(common::hasPriv('testcase', 'batchDelete')) echo "<li>" . html::a('#', $lang->delete, '', $misc) . "</li>";
|
||||
|
||||
if(common::hasPriv('testcase', 'batchCaseTypeChange'))
|
||||
{
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='w-50px'><?php echo $lang->testcase->stepID;?></th>
|
||||
<th class='w-p70 text-left'><?php echo $lang->testcase->stepDesc;?></th>
|
||||
<th class='w-p60 text-left'><?php echo $lang->testcase->stepDesc;?></th>
|
||||
<th class='text-left'><?php echo $lang->testcase->stepExpect;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -85,7 +85,7 @@
|
||||
echo "<th class='step-id'>$stepId</th>";
|
||||
echo "<td class='text-left'><div class='input-group'>";
|
||||
if($step->type == 'item') echo "<span class='step-item-id'>{$stepId}.{$childId}</span>";
|
||||
echo nl2br(str_replace(' ', ' ', htmlspecialchars($step->desc))) . "</td>";
|
||||
echo nl2br(str_replace(' ', ' ', $step->desc)) . "</td>";
|
||||
echo "<td class='text-left'>" . nl2br(str_replace(' ', ' ', $step->expect)) . "</div></td>";
|
||||
echo "</tr>";
|
||||
$childId ++;
|
||||
|
||||
@@ -2,17 +2,12 @@
|
||||
$config->testsuite = new stdclass();
|
||||
$config->testsuite->create = new stdclass();
|
||||
$config->testsuite->edit = new stdclass();
|
||||
$config->testsuite->createlib = new stdclass();
|
||||
$config->testsuite->createcase = new stdclass();
|
||||
$config->testsuite->create->requiredFields = 'name';
|
||||
$config->testsuite->edit->requiredFields = 'name';
|
||||
$config->testsuite->createlib->requiredFields = 'name';
|
||||
$config->testsuite->createcase->requiredFields = 'title,type';
|
||||
$config->testsuite->create->requiredFields = 'name';
|
||||
$config->testsuite->edit->requiredFields = 'name';
|
||||
|
||||
$config->testsuite->editor = new stdclass();
|
||||
$config->testsuite->editor->create = array('id' => 'desc', 'tools' => 'simpleTools');
|
||||
$config->testsuite->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools');
|
||||
$config->testsuite->editor->createlib = array('id' => 'desc', 'tools' => 'simpleTools');
|
||||
|
||||
$config->testsuite->datatable = new stdclass();
|
||||
$config->testsuite->datatable->defaultField = array('id', 'pri', 'title', 'type', 'assignedTo', 'lastRunner', 'lastRunDate', 'lastRunResult', 'status', 'bugs', 'results', 'actions');
|
||||
|
||||
+14
-665
@@ -79,7 +79,7 @@ class testsuite extends control
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = '';
|
||||
$response['message'] = $this->lang->testsuite->successSaved;
|
||||
$suiteID = $this->testsuite->create($productID);
|
||||
if(dao::isError())
|
||||
{
|
||||
@@ -92,7 +92,6 @@ class testsuite extends control
|
||||
$this->executeHooks($suiteID);
|
||||
|
||||
$response['locate'] = $this->createLink('testsuite', 'browse', "productID=$productID");
|
||||
$response['message'] = $this->lang->testsuite->successSaved;
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
@@ -176,7 +175,7 @@ class testsuite extends control
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = '';
|
||||
$response['message'] = $this->lang->testsuite->successSaved;
|
||||
$changes = $this->testsuite->update($suiteID);
|
||||
if(dao::isError())
|
||||
{
|
||||
@@ -186,47 +185,28 @@ class testsuite extends control
|
||||
}
|
||||
if($changes)
|
||||
{
|
||||
$objectType = $suite->type == 'library' ? 'caselib' : 'testsuite';
|
||||
$actionID = $this->loadModel('action')->create($objectType, $suiteID, 'edited');
|
||||
$actionID = $this->loadModel('action')->create('testsuite', $suiteID, 'edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
$this->executeHooks($suiteID);
|
||||
|
||||
$method = $suite->type == 'library' ? 'libView' : 'view';
|
||||
$response['locate'] = inlink($method, "suiteID=$suiteID");
|
||||
$response['message'] = $this->lang->testsuite->successSaved;
|
||||
$response['locate'] = inlink('view', "suiteID=$suiteID");
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
if($suite->type == 'library')
|
||||
{
|
||||
/* Set lib menu. */
|
||||
if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib';
|
||||
$libraries = $this->testsuite->getLibraries();
|
||||
$suiteID = $this->testsuite->saveLibState($suiteID, $libraries);
|
||||
$this->testsuite->setLibMenu($libraries, $suiteID);
|
||||
if($suite->type == 'private' and $suite->addedBy != $this->app->user->account and !$this->app->user->admin) die(js::error($this->lang->error->accessDenied) . js::locate('back'));
|
||||
|
||||
$this->view->title = $libraries[$suiteID] . $this->lang->colon . $this->lang->testsuite->edit;
|
||||
$this->view->position[] = html::a($this->createLink('testsuite', 'library', "libID=$suiteID"), $libraries[$suiteID]);
|
||||
$this->view->position[] = $this->lang->caselib->common;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($suite->type == 'private' and $suite->addedBy != $this->app->user->account and !$this->app->user->admin) die(js::error($this->lang->error->accessDenied) . js::locate('back'));
|
||||
/* Get suite info. */
|
||||
$this->view->products = $this->products = $this->loadModel('product')->getPairs('nocode');
|
||||
$productID = $this->product->saveState($suite->product, $this->products);
|
||||
|
||||
/* Get suite info. */
|
||||
$this->view->products = $this->products = $this->loadModel('product')->getPairs('nocode');
|
||||
$productID = $this->product->saveState($suite->product, $this->products);
|
||||
|
||||
/* Set menu. */
|
||||
$this->testsuite->setMenu($this->products, $productID);
|
||||
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testsuite->edit;
|
||||
$this->view->position[] = html::a($this->createLink('testsuite', 'browse', "productID=$productID"), $this->products[$productID]);
|
||||
$this->view->position[] = $this->lang->testsuite->common;
|
||||
}
|
||||
/* Set menu. */
|
||||
$this->testsuite->setMenu($this->products, $productID);
|
||||
|
||||
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testsuite->edit;
|
||||
$this->view->position[] = html::a($this->createLink('testsuite', 'browse', "productID=$productID"), $this->products[$productID]);
|
||||
$this->view->position[] = $this->lang->testsuite->common;
|
||||
$this->view->position[] = $this->lang->testsuite->edit;
|
||||
|
||||
$this->view->suite = $suite;
|
||||
@@ -245,7 +225,7 @@ class testsuite extends control
|
||||
{
|
||||
if($confirm == 'no')
|
||||
{
|
||||
die(js::confirm($this->lang->testsuite->libraryDelete, inlink('delete', "suiteID=$suiteID&confirm=yes")));
|
||||
die(js::confirm($this->lang->testsuite->confirmDelete, inlink('delete', "suiteID=$suiteID&confirm=yes")));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -384,635 +364,4 @@ class testsuite extends control
|
||||
|
||||
die(js::locate($this->createLink('testsuite', 'view', "suiteID=$suiteID")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show library case.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param string $browseType
|
||||
* @param int $param
|
||||
* @param string $orderBy
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function library($libID = 0, $browseType = 'all', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
|
||||
{
|
||||
/* Set browse type. */
|
||||
$browseType = strtolower($browseType);
|
||||
|
||||
$libraries = $this->testsuite->getLibraries();
|
||||
if(empty($libraries)) $this->locate(inlink('createLib'));
|
||||
|
||||
/* Save session. */
|
||||
$this->session->set('caseList', $this->app->getURI(true));
|
||||
|
||||
/* Set menu. */
|
||||
$libID = $this->testsuite->saveLibState($libID, $libraries);
|
||||
setcookie('preCaseLibID', $libID, $this->config->cookieLife, $this->config->webRoot);
|
||||
if($this->cookie->preCaseLibID != $libID)
|
||||
{
|
||||
$_COOKIE['libCaseModule'] = 0;
|
||||
setcookie('libCaseModule', 0, 0, $this->config->webRoot);
|
||||
}
|
||||
|
||||
if($browseType == 'bymodule') setcookie('libCaseModule', (int)$param, 0, $this->config->webRoot);
|
||||
if($browseType != 'bymodule') $this->session->set('libBrowseType', $browseType);
|
||||
$moduleID = ($browseType == 'bymodule') ? (int)$param : ($browseType == 'bysearch' ? 0 : ($this->cookie->libCaseModule ? $this->cookie->libCaseModule : 0));
|
||||
$queryID = ($browseType == 'bysearch') ? (int)$param : 0;
|
||||
|
||||
/* Set lib menu. */
|
||||
$this->testsuite->setLibMenu($libraries, $libID, $moduleID);
|
||||
if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib';
|
||||
|
||||
/* Load pager. */
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = pager::init($recTotal, $recPerPage, $pageID);
|
||||
|
||||
/* Build the search form. */
|
||||
$this->loadModel('testcase');
|
||||
$actionURL = $this->createLink('testsuite', 'library', "libID=$libID&browseType=bySearch&queryID=myQueryID");
|
||||
$this->testsuite->buildSearchForm($libID, $libraries, $queryID, $actionURL);
|
||||
|
||||
/* Append id for secend sort. */
|
||||
$sort = $this->loadModel('common')->appendOrder($orderBy);
|
||||
|
||||
/* save session .*/
|
||||
$cases = $this->testsuite->getLibCases($libID, $browseType, $queryID, $moduleID, $sort, $pager);
|
||||
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', true);
|
||||
|
||||
$this->loadModel('datatable');
|
||||
$this->loadModel('tree');
|
||||
$showModule = !empty($this->config->datatable->testsuiteLibrary->showModule) ? $this->config->datatable->testsuiteLibrary->showModule : '';
|
||||
$this->view->modulePairs = $showModule ? $this->tree->getModulePairs($libID, 'caselib', $showModule) : array();
|
||||
|
||||
$this->view->title = $this->lang->caselib->common . $this->lang->colon . $libraries[$libID];
|
||||
$this->view->position[] = html::a($this->createLink('testsuite', 'library', "libID=$libID"), $libraries[$libID]);
|
||||
|
||||
$this->view->libID = $libID;
|
||||
$this->view->libName = $libraries[$libID];
|
||||
$this->view->cases = $cases;
|
||||
$this->view->orderBy = $orderBy;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter');
|
||||
$this->view->modules = $this->tree->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0);
|
||||
$this->view->moduleTree = $this->tree->getTreeMenu($libID, $viewType = 'caselib', $startModuleID = 0, array('treeModel', 'createCaseLibLink'));
|
||||
$this->view->pager = $pager;
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->moduleID = $moduleID;
|
||||
$this->view->moduleName = $moduleID ? $this->tree->getById($moduleID)->name : $this->lang->tree->all;
|
||||
$this->view->param = $param;
|
||||
$this->view->setShowModule = true;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create lib
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createLib()
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
$response['message'] = '';
|
||||
$libID = $this->testsuite->createLib();
|
||||
if(dao::isError())
|
||||
{
|
||||
$response['result'] = 'fail';
|
||||
$response['message'] = dao::getError();
|
||||
$this->send($response);
|
||||
}
|
||||
$this->loadModel('action')->create('caselib', $libID, 'opened');
|
||||
$response['locate'] = $this->createLink('testsuite', 'library', "libID=$libID");
|
||||
$response['message'] = $this->lang->testsuite->successSaved;
|
||||
$this->send($response);
|
||||
}
|
||||
|
||||
/* Set menu. */
|
||||
$libraries = $this->testsuite->getLibraries();
|
||||
$libID = $this->testsuite->saveLibState(0, $libraries);
|
||||
$this->testsuite->setLibMenu($libraries, $libID);
|
||||
if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib';
|
||||
|
||||
$this->view->title = $this->lang->caselib->common . $this->lang->colon . $this->lang->testsuite->createLib;
|
||||
$this->view->position[] = $this->lang->caselib->common;
|
||||
$this->view->position[] = $this->lang->testsuite->createLib;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create case for library.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param int $moduleID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createCase($libID, $moduleID = 0, $param = 0)
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
$this->config->testcase->create->requiredFields = $this->config->testsuite->createcase->requiredFields;
|
||||
$caseResult = $this->testcase->create($bugID = 0);
|
||||
if(!$caseResult or dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
$caseID = $caseResult['id'];
|
||||
if($caseResult['status'] == 'exists')
|
||||
{
|
||||
echo js::alert(sprintf($this->lang->duplicate, $this->lang->testcase->common));
|
||||
die(js::locate($this->createLink('testcase', 'view', "caseID=$caseID"), 'parent'));
|
||||
}
|
||||
|
||||
$this->loadModel('action')->create('case', $caseID, 'Opened');
|
||||
|
||||
/* If link from no head then reload. */
|
||||
if(isonlybody()) die(js::reload('parent'));
|
||||
die(js::locate($this->createLink('testsuite', 'library', "libID={$libID}&browseType=byModule¶m={$_POST['module']}"), 'parent'));
|
||||
}
|
||||
/* Set lib menu. */
|
||||
$libraries = $this->testsuite->getLibraries();
|
||||
$libID = $this->testsuite->saveLibState($libID, $libraries);
|
||||
$this->testsuite->setLibMenu($libraries, $libID);
|
||||
if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib';
|
||||
|
||||
$type = 'feature';
|
||||
$stage = '';
|
||||
$pri = 3;
|
||||
$caseTitle = '';
|
||||
$precondition = '';
|
||||
$keywords = '';
|
||||
$steps = array();
|
||||
|
||||
$this->loadModel('testcase');
|
||||
if($param)
|
||||
{
|
||||
$testcase = $this->testcase->getById((int)$param);
|
||||
$type = $testcase->type ? $testcase->type : 'feature';
|
||||
$stage = $testcase->stage;
|
||||
$pri = $testcase->pri;
|
||||
$storyID = $testcase->story;
|
||||
$caseTitle = $testcase->title;
|
||||
$precondition = $testcase->precondition;
|
||||
$keywords = $testcase->keywords;
|
||||
$steps = $testcase->steps;
|
||||
}
|
||||
|
||||
if(count($steps) < $this->config->testcase->defaultSteps)
|
||||
{
|
||||
$paddingCount = $this->config->testcase->defaultSteps - count($steps);
|
||||
$step = new stdclass();
|
||||
$step->type = 'item';
|
||||
$step->desc = '';
|
||||
$step->expect = '';
|
||||
for($i = 1; $i <= $paddingCount; $i ++) $steps[] = $step;
|
||||
}
|
||||
|
||||
$this->view->title = $libraries[$libID] . $this->lang->colon . $this->lang->testcase->create;
|
||||
$this->view->position[] = html::a($this->createLink('testsuite', 'library', "libID=$libID"), $libraries[$libID]);
|
||||
$this->view->position[] = $this->lang->testsuite->common;
|
||||
$this->view->position[] = $this->lang->testcase->create;
|
||||
|
||||
foreach(explode(',', $this->config->testsuite->customCreateFields) as $field) $customFields[$field] = $this->lang->testcase->$field;
|
||||
$this->view->showFields = $this->config->testsuite->custom->createFields;
|
||||
$this->view->customFields = $customFields;
|
||||
$this->view->libraries = $libraries;
|
||||
$this->view->libID = $libID;
|
||||
$this->view->currentModuleID = (int)$moduleID;
|
||||
$this->view->caseTitle = $caseTitle;
|
||||
$this->view->type = $type;
|
||||
$this->view->stage = $stage;
|
||||
$this->view->pri = $pri;
|
||||
$this->view->precondition = $precondition;
|
||||
$this->view->keywords = $keywords;
|
||||
$this->view->steps = $steps;
|
||||
$this->view->moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch create case.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param int $moduleID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function batchCreateCase($libID, $moduleID = 0)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$caseID = $this->testsuite->batchCreateCase($libID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
if(isonlybody()) die(js::closeModal('parent.parent', 'this'));
|
||||
die(js::locate($this->createLink('testsuite', 'library', "libID=$libID&browseType=byModule¶m=$moduleID"), 'parent'));
|
||||
}
|
||||
|
||||
$libraries = $this->testsuite->getLibraries();
|
||||
if(empty($libraries)) $this->locate(inlink('createLib'));
|
||||
|
||||
/* Set lib menu. */
|
||||
$this->testsuite->setLibMenu($libraries, $libID);
|
||||
if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib';
|
||||
|
||||
$currentModuleID = (int)$moduleID;
|
||||
|
||||
/* Set module option menu. */
|
||||
$moduleOptionMenu = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0);
|
||||
$moduleOptionMenu['ditto'] = $this->lang->testcase->ditto;
|
||||
|
||||
$this->view->title = $libraries[$libID] . $this->lang->colon . $this->lang->testcase->batchCreate;
|
||||
$this->view->position[] = html::a($this->createLink('testsuite', 'library', "libID=$libID"), $libraries[$libID]);
|
||||
$this->view->position[] = $this->lang->testcase->batchCreate;
|
||||
$this->view->libID = $libID;
|
||||
$this->view->moduleOptionMenu = $moduleOptionMenu;
|
||||
$this->view->currentModuleID = $currentModuleID;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* View library
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function libView($libID)
|
||||
{
|
||||
$lib = $this->testsuite->getById($libID, true);
|
||||
|
||||
/* Set lib menu. */
|
||||
$libraries = $this->testsuite->getLibraries();
|
||||
$this->testsuite->setLibMenu($libraries, $libID);
|
||||
if($this->config->global->flow == 'onlyTest') $this->lang->menugroup->testsuite = 'caselib';
|
||||
|
||||
$this->loadModel('testcase');
|
||||
$this->view->title = $lib->name . $this->lang->colon . $this->lang->testsuite->view;
|
||||
$this->view->position[] = html::a($this->createLink('testsuite', 'library', "libID=$libID"), $lib->name);
|
||||
$this->view->position[] = $this->lang->testsuite->common;
|
||||
$this->view->position[] = $this->lang->testsuite->view;
|
||||
|
||||
$this->view->lib = $lib;
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter');
|
||||
$this->view->actions = $this->loadModel('action')->getList('caselib', $libID);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get drop menu.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @param string $extra
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetDropMenu($libID, $module, $method, $extra = '')
|
||||
{
|
||||
$this->view->link = $this->testsuite->getLibLink($module, $method, $extra);
|
||||
$this->view->libID = $libID;
|
||||
$this->view->module = $module;
|
||||
$this->view->method = $method;
|
||||
$this->view->extra = $extra;
|
||||
|
||||
$libraries = $this->testsuite->getLibraries();
|
||||
|
||||
$this->view->libraries = $libraries;
|
||||
$this->view->librariesPinyin = common::convert2Pinyin($libraries);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* The results page of search.
|
||||
*
|
||||
* @param string $keywords
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @param mix $extra
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxGetMatchedItems($keywords, $module, $method, $extra)
|
||||
{
|
||||
$libraries = $this->dao->select('*')->from(TABLE_TESTSUITE)->where('deleted')->eq(0)->andWhere('name')->like("%$keywords%")->andWhere('type')->eq('library')->orderBy('`id` desc')->fetchAll();
|
||||
$this->view->link = $this->testsuite->getLibLink($module, $method, $extra);
|
||||
$this->view->libraries = $libraries;
|
||||
$this->view->keywords = $keywords;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Export templet.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function exportTemplet($libID)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
if($_POST)
|
||||
{
|
||||
$fields['module'] = $this->lang->testcase->module;
|
||||
$fields['title'] = $this->lang->testcase->title;
|
||||
$fields['precondition'] = $this->lang->testcase->precondition;
|
||||
$fields['stepDesc'] = $this->lang->testcase->stepDesc;
|
||||
$fields['stepExpect'] = $this->lang->testcase->stepExpect;
|
||||
$fields['keywords'] = $this->lang->testcase->keywords;
|
||||
$fields['pri'] = $this->lang->testcase->pri;
|
||||
$fields['type'] = $this->lang->testcase->type;
|
||||
$fields['stage'] = $this->lang->testcase->stage;
|
||||
|
||||
$fields[''] = '';
|
||||
$fields['typeValue'] = $this->lang->testcase->lblTypeValue;
|
||||
$fields['stageValue'] = $this->lang->testcase->lblStageValue;
|
||||
|
||||
$modules = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0);
|
||||
$rows = array();
|
||||
$num = (int)$this->post->num;
|
||||
for($i = 0; $i < $num; $i++)
|
||||
{
|
||||
foreach($modules as $moduleID => $module)
|
||||
{
|
||||
$row = new stdclass();
|
||||
$row->module = $module . "(#$moduleID)";
|
||||
$row->stepDesc = "1. \n2. \n3.";
|
||||
$row->stepExpect = "1. \n2. \n3.";
|
||||
|
||||
if(empty($rows))
|
||||
{
|
||||
$row->typeValue = join("\n", $this->lang->testcase->typeList);
|
||||
$row->stageValue = join("\n", $this->lang->testcase->stageList);
|
||||
}
|
||||
$rows[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
$this->post->set('fields', $fields);
|
||||
$this->post->set('kind', 'testcase');
|
||||
$this->post->set('rows', $rows);
|
||||
$this->post->set('extraNum', $num);
|
||||
$this->post->set('fileName', 'templet');
|
||||
$this->fetch('file', 'export2csv', $_POST);
|
||||
}
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Import case csv file.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function import($libID)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
if($_FILES)
|
||||
{
|
||||
$file = $this->loadModel('file')->getUpload('file');
|
||||
$file = $file[0];
|
||||
|
||||
$fileName = $this->file->savePath . $this->file->getSaveName($file['pathname']);
|
||||
move_uploaded_file($file['tmpname'], $fileName);
|
||||
|
||||
$rows = $this->file->parseCSV($fileName);
|
||||
$fields = $this->testcase->getImportFields($productID);
|
||||
$fields = array_flip($fields);
|
||||
$header = array();
|
||||
foreach($rows[0] as $i => $rowValue)
|
||||
{
|
||||
if(empty($rowValue)) break;
|
||||
$header[$i] = $rowValue;
|
||||
}
|
||||
unset($rows[0]);
|
||||
|
||||
$columnKey = array();
|
||||
foreach($header as $title)
|
||||
{
|
||||
if(!isset($fields[$title])) continue;
|
||||
$columnKey[] = $fields[$title];
|
||||
}
|
||||
|
||||
if(count($columnKey) != count($header) or $this->post->encode != 'utf-8')
|
||||
{
|
||||
$fc = file_get_contents($fileName);
|
||||
$encode = $this->post->encode != "utf-8" ? $this->post->encode : 'gbk';
|
||||
$fc = helper::convertEncoding($fc, $encode, 'utf-8');
|
||||
file_put_contents($fileName, $fc);
|
||||
|
||||
$rows = $this->file->parseCSV($fileName);
|
||||
$columnKey = array();
|
||||
$header = array();
|
||||
foreach($rows[0] as $i => $rowValue)
|
||||
{
|
||||
if(empty($rowValue)) break;
|
||||
$header[$i] = $rowValue;
|
||||
}
|
||||
unset($rows[0]);
|
||||
foreach($header as $title)
|
||||
{
|
||||
if(!isset($fields[$title])) continue;
|
||||
$columnKey[] = $fields[$title];
|
||||
}
|
||||
if(count($columnKey) != count($header)) die(js::alert($this->lang->testcase->errorEncode));
|
||||
}
|
||||
|
||||
$this->session->set('importFile', $fileName);
|
||||
|
||||
die(js::locate(inlink('showImport', "libID=$libID"), 'parent.parent'));
|
||||
}
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show import case.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function showImport($libID)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
if($_POST)
|
||||
{
|
||||
$this->testsuite->createFromImport($libID);
|
||||
die(js::locate(inlink('library', "libID=$libID"), 'parent'));
|
||||
}
|
||||
|
||||
$libraries = $this->testsuite->getLibraries();
|
||||
if(empty($libraries)) $this->locate(inlink('createLib'));
|
||||
|
||||
$this->testsuite->setLibMenu($libraries, $libID);
|
||||
|
||||
$file = $this->session->importFile;
|
||||
$caseLang = $this->lang->testcase;
|
||||
$caseConfig = $this->config->testcase;
|
||||
$modules = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib', $startModuleID = 0);
|
||||
|
||||
$fields = explode(',', $caseConfig->exportFields);
|
||||
foreach($fields as $key => $fieldName)
|
||||
{
|
||||
$fieldName = trim($fieldName);
|
||||
$fields[$fieldName] = isset($caseLang->$fieldName) ? $caseLang->$fieldName : $fieldName;
|
||||
unset($fields[$key]);
|
||||
}
|
||||
|
||||
$fields = array_flip($fields);
|
||||
$rows = $this->loadModel('file')->parseCSV($file);
|
||||
$header = array();
|
||||
foreach($rows[0] as $i => $rowValue)
|
||||
{
|
||||
if(empty($rowValue)) break;
|
||||
$header[$i] = $rowValue;
|
||||
}
|
||||
unset($rows[0]);
|
||||
|
||||
foreach($header as $title)
|
||||
{
|
||||
if(!isset($fields[$title])) continue;
|
||||
$columnKey[] = $fields[$title];
|
||||
}
|
||||
|
||||
$endField = end($fields);
|
||||
$caseData = array();
|
||||
$stepData = array();
|
||||
$stepVars = 0;
|
||||
foreach($rows as $row => $data)
|
||||
{
|
||||
$case = new stdclass();
|
||||
foreach($columnKey as $key => $field)
|
||||
{
|
||||
if(!isset($data[$key])) continue;
|
||||
$cellValue = $data[$key];
|
||||
if($field == 'module')
|
||||
{
|
||||
$case->$field = 0;
|
||||
if(strrpos($cellValue, '(#') !== false)
|
||||
{
|
||||
$id = trim(substr($cellValue, strrpos($cellValue,'(#') + 2), ')');
|
||||
$case->$field = $id;
|
||||
}
|
||||
}
|
||||
elseif(in_array($field, $caseConfig->export->listFields))
|
||||
{
|
||||
if($field == 'stage')
|
||||
{
|
||||
$stages = explode("\n", $cellValue);
|
||||
foreach($stages as $stage) $case->stage[] = array_search($stage, $caseLang->{$field . 'List'});
|
||||
$case->stage = join(',', $case->stage);
|
||||
}
|
||||
else
|
||||
{
|
||||
$case->$field = array_search($cellValue, $caseLang->{$field . 'List'});
|
||||
}
|
||||
}
|
||||
elseif($field != 'stepDesc' and $field != 'stepExpect')
|
||||
{
|
||||
$case->$field = $cellValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
$steps = (array)$cellValue;
|
||||
if(strpos($cellValue, "\n"))
|
||||
{
|
||||
$steps = explode("\n", $cellValue);
|
||||
}
|
||||
elseif(strpos($cellValue, "\r"))
|
||||
{
|
||||
$steps = explode("\r", $cellValue);
|
||||
}
|
||||
|
||||
$stepKey = str_replace('step', '', strtolower($field));
|
||||
$caseStep = array();
|
||||
|
||||
foreach($steps as $step)
|
||||
{
|
||||
$step = trim($step);
|
||||
if(empty($step)) continue;
|
||||
if(preg_match('/^(([0-9]+)\.[0-9]+)([.、]{1})/U', $step, $out))
|
||||
{
|
||||
$num = $out[1];
|
||||
$parent = $out[2];
|
||||
$sign = $out[3];
|
||||
$signbit = $sign == '.' ? 1 : 3;
|
||||
$step = trim(substr($step, strlen($num) + $signbit));
|
||||
if(!empty($step)) $caseStep[$num]['content'] = $step;
|
||||
$caseStep[$num]['type'] = 'item';
|
||||
$caseStep[$parent]['type'] = 'group';
|
||||
}
|
||||
elseif(preg_match('/^([0-9]+)([.、]{1})/U', $step, $out))
|
||||
{
|
||||
$num = $out[1];
|
||||
$sign = $out[2];
|
||||
$signbit = $sign == '.' ? 1 : 3;
|
||||
$step = trim(substr($step, strlen($num) + $signbit));
|
||||
if(!empty($step)) $caseStep[$num]['content'] = $step;
|
||||
$caseStep[$num]['type'] = 'step';
|
||||
}
|
||||
elseif(isset($num))
|
||||
{
|
||||
if(!isset($caseStep[$num]['content'])) $caseStep[$num]['content'] = '';
|
||||
$caseStep[$num]['content'] .= "\n" . $step;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($field == 'stepDesc')
|
||||
{
|
||||
$num = 1;
|
||||
$caseStep[$num]['content'] = $step;
|
||||
$caseStep[$num]['type'] = 'step';
|
||||
}
|
||||
if($field == 'stepExpect' and isset($stepData[$row]['desc']))
|
||||
{
|
||||
end($stepData[$row]['desc']);
|
||||
$num = key($stepData[$row]['desc']);
|
||||
$caseStep[$num]['content'] = $step;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($num);
|
||||
unset($sign);
|
||||
$stepVars += count($caseStep, COUNT_RECURSIVE) - count($caseStep);
|
||||
$stepData[$row][$stepKey] = $caseStep;
|
||||
}
|
||||
}
|
||||
|
||||
$caseData[$row] = $case;
|
||||
unset($case);
|
||||
}
|
||||
|
||||
if(empty($caseData))
|
||||
{
|
||||
unlink($this->session->importFile);
|
||||
unset($_SESSION['importFile']);
|
||||
echo js::alert($this->lang->error->noData);
|
||||
die(js::locate($this->createLink('testsuite', 'library', "libID=$libID")));
|
||||
}
|
||||
|
||||
/* Judge whether the editedTasks is too large and set session. */
|
||||
$countInputVars = count($caseData) * 9 + $stepVars;
|
||||
$showSuhosinInfo = common::judgeSuhosinSetting($countInputVars);
|
||||
if($showSuhosinInfo) $this->view->suhosinInfo = extension_loaded('suhosin') ? sprintf($this->lang->suhosinInfo, $countInputVars) : sprintf($this->lang->maxVarsInfo, $countInputVars);
|
||||
|
||||
$this->view->title = $this->lang->caselib->common . $this->lang->colon . $this->lang->testcase->showImport;
|
||||
$this->view->position[] = $this->lang->testcase->showImport;
|
||||
|
||||
$this->view->modules = $modules;
|
||||
$this->view->cases = $this->dao->select('id,module,stage,status,pri,type')->from(TABLE_CASE)->where('lib')->eq($libID)->andWhere('deleted')->eq(0)->andWhere('product')->eq(0)->fetchAll('id');
|
||||
$this->view->caseData = $caseData;
|
||||
$this->view->stepData = $stepData;
|
||||
$this->view->libID = $libID;
|
||||
$this->display();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,6 @@ $lang->testsuite->unlinkCase = "Unlink";
|
||||
$lang->testsuite->unlinkCaseAction = "Unlink Case";
|
||||
$lang->testsuite->batchUnlinkCases = "Batch Unlink Cases";
|
||||
$lang->testsuite->deleted = 'Deleted';
|
||||
$lang->testsuite->exportTemplet = 'Export Template';
|
||||
$lang->testsuite->batchCreateCase = 'Batch Create';
|
||||
$lang->testsuite->import = 'Import';
|
||||
$lang->testsuite->importAction = 'Import Case';
|
||||
$lang->testsuite->showImport = 'Imported Data';
|
||||
$lang->testsuite->successSaved = 'Saved';
|
||||
|
||||
$lang->testsuite->id = 'ID';
|
||||
@@ -46,7 +41,6 @@ $lang->testsuite->legendBasicInfo = 'Basic Info';
|
||||
$lang->testsuite->unlinkedCases = 'Unlinked Cases';
|
||||
|
||||
$lang->testsuite->confirmDelete = 'Do you want to delete this test suite?';
|
||||
$lang->testsuite->libraryDelete = 'Do you want to delete this library?';
|
||||
$lang->testsuite->confirmUnlinkCase = 'Do you want to unlink this Case?';
|
||||
$lang->testsuite->noticeNone = 'You have not created any suite yet.';
|
||||
$lang->testsuite->noModule = '<div>You have no modules.</div><div>Manage it now.</div>';
|
||||
@@ -57,12 +51,3 @@ $lang->testsuite->lblUnlinkCase = 'Unlink Case';
|
||||
|
||||
$lang->testsuite->authorList['private'] = 'Private';
|
||||
$lang->testsuite->authorList['public'] = 'Public';
|
||||
|
||||
$lang->caselib->common = 'Case Library';
|
||||
$lang->caselib->all = 'All Case Libraries';
|
||||
|
||||
$lang->testsuite->createLib = 'Create Case Library';
|
||||
$lang->testsuite->editLib = 'Edit Case Library';
|
||||
$lang->testsuite->library = 'View Cases in Library';
|
||||
$lang->testsuite->createCase = 'Create Case';
|
||||
$lang->testsuite->libView = 'Library Detail';
|
||||
|
||||
@@ -21,11 +21,6 @@ $lang->testsuite->unlinkCase = "移除";
|
||||
$lang->testsuite->unlinkCaseAction = "移除用例";
|
||||
$lang->testsuite->batchUnlinkCases = "批量移除用例";
|
||||
$lang->testsuite->deleted = '已删除';
|
||||
$lang->testsuite->exportTemplet = '导出模板';
|
||||
$lang->testsuite->batchCreateCase = '批量创建用例';
|
||||
$lang->testsuite->import = '导入';
|
||||
$lang->testsuite->importAction = '导入用例';
|
||||
$lang->testsuite->showImport = '显示导入数据';
|
||||
$lang->testsuite->successSaved = '保存成功';
|
||||
|
||||
$lang->testsuite->id = '编号';
|
||||
@@ -46,7 +41,6 @@ $lang->testsuite->legendBasicInfo = '基本信息';
|
||||
$lang->testsuite->unlinkedCases = '未关联';
|
||||
|
||||
$lang->testsuite->confirmDelete = '您确认要删除该套件吗?';
|
||||
$lang->testsuite->libraryDelete = '您确认要删除该用例库吗?';
|
||||
$lang->testsuite->confirmUnlinkCase = '您确认要移除该用例吗?';
|
||||
$lang->testsuite->noticeNone = '您还没有创建套件';
|
||||
$lang->testsuite->noModule = '<div>您现在还没有模块信息</div><div>请维护用例库模块</div>';
|
||||
@@ -57,12 +51,3 @@ $lang->testsuite->lblUnlinkCase = '移除用例';
|
||||
|
||||
$lang->testsuite->authorList['private'] = '私有';
|
||||
$lang->testsuite->authorList['public'] = '公开';
|
||||
|
||||
$lang->caselib->common = '公共用例库';
|
||||
$lang->caselib->all = '所有用例库';
|
||||
|
||||
$lang->testsuite->createLib = '创建用例库';
|
||||
$lang->testsuite->editLib = '编辑用例库';
|
||||
$lang->testsuite->library = '浏览库用例';
|
||||
$lang->testsuite->createCase = '创建用例';
|
||||
$lang->testsuite->libView = '查看库概况';
|
||||
|
||||
+1
-573
@@ -99,140 +99,6 @@ class testsuiteModel extends model
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set library menu.
|
||||
*
|
||||
* @param array $libraries
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function setLibMenu($libraries, $libID, $moduleID = 0)
|
||||
{
|
||||
$currentLibName = zget($libraries, $libID, '');
|
||||
$isMobile = $this->app->viewType == 'mhtml';
|
||||
$selectHtml = '';
|
||||
if(!empty($libraries))
|
||||
{
|
||||
if($isMobile)
|
||||
{
|
||||
$selectHtml = "<a id='currentItem' href=\"javascript:showSearchMenu('testsuite', '$libID', 'testsuite', 'library', '')\">{$currentLibName} <span class='icon-caret-down'></span></a><div id='currentItemDropMenu' class='hidden affix enter-from-bottom layer'></div>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$dropMenuLink = helper::createLink('testsuite', 'ajaxGetDropMenu', "objectID=$libID&module=testsuite&method=library");
|
||||
$selectHtml = "<div class='btn-group angle-btn'><div class='btn-group'><button data-toggle='dropdown' type='button' class='btn btn-limit' id='currentItem'>{$currentLibName} <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
|
||||
$selectHtml .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
|
||||
$selectHtml .= "</div></div></div>";
|
||||
}
|
||||
}
|
||||
|
||||
if($this->config->global->flow == 'onlyTest')
|
||||
{
|
||||
$modules = $this->loadModel('tree')->getModulePairs($libID, 'caselib');
|
||||
$moduleName = ($moduleID && isset($modules[$moduleID])) ? $modules[$moduleID] : $this->lang->tree->all;
|
||||
|
||||
if(!$isMobile)
|
||||
{
|
||||
$dropMenuLink = helper::createLink('tree', 'ajaxGetDropMenu', "objectID=$libID&module=testsuite&method=library");
|
||||
$selectHtml .= "<div class='btn-group'><button id='currentModule' data-toggle='dropdown' type='button' class='btn btn-limit'>{$moduleName} <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
|
||||
$selectHtml .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
|
||||
$selectHtml .= "</div></div>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$selectHtml .= "<a id='currentModule' href=\"javascript:showSearchMenu('tree', '$libID', 'testsuite', 'library', '')\">{$moduleName} <span class='icon-caret-down'></span></a><div id='currentBranchDropMenu' class='hidden affix enter-from-bottom layer'></div>";
|
||||
}
|
||||
}
|
||||
|
||||
setCookie("lastCaseLib", $libID, $this->config->cookieLife, $this->config->webRoot);
|
||||
|
||||
$pageNav = '';
|
||||
$pageActions = '';
|
||||
$isMobile = $this->app->viewType == 'mhtml';
|
||||
if($isMobile)
|
||||
{
|
||||
$this->app->loadLang('qa');
|
||||
$pageNav = html::a(helper::createLink('qa', 'index'), $this->lang->qa->index) . $this->lang->colon;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->config->global->flow == 'full')
|
||||
{
|
||||
$this->app->loadLang('qa');
|
||||
$pageNav .= '<div class="btn-group angle-btn"><div class="btn-group"><button data-toggle="dropdown" type="button" class="btn">' . $this->lang->qa->index . ' <span class="caret"></span></button>';
|
||||
$pageNav .= '<ul class="dropdown-menu">';
|
||||
if(common::hasPriv('testsuite', 'createLib')) $pageNav .= '<li>' . html::a(helper::createLink('testsuite', 'createLib'), '<i class="icon icon-plus"></i> ' . $this->lang->testsuite->createLib) . '</li>';
|
||||
$pageNav .= '</ul></div></div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->app->loadLang('testcase');
|
||||
$pageActions .= "<div class='btn-group'>";
|
||||
if(common::hasPriv('testsuite', 'exportTemplet'))
|
||||
{
|
||||
$link = helper::createLink('testsuite', 'exportTemplet', "libID=$libID");
|
||||
$pageActions .= html::a($link, "<i class='icon icon-export muted'> </i>" . $this->lang->testsuite->exportTemplet, '', "class='btn btn-link export'");
|
||||
}
|
||||
if(common::hasPriv('testsuite', 'import'))
|
||||
{
|
||||
$link = helper::createLink('testsuite', 'import', "libID=$libID");
|
||||
$pageActions .= html::a($link, "<i class='icon muted icon-import'> </i>" . $this->lang->testcase->importFile, '', "class='btn btn-link export'");
|
||||
}
|
||||
$pageActions .= '</div>';
|
||||
$params = "libID=$libID&moduleID=" . (isset($moduleID) ? $moduleID : 0);
|
||||
if(common::hasPriv('testsuite', 'batchCreateCase'))
|
||||
{
|
||||
$link = helper::createLink('testsuite', 'batchCreateCase', $params);
|
||||
$pageActions .= html::a($link, "<i class='icon-plus'></i>" . $this->lang->testcase->batchCreate, '', "class='btn btn-secondary'");
|
||||
}
|
||||
if(common::hasPriv('testsuite', 'createCase'))
|
||||
{
|
||||
$link = helper::createLink('testsuite', 'createCase', $params);
|
||||
$pageActions .= html::a($link, "<i class='icon-plus'></i>" . $this->lang->testcase->create, '', "class='btn btn-primary'");
|
||||
}
|
||||
if(common::hasPriv('testsuite', 'createLib'))
|
||||
{
|
||||
$link = helper::createLink('testsuite', 'createLib');
|
||||
$pageActions .= html::a($link, "<i class='icon-plus'></i>" . $this->lang->testsuite->createLib, '', "class='btn btn-primary'");
|
||||
}
|
||||
}
|
||||
}
|
||||
$pageNav .= $selectHtml;
|
||||
|
||||
$this->lang->modulePageNav = $pageNav;
|
||||
$this->lang->modulePageActions = $pageActions;
|
||||
foreach($this->lang->caselib->menu as $key => $value)
|
||||
{
|
||||
$replace = '';
|
||||
if($this->config->global->flow == 'onlyTest') $replace = $libID;
|
||||
common::setMenuVars($this->lang->caselib->menu, $key, $replace);
|
||||
}
|
||||
$this->lang->testsuite->menu = $this->lang->caselib->menu;
|
||||
if($this->config->global->flow != 'full' && $this->app->getMethodName() != 'libview') $this->lang->testsuite->menu->bysearch = "<a class='querybox-toggle' id='bysearchTab'><i class='icon icon-search muted'> </i>{$this->lang->testcase->bySearch}</a>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Save lib state.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param array $libraries
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function saveLibState($libID = 0, $libraries = array())
|
||||
{
|
||||
if($libID > 0) $this->session->set('caseLib', (int)$libID);
|
||||
if($libID == 0 and $this->cookie->lastCaseLib) $this->session->set('caseLib', $this->cookie->lastCaseLib);
|
||||
if($libID == 0 and $this->session->caseLib == '') $this->session->set('caseLib', key($libraries));
|
||||
if(!isset($libraries[$this->session->caseLib]))
|
||||
{
|
||||
$this->session->set('caseLib', key($libraries));
|
||||
$libID = $this->session->caseLib;
|
||||
}
|
||||
return $this->session->caseLib;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test suite.
|
||||
*
|
||||
@@ -424,130 +290,11 @@ class testsuiteModel extends model
|
||||
*/
|
||||
public function delete($suiteID, $table = '')
|
||||
{
|
||||
$suite = $this->getById($suiteID);
|
||||
parent::delete(TABLE_TESTSUITE, $suiteID);
|
||||
if($suite->type == 'library')
|
||||
{
|
||||
$this->dao->update(TABLE_ACTION)->set('objectType')->eq('caselib')->where('objectID')->eq($suiteID)->andWhere('objectType')->eq('testsuite')->exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_SUITECASE)->where('suite')->eq($suiteID)->exec();
|
||||
}
|
||||
$this->dao->delete()->from(TABLE_SUITECASE)->where('suite')->eq($suiteID)->exec();
|
||||
return !dao::isError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get libraries.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getLibraries()
|
||||
{
|
||||
return $this->dao->select("id,name")->from(TABLE_TESTSUITE)
|
||||
->where('product')->eq(0)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('type')->eq('library')
|
||||
->orderBy('id_desc')
|
||||
->fetchPairs('id', 'name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create lib.
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function createLib()
|
||||
{
|
||||
$lib = fixer::input('post')
|
||||
->stripTags($this->config->testsuite->editor->create['id'], $this->config->allowedTags)
|
||||
->setForce('type', 'library')
|
||||
->add('addedBy', $this->app->user->account)
|
||||
->add('addedDate', helper::now())
|
||||
->remove('uid')
|
||||
->get();
|
||||
$lib = $this->loadModel('file')->processImgURL($lib, $this->config->testsuite->editor->create['id'], $this->post->uid);
|
||||
$this->dao->insert(TABLE_TESTSUITE)->data($lib)
|
||||
->batchcheck($this->config->testsuite->createlib->requiredFields, 'notempty')
|
||||
->check('name', 'unique', "deleted = '0'")
|
||||
->exec();
|
||||
if(!dao::isError())
|
||||
{
|
||||
$libID = $this->dao->lastInsertID();
|
||||
$this->file->updateObjectID($this->post->uid, $libID, 'caselib');
|
||||
return $libID;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lib cases.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param string $browseType
|
||||
* @param int $queryID
|
||||
* @param int $moduleID
|
||||
* @param string $sort
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getLibCases($libID, $browseType, $queryID = 0, $moduleID = 0, $sort = 'id_desc', $pager = null)
|
||||
{
|
||||
$moduleIdList = $moduleID ? $this->loadModel('tree')->getAllChildId($moduleID) : '0';
|
||||
$browseType = ($browseType == 'bymodule' and $this->session->libBrowseType and $this->session->libBrowseType != 'bysearch') ? $this->session->libBrowseType : $browseType;
|
||||
|
||||
$cases = array();
|
||||
if($browseType == 'bymodule' or $browseType == 'all' or $browseType == 'wait')
|
||||
{
|
||||
$cases = $this->dao->select('*')->from(TABLE_CASE)
|
||||
->where('lib')->eq((int)$libID)
|
||||
->andWhere('product')->eq(0)
|
||||
->beginIF($moduleIdList)->andWhere('module')->in($moduleIdList)->fi()
|
||||
->beginIF($browseType == 'wait')->andWhere('status')->eq($browseType)->fi()
|
||||
->andWhere('deleted')->eq('0')
|
||||
->orderBy($sort)->page($pager)->fetchAll('id');
|
||||
}
|
||||
/* By search. */
|
||||
elseif($browseType == 'bysearch')
|
||||
{
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
$this->session->set('caselibQuery', ' 1 = 1');
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('caselibQuery', $query->sql);
|
||||
$this->session->set('caselibForm', $query->form);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->caselibQuery == false) $this->session->set('caselibQuery', ' 1 = 1');
|
||||
}
|
||||
|
||||
$queryLibID = $libID;
|
||||
$allLib = "`lib` = 'all'";
|
||||
$caseQuery = '(' . $this->session->caselibQuery;
|
||||
if(strpos($this->session->caselibQuery, $allLib) !== false)
|
||||
{
|
||||
$caseQuery = str_replace($allLib, '1', $caseQuery);
|
||||
$queryLibID = 'all';
|
||||
}
|
||||
$caseQuery .= ')';
|
||||
|
||||
$cases = $this->dao->select('*')->from(TABLE_CASE)->where($caseQuery)
|
||||
->beginIF($queryLibID != 'all')->andWhere('lib')->eq((int)$libID)->fi()
|
||||
->andWhere('product')->eq(0)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->orderBy($sort)->page($pager)->fetchAll();
|
||||
|
||||
}
|
||||
return $cases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get not imported cases.
|
||||
*
|
||||
@@ -601,323 +348,4 @@ class testsuiteModel extends model
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build search form.
|
||||
*
|
||||
* @param int $libID
|
||||
* @param array $libraries
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildSearchForm($libID, $libraries, $queryID, $actionURL)
|
||||
{
|
||||
$this->config->testcase->search['fields']['lib'] = $this->lang->testcase->lib;
|
||||
$this->config->testcase->search['params']['lib']['values'] = array('' => '', $libID => $libraries[$libID], 'all' => $this->lang->caselib->all);
|
||||
$this->config->testcase->search['params']['lib']['operator'] = '=';
|
||||
$this->config->testcase->search['params']['lib']['control'] = 'select';
|
||||
$this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($libID, $viewType = 'caselib');
|
||||
if(!$this->config->testcase->needReview) unset($this->config->testcase->search['params']['status']['values']['wait']);
|
||||
unset($this->config->testcase->search['fields']['product']);
|
||||
unset($this->config->testcase->search['params']['product']);
|
||||
unset($this->config->testcase->search['fields']['branch']);
|
||||
unset($this->config->testcase->search['params']['branch']);
|
||||
unset($this->config->testcase->search['fields']['lastRunner']);
|
||||
unset($this->config->testcase->search['params']['lastRunner']);
|
||||
unset($this->config->testcase->search['fields']['lastRunResult']);
|
||||
unset($this->config->testcase->search['params']['lastRunResult']);
|
||||
unset($this->config->testcase->search['fields']['lastRunDate']);
|
||||
unset($this->config->testcase->search['params']['lastRunDate']);
|
||||
|
||||
$this->config->testcase->search['module'] = 'caselib';
|
||||
$this->config->testcase->search['actionURL'] = $actionURL;
|
||||
$this->config->testcase->search['queryID'] = $queryID;
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->testcase->search);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lib link.
|
||||
*
|
||||
* @param string $module
|
||||
* @param string $method
|
||||
* @param string $extra
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getLibLink($module, $method, $extra)
|
||||
{
|
||||
$link = '';
|
||||
if($module == 'testsuite')
|
||||
{
|
||||
if($module == 'testsuite' && ($method == 'createlib'))
|
||||
{
|
||||
$link = helper::createLink($module, 'library', "libID=%s");
|
||||
}
|
||||
else
|
||||
{
|
||||
$link = helper::createLink($module, $method, "libID=%s");
|
||||
}
|
||||
}
|
||||
else if($module == 'tree')
|
||||
{
|
||||
$link = helper::createLink($module, $method, "libID=%s&type=caselib¤tModuleID=0");
|
||||
}
|
||||
else
|
||||
{
|
||||
$link = helper::createLink('testsuite', 'library', "libID=%s");
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create from import.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function createFromImport($libID)
|
||||
{
|
||||
$this->loadModel('action');
|
||||
$this->loadModel('testcase');
|
||||
$this->loadModel('file');
|
||||
$now = helper::now();
|
||||
$data = fixer::input('post')->get();
|
||||
|
||||
if(!empty($_POST['id']))
|
||||
{
|
||||
$oldSteps = $this->dao->select('t2.*')->from(TABLE_CASE)->alias('t1')
|
||||
->leftJoin(TABLE_CASESTEP)->alias('t2')->on('t1.id = t2.case')
|
||||
->where('t1.id')->in(($_POST['id']))
|
||||
->andWhere('t1.version=t2.version')
|
||||
->orderBy('t2.id')
|
||||
->fetchGroup('case');
|
||||
$oldCases = $this->dao->select('*')->from(TABLE_CASE)->where('id')->in($_POST['id'])->fetchAll('id');
|
||||
}
|
||||
|
||||
$cases = array();
|
||||
foreach($data->lib as $key => $lib)
|
||||
{
|
||||
$caseData = new stdclass();
|
||||
|
||||
$caseData->lib = $lib;
|
||||
$caseData->module = $data->module[$key];
|
||||
$caseData->title = $data->title[$key];
|
||||
$caseData->pri = (int)$data->pri[$key];
|
||||
$caseData->type = $data->type[$key];
|
||||
$caseData->status = $data->status[$key];
|
||||
$caseData->stage = join(',', $data->stage[$key]);
|
||||
$caseData->keywords = $data->keywords[$key];
|
||||
$caseData->frequency = 1;
|
||||
$caseData->precondition = $data->precondition[$key];
|
||||
|
||||
if(isset($this->config->testcase->create->requiredFields))
|
||||
{
|
||||
$requiredFields = explode(',', $this->config->testcase->create->requiredFields);
|
||||
foreach($requiredFields as $requiredField)
|
||||
{
|
||||
$requiredField = trim($requiredField);
|
||||
if(empty($caseData->$requiredField)) dao::$errors[] = sprintf($this->lang->testcase->noRequire, $key, $this->lang->testcase->$requiredField);
|
||||
}
|
||||
}
|
||||
|
||||
$cases[$key] = $caseData;
|
||||
}
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
$forceNotReview = $this->testcase->forceNotReview();
|
||||
foreach($cases as $key => $caseData)
|
||||
{
|
||||
if(!empty($_POST['id'][$key]) and empty($_POST['insert']))
|
||||
{
|
||||
$caseID = $data->id[$key];
|
||||
$stepChanged = false;
|
||||
$steps = array();
|
||||
$oldStep = isset($oldSteps[$caseID]) ? $oldSteps[$caseID] : array();
|
||||
$oldCase = $oldCases[$caseID];
|
||||
|
||||
/* Remove the empty setps in post. */
|
||||
$steps = array();
|
||||
if(isset($_POST['desc'][$key]))
|
||||
{
|
||||
foreach($data->desc[$key] as $id => $desc)
|
||||
{
|
||||
$desc = trim($desc);
|
||||
if(empty($desc)) continue;
|
||||
$step = new stdclass();
|
||||
$step->type = $data->stepType[$key][$id];
|
||||
$step->desc = $desc;
|
||||
$step->expect = trim($data->expect[$key][$id]);
|
||||
|
||||
$steps[] = $step;
|
||||
}
|
||||
}
|
||||
|
||||
/* If step count changed, case changed. */
|
||||
if((!$oldStep != !$steps) or (count($oldStep) != count($steps)))
|
||||
{
|
||||
$stepChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Compare every step. */
|
||||
foreach($oldStep as $id => $oldStep)
|
||||
{
|
||||
if(trim($oldStep->desc) != trim($steps[$id]->desc) or trim($oldStep->expect) != $steps[$id]->expect)
|
||||
{
|
||||
$stepChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$version = $stepChanged ? $oldCase->version + 1 : $oldCase->version;
|
||||
$caseData->version = $version;
|
||||
$changes = common::createChanges($oldCase, $caseData);
|
||||
if(!$changes and !$stepChanged) continue;
|
||||
|
||||
if($changes or $stepChanged)
|
||||
{
|
||||
$caseData->lastEditedBy = $this->app->user->account;
|
||||
$caseData->lastEditedDate = $now;
|
||||
if($stepChanged and !$forceNotReview) $caseData->status = 'wait';
|
||||
$this->dao->update(TABLE_CASE)->data($caseData)->where('id')->eq($caseID)->autoCheck()->exec();
|
||||
if($stepChanged)
|
||||
{
|
||||
$parentStepID = 0;
|
||||
foreach($steps as $id => $step)
|
||||
{
|
||||
$step = (array)$step;
|
||||
if(empty($step['desc'])) continue;
|
||||
$stepData = new stdclass();
|
||||
$stepData->type = ($step['type'] == 'item' and $parentStepID == 0) ? 'step' : $step['type'];
|
||||
$stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0;
|
||||
$stepData->case = $caseID;
|
||||
$stepData->version = $version;
|
||||
$stepData->desc = $step['desc'];
|
||||
$stepData->expect = $step['expect'];
|
||||
$this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec();
|
||||
if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID();
|
||||
if($stepData->type == 'step') $parentStepID = 0;
|
||||
}
|
||||
}
|
||||
$oldCase->steps = $this->testcase->joinStep($oldStep);
|
||||
$caseData->steps = $this->testcase->joinStep($steps);
|
||||
$changes = common::createChanges($oldCase, $caseData);
|
||||
$actionID = $this->action->create('case', $caseID, 'Edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$caseData->version = 1;
|
||||
$caseData->openedBy = $this->app->user->account;
|
||||
$caseData->openedDate = $now;
|
||||
$caseData->status = $forceNotReview ? 'normal' : 'wait';
|
||||
$this->dao->insert(TABLE_CASE)->data($caseData)->autoCheck()->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$caseID = $this->dao->lastInsertID();
|
||||
$parentStepID = 0;
|
||||
foreach($data->desc[$key] as $id => $desc)
|
||||
{
|
||||
$desc = trim($desc);
|
||||
if(empty($desc)) continue;
|
||||
$stepData = new stdclass();
|
||||
$stepData->type = ($data->stepType[$key][$id] == 'item' and $parentStepID == 0) ? 'step' : $data->stepType[$key][$id];
|
||||
$stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0;
|
||||
$stepData->case = $caseID;
|
||||
$stepData->version = 1;
|
||||
$stepData->desc = $desc;
|
||||
$stepData->expect = $data->expect[$key][$id];
|
||||
$this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec();
|
||||
if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID();
|
||||
if($stepData->type == 'step') $parentStepID = 0;
|
||||
}
|
||||
$this->action->create('case', $caseID, 'Opened');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unlink($this->session->importFile);
|
||||
unset($_SESSION['importFile']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch create case for lib.
|
||||
*
|
||||
* @param int $libID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function batchCreateCase($libID)
|
||||
{
|
||||
$this->loadModel('testcase');
|
||||
$this->loadModel('action');
|
||||
|
||||
$now = helper::now();
|
||||
$cases = fixer::input('post')->get();
|
||||
$batchNum = count(reset($cases));
|
||||
|
||||
$result = $this->loadModel('common')->removeDuplicate('case', $cases, "lib={$libID}");
|
||||
$cases = $result['data'];
|
||||
|
||||
for($i = 0; $i < $batchNum; $i++)
|
||||
{
|
||||
if(!empty($cases->title[$i]) and empty($cases->type[$i])) die(js::alert(sprintf($this->lang->error->notempty, $this->lang->testcase->type)));
|
||||
}
|
||||
|
||||
$module = 0;
|
||||
$type = '';
|
||||
$pri = 3;
|
||||
for($i = 0; $i < $batchNum; $i++)
|
||||
{
|
||||
$module = $cases->module[$i] == 'ditto' ? $module : $cases->module[$i];
|
||||
$type = $cases->type[$i] == 'ditto' ? $type : $cases->type[$i];
|
||||
$pri = $cases->pri[$i] == 'ditto' ? $pri : $cases->pri[$i];
|
||||
$cases->module[$i] = (int)$module;
|
||||
$cases->type[$i] = $type;
|
||||
$cases->pri[$i] = $pri;
|
||||
}
|
||||
|
||||
$forceNotReview = $this->testcase->forceNotReview();
|
||||
for($i = 0; $i < $batchNum; $i++)
|
||||
{
|
||||
if($cases->type[$i] != '' and $cases->title[$i] != '')
|
||||
{
|
||||
$data[$i] = new stdclass();
|
||||
$data[$i]->lib = $libID;
|
||||
$data[$i]->module = $cases->module[$i];
|
||||
$data[$i]->type = $cases->type[$i];
|
||||
$data[$i]->pri = $cases->pri[$i];
|
||||
$data[$i]->stage = empty($cases->stage[$i]) ? '' : implode(',', $cases->stage[$i]);
|
||||
$data[$i]->color = $cases->color[$i];
|
||||
$data[$i]->title = $cases->title[$i];
|
||||
$data[$i]->precondition = $cases->precondition[$i];
|
||||
$data[$i]->keywords = $cases->keywords[$i];
|
||||
$data[$i]->openedBy = $this->app->user->account;
|
||||
$data[$i]->openedDate = $now;
|
||||
$data[$i]->status = $forceNotReview ? 'normal' : 'wait';
|
||||
$data[$i]->version = 1;
|
||||
|
||||
$this->dao->insert(TABLE_CASE)->data($data[$i])
|
||||
->autoCheck()
|
||||
->batchCheck($this->config->testcase->create->requiredFields, 'notempty')
|
||||
->exec();
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
echo js::error(dao::getError());
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
|
||||
$caseID = $this->dao->lastInsertID();
|
||||
$actionID = $this->action->create('case', $caseID, 'Opened');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,6 +289,7 @@ class testtask extends control
|
||||
$this->config->testcase->search['module'] = 'testtask';
|
||||
$this->config->testcase->search['params']['product']['values'] = array($productID => $this->products[$productID], 'all' => $this->lang->testcase->allProduct);
|
||||
$this->config->testcase->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($productID, $viewType = 'case');
|
||||
$this->config->testcase->search['params']['status']['values'] = array('' => '') + $this->lang->testtask->statusList;
|
||||
|
||||
$this->config->testcase->search['queryID'] = $queryID;
|
||||
$this->config->testcase->search['fields']['assignedTo'] = $this->lang->testtask->assignedTo;
|
||||
@@ -505,7 +506,7 @@ class testtask extends control
|
||||
|
||||
if($this->post->comment != '' or !empty($changes))
|
||||
{
|
||||
$actionID = $this->action->create('testtask', $taskID, 'Started', $this->post->comment);
|
||||
$actionID = $this->loadModel('action')->create('testtask', $taskID, 'Started', $this->post->comment);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
@@ -547,7 +548,7 @@ class testtask extends control
|
||||
|
||||
if($this->post->comment != '' or !empty($changes))
|
||||
{
|
||||
$actionID = $this->action->create('testtask', $taskID, 'Activated', $this->post->comment);
|
||||
$actionID = $this->loadModel('action')->create('testtask', $taskID, 'Activated', $this->post->comment);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
@@ -589,7 +590,7 @@ class testtask extends control
|
||||
|
||||
if($this->post->comment != '' or !empty($changes))
|
||||
{
|
||||
$actionID = $this->action->create('testtask', $taskID, 'Closed', $this->post->comment);
|
||||
$actionID = $this->loadModel('action')->create('testtask', $taskID, 'Closed', $this->post->comment);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
@@ -632,7 +633,7 @@ class testtask extends control
|
||||
|
||||
if($this->post->comment != '' or !empty($changes))
|
||||
{
|
||||
$actionID = $this->action->create('testtask', $taskID, 'Blocked', $this->post->comment);
|
||||
$actionID = $this->loadModel('action')->create('testtask', $taskID, 'Blocked', $this->post->comment);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
|
||||
@@ -574,8 +574,8 @@ class testtaskModel extends model
|
||||
{
|
||||
$datas = $this->dao->select('lastRunner AS name, COUNT(*) AS value')->from(TABLE_TESTRUN)->where('task')->eq($taskID)->groupBy('name')->orderBy('value DESC')->fetchAll('name');
|
||||
if(!$datas) return array();
|
||||
|
||||
foreach($datas as $result => $data) $data->name = $result ? $result : $this->lang->testtask->unexecuted;
|
||||
$users = $this->loadModel('user')->getPairs('noclosed|noletter');
|
||||
foreach($datas as $result => $data) $data->name = $result ? zget($users, $result, $result) : $this->lang->testtask->unexecuted;
|
||||
|
||||
return $datas;
|
||||
}
|
||||
@@ -764,7 +764,7 @@ class testtaskModel extends model
|
||||
{
|
||||
$orderBy = (strpos($orderBy, 'assignedTo') !== false or strpos($orderBy, 'lastRunResult') !== false) ? ('t1.' . $orderBy) : ('t2.' . $orderBy);
|
||||
|
||||
return $this->dao->select('t2.*,t1.*,t2.version as caseVersion,t3.title as storyTitle')->from(TABLE_TESTRUN)->alias('t1')
|
||||
return $this->dao->select('t2.*,t1.*,t2.version as caseVersion,t3.title as storyTitle,t2.status as caseStatus')->from(TABLE_TESTRUN)->alias('t1')
|
||||
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id')
|
||||
->leftJoin(TABLE_STORY)->alias('t3')->on('t2.story = t3.id')
|
||||
->where('t1.task')->eq((int)$taskID)
|
||||
@@ -788,7 +788,7 @@ class testtaskModel extends model
|
||||
{
|
||||
$orderBy = strpos($orderBy, 'assignedTo') !== false ? ('t1.' . $orderBy) : ('t2.' . $orderBy);
|
||||
|
||||
return $this->dao->select('t2.*,t1.*,t2.version as caseVersion,t3.title as storyTitle')->from(TABLE_TESTRUN)->alias('t1')
|
||||
return $this->dao->select('t2.*,t1.*,t2.version as caseVersion,t3.title as storyTitle,t2.status as caseStatus')->from(TABLE_TESTRUN)->alias('t1')
|
||||
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id')
|
||||
->leftJoin(TABLE_STORY)->alias('t3')->on('t2.story = t3.id')
|
||||
->where('t1.task')->eq((int)$taskID)
|
||||
@@ -852,9 +852,10 @@ class testtaskModel extends model
|
||||
}
|
||||
|
||||
$caseQuery = preg_replace('/`(\w+)`/', 't2.`$1`', $caseQuery);
|
||||
$caseQuery = str_replace(array('t2.`assignedTo`', 't2.`lastRunner`', 't2.`lastRunDate`', 't2.`lastRunResult`'), array('t1.`assignedTo`', 't1.`lastRunner`', 't1.`lastRunDate`', 't1.`lastRunResult`'), $caseQuery);
|
||||
$runs = $this->dao->select('t2.*,t1.*, t2.version as caseVersion')->from(TABLE_TESTRUN)->alias('t1')
|
||||
$caseQuery = str_replace(array('t2.`assignedTo`', 't2.`lastRunner`', 't2.`lastRunDate`', 't2.`lastRunResult`', 't2.`status`'), array('t1.`assignedTo`', 't1.`lastRunner`', 't1.`lastRunDate`', 't1.`lastRunResult`', 't1.`status`'), $caseQuery);
|
||||
$runs = $this->dao->select('t2.*,t1.*, t2.version as caseVersion,t3.title as storyTitle,t2.status as caseStatus')->from(TABLE_TESTRUN)->alias('t1')
|
||||
->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id')
|
||||
->leftJoin(TABLE_STORY)->alias('t3')->on('t2.story = t3.id')
|
||||
->where($caseQuery)
|
||||
->andWhere('t1.task')->eq($task->id)
|
||||
->andWhere('t2.deleted')->eq(0)
|
||||
@@ -1159,7 +1160,7 @@ class testtaskModel extends model
|
||||
if($action == 'block') return ($testtask->status == 'doing' || $testtask->status == 'wait');
|
||||
if($action == 'activate') return ($testtask->status == 'blocked' || $testtask->status == 'done');
|
||||
if($action == 'close') return $testtask->status != 'done';
|
||||
if($action == 'runcase') return $testtask->status != 'wait';
|
||||
if($action == 'runcase') return isset($testtask->caseStatus) ? $testtask->caseStatus != 'wait' : $testtask->status != 'wait';
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ class todo extends control
|
||||
$actionID = $this->loadModel('action')->create('todo', $todoID, 'edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
die(js::locate(inlink('view', "todoID=$todoID"), 'parent'));
|
||||
die(js::locate($this->session->todoList, 'parent'));
|
||||
}
|
||||
|
||||
/* Judge a private todo or not, If private, die. */
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<div class="modal-header">
|
||||
<h4 class='modal-title pull-left'><?php echo html::a($this->createLink('todo', 'view', 'todo=' . $todo->id), "TODO #{$todo->id} {$todo->name}");?></h4>
|
||||
</div>
|
||||
<form class='modal-body form-horizontal' method='post' target='hiddenwin' id='dataform'>
|
||||
<form class='modal-body form-horizontal' method='post' id='dataform'>
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-1"><?php echo $lang->todo->date;?></label>
|
||||
<div class="col-sm-10">
|
||||
|
||||
@@ -54,8 +54,8 @@ class tree extends control
|
||||
}
|
||||
elseif(strpos($viewType, 'caselib') !== false)
|
||||
{
|
||||
$this->loadModel('testsuite');
|
||||
$lib = $this->testsuite->getById($rootID);
|
||||
$this->loadModel('caselib');
|
||||
$lib = $this->caselib->getById($rootID);
|
||||
$this->view->root = $lib;
|
||||
}
|
||||
|
||||
@@ -116,13 +116,13 @@ class tree extends control
|
||||
}
|
||||
elseif($viewType == 'caselib')
|
||||
{
|
||||
$this->testsuite->setLibMenu($this->testsuite->getLibraries(), $rootID);
|
||||
$this->lang->tree->menu = $this->lang->testsuite->menu;
|
||||
$this->lang->tree->menuOrder = $this->lang->testsuite->menuOrder;
|
||||
$this->caselib->setLibMenu($this->caselib->getLibraries(), $rootID);
|
||||
$this->lang->tree->menu = $this->lang->caselib->menu;
|
||||
$this->lang->tree->menuOrder = $this->lang->caselib->menuOrder;
|
||||
$this->lang->set('menugroup.tree', 'qa');
|
||||
|
||||
$title = $this->lang->tree->manageCaseLib;
|
||||
$position[] = html::a($this->createLink('testsuite', 'library', "libID=$rootID"), $lib->name);
|
||||
$position[] = html::a($this->createLink('caselib', 'browse', "libID=$rootID"), $lib->name);
|
||||
$position[] = $this->lang->tree->manageCaseLib;
|
||||
}
|
||||
elseif(strpos($viewType, 'doc') !== false)
|
||||
@@ -438,9 +438,9 @@ class tree extends control
|
||||
$this->view->method = $method;
|
||||
$this->view->extra = $extra;
|
||||
|
||||
$viewType = $module;
|
||||
if($module == 'bug') $viewType = 'bug';
|
||||
if($module == 'testcase') $viewType = 'case';
|
||||
if($module == 'testsuite') $viewType = 'caselib';
|
||||
|
||||
$modules = $this->tree->getOptionMenu($rootID, $viewType);
|
||||
$modulesPinyin = common::convert2Pinyin($modules);
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
body{background:white; overflow:none}
|
||||
@@ -1 +1 @@
|
||||
.thWidth{width:80px !important;}
|
||||
.thWidth{width:90px !important;}
|
||||
|
||||
@@ -1 +1 @@
|
||||
.thWidth{width:80px !important;}
|
||||
.thWidth{width:90px !important;}
|
||||
|
||||
@@ -39,6 +39,7 @@ $lang->tree->addChild = "增加子模块";
|
||||
$lang->tree->confirmDelete = '该模块及其子模块都会被删除,您确定删除吗?';
|
||||
$lang->tree->confirmDeleteLine = "您确定删除该{$lang->productCommon}线吗?";
|
||||
$lang->tree->confirmRoot = "模块的所属{$lang->productCommon}修改,会关联修改该模块下的需求、Bug、用例的所属{$lang->productCommon},以及{$lang->projectCommon}和{$lang->productCommon}的关联关系。该操作比较危险,请谨慎操作。是否确认修改?";
|
||||
$lang->tree->confirmRoot4Doc = "模块的所属文档库修改,会关联修改该模块下的文档的关联关系。该操作比较危险,请谨慎操作。是否确认修改?";
|
||||
$lang->tree->successSave = '成功保存';
|
||||
$lang->tree->successFixed = '成功修正数据!';
|
||||
$lang->tree->repeatName = '模块名“%s”已经存在!';
|
||||
|
||||
@@ -248,6 +248,8 @@ class treeModel extends model
|
||||
{
|
||||
$parentModules = explode(',', trim($module->path, ','));
|
||||
if($type == 'product' and isset($noProductModules[$parentModules[0]])) continue;
|
||||
/* Fix bug #2007. */
|
||||
if($type == 'product' and $module->type == 'task' and !isset($modules[$parentModules[0]])) continue;
|
||||
$rootName = ($productNum > 1 and $type == 'product') ? "/$rootModule/" : '/';
|
||||
if($type == 'product' and $module->branch and isset($branchGroups[$id][$module->branch])) $rootName .= $branchGroups[$id][$module->branch] . '/';
|
||||
$this->buildTreeArray($treeMenu, $modules, $module, $rootName);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
<?php if($viewType != 'story'):?>
|
||||
<style>
|
||||
li.tree-item-story > .tree-actions .tree-action[data-type=sort]{display:none;}
|
||||
li.tree-item-story > .tree-actions .tree-action[data-type=edit]{display:none;}
|
||||
li.tree-item-story > .tree-actions .tree-action[data-type=delete]{display:none;}
|
||||
</style>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -34,7 +34,7 @@ if(isset($pageCSS)) css::internal($pageCSS);
|
||||
<?php if($type == 'doc'):?>
|
||||
<tr>
|
||||
<th class='thWidth'><?php echo $lang->doc->lib;?></th>
|
||||
<td><?php echo html::select('root', $libs, $module->root, "class='form-control chosen' onchange=loadDocModule(this.value)");?></td>
|
||||
<td><?php echo html::select('root', $libs, $module->root, "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<?php if($module->type != 'line'):?>
|
||||
@@ -81,20 +81,7 @@ function getProductModules(productID)
|
||||
$('#parent').trigger('chosen:updated')
|
||||
}, 'json');
|
||||
}
|
||||
$(function()
|
||||
{
|
||||
if(type == 'doc') return;
|
||||
$('#root').change(function()
|
||||
{
|
||||
if($(this).val() == currentRoot) return true;
|
||||
if(!confirm('<?php echo $lang->tree->confirmRoot?>'))
|
||||
{
|
||||
$('#root').val(currentRoot);
|
||||
$('#root').trigger('chosen:updated');
|
||||
}
|
||||
getProductModules($(this).val());
|
||||
})
|
||||
})
|
||||
|
||||
function loadDocModule(libID)
|
||||
{
|
||||
var link = createLink('doc', 'ajaxGetChild', 'libID=' + libID + '&type=parent');
|
||||
@@ -105,6 +92,22 @@ function loadDocModule(libID)
|
||||
}
|
||||
$(function()
|
||||
{
|
||||
$('#root').change(function()
|
||||
{
|
||||
if($(this).val() == currentRoot) return true;
|
||||
var confirmRoot = <?php echo json_encode($type == 'doc' ? $lang->tree->confirmRoot4Doc : $lang->tree->confirmRoot);?>;
|
||||
if(!confirm(confirmRoot))
|
||||
{
|
||||
$('#root').val(currentRoot);
|
||||
$('#root').trigger('chosen:updated');
|
||||
}
|
||||
else
|
||||
{
|
||||
if(type != 'doc') getProductModules($(this).val());
|
||||
if(type == 'doc') loadDocModule($(this).val());
|
||||
}
|
||||
})
|
||||
|
||||
$('#dataform .chosen').chosen();
|
||||
|
||||
// hide #parent chosen dropdown on root dropdown show
|
||||
|
||||
@@ -111,3 +111,4 @@ $lang->upgrade->fromVersions['11_5_1'] = '11.5.1';
|
||||
$lang->upgrade->fromVersions['11_5_2'] = '11.5.2';
|
||||
$lang->upgrade->fromVersions['11_6'] = '11.6';
|
||||
$lang->upgrade->fromVersions['11_6_1'] = '11.6.1';
|
||||
$lang->upgrade->fromVersions['11_6_2'] = '11.6.2';
|
||||
|
||||
+199
-27
@@ -110,235 +110,338 @@ class upgradeModel extends model
|
||||
case '3_1':
|
||||
$this->saveLogs('Execute 3_1');
|
||||
$this->execSQL($this->getUpgradeFile('3.1'));
|
||||
$this->appendExec('3_1');
|
||||
case '3_2':
|
||||
$this->saveLogs('Execute 3_2');
|
||||
$this->execSQL($this->getUpgradeFile('3.2'));
|
||||
$this->appendExec('3_2');
|
||||
case '3_2_1':
|
||||
$this->saveLogs('Execute 3_2_1');
|
||||
$this->execSQL($this->getUpgradeFile('3.2.1'));
|
||||
$this->appendExec('3_2_1');
|
||||
case '3_3':
|
||||
$this->saveLogs('Execute 3_3');
|
||||
$this->execSQL($this->getUpgradeFile('3.3'));
|
||||
$this->updateTaskAssignedTo();
|
||||
$this->appendExec('3_3');
|
||||
case '4_0_beta1':
|
||||
$this->saveLogs('Execute 4_0_beta1');
|
||||
$this->execSQL($this->getUpgradeFile('4.0.beta1'));
|
||||
$this->appendExec('4_0_beta1');
|
||||
case '4_0_beta2':
|
||||
$this->saveLogs('Execute 4_0_beta2');
|
||||
$this->execSQL($this->getUpgradeFile('4.0.beta2'));
|
||||
$this->updateProjectType();
|
||||
$this->updateEstimatePriv();
|
||||
$this->appendExec('4_0_beta2');
|
||||
case '4_0':
|
||||
$this->saveLogs('Execute 4_0');
|
||||
$this->execSQL($this->getUpgradeFile('4.0'));
|
||||
$this->appendExec('4_0');
|
||||
case '4_0_1':
|
||||
$this->saveLogs('Execute 4_0_1');
|
||||
$this->execSQL($this->getUpgradeFile('4.0.1'));
|
||||
$this->addPriv4_0_1();
|
||||
$this->appendExec('4_0_1');
|
||||
case '4_1':
|
||||
$this->saveLogs('Execute 4_1');
|
||||
$this->execSQL($this->getUpgradeFile('4.1'));
|
||||
$this->addPriv4_1();
|
||||
$this->processTaskFinish();
|
||||
$this->deleteCompany();
|
||||
$this->appendExec('4_1');
|
||||
case '4_2_beta':
|
||||
$this->saveLogs('Execute 4_2_beta');
|
||||
$this->execSQL($this->getUpgradeFile('4.2'));
|
||||
$this->appendExec('4_2_beta');
|
||||
case '4_3_beta':
|
||||
$this->saveLogs('Execute 4_3_beta');
|
||||
$this->execSQL($this->getUpgradeFile('4.3'));
|
||||
case '5_0_beta1': $this->saveLogs('Execute 5_0_beta1');
|
||||
case '5_0_beta2': $this->saveLogs('Execute 5_0_beta2');
|
||||
case '5_0': $this->saveLogs('Execute 5_0');
|
||||
case '5_1': $this->saveLogs('Execute 5_1');
|
||||
case '5_2': $this->saveLogs('Execute 5_2');
|
||||
$this->appendExec('4_3_beta');
|
||||
case '5_0_beta1':
|
||||
$this->saveLogs('Execute 5_0_beta1');
|
||||
$this->appendExec('5_0_beta1');
|
||||
case '5_0_beta2':
|
||||
$this->saveLogs('Execute 5_0_beta2');
|
||||
$this->appendExec('5_0_beta2');
|
||||
case '5_0':
|
||||
$this->saveLogs('Execute 5_0');
|
||||
$this->appendExec('5_0');
|
||||
case '5_1':
|
||||
$this->saveLogs('Execute 5_1');
|
||||
$this->appendExec('5_1');
|
||||
case '5_2':
|
||||
$this->saveLogs('Execute 5_2');
|
||||
$this->appendExec('5_2');
|
||||
case '5_2_1':
|
||||
$this->saveLogs('Execute 5_2_1');
|
||||
$this->mergeProjectGoalAndDesc();
|
||||
$this->execSQL($this->getUpgradeFile('5.2.1'));
|
||||
case '5_3': $this->saveLogs('Execute 5_3');
|
||||
$this->appendExec('5_2_1');
|
||||
case '5_3':
|
||||
$this->saveLogs('Execute 5_3');
|
||||
$this->appendExec('5_3');
|
||||
case '6_0_beta1':
|
||||
$this->saveLogs('Execute 6_0_beta');
|
||||
$this->execSQL($this->getUpgradeFile('6.0.beta1'));
|
||||
$this->toLowerTable();
|
||||
$this->fixBugOSInfo();
|
||||
$this->fixTaskFinishedBy();
|
||||
$this->appendExec('6_0_beta1');
|
||||
case '6_0':
|
||||
$this->saveLogs('Execute 6_0');
|
||||
$this->execSQL($this->getUpgradeFile('6.0'));
|
||||
$this->fixDataIndex();
|
||||
$this->appendExec('6_0');
|
||||
case '6_1':
|
||||
$this->saveLogs('Execute 6_1');
|
||||
$this->execSQL($this->getUpgradeFile('6.1'));
|
||||
case '6_2': $this->saveLogs('Execute 6_2');
|
||||
case '6_3': $this->saveLogs('Execute 6_3');
|
||||
case '6_4': $this->saveLogs('Execute 6_4');
|
||||
$this->appendExec('6_1');
|
||||
case '6_2':
|
||||
$this->saveLogs('Execute 6_2');
|
||||
$this->appendExec('6_2');
|
||||
case '6_3':
|
||||
$this->saveLogs('Execute 6_3');
|
||||
$this->appendExec('6_3');
|
||||
case '6_4':
|
||||
$this->saveLogs('Execute 6_4');
|
||||
$this->appendExec('6_4');
|
||||
case '7_0':
|
||||
$this->saveLogs('Execute 7_0');
|
||||
$this->execSQL($this->getUpgradeFile('7.0'));
|
||||
$this->appendExec('7_0');
|
||||
case '7_1':
|
||||
$this->saveLogs('Execute 7_1');
|
||||
$this->execSQL($this->getUpgradeFile('7.1'));
|
||||
$this->initOrder();
|
||||
case '7_2': $this->saveLogs('Execute 7_2');
|
||||
$this->appendExec('7_1');
|
||||
case '7_2':
|
||||
$this->saveLogs('Execute 7_2');
|
||||
$this->appendExec('7_2');
|
||||
case '7_2_4':
|
||||
$this->saveLogs('Execute 7_2_4');
|
||||
$this->execSQL($this->getUpgradeFile('7.2.4'));
|
||||
$this->appendExec('7_2_4');
|
||||
case '7_2_5':
|
||||
$this->saveLogs('Execute 7_2_5');
|
||||
$this->adjustOrder7_3();
|
||||
$this->appendExec('7_2_5');
|
||||
case '7_3':
|
||||
$this->saveLogs('Execute 7_3');
|
||||
$this->execSQL($this->getUpgradeFile('7.3'));
|
||||
$this->adjustPriv7_4_beta();
|
||||
$this->appendExec('7_3');
|
||||
case '7_4_beta':
|
||||
$this->saveLogs('Execute 7_4_beta');
|
||||
$this->execSQL($this->getUpgradeFile('7.4.beta'));
|
||||
case '8_0': $this->saveLogs('Execute 8_0');
|
||||
$this->appendExec('7_4_beta');
|
||||
case '8_0':
|
||||
$this->saveLogs('Execute 8_0');
|
||||
$this->appendExec('8_0');
|
||||
case '8_0_1':
|
||||
$this->saveLogs('Execute 8_0_1');
|
||||
$this->execSQL($this->getUpgradeFile('8.0.1'));
|
||||
$this->addPriv8_1();
|
||||
$this->appendExec('8_0_1');
|
||||
case '8_1':
|
||||
$this->saveLogs('Execute 8_1');
|
||||
$this->execSQL($this->getUpgradeFile('8.1'));
|
||||
$this->appendExec('8_1');
|
||||
case '8_1_3':
|
||||
$this->saveLogs('Execute 8_1_3');
|
||||
$this->execSQL($this->getUpgradeFile('8.1.3'));
|
||||
$this->addPriv8_2_beta();
|
||||
$this->adjustConfigSectionAndKey();
|
||||
case '8_2_beta': $this->saveLogs('Execute 8_2_beta');
|
||||
case '8_2': $this->saveLogs('Execute 8_2');
|
||||
$this->appendExec('8_1_3');
|
||||
case '8_2_beta':
|
||||
$this->saveLogs('Execute 8_2_beta');
|
||||
$this->appendExec('8_2_beta');
|
||||
case '8_2':
|
||||
$this->saveLogs('Execute 8_2');
|
||||
$this->appendExec('8_2');
|
||||
case '8_2_1':
|
||||
$this->saveLogs('Execute 8_2_1');
|
||||
$this->execSQL($this->getUpgradeFile('8.2.1'));
|
||||
case '8_2_2': $this->saveLogs('Execute 8_2_2');
|
||||
case '8_2_3': $this->saveLogs('Execute 8_2_3');
|
||||
case '8_2_4': $this->saveLogs('Execute 8_2_4');
|
||||
case '8_2_5': $this->saveLogs('Execute 8_2_5');
|
||||
$this->appendExec('8_2_1');
|
||||
case '8_2_2':
|
||||
$this->saveLogs('Execute 8_2_2');
|
||||
$this->appendExec('8_2_2');
|
||||
case '8_2_3':
|
||||
$this->saveLogs('Execute 8_2_3');
|
||||
$this->appendExec('8_2_3');
|
||||
case '8_2_4':
|
||||
$this->saveLogs('Execute 8_2_4');
|
||||
$this->appendExec('8_2_4');
|
||||
case '8_2_5':
|
||||
$this->saveLogs('Execute 8_2_5');
|
||||
$this->appendExec('8_2_5');
|
||||
case '8_2_6':
|
||||
$this->saveLogs('Execute 8_2_6');
|
||||
$this->execSQL($this->getUpgradeFile('8.2.6'));
|
||||
$this->adjustDocModule();
|
||||
$this->moveDocContent();
|
||||
$this->adjustPriv8_3();
|
||||
case '8_3': $this->saveLogs('Execute 8_3');
|
||||
$this->appendExec('8_2_6');
|
||||
case '8_3':
|
||||
$this->saveLogs('Execute 8_3');
|
||||
$this->appendExec('8_3');
|
||||
case '8_3_1':
|
||||
$this->saveLogs('Execute 8_3_1');
|
||||
$this->execSQL($this->getUpgradeFile('8.3.1'));
|
||||
$this->renameMainLib();
|
||||
$this->adjustPriv8_4();
|
||||
case '8_4': $this->saveLogs('Execute 8_4');
|
||||
$this->appendExec('8_3_1');
|
||||
case '8_4':
|
||||
$this->saveLogs('Execute 8_4');
|
||||
$this->appendExec('8_4');
|
||||
case '8_4_1':
|
||||
$this->saveLogs('Execute 8_4_1');
|
||||
$this->execSQL($this->getUpgradeFile('8.4.1'));
|
||||
$this->appendExec('8_4_1');
|
||||
case '9_0_beta':
|
||||
$this->saveLogs('Execute 9_0_beta');
|
||||
$this->execSQL($this->getUpgradeFile('9.0.beta'));
|
||||
$this->adjustPriv9_0();
|
||||
$this->appendExec('9_0_beta');
|
||||
case '9_0':
|
||||
$this->saveLogs('Execute 9_0');
|
||||
$this->fixProjectProductData();
|
||||
$this->appendExec('9_0');
|
||||
case '9_0_1':
|
||||
$this->saveLogs('Execute 9_0_1');
|
||||
$this->execSQL($this->getUpgradeFile('9.0.1'));
|
||||
$this->addBugDeadlineToCustomFields();
|
||||
$this->adjustPriv9_0_1();
|
||||
$this->appendExec('9_0_1');
|
||||
case '9_1':
|
||||
$this->saveLogs('Execute 9_1');
|
||||
$this->execSQL($this->getUpgradeFile('9.1'));
|
||||
$this->appendExec('9_1');
|
||||
case '9_1_1':
|
||||
$this->saveLogs('Execute 9_1_1');
|
||||
$this->execSQL($this->getUpgradeFile('9.1.1'));
|
||||
$this->appendExec('9_1_1');
|
||||
case '9_1_2':
|
||||
$this->saveLogs('Execute 9_1_2');
|
||||
$this->execSQL($this->getUpgradeFile('9.1.2'));
|
||||
$this->processCustomMenus();
|
||||
$this->adjustPriv9_2();
|
||||
case '9_2': $this->saveLogs('Execute 9_2');
|
||||
case '9_2_1': $this->saveLogs('Execute 9_2_1');
|
||||
$this->appendExec('9_1_2');
|
||||
case '9_2':
|
||||
$this->saveLogs('Execute 9_2');
|
||||
$this->appendExec('9_2');
|
||||
case '9_2_1':
|
||||
$this->saveLogs('Execute 9_2_1');
|
||||
$this->appendExec('9_2_1');
|
||||
case '9_3_beta':
|
||||
$this->saveLogs('Execute 9_3_beta');
|
||||
$this->execSQL($this->getUpgradeFile('9.3.beta'));
|
||||
$this->appendExec('9_3_beta');
|
||||
case '9_4':
|
||||
$this->saveLogs('Execute 9_4');
|
||||
$this->execSQL($this->getUpgradeFile('9.4'));
|
||||
$this->adjustPriv9_4();
|
||||
$this->appendExec('9_4');
|
||||
case '9_5':
|
||||
$this->saveLogs('Execute 9_5');
|
||||
$this->execSQL($this->getUpgradeFile('9.5'));
|
||||
$this->appendExec('9_5');
|
||||
case '9_5_1':
|
||||
$this->saveLogs('Execute 9_5_1');
|
||||
$this->execSQL($this->getUpgradeFile('9.5.1'));
|
||||
$this->initProjectStoryOrder();
|
||||
$this->appendExec('9_5_1');
|
||||
case '9_6':
|
||||
$this->saveLogs('Execute 9_6');
|
||||
$this->execSQL($this->getUpgradeFile('9.6'));
|
||||
$this->fixDatatableColsConfig();
|
||||
$this->appendExec('9_6');
|
||||
case '9_6_1':
|
||||
$this->saveLogs('Execute 9_6_1');
|
||||
$this->addLimitedGroup();
|
||||
case '9_6_2': $this->saveLogs('Execute 9_6_2');
|
||||
$this->appendExec('9_6_1');
|
||||
case '9_6_2':
|
||||
$this->saveLogs('Execute 9_6_2');
|
||||
$this->appendExec('9_6_2');
|
||||
case '9_6_3':
|
||||
$this->saveLogs('Execute 9_6_3');
|
||||
$this->execSQL($this->getUpgradeFile('9.6.3'));
|
||||
$this->changeLimitedName();
|
||||
$this->adjustPriv9_7();
|
||||
$this->changeStoryWidth();
|
||||
$this->appendExec('9_6_3');
|
||||
case '9_7':
|
||||
$this->saveLogs('Execute 9_7');
|
||||
$this->execSQL($this->getUpgradeFile('9.7'));
|
||||
$this->changeTeamFields();
|
||||
$this->moveData2Notify();
|
||||
$this->appendExec('9_7');
|
||||
case '9_8':
|
||||
$this->saveLogs('Execute 9_8');
|
||||
$this->fixTaskFinishedInfo();
|
||||
$this->appendExec('9_8');
|
||||
case '9_8_1':
|
||||
$this->saveLogs('Execute 9_8_1');
|
||||
$this->execSQL($this->getUpgradeFile('9.8.1'));
|
||||
$this->fixTaskAssignedTo();
|
||||
$this->fixProjectClosedInfo();
|
||||
$this->resetProductLine();
|
||||
$this->appendExec('9_8_1');
|
||||
case '9_8_2':
|
||||
$this->saveLogs('Execute 9_8_2');
|
||||
$this->execSQL($this->getUpgradeFile('9.8.2'));
|
||||
$this->addUniqueKeyToTeam();
|
||||
$this->appendExec('9_8_2');
|
||||
case '9_8_3':
|
||||
$this->saveLogs('Execute 9_8_3');
|
||||
$this->execSQL($this->getUpgradeFile('9.8.3'));
|
||||
$this->adjustPriv10_0_alpha();
|
||||
$this->appendExec('9_8_3');
|
||||
case '10_0_alpha':
|
||||
$this->saveLogs('Execute 10_0_alpha');
|
||||
$this->execSQL($this->getUpgradeFile('10.0.alpha'));
|
||||
$this->fixProjectStatisticBlock();
|
||||
$this->appendExec('10_0_alpha');
|
||||
case '10_0_beta':
|
||||
$this->saveLogs('Execute 10_0_beta');
|
||||
$this->execSQL($this->getUpgradeFile('10.0.beta'));
|
||||
$this->appendExec('10_0_beta');
|
||||
case '10_0':
|
||||
$this->saveLogs('Execute 10_0');
|
||||
$this->execSQL($this->getUpgradeFile('10.0'));
|
||||
$this->fixStorySpecTitle();
|
||||
$this->removeUnlinkPriv();//Remove unlink privilege for story, bug and testcase module.
|
||||
$this->appendExec('10_0');
|
||||
case '10_1':
|
||||
$this->saveLogs('Execute 10_1');
|
||||
$xuanxuanSql = $this->app->getAppRoot() . 'db' . DS . 'xuanxuan.sql';
|
||||
$this->execSQL($xuanxuanSql);
|
||||
$executeXuanxuan = true;
|
||||
case '10_2': $this->saveLogs('Execute 10_2');
|
||||
case '10_3': $this->saveLogs('Execute 10_3');
|
||||
$this->appendExec('10_1');
|
||||
case '10_2':
|
||||
$this->saveLogs('Execute 10_2');
|
||||
$this->appendExec('10_2');
|
||||
case '10_3':
|
||||
$this->saveLogs('Execute 10_3');
|
||||
$this->appendExec('10_3');
|
||||
case '10_3_1':
|
||||
$this->saveLogs('Execute 10_3_1');
|
||||
$this->execSQL($this->getUpgradeFile('10.3.1'));
|
||||
$this->removeCustomMenu();
|
||||
$this->initUserView();
|
||||
$this->appendExec('10_3_1');
|
||||
case '10_4':
|
||||
$this->saveLogs('Execute 10_4');
|
||||
$this->execSQL($this->getUpgradeFile('10.4'));
|
||||
$this->changeTaskParentValue();
|
||||
case '10_5': $this->saveLogs('Execute 10_5');
|
||||
$this->appendExec('10_4');
|
||||
case '10_5':
|
||||
$this->saveLogs('Execute 10_5');
|
||||
$this->appendExec('10_5');
|
||||
case '10_5_1':
|
||||
$this->saveLogs('Execute 10_5_1');
|
||||
$this->execSQL($this->getUpgradeFile('10.5.1'));
|
||||
$this->appendExec('10_5_1');
|
||||
case '10_6':
|
||||
$this->saveLogs('Execute 10_6');
|
||||
if(!$executeXuanxuan)
|
||||
@@ -349,7 +452,10 @@ class upgradeModel extends model
|
||||
$this->execSQL($xuanxuanSql);
|
||||
}
|
||||
$this->initXuanxuan();
|
||||
case '11_0': $this->saveLogs('Execute 11_0');
|
||||
$this->appendExec('10_6');
|
||||
case '11_0':
|
||||
$this->saveLogs('Execute 11_0');
|
||||
$this->appendExec('11_0');
|
||||
case '11_1':
|
||||
$this->saveLogs('Execute 11_1');
|
||||
$this->execSQL($this->getUpgradeFile('11.1'));
|
||||
@@ -363,17 +469,21 @@ class upgradeModel extends model
|
||||
$this->dao->update(TABLE_CONFIG)->set('value')->eq('off')->where('`key`')->eq('isHttps')->andWhere('`section`')->eq('xuanxuan')->andWhere('`value`')->eq('0')->exec();
|
||||
$this->dao->update(TABLE_CONFIG)->set('value')->eq('on')->where('`key`')->eq('isHttps')->andWhere('`section`')->eq('xuanxuan')->andWhere('`value`')->eq('1')->exec();
|
||||
}
|
||||
$this->appendExec('11_1');
|
||||
case '11_2':
|
||||
$this->saveLogs('Execute 11_2');
|
||||
$this->execSQL($this->getUpgradeFile('11.2'));
|
||||
$this->processDocLibAcl();
|
||||
$this->appendExec('11_2');
|
||||
case '11_3':
|
||||
$this->saveLogs('Execute 11_3');
|
||||
$this->execSQL($this->getUpgradeFile('11.3'));
|
||||
$this->addPriv11_4();
|
||||
$this->appendExec('11_3');
|
||||
case '11_4':
|
||||
$this->saveLogs('Execute 11_4');
|
||||
$this->execSQL($this->getUpgradeFile('11.4'));
|
||||
$this->appendExec('11_4');
|
||||
case '11_4_1':
|
||||
$this->saveLogs('Execute 11_4_1');
|
||||
$this->execSQL($this->getUpgradeFile('11.4.1'));
|
||||
@@ -389,20 +499,30 @@ class upgradeModel extends model
|
||||
}
|
||||
$this->updateXX_11_5();
|
||||
}
|
||||
$this->appendExec('11_4_1');
|
||||
case '11_5':
|
||||
$this->saveLogs('Execute 11_5');
|
||||
$this->execSQL($this->getUpgradeFile('11.5'));
|
||||
$this->appendExec('11_5');
|
||||
case '11_5_1':
|
||||
$this->saveLogs('Execute 11_5_1');
|
||||
$this->appendExec('11_5_1');
|
||||
case '11_5_2':
|
||||
$this->saveLogs('Execute 11_5_2');
|
||||
$this->execSQL($this->getUpgradeFile('11.5.2'));
|
||||
$this->appendExec('11_5_2');
|
||||
case '11_6':
|
||||
$this->saveLogs('Execute 11_6');
|
||||
$this->execSQL($this->getUpgradeFile('11.6'));
|
||||
$this->appendExec('11_6');
|
||||
case '11_6_1':
|
||||
$this->saveLogs('Execute 11_6_1');
|
||||
$this->adjustWebhookType();
|
||||
$this->adjustPriv11_6_2();
|
||||
$this->appendExec('11_6_1');
|
||||
case '11_6_2':
|
||||
$this->saveLogs('Execute 11_6_2');
|
||||
$this->appendExec('11_6_2');
|
||||
}
|
||||
|
||||
$this->deletePatch();
|
||||
@@ -547,7 +667,9 @@ class upgradeModel extends model
|
||||
case '11_5' : $confirmContent .= file_get_contents($this->getUpgradeFile('11.5'));
|
||||
case '11_5_1' :
|
||||
case '11_5_2' : $confirmContent .= file_get_contents($this->getUpgradeFile('11.5.2'));
|
||||
case '11_6' : $confirmContent .= file_get_contents($this->getUpgradeFile('11.6'));
|
||||
case '11_6' : $confirmContent .= file_get_contents($this->getUpgradeFile('11.6'));
|
||||
case '11_6_1' :
|
||||
case '11_6_2' :
|
||||
}
|
||||
return str_replace('zt_', $this->config->db->prefix, $confirmContent);
|
||||
}
|
||||
@@ -3199,6 +3321,45 @@ class upgradeModel extends model
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust priv for 11.6.4.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function adjustPriv11_6_4()
|
||||
{
|
||||
$this->saveLogs('Run Method ' . __FUNCTION__);
|
||||
|
||||
$this->dao->update(TABLE_GROUPPRIV)->set('module')->eq('caselib')->set('method')->eq('browse')->where('module')->eq('testsuite')->andWhere('method')->eq('library')->exec();
|
||||
$this->dao->update(TABLE_GROUPPRIV)->set('module')->eq('caselib')->set('method')->eq('create')->where('module')->eq('testsuite')->andWhere('method')->eq('createLib')->exec();
|
||||
$this->dao->update(TABLE_GROUPPRIV)->set('module')->eq('caselib')->set('method')->eq('view')->where('module')->eq('testsuite')->andWhere('method')->eq('libView')->exec();
|
||||
$this->dao->update(TABLE_GROUPPRIV)->set('module')->eq('caselib')->where('module')->eq('testsuite')->andWhere('method')->in('exportTemplet,import,showImport,batchCreateCase,createCase')->exec();
|
||||
|
||||
$groups = $this->dao->select('*')->from(TABLE_GROUPPRIV)->where('module')->eq('testsuite')->andWhere('method')->eq('edit')->fetchPairs('group', 'group');
|
||||
foreach($groups as $groupID)
|
||||
{
|
||||
$groupPriv = new stdclass();
|
||||
$groupPriv->group = $groupID;
|
||||
$groupPriv->module = 'caselib';
|
||||
$groupPriv->method = 'edit';
|
||||
$this->dao->replace(TABLE_GROUPPRIV)->data($groupPriv)->exec();
|
||||
$this->saveLogs($this->dao->get());
|
||||
}
|
||||
|
||||
$groups = $this->dao->select('*')->from(TABLE_GROUPPRIV)->where('module')->eq('testsuite')->andWhere('method')->eq('delete')->fetchPairs('group', 'group');
|
||||
foreach($groups as $groupID)
|
||||
{
|
||||
$groupPriv = new stdclass();
|
||||
$groupPriv->group = $groupID;
|
||||
$groupPriv->module = 'caselib';
|
||||
$groupPriv->method = 'delete';
|
||||
$this->dao->replace(TABLE_GROUPPRIV)->data($groupPriv)->exec();
|
||||
$this->saveLogs($this->dao->get());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Logs.
|
||||
*
|
||||
@@ -3216,4 +3377,15 @@ class upgradeModel extends model
|
||||
if(empty($fh)) $fh = fopen($logFile, 'a');
|
||||
fwrite($fh, $log);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append execute for pro and biz.
|
||||
*
|
||||
* @param string $fromVersion
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function appendExec($zentaoVersion)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
+22
-3
@@ -846,8 +846,25 @@ class user extends control
|
||||
$this->view->refererBeforeDeny = $refererBeforeDeny; // The referer of the denied page.
|
||||
$this->app->loadLang($module);
|
||||
$this->app->loadLang('my');
|
||||
$this->display();
|
||||
exit;
|
||||
|
||||
/* Check deny type. */
|
||||
$rights = $this->app->user->rights['rights'];
|
||||
$acls = $this->app->user->rights['acls'];
|
||||
$module = strtolower($module);
|
||||
$method = strtolower($method);
|
||||
|
||||
$denyType = 'nopriv';
|
||||
if(isset($rights[$module][$method]))
|
||||
{
|
||||
$menu = isset($this->lang->menugroup->$module) ? $this->lang->menugroup->$module : $module;
|
||||
$menu = strtolower($menu);
|
||||
|
||||
if(!isset($acls['views'][$menu])) $denyType = 'noview';
|
||||
$this->view->menu = $menu;
|
||||
}
|
||||
$this->view->denyType = $denyType;
|
||||
|
||||
die($this->display());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1052,7 +1069,9 @@ class user extends control
|
||||
*/
|
||||
public function ajaxDeleteTemplate($templateID)
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_USERTPL)->where('id')->eq($templateID)->andWhere('account')->eq($this->app->user->account)->exec();
|
||||
$this->dao->delete()->from(TABLE_USERTPL)->where('id')->eq($templateID)
|
||||
->beginIF(!$this->app->user->admin)->andWhere('account')->eq($this->app->user->account)->fi()
|
||||
->exec();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ $lang->user->case2Him = '给%s的用例';
|
||||
$lang->user->caseByHim = '%s建的用例';
|
||||
|
||||
$lang->user->errorDeny = "抱歉,您无权访问『<b>%s</b>』模块的『<b>%s</b>』功能。请联系管理员获取权限。点击后退返回上页。";
|
||||
$lang->user->errorView = "抱歉,您无权访问『<b>%s</b>』视图。请联系管理员获取权限。点击后退返回上页。";
|
||||
$lang->user->loginFailed = "登录失败,请检查您的用户名或密码是否填写正确。";
|
||||
$lang->user->lockWarning = "您还有%s次尝试机会。";
|
||||
$lang->user->loginLocked = "密码尝试次数太多,请联系管理员解锁,或%s分钟后重试。";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user