diff --git a/db/update17.5.sql b/db/update17.5.sql new file mode 100644 index 0000000000..bd9371892f --- /dev/null +++ b/db/update17.5.sql @@ -0,0 +1,249 @@ +ALTER TABLE `zt_bug` MODIFY COLUMN `os` varchar(255) NOT NULL default ''; +ALTER TABLE `zt_bug` MODIFY COLUMN `browser` varchar(255) NOT NULL default ''; + +INSERT IGNORE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`, `vision`) VALUES +('zh-cn', 'bug', 'browserList', 'all', '全部', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'chrome', 'Chrome', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'edge', 'Edge', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'ie', 'IE系列', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'ie11', 'IE11', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'ie10', 'IE10', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'ie9', 'IE9', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'ie8', 'IE8', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'ie7', 'IE7', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'ie6', 'IE6', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'firefox', 'firefox系列', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'firefox4', 'firefox4', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'firefox3', 'firefox3', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'firefox2', 'firefox2', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'opera', 'Opera系列', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'opera11', 'opera11', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'opera10', 'opera10', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'opera9', 'opera9', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'safari', 'safari', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', '360', '360浏览器', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'qq', 'QQ浏览器', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'maxthon', '遨游', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'uc', 'UC', '1', 'rnd'), +('zh-cn', 'bug', 'browserList', 'other', '其他', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'all', '全部', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'chrome', 'Chrome', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'edge', 'Edge', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'ie', 'IE系列', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'ie11', 'IE11', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'ie10', 'IE10', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'ie9', 'IE9', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'ie8', 'IE8', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'ie7', 'IE7', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'ie6', 'IE6', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'firefox', 'firefox系列', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'firefox4', 'firefox4', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'firefox3', 'firefox3', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'firefox2', 'firefox2', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'opera', 'Opera系列', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'opera11', 'opera11', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'opera10', 'opera10', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'opera9', 'opera9', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'safari', 'safari', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', '360', '360瀏覽器', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'qq', 'QQ瀏覽器', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'maxthon', '遨游', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'uc', 'UC', '1', 'rnd'), +('zh-tw', 'bug', 'browserList', 'other', '其他', '1', 'rnd'), +('en', 'bug', 'browserList', 'all', 'All', '1', 'rnd'), +('en', 'bug', 'browserList', 'chrome', 'Chrome', '1', 'rnd'), +('en', 'bug', 'browserList', 'edge', 'Edge', '1', 'rnd'), +('en', 'bug', 'browserList', 'ie', 'IE series', '1', 'rnd'), +('en', 'bug', 'browserList', 'ie11', 'IE11', '1', 'rnd'), +('en', 'bug', 'browserList', 'ie10', 'IE10', '1', 'rnd'), +('en', 'bug', 'browserList', 'ie9', 'IE9', '1', 'rnd'), +('en', 'bug', 'browserList', 'ie8', 'IE8', '1', 'rnd'), +('en', 'bug', 'browserList', 'ie7', 'IE7', '1', 'rnd'), +('en', 'bug', 'browserList', 'ie6', 'IE6', '1', 'rnd'), +('en', 'bug', 'browserList', 'firefox', 'Firefox series', '1', 'rnd'), +('en', 'bug', 'browserList', 'firefox4', 'Firefox4', '1', 'rnd'), +('en', 'bug', 'browserList', 'firefox3', 'Firefox3', '1', 'rnd'), +('en', 'bug', 'browserList', 'firefox2', 'Firefox2', '1', 'rnd'), +('en', 'bug', 'browserList', 'opera', 'Opera series', '1', 'rnd'), +('en', 'bug', 'browserList', 'opera11', 'Opera11', '1', 'rnd'), +('en', 'bug', 'browserList', 'opera10', 'Opera10', '1', 'rnd'), +('en', 'bug', 'browserList', 'opera9', 'Opera9', '1', 'rnd'), +('en', 'bug', 'browserList', 'safari', 'Safari', '1', 'rnd'), +('en', 'bug', 'browserList', '360', '360', '1', 'rnd'), +('en', 'bug', 'browserList', 'qq', 'QQ', '1', 'rnd'), +('en', 'bug', 'browserList', 'maxthon', 'Maxthon', '1', 'rnd'), +('en', 'bug', 'browserList', 'uc', 'UC', '1', 'rnd'), +('en', 'bug', 'browserList', 'other', 'Others', '1', 'rnd'), +('fr', 'bug', 'browserList', 'all', 'Tous', '1', 'rnd'), +('fr', 'bug', 'browserList', 'chrome', 'Chrome', '1', 'rnd'), +('fr', 'bug', 'browserList', 'edge', 'Edge', '1', 'rnd'), +('fr', 'bug', 'browserList', 'ie', 'IE series', '1', 'rnd'), +('fr', 'bug', 'browserList', 'ie11', 'IE11', '1', 'rnd'), +('fr', 'bug', 'browserList', 'ie10', 'IE10', '1', 'rnd'), +('fr', 'bug', 'browserList', 'ie9', 'IE9', '1', 'rnd'), +('fr', 'bug', 'browserList', 'ie8', 'IE8', '1', 'rnd'), +('fr', 'bug', 'browserList', 'ie7', 'IE7', '1', 'rnd'), +('fr', 'bug', 'browserList', 'ie6', 'IE6', '1', 'rnd'), +('fr', 'bug', 'browserList', 'firefox', 'Firefox series', '1', 'rnd'), +('fr', 'bug', 'browserList', 'firefox4', 'Firefox4', '1', 'rnd'), +('fr', 'bug', 'browserList', 'firefox3', 'Firefox3', '1', 'rnd'), +('fr', 'bug', 'browserList', 'firefox2', 'Firefox2', '1', 'rnd'), +('fr', 'bug', 'browserList', 'opera', 'Opera series', '1', 'rnd'), +('fr', 'bug', 'browserList', 'opera11', 'Opera11', '1', 'rnd'), +('fr', 'bug', 'browserList', 'opera10', 'Opera10', '1', 'rnd'), +('fr', 'bug', 'browserList', 'opera9', 'Opera9', '1', 'rnd'), +('fr', 'bug', 'browserList', 'safari', 'Safari', '1', 'rnd'), +('fr', 'bug', 'browserList', '360', '360', '1', 'rnd'), +('fr', 'bug', 'browserList', 'qq', 'QQ', '1', 'rnd'), +('fr', 'bug', 'browserList', 'maxthon', 'Maxthon', '1', 'rnd'), +('fr', 'bug', 'browserList', 'uc', 'UC', '1', 'rnd'), +('fr', 'bug', 'browserList', 'other', 'Autres', '1', 'rnd'), +('de', 'bug', 'browserList', 'all', 'Alle', '1', 'rnd'), +('de', 'bug', 'browserList', 'chrome', 'Chrome', '1', 'rnd'), +('de', 'bug', 'browserList', 'edge', 'Edge', '1', 'rnd'), +('de', 'bug', 'browserList', 'ie', 'IE series', '1', 'rnd'), +('de', 'bug', 'browserList', 'ie11', 'IE11', '1', 'rnd'), +('de', 'bug', 'browserList', 'ie10', 'IE10', '1', 'rnd'), +('de', 'bug', 'browserList', 'ie9', 'IE9', '1', 'rnd'), +('de', 'bug', 'browserList', 'ie8', 'IE8', '1', 'rnd'), +('de', 'bug', 'browserList', 'ie7', 'IE7', '1', 'rnd'), +('de', 'bug', 'browserList', 'ie6', 'IE6', '1', 'rnd'), +('de', 'bug', 'browserList', 'firefox', 'Firefox series', '1', 'rnd'), +('de', 'bug', 'browserList', 'firefox4', 'Firefox4', '1', 'rnd'), +('de', 'bug', 'browserList', 'firefox3', 'Firefox3', '1', 'rnd'), +('de', 'bug', 'browserList', 'firefox2', 'Firefox2', '1', 'rnd'), +('de', 'bug', 'browserList', 'opera', 'Opera series', '1', 'rnd'), +('de', 'bug', 'browserList', 'opera11', 'Opera11', '1', 'rnd'), +('de', 'bug', 'browserList', 'opera10', 'Opera10', '1', 'rnd'), +('de', 'bug', 'browserList', 'opera9', 'Opera9', '1', 'rnd'), +('de', 'bug', 'browserList', 'safari', 'Safari', '1', 'rnd'), +('de', 'bug', 'browserList', '360', '360', '1', 'rnd'), +('de', 'bug', 'browserList', 'qq', 'QQ', '1', 'rnd'), +('de', 'bug', 'browserList', 'maxthon', 'Maxthon', '1', 'rnd'), +('de', 'bug', 'browserList', 'uc', 'UC', '1', 'rnd'), +('de', 'bug', 'browserList', 'other', 'Andere', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'all', '全部', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'windows', 'Windows', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'win11', 'Windows 11', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'win10', 'Windows 10', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'win8', 'Windows 8', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'win7', 'Windows 7', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'winxp', 'Windows XP', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'osx', 'Mac OS', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'android', 'Android', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'ios', 'IOS', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'linux', 'Linux', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'ubuntu', 'Ubuntu', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'chromeos', 'Chrome OS', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'fedora', 'Fedora', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'vista', 'Windows Vista', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'win2012', 'Windows 2012', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'win2008', 'Windows 2008', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'win2003', 'Windows 2003', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'win2000', 'Windows 2000', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'wp8', 'WP8', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'wp7', 'WP7', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'symbian', 'Symbian', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'freebsd', 'FreeBSD', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'unix', 'Unix', '1', 'rnd'), +('zh-cn', 'bug', 'osList', 'others', '其他', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'all', '全部', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'windows', 'Windows', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'win11', 'Windows 11', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'win10', 'Windows 10', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'win8', 'Windows 8', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'win7', 'Windows 7', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'winxp', 'Windows XP', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'osx', 'Mac OS', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'android', 'Android', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'ios', 'IOS', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'linux', 'Linux', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'ubuntu', 'Ubuntu', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'chromeos', 'Chrome OS', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'fedora', 'Fedora', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'vista', 'Windows Vista', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'win2012', 'Windows 2012', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'win2008', 'Windows 2008', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'win2003', 'Windows 2003', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'win2000', 'Windows 2000', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'wp8', 'WP8', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'wp7', 'WP7', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'symbian', 'Symbian', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'freebsd', 'FreeBSD', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'unix', 'Unix', '1', 'rnd'), +('zh-tw', 'bug', 'osList', 'others', '其他', '1', 'rnd'), +('en', 'bug', 'osList', 'all', 'All', '1', 'rnd'), +('en', 'bug', 'osList', 'windows', 'Windows', '1', 'rnd'), +('en', 'bug', 'osList', 'win11', 'Windows 11', '1', 'rnd'), +('en', 'bug', 'osList', 'win10', 'Windows 10', '1', 'rnd'), +('en', 'bug', 'osList', 'win8', 'Windows 8', '1', 'rnd'), +('en', 'bug', 'osList', 'win7', 'Windows 7', '1', 'rnd'), +('en', 'bug', 'osList', 'winxp', 'Windows XP', '1', 'rnd'), +('en', 'bug', 'osList', 'osx', 'Mac OS', '1', 'rnd'), +('en', 'bug', 'osList', 'android', 'Android', '1', 'rnd'), +('en', 'bug', 'osList', 'ios', 'IOS', '1', 'rnd'), +('en', 'bug', 'osList', 'linux', 'Linux', '1', 'rnd'), +('en', 'bug', 'osList', 'ubuntu', 'Ubuntu', '1', 'rnd'), +('en', 'bug', 'osList', 'chromeos', 'Chrome OS', '1', 'rnd'), +('en', 'bug', 'osList', 'fedora', 'Fedora', '1', 'rnd'), +('en', 'bug', 'osList', 'vista', 'Windows Vista', '1', 'rnd'), +('en', 'bug', 'osList', 'win2012', 'Windows 2012', '1', 'rnd'), +('en', 'bug', 'osList', 'win2008', 'Windows 2008', '1', 'rnd'), +('en', 'bug', 'osList', 'win2003', 'Windows 2003', '1', 'rnd'), +('en', 'bug', 'osList', 'win2000', 'Windows 2000', '1', 'rnd'), +('en', 'bug', 'osList', 'wp8', 'WP8', '1', 'rnd'), +('en', 'bug', 'osList', 'wp7', 'WP7', '1', 'rnd'), +('en', 'bug', 'osList', 'symbian', 'Symbian', '1', 'rnd'), +('en', 'bug', 'osList', 'freebsd', 'FreeBSD', '1', 'rnd'), +('en', 'bug', 'osList', 'unix', 'Unix', '1', 'rnd'), +('en', 'bug', 'osList', 'others', 'Others', '1', 'rnd'), +('fr', 'bug', 'osList', 'all', 'Tous', '1', 'rnd'), +('fr', 'bug', 'osList', 'windows', 'Windows', '1', 'rnd'), +('fr', 'bug', 'osList', 'win11', 'Windows 11', '1', 'rnd'), +('fr', 'bug', 'osList', 'win10', 'Windows 10', '1', 'rnd'), +('fr', 'bug', 'osList', 'win8', 'Windows 8', '1', 'rnd'), +('fr', 'bug', 'osList', 'win7', 'Windows 7', '1', 'rnd'), +('fr', 'bug', 'osList', 'winxp', 'Windows XP', '1', 'rnd'), +('fr', 'bug', 'osList', 'osx', 'Mac OS', '1', 'rnd'), +('fr', 'bug', 'osList', 'android', 'Android', '1', 'rnd'), +('fr', 'bug', 'osList', 'ios', 'IOS', '1', 'rnd'), +('fr', 'bug', 'osList', 'linux', 'Linux', '1', 'rnd'), +('fr', 'bug', 'osList', 'ubuntu', 'Ubuntu', '1', 'rnd'), +('fr', 'bug', 'osList', 'chromeos', 'Chrome OS', '1', 'rnd'), +('fr', 'bug', 'osList', 'fedora', 'Fedora', '1', 'rnd'), +('fr', 'bug', 'osList', 'vista', 'Windows Vista', '1', 'rnd'), +('fr', 'bug', 'osList', 'win2012', 'Windows 2012', '1', 'rnd'), +('fr', 'bug', 'osList', 'win2008', 'Windows 2008', '1', 'rnd'), +('fr', 'bug', 'osList', 'win2003', 'Windows 2003', '1', 'rnd'), +('fr', 'bug', 'osList', 'win2000', 'Windows 2000', '1', 'rnd'), +('fr', 'bug', 'osList', 'wp8', 'WP8', '1', 'rnd'), +('fr', 'bug', 'osList', 'wp7', 'WP7', '1', 'rnd'), +('fr', 'bug', 'osList', 'symbian', 'Symbian', '1', 'rnd'), +('fr', 'bug', 'osList', 'freebsd', 'FreeBSD', '1', 'rnd'), +('fr', 'bug', 'osList', 'unix', 'Unix', '1', 'rnd'), +('fr', 'bug', 'osList', 'others', 'Autres', '1', 'rnd'), +('de', 'bug', 'osList', 'all', 'Alle', '1', 'rnd'), +('de', 'bug', 'osList', 'windows', 'Windows', '1', 'rnd'), +('de', 'bug', 'osList', 'win11', 'Windows 11', '1', 'rnd'), +('de', 'bug', 'osList', 'win10', 'Windows 10', '1', 'rnd'), +('de', 'bug', 'osList', 'win8', 'Windows 8', '1', 'rnd'), +('de', 'bug', 'osList', 'win7', 'Windows 7', '1', 'rnd'), +('de', 'bug', 'osList', 'winxp', 'Windows XP', '1', 'rnd'), +('de', 'bug', 'osList', 'osx', 'Mac OS', '1', 'rnd'), +('de', 'bug', 'osList', 'android', 'Android', '1', 'rnd'), +('de', 'bug', 'osList', 'ios', 'IOS', '1', 'rnd'), +('de', 'bug', 'osList', 'linux', 'Linux', '1', 'rnd'), +('de', 'bug', 'osList', 'ubuntu', 'Ubuntu', '1', 'rnd'), +('de', 'bug', 'osList', 'chromeos', 'Chrome OS', '1', 'rnd'), +('de', 'bug', 'osList', 'fedora', 'Fedora', '1', 'rnd'), +('de', 'bug', 'osList', 'vista', 'Windows Vista', '1', 'rnd'), +('de', 'bug', 'osList', 'win2012', 'Windows 2012', '1', 'rnd'), +('de', 'bug', 'osList', 'win2008', 'Windows 2008', '1', 'rnd'), +('de', 'bug', 'osList', 'win2003', 'Windows 2003', '1', 'rnd'), +('de', 'bug', 'osList', 'win2000', 'Windows 2000', '1', 'rnd'), +('de', 'bug', 'osList', 'wp8', 'WP8', '1', 'rnd'), +('de', 'bug', 'osList', 'wp7', 'WP7', '1', 'rnd'), +('de', 'bug', 'osList', 'symbian', 'Symbian', '1', 'rnd'), +('de', 'bug', 'osList', 'freebsd', 'FreeBSD', '1', 'rnd'), +('de', 'bug', 'osList', 'unix', 'Unix', '1', 'rnd'), +('de', 'bug', 'osList', 'others', 'Andere', '1', 'rnd'); diff --git a/db/zentao.sql b/db/zentao.sql index 7bee5678c7..d586ddba19 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -262,8 +262,8 @@ CREATE TABLE IF NOT EXISTS `zt_bug` ( `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 '', + `os` varchar(255) NOT NULL default '', + `browser` varchar(255) NOT NULL default '', `hardware` varchar(30) NOT NULL, `found` varchar(30) NOT NULL default '', `steps` mediumtext NOT NULL, diff --git a/module/action/model.php b/module/action/model.php index 4debe68768..97ee08747b 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -1765,6 +1765,12 @@ class actionModel extends model { $products = $this->product->getProducts($project->id, 'all', '', false); if(!empty($products)) $this->loadModel('user')->updateUserView(array_keys($products), 'product'); + + if($action->objectType == 'execution') + { + $execution = $this->dao->select('id, project, grade, parent, status, deleted')->from(TABLE_EXECUTION)->where('id')->eq($action->objectID)->fetch(); + $this->loadModel('common')->syncExecutionByChild($execution); + } } /* Revert doclib when undelete product or project. */ diff --git a/module/admin/lang/de.php b/module/admin/lang/de.php index 4911a17729..35be329946 100644 --- a/module/admin/lang/de.php +++ b/module/admin/lang/de.php @@ -75,6 +75,7 @@ $lang->admin->safe->checkWeak = 'Schwache Passwörter prüfen'; $lang->admin->safe->changeWeak = 'Ihr Passwort ist schwach. Bitte ändern.'; $lang->admin->safe->loginCaptcha = 'Login using CAPTCHA'; $lang->admin->safe->modifyPasswordFirstLogin = 'Passwort nach der ersten Anmeldung ändern'; +$lang->admin->safe->passwordStrengthWeak = 'The password strength is weaker than the system settings.'; $lang->admin->safe->modeList[0] = 'N/A'; $lang->admin->safe->modeList[1] = 'Medium'; diff --git a/module/admin/lang/en.php b/module/admin/lang/en.php index 1c8d55ebc2..1657fb2e33 100644 --- a/module/admin/lang/en.php +++ b/module/admin/lang/en.php @@ -75,6 +75,7 @@ $lang->admin->safe->checkWeak = 'Weak Password Scan'; $lang->admin->safe->changeWeak = 'Force to change weak password'; $lang->admin->safe->loginCaptcha = 'Login using CAPTCHA'; $lang->admin->safe->modifyPasswordFirstLogin = 'Force to change password after first login'; +$lang->admin->safe->passwordStrengthWeak = 'The password strength is weaker than the system settings.'; $lang->admin->safe->modeList[0] = 'I don\'t care.'; $lang->admin->safe->modeList[1] = 'Medium'; diff --git a/module/admin/lang/fr.php b/module/admin/lang/fr.php index 4bb1433680..f8370e4fee 100644 --- a/module/admin/lang/fr.php +++ b/module/admin/lang/fr.php @@ -75,6 +75,7 @@ $lang->admin->safe->checkWeak = 'Balayage des mots de passe faibl $lang->admin->safe->changeWeak = 'Forcer le changement des mots de passe faibles'; $lang->admin->safe->loginCaptcha = 'Login using CAPTCHA'; $lang->admin->safe->modifyPasswordFirstLogin = 'Forcer le changement du mot de passe après la première connexion'; +$lang->admin->safe->passwordStrengthWeak = 'Le mot de passe est moins fort que les paramètres du système.'; $lang->admin->safe->modeList[0] = "Contrôle Modéré"; $lang->admin->safe->modeList[1] = 'Contrôle Moyen'; diff --git a/module/admin/lang/zh-cn.php b/module/admin/lang/zh-cn.php index 51b9e2c510..2d5d8048c7 100644 --- a/module/admin/lang/zh-cn.php +++ b/module/admin/lang/zh-cn.php @@ -75,6 +75,7 @@ $lang->admin->safe->checkWeak = '弱口令扫描'; $lang->admin->safe->changeWeak = '修改弱口令密码'; $lang->admin->safe->loginCaptcha = '登录使用验证码'; $lang->admin->safe->modifyPasswordFirstLogin = '首次登录修改密码'; +$lang->admin->safe->passwordStrengthWeak = '密码强度小于系统设置'; $lang->admin->safe->modeList[0] = '不检查'; $lang->admin->safe->modeList[1] = '中'; diff --git a/module/admin/model.php b/module/admin/model.php index 1a6062e7f0..c6ec4bed40 100644 --- a/module/admin/model.php +++ b/module/admin/model.php @@ -234,13 +234,6 @@ class adminModel extends model { $weaks = array(); - /* Check weak password when login. */ - if($this->app->moduleName == 'user' and $this->app->methodName == 'login') - { - if(!isset($_POST['passwordStrength'])) return false; - if(isset($this->config->safe->mode) and $this->post->passwordStrength < $this->config->safe->mode) return true; - } - foreach(explode(',', $this->config->safe->weak) as $weak) { $weak = md5(trim($weak)); diff --git a/module/block/control.php b/module/block/control.php index 6b53ff3a5b..224ca9b8b4 100644 --- a/module/block/control.php +++ b/module/block/control.php @@ -888,6 +888,7 @@ class block extends control /* Load models and langs. */ $this->loadModel('project'); $this->loadModel('weekly'); + $this->loadModel('execution'); $this->app->loadLang('task'); $this->app->loadLang('story'); $this->app->loadLang('bug'); @@ -898,7 +899,7 @@ class block extends control /* Get projects. */ $excludedModel = $this->config->edition == 'max' ? '' : 'waterfall'; - $projects = $this->loadModel('project')->getOverviewList('byStatus', $status, 'order_asc', $count, $excludedModel); + $projects = $this->project->getOverviewList('byStatus', $status, 'order_asc', $count, $excludedModel); if(empty($projects)) { $this->view->projects = $projects; @@ -924,7 +925,7 @@ class block extends control $this->app->loadClass('pager', $static = true); $pager = pager::init(0, 3, 1); $project->progress = $project->allStories == 0 ? 0 : round($project->doneStories / $project->allStories, 3) * 100; - $project->executions = $this->project->getStats($projectID, 'all', 0, 0, 30, 'id_desc', $pager); + $project->executions = $this->execution->getStatData($projectID, 'all', 0, 0, false, '', 'id_desc', $pager); } elseif($project->model == 'waterfall') { @@ -1356,8 +1357,8 @@ class block extends control $this->app->loadClass('pager', $static = true); $pager = pager::init(0, $count, 1); - $this->app->loadLang('execution'); - $this->view->executionStats = !defined('TUTORIAL') ? $this->loadModel('project')->getStats($this->session->project, $type, 0, 0, 30, 'id_desc', $pager) : array($this->loadModel('tutorial')->getExecution()); + $this->loadModel('execution'); + $this->view->executionStats = !defined('TUTORIAL') ? $this->execution->getStatData($this->session->project, $type, 0, 0, false, '', 'id_desc', $pager) : array($this->loadModel('tutorial')->getExecution()); } /** @@ -1692,7 +1693,7 @@ class block extends control $count = isset($this->params->count) ? (int)$this->params->count : 0; $status = isset($this->params->type) ? $this->params->type : 'all'; - $this->app->loadLang('execution'); + $this->loadModel('execution'); $this->app->loadClass('pager', true); $pager = pager::init(0, $count, 1); @@ -1700,18 +1701,8 @@ class block extends control if($this->config->systemMode == 'new') $projectPairs = $this->dao->select('id,name')->from(TABLE_PROJECT)->where('type')->eq('project')->fetchPairs('id', 'name'); $projectID = $this->view->block->module == 'my' ? 0 : (int)$this->session->project; - $executions = $this->loadModel('project')->getStats($projectID, $status, 0, 0, 30, 'id_asc', $pager); - foreach($executions as $index => $execution) - { - if(empty($execution->children)) continue; - - foreach($execution->children as $child) $executions[] = $child; - unset($executions[$index]); - } - - $this->view->executionStats = $executions; - $this->view->projectPairs = $projectPairs; + $this->view->executionStats = $this->execution->getStatData($projectID, $status, 0, 0, false, 'skipParent', 'id_asc', $pager); } /** diff --git a/module/block/view/executionblock.html.php b/module/block/view/executionblock.html.php index 1f5d597033..d3d3804164 100644 --- a/module/block/view/executionblock.html.php +++ b/module/block/view/executionblock.html.php @@ -43,7 +43,6 @@ get->entry}'" : "class='text-center'"; $viewLink = $this->createLink('execution', 'task', 'executionID=' . $execution->id); - if($config->systemMode == 'new' and isset($projectPairs[$execution->project])) $execution->name = zget($projectPairs, $execution->project, '') . ' / ' . $execution->name; ?> > name, '', "title='$execution->name'");?> diff --git a/module/bug/config.php b/module/bug/config.php index c0dd78d8ef..0ba621fbc7 100644 --- a/module/bug/config.php +++ b/module/bug/config.php @@ -133,35 +133,28 @@ $config->bug->search['params']['branch'] = array('operator' => '=', $config->bug->search['params']['plan'] = array('operator' => '=', 'control' => 'select', 'values' => ''); $config->bug->search['params']['module'] = array('operator' => 'belong', 'control' => 'select', 'values' => 'modules'); $config->bug->search['params']['execution'] = array('operator' => '=', 'control' => 'select', 'values' => 'executions'); - $config->bug->search['params']['severity'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->severityList); $config->bug->search['params']['pri'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->priList); $config->bug->search['params']['type'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->typeList); -$config->bug->search['params']['os'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->osList); -$config->bug->search['params']['browser'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->browserList); +$config->bug->search['params']['os'] = array('operator' => 'include', 'control' => 'select', 'values' => $lang->bug->osList); +$config->bug->search['params']['browser'] = array('operator' => 'include', 'control' => 'select', 'values' => $lang->bug->browserList); $config->bug->search['params']['resolution'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->bug->resolutionList); - $config->bug->search['params']['activatedCount']= array('operator' => '>=', 'control' => 'input', 'values' => ''); - $config->bug->search['params']['toTask'] = array('operator' => '=', 'control' => 'input', 'values' => ''); $config->bug->search['params']['toStory'] = array('operator' => '=', 'control' => 'input', 'values' => ''); - $config->bug->search['params']['openedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); $config->bug->search['params']['closedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); $config->bug->search['params']['lastEditedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); - -$config->bug->search['params']['mailto'] = array('operator' => 'include', 'control' => 'select', 'values' => 'users'); - +$config->bug->search['params']['mailto'] = array('operator' => 'include', 'control' => 'select', 'values' => 'users'); $config->bug->search['params']['openedBuild'] = array('operator' => 'include', 'control' => 'select', 'values' => 'builds'); $config->bug->search['params']['resolvedBuild'] = array('operator' => '=', 'control' => 'select', 'values' => 'builds'); - -$config->bug->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['assignedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['resolvedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['closedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['lastEditedDate']= array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['deadline'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->bug->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->bug->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->bug->search['params']['assignedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->bug->search['params']['resolvedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->bug->search['params']['closedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->bug->search['params']['lastEditedDate']= array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->bug->search['params']['deadline'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->bug->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); $config->bug->datatable = new stdclass(); $config->bug->datatable->defaultField = array('id', 'severity', 'pri', 'confirmed', 'title', 'status', 'openedBy', 'openedDate', 'assignedTo', 'resolution', 'actions'); diff --git a/module/bug/control.php b/module/bug/control.php index 7dcae1aa83..bb3f353043 100755 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -859,6 +859,7 @@ class bug extends control $this->view->moduleID = $moduleID; $this->view->branch = $branch; $this->view->branches = $branches; + $this->display(); } @@ -1132,6 +1133,8 @@ class bug extends control $moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0, $bug->branch); if(!isset($moduleOptionMenu[$bug->module])) $moduleOptionMenu += $this->tree->getModulesName($bug->module); + $cases = $this->loadmodel('testcase')->getPairsByProduct($bug->product, array(0, $bug->branch)); + /* Get assigned to member. */ if($bug->execution) { @@ -1165,6 +1168,7 @@ class bug extends control $this->view->testtasks = $this->loadModel('testtask')->getPairs($bug->product, $bug->execution, $bug->testtask); $this->view->users = $this->user->getPairs('', "$bug->assignedTo,$bug->resolvedBy,$bug->closedBy,$bug->openedBy"); $this->view->assignedToList = $assignedToList; + $this->view->cases = array('' => '') + $cases; $this->view->openedBuilds = $openedBuilds; $this->view->resolvedBuilds = array('' => '') + $openedBuilds + $oldResolvedBuild; $this->view->actions = $this->action->getList('bug', $bugID); @@ -1379,8 +1383,6 @@ class bug extends control $this->view->priList = array('0' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->priList; $this->view->resolutionList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->resolutionList; $this->view->statusList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->statusList; - $this->view->osList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->osList; - $this->view->browserList = array('' => '', 'ditto' => $this->lang->bug->ditto) + $this->lang->bug->browserList; $this->view->bugs = $bugs; $this->view->branch = $branch; $this->view->users = $users; diff --git a/module/bug/css/create.css b/module/bug/css/create.css index 470dd51d77..557bf69e84 100644 --- a/module/bug/css/create.css +++ b/module/bug/css/create.css @@ -55,3 +55,4 @@ html[lang='de'] #keywordsAddonLabel, .task {width: 73px;} #executionLabel {display: inline; position: relative; width: 50%; left: 37%;} #projectLabel {display: inline;} #openedBuildLabel {display: inline; position: relative; width: 50%; left: 14%;} +#bugTypeInputGroup > .table-col {width: 40% !important;} diff --git a/module/bug/css/view.css b/module/bug/css/view.css index 452146b88a..7583e152e0 100644 --- a/module/bug/css/view.css +++ b/module/bug/css/view.css @@ -5,3 +5,4 @@ .tab-pane table {border: 1px solid #ddd; border-top: none;} .btn-edit-comment {z-index: 100;} .select-project-modal .modal-body {right: 15px;} +.osContent, .browserContent {margin: 0 0 5px;} diff --git a/module/bug/js/browse.js b/module/bug/js/browse.js index 6d469700d9..0cc3ce246d 100644 --- a/module/bug/js/browse.js +++ b/module/bug/js/browse.js @@ -8,4 +8,27 @@ $(function() $("#sidebarHeader").toggle("fast"); }); if($("main").is(".hide-sidebar")) $("#sidebarHeader").hide(); + + $('#bugList').on('change', "[name='bugIDList[]']", checkClosed); }); + +/** + * Closed bugs are not assignable. + * + * @access public + * @return void + */ +function checkClosed() +{ + var disabledAssigned = $('#bugList tr.checked .c-assignedTo a').length > 0 ? true : false; + $('#bugList tr.checked .c-assignedTo a').each(function() + { + if(!$(this).hasClass('disabled')) + { + disabledAssigned = false; + return false; + } + }); + + $('#mulAssigned').prop('disabled', disabledAssigned); +} diff --git a/module/bug/lang/de.php b/module/bug/lang/de.php index c9e6875e7b..4a4999204f 100644 --- a/module/bug/lang/de.php +++ b/module/bug/lang/de.php @@ -232,51 +232,39 @@ $lang->bug->priList[2] = '2'; $lang->bug->priList[3] = '3'; $lang->bug->priList[4] = '4'; -$lang->bug->osList[''] = ''; -$lang->bug->osList['all'] = 'Alle'; -$lang->bug->osList['windows'] = 'Windows'; -$lang->bug->osList['win10'] = 'Windows 10'; -$lang->bug->osList['win8'] = 'Windows 8'; -$lang->bug->osList['win7'] = 'Windows 7'; -$lang->bug->osList['vista'] = 'Windows Vista'; -$lang->bug->osList['winxp'] = 'Windows XP'; -$lang->bug->osList['win2012'] = 'Windows 2012'; -$lang->bug->osList['win2008'] = 'Windows 2008'; -$lang->bug->osList['win2003'] = 'Windows 2003'; -$lang->bug->osList['win2000'] = 'Windows 2000'; -$lang->bug->osList['android'] = 'Android'; -$lang->bug->osList['ios'] = 'IOS'; -$lang->bug->osList['wp8'] = 'WP8'; -$lang->bug->osList['wp7'] = 'WP7'; -$lang->bug->osList['symbian'] = 'Symbian'; -$lang->bug->osList['linux'] = 'Linux'; -$lang->bug->osList['freebsd'] = 'FreeBSD'; -$lang->bug->osList['osx'] = 'OS X'; -$lang->bug->osList['unix'] = 'Unix'; -$lang->bug->osList['others'] = 'Andere'; +$lang->bug->osList[''] = ''; +$lang->bug->osList['all'] = 'Alle'; +$lang->bug->osList['windows'] = 'Windows'; +$lang->bug->osList['win11'] = 'Windows 11'; +$lang->bug->osList['win10'] = 'Windows 10'; +$lang->bug->osList['win8'] = 'Windows 8'; +$lang->bug->osList['win7'] = 'Windows 7'; +$lang->bug->osList['winxp'] = 'Windows XP'; +$lang->bug->osList['osx'] = 'Mac OS'; +$lang->bug->osList['android'] = 'Android'; +$lang->bug->osList['ios'] = 'IOS'; +$lang->bug->osList['linux'] = 'Linux'; +$lang->bug->osList['ubuntu'] = 'Ubuntu'; +$lang->bug->osList['chromeos'] = 'Chrome OS'; +$lang->bug->osList['fedora'] = 'Fedora'; +$lang->bug->osList['unix'] = 'Unix'; +$lang->bug->osList['others'] = 'Andere'; -$lang->bug->browserList[''] = ''; -$lang->bug->browserList['all'] = 'Alle'; -$lang->bug->browserList['ie'] = 'IE series'; -$lang->bug->browserList['ie11'] = 'IE11'; -$lang->bug->browserList['ie10'] = 'IE10'; -$lang->bug->browserList['ie9'] = 'IE9'; -$lang->bug->browserList['ie8'] = 'IE8'; -$lang->bug->browserList['ie7'] = 'IE7'; -$lang->bug->browserList['ie6'] = 'IE6'; -$lang->bug->browserList['chrome'] = 'chrome'; -$lang->bug->browserList['firefox'] = 'Firefox series'; -$lang->bug->browserList['firefox4'] = 'Firefox4'; -$lang->bug->browserList['firefox3'] = 'Firefox3'; -$lang->bug->browserList['firefox2'] = 'Firefox2'; -$lang->bug->browserList['opera'] = 'Opera series'; -$lang->bug->browserList['oprea11'] = 'Opera11'; -$lang->bug->browserList['oprea10'] = 'Opera10'; -$lang->bug->browserList['opera9'] = 'Opera9'; -$lang->bug->browserList['safari'] = 'Safari'; -$lang->bug->browserList['maxthon'] = 'Maxthon'; -$lang->bug->browserList['uc'] = 'UC'; -$lang->bug->browserList['other'] = 'Andere'; +$lang->bug->browserList[''] = ''; +$lang->bug->browserList['all'] = 'Alle'; +$lang->bug->browserList['chrome'] = 'Chrome'; +$lang->bug->browserList['edge'] = 'Edge'; +$lang->bug->browserList['ie'] = 'IE series'; +$lang->bug->browserList['ie11'] = 'IE11'; +$lang->bug->browserList['ie10'] = 'IE10'; +$lang->bug->browserList['ie9'] = 'IE9'; +$lang->bug->browserList['ie8'] = 'IE8'; +$lang->bug->browserList['firefox'] = 'Firefox series'; +$lang->bug->browserList['opera'] = 'Opera series'; +$lang->bug->browserList['safari'] = 'Safari'; +$lang->bug->browserList['360'] = '360 series'; +$lang->bug->browserList['qq'] = 'QQ series'; +$lang->bug->browserList['other'] = 'Andere'; $lang->bug->typeList[''] = ''; $lang->bug->typeList['codeerror'] = 'Code Fehler'; @@ -428,7 +416,6 @@ $lang->bug->featureBar['browse']['unclosed'] = $lang->bug->unclosed; $lang->bug->featureBar['browse']['openedbyme'] = $lang->bug->openedByMe; $lang->bug->featureBar['browse']['assigntome'] = $lang->bug->assignToMe; $lang->bug->featureBar['browse']['resolvedbyme'] = $lang->bug->resolvedByMe; - $lang->bug->featureBar['browse']['unresolved'] = $lang->bug->unResolved; $lang->bug->featureBar['browse']['more'] = $lang->more; diff --git a/module/bug/lang/en.php b/module/bug/lang/en.php index fc62a14d4f..9a67e54d8c 100644 --- a/module/bug/lang/en.php +++ b/module/bug/lang/en.php @@ -232,51 +232,39 @@ $lang->bug->priList[2] = '2'; $lang->bug->priList[3] = '3'; $lang->bug->priList[4] = '4'; -$lang->bug->osList[''] = ''; -$lang->bug->osList['all'] = 'All'; -$lang->bug->osList['windows'] = 'Windows'; -$lang->bug->osList['win10'] = 'Windows 10'; -$lang->bug->osList['win8'] = 'Windows 8'; -$lang->bug->osList['win7'] = 'Windows 7'; -$lang->bug->osList['vista'] = 'Windows Vista'; -$lang->bug->osList['winxp'] = 'Windows XP'; -$lang->bug->osList['win2012'] = 'Windows 2012'; -$lang->bug->osList['win2008'] = 'Windows 2008'; -$lang->bug->osList['win2003'] = 'Windows 2003'; -$lang->bug->osList['win2000'] = 'Windows 2000'; -$lang->bug->osList['android'] = 'Android'; -$lang->bug->osList['ios'] = 'IOS'; -$lang->bug->osList['wp8'] = 'WP8'; -$lang->bug->osList['wp7'] = 'WP7'; -$lang->bug->osList['symbian'] = 'Symbian'; -$lang->bug->osList['linux'] = 'Linux'; -$lang->bug->osList['freebsd'] = 'FreeBSD'; -$lang->bug->osList['osx'] = 'OS X'; -$lang->bug->osList['unix'] = 'Unix'; -$lang->bug->osList['others'] = 'Others'; +$lang->bug->osList[''] = ''; +$lang->bug->osList['all'] = 'All'; +$lang->bug->osList['windows'] = 'Windows'; +$lang->bug->osList['win11'] = 'Windows 11'; +$lang->bug->osList['win10'] = 'Windows 10'; +$lang->bug->osList['win8'] = 'Windows 8'; +$lang->bug->osList['win7'] = 'Windows 7'; +$lang->bug->osList['winxp'] = 'Windows XP'; +$lang->bug->osList['osx'] = 'Mac OS'; +$lang->bug->osList['android'] = 'Android'; +$lang->bug->osList['ios'] = 'IOS'; +$lang->bug->osList['linux'] = 'Linux'; +$lang->bug->osList['ubuntu'] = 'Ubuntu'; +$lang->bug->osList['chromeos'] = 'Chrome OS'; +$lang->bug->osList['fedora'] = 'Fedora'; +$lang->bug->osList['unix'] = 'Unix'; +$lang->bug->osList['others'] = 'Others'; -$lang->bug->browserList[''] = ''; -$lang->bug->browserList['all'] = 'All'; -$lang->bug->browserList['ie'] = 'IE series'; -$lang->bug->browserList['ie11'] = 'IE11'; -$lang->bug->browserList['ie10'] = 'IE10'; -$lang->bug->browserList['ie9'] = 'IE9'; -$lang->bug->browserList['ie8'] = 'IE8'; -$lang->bug->browserList['ie7'] = 'IE7'; -$lang->bug->browserList['ie6'] = 'IE6'; -$lang->bug->browserList['chrome'] = 'Chrome'; -$lang->bug->browserList['firefox'] = 'Firefox series'; -$lang->bug->browserList['firefox4'] = 'Firefox4'; -$lang->bug->browserList['firefox3'] = 'Firefox3'; -$lang->bug->browserList['firefox2'] = 'Firefox2'; -$lang->bug->browserList['opera'] = 'Opera series'; -$lang->bug->browserList['oprea11'] = 'Opera11'; -$lang->bug->browserList['oprea10'] = 'Opera10'; -$lang->bug->browserList['opera9'] = 'Opera9'; -$lang->bug->browserList['safari'] = 'Safari'; -$lang->bug->browserList['maxthon'] = 'Maxthon'; -$lang->bug->browserList['uc'] = 'UC'; -$lang->bug->browserList['other'] = 'Others'; +$lang->bug->browserList[''] = ''; +$lang->bug->browserList['all'] = 'All'; +$lang->bug->browserList['chrome'] = 'Chrome'; +$lang->bug->browserList['edge'] = 'Edge'; +$lang->bug->browserList['ie'] = 'IE series'; +$lang->bug->browserList['ie11'] = 'IE11'; +$lang->bug->browserList['ie10'] = 'IE10'; +$lang->bug->browserList['ie9'] = 'IE9'; +$lang->bug->browserList['ie8'] = 'IE8'; +$lang->bug->browserList['firefox'] = 'Firefox series'; +$lang->bug->browserList['opera'] = 'Opera series'; +$lang->bug->browserList['safari'] = 'Safari'; +$lang->bug->browserList['360'] = '360 series'; +$lang->bug->browserList['qq'] = 'QQ series'; +$lang->bug->browserList['other'] = 'Others'; $lang->bug->typeList[''] = ''; $lang->bug->typeList['codeerror'] = 'CodeError'; @@ -428,7 +416,6 @@ $lang->bug->featureBar['browse']['unclosed'] = $lang->bug->unclosed; $lang->bug->featureBar['browse']['openedbyme'] = $lang->bug->openedByMe; $lang->bug->featureBar['browse']['assigntome'] = $lang->bug->assignToMe; $lang->bug->featureBar['browse']['resolvedbyme'] = $lang->bug->resolvedByMe; - $lang->bug->featureBar['browse']['unresolved'] = $lang->bug->unResolved; $lang->bug->featureBar['browse']['more'] = $lang->more; diff --git a/module/bug/lang/fr.php b/module/bug/lang/fr.php index ff95166866..6ea57d780c 100644 --- a/module/bug/lang/fr.php +++ b/module/bug/lang/fr.php @@ -232,51 +232,39 @@ $lang->bug->priList[2] = '2'; $lang->bug->priList[3] = '3'; $lang->bug->priList[4] = '4'; -$lang->bug->osList[''] = ''; -$lang->bug->osList['all'] = 'Tous'; -$lang->bug->osList['windows'] = 'Windows'; -$lang->bug->osList['win10'] = 'Windows 10'; -$lang->bug->osList['win8'] = 'Windows 8'; -$lang->bug->osList['win7'] = 'Windows 7'; -$lang->bug->osList['vista'] = 'Windows Vista'; -$lang->bug->osList['winxp'] = 'Windows XP'; -$lang->bug->osList['win2012'] = 'Windows 2012'; -$lang->bug->osList['win2008'] = 'Windows 2008'; -$lang->bug->osList['win2003'] = 'Windows 2003'; -$lang->bug->osList['win2000'] = 'Windows 2000'; -$lang->bug->osList['android'] = 'Android'; -$lang->bug->osList['ios'] = 'IOS'; -$lang->bug->osList['wp8'] = 'WP8'; -$lang->bug->osList['wp7'] = 'WP7'; -$lang->bug->osList['symbian'] = 'Symbian'; -$lang->bug->osList['linux'] = 'Linux'; -$lang->bug->osList['freebsd'] = 'FreeBSD'; -$lang->bug->osList['osx'] = 'OS X'; -$lang->bug->osList['unix'] = 'Unix'; -$lang->bug->osList['others'] = 'Autres'; +$lang->bug->osList[''] = ''; +$lang->bug->osList['all'] = 'Tous'; +$lang->bug->osList['windows'] = 'Windows'; +$lang->bug->osList['win11'] = 'Windows 11'; +$lang->bug->osList['win10'] = 'Windows 10'; +$lang->bug->osList['win8'] = 'Windows 8'; +$lang->bug->osList['win7'] = 'Windows 7'; +$lang->bug->osList['winxp'] = 'Windows XP'; +$lang->bug->osList['osx'] = 'Mac OS'; +$lang->bug->osList['android'] = 'Android'; +$lang->bug->osList['ios'] = 'IOS'; +$lang->bug->osList['linux'] = 'Linux'; +$lang->bug->osList['ubuntu'] = 'Ubuntu'; +$lang->bug->osList['chromeos'] = 'Chrome OS'; +$lang->bug->osList['fedora'] = 'Fedora'; +$lang->bug->osList['unix'] = 'Unix'; +$lang->bug->osList['others'] = 'Autres'; -$lang->bug->browserList[''] = ''; -$lang->bug->browserList['all'] = 'Tous'; -$lang->bug->browserList['ie'] = 'IE series'; -$lang->bug->browserList['ie11'] = 'IE11'; -$lang->bug->browserList['ie10'] = 'IE10'; -$lang->bug->browserList['ie9'] = 'IE9'; -$lang->bug->browserList['ie8'] = 'IE8'; -$lang->bug->browserList['ie7'] = 'IE7'; -$lang->bug->browserList['ie6'] = 'IE6'; -$lang->bug->browserList['chrome'] = 'Chrome'; -$lang->bug->browserList['firefox'] = 'Firefox series'; -$lang->bug->browserList['firefox4'] = 'Firefox4'; -$lang->bug->browserList['firefox3'] = 'Firefox3'; -$lang->bug->browserList['firefox2'] = 'Firefox2'; -$lang->bug->browserList['opera'] = 'Opera series'; -$lang->bug->browserList['oprea11'] = 'Opera11'; -$lang->bug->browserList['oprea10'] = 'Opera10'; -$lang->bug->browserList['opera9'] = 'Opera9'; -$lang->bug->browserList['safari'] = 'Safari'; -$lang->bug->browserList['maxthon'] = 'Maxthon'; -$lang->bug->browserList['uc'] = 'UC'; -$lang->bug->browserList['other'] = 'Autres'; +$lang->bug->browserList[''] = ''; +$lang->bug->browserList['all'] = 'Tous'; +$lang->bug->browserList['chrome'] = 'Chrome'; +$lang->bug->browserList['edge'] = 'Edge'; +$lang->bug->browserList['ie'] = 'IE series'; +$lang->bug->browserList['ie11'] = 'IE11'; +$lang->bug->browserList['ie10'] = 'IE10'; +$lang->bug->browserList['ie9'] = 'IE9'; +$lang->bug->browserList['ie8'] = 'IE8'; +$lang->bug->browserList['firefox'] = 'Firefox series'; +$lang->bug->browserList['opera'] = 'Opera series'; +$lang->bug->browserList['safari'] = 'Safari'; +$lang->bug->browserList['360'] = '360 series'; +$lang->bug->browserList['qq'] = 'QQ series'; +$lang->bug->browserList['other'] = 'Autres'; $lang->bug->typeList[''] = ''; $lang->bug->typeList['codeerror'] = 'Code Erreur'; @@ -428,7 +416,6 @@ $lang->bug->featureBar['browse']['unclosed'] = $lang->bug->unclosed; $lang->bug->featureBar['browse']['openedbyme'] = $lang->bug->openedByMe; $lang->bug->featureBar['browse']['assigntome'] = $lang->bug->assignToMe; $lang->bug->featureBar['browse']['resolvedbyme'] = $lang->bug->resolvedByMe; - $lang->bug->featureBar['browse']['unresolved'] = $lang->bug->unResolved; $lang->bug->featureBar['browse']['more'] = $lang->more; diff --git a/module/bug/lang/zh-cn.php b/module/bug/lang/zh-cn.php index 73c41b12e0..e4ea8310b7 100644 --- a/module/bug/lang/zh-cn.php +++ b/module/bug/lang/zh-cn.php @@ -232,51 +232,39 @@ $lang->bug->priList[2] = '2'; $lang->bug->priList[3] = '3'; $lang->bug->priList[4] = '4'; -$lang->bug->osList[''] = ''; -$lang->bug->osList['all'] = '全部'; -$lang->bug->osList['windows'] = 'Windows'; -$lang->bug->osList['win10'] = 'Windows 10'; -$lang->bug->osList['win8'] = 'Windows 8'; -$lang->bug->osList['win7'] = 'Windows 7'; -$lang->bug->osList['vista'] = 'Windows Vista'; -$lang->bug->osList['winxp'] = 'Windows XP'; -$lang->bug->osList['win2012'] = 'Windows 2012'; -$lang->bug->osList['win2008'] = 'Windows 2008'; -$lang->bug->osList['win2003'] = 'Windows 2003'; -$lang->bug->osList['win2000'] = 'Windows 2000'; -$lang->bug->osList['android'] = 'Android'; -$lang->bug->osList['ios'] = 'IOS'; -$lang->bug->osList['wp8'] = 'WP8'; -$lang->bug->osList['wp7'] = 'WP7'; -$lang->bug->osList['symbian'] = 'Symbian'; -$lang->bug->osList['linux'] = 'Linux'; -$lang->bug->osList['freebsd'] = 'FreeBSD'; -$lang->bug->osList['osx'] = 'OS X'; -$lang->bug->osList['unix'] = 'Unix'; -$lang->bug->osList['others'] = '其他'; +$lang->bug->osList[''] = ''; +$lang->bug->osList['all'] = '全部'; +$lang->bug->osList['windows'] = 'Windows'; +$lang->bug->osList['win11'] = 'Windows 11'; +$lang->bug->osList['win10'] = 'Windows 10'; +$lang->bug->osList['win8'] = 'Windows 8'; +$lang->bug->osList['win7'] = 'Windows 7'; +$lang->bug->osList['winxp'] = 'Windows XP'; +$lang->bug->osList['osx'] = 'Mac OS'; +$lang->bug->osList['android'] = 'Android'; +$lang->bug->osList['ios'] = 'IOS'; +$lang->bug->osList['linux'] = 'Linux'; +$lang->bug->osList['ubuntu'] = 'Ubuntu'; +$lang->bug->osList['chromeos'] = 'Chrome OS'; +$lang->bug->osList['fedora'] = 'Fedora'; +$lang->bug->osList['unix'] = 'Unix'; +$lang->bug->osList['others'] = '其他'; -$lang->bug->browserList[''] = ''; -$lang->bug->browserList['all'] = '全部'; -$lang->bug->browserList['ie'] = 'IE系列'; -$lang->bug->browserList['ie11'] = 'IE11'; -$lang->bug->browserList['ie10'] = 'IE10'; -$lang->bug->browserList['ie9'] = 'IE9'; -$lang->bug->browserList['ie8'] = 'IE8'; -$lang->bug->browserList['ie7'] = 'IE7'; -$lang->bug->browserList['ie6'] = 'IE6'; -$lang->bug->browserList['chrome'] = 'chrome'; -$lang->bug->browserList['firefox'] = 'firefox系列'; -$lang->bug->browserList['firefox4'] = 'firefox4'; -$lang->bug->browserList['firefox3'] = 'firefox3'; -$lang->bug->browserList['firefox2'] = 'firefox2'; -$lang->bug->browserList['opera'] = 'opera系列'; -$lang->bug->browserList['oprea11'] = 'opera11'; -$lang->bug->browserList['oprea10'] = 'opera10'; -$lang->bug->browserList['opera9'] = 'opera9'; -$lang->bug->browserList['safari'] = 'safari'; -$lang->bug->browserList['maxthon'] = '傲游'; -$lang->bug->browserList['uc'] = 'UC'; -$lang->bug->browserList['other'] = '其他'; +$lang->bug->browserList[''] = ''; +$lang->bug->browserList['all'] = '全部'; +$lang->bug->browserList['chrome'] = 'Chrome'; +$lang->bug->browserList['edge'] = 'Edge'; +$lang->bug->browserList['ie'] = 'IE系列'; +$lang->bug->browserList['ie11'] = 'IE11'; +$lang->bug->browserList['ie10'] = 'IE10'; +$lang->bug->browserList['ie9'] = 'IE9'; +$lang->bug->browserList['ie8'] = 'IE8'; +$lang->bug->browserList['firefox'] = 'firefox系列'; +$lang->bug->browserList['opera'] = 'Opera系列'; +$lang->bug->browserList['safari'] = 'safari'; +$lang->bug->browserList['360'] = '360浏览器'; +$lang->bug->browserList['qq'] = 'QQ浏览器'; +$lang->bug->browserList['other'] = '其他'; $lang->bug->typeList[''] = ''; $lang->bug->typeList['codeerror'] = '代码错误'; @@ -432,7 +420,6 @@ $lang->bug->featureBar['browse']['assignedbyme'] = $lang->bug->assignedByMe; $lang->bug->featureBar['browse']['unresolved'] = $lang->bug->unResolved; $lang->bug->featureBar['browse']['more'] = $lang->more; - $lang->bug->moreSelects['unconfirmed'] = $lang->bug->unconfirmed; $lang->bug->moreSelects['assigntonull'] = $lang->bug->assignToNull; $lang->bug->moreSelects['longlifebugs'] = $lang->bug->longLifeBugs; diff --git a/module/bug/model.php b/module/bug/model.php index 34c06d1800..803fba1cf8 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -76,6 +76,8 @@ class bugModel extends model ->trim('title') ->join('openedBuild', ',') ->join('mailto', ',') + ->join('os', ',') + ->join('browser', ',') ->remove('files,labels,uid,oldTaskID,contactListMenu,region,lane') ->get(); @@ -163,25 +165,24 @@ class bugModel extends model $execution = 0; $type = ''; $pri = 0; - $os = ''; - $browser = ''; foreach($data->title as $i => $title) { + $oses = array_filter($data->oses[$i]); + $browsers = array_filter($data->browsers[$i]); + if($data->modules[$i] != 'ditto') $module = (int)$data->modules[$i]; if($data->projects[$i] != 'ditto') $project = (int)$data->projects[$i]; if($data->executions[$i] != 'ditto') $execution = (int)$data->executions[$i]; if($data->types[$i] != 'ditto') $type = $data->types[$i]; if($data->pris[$i] != 'ditto') $pri = $data->pris[$i]; - if($data->oses[$i] != 'ditto') $os = $data->oses[$i]; - if($data->browsers[$i] != 'ditto') $browser = $data->browsers[$i]; $data->modules[$i] = (int)$module; $data->projects[$i] = (int)$project; $data->executions[$i] = (int)$execution; $data->types[$i] = $type; $data->pris[$i] = $pri; - $data->oses[$i] = $os; - $data->browsers[$i] = $browser; + $data->oses[$i] = implode(',', $oses); + $data->browsers[$i] = implode(',', $browsers); } /* Get bug data. */ @@ -689,6 +690,8 @@ class bugModel extends model ->stripTags($this->config->bug->editor->edit['id'], $this->config->allowedTags) ->setDefault('product,module,execution,story,task,duplicateBug,branch', 0) ->setDefault('openedBuild', '') + ->setDefault('os', '') + ->setDefault('browser', '') ->setDefault('plan', 0) ->setDefault('deadline', '0000-00-00') ->setDefault('resolvedDate', '0000-00-00 00:00:00') @@ -699,6 +702,8 @@ class bugModel extends model ->join('openedBuild', ',') ->join('mailto', ',') ->join('linkBug', ',') + ->join('os', ',') + ->join('browser', ',') ->setIF($this->post->assignedTo != $oldBug->assignedTo, 'assignedDate', $now) ->setIF($this->post->resolvedBy != '' and $this->post->resolvedDate == '', 'resolvedDate', $now) ->setIF($this->post->resolution != '' and $this->post->resolvedDate == '', 'resolvedDate', $now) @@ -716,6 +721,7 @@ class bugModel extends model ->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', '') + ->setIF($this->post->case === '', 'case', 0) ->remove('comment,files,labels,uid,contactListMenu') ->get(); @@ -805,8 +811,6 @@ class bugModel extends model if($data->assignedTos[$bugID] == 'ditto') $data->assignedTos[$bugID] = isset($prev['assignedTo']) ? $prev['assignedTo'] : ''; if($data->resolvedBys[$bugID] == 'ditto') $data->resolvedBys[$bugID] = isset($prev['resolvedBy']) ? $prev['resolvedBy'] : ''; if($data->resolutions[$bugID] == 'ditto') $data->resolutions[$bugID] = isset($prev['resolution']) ? $prev['resolution'] : ''; - if($data->os[$bugID] == 'ditto') $data->os[$bugID] = isset($prev['os']) ? $prev['os'] : ''; - if($data->browsers[$bugID] == 'ditto') $data->browsers[$bugID] = isset($prev['browser']) ? $prev['browser'] : ''; if(isset($data->branches[$bugID]) and $data->branches[$bugID] == 'ditto') $data->branches[$bugID] = isset($prev['branch']) ? $prev['branch'] : 0; $prev['type'] = $data->types[$bugID]; @@ -817,8 +821,6 @@ class bugModel extends model $prev['assignedTo'] = $data->assignedTos[$bugID]; $prev['resolvedBy'] = $data->resolvedBys[$bugID]; $prev['resolution'] = $data->resolutions[$bugID]; - $prev['os'] = $data->os[$bugID]; - $prev['browser'] = $data->browsers[$bugID]; } /* Initialize bugs from the post data.*/ @@ -828,6 +830,9 @@ class bugModel extends model { $oldBug = $oldBugs[$bugID]; + $os = array_filter($data->os[$bugID]); + $browsers = array_filter($data->browsers[$bugID]); + $bug = new stdclass(); $bug->id = $bugID; $bug->lastEditedBy = $this->app->user->account; @@ -840,12 +845,12 @@ class bugModel extends model $bug->plan = empty($data->plans[$bugID]) ? 0 : $data->plans[$bugID]; $bug->branch = empty($data->branches[$bugID]) ? 0 : $data->branches[$bugID]; $bug->module = $data->modules[$bugID]; - $bug->assignedTo = $data->assignedTos[$bugID]; + $bug->assignedTo = $bug->status == 'closed' ? $oldBug->assignedTo : $data->assignedTos[$bugID]; $bug->deadline = $data->deadlines[$bugID]; $bug->resolvedBy = $data->resolvedBys[$bugID]; $bug->keywords = $data->keywords[$bugID]; - $bug->os = $data->os[$bugID]; - $bug->browser = $data->browsers[$bugID]; + $bug->os = implode(',', $os); + $bug->browser = implode(',', $browsers); $bug->resolution = $data->resolutions[$bugID]; $bug->duplicateBug = $data->duplicateBugs[$bugID] ? $data->duplicateBugs[$bugID] : $oldBug->duplicateBug; @@ -1004,6 +1009,8 @@ class bugModel extends model { $now = helper::now(); $oldBug = $this->getById($bugID); + if($oldBug->status == 'closed') return false; + $bug = fixer::input('post') ->add('id', $bugID) ->setDefault('lastEditedBy', $this->app->user->account) @@ -3170,9 +3177,25 @@ class bugModel extends model } } - $bugLink = helper::createLink('bug', 'view', "bugID=$bug->id"); - $account = $this->app->user->account; - $id = $col->id; + $bugLink = helper::createLink('bug', 'view', "bugID=$bug->id"); + $account = $this->app->user->account; + $id = $col->id; + $os = ''; + $browser = ''; + $osList = explode(',', $bug->os); + $browserList = explode(',', $bug->browser); + foreach($osList as $value) + { + if(empty($value)) continue; + $os .= $this->lang->bug->osList[$value] . ','; + } + foreach($browserList as $value) + { + if(empty($value)) continue; + $browser .= $this->lang->bug->browserList[$value] . ','; + } + $os = trim($os, ','); + $browser = trim($browser, ','); if($col->show) { $class = "c-$id"; @@ -3221,6 +3244,14 @@ class bugModel extends model $class .= ' text-ellipsis'; $title = "title='" . $bug->resolvedBuild . "'"; break; + case 'os': + $class .= ' text-ellipsis'; + $title = "title='" . $os . "'"; + break; + case 'browser': + $class .= ' text-ellipsis'; + $title = "title='" . $browser . "'"; + break; } if($id == 'deadline' && isset($bug->delay) && $bug->status == 'active') $class .= ' delayed'; @@ -3319,10 +3350,10 @@ class bugModel extends model echo $bug->keywords; break; case 'os': - echo zget($this->lang->bug->osList, $bug->os); + echo $os; break; case 'browser': - echo zget($this->lang->bug->browserList, $bug->browser); + echo $browser; break; case 'mailto': $mailto = explode(',', $bug->mailto); @@ -3528,7 +3559,7 @@ class bugModel extends model $toStoryParams = "product=$bug->product&branch=$bug->branch&module=0&story=0&execution=0&bugID=$bug->id"; $menu .= $this->buildMenu('bug', 'confirmBug', $params, $bug, $type, 'ok', '', "iframe", true); - if($type == 'view') $menu .= $this->buildMenu('bug', 'assignTo', $params, $bug, $type, '', '', "iframe", true); + if($type == 'view' and $bug->status != 'closed') $menu .= $this->buildMenu('bug', 'assignTo', $params, $bug, $type, '', '', "iframe", true); $menu .= $this->buildMenu('bug', 'resolve', $params, $bug, $type, 'checked', '', "iframe showinonlybody", true); $menu .= $this->buildMenu('bug', 'close', $params, $bug, $type, '', '', "text-danger iframe showinonlybody", true); if($type == 'view') $menu .= $this->buildMenu('bug', 'activate', $params, $bug, $type, '', '', "text-success iframe showinonlybody", true); diff --git a/module/bug/view/batchcreate.html.php b/module/bug/view/batchcreate.html.php index 762b5634ed..5e167e4891 100755 --- a/module/bug/view/batchcreate.html.php +++ b/module/bug/view/batchcreate.html.php @@ -92,8 +92,6 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field) $executions += array('ditto' => $lang->bug->ditto); $lang->bug->typeList += array('ditto' => $lang->bug->ditto); $lang->bug->priList += array('ditto' => $lang->bug->ditto); - $lang->bug->osList += array('ditto' => $lang->bug->ditto); - $lang->bug->browserList += array('ditto' => $lang->bug->ditto); ?> @@ -104,8 +102,6 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field) $executionID = $i == 1 ? $executionID : 'ditto'; $type = $i == 1 ? '' : 'ditto'; $pri = $i == 1 ? 0 : 'ditto'; - $os = $i == 1 ? '' : 'ditto'; - $browser = $i == 1 ? '' : 'ditto'; ?> @@ -139,8 +135,8 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field) typeBox' style='overflow:visible'> bug->typeList, $type, "class='form-control chosen'");?> priBox' style='overflow:visible'> bug->priList, $pri, "class='form-control'");?> severityBox' style='overflow:visible'>bug->severityList, '3', "class='form-control'");?> - osBox' style='overflow:visible'> bug->osList, $os, "class='form-control chosen'");?> - browserBox' style='overflow:visible'> bug->browserList, $browser, "class='form-control chosen'");?> + osBox' style='overflow:visible'> bug->osList, '', "class='form-control chosen' multiple");?> + browserBox' style='overflow:visible'> bug->browserList, '', "class='form-control chosen' multiple");?> keywordsBox'> loadModel('flow'); @@ -164,8 +160,6 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field) $executionID = $i - $nextStart == 0 ? $executionID : 'ditto'; $type = $i - $nextStart == 0 ? '' : 'ditto'; $pri = $i - $nextStart == 0 ? 0 : 'ditto'; - $os = $i - $nextStart == 0 ? '' : 'ditto'; - $browser = $i - $nextStart == 0 ? '' : 'ditto'; ?> @@ -199,8 +193,8 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field) typeBox' style='overflow:visible'> bug->typeList, $type, "class='form-control chosen'");?> priBox' style='overflow:visible'> bug->priList, $pri, "class='form-control'");?> severityBox' style='overflow:visible'>bug->severityList, '3', "class='form-control'");?> - osBox' style='overflow:visible'> bug->osList, $os, "class='form-control chosen'");?> - browserBox' style='overflow:visible'> bug->browserList, $browser, "class='form-control chosen'");?> + osBox' style='overflow:visible'> bug->osList, '', "class='form-control chosen' multiple");?> + browserBox' style='overflow:visible'> bug->browserList, '', "class='form-control chosen' multiple");?> keywordsBox'> loadModel('flow'); @@ -258,8 +252,8 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field) typeBox' style='overflow:visible'> bug->typeList, $type, "class='form-control chosen'");?> priBox' style='overflow:visible'> bug->priList, $pri, "class='form-control'");?> severityBox' style='overflow:visible'>bug->severityList, '3', "class='form-control'");?> - osBox' style='overflow:visible'> bug->osList, $os, "class='form-control chosen'");?> - browserBox' style='overflow:visible'> bug->browserList, $browser, "class='form-control chosen'");?> + osBox' style='overflow:visible'> bug->osList, '', "class='form-control chosen' multiple");?> + browserBox' style='overflow:visible'> bug->browserList, '', "class='form-control chosen' multiple");?> keywordsBox'> loadModel('flow'); @@ -307,8 +301,8 @@ foreach(explode(',', $config->bug->create->requiredFields) as $field) typeBox' style='overflow:visible'> bug->typeList, $type, "class='form-control chosen'");?> priBox' style='overflow:visible'> bug->priList, $pri, "class='form-control'");?> severityBox' style='overflow:visible'>bug->severityList, '3', "class='form-control'");?> - osBox' style='overflow:visible'> bug->osList, $os, "class='form-control chosen'");?> - browserBox' style='overflow:visible'> bug->browserList, $browser, "class='form-control chosen'");?> + osBox' style='overflow:visible'> bug->osList, '', "class='form-control chosen' multiple");?> + browserBox' style='overflow:visible'> bug->browserList, '', "class='form-control chosen' multiple");?> keywordsBox'> loadModel('flow'); diff --git a/module/bug/view/batchedit.html.php b/module/bug/view/batchedit.html.php index 68d5f4bd91..20ecce70db 100644 --- a/module/bug/view/batchedit.html.php +++ b/module/bug/view/batchedit.html.php @@ -132,10 +132,10 @@ unset($assignedToList['closed']); } ?> - ' style='overflow:visible'>assignedTo, "class='form-control picker-select' data-drop-width='135px'");?> + ' style='overflow:visible'>status == 'closed' ? ucfirst($bug->assignedTo) : html::select("assignedTos[$bugID]", $assignedToList, $bug->assignedTo, "class='form-control picker-select' data-drop-width='135px'");?> ' style='overflow:visible'>deadline) ? '' : $bug->deadline, "class='form-control form-date'");?> - >os, 'class=form-control');?> - >browser, 'class=form-control');?> + >bug->osList, $bug->os, 'class="form-control chosen" multiple');?> + >bug->browserList, $bug->browser, 'class="form-control chosen" multiple');?> >keywords, 'class=form-control');?> ' style='overflow:visible'>resolvedBy, "class='form-control picker-select' data-drop-width='auto'");?> > diff --git a/module/bug/view/browse.html.php b/module/bug/view/browse.html.php index b3e3e81c65..248a4d7f4a 100644 --- a/module/bug/view/browse.html.php +++ b/module/bug/view/browse.html.php @@ -403,7 +403,7 @@ $currentBrowseType = isset($lang->bug->mySelects[$browseType]) && in_array($brow
- + 6;?> diff --git a/module/bug/view/linkbugs.html.php b/module/bug/view/linkbugs.html.php index 6f883c20ae..ba9f34c460 100644 --- a/module/bug/view/linkbugs.html.php +++ b/module/bug/view/linkbugs.html.php @@ -90,7 +90,7 @@ $(function() output += checkbox; }); $.closeModal(); - parent.$('#linkBugsBox').html(output); + parent.$('#linkBugsBox').html(output).closest('tr').removeClass('hidden'); return false; }); }); diff --git a/module/bug/view/view.html.php b/module/bug/view/view.html.php index 46013377fa..2b78e900a7 100644 --- a/module/bug/view/view.html.php +++ b/module/bug/view/view.html.php @@ -232,11 +232,29 @@ bug->os;?> - bug->osList[$bug->os];?> + + os);?> + +

+ + " . zget($lang->bug->osList, $os) . "";?> + +

+ + bug->browser;?> - bug->browserList[$bug->browser];?> + + browser);?> + +

+ + " . zget($lang->bug->browserList, $browser) . "";?> + +

+ + bug->keywords;?> diff --git a/module/common/model.php b/module/common/model.php index 98e5f4df58..24e444425c 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -66,7 +66,7 @@ class commonModel extends model if($rawModule == 'execution') { $executionID = $objectID; - $execution = $this->dao->select('id, project, grade, parent')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->fetch(); + $execution = $this->dao->select('id, project, grade, parent, status, deleted')->from(TABLE_EXECUTION)->where('id')->eq($executionID)->fetch(); $this->syncExecutionByChild($execution); $project = $this->syncProjectStatus($execution); $this->syncProgramStatus($project); @@ -153,7 +153,7 @@ class commonModel extends model $today = helper::today(); $parentExecution = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($parentExecutionID)->fetch(); - if($parentExecution->status == 'wait') + if($execution->deleted == '0' and $execution->status == 'doing' and in_array($parentExecution->status, array('wait', 'closed'))) { $this->dao->update(TABLE_EXECUTION) ->set('status')->eq('doing') @@ -163,6 +163,32 @@ class commonModel extends model $this->loadModel('action')->create('execution', $parentExecutionID, 'syncexecutionbychild'); } + if($parentExecution->type == 'stage') + { + $childExecutions = $this->dao->select('*')->from(TABLE_EXECUTION)->where('parent')->eq($parentExecutionID)->andWhere('deleted')->eq('0')->fetchAll('id'); + if($execution->deleted == '1' and count($childExecutions) > 0) + { + $childWait = true; + $childClosed = true; + foreach($childExecutions as $childExecution) + { + if($childExecution->status != 'wait') $childWait = false; + if($childExecution->status != 'closed') $childClosed = false; + } + + if($childWait and $parentExecution->status != 'wait') + { + $this->dao->update(TABLE_EXECUTION)->set('status')->eq('wait')->where('id')->eq($parentExecutionID)->exec(); + $this->loadModel('action')->create('execution', $parentExecutionID, 'waitbychilddelete'); + } + if($childClosed and $parentExecution->status != 'closed') + { + $this->dao->update(TABLE_EXECUTION)->set('status')->eq('closed')->where('id')->eq($parentExecutionID)->exec(); + $this->loadModel('action')->create('execution', $parentExecutionID, 'closebychilddelete'); + } + } + } + return $parentExecution; } @@ -185,6 +211,11 @@ class commonModel extends model { $this->dao->update(TABLE_EXECUTION)->set('status')->eq('doing')->set('realBegan')->eq($today)->where('id')->eq($execution->id)->exec(); $this->loadModel('action')->create('execution', $execution->id, 'syncexecution'); + if($execution->parent) + { + $execution = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($execution->id)->fetch(); // Get updated execution. + $this->syncExecutionByChild($execution); + } } return $execution; } diff --git a/module/execution/config.php b/module/execution/config.php index 57c97990ff..10694f9e4f 100644 --- a/module/execution/config.php +++ b/module/execution/config.php @@ -1,10 +1,11 @@ execution = new stdclass(); -$config->execution->defaultWorkhours = '7.0'; -$config->execution->orderBy = 'isDone,status,order_desc'; -$config->execution->maxBurnDay = '31'; -$config->execution->weekend = '2'; -$config->execution->ownerFields = array('PO', 'PM', 'QD', 'RD'); +$config->execution->defaultWorkhours = '7.0'; +$config->execution->orderBy = 'isDone,status,order_desc'; +$config->execution->maxBurnDay = '31'; +$config->execution->weekend = '2'; +$config->execution->ownerFields = array('PO', 'PM', 'QD', 'RD'); +$config->execution->defaultBurnPeriod = 30; $config->execution->list = new stdclass(); $config->execution->list->exportFields = 'id,name,projectName,code,PM,begin,end,status,totalEstimate,totalConsumed,totalLeft,progress'; diff --git a/module/execution/control.php b/module/execution/control.php index 282e2bedee..c8b7475689 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -469,10 +469,13 @@ class execution extends control * * @param int $executionID * @param int $fromExecution + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID * @access public * @return void */ - public function importTask($toExecution, $fromExecution = 0) + public function importTask($toExecution, $fromExecution = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1) { if(!empty($_POST)) { @@ -509,13 +512,20 @@ class execution extends control $tasks2Imported = zget($tasks, $fromExecution, array()); } + /* Pager. */ + $this->app->loadClass('pager', $static = true); + $recTotal = count($tasks2Imported); + $pager = new pager($recTotal, $recPerPage, $pageID); + $tasks2ImportedList = array_chunk($tasks2Imported, $pager->recPerPage, true); + /* Save session. */ $this->app->session->set('taskList', $this->app->getURI(true), 'execution'); $this->view->title = $execution->name . $this->lang->colon . $this->lang->execution->importTask; + $this->view->pager = $pager; $this->view->position[] = html::a(inlink('browse', "executionID=$toExecution"), $execution->name); $this->view->position[] = $this->lang->execution->importTask; - $this->view->tasks2Imported = $tasks2Imported; + $this->view->tasks2Imported = empty($tasks2ImportedList) ? $tasks2ImportedList : $tasks2ImportedList[$pageID - 1]; $this->view->executions = $executions; $this->view->executionID = $execution->id; $this->view->fromExecution = $fromExecution; @@ -632,7 +642,7 @@ class execution extends control $this->config->bug->search['params']['product']['values'] = array(''=>''); } $this->config->bug->search['params']['execution']['values'] = array(''=>'') + $executions + array('all'=>$this->lang->execution->aboveAllExecution); - $this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairs(array_keys($products)); + $this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairs(array_keys($products)); $this->config->bug->search['module'] = 'importBug'; $this->config->bug->search['params']['confirmed']['values'] = array('' => '') + $this->lang->bug->confirmedList; @@ -2179,15 +2189,9 @@ class execution extends control if(!empty($_POST)) { - $this->loadModel('action'); - $changes = $this->execution->activate($executionID); + $this->execution->activate($executionID); if(dao::isError()) return print(js::error(dao::getError())); - if($this->post->comment != '' or !empty($changes)) - { - $actionID = $this->action->create($this->objectType, $executionID, 'Activated', $this->post->comment); - $this->action->logHistory($actionID, $changes); - } $this->executeHooks($executionID); if(isonlybody() and $from == 'kanban') { @@ -2230,16 +2234,10 @@ class execution extends control if(!empty($_POST)) { - $this->loadModel('action'); $this->execution->computeBurn($executionID); - $changes = $this->execution->close($executionID); + $this->execution->close($executionID); if(dao::isError()) return print(js::error(dao::getError())); - if($this->post->comment != '' or !empty($changes)) - { - $actionID = $this->action->create($this->objectType, $executionID, 'Closed', $this->post->comment); - $this->action->logHistory($actionID, $changes); - } $this->executeHooks($executionID); if(isonlybody() and $from == 'kanban') { @@ -2552,7 +2550,7 @@ class execution extends control { $this->loadModel('project'); $projects = $this->project->getPairsByProgram('', 'noclosed'); - $executions = $this->project->getStats(0, 'all', 0, 0, 30, 'id_desc'); + $executions = $this->execution->getStatData(0, 'all', 0, 0, false, '', 'id_desc'); $teams = $this->dao->select('root,account')->from(TABLE_TEAM) ->where('root')->in($this->app->user->view->sprints) @@ -2890,6 +2888,7 @@ class execution extends control $this->dao->update(TABLE_EXECUTION)->set('deleted')->eq(1)->where('id')->eq($executionID)->exec(); $this->loadModel('action')->create('execution', $executionID, 'deleted', '', ACTIONMODEL::CAN_UNDELETED); $this->execution->updateUserView($executionID); + $this->loadModel('common')->syncPPEStatus($executionID); $this->session->set('execution', ''); $message = $this->executeHooks($executionID); @@ -3731,7 +3730,7 @@ class execution extends control $this->view->title = $this->lang->execution->allExecutions; $this->view->position[] = $this->lang->execution->allExecutions; - $executionStats = $this->project->getStats(0, $status, $productID, 0, 30, $orderBy, $pager, false, $queryID); + $executionStats = $this->execution->getStatData(0, $status, $productID, 0, false, $queryID, $orderBy, $pager); $parentIdList = array(); foreach($executionStats as $execution) @@ -3742,7 +3741,7 @@ class execution extends control $parents = array(); if($parentIdList) $parents = $this->execution->getByIdList($parentIdList); - $allExecutionsNum = $this->project->getStats(0, 'all'); + $allExecutionsNum = $this->execution->getStatData(0, 'all'); $this->view->allExecutionsNum = count($allExecutionsNum); $this->view->executionStats = $executionStats; @@ -3853,7 +3852,7 @@ class execution extends control } $project = $this->project->getByID($projectID); - $executionStats = $this->project->getStats($projectID, $status == 'byproduct' ? 'all' : $status, $productID, 0, 30, 'id_asc'); + $executionStats = $this->execution->getStatData($projectID, $status == 'byproduct' ? 'all' : $status, $productID, 0, false, '', 'id_asc'); if(isset($project->model) and $project->model == 'waterfall') { $stageList = array(); diff --git a/module/execution/js/bug.js b/module/execution/js/bug.js index ce07804c40..7a73ac2808 100644 --- a/module/execution/js/bug.js +++ b/module/execution/js/bug.js @@ -2,4 +2,27 @@ $(function() { if(browseType != 'bysearch') $('#module' + param).closest('li').addClass('active'); if($('#bugList thead th.c-title').width() < 150) $('#bugList thead th.c-title').width(150); + + $('#bugList').on('change', "[name='bugIDList[]']", checkClosed); }); + +/** + * Closed bugs are not assignable. + * + * @access public + * @return void + */ +function checkClosed() +{ + var disabledAssigned = $('#bugList tr.checked .c-assignedTo a').length > 0 ? true : false; + $('#bugList tr.checked .c-assignedTo a').each(function() + { + if(!$(this).hasClass('disabled')) + { + disabledAssigned = false; + return false; + } + }); + + $('#mulAssigned').prop('disabled', disabledAssigned); +} diff --git a/module/execution/lang/de.php b/module/execution/lang/de.php index 7ab7927d18..1cc9cb51bd 100644 --- a/module/execution/lang/de.php +++ b/module/execution/lang/de.php @@ -536,10 +536,19 @@ $lang->execution->treeLevel['task'] = 'Aufgabe anzeigen'; $lang->execution->treeLevel['story'] = 'Story anzeigen'; $lang->execution->action = new stdclass(); -$lang->execution->action->opened = '$date, created by $actor. $extra' . "\n"; -$lang->execution->action->managed = '$date, managed by $actor. $extra' . "\n"; -$lang->execution->action->edited = '$date, edited by $actor. $extra' . "\n"; -$lang->execution->action->extra = 'Linked products is %s.'; +$lang->execution->action->opened = '$date, created by $actor. $extra' . "\n"; +$lang->execution->action->managed = '$date, managed by $actor. $extra' . "\n"; +$lang->execution->action->edited = '$date, edited by $actor. $extra' . "\n"; +$lang->execution->action->extra = 'Linked products is %s.'; +$lang->execution->action->startbychildactivate = '$date, activating the sub stage sets the execution status as Ongoing.' . "\n"; +$lang->execution->action->waitbychilddelete = '$date, deleting the sub stage sets the execution status as waitting.' . "\n"; +$lang->execution->action->closebychilddelete = '$date, deleting the sub stage sets the execution status as closing.' . "\n"; +$lang->execution->action->closebychildclose = '$date, closing the sub stage sets the execution status as closing.' . "\n"; + +$lang->execution->startbychildactivate = 'activated'; +$lang->execution->waitbychilddelete = 'stop'; +$lang->execution->closebychilddelete = 'closed'; +$lang->execution->closebychildclose = 'closed'; $lang->execution->statusColorList = array(); $lang->execution->statusColorList['wait'] = '#0991FF'; diff --git a/module/execution/lang/en.php b/module/execution/lang/en.php index cf11af6af7..4c34595681 100644 --- a/module/execution/lang/en.php +++ b/module/execution/lang/en.php @@ -536,10 +536,19 @@ $lang->execution->treeLevel['task'] = 'Stories&Tasks'; $lang->execution->treeLevel['story'] = 'Only Stories'; $lang->execution->action = new stdclass(); -$lang->execution->action->opened = '$date, created by $actor. $extra' . "\n"; -$lang->execution->action->managed = '$date, managed by $actor. $extra' . "\n"; -$lang->execution->action->edited = '$date, edited by $actor. $extra' . "\n"; -$lang->execution->action->extra = 'Linked products is %s.'; +$lang->execution->action->opened = '$date, created by $actor. $extra' . "\n"; +$lang->execution->action->managed = '$date, managed by $actor. $extra' . "\n"; +$lang->execution->action->edited = '$date, edited by $actor. $extra' . "\n"; +$lang->execution->action->extra = 'Linked products is %s.'; +$lang->execution->action->startbychildactivate = '$date, activating the sub stage sets the execution status as Ongoing.' . "\n"; +$lang->execution->action->waitbychilddelete = '$date, deleting the sub stage sets the execution status as waitting.' . "\n"; +$lang->execution->action->closebychilddelete = '$date, deleting the sub stage sets the execution status as closing.' . "\n"; +$lang->execution->action->closebychildclose = '$date, closing the sub stage sets the execution status as closing.' . "\n"; + +$lang->execution->startbychildactivate = 'activated'; +$lang->execution->waitbychilddelete = 'stop'; +$lang->execution->closebychilddelete = 'closed'; +$lang->execution->closebychildclose = 'closed'; $lang->execution->statusColorList = array(); $lang->execution->statusColorList['wait'] = '#0991FF'; diff --git a/module/execution/lang/fr.php b/module/execution/lang/fr.php index 6dea9a32aa..3e71a37d6b 100644 --- a/module/execution/lang/fr.php +++ b/module/execution/lang/fr.php @@ -536,10 +536,19 @@ $lang->execution->treeLevel['task'] = 'Stories&Tâches'; $lang->execution->treeLevel['story'] = 'Seulement Stories'; $lang->execution->action = new stdclass(); -$lang->execution->action->opened = '$date, created by $actor. $extra' . "\n"; -$lang->execution->action->managed = '$date, managed by $actor. $extra' . "\n"; -$lang->execution->action->edited = '$date, edited by $actor. $extra' . "\n"; -$lang->execution->action->extra = 'Linked products is %s.'; +$lang->execution->action->opened = '$date, created by $actor. $extra' . "\n"; +$lang->execution->action->managed = '$date, managed by $actor. $extra' . "\n"; +$lang->execution->action->edited = '$date, edited by $actor. $extra' . "\n"; +$lang->execution->action->extra = 'Linked products is %s.'; +$lang->execution->action->startbychildactivate = '$date, activating the sub stage sets the execution status as Ongoing.' . "\n"; +$lang->execution->action->waitbychilddelete = '$date, deleting the sub stage sets the execution status as waitting.' . "\n"; +$lang->execution->action->closebychilddelete = '$date, deleting the sub stage sets the execution status as closing.' . "\n"; +$lang->execution->action->closebychildclose = '$date, closing the sub stage sets the execution status as closing.' . "\n"; + +$lang->execution->startbychildactivate = 'activated'; +$lang->execution->waitbychilddelete = 'stop'; +$lang->execution->closebychilddelete = 'closed'; +$lang->execution->closebychildclose = 'closed'; $lang->execution->statusColorList = array(); $lang->execution->statusColorList['wait'] = '#0991FF'; diff --git a/module/execution/lang/zh-cn.php b/module/execution/lang/zh-cn.php index a064ccd15c..046e868a9d 100644 --- a/module/execution/lang/zh-cn.php +++ b/module/execution/lang/zh-cn.php @@ -536,10 +536,19 @@ $lang->execution->treeLevel['task'] = '全部显示'; $lang->execution->treeLevel['story'] = "只看{$lang->SRCommon}"; $lang->execution->action = new stdclass(); -$lang->execution->action->opened = '$date, 由 $actor 创建。$extra' . "\n"; -$lang->execution->action->managed = '$date, 由 $actor 维护。$extra' . "\n"; -$lang->execution->action->edited = '$date, 由 $actor 编辑。$extra' . "\n"; -$lang->execution->action->extra = '相关产品为 %s。'; +$lang->execution->action->opened = '$date, 由 $actor 创建。$extra' . "\n"; +$lang->execution->action->managed = '$date, 由 $actor 维护。$extra' . "\n"; +$lang->execution->action->edited = '$date, 由 $actor 编辑。$extra' . "\n"; +$lang->execution->action->extra = '相关产品为 %s。'; +$lang->execution->action->startbychildactivate = '$date, 系统判断由于子阶段激活,将' . $lang->executionCommon . '状态置为进行中。' . "\n"; +$lang->execution->action->waitbychilddelete = '$date, 系统判断由于子阶段删除,将' . $lang->executionCommon . '状态置为未开始。' . "\n"; +$lang->execution->action->closebychilddelete = '$date, 系统判断由于子阶段删除,将' . $lang->executionCommon . '状态置为已关闭。' . "\n"; +$lang->execution->action->closebychildclose = '$date, 系统判断由于子阶段关闭,将' . $lang->executionCommon . '状态置为已关闭。' . "\n"; + +$lang->execution->startbychildactivate = '激活了'; +$lang->execution->waitbychilddelete = '停止了'; +$lang->execution->closebychilddelete = '关闭了'; +$lang->execution->closebychildclose = '关闭了'; $lang->execution->statusColorList = array(); $lang->execution->statusColorList['wait'] = '#0991FF'; diff --git a/module/execution/model.php b/module/execution/model.php index fdfc3479c8..39756b26b9 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -1005,17 +1005,24 @@ class executionModel extends model } } + $changes = common::createChanges($oldExecution, $execution); + if($this->post->comment != '' or !empty($changes)) + { + $this->loadModel('action'); + $actionID = $this->action->create('execution', $executionID, 'Activated', $this->post->comment); + $this->action->logHistory($actionID, $changes); + } + /* Update the status of the parent stage. */ if($oldExecution->type == 'stage') { $parent = $this->getByID($oldExecution->parent); - if($parent->type == 'stage' and $parent->status == 'closed') + if($parent->type == 'stage' and in_array($parent->status, array('closed', 'wait'))) { $this->dao->update(TABLE_EXECUTION)->set('status')->eq('doing')->where('id')->eq($parent->id)->exec(); + $this->loadModel('action')->create('execution', $parent->id, 'startbychildactivate'); } } - - if(!dao::isError()) return common::createChanges($oldExecution, $execution); } /** @@ -1058,6 +1065,15 @@ class executionModel extends model if(!dao::isError()) { + + $changes = common::createChanges($oldExecution, $execution); + if($this->post->comment != '' or !empty($changes)) + { + $this->loadModel('action'); + $actionID = $this->action->create('execution', $executionID, 'Closed', $this->post->comment); + $this->action->logHistory($actionID, $changes); + } + /* Update the status of the parent stage. */ if($oldExecution->type == 'stage') { @@ -1071,12 +1087,15 @@ class executionModel extends model if($childExecution->status != 'closed') $isClosed = false; } - if($isClosed) $this->dao->update(TABLE_EXECUTION)->set('status')->eq('closed')->where('id')->eq($parent->id)->exec(); + if($isClosed) + { + $this->dao->update(TABLE_EXECUTION)->set('status')->eq('closed')->where('id')->eq($parent->id)->exec(); + $this->loadModel('action')->create('execution', $parent->id, 'closebychildclose'); + } } } $this->loadModel('score')->create('execution', 'close', $oldExecution); - return common::createChanges($oldExecution, $execution); } } @@ -1409,6 +1428,129 @@ class executionModel extends model ->fetchPairs('id', 'id'); } + /** + * Get execution stat data. + + * @param int $projectID + * @param string $browseType all|undone|wait|doing|suspended|closed|involved|bySearch|review + * @param int $productID + * @param int $branch + * @param bool $withTasks + * @param string|int $param skipParent + * @param string $orderBy + * @param object $pager + * @access public + * @return array + */ + public function getStatData($projectID = 0, $browseType = 'undone', $productID = 0, $branch = 0, $withTasks = false, $param = '', $orderBy = 'id_asc', $pager = null) + { + /* Construct the query SQL at search executions. */ + $executionQuery = ''; + if($browseType == 'bySearch') + { + $queryID = (int)$param; + if($queryID) + { + $query = $this->loadModel('search')->getQuery($queryID); + if($query) + { + $this->session->set('executionQuery', $query->sql); + $this->session->set('executionForm', $query->form); + } + } + if($this->session->executionQuery == false) $this->session->set('executionQuery', ' 1 = 1'); + + $executionQuery = $this->session->executionQuery; + $allProject = "`project` = 'all'"; + + if(strpos($executionQuery, $allProject) !== false) $executionQuery = str_replace($allProject, '1', $executionQuery); + $executionQuery = preg_replace('/(`\w*`)/', 't1.$1',$executionQuery); + } + + /* Get involved executions. */ + $myExecutionIDList = array(); + if($browseType == 'involved') + { + $myExecutionIDList = $this->dao->select('root')->from(TABLE_TEAM) + ->where('account')->eq($this->app->user->account) + ->andWhere('type')->eq('execution') + ->fetchPairs(); + } + + $executions = $this->dao->select('t1.*,t2.name projectName, t2.model as projectModel')->from(TABLE_EXECUTION)->alias('t1') + ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id') + ->beginIF($productID)->leftJoin(TABLE_PROJECTPRODUCT)->alias('t3')->on('t1.id=t3.project')->fi() + ->where('t1.type')->in('sprint,stage,kanban') + ->andWhere('t1.deleted')->eq('0') + ->andWhere('t1.vision')->eq($this->config->vision) + ->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->sprints)->fi() + ->beginIF(!empty($executionQuery))->andWhere($executionQuery)->fi() + ->beginIF($productID)->andWhere('t3.product')->eq($productID)->fi() + ->beginIF($projectID)->andWhere('t1.project')->eq($projectID)->fi() + ->beginIF(!in_array($browseType, array('all', 'undone', 'involved', 'review', 'bySearch')))->andWhere('t1.status')->eq($browseType)->fi() + ->beginIF($browseType == 'undone')->andWhere('t1.status')->notIN('done,closed')->fi() + ->beginIF($browseType == 'review') + ->andWhere("FIND_IN_SET('{$this->app->user->account}', t1.reviewers)") + ->andWhere('t1.reviewStatus')->eq('doing') + ->fi() + ->orderBy($orderBy) + ->page($pager) + ->fetchAll('id'); + + $hours = $this->loadModel('project')->computerProgress($executions); + $burns = $this->getBurnData($executions); + + if($withTasks) $executionTasks = $this->getTaskGroupByExecution(array_keys($executions)); + + /* Process executions. */ + $this->app->loadConfig('task'); + + $emptyHour = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'progress' => 0); + $today = helper::today(); + foreach($executions as $key => $execution) + { + /* Process the end time. */ + $execution->end = date(DT_DATE1, strtotime($execution->end)); + + /* Judge whether the execution is delayed. */ + if($execution->status != 'done' and $execution->status != 'closed' and $execution->status != 'suspended') + { + $delay = helper::diffDate($today, $execution->end); + if($delay > 0) $execution->delay = $delay; + } + + /* Process the burns. */ + $execution->burns = array(); + $burnData = isset($burns[$execution->id]) ? $burns[$execution->id] : array(); + foreach($burnData as $data) $execution->burns[] = $data->value; + + /* Process the hours. */ + $execution->hours = isset($hours[$execution->id]) ? $hours[$execution->id] : (object)$emptyHour; + + if(isset($executionTasks) and isset($executionTasks[$execution->id])) + { + $tasks = array_chunk($executionTasks[$execution->id], $this->config->task->defaultLoadCount, true); + $execution->tasks = $tasks[0]; + } + + /* In the case of the waterfall model, calculate the sub-stage. */ + if($param == 'skipParent') + { + if($execution->parent < 0 and $execution->type == 'stage') unset($executions[$key]); + if($this->config->systemMode == 'new' and $execution->projectName) $execution->name = $execution->projectName . ' / ' . $execution->name; + } + else + { + if(isset($executions[$execution->parent]) and $execution->type == 'stage') + { + $executions[$execution->parent]->children[$key] = $execution; + unset($executions[$key]); + } + } + } + return array_values($executions); + } + /** * Get executions by project. * @@ -1800,6 +1942,38 @@ class executionModel extends model return $tasks; } + /** + * Get the task data group by execution id list. + * + * @param array $executionIdList + * @access public + * @return array + */ + public function getTaskGroupByExecution($executionIdList = array()) + { + if(empty($executionIdList)) return array(); + $executionTasks = $this->dao->select('*')->from(TABLE_TASK) + ->where('deleted')->eq(0) + ->andWhere('status')->notin('closed,cancel') + ->andWhere('execution')->in($executionIdList) + ->orderBy('id_asc') + ->fetchGroup('execution', 'id'); + + foreach($executionTasks as $executionID => $tasks) + { + foreach($tasks as $task) + { + if($task->parent > 0 and isset($executionTasks[$executionID][$task->parent])) + { + $executionTasks[$executionID][$task->parent]->children[$task->id] = $task; + unset($executionTasks[$executionID][$task->id]); + } + } + } + + return $executionTasks; + } + /** * Get the execution by ID. * @@ -3236,6 +3410,47 @@ class executionModel extends model return $burnData; } + /** + * Get execution burn data. + * + * @param array $executions + * @access public + * @return array + */ + public function getBurnData($executions) + { + if(empty($executions)) return array(); + + /* Get burndown charts datas. */ + $burns = $this->dao->select('execution, date AS name, `left` AS value') + ->from(TABLE_BURN) + ->where('execution')->in(array_keys($executions)) + ->andWhere('task')->eq(0) + ->orderBy('date desc') + ->fetchGroup('execution', 'name'); + + foreach($burns as $executionID => $executionBurns) + { + /* If executionBurns > $itemCounts, split it, else call processBurnData() to pad burns. */ + $begin = $executions[$executionID]->begin; + $end = $executions[$executionID]->end; + if(helper::isZeroDate($begin)) $begin = $executions[$executionID]->openedDate; + $executionBurns = $this->processBurnData($executionBurns, $this->config->execution->defaultBurnPeriod, $begin, $end); + + /* Shorter names. */ + foreach($executionBurns as $executionBurn) + { + $executionBurn->name = substr($executionBurn->name, 5); + unset($executionBurn->execution); + } + + ksort($executionBurns); + $burns[$executionID] = $executionBurns; + } + + return $burns; + } + /** * Process burndown datas when the sets is smaller than the itemCounts. * diff --git a/module/execution/view/bug.html.php b/module/execution/view/bug.html.php index 0dcf920a7a..606c7aee68 100644 --- a/module/execution/view/bug.html.php +++ b/module/execution/view/bug.html.php @@ -162,7 +162,7 @@
- + 10; $actionLink = $this->createLink('bug', 'batchAssignTo', "executionID={$execution->id}&type=execution"); diff --git a/module/execution/view/importtask.html.php b/module/execution/view/importtask.html.php index 0b5eab0383..3eb2618aad 100644 --- a/module/execution/view/importtask.html.php +++ b/module/execution/view/importtask.html.php @@ -95,6 +95,7 @@
+ show('right', 'pagerjs');?>
diff --git a/module/install/lang/de.php b/module/install/lang/de.php index 5c7d739bf6..ac375fa988 100644 --- a/module/install/lang/de.php +++ b/module/install/lang/de.php @@ -162,7 +162,7 @@ $lang->install->account = 'Admin Konto'; $lang->install->password = 'Admin Passwort'; $lang->install->placeholder = new stdclass(); -$lang->install->placeholder->password = 'Combination of letters, numbers and special symbols, at least 6 characters'; +$lang->install->placeholder->password = 'The Password should be ≥ 6 characters, combination of uppercase, lowercase letters and numbers.'; $lang->install->errorEmpty['company'] = "{$lang->install->company} should not be blank."; $lang->install->errorEmpty['account'] = "{$lang->install->account} should not be blank."; diff --git a/module/install/lang/en.php b/module/install/lang/en.php index cfba4afa3c..ae67f6612d 100644 --- a/module/install/lang/en.php +++ b/module/install/lang/en.php @@ -162,7 +162,7 @@ $lang->install->account = 'Admin Account'; $lang->install->password = 'Admin Password'; $lang->install->placeholder = new stdclass(); -$lang->install->placeholder->password = 'Combination of letters, numbers and special symbols, at least 6 characters'; +$lang->install->placeholder->password = 'The Password should be ≥ 6 characters, combination of uppercase, lowercase letters and numbers.'; $lang->install->errorEmpty['company'] = "{$lang->install->company} should not be blank."; $lang->install->errorEmpty['account'] = "{$lang->install->account} should not be blank."; diff --git a/module/install/lang/fr.php b/module/install/lang/fr.php index c5d7bfad74..ffa59af709 100644 --- a/module/install/lang/fr.php +++ b/module/install/lang/fr.php @@ -162,7 +162,7 @@ $lang->install->account = 'Compte Admin'; $lang->install->password = 'Mot de Passe Admin'; $lang->install->placeholder = new stdclass(); -$lang->install->placeholder->password = 'Combination of letters, numbers and special symbols, at least 6 characters'; +$lang->install->placeholder->password = 'Le mot de passe doit ≥ 6 caractères, combinaison de lettres majuscules, minuscules et de chiffres.'; $lang->install->errorEmpty['company'] = "{$lang->install->company} should not be blank."; $lang->install->errorEmpty['account'] = "{$lang->install->account} should not be blank."; diff --git a/module/install/lang/zh-cn.php b/module/install/lang/zh-cn.php index 0b4042c8b7..14dd84cb04 100644 --- a/module/install/lang/zh-cn.php +++ b/module/install/lang/zh-cn.php @@ -162,7 +162,7 @@ $lang->install->account = '管理员帐号'; $lang->install->password = '管理员密码'; $lang->install->placeholder = new stdclass(); -$lang->install->placeholder->password = '六位及以上,包含数字、字母和特殊字符'; +$lang->install->placeholder->password = '6位及以上,包含大小写字母,数字。'; $lang->install->errorEmpty['company'] = "{$lang->install->company}不能为空"; $lang->install->errorEmpty['account'] = "{$lang->install->account}不能为空"; diff --git a/module/install/model.php b/module/install/model.php index 8d4b8d65c3..4d4d302c96 100644 --- a/module/install/model.php +++ b/module/install/model.php @@ -516,14 +516,13 @@ class installModel extends model } } + $this->loadModel('user'); + $this->app->loadConfig('admin'); /* Check password. */ if(!validater::checkReg($this->post->password, '|(.){6,}|')) dao::$errors['password'][] = $this->lang->error->passwordrule; - if(isset($this->config->safe->mode) and (strlen($this->post->password) < $this->config->safe->mode)) dao::$errors['password'][] = $this->lang->user->weakPassword; - if(!empty($this->config->safe->changeWeak)) - { - if(!isset($this->config->safe->weak)) $this->app->loadConfig('admin'); - if(strpos(",{$this->config->safe->weak},", ",{$this->post->password},") !== false) dao::$errors['password'][] = sprintf($this->lang->user->errorWeak, $this->config->safe->weak); - } + if($this->user->computePasswordStrength($this->post->password) < 1) dao::$errors['password'][] = $this->lang->user->placeholder->passwordStrengthCheck[1]; + if(!isset($this->config->safe->weak)) $this->app->loadConfig('admin'); + if(strpos(",{$this->config->safe->weak},", ",{$this->post->password},") !== false) dao::$errors['password'] = sprintf($this->lang->user->errorWeak, $this->config->safe->weak); if(dao::isError()) return false; /* Insert a company. */ diff --git a/module/kanban/control.php b/module/kanban/control.php index 3f3b9f82b0..e58bca853b 100644 --- a/module/kanban/control.php +++ b/module/kanban/control.php @@ -1353,7 +1353,7 @@ class kanban extends control $this->view->projects = array($this->lang->kanban->allProjects) + $this->project->getPairsByProgram(); $this->view->selectedProjectID = $selectedProjectID; $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID); - $this->view->executions2Imported = $this->project->getStats($selectedProjectID, 'undone', 0, 0, 30, 'id_asc', $pager); + $this->view->executions2Imported = $this->execution->getStatData($selectedProjectID, 'undone', 0, 0, false, '', 'id_asc', $pager); $this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted'); $this->view->pager = $pager; $this->view->kanbanID = $kanbanID; diff --git a/module/kanban/model.php b/module/kanban/model.php index 020e6ab7d9..a0e0f05747 100755 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -1664,6 +1664,7 @@ class kanbanModel extends model if(in_array($groupBy, array('type', 'category', 'source')) and $object->$groupBy !== $laneID) continue; if($groupBy == 'assignedTo') { + $laneID = (string)$laneID; if(empty($object->team) and $object->$groupBy !== $laneID) continue; if(!empty($object->team) and !in_array($laneID, array_keys($object->team), true)) continue; diff --git a/module/my/view/changepassword.html.php b/module/my/view/changepassword.html.php index 42cd5db2e3..4fc172707a 100755 --- a/module/my/view/changepassword.html.php +++ b/module/my/view/changepassword.html.php @@ -54,8 +54,9 @@ app->user->modifyPasswordReason)):?> app->loadLang('admin');?>
+ app->user->modifyPasswordReason;?> admin->safe->common . ' : ';?> - app->user->modifyPasswordReason == 'weak' ? $lang->admin->safe->changeWeak : $lang->admin->safe->modifyPasswordFirstLogin;?> + admin->safe->changeWeak : $lang->admin->safe->$reason;?>
diff --git a/module/project/control.php b/module/project/control.php index fd90e7168d..fe97348180 100644 --- a/module/project/control.php +++ b/module/project/control.php @@ -1024,13 +1024,13 @@ class project extends control $this->app->loadClass('pager', $static = true); $pager = new pager($recTotal, $recPerPage, $pageID); - $allExecution = $this->project->getStats($projectID, 'all'); + $allExecution = $this->execution->getStatData($projectID, 'all'); $this->view->allExecutionNum = empty($allExecution); $this->view->title = $this->lang->execution->allExecutions; $this->view->position[] = $this->lang->execution->allExecutions; - $this->view->executionStats = $this->project->getStats($projectID, $status, $productID, 0, 30, $orderBy, $pager, $this->cookie->showTask); + $this->view->executionStats = $this->execution->getStatData($projectID, $status, $productID, 0, $this->cookie->showTask, '', $orderBy, $pager); $this->view->productList = $this->loadModel('product')->getProductPairsByProject($projectID); $this->view->productID = $productID; $this->view->projectID = $projectID; diff --git a/module/project/model.php b/module/project/model.php index 57e1968acd..1bd12fd0cb 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -240,7 +240,7 @@ class projectModel extends model { $orderBy = $project->model == 'waterfall' ? 'id_asc' : 'id_desc'; $pager = $project->model == 'waterfall' ? null : new pager(0, 1, 1); - $project->executions = $this->getStats($projectID, 'undone', 0, 0, 30, $orderBy, $pager); + $project->executions = $this->loadModel('execution')->getStatData($projectID, 'undone', 0, 0, false, '', $orderBy, $pager); $project->teamCount = isset($teams[$projectID]) ? $teams[$projectID]->count : 0; $project->estimate = isset($estimates[$projectID]) ? round($estimates[$projectID]->estimate, 2) : 0; $project->parentName = $this->getParentProgram($project); @@ -2263,215 +2263,6 @@ class projectModel extends model ->fetchAll('account'); } - /** - * Get project stats. - * - * @param int $projectID - * @param string $status - * @param int $productID - * @param int $branch - * @param int $itemCounts - * @param string $orderBy - * @param object $pager - * @param bool $withTasks - * @param int $queryID - * @access public - * @return array - */ - public function getStats($projectID = 0, $status = 'undone', $productID = 0, $branch = 0, $itemCounts = 30, $orderBy = 'id_asc', $pager = null, $withTasks = false, $queryID = 0) - { - if(empty($productID)) - { - $myExecutionIDList = array(); - $query = ''; - if($status == 'bySearch') - { - $status = 'all'; - if($queryID) - { - $query = $this->loadModel('search')->getQuery($queryID); - if($query) - { - $this->session->set('executionQuery', $query->sql); - $this->session->set('executionForm', $query->form); - } - else - { - $this->session->set('executionQuery', ' 1 = 1'); - } - } - else - { - if($this->session->executionQuery == false) $this->session->set('executionQuery', ' 1 = 1'); - } - $query = $this->session->executionQuery; - $allProject = "`project` = 'all'"; - - if(strpos($query, $allProject) !== false) $query = str_replace($allProject, '1', $query); - $query = preg_replace('/(`\w*`)/', 't1.$1',$query); - } - - if($status == 'involved') - { - $myExecutionIDList = $this->dao->select('root')->from(TABLE_TEAM) - ->where('account')->eq($this->app->user->account) - ->andWhere('type')->eq('execution') - ->fetchPairs(); - } - - $executions = $this->dao->select('t1.*,t2.name projectName, t2.model as projectModel')->from(TABLE_EXECUTION)->alias('t1') - ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id') - ->where('t1.type')->in('sprint,stage,kanban') - ->beginIF(!empty($query))->andWhere($query)->fi() - ->beginIF($projectID != 0)->andWhere('t1.project')->eq($projectID)->fi() - ->beginIF($projectID == 0 and $this->config->vision)->andWhere('t1.vision')->eq($this->config->vision)->fi() - ->beginIF(!empty($myExecutionIDList))->andWhere('t1.id')->in(array_keys($myExecutionIDList))->fi() - ->beginIF($status == 'undone')->andWhere('t1.status')->notIN('done,closed')->fi() - ->beginIF(!in_array($status, array('all', 'undone', 'involved', 'review'), true))->andWhere('t1.status')->eq($status)->fi() - ->beginIF($status == 'review') - ->andWhere("FIND_IN_SET('{$this->app->user->account}', t1.reviewers)") - ->andWhere('t1.reviewStatus')->eq('doing') - ->fi() - ->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->sprints)->fi() - ->andWhere('t1.vision')->eq($this->config->vision) - ->andWhere('t1.deleted')->eq('0') - ->orderBy($orderBy) - ->page($pager) - ->fetchAll('id'); - } - else - { - $executions = $this->dao->select('t2.*,t3.name projectName, t3.model as projectModel')->from(TABLE_PROJECTPRODUCT)->alias('t1') - ->leftJoin(TABLE_EXECUTION)->alias('t2')->on('t1.project=t2.id') - ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t2.project=t3.id') - ->where('t1.product')->eq($productID) - ->beginIF($projectID)->andWhere('t2.project')->eq($projectID)->fi() - ->beginIF($status == 'undone')->andWhere('t2.status')->notIN('done,closed')->fi() - ->beginIF($status != 'all' and $status != 'undone')->andWhere('t2.status')->eq($status)->fi() - ->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->sprints)->fi() - ->andWhere('t2.deleted')->eq('0') - ->andWhere('t2.vision')->eq($this->config->vision) - ->orderBy($orderBy) - ->page($pager) - ->fetchAll('id'); - } - - $hours = $this->computerProgress($executions); - $emptyHour = array('totalEstimate' => 0, 'totalConsumed' => 0, 'totalLeft' => 0, 'progress' => 0); - - /* Get burndown charts datas. */ - $burns = $this->dao->select('execution, date AS name, `left` AS value') - ->from(TABLE_BURN) - ->where('execution')->in(array_keys($executions)) - ->andWhere('task')->eq(0) - ->orderBy('date desc') - ->fetchGroup('execution', 'name'); - - $this->loadModel('execution'); - foreach($burns as $executionID => $executionBurns) - { - /* If executionBurns > $itemCounts, split it, else call processBurnData() to pad burns. */ - $begin = $executions[$executionID]->begin; - $end = $executions[$executionID]->end; - if(helper::isZeroDate($begin)) $begin = $executions[$executionID]->openedDate; - $executionBurns = $this->execution->processBurnData($executionBurns, $itemCounts, $begin, $end); - - /* Shorter names. */ - foreach($executionBurns as $executionBurn) - { - $executionBurn->name = substr($executionBurn->name, 5); - unset($executionBurn->execution); - } - - ksort($executionBurns); - $burns[$executionID] = $executionBurns; - } - - if($withTasks) - { - $executionTasks = $this->dao->select('*')->from(TABLE_TASK) - ->where('deleted')->eq(0) - ->andWhere('status')->notin('closed,cancel') - ->andWhere('execution')->in(array_keys($executions)) - ->orderBy('id_asc') - ->fetchGroup('execution', 'id'); - - foreach($executionTasks as $executionID => $tasks) - { - foreach($tasks as $task) - { - if($task->parent > 0) - { - if(isset($executionTasks[$executionID][$task->parent])) - { - $executionTasks[$executionID][$task->parent]->children[$task->id] = $task; - unset($executionTasks[$executionID][$task->id]); - } - } - } - } - } - - /* Process executions. */ - $parents = array(); - $children = array(); - foreach($executions as $key => $execution) - { - /* Process the end time. */ - $execution->end = date(DT_DATE1, strtotime($execution->end)); - - /* Judge whether the execution is delayed. */ - if($execution->status != 'done' and $execution->status != 'closed' and $execution->status != 'suspended') - { - $delay = helper::diffDate(helper::today(), $execution->end); - if($delay > 0) $execution->delay = $delay; - } - - /* Process the burns. */ - $execution->burns = array(); - $burnData = isset($burns[$execution->id]) ? $burns[$execution->id] : array(); - foreach($burnData as $data) $execution->burns[] = $data->value; - - /* Process the hours. */ - $execution->hours = isset($hours[$execution->id]) ? $hours[$execution->id] : (object)$emptyHour; - - $execution->children = array(); - $execution->grade == 1 ? $parents[$execution->id] = $execution : $children[$execution->parent][] = $execution; - if(isset($executionTasks) and isset($executionTasks[$execution->id])) - { - $tasks = array_chunk($executionTasks[$execution->id], 50, true); - $execution->tasks = $tasks[0]; - } - } - - /* In the case of the waterfall model, calculate the sub-stage. */ - if($projectID == 0) - { - foreach($executions as $key => $execution) - { - if($execution->type == 'stage') - { - $execution->children = isset($children[$execution->id]) ? $children[$execution->id] : array(); - unset($children[$execution->id]); - } - } - } - $project = $this->getByID($projectID); - if($project and $project->model == 'waterfall') - { - foreach($parents as $id => $execution) - { - $execution->children = isset($children[$id]) ? $children[$id] : array(); - unset($children[$id]); - } - } - - $orphan = array(); - foreach($children as $child) $orphan = array_merge($child, $orphan); - - return array_merge($parents, $orphan); - } - /** * Get stats for project kanban. * @@ -2483,7 +2274,7 @@ class projectModel extends model $this->loadModel('program'); $projects = $this->program->getProjectStats(0, 'all', 0, 'order_asc'); - $executions = $this->getStats(0, 'doing'); + $executions = $this->loadModel('execution')->getStatData(0, 'doing'); $doingExecutions = array(); $latestExecutions = array(); diff --git a/module/search/model.php b/module/search/model.php index 0c17675817..742cf697ea 100644 --- a/module/search/model.php +++ b/module/search/model.php @@ -215,10 +215,19 @@ class searchModel extends model $condition = '`' . $this->post->$fieldName . "` >= '$value' AND `" . $this->post->$fieldName . "` <= '$value 23:59:59'"; $where .= " $andOr ($condition)"; } + elseif($operator == '!=' and preg_match('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/', $value)) + { + $condition = '`' . $this->post->$fieldName . "` < '$value' OR `" . $this->post->$fieldName . "` > '$value 23:59:59'"; + $where .= " $andOr ($condition)"; + } elseif($operator == '<=' and preg_match('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/', $value)) { $where .= " $andOr " . '`' . $this->post->$fieldName . "` <= '$value 23:59:59'"; } + elseif($operator == '>' and preg_match('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/', $value)) + { + $where .= " $andOr " . '`' . $this->post->$fieldName . "` > '$value 23:59:59'"; + } elseif($condition) { $where .= " $andOr " . '`' . $this->post->$fieldName . '` ' . $condition; diff --git a/module/task/config.php b/module/task/config.php index 9068d4a030..b14fdcb456 100644 --- a/module/task/config.php +++ b/module/task/config.php @@ -41,6 +41,7 @@ $config->task->exportFields = ' $config->task->customCreateFields = 'story,estStarted,deadline,mailto,pri,estimate'; $config->task->customBatchCreateFields = 'module,story,assignedTo,estimate,estStarted,deadline,desc,pri'; $config->task->customBatchEditFields = 'module,assignedTo,status,pri,estimate,record,left,estStarted,deadline,finishedBy,canceledBy,closedBy,closedReason'; +$config->task->defaultLoadCount = 50; $config->task->custom = new stdclass(); $config->task->custom->createFields = $config->task->customCreateFields; diff --git a/module/testcase/model.php b/module/testcase/model.php index fd02631f3b..b626241bc0 100644 --- a/module/testcase/model.php +++ b/module/testcase/model.php @@ -702,6 +702,24 @@ class testcaseModel extends model ->fetchAll('id'); } + /** + * Get case pairs by product id and branch. + * + * @param int $productID + * @param int|string $branch + * @access public + * @return void + */ + public function getPairsByProduct($productID, $branch = 0) + { + return $this->dao->select('id, concat_ws(":", id, title) as title')->from(TABLE_CASE) + ->where('deleted')->eq(0) + ->andWhere('product')->eq($productID) + ->beginIF($branch)->andWhere('branch')->in($branch)->fi() + ->orderBy('id_desc') + ->fetchPairs(); + } + /** * Get cases of a story. * diff --git a/module/upgrade/model.php b/module/upgrade/model.php index 793c336335..d62ac53853 100644 --- a/module/upgrade/model.php +++ b/module/upgrade/model.php @@ -543,6 +543,9 @@ class upgradeModel extends model } } break; + case '17_5': + $this->updateOSAndBrowserOfBug(); + break; } $this->deletePatch(); @@ -7089,4 +7092,31 @@ class upgradeModel extends model return $result->rowCount() > 0; } + + /** + * Update OS and browser of bug. + * + * @access public + * @return bool + */ + public function updateOSAndBrowserOfBug() + { + $existOSList = $this->dao->select('distinct os')->from(TABLE_BUG)->where('os')->ne('')->fetchPairs(); + $existBrowserList = $this->dao->select('distinct browser')->from(TABLE_BUG)->where('os')->ne('')->fetchPairs(); + $deletedOSList = array('vista', 'win2012', 'win2008', 'win2003', 'win2000', 'wp8', 'wp7', 'symbian', 'freebsd'); + $deletedBrowserList = array('ie7', 'ie6', 'firefox4', 'firefox3', 'firefox2', 'oprea11', 'oprea10', 'oprea9', 'maxthon', 'uc'); + $existList = array_merge($existOSList, $existBrowserList); + $deletedList = array_merge($deletedOSList, $deletedBrowserList); + + foreach($deletedList as $deletedLang) + { + if(in_array($deletedLang, $existList)) continue; + $this->dao->delete()->from(TABLE_LANG)->where('module')->eq('bug')->andWhere('`key`')->eq($deletedLang)->andWhere('`system`')->eq(1)->andWhere('vision')->eq('rnd')->exec(); + } + + $this->dao->update(TABLE_LANG)->set('value')->eq('Mac OS')->where('module')->eq('bug')->andWhere('`key`')->eq('osx')->andWhere('value')->eq('OS X')->exec(); + $this->dao->update(TABLE_LANG)->set('value')->eq('Opera 系列')->where('module')->eq('bug')->andWhere('`key`')->eq('operea')->andWhere('value')->eq('opera 系列')->exec(); + + return true; + } } diff --git a/module/user/model.php b/module/user/model.php index 7fec646510..f0d90532c9 100644 --- a/module/user/model.php +++ b/module/user/model.php @@ -920,6 +920,12 @@ class userModel extends model $user->modifyPassword = $this->loadModel('admin')->checkWeak($user); if($user->modifyPassword) $user->modifyPasswordReason = 'weak'; } + /* Check weak password when login. */ + if(!$user->modifyPassword and $this->app->moduleName == 'user' and $this->app->methodName == 'login' and isset($_POST['passwordStrength'])) + { + $user->modifyPassword = (isset($this->config->safe->mode) and $this->post->passwordStrength < $this->config->safe->mode); + if($user->modifyPassword) $user->modifyPasswordReason = 'passwordStrengthWeak'; + } /* code for bug #2729. */ if(defined('IN_USE')) $this->dao->update(TABLE_USER)->set('visits = visits + 1')->set('ip')->eq($ip)->set('last')->eq($last)->where('account')->eq($account)->exec(); diff --git a/test/class/execution.class.php b/test/class/execution.class.php index 12e317336a..9600ac750a 100644 --- a/test/class/execution.class.php +++ b/test/class/execution.class.php @@ -166,10 +166,11 @@ class executionTest * * @param string $executionID * @param array $param + * @param bool $testParent * @access public * @return array */ - public function startTest($executionID,$param = array()) + public function startTest($executionID,$param = array(), $testParent = false) { $data = date('Y-m-d'); @@ -196,6 +197,12 @@ class executionTest } else { + if($testParent) + { + $execution = $this->objectModel->getByID($executionID); + $executionParent = $this->objectModel->getByID($execution->parent); + return $executionParent; + } return $obj; } } @@ -268,10 +275,11 @@ class executionTest * * @param string $executionID * @param array $param + * @param bool $testParent * @access public * @return array */ - public function activateTest($executionID, $param = array()) + public function activateTest($executionID, $param = array(), $testParent = false) { self::suspendTest($executionID); @@ -294,6 +302,12 @@ class executionTest } else { + if($testParent) + { + $execution = $this->objectModel->getByID($executionID); + $executionParent = $this->objectModel->getByID($execution->parent); + return $executionParent; + } return $obj; } } @@ -303,10 +317,11 @@ class executionTest * * @param string $executionID * @param array $param + * @param bool $testParent * @access public * @return array */ - public function closeTest($executionID, $param = array()) + public function closeTest($executionID, $param = array(), $testParent = false) { $todate = date('Y-m-d'); @@ -326,6 +341,12 @@ class executionTest } else { + if($testParent) + { + $execution = $this->objectModel->getByID($executionID); + $executionParent = $this->objectModel->getByID($execution->parent); + return $executionParent; + } return $obj; } } diff --git a/test/class/testcase.class.php b/test/class/testcase.class.php index 5642b59f97..077080ef01 100644 --- a/test/class/testcase.class.php +++ b/test/class/testcase.class.php @@ -306,6 +306,24 @@ class testcaseTest return $objects; } + /** + * Test get case pairs by product id and branch. + * + * @param int $productID + * @param int $branch + * @access public + * @return array + */ + public function getPairsByProductTest($productID = 0, $branch = 0) + { + $objects = $this->objectModel->getPairsByProduct($productID, $branch); + + if(dao::isError()) return dao::getError(); + + if(empty($objects)) return 'empty'; + return $objects; + } + /** * Test get counts of some stories' cases. * diff --git a/test/model/execution/activate.php b/test/model/execution/activate.php index c026149452..8730b9d6c5 100755 --- a/test/model/execution/activate.php +++ b/test/model/execution/activate.php @@ -16,18 +16,19 @@ pid=1 看板执行激活 >> status,suspended,doing 修改激活时间 >> begin 修改顺延 >> begin +子瀑布激活获取父瀑布状态 >> doing */ -$executionIDList = array('105', '136', '165', '106', '107'); +$executionIDList = array('105', '136', '165', '106', '107', '708'); $readjustTask = array('readjustTime' => '1', 'readjustTask' => '1'); $readjustTime = array('readjustTime' => '1'); $execution = new executionTest(); -//var_dump($execution->activateTest($executionIDList[4],$readjustTask ));die; -r($execution->activateTest($executionIDList[0])) && p('0:field,old,new') && e('status,suspended,doing'); // 敏捷执行激活 -r($execution->activateTest($executionIDList[1])) && p('0:field,old,new') && e('status,suspended,doing'); // 瀑布执行激活 -r($execution->activateTest($executionIDList[2])) && p('0:field,old,new') && e('status,suspended,doing'); // 看板执行激活 -r($execution->activateTest($executionIDList[3],$readjustTime)) && p('1:field') && e('begin'); // 修改激活时间 -r($execution->activateTest($executionIDList[4],$readjustTask)) && p('1:field') && e('begin'); // 修改顺延 -$db->restoreDB(); \ No newline at end of file +r($execution->activateTest($executionIDList[0])) && p('0:field,old,new') && e('status,suspended,doing'); // 敏捷执行激活 +r($execution->activateTest($executionIDList[1])) && p('0:field,old,new') && e('status,suspended,doing'); // 瀑布执行激活 +r($execution->activateTest($executionIDList[2])) && p('0:field,old,new') && e('status,suspended,doing'); // 看板执行激活 +r($execution->activateTest($executionIDList[3],$readjustTime)) && p('1:field') && e('begin'); // 修改激活时间 +r($execution->activateTest($executionIDList[4],$readjustTask)) && p('1:field') && e('begin'); // 修改顺延 +r($execution->activateTest($executionIDList[5], array(), true)) && p('status') && e('doing'); // 子瀑布激活获取父瀑布状态 +$db->restoreDB(); diff --git a/test/model/execution/close.php b/test/model/execution/close.php index cd43bbabf6..6f0752d869 100755 --- a/test/model/execution/close.php +++ b/test/model/execution/close.php @@ -15,15 +15,17 @@ pid=1 瀑布执行关闭 >> status,doing,closed 看板执行关闭 >> status,doing,closed 不输入实际完成时间校验 >> 『realEnd』不能为空。 +子瀑布关闭获取父瀑布状态 >> closed */ -$executionIDList = array('109', '138', '168'); +$executionIDList = array('109', '138', '168', '708'); $noRealEnd = array('realEnd' => ''); $execution = new executionTest(); -r($execution->closeTest($executionIDList[0])) && p('0:field,old,new') && e('status,wait,closed'); // 敏捷执行关闭 -r($execution->closeTest($executionIDList[1])) && p('0:field,old,new') && e('status,doing,closed'); // 瀑布执行关闭 -r($execution->closeTest($executionIDList[2])) && p('0:field,old,new') && e('status,doing,closed'); // 看板执行关闭 -r($execution->closeTest($executionIDList[1],$noRealEnd)) && p('realEnd:0') && e('『realEnd』不能为空。'); // 不输入实际完成时间校验 -$db->restoreDB(); \ No newline at end of file +r($execution->closeTest($executionIDList[0])) && p('0:field,old,new') && e('status,wait,closed'); // 敏捷执行关闭 +r($execution->closeTest($executionIDList[1])) && p('0:field,old,new') && e('status,doing,closed'); // 瀑布执行关闭 +r($execution->closeTest($executionIDList[2])) && p('0:field,old,new') && e('status,doing,closed'); // 看板执行关闭 +r($execution->closeTest($executionIDList[1],$noRealEnd)) && p('realEnd:0') && e('『realEnd』不能为空。'); // 不输入实际完成时间校验 +r($execution->closeTest($executionIDList[3], array(), true)) && p('status') && e('closed'); // 子瀑布关闭获取父瀑布状态 +$db->restoreDB(); diff --git a/test/model/execution/start.php b/test/model/execution/start.php index 22f92a08d1..1f52ea7577 100755 --- a/test/model/execution/start.php +++ b/test/model/execution/start.php @@ -15,16 +15,18 @@ pid=1 瀑布阶段开始 >> status,wait,doing 看板执行开始 >> status,wait,doing 重复执行开始 >> 此任务已被启动,不能重复启动! +子瀑布开启获取父瀑布状态 >> doing */ -$executionIDList = array('101', '131', '161', '103'); +$executionIDList = array('101', '131', '161', '103', '701'); $noRealBegan = array('realBegan' => ''); $execution = new executionTest(); -r($execution->startTest($executionIDList[0])) && p('1:field,old,new') && e('status,wait,doing'); // 敏捷执行开始 -r($execution->startTest($executionIDList[1])) && p('1:field,old,new') && e('status,wait,doing'); // 瀑布阶段开始 -r($execution->startTest($executionIDList[2])) && p('1:field,old,new') && e('status,wait,doing'); // 看板执行开始 -r($execution->startTest($executionIDList[0],$noRealBegan)) && p() && e('此任务已被启动,不能重复启动!'); // 重复执行开始 -$db->restoreDB(); \ No newline at end of file +r($execution->startTest($executionIDList[0])) && p('1:field,old,new') && e('status,wait,doing'); // 敏捷执行开始 +r($execution->startTest($executionIDList[1])) && p('1:field,old,new') && e('status,wait,doing'); // 瀑布阶段开始 +r($execution->startTest($executionIDList[2])) && p('1:field,old,new') && e('status,wait,doing'); // 看板执行开始 +r($execution->startTest($executionIDList[0],$noRealBegan)) && p() && e('此任务已被启动,不能重复启动!'); // 重复执行开始 +r($execution->startTest($executionIDList[3], array(), true)) && p('status') && e('doing'); // 子瀑布开启获取父瀑布状态 +$db->restoreDB(); diff --git a/test/model/testcase/getpairsbyproduct.php b/test/model/testcase/getpairsbyproduct.php new file mode 100644 index 0000000000..1eda797975 --- /dev/null +++ b/test/model/testcase/getpairsbyproduct.php @@ -0,0 +1,22 @@ +#!/usr/bin/env php +getPairsByProduct(); +cid=1 +pid=1 + +获取产品1的case >> 1:这个是测试用例1 +获取产品41分支1的case >> empty + +*/ +$productIDList = array(1, 41); +$branch = 1; + +$testcase = new testcaseTest(); +r($testcase->getPairsByProductTest($productIDList[0])) && p('1') && e('1:这个是测试用例1'); // 获取产品1的case +r($testcase->getPairsByProductTest($productIDList[1], $branch)) && p() && e('empty'); // 获取产品41分支1的case diff --git a/test/ztest b/test/ztest index 6fc88a6b7c..8454508f16 100755 --- a/test/ztest +++ b/test/ztest @@ -58,6 +58,9 @@ switch($argv[1]) case 'cron': ztfRun('model/cron'); break; + case 'custom': + ztfRun('model/custom'); + break; case 'datatable': ztfRun('model/datatable'); break;