This commit is contained in:
reneeteng
2019-11-21 13:52:48 +08:00
401 changed files with 3105 additions and 49224 deletions
+3
View File
@@ -32,6 +32,9 @@ common:
mv zentaopms/www/install.php.tmp zentaopms/www/install.php
mv zentaopms/www/upgrade.php.tmp zentaopms/www/upgrade.php
cp VERSION zentaopms/
# create index.html of each folder.
for path in `find zentaopms/ -type d`; do touch "$$path/index.html"; done
rm zentaopms/www/index.html
# combine js and css files.
cp -fr tools zentaopms/tools && cd zentaopms/tools/ && php ./minifyfront.php
rm -fr zentaopms/tools
+1 -1
View File
@@ -1 +1 @@
11.6.4
11.6.5
+2 -2
View File
@@ -3,8 +3,8 @@ Version: 6.1
Section: utils
Priority: optional
Architecture: all
Depends: apache2, libapache2-mod-php5 | libapache2-mod-php5filter | php5-cgi | php5-fpm | php5, php5-cli, php5-common, php5-mysql, php5-json, php5-ldap, mysql-server
Recommends: php5-gd
Depends: apache2, libapache2-mod-php | libapache2-mod-phpfilter | php-cgi | php-fpm | php, php-cli, php-common, php-mysql, php-json, php-ldap, mysql-server
Recommends: php-gd
Installed-Size: 512
Maintainer: [url=www.zentao.net]
Description: zentaopms
+1 -1
View File
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
if(!function_exists('getWebRoot')){function getWebRoot(){}}
/* 基本设置。Basic settings. */
$config->version = '11.6.4'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->version = '11.6.5'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP.
$config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time.
$config->timezone = 'Asia/Shanghai'; // 时区设置。 The time zone setting, for more see http://www.php.net/manual/en/timezones.php.
-5
View File
@@ -45,7 +45,6 @@ $filter->mail = new stdclass();
$filter->user = new stdclass();
$filter->block = new stdclass();
$filter->file = new stdclass();
$filter->translate = new stdclass();
$filter->block->default = new stdclass();
$filter->block->main = new stdclass();
@@ -62,7 +61,6 @@ $filter->mail->ztcloud = new stdclass();
$filter->mail->batchdelete = new stdclass();
$filter->misc->checkupdate = new stdclass();
$filter->file->download = new stdclass();
$filter->file->ajaxueditorupload = new stdclass();
$filter->product->browse = new stdclass();
$filter->product->default = new stdclass();
$filter->product->index = new stdclass();
@@ -184,7 +182,6 @@ $filter->doc->showfiles->get['recPerPage'] = 'int';
$filter->doc->showfiles->get['recTotal'] = 'int';
$filter->doc->showfiles->get['title'] = 'reg::any';
$filter->file->ajaxueditorupload->get['action'] = 'equal::config';
$filter->file->download->get['charset'] = 'reg::lang';
$filter->mail->batchdelete->get['idList'] = 'reg::idList';
@@ -215,5 +212,3 @@ $filter->git->cat->get['repoUrl'] = 'reg::base64';
$filter->git->diff->get['repoUrl'] = 'reg::base64';
$filter->svn->cat->get['repoUrl'] = 'reg::base64';
$filter->svn->diff->get['repoUrl'] = 'reg::base64';
$filter->translate->module->cookie['translateView'] = 'equal::split';
+64 -14
View File
@@ -13,6 +13,7 @@
/* Framework settings. */
$config->framework->autoRepairTable = true;
$config->framework->autoLang = false;
$config->framework->filterCSRF = false;
/* Upload settings. */
$config->allowedTags = '<p><span><h1><h2><h3><h4><h5><em><u><strong><br><ol><ul><li><img><a><b><font><hr><pre><div><table><td><th><tr><tbody><embed><style>';
@@ -24,26 +25,74 @@ $config->wideSize = 1400;
$config->timeout = 30000;
$config->duplicateTime = 60;
$config->productCommonList['en'][0] = 'Product';
$config->productCommonList['en'][1] = 'Project';
$config->projectCommonList['en'][0] = 'Project';
$config->projectCommonList['en'][1] = 'Sprint';
/* Product common list. */
$config->productCommonList['zh-cn'][0] = '产品';
$config->productCommonList['zh-cn'][1] = '项目';
$config->projectCommonList['zh-cn'][0] = '项目';
$config->projectCommonList['zh-cn'][1] = '迭代';
$config->productCommonList['zh-tw'][0] = '產品';
$config->productCommonList['zh-tw'][1] = '項目';
$config->productCommonList['en'][0] = 'Product';
$config->productCommonList['en'][1] = 'Project';
$config->productCommonList['de'][0] = 'Produkt';
$config->productCommonList['de'][1] = 'Projekt';
$config->productCommonList['fr'][0] = 'Product';
$config->productCommonList['fr'][1] = 'Projet';
/* Project common list. */
$config->projectCommonList['zh-cn'][0] = '项目';
$config->projectCommonList['zh-cn'][1] = '迭代';
$config->projectCommonList['zh-cn'][2] = '冲刺';
$config->projectCommonList['zh-tw'][0] = '項目';
$config->projectCommonList['zh-tw'][1] = '迭代';
$config->productCommonList['de'][0] = 'Produkt';
$config->productCommonList['de'][1] = 'Projekt';
$config->projectCommonList['de'][0] = 'Projekt';
$config->projectCommonList['de'][1] = 'Iteration';
$config->productCommonList['fr'][0] = 'Product';
$config->productCommonList['fr'][1] = 'Projet';
$config->projectCommonList['fr'][0] = 'Projet';
$config->projectCommonList['fr'][1] = 'Sprint';
$config->projectCommonList['zh-tw'][2] = '冲刺';
$config->projectCommonList['en'][0] = 'Project';
$config->projectCommonList['en'][1] = 'Iteration';
$config->projectCommonList['en'][2] = 'Sprint';
$config->projectCommonList['de'][0] = 'Projekt';
$config->projectCommonList['de'][1] = 'Iteration';
$config->projectCommonList['de'][2] = 'Sprint';
$config->projectCommonList['fr'][0] = 'Projet';
$config->projectCommonList['fr'][1] = 'Iteration';
$config->projectCommonList['fr'][2] = 'Sprint';
/* Story common list. */
$config->storyCommonList['zh-cn'][0] = '需求';
$config->storyCommonList['zh-cn'][1] = '故事';
$config->storyCommonList['zh-tw'][0] = '需求';
$config->storyCommonList['zh-tw'][1] = '故事';
$config->storyCommonList['en'][0] = 'story';
$config->storyCommonList['en'][1] = 'story';
$config->storyCommonList['de'][0] = 'story';
$config->storyCommonList['de'][1] = 'story';
$config->storyCommonList['fr'][0] = 'story';
$config->storyCommonList['fr'][1] = 'story';
/* Story common list. */
$config->hourPointCommonList['zh-cn'][0] = '工时';
$config->hourPointCommonList['zh-cn'][1] = '故事点';
$config->hourPointCommonList['zh-tw'][0] = '工时';
$config->hourPointCommonList['zh-tw'][1] = '故事点';
$config->hourPointCommonList['en'][0] = 'hour';
$config->hourPointCommonList['en'][1] = 'story point';
$config->hourPointCommonList['de'][0] = 'hour';
$config->hourPointCommonList['de'][1] = 'story point';
$config->hourPointCommonList['fr'][0] = 'hour';
$config->hourPointCommonList['fr'][1] = 'story point';
/* Supported charsets. */
$config->charsets['zh-cn']['utf-8'] = 'UTF-8';
@@ -120,6 +169,7 @@ define('TABLE_LOG', '`' . $config->db->prefix . 'log`');
define('TABLE_SCORE', '`' . $config->db->prefix . 'score`');
define('TABLE_NOTIFY', '`' . $config->db->prefix . 'notify`');
define('TABLE_TRANSLATION', '`' . $config->db->prefix . 'translation`');
define('TABLE_DINGUSERID', '`' . $config->db->prefix . 'dinguserid`');
if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`');
$config->objectTables['product'] = TABLE_PRODUCT;
+938
View File
@@ -0,0 +1,938 @@
CREATE TABLE `zt_action` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`objectType` varchar(30) NOT NULL DEFAULT '',
`objectID` mediumint(8) unsigned NOT NULL DEFAULT '0',
`product` varchar(255) NOT NULL,
`project` mediumint(9) NOT NULL,
`actor` varchar(30) NOT NULL DEFAULT '',
`action` varchar(30) NOT NULL DEFAULT '',
`date` datetime NOT NULL,
`comment` text NOT NULL,
`extra` text NOT NULL,
`read` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `date` (`date`),
KEY `actor` (`actor`),
KEY `project` (`project`),
KEY `objectID` (`objectID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_block` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`account` char(30) NOT NULL,
`module` varchar(20) NOT NULL,
`title` varchar(100) NOT NULL,
`source` varchar(20) NOT NULL,
`block` varchar(20) NOT NULL,
`params` text NOT NULL,
`order` tinyint(3) unsigned NOT NULL DEFAULT '0',
`grid` tinyint(3) unsigned NOT NULL DEFAULT '0',
`height` smallint(5) unsigned NOT NULL DEFAULT '0',
`hidden` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `accountModuleOrder` (`account`,`module`,`order`),
KEY `account` (`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_branch` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`order` smallint(5) unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_bug` (
`id` mediumint(8) NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` mediumint(8) unsigned NOT NULL DEFAULT '0',
`project` mediumint(8) unsigned NOT NULL DEFAULT '0',
`plan` mediumint(8) unsigned NOT NULL DEFAULT '0',
`story` mediumint(8) unsigned NOT NULL DEFAULT '0',
`storyVersion` smallint(6) NOT NULL DEFAULT '1',
`task` mediumint(8) unsigned NOT NULL DEFAULT '0',
`toTask` mediumint(8) unsigned NOT NULL DEFAULT '0',
`toStory` mediumint(8) NOT NULL DEFAULT '0',
`title` varchar(255) NOT NULL,
`keywords` varchar(255) NOT NULL,
`severity` tinyint(4) NOT NULL DEFAULT '0',
`pri` tinyint(3) unsigned NOT NULL,
`type` varchar(30) NOT NULL DEFAULT '',
`os` varchar(30) NOT NULL DEFAULT '',
`browser` varchar(30) NOT NULL DEFAULT '',
`hardware` varchar(30) NOT NULL,
`found` varchar(30) NOT NULL DEFAULT '',
`steps` text NOT NULL,
`status` enum('active','resolved','closed') NOT NULL DEFAULT 'active',
`subStatus` varchar(30) NOT NULL DEFAULT '',
`color` char(7) NOT NULL,
`confirmed` tinyint(1) NOT NULL DEFAULT '0',
`activatedCount` smallint(6) NOT NULL,
`activatedDate` datetime NOT NULL,
`mailto` text,
`openedBy` varchar(30) NOT NULL DEFAULT '',
`openedDate` datetime NOT NULL,
`openedBuild` varchar(255) NOT NULL,
`assignedTo` varchar(30) NOT NULL DEFAULT '',
`assignedDate` datetime NOT NULL,
`deadline` date NOT NULL,
`resolvedBy` varchar(30) NOT NULL DEFAULT '',
`resolution` varchar(30) NOT NULL DEFAULT '',
`resolvedBuild` varchar(30) NOT NULL DEFAULT '',
`resolvedDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL DEFAULT '',
`closedDate` datetime NOT NULL,
`duplicateBug` mediumint(8) unsigned NOT NULL,
`linkBug` varchar(255) NOT NULL,
`case` mediumint(8) unsigned NOT NULL,
`caseVersion` smallint(6) NOT NULL DEFAULT '1',
`result` mediumint(8) unsigned NOT NULL,
`testtask` mediumint(8) unsigned NOT NULL,
`lastEditedBy` varchar(30) NOT NULL DEFAULT '',
`lastEditedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `project` (`project`),
KEY `status` (`status`),
KEY `plan` (`plan`),
KEY `story` (`story`),
KEY `case` (`case`),
KEY `assignedTo` (`assignedTo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_build` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`project` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` char(150) NOT NULL,
`scmPath` char(255) NOT NULL,
`filePath` char(255) NOT NULL,
`date` date NOT NULL,
`stories` text NOT NULL,
`bugs` text NOT NULL,
`builder` char(30) NOT NULL DEFAULT '',
`desc` text NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `project` (`project`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_burn` (
`project` mediumint(8) unsigned NOT NULL,
`task` mediumint(8) unsigned NOT NULL DEFAULT '0',
`date` date NOT NULL,
`estimate` float NOT NULL,
`left` float NOT NULL,
`consumed` float NOT NULL,
PRIMARY KEY (`project`,`date`,`task`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_case` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`lib` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` mediumint(8) unsigned NOT NULL DEFAULT '0',
`path` mediumint(8) unsigned NOT NULL DEFAULT '0',
`story` mediumint(30) unsigned NOT NULL DEFAULT '0',
`storyVersion` smallint(6) NOT NULL DEFAULT '1',
`title` varchar(255) NOT NULL,
`precondition` text NOT NULL,
`keywords` varchar(255) NOT NULL,
`pri` tinyint(3) unsigned NOT NULL DEFAULT '3',
`type` char(30) NOT NULL DEFAULT '1',
`stage` varchar(255) NOT NULL,
`howRun` varchar(30) NOT NULL,
`scriptedBy` varchar(30) NOT NULL,
`scriptedDate` date NOT NULL,
`scriptStatus` varchar(30) NOT NULL,
`scriptLocation` varchar(255) NOT NULL,
`status` char(30) NOT NULL DEFAULT '1',
`subStatus` varchar(30) NOT NULL DEFAULT '',
`color` char(7) NOT NULL,
`frequency` enum('1','2','3') NOT NULL DEFAULT '1',
`order` tinyint(30) unsigned NOT NULL DEFAULT '0',
`openedBy` char(30) NOT NULL DEFAULT '',
`openedDate` datetime NOT NULL,
`reviewedBy` varchar(255) NOT NULL,
`reviewedDate` date NOT NULL,
`lastEditedBy` char(30) NOT NULL DEFAULT '',
`lastEditedDate` datetime NOT NULL,
`version` tinyint(3) unsigned NOT NULL DEFAULT '0',
`linkCase` varchar(255) NOT NULL,
`fromBug` mediumint(8) unsigned NOT NULL,
`fromCaseID` mediumint(8) unsigned NOT NULL,
`fromCaseVersion` mediumint(8) unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
`lastRunner` varchar(30) NOT NULL,
`lastRunDate` datetime NOT NULL,
`lastRunResult` char(30) NOT NULL,
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `story` (`story`),
KEY `module` (`module`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_casestep` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`parent` mediumint(8) unsigned NOT NULL DEFAULT '0',
`case` mediumint(8) unsigned NOT NULL DEFAULT '0',
`version` smallint(3) unsigned NOT NULL DEFAULT '0',
`type` varchar(10) NOT NULL DEFAULT 'step',
`desc` text NOT NULL,
`expect` text NOT NULL,
PRIMARY KEY (`id`),
KEY `case` (`case`),
KEY `version` (`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_company` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` char(120) DEFAULT NULL,
`phone` char(20) DEFAULT NULL,
`fax` char(20) DEFAULT NULL,
`address` char(120) DEFAULT NULL,
`zipcode` char(10) DEFAULT NULL,
`website` char(120) DEFAULT NULL,
`backyard` char(120) DEFAULT NULL,
`guest` enum('1','0') NOT NULL DEFAULT '0',
`admins` char(255) DEFAULT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_config` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`owner` char(30) NOT NULL DEFAULT '',
`module` varchar(30) NOT NULL,
`section` char(30) NOT NULL DEFAULT '',
`key` char(30) NOT NULL DEFAULT '',
`value` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique` (`owner`,`module`,`section`,`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_cron` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`m` varchar(20) NOT NULL,
`h` varchar(20) NOT NULL,
`dom` varchar(20) NOT NULL,
`mon` varchar(20) NOT NULL,
`dow` varchar(20) NOT NULL,
`command` text NOT NULL,
`remark` varchar(255) NOT NULL,
`type` varchar(20) NOT NULL,
`buildin` tinyint(1) NOT NULL DEFAULT '0',
`status` varchar(20) NOT NULL,
`lastTime` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `lastTime` (`lastTime`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_dept` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` char(60) NOT NULL,
`parent` mediumint(8) unsigned NOT NULL DEFAULT '0',
`path` char(255) NOT NULL DEFAULT '',
`grade` tinyint(3) unsigned NOT NULL DEFAULT '0',
`order` tinyint(3) unsigned NOT NULL DEFAULT '0',
`position` char(30) NOT NULL DEFAULT '',
`function` char(255) NOT NULL DEFAULT '',
`manager` char(30) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
KEY `path` (`path`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_doc` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`project` mediumint(8) unsigned NOT NULL,
`lib` varchar(30) NOT NULL,
`module` varchar(30) NOT NULL,
`title` varchar(255) NOT NULL,
`keywords` varchar(255) NOT NULL,
`type` varchar(30) NOT NULL,
`views` smallint(5) unsigned NOT NULL,
`collector` text NOT NULL,
`addedBy` varchar(30) NOT NULL,
`addedDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`acl` varchar(10) NOT NULL DEFAULT 'open',
`groups` varchar(255) NOT NULL,
`users` text NOT NULL,
`version` smallint(5) unsigned NOT NULL DEFAULT '1',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `project` (`project`),
KEY `lib` (`lib`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_doccontent` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`doc` mediumint(8) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`digest` varchar(255) NOT NULL,
`content` text NOT NULL,
`files` text NOT NULL,
`type` varchar(10) NOT NULL,
`version` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `doc_version` (`doc`,`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_doclib` (
`id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`type` varchar(30) NOT NULL,
`product` mediumint(8) unsigned NOT NULL,
`project` mediumint(8) unsigned NOT NULL,
`name` varchar(60) NOT NULL,
`acl` varchar(10) NOT NULL DEFAULT 'open',
`groups` varchar(255) NOT NULL,
`users` text NOT NULL,
`main` enum('0','1') NOT NULL DEFAULT '0',
`collector` text NOT NULL,
`order` tinyint(5) unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `project` (`project`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_effort` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`user` char(30) NOT NULL DEFAULT '',
`todo` enum('1','0') NOT NULL DEFAULT '1',
`date` date NOT NULL,
`begin` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`end` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`type` enum('1','2','3') NOT NULL DEFAULT '1',
`idvalue` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` char(30) NOT NULL DEFAULT '',
`desc` char(255) NOT NULL DEFAULT '',
`status` enum('1','2','3') NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `user` (`user`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `zt_entry` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`account` varchar(30) NOT NULL DEFAULT '',
`code` varchar(20) NOT NULL,
`key` varchar(32) NOT NULL,
`freePasswd` enum('0','1') NOT NULL DEFAULT '0',
`ip` varchar(100) NOT NULL,
`desc` text NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`calledTime` int(10) unsigned NOT NULL DEFAULT '0',
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`deleted` enum('0', '1') NOT NULL DEFAULT '0',
PRIMARY KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_extension` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(150) NOT NULL,
`code` varchar(30) NOT NULL,
`version` varchar(50) NOT NULL,
`author` varchar(100) NOT NULL,
`desc` text NOT NULL,
`license` text NOT NULL,
`type` varchar(20) NOT NULL DEFAULT 'extension',
`site` varchar(150) NOT NULL,
`zentaoCompatible` varchar(100) NOT NULL,
`installedTime` datetime NOT NULL,
`depends` varchar(100) NOT NULL,
`dirs` mediumtext NOT NULL,
`files` mediumtext NOT NULL,
`status` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `code` (`code`),
KEY `name` (`name`),
KEY `installedTime` (`installedTime`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_file` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`pathname` char(100) NOT NULL,
`title` char(255) NOT NULL,
`extension` char(30) NOT NULL,
`size` int(10) unsigned NOT NULL DEFAULT '0',
`objectType` char(30) NOT NULL,
`objectID` mediumint(9) NOT NULL,
`addedBy` char(30) NOT NULL DEFAULT '',
`addedDate` datetime NOT NULL,
`downloads` mediumint(8) unsigned NOT NULL DEFAULT '0',
`extra` varchar(255) NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `objectType` (`objectType`),
KEY `objectID` (`objectID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_group` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` char(30) NOT NULL,
`role` char(30) NOT NULL DEFAULT '',
`desc` char(255) NOT NULL DEFAULT '',
`acl` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_grouppriv` (
`group` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` char(30) NOT NULL DEFAULT '',
`method` char(30) NOT NULL DEFAULT '',
UNIQUE KEY `group` (`group`,`module`,`method`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_history` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`action` mediumint(8) unsigned NOT NULL DEFAULT '0',
`field` varchar(30) NOT NULL DEFAULT '',
`old` text NOT NULL,
`new` text NOT NULL,
`diff` mediumtext NOT NULL,
PRIMARY KEY (`id`),
KEY `action` (`action`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_lang` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`lang` varchar(30) NOT NULL,
`module` varchar(30) NOT NULL,
`section` varchar(30) NOT NULL,
`key` varchar(60) NOT NULL,
`value` text NOT NULL,
`system` enum('0','1') NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
UNIQUE KEY `lang` (`lang`,`module`,`section`,`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_log` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`objectType` varchar(30) NOT NULL,
`objectID` mediumint(8) unsigned NOT NULL,
`action` mediumint(8) unsigned NOT NULL,
`date` datetime NOT NULL,
`url` varchar(255) NOT NULL,
`contentType` varchar(30) NOT NULL,
`data` text NOT NULL,
`result` text NOT NULL,
PRIMARY KEY (`id`),
KEY `objectType` (`objectType`),
KEY `obejctID` (`objectID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_module` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`root` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` char(60) NOT NULL DEFAULT '',
`parent` mediumint(8) unsigned NOT NULL DEFAULT '0',
`path` char(255) NOT NULL DEFAULT '',
`grade` tinyint(3) unsigned NOT NULL DEFAULT '0',
`order` smallint(5) unsigned NOT NULL DEFAULT '0',
`type` char(30) NOT NULL,
`owner` varchar(30) NOT NULL,
`collector` text NOT NULL,
`short` varchar(30) NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `root` (`root`),
KEY `type` (`type`),
KEY `path` (`path`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_notify` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`objectType` varchar(50) NOT NULL,
`objectID` mediumint(8) unsigned NOT NULL,
`action` mediumint(9) NOT NULL,
`toList` varchar(255) NOT NULL,
`ccList` text NOT NULL,
`subject` varchar(255) NOT NULL,
`data` text NOT NULL,
`createdBy` char(30) NOT NULL,
`createdDate` datetime NOT NULL,
`sendTime` datetime NOT NULL,
`status` varchar(10) NOT NULL DEFAULT 'wait',
`failReason` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_product` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(90) NOT NULL,
`code` varchar(45) NOT NULL,
`line` mediumint(8) NOT NULL,
`type` varchar(30) NOT NULL DEFAULT 'normal',
`status` varchar(30) NOT NULL DEFAULT '',
`subStatus` varchar(30) NOT NULL DEFAULT '',
`desc` text NOT NULL,
`PO` varchar(30) NOT NULL,
`QD` varchar(30) NOT NULL,
`RD` varchar(30) NOT NULL,
`acl` enum('open','private','custom') NOT NULL DEFAULT 'open',
`whitelist` text NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`createdVersion` varchar(20) NOT NULL,
`order` mediumint(8) unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `order` (`order`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_productplan` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`branch` mediumint(8) unsigned NOT NULL,
`parent` mediumint(9) NOT NULL DEFAULT '0',
`title` varchar(90) NOT NULL,
`desc` text NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
`order` text NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `end` (`end`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_project` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`isCat` enum('1','0') NOT NULL DEFAULT '0',
`catID` mediumint(8) unsigned NOT NULL,
`type` varchar(20) NOT NULL DEFAULT 'sprint',
`parent` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` varchar(90) NOT NULL,
`code` varchar(45) NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
`days` smallint(5) unsigned NOT NULL,
`status` varchar(10) NOT NULL,
`subStatus` varchar(30) NOT NULL DEFAULT '',
`statge` enum('1','2','3','4','5') NOT NULL DEFAULT '1',
`pri` enum('1','2','3','4') NOT NULL DEFAULT '1',
`desc` text NOT NULL,
`openedBy` varchar(30) NOT NULL DEFAULT '',
`openedDate` datetime NOT NULL,
`openedVersion` varchar(20) NOT NULL,
`closedBy` varchar(30) NOT NULL DEFAULT '',
`closedDate` datetime NOT NULL,
`canceledBy` varchar(30) NOT NULL DEFAULT '',
`canceledDate` datetime NOT NULL,
`PO` varchar(30) NOT NULL DEFAULT '',
`PM` varchar(30) NOT NULL DEFAULT '',
`QD` varchar(30) NOT NULL DEFAULT '',
`RD` varchar(30) NOT NULL DEFAULT '',
`team` varchar(90) NOT NULL,
`acl` enum('open','private','custom') NOT NULL DEFAULT 'open',
`whitelist` text NOT NULL,
`order` mediumint(8) unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
KEY `begin` (`begin`),
KEY `end` (`end`),
KEY `status` (`status`),
KEY `order` (`order`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_projectproduct` (
`project` mediumint(8) unsigned NOT NULL,
`product` mediumint(8) unsigned NOT NULL,
`branch` mediumint(8) unsigned NOT NULL,
`plan` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`project`,`product`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_projectstory` (
`project` mediumint(8) unsigned NOT NULL DEFAULT '0',
`product` mediumint(8) unsigned NOT NULL,
`story` mediumint(8) unsigned NOT NULL DEFAULT '0',
`version` smallint(6) NOT NULL DEFAULT '1',
`order` smallint(6) unsigned NOT NULL,
UNIQUE KEY `project` (`project`,`story`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_release` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL DEFAULT '0',
`branch` mediumint(8) unsigned NOT NULL DEFAULT '0',
`build` mediumint(8) unsigned NOT NULL,
`name` varchar(255) NOT NULL DEFAULT '',
`marker` enum('0','1') NOT NULL DEFAULT '0',
`date` date NOT NULL,
`stories` text NOT NULL,
`bugs` text NOT NULL,
`leftBugs` text NOT NULL,
`desc` text NOT NULL,
`status` varchar(20) NOT NULL DEFAULT 'normal',
`subStatus` varchar(30) NOT NULL DEFAULT '',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `build` (`build`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_score` (
`id` bigint(12) unsigned NOT NULL AUTO_INCREMENT,
`account` varchar(30) NOT NULL,
`module` varchar(30) NOT NULL DEFAULT '',
`method` varchar(30) NOT NULL,
`desc` varchar(250) NOT NULL DEFAULT '',
`before` int(11) NOT NULL DEFAULT '0',
`score` int(11) NOT NULL DEFAULT '0',
`after` int(11) NOT NULL DEFAULT '0',
`time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `account` (`account`),
KEY `model` (`module`),
KEY `method` (`method`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `zt_story` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`product` mediumint(8) unsigned NOT NULL default '0',
`branch` mediumint(8) unsigned NOT NULL default '0',
`module` mediumint(8) unsigned NOT NULL default '0',
`plan` text,
`source` varchar(20) NOT NULL,
`sourceNote` varchar(255) NOT NULL,
`fromBug` mediumint(8) unsigned NOT NULL default '0',
`title` varchar(255) NOT NULL,
`keywords` varchar(255) NOT NULL,
`type` varchar(30) NOT NULL default '',
`pri` tinyint(3) unsigned NOT NULL default '3',
`estimate` float unsigned NOT NULL,
`status` enum('','changed','active','draft','closed') NOT NULL default '',
`subStatus` varchar(30) NOT NULL DEFAULT '',
`color` char(7) NOT NULL,
`stage` enum('','wait','planned','projected','developing','developed','testing','tested','verified','released', 'closed') NOT NULL DEFAULT 'wait',
`stagedBy` char(30) NOT NULL,
`mailto` text,
`openedBy` varchar(30) NOT NULL default '',
`openedDate` datetime NOT NULL,
`assignedTo` varchar(30) NOT NULL default '',
`assignedDate` datetime NOT NULL,
`lastEditedBy` varchar(30) NOT NULL default '',
`lastEditedDate` datetime NOT NULL,
`reviewedBy` varchar(255) NOT NULL,
`reviewedDate` date NOT NULL,
`closedBy` varchar(30) NOT NULL default '',
`closedDate` datetime NOT NULL,
`closedReason` varchar(30) NOT NULL,
`toBug` mediumint(8) unsigned NOT NULL,
`childStories` varchar(255) NOT NULL,
`linkStories` varchar(255) NOT NULL,
`duplicateStory` mediumint(8) unsigned NOT NULL,
`version` smallint(6) NOT NULL default '1',
`deleted` enum('0','1') NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `status` (`status`),
KEY `assignedTo` (`assignedTo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_storyspec` (
`story` mediumint(9) NOT NULL,
`version` smallint(6) NOT NULL,
`title` varchar(255) NOT NULL,
`spec` text NOT NULL,
`verify` text NOT NULL,
UNIQUE KEY `story` (`story`,`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `zt_storystage` (
`story` mediumint(8) unsigned NOT NULL,
`branch` mediumint(8) unsigned NOT NULL,
`stage` varchar(50) NOT NULL,
`stagedBy` char(30) NOT NULL,
UNIQUE KEY `story_branch` (`story`,`branch`),
KEY `story` (`story`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_suitecase` (
`suite` mediumint(8) unsigned NOT NULL,
`product` mediumint(8) unsigned NOT NULL,
`case` mediumint(8) unsigned NOT NULL,
`version` smallint(5) unsigned NOT NULL,
UNIQUE KEY `suitecase` (`suite`,`case`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_task` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`parent` mediumint(8) NOT NULL DEFAULT '0',
`project` mediumint(8) unsigned NOT NULL DEFAULT '0',
`module` mediumint(8) unsigned NOT NULL DEFAULT '0',
`story` mediumint(8) unsigned NOT NULL DEFAULT '0',
`storyVersion` smallint(6) NOT NULL DEFAULT '1',
`fromBug` mediumint(8) unsigned NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`type` varchar(20) NOT NULL,
`pri` tinyint(3) unsigned NOT NULL DEFAULT '0',
`estimate` float unsigned NOT NULL,
`consumed` float unsigned NOT NULL,
`left` float unsigned NOT NULL,
`deadline` date NOT NULL,
`status` enum('wait','doing','done','pause','cancel','closed') NOT NULL DEFAULT 'wait',
`subStatus` varchar(30) NOT NULL DEFAULT '',
`color` char(7) NOT NULL,
`mailto` text,
`desc` text NOT NULL,
`openedBy` varchar(30) NOT NULL,
`openedDate` datetime NOT NULL,
`assignedTo` varchar(30) NOT NULL,
`assignedDate` datetime NOT NULL,
`estStarted` date NOT NULL,
`realStarted` date NOT NULL,
`finishedBy` varchar(30) NOT NULL,
`finishedDate` datetime NOT NULL,
`finishedList` text NOT NULL,
`canceledBy` varchar(30) NOT NULL,
`canceledDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL,
`closedDate` datetime NOT NULL,
`closedReason` varchar(30) NOT NULL,
`lastEditedBy` varchar(30) NOT NULL,
`lastEditedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `project` (`project`),
KEY `story` (`story`),
KEY `assignedTo` (`assignedTo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_taskestimate` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`task` mediumint(8) unsigned NOT NULL DEFAULT '0',
`date` date NOT NULL,
`left` float unsigned NOT NULL DEFAULT '0',
`consumed` float unsigned NOT NULL,
`account` char(30) NOT NULL DEFAULT '',
`work` text,
PRIMARY KEY (`id`),
KEY `task` (`task`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_team` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`root` mediumint(8) unsigned NOT NULL DEFAULT '0',
`type` enum('project','task') NOT NULL DEFAULT 'project',
`account` char(30) NOT NULL DEFAULT '',
`role` char(30) NOT NULL DEFAULT '',
`limited` char(8) NOT NULL DEFAULT 'no',
`join` date NOT NULL DEFAULT '0000-00-00',
`days` smallint(5) unsigned NOT NULL,
`hours` float(2,1) unsigned NOT NULL DEFAULT '0.0',
`estimate` decimal(12,2) unsigned NOT NULL DEFAULT '0.00',
`consumed` decimal(12,2) unsigned NOT NULL DEFAULT '0.00',
`left` decimal(12,2) unsigned NOT NULL DEFAULT '0.00',
`order` tinyint(3) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `team` (`root`,`type`,`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_testreport` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`project` mediumint(8) unsigned NOT NULL,
`tasks` varchar(255) NOT NULL,
`builds` varchar(255) NOT NULL,
`title` varchar(255) NOT NULL,
`begin` date NOT NULL,
`end` date NOT NULL,
`owner` char(30) NOT NULL,
`members` text NOT NULL,
`stories` text NOT NULL,
`bugs` text NOT NULL,
`cases` text NOT NULL,
`report` text NOT NULL,
`objectType` varchar(20) NOT NULL,
`objectID` mediumint(8) unsigned NOT NULL,
`createdBy` char(30) NOT NULL,
`createdDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_testresult` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`run` mediumint(8) unsigned NOT NULL,
`case` mediumint(8) unsigned NOT NULL,
`version` smallint(5) unsigned NOT NULL,
`caseResult` char(30) NOT NULL,
`stepResults` text NOT NULL,
`lastRunner` varchar(30) NOT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `case` (`case`),
KEY `version` (`version`),
KEY `run` (`run`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_testrun` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`task` mediumint(8) unsigned NOT NULL DEFAULT '0',
`case` mediumint(8) unsigned NOT NULL DEFAULT '0',
`version` tinyint(3) unsigned NOT NULL DEFAULT '0',
`assignedTo` char(30) NOT NULL DEFAULT '',
`lastRunner` varchar(30) NOT NULL,
`lastRunDate` datetime NOT NULL,
`lastRunResult` char(30) NOT NULL,
`status` char(30) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `task` (`task`,`case`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_testsuite` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`desc` text NOT NULL,
`type` varchar(20) NOT NULL,
`addedBy` char(30) NOT NULL,
`addedDate` datetime NOT NULL,
`lastEditedBy` char(30) NOT NULL,
`lastEditedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL,
PRIMARY KEY (`id`),
KEY `product` (`product`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_testtask` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` char(90) NOT NULL,
`product` mediumint(8) unsigned NOT NULL,
`project` mediumint(8) unsigned NOT NULL DEFAULT '0',
`build` char(30) NOT NULL,
`owner` varchar(30) NOT NULL,
`pri` tinyint(3) unsigned NOT NULL DEFAULT '0',
`begin` date NOT NULL,
`end` date NOT NULL,
`mailto` text,
`desc` text NOT NULL,
`report` text NOT NULL,
`status` enum('blocked','doing','wait','done') NOT NULL DEFAULT 'wait',
`subStatus` varchar(30) NOT NULL DEFAULT '',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`),
KEY `build` (`build`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_translation` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`lang` varchar(30) NOT NULL,
`module` varchar(30) NOT NULL,
`key` varchar(100) NOT NULL,
`value` text NOT NULL,
`referer` text NOT NULL,
`status` varchar(30) NOT NULL,
`translator` char(30) NOT NULL,
`translatedTime` datetime NOT NULL,
`reviewer` char(30) NOT NULL,
`reviewedTime` datetime NOT NULL,
`reason` text NOT NULL,
`version` varchar(20) NOT NULL,
`mode` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `lang_module_key_mode` (`lang`,`module`,`key`,`mode`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_todo` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`account` char(30) NOT NULL,
`date` date NOT NULL,
`begin` smallint(4) unsigned zerofill NOT NULL,
`end` smallint(4) unsigned zerofill NOT NULL,
`type` char(10) NOT NULL,
`cycle` tinyint(3) unsigned NOT NULL DEFAULT '0',
`idvalue` mediumint(8) unsigned NOT NULL DEFAULT '0',
`pri` tinyint(3) unsigned NOT NULL,
`name` char(150) NOT NULL,
`desc` text NOT NULL,
`status` enum('wait','doing','done','closed') NOT NULL DEFAULT 'wait',
`private` tinyint(1) NOT NULL,
`config` varchar(255) NOT NULL,
`assignedTo` varchar(30) NOT NULL DEFAULT '',
`assignedBy` varchar(30) NOT NULL DEFAULT '',
`assignedDate` datetime NOT NULL,
`finishedBy` varchar(30) NOT NULL DEFAULT '',
`finishedDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL DEFAULT '',
`closedDate` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `account` (`account`),
KEY `assignedTo` (`assignedTo`),
KEY `finishedBy` (`finishedBy`),
KEY `date` (`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_user` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`dept` mediumint(8) unsigned NOT NULL DEFAULT '0',
`account` char(30) NOT NULL DEFAULT '',
`password` char(32) NOT NULL DEFAULT '',
`role` char(10) NOT NULL DEFAULT '',
`realname` varchar(100) NOT NULL DEFAULT '',
`nickname` char(60) NOT NULL DEFAULT '',
`commiter` varchar(100) NOT NULL,
`avatar` char(30) NOT NULL DEFAULT '',
`birthday` date NOT NULL DEFAULT '0000-00-00',
`gender` enum('f','m') NOT NULL DEFAULT 'f',
`email` char(90) NOT NULL DEFAULT '',
`skype` char(90) NOT NULL DEFAULT '',
`qq` char(20) NOT NULL DEFAULT '',
`mobile` char(11) NOT NULL DEFAULT '',
`phone` char(20) NOT NULL DEFAULT '',
`weixin` varchar(90) NOT NULL DEFAULT '',
`dingding` varchar(90) NOT NULL DEFAULT '',
`slack` varchar(90) NOT NULL DEFAULT '',
`whatsapp` varchar(90) NOT NULL DEFAULT '',
`address` char(120) NOT NULL DEFAULT '',
`zipcode` char(10) NOT NULL DEFAULT '',
`join` date NOT NULL DEFAULT '0000-00-00',
`visits` mediumint(8) unsigned NOT NULL DEFAULT '0',
`ip` char(15) NOT NULL DEFAULT '',
`last` int(10) unsigned NOT NULL DEFAULT '0',
`fails` tinyint(5) NOT NULL DEFAULT '0',
`locked` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`ranzhi` char(30) NOT NULL DEFAULT '',
`score` int(11) NOT NULL DEFAULT '0',
`scoreLevel` int(11) NOT NULL DEFAULT '0',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `account` (`account`),
KEY `dept` (`dept`),
KEY `email` (`email`),
KEY `commiter` (`commiter`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_usercontact` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`account` char(30) NOT NULL,
`listName` varchar(60) NOT NULL,
`userList` text NOT NULL,
PRIMARY KEY (`id`),
KEY `account` (`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_usergroup` (
`account` char(30) NOT NULL DEFAULT '',
`group` mediumint(8) unsigned NOT NULL DEFAULT '0',
UNIQUE KEY `account` (`account`,`group`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_userquery` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`account` char(30) NOT NULL,
`module` varchar(30) NOT NULL,
`title` varchar(90) NOT NULL,
`form` text NOT NULL,
`sql` text NOT NULL,
`shortcut` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `account` (`account`),
KEY `module` (`module`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_usertpl` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`account` char(30) NOT NULL,
`type` char(30) NOT NULL,
`title` varchar(150) NOT NULL,
`content` text NOT NULL,
`public` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `account` (`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_userview` (
`account` char(30) NOT NULL,
`products` mediumtext NOT NULL,
`projects` mediumtext NOT NULL,
UNIQUE KEY `account` (`account`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `zt_webhook` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`type` varchar(10) NOT NULL DEFAULT 'default',
`name` varchar(50) NOT NULL,
`url` varchar(255) NOT NULL,
`domain` varchar(255) NOT NULL,
`secret` varchar(255) NOT NULL,
`contentType` varchar(30) NOT NULL DEFAULT 'application/json',
`sendType` enum('sync','async') NOT NULL DEFAULT 'sync',
`products` text NOT NULL,
`projects` text NOT NULL,
`params` varchar(100) NOT NULL,
`actions` text NOT NULL,
`desc` text NOT NULL,
`createdBy` varchar(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+7
View File
@@ -0,0 +1,7 @@
ALTER TABLE `zt_dept` CHANGE `order` `order` smallint(4) unsigned NOT NULL DEFAULT '0' AFTER `grade`;
CREATE TABLE `zt_dinguserid` (
`webhook` mediumint(8) unsigned NOT NULL,
`account` varchar(30) NOT NULL,
`userid` varchar(255) NOT NULL,
UNIQUE KEY `webhook_account_userid` (`webhook`,`account`,`userid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+3 -6
View File
@@ -943,6 +943,7 @@ CREATE TABLE IF NOT EXISTS `zt_webhook` (
`name` varchar(50) NOT NULL,
`url` varchar(255) NOT NULL,
`domain` varchar(255) NOT NULL,
`secret` varchar(255) NOT NULL,
`contentType` varchar(30) NOT NULL DEFAULT 'application/json',
`sendType` enum('sync','async') NOT NULL DEFAULT 'sync',
`products` text NOT NULL,
@@ -1101,6 +1102,8 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(1, 'dept', 'updateOrder'),
(1, 'dev', 'api'),
(1, 'dev', 'db'),
(1, 'dev', 'editor'),
(1, 'dev', 'translate'),
(1, 'doc', 'browse'),
(1, 'doc', 'create'),
(1, 'doc', 'createLib'),
@@ -1114,12 +1117,6 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(1, 'doc', 'showFiles'),
(1, 'doc', 'view'),
(1, 'doc', 'sort'),
(1, 'editor', 'delete'),
(1, 'editor', 'edit'),
(1, 'editor', 'extend'),
(1, 'editor', 'index'),
(1, 'editor', 'newPage'),
(1, 'editor', 'save'),
(1, 'extension', 'activate'),
(1, 'extension', 'browse'),
(1, 'extension', 'deactivate'),
+10
View File
@@ -1,3 +1,13 @@
2019-11-08 11.6.5
完成的需求:
4411 优化产品汇总表中对子计划的展示
修复的Bug:
2821 测试单点击用例标题报错
2822 点击用例库模块提示错误
2824 /module/task/view/create.html.php文件语句问题,199行</td>与151行<td>导致页面出错
2831 权限名称和菜单名称不统一
修复WebHook对钉钉的支持
2019-10-17 11.6.4
完成的需求:
4392 维护文档分类切换所属文档库后把分类下面的文档也带到新文档库中
+9 -6
View File
@@ -595,9 +595,12 @@ class baseRouter
unset($_REQUEST);
/* Change for CSRF. */
$httpType = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on') ? 'https' : 'http';
$httpHost = $_SERVER['HTTP_HOST'];
if(strpos($this->server->http_referer, "$httpType://$httpHost") !== 0) $_FILES = $_POST = array();
if($this->config->framework->filterCSRF)
{
$httpType = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on') ? 'https' : 'http';
$httpHost = $_SERVER['HTTP_HOST'];
if((!defined('RUN_MODE') or RUN_MODE != 'api') and strpos($this->server->http_referer, "$httpType://$httpHost") !== 0) $_FILES = $_POST = array();
}
$_FILES = validater::filterFiles();
$_POST = validater::filterSuper($_POST);
@@ -864,7 +867,7 @@ class baseRouter
$this->clientLang = $this->config->default->lang;
}
setcookie('lang', $this->clientLang, $this->config->cookieLife, $this->config->webRoot);
setcookie('lang', $this->clientLang, $this->config->cookieLife, $this->config->webRoot, '', false, true);
if(!isset($_COOKIE['lang'])) $_COOKIE['lang'] = $this->clientLang;
return true;
@@ -918,7 +921,7 @@ class baseRouter
$this->clientTheme = $this->config->default->theme;
}
setcookie('theme', $this->clientTheme, $this->config->cookieLife, $this->config->webRoot);
setcookie('theme', $this->clientTheme, $this->config->cookieLife, $this->config->webRoot, '', false, true);
if(!isset($_COOKIE['theme'])) $_COOKIE['theme'] = $this->clientTheme;
return true;
@@ -944,7 +947,7 @@ class baseRouter
$this->clientDevice = ($mobile->isMobile() and !$mobile->isTablet()) ? 'mobile' : 'desktop';
}
setcookie('device', $this->clientDevice, $this->config->cookieLife, $this->config->webRoot);
setcookie('device', $this->clientDevice, $this->config->cookieLife, $this->config->webRoot, '', false, true);
if(!isset($_COOKIE['device'])) $_COOKIE['device'] = $this->clientDevice;
return $this->clientDevice;
+41 -17
View File
@@ -21,7 +21,7 @@ include dirname(__FILE__) . '/base/control.class.php';
class control extends baseControl
{
/**
* Set requiredFields for workflow.
* Check requiredFields and set exportFields for workflow.
*
* @param string $moduleName
* @param string $methodName
@@ -35,27 +35,16 @@ class control extends baseControl
if(!isset($this->config->bizVersion)) return false;
/* Code for task #9224. Set requiredFields for workflow. */
$fields = $this->loadModel('workflowaction')->getFields($this->moduleName, $this->methodName);
$layouts = $this->loadModel('workflowlayout')->getFields($this->moduleName, $this->methodName);
$notEmptyRule = $this->loadModel('workflowrule')->getByTypeAndRule('system', 'notempty');
foreach($fields as $field)
if($this->dbh and $this->moduleName != 'upgrade' and $this->moduleName != 'install')
{
$this->checkRequireFlowField();
if($notEmptyRule && strpos(",$field->rules,", ",$notEmptyRule->id,") !== false)
if(isset($this->config->{$this->moduleName}) and isset($this->config->{$this->moduleName}->exportFields) and strpos($this->methodName, 'export') !== false)
{
if(!isset($this->config->{$this->moduleName})) $this->config->{$this->moduleName} = new stdclass();
if(!isset($this->config->{$this->moduleName}->{$this->methodName})) $this->config->{$this->moduleName}->{$this->methodName} = new stdclass();
if(!isset($this->config->{$this->moduleName}->{$this->methodName}->requiredFields)) $this->config->{$this->moduleName}->{$this->methodName}->requiredFields = '';
$this->config->{$this->moduleName}->{$this->methodName}->requiredFields .= ",{$field->field}";
$exportFields = $this->dao->select('*')->from(TABLE_WORKFLOWFIELD)->where('module')->eq($this->moduleName)->andWhere('canExport')->eq('1')->andWhere('buildin')->eq('0')->fetchAll('field');
foreach($exportFields as $field) $this->config->{$this->moduleName}->exportFields .= ",{$field->field}";
}
}
if(isset($this->config->{$this->moduleName}) and isset($this->config->{$this->moduleName}->exportFields))
{
$exportFields = $this->dao->select('*')->from(TABLE_WORKFLOWFIELD)->where('module')->eq($this->moduleName)->andWhere('canExport')->eq('1')->andWhere('buildin')->eq('0')->fetchAll('field');
foreach($exportFields as $field) $this->config->{$this->moduleName}->exportFields .= ",{$field->field}";
}
}
/**
@@ -254,4 +243,39 @@ class control extends baseControl
return $this->$moduleName->processStatus($module, $record);
}
/**
* Check require with flow field when post data.
*
* @access public
* @return void
*/
public function checkRequireFlowField()
{
if(!isset($this->config->bizVersion)) return false;
if(empty($_POST)) return false;
$fields = $this->loadModel('workflowaction')->getFields($this->moduleName, $this->methodName);
$layouts = $this->loadModel('workflowlayout')->getFields($this->moduleName, $this->methodName);
$notEmptyRule = $this->loadModel('workflowrule')->getByTypeAndRule('system', 'notempty');
$requiredFields = '';
foreach($fields as $field)
{
if($field->buildin or !$field->show or !isset($layouts[$field->field])) continue;
if($notEmptyRule && strpos(",$field->rules,", ",$notEmptyRule->id,") !== false) $requiredFields .= ",{$field->field}";
}
if($requiredFields)
{
if(isset($this->config->{$this->moduleName}->{$this->methodName}->requiredFields)) $requiredFields .= ',' . $this->config->{$this->moduleName}->{$this->methodName}->requiredFields;
$message = array();
foreach(explode(',', $requiredFields) as $requiredField)
{
if(isset($_POST[$requiredField]) and $_POST[$requiredField] === '')$message[$requiredField] = sprintf($this->lang->error->notempty, $fields[$requiredField]->name);
}
if($message) $this->send(array('result' => 'fail', 'message' => $message));
}
}
}
+17 -3
View File
@@ -39,7 +39,7 @@ class router extends baseRouter
public $rawMethod;
/**
* 请求的原始方法名。
* 请求的原始参数。
* The requested params parsed from a URL.
*
* @var array
@@ -105,7 +105,9 @@ class router extends baseRouter
try
{
$productProject = $this->dbh->query('SELECT value FROM' . TABLE_CONFIG . "WHERE `owner`='system' AND `module`='custom' AND `key`='productProject'")->fetch();
$productProject = $this->dbh->query('SELECT value FROM' . TABLE_CONFIG . "WHERE `owner`='system' AND `module`='custom' AND `key`='productProject'")->fetch();
$storyRequirement = $this->dbh->query('SELECT value FROM' . TABLE_CONFIG . "WHERE `owner`='system' AND `module`='custom' AND `key`='storyRequirement'")->fetch();
$hourPoint = $this->dbh->query('SELECT value FROM' . TABLE_CONFIG . "WHERE `owner`='system' AND `module`='custom' AND `key`='hourPoint'")->fetch();
}
catch (PDOException $exception)
{
@@ -125,7 +127,7 @@ class router extends baseRouter
}
}
$productCommon = $projectCommon = 0;
$productCommon = $projectCommon = $storyCommon = 0;
if(!empty($this->config->isINT)) $projectCommon = 1;
if($productProject)
{
@@ -133,6 +135,18 @@ class router extends baseRouter
list($productCommon, $projectCommon) = explode('_', $productProject);
}
if($storyRequirement)
{
$storyCommon = $storyRequirement->value;
$lang->storyCommon = isset($this->config->storyCommonList[$this->clientLang][(int)$storyCommon]) ? $this->config->storyCommonList[$this->clientLang][(int)$storyCommon] : $this->config->storyCommonList['en'][(int)$storyCommon];
}
if($hourPoint)
{
$hourCommon = $hourPoint->value;
$lang->hourCommon = isset($this->config->hourPointCommonList[$this->clientLang][(int)$hourCommon]) ? $this->config->hourPointCommonList[$this->clientLang][(int)$hourCommon] : $this->config->hourPointCommonList['en'][(int)$hourCommon];
}
/* Set productCommon and projectCommon. Default english lang. */
$lang->productCommon = isset($this->config->productCommonList[$this->clientLang][(int)$productCommon]) ? $this->config->productCommonList[$this->clientLang][(int)$productCommon] : $this->config->productCommonList['en'][(int)$productCommon];
$lang->projectCommon = isset($this->config->projectCommonList[$this->clientLang][(int)$projectCommon]) ? $this->config->projectCommonList[$this->clientLang][(int)$projectCommon] : $this->config->projectCommonList['en'][(int)$projectCommon];
+2 -2
View File
@@ -330,7 +330,7 @@ class baseValidater
*/
public static function checkNotEmpty($var)
{
return !empty($var);
return strlen(trim($var)) != 0;
}
/**
@@ -344,7 +344,7 @@ class baseValidater
*/
public static function checkEmpty($var)
{
return empty($var);
return strlen(trim($var)) == 0;
}
/**
+1 -1
View File
@@ -110,7 +110,7 @@ class baseHTML
{
global $config;
if(empty($title)) $title = $href;
if(strlen(trim($title)) == 0) $title = $href;
$newline = $newline ? "\n" : '';
return "<a href='$href' $misc>$title</a>$newline";
+114
View File
@@ -0,0 +1,114 @@
<?php
class dingapi
{
public $apiUrl = 'https://oapi.dingtalk.com/';
private $appKey;
private $appSecret;
private $token;
private $expires;
private $errors = array();
public function __construct($appKey, $appSecret, $agentId, $apiUrl = '')
{
$this->appKey = $appKey;
$this->appSecret = $appSecret;
$this->agentId = $agentId;
if($apiUrl) $this->apiUrl = rtrim($apiUrl, '/') . '/';
if(!$this->getToken()) return array('result' => 'fail', 'message' => $this->errors);
}
public function getToken()
{
if($this->token and (time() - $this->expires) >= 0) return $this->token;
$response = $this->queryAPI($this->apiUrl . "gettoken?appkey={$this->appKey}&appsecret={$this->appSecret}");
if($this->isError()) return false;
$this->token = $response->access_token;
$this->expires = time() + $response->expires_in;
return $this->token;
}
public function getAllUsers()
{
$depts = $this->getAllDepts();
if($this->isError()) return array('result' => 'fail', 'message' => $this->errors);
$users = array();
foreach($depts as $deptID => $deptName)
{
$response = $this->queryAPI($this->apiUrl . "user/simplelist?access_token={$this->token}&department_id={$deptID}");
if($this->isError()) return array('result' => 'fail', 'message' => $this->errors);
foreach($response->userlist as $user) $users[$user->name] = $user->userid;
}
return array('result' => 'success', 'data' => $users);
}
public function getAllDepts()
{
$response = $this->queryAPI($this->apiUrl . "department/list?access_token={$this->token}");
if($this->isError()) return false;
$deptPairs = array();
foreach($response->department as $dept) $deptPairs[$dept->id] = $dept->name;
return $deptPairs;
}
public function send($userList, $message)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($curl, CURLOPT_USERAGENT, 'Sae T OAuth2 v0.1');
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($curl, CURLOPT_HEADER, FALSE);
curl_setopt($curl, CURLOPT_URL, $this->apiUrl . 'topapi/message/corpconversation/asyncsend_v2?access_token=' . $this->token);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
$postData = array();
$postData['agent_id'] = $this->agentId;
$postData['userid_list'] = $userList;
$postData['msg'] = $message;
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
$response = curl_exec($curl);
curl_close($curl);
$response = json_decode($response);
if(isset($response->errcode) and $response->errcode == 0) return array('result' => 'success');
$this->errors[$response->errcode] = "Errcode:{$response->errcode}, Errmsg:{$response->errmsg}";
return array('result' => 'fail', 'message' => $this->errors);
}
public function queryAPI($url)
{
$response = json_decode(file_get_contents($url));
if(isset($response->errcode) and $response->errcode == 0) return $response;
$this->errors[$response->errcode] = "Errcode:{$response->errcode}, Errmsg:{$response->errmsg}";
return false;
}
public function isError()
{
return !empty($this->errors);
}
public function getErrors()
{
$errors = $this->errors;
$this->errors = array();
return $errors;
}
}
+1 -1
View File
@@ -134,7 +134,7 @@ class action extends control
*/
public function editComment($actionID)
{
if(trim(strip_tags($this->post->lastComment, '<img>')))
if(strlen(trim(strip_tags($this->post->lastComment, '<img>'))) != 0)
{
$this->action->updateComment($actionID);
}
+1 -1
View File
@@ -373,7 +373,7 @@ $lang->action->label->bug = 'Bug|bug|view|bugID=%s';
$lang->action->label->case = 'Case|testcase|view|caseID=%s';
$lang->action->label->testtask = 'Request|testtask|view|caseID=%s';
$lang->action->label->testsuite = 'Test Suite|testsuite|view|suiteID=%s';
$lang->action->label->caselib = 'Case Library|testsuite|libview|libID=%s';
$lang->action->label->caselib = 'Case Library|caselib|view|libID=%s';
$lang->action->label->todo = 'Todo|todo|view|todoID=%s';
$lang->action->label->doclib = 'Doc Library|doc|browse|libID=%s';
$lang->action->label->doc = 'Doc|doc|view|docID=%s';
+31 -31
View File
@@ -65,7 +65,7 @@ $lang->action->periods['thismonth'] = $lang->action->dynamic->thisMonth;
$lang->action->periods['lastmonth'] = $lang->action->dynamic->lastMonth;
$lang->action->objectTypes['product'] = $lang->productCommon;
$lang->action->objectTypes['story'] = '需求';
$lang->action->objectTypes['story'] = $lang->storyCommon;
$lang->action->objectTypes['productplan'] = '计划';
$lang->action->objectTypes['release'] = '发布';
$lang->action->objectTypes['project'] = $lang->projectCommon;
@@ -108,7 +108,7 @@ $lang->action->desc->commented = '$date, 由 <strong>$actor</strong> 添加
$lang->action->desc->activated = '$date, 由 <strong>$actor</strong> 激活。' . "\n";
$lang->action->desc->blocked = '$date, 由 <strong>$actor</strong> 阻塞。' . "\n";
$lang->action->desc->moved = '$date, 由 <strong>$actor</strong> 移动,之前为 "$extra"。' . "\n";
$lang->action->desc->confirmed = '$date, 由 <strong>$actor</strong> 确认需求变动,最新版本为<strong>#$extra</strong>。' . "\n";
$lang->action->desc->confirmed = '$date, 由 <strong>$actor</strong> 确认' . $lang->storyCommon . '变动,最新版本为<strong>#$extra</strong>。' . "\n";
$lang->action->desc->caseconfirmed = '$date, 由 <strong>$actor</strong> 确认用例变动,最新版本为<strong>#$extra</strong>。' . "\n";
$lang->action->desc->bugconfirmed = '$date, 由 <strong>$actor</strong> 确认Bug。' . "\n";
$lang->action->desc->frombug = '$date, 由 <strong>$actor</strong> Bug转化而来,Bug编号为 <strong>$extra</strong>。';
@@ -163,10 +163,10 @@ $lang->action->label->blocked = '阻塞了';
$lang->action->label->resolved = '解决了';
$lang->action->label->reviewed = '评审了';
$lang->action->label->moved = '移动了';
$lang->action->label->confirmed = '确认了需求';
$lang->action->label->confirmed = "确认了{$lang->storyCommon}";
$lang->action->label->bugconfirmed = '确认了';
$lang->action->label->tostory = '转需求';
$lang->action->label->frombug = '转需求';
$lang->action->label->tostory = "转{$lang->storyCommon}";
$lang->action->label->frombug = "转{$lang->storyCommon}";
$lang->action->label->fromlib = '从用例库导入';
$lang->action->label->totask = '转任务';
$lang->action->label->svncommited = '提交代码';
@@ -184,10 +184,10 @@ $lang->action->label->linkrelatedbug = "关联了相关Bug";
$lang->action->label->unlinkrelatedbug = "移除了相关Bug";
$lang->action->label->linkrelatedcase = "关联了相关用例";
$lang->action->label->unlinkrelatedcase = "移除了相关用例";
$lang->action->label->linkrelatedstory = "关联了相关需求";
$lang->action->label->unlinkrelatedstory = "移除了相关需求";
$lang->action->label->subdividestory = "细分了需求";
$lang->action->label->unlinkchildstory = "移除了细分需求";
$lang->action->label->linkrelatedstory = "关联了相关{$lang->storyCommon}";
$lang->action->label->unlinkrelatedstory = "移除了相关{$lang->storyCommon}";
$lang->action->label->subdividestory = "细分了{$lang->storyCommon}";
$lang->action->label->unlinkchildstory = "移除了细分{$lang->storyCommon}";
$lang->action->label->started = '开始了';
$lang->action->label->restarted = '继续了';
$lang->action->label->recordestimate = '记录了工时';
@@ -238,22 +238,22 @@ $lang->action->dynamicAction->release['edited'] = '编辑发布';
$lang->action->dynamicAction->release['changestatus'] = '修改发布状态';
$lang->action->dynamicAction->release['undeleted'] = '还原发布';
$lang->action->dynamicAction->release['hidden'] = '隐藏发布';
$lang->action->dynamicAction->story['opened'] = '创建需求';
$lang->action->dynamicAction->story['edited'] = '编辑需求';
$lang->action->dynamicAction->story['activated'] = '激活需求';
$lang->action->dynamicAction->story['reviewed'] = '评审需求';
$lang->action->dynamicAction->story['closed'] = '关闭需求';
$lang->action->dynamicAction->story['assigned'] = '指派需求';
$lang->action->dynamicAction->story['changed'] = '变更需求';
$lang->action->dynamicAction->story['linked2plan'] = '需求关联计划';
$lang->action->dynamicAction->story['unlinkedfromplan'] = '计划移除需求';
$lang->action->dynamicAction->story['linked2release'] = '需求关联发布';
$lang->action->dynamicAction->story['unlinkedfromrelease'] = '发布移除需求';
$lang->action->dynamicAction->story['linked2build'] = '需求关联版本';
$lang->action->dynamicAction->story['unlinkedfrombuild'] = '版本移除需求';
$lang->action->dynamicAction->story['opened'] = "创建{$lang->storyCommon}";
$lang->action->dynamicAction->story['edited'] = "编辑{$lang->storyCommon}";
$lang->action->dynamicAction->story['activated'] = "激活{$lang->storyCommon}";
$lang->action->dynamicAction->story['reviewed'] = "评审{$lang->storyCommon}";
$lang->action->dynamicAction->story['closed'] = "关闭{$lang->storyCommon}";
$lang->action->dynamicAction->story['assigned'] = "指派{$lang->storyCommon}";
$lang->action->dynamicAction->story['changed'] = "变更{$lang->storyCommon}";
$lang->action->dynamicAction->story['linked2plan'] = "{$lang->storyCommon}关联计划";
$lang->action->dynamicAction->story['unlinkedfromplan'] = "计划移除{$lang->storyCommon}";
$lang->action->dynamicAction->story['linked2release'] = "{$lang->storyCommon}关联发布";
$lang->action->dynamicAction->story['unlinkedfromrelease'] = "发布移除{$lang->storyCommon}";
$lang->action->dynamicAction->story['linked2build'] = "{$lang->storyCommon}关联版本";
$lang->action->dynamicAction->story['unlinkedfrombuild'] = "版本移除{$lang->storyCommon}";
$lang->action->dynamicAction->story['unlinkedfromproject'] = '移除项目';
$lang->action->dynamicAction->story['undeleted'] = '还原需求';
$lang->action->dynamicAction->story['hidden'] = '隐藏需求';
$lang->action->dynamicAction->story['undeleted'] = "还原{$lang->storyCommon}";
$lang->action->dynamicAction->story['hidden'] = "隐藏{$lang->storyCommon}";
$lang->action->dynamicAction->project['opened'] = '创建' . $lang->projectCommon;
$lang->action->dynamicAction->project['edited'] = '编辑' . $lang->projectCommon;
@@ -271,7 +271,7 @@ $lang->action->dynamicAction->task['opened'] = '创建任务';
$lang->action->dynamicAction->task['edited'] = '编辑任务';
$lang->action->dynamicAction->task['commented'] = '备注任务';
$lang->action->dynamicAction->task['assigned'] = '指派任务';
$lang->action->dynamicAction->task['confirmed'] = '确认需求变更';
$lang->action->dynamicAction->task['confirmed'] = "确认{$lang->storyCommon}变更";
$lang->action->dynamicAction->task['started'] = '开始任务';
$lang->action->dynamicAction->task['finished'] = '完成任务';
$lang->action->dynamicAction->task['recordestimate'] = '记录工时';
@@ -302,8 +302,8 @@ $lang->action->dynamicAction->bug['bugconfirmed'] = '确认Bug';
$lang->action->dynamicAction->bug['resolved'] = '解决Bug';
$lang->action->dynamicAction->bug['undeleted'] = '还原Bug';
$lang->action->dynamicAction->bug['hidden'] = '隐藏Bug';
$lang->action->dynamicAction->bug['confirmed'] = '确认需求变更';
$lang->action->dynamicAction->bug['tostory'] = '转需求';
$lang->action->dynamicAction->bug['confirmed'] = "确认{$lang->storyCommon}变更";
$lang->action->dynamicAction->bug['tostory'] = "转{$lang->storyCommon}";
$lang->action->dynamicAction->bug['totask'] = '转任务';
$lang->action->dynamicAction->bug['linked2plan'] = 'Bug关联计划';
$lang->action->dynamicAction->bug['unlinkedfromplan'] = '计划移除Bug';
@@ -323,7 +323,7 @@ $lang->action->dynamicAction->case['deleted'] = '删除用例';
$lang->action->dynamicAction->case['undeleted'] = '还原用例';
$lang->action->dynamicAction->case['hidden'] = '隐藏用例';
$lang->action->dynamicAction->case['reviewed'] = '评审用例';
$lang->action->dynamicAction->case['confirmed'] = '确认需求变更';
$lang->action->dynamicAction->case['confirmed'] = "确认{$lang->storyCommon}变更";
$lang->action->dynamicAction->case['fromlib'] = '从用例库导入';
$lang->action->dynamicAction->testreport['opened'] = '创建测试报告';
$lang->action->dynamicAction->testreport['edited'] = '编辑测试报告';
@@ -365,7 +365,7 @@ $lang->action->dynamicAction->entry['edited'] = '编辑应用';
$lang->action->label->product = $lang->productCommon . '|product|view|productID=%s';
$lang->action->label->productplan = '计划|productplan|view|productID=%s';
$lang->action->label->release = '发布|release|view|productID=%s';
$lang->action->label->story = '需求|story|view|storyID=%s';
$lang->action->label->story = "{$lang->storyCommon}|story|view|storyID=%s";
$lang->action->label->project = "{$lang->projectCommon}|project|view|projectID=%s";
$lang->action->label->task = '任务|task|view|taskID=%s';
$lang->action->label->build = '版本|build|view|buildID=%s';
@@ -373,7 +373,7 @@ $lang->action->label->bug = 'Bug|bug|view|bugID=%s';
$lang->action->label->case = '用例|testcase|view|caseID=%s';
$lang->action->label->testtask = '测试单|testtask|view|caseID=%s';
$lang->action->label->testsuite = '测试套件|testsuite|view|suiteID=%s';
$lang->action->label->caselib = '用例库|testsuite|libview|libID=%s';
$lang->action->label->caselib = '用例库|caselib|view|libID=%s';
$lang->action->label->todo = '待办|todo|view|todoID=%s';
$lang->action->label->doclib = '文档库|doc|browse|libID=%s';
$lang->action->label->doc = '文档|doc|view|docID=%s';
@@ -391,7 +391,7 @@ $lang->action->search->objectTypeList['bug'] = 'Bug';
$lang->action->search->objectTypeList['case'] = '用例';
$lang->action->search->objectTypeList['caseresult'] = '用例结果';
$lang->action->search->objectTypeList['stepresult'] = '用例步骤';
$lang->action->search->objectTypeList['story'] = '需求';
$lang->action->search->objectTypeList['story'] = $lang->storyCommon;
$lang->action->search->objectTypeList['task'] = '任务';
$lang->action->search->objectTypeList['testtask'] = '测试单';
$lang->action->search->objectTypeList['user'] = '用户';
+1 -1
View File
@@ -373,7 +373,7 @@ $lang->action->label->bug = 'Bug|bug|view|bugID=%s';
$lang->action->label->case = '用例|testcase|view|caseID=%s';
$lang->action->label->testtask = '測試單|testtask|view|caseID=%s';
$lang->action->label->testsuite = '測試套件|testsuite|view|suiteID=%s';
$lang->action->label->caselib = '用例庫|testsuite|libview|libID=%s';
$lang->action->label->caselib = '用例庫|caselib|view|libID=%s';
$lang->action->label->todo = '待辦|todo|view|todoID=%s';
$lang->action->label->doclib = '文檔庫|doc|browse|libID=%s';
$lang->action->label->doc = '文檔|doc|view|docID=%s';
+5 -5
View File
@@ -397,8 +397,8 @@ $lang->block->gridOptions[8] = 'Left';
$lang->block->gridOptions[4] = 'Right';
$lang->block->flowchart = array();
$lang->block->flowchart[] = array('Administrateur', 'Ajoute Compartiment', 'Ajoute Utilisateurs', 'Administre Privilèges');
$lang->block->flowchart[] = array($lang->productCommon . ' Owner', 'Ajoute ' . $lang->productCommon . '/Modules', 'Ajoute ' . $lang->projectCommon . 's', 'Ajoute Stories', 'Maintient Plans', 'Crée Releases');
$lang->block->flowchart[] = array('Scrum Master', 'Ajoute ' . $lang->projectCommon . 's', 'Constitue Equipes', 'Associe ' . $lang->productCommon . 's', 'Rattache Stories', 'Crée/Affecte Tâches');
$lang->block->flowchart[] = array('Développeurs', 'Réclament Tâches/Bugs', 'Effectuent Tâches', 'Corrigent Bugs', 'MàJ Statuts', 'Terminent Tâches/Bugs');
$lang->block->flowchart[] = array('Testeurs', 'Rédigent CasTests', 'Jouent CasTests', 'Détectent Bugs', 'Vérifient Corrections', 'Ferment Bugs');
$lang->block->flowchart['admin'] = array('Administrateur', 'Ajoute Compartiment', 'Ajoute Utilisateurs', 'Administre Privilèges');
$lang->block->flowchart['product'] = array($lang->productCommon . ' Owner', 'Ajoute ' . $lang->productCommon . '/Modules', 'Ajoute ' . $lang->projectCommon . 's', 'Ajoute Stories', 'Maintient Plans', 'Crée Releases');
$lang->block->flowchart['project'] = array('Scrum Master', 'Ajoute ' . $lang->projectCommon . 's', 'Constitue Equipes', 'Associe ' . $lang->productCommon . 's', 'Rattache Stories', 'Crée/Affecte Tâches');
$lang->block->flowchart['dev'] = array('Développeurs', 'Réclament Tâches/Bugs', 'Effectuent Tâches', 'Corrigent Bugs', 'MàJ Statuts', 'Terminent Tâches/Bugs');
$lang->block->flowchart['tester'] = array('Testeurs', 'Rédigent CasTests', 'Jouent CasTests', 'Détectent Bugs', 'Vérifient Corrections', 'Ferment Bugs');
+6 -6
View File
@@ -38,7 +38,7 @@ $lang->block->lblTesttask = '查看测试详情';
$lang->block->leftToday = '今天剩余工作总计';
$lang->block->myTask = '我的任务';
$lang->block->myStory = '我的需求';
$lang->block->myStory = "我的{$lang->storyCommon}";
$lang->block->myBug = '我的BUG';
$lang->block->myProject = '进行中的' . $lang->projectCommon;
$lang->block->myProduct = '未关闭的' . $lang->productCommon;
@@ -82,7 +82,7 @@ $lang->block->default['product']['3']['grid'] = 8;
$lang->block->default['product']['3']['params']['num'] = 15;
$lang->block->default['product']['3']['params']['type'] = 'noclosed';
$lang->block->default['product']['4']['title'] = '指派给我的需求';
$lang->block->default['product']['4']['title'] = "指派给我的{$lang->storyCommon}";
$lang->block->default['product']['4']['block'] = 'story';
$lang->block->default['product']['4']['grid'] = 4;
@@ -238,7 +238,7 @@ $lang->block->availableBlocks->todo = '我的待办';
$lang->block->availableBlocks->task = '我的任务';
$lang->block->availableBlocks->bug = '我的Bug';
$lang->block->availableBlocks->case = '我的用例';
$lang->block->availableBlocks->story = '我的需求';
$lang->block->availableBlocks->story = "我的{$lang->storyCommon}";
$lang->block->availableBlocks->product = $lang->productCommon . '列表';
$lang->block->availableBlocks->project = $lang->projectCommon . '列表';
$lang->block->availableBlocks->plan = '计划列表';
@@ -256,7 +256,7 @@ $lang->block->modules['product']->availableBlocks = new stdclass();
$lang->block->modules['product']->availableBlocks->statistic = $lang->productCommon . '统计';
$lang->block->modules['product']->availableBlocks->overview = $lang->productCommon . '总览';
$lang->block->modules['product']->availableBlocks->list = $lang->productCommon . '列表';
$lang->block->modules['product']->availableBlocks->story = '需求列表';
$lang->block->modules['product']->availableBlocks->story = "{$lang->storyCommon}列表";
$lang->block->modules['product']->availableBlocks->plan = '计划列表';
$lang->block->modules['product']->availableBlocks->release = '发布列表';
$lang->block->modules['project'] = new stdclass();
@@ -398,7 +398,7 @@ $lang->block->gridOptions[4] = '右侧';
$lang->block->flowchart = array();
$lang->block->flowchart['admin'] = array('管理员', '维护公司', '添加用户', '维护权限');
$lang->block->flowchart['product'] = array($lang->productCommon . '经理', '创建' . $lang->productCommon, '维护模块', '维护计划', '维护需求', '创建发布');
$lang->block->flowchart['project'] = array($lang->projectCommon . '经理', '创建' . $lang->projectCommon, '维护团队', '关联' . $lang->productCommon, '关联需求', '分解任务');
$lang->block->flowchart['product'] = array($lang->productCommon . '经理', '创建' . $lang->productCommon, '维护模块', '维护计划', "维护{$lang->storyCommon}", '创建发布');
$lang->block->flowchart['project'] = array($lang->projectCommon . '经理', '创建' . $lang->projectCommon, '维护团队', '关联' . $lang->productCommon, "关联{$lang->storyCommon}", '分解任务');
$lang->block->flowchart['dev'] = array('研发人员', '领取任务和Bug', '更新状态', '完成任务和Bug');
$lang->block->flowchart['tester'] = array('测试人员', '撰写用例', '执行用例', '提交Bug', '验证Bug', '关闭Bug');
+5 -5
View File
@@ -397,8 +397,8 @@ $lang->block->gridOptions[8] = '左側';
$lang->block->gridOptions[4] = '右側';
$lang->block->flowchart = array();
$lang->block->flowchart[] = array('管理員', '維護公司', '添加用戶', '維護權限');
$lang->block->flowchart[] = array($lang->productCommon . '經理', '創建' . $lang->productCommon, '維護模組', '維護計劃', '維護需求', '創建發佈');
$lang->block->flowchart[] = array($lang->projectCommon . '經理', '創建' . $lang->projectCommon, '維護團隊', '關聯' . $lang->productCommon, '關聯需求', '分解任務');
$lang->block->flowchart[] = array('研發人員', '領取任務和Bug', '更新狀態', '完成任務和Bug');
$lang->block->flowchart[] = array('測試人員', '撰寫用例', '執行用例', '提交Bug', '驗證Bug', '關閉Bug');
$lang->block->flowchart['admin'] = array('管理員', '維護公司', '添加用戶', '維護權限');
$lang->block->flowchart['product'] = array($lang->productCommon . '經理', '創建' . $lang->productCommon, '維護模組', '維護計劃', '維護需求', '創建發佈');
$lang->block->flowchart['project'] = array($lang->projectCommon . '經理', '創建' . $lang->projectCommon, '維護團隊', '關聯' . $lang->productCommon, '關聯需求', '分解任務');
$lang->block->flowchart['dev'] = array('研發人員', '領取任務和Bug', '更新狀態', '完成任務和Bug');
$lang->block->flowchart['tester'] = array('測試人員', '撰寫用例', '執行用例', '提交Bug', '驗證Bug', '關閉Bug');
+1 -1
View File
@@ -79,7 +79,7 @@ $useGuest = $this->app->user->account == 'guest';
<li class='dropdown'>
<a href='javascript:;' data-toggle='dropdown' class='panel-action'><i class='icon icon-ellipsis-v'></i></a>
<ul class='dropdown-menu pull-right'>
<li><a href='javascript:;' class='refresh-panel'><i class='icon-repeat'></i> <?php echo $lang->block->refresh;?></a></li>
<li><a href='javascript:;' class='refresh-panel'><i class='icon-repeat'></i> <?php echo $lang->block->refresh?></a></li>
<?php if(!$useGuest):?>
<li><a data-toggle='modal' href="<?php echo $this->createLink("block", "admin", "id=$block->id&module=$module"); ?>" class='edit-block' data-title='<?php echo $block->title; ?>' ><?php echo $lang->edit; ?></a></li>
<li><a href='javascript:deleteBlock(<?php echo $index?>);' class='hidden-panel'><?php echo $lang->block->hidden; ?></a></li>
@@ -87,7 +87,15 @@ $(function()
if ($next.length) $next.find('a').trigger('click');
else $nav.children('li:not(.switch-icon)')[isPrev ? 'last' : 'first']().find('a').trigger('click');
e.preventDefault();
});
var $productLi = $('#activeProduct');
if($productLi.length)
{
var productLi = $productLi[0];
$(".col ul.nav").animate({scrollTop: productLi.offsetTop}, "slow");
}
});
</script>
<div class="panel-body">
@@ -101,7 +109,7 @@ $(function()
<ul class="nav nav-stacked nav-secondary scrollbar-hover" id='<?php echo $blockNavId;?>'>
<li class='switch-icon prev'><a><i class='icon icon-arrow-left'></i></a></li>
<?php foreach($products as $product):?>
<li <?php if($product == reset($products)) echo "class='active'";?> productID='<?php echo $product->id;?>'>
<li <?php if($product->id == $this->session->product) echo "class='active' id='activeProduct'";?> productID='<?php echo $product->id;?>'>
<a href="javascript:;" data-target="#tabProduct<?php echo $product->id;?>" data-toggle="tab" title='<?php echo $product->name;?>'><?php echo $product->name;?></a>
<?php echo html::a(helper::createLink('product', 'browse', "productID=$product->id"), "<i class='icon-arrow-right text-primary'></i>", '', "class='btn-view' title={$lang->product->browse}");?></li>
<?php endforeach;?>
@@ -73,6 +73,13 @@ $(function()
else $nav.children('li:not(.switch-icon)')[isPrev ? 'last' : 'first']().find('a').trigger('click');
e.preventDefault();
});
var $projectLi = $('#activeProject');
if($projectLi.length)
{
var projectLi = $projectLi[0];
$(".col ul.nav").animate({scrollTop: projectLi.offsetTop}, "slow");
}
});
</script>
<div class="panel-body">
@@ -86,7 +93,7 @@ $(function()
<ul class="nav nav-stacked nav-secondary scrollbar-hover" id='<?php echo $blockNavId;?>'>
<li class='switch-icon prev'><a><i class='icon icon-arrow-left'></i></a></li>
<?php foreach($projects as $project):?>
<li <?php if($project == reset($projects)) echo "class='active'";?> projectID='<?php echo $project->id;?>'>
<li <?php if($project->id == $this->session->project) echo "class='active' id='activeProject'";?> projectID='<?php echo $project->id;?>'>
<a href="###" data-target="#tab3Content<?php echo $project->id;?>" data-toggle="tab"><?php echo $project->name;?></a>
<?php echo html::a(helper::createLink('project', 'task', "projectID=$project->id"), "<i class='icon-arrow-right text-primary'></i>", '', "class='btn-view' title={$lang->project->task}");?>
</li>
+1 -1
View File
@@ -23,7 +23,7 @@ $themeRoot = $webRoot . "theme/";
<?php
$control = $param['control'];
$attr = empty($param['attr']) ? '' : $param['attr'];
$default = $block ? (isset($block->params->$key) ? $block->params->$key : '') : (isset($param['default']) ? $param['default'] : '');
$default = $block ? (isset($block->params->type) ? $block->params->type : '') : (isset($param['default']) ? $param['default'] : '');
$options = isset($param['options']) ? $param['options'] : array();
echo html::$control("params[type]", $options, $default, "class='form-control chosen' $attr");
?>
+31
View File
@@ -51,6 +51,37 @@ class branchModel extends model
return $branches;
}
/**
* Get all pairs.
*
* @param string $params
* @access public
* @return array
*/
public function getAllPairs($params = '')
{
$branchGroups = $this->dao->select('*')->from(TABLE_BRANCH)->where('deleted')->eq(0)->orderBy('product,`order`')->fetchGroup('product', 'id');
$products = $this->loadModel('product')->getByIdList(array_keys($branchGroups));
$branchPairs = array();
foreach($branchGroups as $productID => $branches)
{
if(empty($products[$productID])) continue;
$product = $products[$productID];
foreach($branches as $branch)
{
$branchPairs[$branch->id] = $product->name . '/' . $branch->name;
}
}
if(strpos($params, 'noempty') === false)
{
$branchPairs = array('0' => $this->lang->branch->all . $this->lang->product->branchName['branch']) + $branchPairs;
}
return $branchPairs;
}
/**
* Manage branch
*
+2 -5
View File
@@ -1448,7 +1448,6 @@ class bug extends control
/* Get related objects id lists. */
$relatedProductIdList = array();
$relatedModuleIdList = array();
$relatedStoryIdList = array();
$relatedTaskIdList = array();
$relatedBugIdList = array();
@@ -1459,7 +1458,6 @@ class bug extends control
foreach($bugs as $bug)
{
$relatedProductIdList[$bug->product] = $bug->product;
$relatedModuleIdList[$bug->module] = $bug->module;
$relatedStoryIdList[$bug->story] = $bug->story;
$relatedTaskIdList[$bug->task] = $bug->task;
$relatedCaseIdList[$bug->case] = $bug->case;
@@ -1483,7 +1481,6 @@ class bug extends control
}
/* Get related objects title or names. */
$relatedModules = array();
$productsType = $this->dao->select('id, type')->from(TABLE_PRODUCT)->where('id')->in($relatedProductIdList)->fetchPairs();
$relatedStories = $this->dao->select('id,title')->from(TABLE_STORY) ->where('id')->in($relatedStoryIdList)->fetchPairs();
$relatedTasks = $this->dao->select('id, name')->from(TABLE_TASK)->where('id')->in($relatedTaskIdList)->fetchPairs();
@@ -1492,8 +1489,8 @@ class bug extends control
$relatedBranch = array('0' => $this->lang->branch->all) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
$relatedBuilds = array('trunk' => $this->lang->trunk) + $this->dao->select('id, name')->from(TABLE_BUILD)->where('id')->in($relatedBuildIdList)->fetchPairs();
$relatedFiles = $this->dao->select('id, objectID, pathname, title')->from(TABLE_FILE)->where('objectType')->eq('bug')->andWhere('objectID')->in(@array_keys($bugs))->andWhere('extra')->ne('editor')->fetchGroup('objectID');
foreach($relatedProductIdList as $relatedProductId) $relatedModules += $this->loadModel('tree')->getOptionMenu($relatedProductId, 'bug');
$this->loadModel('tree');
foreach($bugs as $bug)
{
if($this->post->fileType == 'csv')
@@ -1512,10 +1509,10 @@ class bug extends control
$bug->task = !isset($relatedTasks[$bug->task]) ? '' : $relatedTasks[$bug->task] . "($bug->task)";
$bug->case = !isset($relatedCases[$bug->case]) ? '' : $relatedCases[$bug->case] . "($bug->case)";
if(isset($relatedModules[$bug->module])) $bug->module = $relatedModules[$bug->module] . "(#$bug->module)";
if(isset($relatedBugs[$bug->duplicateBug])) $bug->duplicateBug = $relatedBugs[$bug->duplicateBug] . "($bug->duplicateBug)";
if(isset($relatedBuilds[$bug->resolvedBuild])) $bug->resolvedBuild = $relatedBuilds[$bug->resolvedBuild] . "(#$bug->resolvedBuild)";
if(isset($relatedBranch[$bug->branch])) $bug->branch = $relatedBranch[$bug->branch] . "(#$bug->branch)";
$bugh->module = $bug->module ? $this->tree->getModulePathByID($bug->module) . "(#$bug->module)" : '';
if(isset($bugLang->priList[$bug->pri])) $bug->pri = $bugLang->priList[$bug->pri];
if(isset($bugLang->typeList[$bug->type])) $bug->type = $bugLang->typeList[$bug->type];
-4
View File
@@ -243,17 +243,13 @@ $lang->bug->browserList['other'] = 'Andere';
$lang->bug->typeList[''] = '';
$lang->bug->typeList['codeerror'] = 'Code Fehler';
$lang->bug->typeList['interface'] = 'UI Optimierung';
$lang->bug->typeList['config'] = 'Konfiguration';
$lang->bug->typeList['install'] = 'Install/Ausrollen';
$lang->bug->typeList['security'] = 'Sicherheit';
$lang->bug->typeList['performance'] = 'Performance';
$lang->bug->typeList['standard'] = 'Standard';
$lang->bug->typeList['automation'] = 'Script-Test';
$lang->bug->typeList['designchange'] = 'Design Änderung';
$lang->bug->typeList['newfeature'] = 'Neues Feature';
$lang->bug->typeList['designdefect'] = 'Design Fehler';
$lang->bug->typeList['trackthings'] = 'Arbeit Verfolgen';
$lang->bug->typeList['others'] = 'Andere';
$lang->bug->statusList[''] = '';
-4
View File
@@ -243,17 +243,13 @@ $lang->bug->browserList['other'] = 'Others';
$lang->bug->typeList[''] = '';
$lang->bug->typeList['codeerror'] = 'CodeError';
$lang->bug->typeList['interface'] = 'Interface';
$lang->bug->typeList['config'] = 'Configuration';
$lang->bug->typeList['install'] = 'Installation';
$lang->bug->typeList['security'] = 'Security';
$lang->bug->typeList['performance'] = 'Performance';
$lang->bug->typeList['standard'] = 'CodingConventions';
$lang->bug->typeList['automation'] = 'TestScript';
$lang->bug->typeList['designchange'] = 'DesignChange';
$lang->bug->typeList['newfeature'] = 'NewFeature';
$lang->bug->typeList['designdefect'] = 'DesignDefect';
$lang->bug->typeList['trackthings'] = 'Tracking';
$lang->bug->typeList['others'] = 'Others';
$lang->bug->statusList[''] = '';
-4
View File
@@ -243,17 +243,13 @@ $lang->bug->browserList['other'] = 'Autres';
$lang->bug->typeList[''] = '';
$lang->bug->typeList['codeerror'] = 'Code Erreur';
$lang->bug->typeList['interface'] = 'Interface';
$lang->bug->typeList['config'] = 'Configuration';
$lang->bug->typeList['install'] = 'Installation';
$lang->bug->typeList['security'] = 'Faille Sécurité';
$lang->bug->typeList['performance'] = 'Performance';
$lang->bug->typeList['standard'] = 'Convention de Code';
$lang->bug->typeList['automation'] = 'Script automatisation';
$lang->bug->typeList['designchange'] = 'Design Change';
$lang->bug->typeList['newfeature'] = 'Nouvelle fonctionnalité';
$lang->bug->typeList['designdefect'] = 'Erreur de Design';
$lang->bug->typeList['trackthings'] = 'Tracking';
$lang->bug->typeList['others'] = 'Autres';
$lang->bug->statusList[''] = '';
+9 -13
View File
@@ -18,8 +18,8 @@ $lang->bug->productplan = '所属计划';
$lang->bug->module = '所属模块';
$lang->bug->moduleAB = '模块';
$lang->bug->project = '所属' . $lang->projectCommon;
$lang->bug->story = '相关需求';
$lang->bug->storyVersion = '需求版本';
$lang->bug->story = "相关{$lang->storyCommon}";
$lang->bug->storyVersion = "{$lang->storyCommon}版本";
$lang->bug->color = '标题颜色';
$lang->bug->task = '相关任务';
$lang->bug->title = 'Bug标题';
@@ -39,7 +39,7 @@ $lang->bug->activatedDate = '激活日期';
$lang->bug->confirmed = '是否确认';
$lang->bug->confirmedAB = '确认';
$lang->bug->toTask = '转任务';
$lang->bug->toStory = '转需求';
$lang->bug->toStory = "转{$lang->storyCommon}";
$lang->bug->mailto = '抄送给';
$lang->bug->openedBy = '由谁创建';
$lang->bug->openedByAB = '创建者';
@@ -110,7 +110,7 @@ $lang->bug->exportAction = '导出Bug';
$lang->bug->delete = '删除';
$lang->bug->deleteAction = '删除Bug';
$lang->bug->deleted = '已删除';
$lang->bug->confirmStoryChange = '确认需求变动';
$lang->bug->confirmStoryChange = "确认{$lang->storyCommon}变动";
$lang->bug->copy = '复制Bug';
$lang->bug->search = '搜索';
@@ -129,7 +129,7 @@ $lang->bug->postponedBugs = '被延期';
$lang->bug->overdueBugs = '过期Bug';
$lang->bug->allBugs = '所有';
$lang->bug->byQuery = '搜索';
$lang->bug->needConfirm = '需求变动';
$lang->bug->needConfirm = "{$lang->storyCommon}变动";
$lang->bug->allProduct = '所有' . $lang->productCommon;
$lang->bug->my = '我的';
$lang->bug->yesterdayResolved = '昨天解决Bug数';
@@ -159,7 +159,7 @@ $lang->bug->createBuild = '新建';
/* legend列表。*/
$lang->bug->legendBasicInfo = '基本信息';
$lang->bug->legendAttatch = '附件';
$lang->bug->legendPrjStoryTask = $lang->projectCommon . '/需求/任务';
$lang->bug->legendPrjStoryTask = $lang->projectCommon . "/{$lang->storyCommon}/任务";
$lang->bug->lblTypeAndSeverity = '类型/严重程度';
$lang->bug->lblSystemBrowserAndHardware = '系统/浏览器';
$lang->bug->legendSteps = '重现步骤';
@@ -173,7 +173,7 @@ $lang->bug->buttonConfirm = '确认';
/* 交互提示。*/
$lang->bug->summary = "本页共 <strong>%s</strong> 个Bug,未解决 <strong>%s</strong>。";
$lang->bug->confirmChangeProduct = "修改{$lang->productCommon}会导致相应的{$lang->projectCommon}、需求和任务发生变化,确定吗?";
$lang->bug->confirmChangeProduct = "修改{$lang->productCommon}会导致相应的{$lang->projectCommon}、{$lang->storyCommon}和任务发生变化,确定吗?";
$lang->bug->confirmDelete = '您确认要删除该Bug吗?';
$lang->bug->remindTask = '该Bug已经转化为任务,是否更新任务(编号:%s)状态 ?';
$lang->bug->skipClose = 'Bug %s 不是已解决状态,不能关闭。';
@@ -243,17 +243,13 @@ $lang->bug->browserList['other'] = '其他';
$lang->bug->typeList[''] = '';
$lang->bug->typeList['codeerror'] = '代码错误';
$lang->bug->typeList['interface'] = '界面优化';
$lang->bug->typeList['config'] = '配置相关';
$lang->bug->typeList['install'] = '安装部署';
$lang->bug->typeList['security'] = '安全相关';
$lang->bug->typeList['performance'] = '性能问题';
$lang->bug->typeList['standard'] = '标准规范';
$lang->bug->typeList['automation'] = '测试脚本';
$lang->bug->typeList['designchange'] = '设计变更';
$lang->bug->typeList['newfeature'] = '新增需求';
$lang->bug->typeList['designdefect'] = '设计缺陷';
$lang->bug->typeList['trackthings'] = '事务跟踪';
$lang->bug->typeList['others'] = '其他';
$lang->bug->statusList[''] = '';
@@ -272,7 +268,7 @@ $lang->bug->resolutionList['fixed'] = '已解决';
$lang->bug->resolutionList['notrepro'] = '无法重现';
$lang->bug->resolutionList['postponed'] = '延期处理';
$lang->bug->resolutionList['willnotfix'] = "不予解决";
$lang->bug->resolutionList['tostory'] = '转为需求';
$lang->bug->resolutionList['tostory'] = "转为{$lang->storyCommon}";
/* 统计报表。*/
$lang->bug->report = new stdclass();
@@ -373,7 +369,7 @@ $lang->bug->report->bugHistories->graph->xAxisName = '处理步骤';
/* 操作记录。*/
$lang->bug->action = new stdclass();
$lang->bug->action->resolved = array('main' => '$date, 由 <strong>$actor</strong> 解决,方案为 <strong>$extra</strong> $appendLink。', 'extra' => 'resolutionList');
$lang->bug->action->tostory = array('main' => '$date, 由 <strong>$actor</strong> 转为<strong>需求</strong>,编号为 <strong>$extra</strong>。');
$lang->bug->action->tostory = array('main' => '$date, 由 <strong>$actor</strong> 转为<strong>{$lang->storyCommon}</strong>,编号为 <strong>$extra</strong>。');
$lang->bug->action->totask = array('main' => '$date, 由 <strong>$actor</strong> 导入为<strong>任务</strong>,编号为 <strong>$extra</strong>。');
$lang->bug->action->linked2plan = array('main' => '$date, 由 <strong>$actor</strong> 关联到计划 <strong>$extra</strong>。');
$lang->bug->action->unlinkedfromplan = array('main' => '$date, 由 <strong>$actor</strong> 从计划 <strong>$extra</strong> 移除。');
+10 -3
View File
@@ -792,6 +792,7 @@ class bugModel extends model
$activateBugs[$bugID]['openedBuild'] = $data->openedBuildList[$bugID];
$activateBugs[$bugID]['comment'] = $data->commentList[$bugID];
$activateBugs[$bugID]['activatedDate'] = $now;
$activateBugs[$bugID]['assignedDate'] = $now;
$activateBugs[$bugID]['resolution'] = '';
$activateBugs[$bugID]['status'] = 'active';
@@ -911,10 +912,16 @@ class bugModel extends model
*/
public function resolve($bugID)
{
if(strpos($this->config->bug->resolve->requiredFields, 'comment') !== false and !$this->post->comment)
/* Check required fields before create build. */
$requiredFields = explode(',', trim($this->config->bug->resolve->requiredFields, ','));
foreach($requiredFields as $requiredField)
{
dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->comment);
return false;
if(!$this->post->$requiredField)
{
$tip = $requiredField == 'comment' ? $this->lang->comment : $this->lang->bug->$requiredField;
dao::$errors[] = sprintf($this->lang->error->notempty, $tip);
return false;
}
}
$now = helper::now();
-6
View File
@@ -64,12 +64,6 @@
</thead>
<tbody>
<?php
/* Remove the unused types. */
unset($lang->bug->typeList['interface']);
unset($lang->bug->typeList['designchange']);
unset($lang->bug->typeList['newfeature']);
unset($lang->bug->typeList['trackthings']);
$moduleOptionMenu += array('ditto' => $lang->bug->ditto);
$projects += array('ditto' => $lang->bug->ditto);
$lang->bug->typeList += array('ditto' => $lang->bug->ditto);
-8
View File
@@ -83,14 +83,6 @@
$branches = array('ditto' => $this->lang->story->ditto) + $branches;
}
}
/**
* Remove designchange, newfeature, trackings from the typeList, because should be tracked in story or task.
* These thress types if upgrade from bugfree2.x.
*/
if($bug->type != 'interface') unset($typeList['interface']);
if($bug->type != 'designchange') unset($typeList['designchange']);
if($bug->type != 'newfeature') unset($typeList['newfeature']);
if($bug->type != 'trackthings') unset($typeList['trackthings']);
?>
<tr>
<td><?php echo $bugID . html::hidden("bugIDList[$bugID]", $bugID);?></td>
+2 -16
View File
@@ -69,14 +69,7 @@ js::set('flow', $config->global->flow);
<?php $showBrowser = strpos(",$showFields,", ',browser,') !== false;?>
<td>
<div class='input-group' id='bugTypeInputGroup'>
<?php
/* Remove the unused types. */
unset($lang->bug->typeList['interface']);
unset($lang->bug->typeList['designchange']);
unset($lang->bug->typeList['newfeature']);
unset($lang->bug->typeList['trackthings']);
echo html::select('type', $lang->bug->typeList, $type, "class='form-control'");
?>
<?php echo html::select('type', $lang->bug->typeList, $type, "class='form-control'");?>
<?php if($showOS):?>
<span class='input-group-addon fix-border'><?php echo $lang->bug->os?></span>
<?php echo html::select('os', $lang->bug->osList, $os, "class='form-control'");?>
@@ -126,14 +119,7 @@ js::set('flow', $config->global->flow);
<td>
<div class='table-row'>
<div class='table-col' id='typeBox'>
<?php
/* Remove the unused types. */
unset($lang->bug->typeList['interface']);
unset($lang->bug->typeList['designchange']);
unset($lang->bug->typeList['newfeature']);
unset($lang->bug->typeList['trackthings']);
echo html::select('type', $lang->bug->typeList, $type, "class='form-control chosen'");
?>
<?php echo html::select('type', $lang->bug->typeList, $type, "class='form-control chosen'");?>
</div>
<?php if($showOS):?>
<div class='table-col' id='osBox'>
+1 -13
View File
@@ -122,19 +122,7 @@ js::set('oldResolvedBuild' , $bug->resolvedBuild);
<?php endif;?>
<tr>
<th><?php echo $lang->bug->type;?></th>
<td>
<?php
/**
* Remove designchange, newfeature, trackings from the typeList, because should be tracked in story or task.
* These thress types if upgrade from bugfree2.x.
*/
if($bug->type != 'interface') unset($lang->bug->typeList['interface']);
if($bug->type != 'designchange') unset($lang->bug->typeList['designchange']);
if($bug->type != 'newfeature') unset($lang->bug->typeList['newfeature']);
if($bug->type != 'trackthings') unset($lang->bug->typeList['trackthings']);
echo html::select('type', $lang->bug->typeList, $bug->type, "class='form-control chosen'");
?>
</td>
<td><?php echo html::select('type', $lang->bug->typeList, $bug->type, "class='form-control chosen'"); ?></td>
</tr>
<tr>
<th><?php echo $lang->bug->severity;?></th>
+1 -1
View File
@@ -346,7 +346,7 @@ class build extends control
$params = ($type == 'all') ? 'noempty' : 'noempty, noterminate, nodone';
$builds = $this->build->getProjectBuildPairs($projectID, $productID, $branch, $params, $build);
if($isJsonView) die(json_encode($builds));
else die(html::select($varName . '[]', $builds , $build, 'size=4 class=form-control multiple'));
else die(html::select($varName . '[]', $builds , '', 'size=4 class=form-control multiple'));
}
if($varName == 'openedBuilds')
{
+6 -6
View File
@@ -12,17 +12,17 @@
$lang->build->common = "版本";
$lang->build->create = "创建版本";
$lang->build->edit = "编辑版本";
$lang->build->linkStory = "关联需求";
$lang->build->linkStory = "关联{$lang->storyCommon}";
$lang->build->linkBug = "关联Bug";
$lang->build->delete = "删除版本";
$lang->build->deleted = "已删除";
$lang->build->view = "版本详情";
$lang->build->batchUnlink = '批量移除';
$lang->build->batchUnlinkStory = '批量移除需求';
$lang->build->batchUnlinkStory = "批量移除{$lang->storyCommon}";
$lang->build->batchUnlinkBug = '批量移除Bug';
$lang->build->confirmDelete = "您确认删除该版本吗?";
$lang->build->confirmUnlinkStory = "您确认移除该需求吗?";
$lang->build->confirmUnlinkStory = "您确认移除该{$lang->storyCommon}吗?";
$lang->build->confirmUnlinkBug = "您确认移除该Bug吗?";
$lang->build->basicInfo = '基本信息';
@@ -40,15 +40,15 @@ $lang->build->desc = '描述';
$lang->build->files = '上传发行包';
$lang->build->last = '上个版本';
$lang->build->packageType = '包类型';
$lang->build->unlinkStory = '移除需求';
$lang->build->unlinkStory = "移除{$lang->storyCommon}";
$lang->build->unlinkBug = '移除Bug';
$lang->build->stories = '完成的需求';
$lang->build->stories = "完成的{$lang->storyCommon}";
$lang->build->bugs = '解决的Bug';
$lang->build->generatedBugs = '产生的Bug';
$lang->build->noProduct = " <span style='color:red'>该{$lang->projectCommon}没有关联{$lang->productCommon},无法创建版本,请先<a href='%s'>关联{$lang->productCommon}</a></span>";
$lang->build->noBuild = '暂时没有版本。';
$lang->build->finishStories = ' 本次共完成 %s 个需求';
$lang->build->finishStories = " 本次共完成 %s 个{$lang->storyCommon}";
$lang->build->resolvedBugs = ' 本次共解决 %s 个Bug';
$lang->build->createdBugs = ' 本次共产生 %s 个Bug';
+1
View File
@@ -1,4 +1,5 @@
.w-220px{width:220px}
#caseList tr th, #caseList tr td {white-space:nowrap; text-overflow:ellipsis; overflow: hidden;}
#createActionMenu .dropdown-menu {width: 100%;}
+3 -9
View File
@@ -375,8 +375,8 @@ $lang->admin->menu->message = array('link' => 'Notification|message|index', 's
$lang->admin->menu->custom = array('link' => 'Custom|custom|set', 'subModule' => 'custom');
$lang->admin->menu->sso = array('link' => 'Integration|admin|sso');
$lang->admin->menu->dev = array('link' => 'Entwicklung|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor,entry');
$lang->admin->menu->translate = array('link' => 'Translate|translate|index', 'subModule' => 'translate');
$lang->admin->menu->dev = array('link' => 'Entwicklung|dev|api', 'alias' => 'db', 'subModule' => 'dev,entry');
$lang->admin->menu->translate = array('link' => 'Translate|dev|translate');
$lang->admin->menu->data = array('link' => 'Data|backup|index', 'subModule' => 'backup,action');
$lang->admin->menu->safe = array('link' => 'Sicherheit|admin|safe', 'alias' => 'checkweak');
$lang->admin->menu->system = array('link' => 'System|cron|index', 'subModule' => 'cron');
@@ -394,7 +394,7 @@ $lang->admin->subMenu->sso->ranzhi = 'Zdoo|admin|sso';
$lang->admin->subMenu->dev = new stdclass();
$lang->admin->subMenu->dev->api = array('link' => 'API|dev|api');
$lang->admin->subMenu->dev->db = array('link' => 'Database|dev|db');
$lang->admin->subMenu->dev->editor = array('link' => 'Editor|editor|index', 'subModule' => 'editor');
$lang->admin->subMenu->dev->editor = array('link' => 'Editor|dev|editor');
$lang->admin->subMenu->dev->entry = array('link' => 'Application|entry|browse', 'subModule' => 'entry');
$lang->admin->subMenu->data = new stdclass();
@@ -418,8 +418,6 @@ $lang->entry = new stdclass();
$lang->webhook = new stdclass();
$lang->message = new stdclass();
$lang->search = new stdclass();
$lang->translate = new stdclass();
$lang->editor = new stdclass();
$lang->convert->menu = $lang->admin->menu;
$lang->upgrade->menu = $lang->admin->menu;
@@ -433,8 +431,6 @@ $lang->dev->menu = $lang->admin->menu;
$lang->entry->menu = $lang->admin->menu;
$lang->webhook->menu = $lang->admin->menu;
$lang->message->menu = $lang->admin->menu;
$lang->translate->menu = $lang->admin->menu;
$lang->editor->menu = $lang->admin->menu;
/* 菜单分组。*/
$lang->menugroup = new stdclass();
@@ -470,8 +466,6 @@ $lang->menugroup->dev = 'admin';
$lang->menugroup->entry = 'admin';
$lang->menugroup->webhook = 'admin';
$lang->menugroup->message = 'admin';
$lang->menugroup->translate = 'admin';
$lang->menugroup->editor = 'admin';
/* 错误提示信息。*/
$lang->error = new stdclass();
+3 -9
View File
@@ -375,8 +375,8 @@ $lang->admin->menu->message = array('link' => 'Notification|message|index', 's
$lang->admin->menu->custom = array('link' => 'Custom|custom|set', 'subModule' => 'custom');
$lang->admin->menu->sso = array('link' => 'Integration|admin|sso');
$lang->admin->menu->dev = array('link' => 'Develop|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor,entry');
$lang->admin->menu->translate = array('link' => 'Translate|translate|index', 'subModule' => 'translate');
$lang->admin->menu->dev = array('link' => 'Develop|dev|api', 'alias' => 'db', 'subModule' => 'dev,entry');
$lang->admin->menu->translate = array('link' => 'Translate|dev|translate');
$lang->admin->menu->data = array('link' => 'Data|backup|index', 'subModule' => 'backup,action');
$lang->admin->menu->safe = array('link' => 'Security|admin|safe', 'alias' => 'checkweak');
$lang->admin->menu->system = array('link' => 'System|cron|index', 'subModule' => 'cron');
@@ -394,7 +394,7 @@ $lang->admin->subMenu->sso->ranzhi = 'Zdoo|admin|sso';
$lang->admin->subMenu->dev = new stdclass();
$lang->admin->subMenu->dev->api = array('link' => 'API|dev|api');
$lang->admin->subMenu->dev->db = array('link' => 'Database|dev|db');
$lang->admin->subMenu->dev->editor = array('link' => 'Editor|editor|index', 'subModule' => 'editor');
$lang->admin->subMenu->dev->editor = array('link' => 'Editor|dev|editor');
$lang->admin->subMenu->dev->entry = array('link' => 'Application|entry|browse', 'subModule' => 'entry');
$lang->admin->subMenu->data = new stdclass();
@@ -418,8 +418,6 @@ $lang->entry = new stdclass();
$lang->webhook = new stdclass();
$lang->message = new stdclass();
$lang->search = new stdclass();
$lang->translate = new stdclass();
$lang->editor = new stdclass();
$lang->convert->menu = $lang->admin->menu;
$lang->upgrade->menu = $lang->admin->menu;
@@ -433,8 +431,6 @@ $lang->dev->menu = $lang->admin->menu;
$lang->entry->menu = $lang->admin->menu;
$lang->webhook->menu = $lang->admin->menu;
$lang->message->menu = $lang->admin->menu;
$lang->translate->menu = $lang->admin->menu;
$lang->editor->menu = $lang->admin->menu;
/* Menu group. */
$lang->menugroup = new stdclass();
@@ -470,8 +466,6 @@ $lang->menugroup->dev = 'admin';
$lang->menugroup->entry = 'admin';
$lang->menugroup->webhook = 'admin';
$lang->menugroup->message = 'admin';
$lang->menugroup->translate = 'admin';
$lang->menugroup->editor = 'admin';
/* Error info. */
$lang->error = new stdclass();
+3 -9
View File
@@ -375,8 +375,8 @@ $lang->admin->menu->message = array('link' => 'Notification|message|index', 's
$lang->admin->menu->custom = array('link' => 'Personnalisation|custom|set', 'subModule' => 'custom');
$lang->admin->menu->sso = array('link' => 'Intégration|admin|sso');
$lang->admin->menu->dev = array('link' => 'Dévelop.|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor,entry');
$lang->admin->menu->translate = array('link' => 'Traduire|translate|index', 'subModule' => 'translate');
$lang->admin->menu->dev = array('link' => 'Dévelop.|dev|api', 'alias' => 'db', 'subModule' => 'dev,entry');
$lang->admin->menu->translate = array('link' => 'Traduire|dev|translate');
$lang->admin->menu->data = array('link' => 'Données|backup|index', 'subModule' => 'backup,action');
$lang->admin->menu->safe = array('link' => 'Sécurité|admin|safe', 'alias' => 'checkweak');
$lang->admin->menu->system = array('link' => 'Système|cron|index', 'subModule' => 'cron');
@@ -394,7 +394,7 @@ $lang->admin->subMenu->sso->ranzhi = 'Zdoo|admin|sso';
$lang->admin->subMenu->dev = new stdclass();
$lang->admin->subMenu->dev->api = array('link' => 'API|dev|api');
$lang->admin->subMenu->dev->db = array('link' => 'Database|dev|db');
$lang->admin->subMenu->dev->editor = array('link' => 'Editor|editor|index', 'subModule' => 'editor');
$lang->admin->subMenu->dev->editor = array('link' => 'Editor|dev|editor');
$lang->admin->subMenu->dev->entry = array('link' => 'Application|entry|browse', 'subModule' => 'entry');
$lang->admin->subMenu->data = new stdclass();
@@ -418,8 +418,6 @@ $lang->entry = new stdclass();
$lang->webhook = new stdclass();
$lang->message = new stdclass();
$lang->search = new stdclass();
$lang->translate = new stdclass();
$lang->editor = new stdclass();
$lang->convert->menu = $lang->admin->menu;
$lang->upgrade->menu = $lang->admin->menu;
@@ -433,8 +431,6 @@ $lang->dev->menu = $lang->admin->menu;
$lang->entry->menu = $lang->admin->menu;
$lang->webhook->menu = $lang->admin->menu;
$lang->message->menu = $lang->admin->menu;
$lang->translate->menu = $lang->admin->menu;
$lang->editor->menu = $lang->admin->menu;
/* Menu group. */
$lang->menugroup = new stdclass();
@@ -470,8 +466,6 @@ $lang->menugroup->dev = 'admin';
$lang->menugroup->entry = 'admin';
$lang->menugroup->webhook = 'admin';
$lang->menugroup->message = 'admin';
$lang->menugroup->translate = 'admin';
$lang->menugroup->editor = 'admin';
/* Error info. */
$lang->error = new stdclass();
+8 -14
View File
@@ -131,7 +131,7 @@ $lang->dividerMenu = ',qa,report,';
/* 查询条中可以选择的对象列表。*/
$lang->searchObjects['bug'] = 'Bug';
$lang->searchObjects['story'] = '需求';
$lang->searchObjects['story'] = "{$lang->storyCommon}";
$lang->searchObjects['task'] = '任务';
$lang->searchObjects['testcase'] = '用例';
$lang->searchObjects['project'] = $lang->projectCommon;
@@ -188,7 +188,7 @@ $lang->my->menu->calendar = array('link' => '日程|my|calendar|', 'subMod
$lang->my->menu->task = array('link' => '任务|my|task|', 'subModule' => 'task');
$lang->my->menu->bug = array('link' => 'Bug|my|bug|', 'subModule' => 'bug');
$lang->my->menu->testtask = array('link' => '测试|my|testtask|', 'subModule' => 'testcase,testtask', 'alias' => 'testcase');
$lang->my->menu->story = array('link' => '需求|my|story|', 'subModule' => 'story');
$lang->my->menu->story = array('link' => "{$lang->storyCommon}|my|story|", 'subModule' => 'story');
$lang->my->menu->myProject = "{$lang->projectCommon}|my|project|";
$lang->my->menu->dynamic = '动态|my|dynamic|';
$lang->my->menu->profile = array('link' => '档案|my|profile', 'alias' => 'editprofile');
@@ -208,7 +208,7 @@ $lang->score->menu = $lang->my->menu;
$lang->product = new stdclass();
$lang->product->menu = new stdclass();
$lang->product->menu->story = array('link' => '需求|product|browse|productID=%s', 'alias' => 'batchedit', 'subModule' => 'story');
$lang->product->menu->story = array('link' => "{$lang->storyCommon}|product|browse|productID=%s", 'alias' => 'batchedit', 'subModule' => 'story');
$lang->product->menu->plan = array('link' => '计划|productplan|browse|productID=%s', 'subModule' => 'productplan');
$lang->product->menu->release = array('link' => '发布|release|browse|productID=%s', 'subModule' => 'release');
$lang->product->menu->roadmap = '路线图|product|roadmap|productID=%s';
@@ -239,7 +239,7 @@ $lang->project->menu->task = array('link' => '任务|project|task|projectID=%
$lang->project->menu->kanban = array('link' => '看板|project|kanban|projectID=%s');
$lang->project->menu->burn = array('link' => '燃尽图|project|burn|projectID=%s');
$lang->project->menu->list = array('link' => '更多|project|grouptask|projectID=%s', 'alias' => 'grouptask,tree', 'class' => 'dropdown dropdown-hover');
$lang->project->menu->story = array('link' => '需求|project|story|projectID=%s', 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
$lang->project->menu->story = array('link' => "{$lang->storyCommon}|project|story|projectID=%s", 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
$lang->project->menu->qa = array('link' => '测试|project|bug|projectID=%s', 'subModule' => 'bug,build,testtask', 'alias' => 'build,testtask', 'class' => 'dropdown dropdown-hover');
$lang->project->menu->doc = array('link' => '文档|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
$lang->project->menu->action = array('link' => '动态|project|dynamic|projectID=%s', 'subModule' => 'dynamic', 'class' => 'dropdown dropdown-hover');
@@ -375,8 +375,8 @@ $lang->admin->menu->message = array('link' => '通知|message|index', 'subModu
$lang->admin->menu->custom = array('link' => '自定义|custom|set', 'subModule' => 'custom');
$lang->admin->menu->sso = array('link' => '集成|admin|sso');
$lang->admin->menu->extension = array('link' => '插件|extension|browse', 'subModule' => 'extension');
$lang->admin->menu->dev = array('link' => '二次开发|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor,entry');
$lang->admin->menu->translate = array('link' => '翻译|translate|index', 'subModule' => 'translate');
$lang->admin->menu->dev = array('link' => '二次开发|dev|api', 'alias' => 'db', 'subModule' => 'dev,entry');
$lang->admin->menu->translate = array('link' => '翻译|dev|translate');
$lang->admin->menu->data = array('link' => '数据|backup|index', 'subModule' => 'backup,action');
$lang->admin->menu->safe = array('link' => '安全|admin|safe', 'alias' => 'checkweak');
$lang->admin->menu->system = array('link' => '系统|cron|index', 'subModule' => 'cron');
@@ -394,7 +394,7 @@ $lang->admin->subMenu->sso->ranzhi = '然之协同|admin|sso';
$lang->admin->subMenu->dev = new stdclass();
$lang->admin->subMenu->dev->api = array('link' => 'API|dev|api');
$lang->admin->subMenu->dev->db = array('link' => '数据库|dev|db');
$lang->admin->subMenu->dev->editor = array('link' => '编辑器|editor|index', 'subModule' => 'editor');
$lang->admin->subMenu->dev->editor = array('link' => '编辑器|dev|editor');
$lang->admin->subMenu->dev->entry = array('link' => '应用|entry|browse', 'subModule' => 'entry');
$lang->admin->subMenu->data = new stdclass();
@@ -418,8 +418,6 @@ $lang->entry = new stdclass();
$lang->webhook = new stdclass();
$lang->message = new stdclass();
$lang->search = new stdclass();
$lang->translate = new stdclass();
$lang->editor = new stdclass();
$lang->convert->menu = $lang->admin->menu;
$lang->upgrade->menu = $lang->admin->menu;
@@ -433,8 +431,6 @@ $lang->dev->menu = $lang->admin->menu;
$lang->entry->menu = $lang->admin->menu;
$lang->webhook->menu = $lang->admin->menu;
$lang->message->menu = $lang->admin->menu;
$lang->translate->menu = $lang->admin->menu;
$lang->editor->menu = $lang->admin->menu;
/* 菜单分组。*/
$lang->menugroup = new stdclass();
@@ -470,8 +466,6 @@ $lang->menugroup->dev = 'admin';
$lang->menugroup->entry = 'admin';
$lang->menugroup->webhook = 'admin';
$lang->menugroup->message = 'admin';
$lang->menugroup->translate = 'admin';
$lang->menugroup->editor = 'admin';
/* 错误提示信息。*/
$lang->error = new stdclass();
@@ -788,7 +782,7 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTest')
$lang->bug->subMenu->more->longlifebugs = '久未处理|bug|browse|productID=%s&branch=%s&browseType=longlifebugs&param=%s';
$lang->bug->subMenu->more->postponedbugs = '被延期|bug|browse|productID=%s&branch=%s&browseType=postponedbugs&param=%s';
$lang->bug->subMenu->more->overduebugs = '过期Bug|bug|browse|productID=%s&branch=%s&browseType=overduebugs&param=%s';
$lang->bug->subMenu->more->needconfirm = '需求变动|bug|browse|productID=%s&branch=%s&browseType=needconfirm&param=%s';
$lang->bug->subMenu->more->needconfirm = "{$lang->storyCommon}变动|bug|browse|productID=%s&branch=%s&browseType=needconfirm&param=%s";
$lang->bug->menuOrder[5] = 'product';
$lang->bug->menuOrder[10] = 'all';
+4 -4
View File
@@ -28,9 +28,9 @@ class commonModel extends model
$this->setUser();
$this->loadConfigFromDB();
$this->app->setTimezone();
if((strpos($this->config->global->version, 'pro') !== false && version_compare($this->config->global->version, 'pro2.3.beta', '>'))
|| (strpos($this->config->global->version, 'biz') !== false)
|| version_compare($this->config->global->version, '4.3.beta', '>'))
if((strpos($this->config->version, 'pro') !== false && version_compare($this->config->version, 'pro2.3.beta', '>'))
|| (strpos($this->config->version, 'biz') !== false)
|| version_compare($this->config->version, '4.3.beta', '>'))
{
$this->loadCustomFromDB();
}
@@ -254,7 +254,7 @@ class commonModel extends model
if(!$isGuest)
{
echo '<li class="user-profile-item">';
echo "<a href='". helper::createLink('my', 'profile') . (!empty($app->user->role) && isset($lang->user->roleList[$app->user->role]) ? '' : ' no-role') . "'>";
echo "<a href='" . helper::createLink('my', 'profile') . "'" . "class='" . (!empty($app->user->role) && isset($lang->user->roleList[$app->user->role]) ? '' : ' no-role') . "'>";
echo "<div class='avatar avatar bg-secondary avatar-circle'>" . strtoupper($app->user->account{0}) . "</div>\n";
echo '<div class="user-profile-name">' . (empty($app->user->realname) ? $app->user->account : $app->user->realname) . '</div>';
if(isset($lang->user->roleList[$app->user->role])) echo '<div class="user-profile-role">' . $lang->user->roleList[$app->user->role] . '</div>';
+2 -2
View File
@@ -47,7 +47,7 @@
<ol class='histories-list'>
<?php $i = 1; ?>
<?php foreach($actions as $action):?>
<?php $canEditComment = (end($actions) == $action and $action->comment and $this->methodName == 'view' and $action->actor == $this->app->user->account and common::hasPriv('action', 'editComment'));?>
<?php $canEditComment = (end($actions) == $action and strlen(trim(($action->comment))) != 0 and $this->methodName == 'view' and $action->actor == $this->app->user->account and common::hasPriv('action', 'editComment'));?>
<li value='<?php echo $i ++;?>'>
<?php
$action->actor = zget($users, $action->actor);
@@ -61,7 +61,7 @@
<?php echo $this->action->printChanges($action->objectType, $action->history);?>
</div>
<?php endif;?>
<?php if(!empty($action->comment)):?>
<?php if(strlen(trim(($action->comment))) != 0):?>
<?php if($canEditComment):?>
<?php echo html::commonButton('<i class="icon icon-pencil"></i>', "title='{$lang->action->editComment}'", 'btn btn-link btn-icon btn-sm btn-edit-comment');?>
<style>.comment .comment-content{width: 98%}</style>
+1 -1
View File
@@ -5,7 +5,7 @@ $method = $this->methodName;
if(!isset($config->$module->editor->$method)) return;
$editor = $config->$module->editor->$method;
$editor['id'] = explode(',', $editor['id']);
$editorLangs = array('en' => 'en', 'zh-cn' => 'zh_CN', 'zh-tw' => 'zh_TW');
$editorLangs = array('en' => 'en', 'zh-cn' => 'zh_CN', 'zh-tw' => 'zh_TW', 'ja' => 'ja');
$editorLang = isset($editorLangs[$app->getClientLang()]) ? $editorLangs[$app->getClientLang()] : 'en';
/* set uid for upload. */
-63
View File
@@ -1,63 +0,0 @@
<?php if($extView = $this->getExtViewFile(__FILE__)){include $extView; return helper::cd();}?>
<?php
$module = $this->moduleName;
$method = $this->methodName;
js::set('themeRoot', $themeRoot);
if(!isset($config->$module->editor->$method)) return;
$editor = $config->$module->editor->$method;
$editor['id'] = explode(',', $editor['id']);
$editorLangs = array('en' => 'en', 'zh-cn' => 'zh-cn', 'zh-tw' => 'zh-tw');
$editorLang = isset($editorLangs[$app->getClientLang()]) ? $editorLangs[$app->getClientLang()] : 'en';
/* set uid for upload. */
$uid = uniqid('');
js::set('kuid', $uid);
?>
<script charset="utf-8" src="<?php echo $this->app->getWebRoot() . "js/"?>ueditor/ueditor.config.js"></script>
<script charset="utf-8" src="<?php echo $this->app->getWebRoot() . "js/"?>ueditor/ueditor.all.min.js"> </script>
<script>
var editor = <?php echo json_encode($editor);?>;
var toolbars = [[
'paragraph', 'fontfamily', 'fontsize', '|',
'forecolor', 'backcolor', 'bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'blockquote', 'pasteplain', '|',
'insertorderedlist', 'insertunorderedlist', 'justifyleft', 'justifycenter', 'justifyright', '|',
'simpleupload', 'insertcode', '|',
'link', 'unlink', '|',
'inserttable', '|',
'fullscreen', 'source', '|',
'preview', 'help'
]];
$(document).ready(initUeditor);
function initUeditor(afterInit)
{
$(':input[type=submit]').after("<input type='hidden' id='uid' name='uid' value=" + kuid + ">");
var options =
{
lang: '<?php echo $editorLang?>',
toolbars: toolbars,
serverUrl: '<?php echo $this->createLink('file', 'ajaxUeditorUpload', "uid=$uid")?>',
autoClearinitialContent:false,
wordCount:false,
<?php if($editorLang != 'zh-cn' and $editorLang != 'zh-tw') echo "iframeCssUrl:'',"; //When lang is zh-cn or zh-tw then load ueditor/themes/iframe.css file for font-family and size of editor.?>
enableAutoSave:false,
elementPathEnabled:false
};
$.each(editor.id, function(key, editorID)
{
if(!window.editor) window.editor = {};
if($('#' + editorID).size() != 0)
{
ueditor = UE.getEditor(editorID, options);
window.editor['#'] = window.editor[editorID] = ueditor;
ueditor.addListener('ready', function()
{
$('#' + editorID).find('.edui-editor').css('z-index', '5');
});
}
});
if($.isFunction(afterInit)) afterInit();
}
</script>
+1 -1
View File
@@ -16,4 +16,4 @@
.dynamic.active .dynamic-date:before {background-color: #00a9fc;}
.dynamic.collapsed .timeline {max-height: 58px;}
.dynamic.collapsed .timeline > li + li {display: none;}
.dynamic.collapsed .dynamic-btn > .icon:before {content: '\f0d7'; }
.dynamic.collapsed .dynamic-btn > .icon:before {content: '\f0d8'; }
+3 -2
View File
@@ -46,7 +46,7 @@
<span class="date-label"><?php echo $lang->action->dynamic->today;?></span>
<?php endif;?>
<span class="date-text"><?php echo $date;?></span>
<button type="button" class="btn btn-info btn-icon btn-sm dynamic-btn"><i class="icon icon-caret-up"></i></button>
<button type="button" class="btn btn-info btn-icon btn-sm dynamic-btn"><i class="icon icon-caret-down"></i></button>
</div>
<ul class="timeline timeline-tag-left">
<?php if($direction == 'next') $actions = array_reverse($actions);?>
@@ -56,7 +56,8 @@
<div>
<span class="timeline-tag"><?php echo $action->time?></span>
<span class="timeline-text">
<?php echo zget($users, $action->actor) . ' ' . $action->actionLabel;?>
<?php echo zget($users, $action->actor);?>
<span class='label-action'><?php echo ' ' . $action->actionLabel;?></span>
<?php if($action->action != 'login' and $action->action != 'logout'):?>
<span class="text"><?php echo $action->objectLabel;?></span>
<?php echo html::a($action->objectLink, $action->objectName);?>
+2 -2
View File
@@ -35,7 +35,7 @@ $lang->convert->aimTypeOfZentao = '转化为Zentao中的类型';
$lang->convert->directionList['bug'] = 'Bug';
$lang->convert->directionList['task'] = '任务';
$lang->convert->directionList['story'] = '需求';
$lang->convert->directionList['story'] = $lang->storyCommon;
$lang->convert->sourceList['BugFree'] = array('bugfree_1' => '1.x', 'bugfree_2' => '2.x');
$lang->convert->sourceList['Redmine'] = array('Redmine_1.1' => '1.1');
@@ -79,7 +79,7 @@ $lang->convert->redmine->users = '用户';
$lang->convert->redmine->groups = '用户分组';
$lang->convert->redmine->products = $lang->productCommon;
$lang->convert->redmine->projects = $lang->projectCommon;
$lang->convert->redmine->stories = '需求';
$lang->convert->redmine->stories = $lang->storyCommon;
$lang->convert->redmine->tasks = '任务';
$lang->convert->redmine->bugs = 'Bug';
$lang->convert->redmine->productPlans = $lang->productCommon . '计划';
+26 -27
View File
@@ -41,13 +41,6 @@ class custom extends control
$this->app->loadLang($module);
$fieldList = zget($this->lang->$module, $field, '');
if($module == 'bug' and $field == 'typeList')
{
unset($fieldList['interface']);
unset($fieldList['designchange']);
unset($fieldList['newfeature']);
unset($fieldList['trackthings']);
}
if(($module == 'story' or $module == 'testcase') and $field == 'review')
{
$this->app->loadConfig($module);
@@ -131,7 +124,7 @@ class custom extends control
{
if(!is_numeric($key) or $key > 255) $this->send(array('result' => 'fail', 'message' => $this->lang->custom->notice->invalidNumberKey));
}
if(!empty($key) and !isset($oldCustoms[$key]) and $key != 'n/a' and !validater::checkREG($key, '/^[a-z_0-9]+$/')) $this->send(array('result' => 'fail', 'message' => $this->lang->custom->notice->invalidStringKey));
if(!empty($key) and !empty($oldCustoms) and !isset($oldCustoms[$key]) and $key != 'n/a' and !validater::checkREG($key, '/^[a-z_0-9]+$/')) $this->send(array('result' => 'fail', 'message' => $this->lang->custom->notice->invalidStringKey));
/* The length of roleList in user module and typeList in todo module is less than 10. check it when saved. */
if($field == 'roleList' or $module == 'todo' and $field == 'typeList')
@@ -235,25 +228,7 @@ class custom extends control
{
if($_POST)
{
$this->loadModel('setting')->setItem('system.custom.productProject', $this->post->productProject);
/* Change block title. */
$oldConfig = isset($this->config->custom->productProject) ? $this->config->custom->productProject : '0_0';
$newConfig = $this->post->productProject;
list($oldProductIndex, $oldProjectIndex) = explode('_', $oldConfig);
list($newProductIndex, $newProjectIndex) = explode('_', $newConfig);
foreach($this->config->productCommonList as $clientLang => $productCommonList)
{
$this->dao->update(TABLE_BLOCK)->set("`title` = REPLACE(`title`, '{$productCommonList[$oldProductIndex]}', '{$productCommonList[$newProductIndex]}')")->where('source')->eq('product')->exec();
}
foreach($this->config->projectCommonList as $clientLang => $projectCommonList)
{
$this->dao->update(TABLE_BLOCK)->set("`title` = REPLACE(`title`, '{$projectCommonList[$oldProjectIndex]}', '{$projectCommonList[$newProjectIndex]}')")->where('source')->eq('project')->exec();
}
$this->custom->setFlow();
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'reload'));
}
@@ -262,6 +237,30 @@ class custom extends control
$this->display();
}
/**
* Set concept.
*
* @access public
* @return void
*/
public function concept()
{
if($_POST)
{
$this->custom->setFlow();
$this->custom->setStoryRequirement();
$this->loadModel('setting')->setItem('system.custom.hourPoint', $this->post->hourPoint);
$this->loadModel('setting')->setItem('system.common.conceptSetted', 1);
$this->app->loadLang('common');
$message = sprintf($this->lang->custom->notice->conceptResult, $this->lang->productCommon, $this->lang->projectCommon, $this->lang->storyCommon, $this->lang->hourCommon);
$this->send(array('result' => 'success', 'notice' => $message, 'locate' => inlink('concept')));
}
$this->view->title = $this->lang->custom->concept;
$this->view->position[] = $this->lang->custom->concept;
$this->display();
}
public function working()
{
if($_POST)
+18
View File
@@ -0,0 +1,18 @@
$(document).ready(function()
{
$('#mainMenu #conceptTab').addClass('btn-active-text');
$('#ajaxForm').ajaxForm(
{
finish:function(response)
{
if(response.result == 'success')
{
bootbox.alert(response.notice, function()
{
location.reload();
});
}
return false;
}
});
});
+21 -3
View File
@@ -6,6 +6,7 @@ $lang->custom->restore = '恢复默认';
$lang->custom->key = '键';
$lang->custom->value = '值';
$lang->custom->flow = '流程';
$lang->custom->concept = '使用偏好设置';
$lang->custom->working = '工作方式';
$lang->custom->select = '请选择流程:';
$lang->custom->branch = '多分支';
@@ -20,7 +21,7 @@ $lang->custom->timezone = '时区';
$lang->custom->scoreReset = '重置积分';
$lang->custom->scoreTitle = '积分功能';
$lang->custom->object['story'] = '需求';
$lang->custom->object['story'] = $lang->storyCommon;
$lang->custom->object['task'] = '任务';
$lang->custom->object['bug'] = 'Bug';
$lang->custom->object['testcase'] = '用例';
@@ -78,7 +79,7 @@ $lang->custom->user->fields['statusList'] = '状态';
$lang->custom->user->fields['contactField'] = '可用联系方式';
$lang->custom->user->fields['deleted'] = '列出已删除用户';
$lang->custom->system = array('flow', 'working', 'required', 'score');
$lang->custom->system = array('concept', 'flow', 'working', 'required', 'score');
$lang->custom->block->fields['closed'] = '关闭的区块';
@@ -98,6 +99,7 @@ $lang->custom->notice->invalidStringKey = '键值应当为小写英
$lang->custom->notice->cannotSetTimezone = 'date_default_timezone_set方法不存在或禁用,不能设置时区。';
$lang->custom->notice->noClosedBlock = '没有永久关闭的区块';
$lang->custom->notice->required = '页面提交时,选中的字段必填';
$lang->custom->notice->conceptResult = '我们已经根据您的选择为您设置了<b> %s-%s </b>模式,使用<b>%s</b> + <b> %s</b>。';
$lang->custom->notice->indexPage['product'] = "从8.2版本起增加了产品主页视图,是否默认进入产品主页?";
$lang->custom->notice->indexPage['project'] = "从8.2版本起增加了项目主页视图,是否默认进入项目主页?";
@@ -126,12 +128,14 @@ $lang->custom->productProject = new stdclass();
$lang->custom->productProject->relation['0_0'] = '产品 - 项目';
$lang->custom->productProject->relation['0_1'] = '产品 - 迭代';
$lang->custom->productProject->relation['1_1'] = '项目 - 迭代';
$lang->custom->productProject->relation['0_2'] = '产品 - 冲刺';
$lang->custom->productProject->relation['1_2'] = '项目 - 冲刺';
$lang->custom->productProject->notice = '请根据实际情况选择适合自己团队的概念。';
$lang->custom->workingList['full'] = '完整研发管理工具';
$lang->custom->workingList['onlyTest'] = '测试管理工具';
$lang->custom->workingList['onlyStory'] = '需求管理工具';
$lang->custom->workingList['onlyStory'] = "{$lang->storyCommon}管理工具";
$lang->custom->workingList['onlyTask'] = '任务管理工具';
$lang->custom->menuTip = '点击显示或隐藏导航条目,拖拽来更改显示顺序。';
@@ -144,3 +148,17 @@ $lang->custom->scoreStatus[0] = '关闭';
$lang->custom->moduleName['product'] = $lang->productCommon;
$lang->custom->moduleName['productplan'] = '计划';
$lang->custom->moduleName['project'] = $lang->projectCommon;
$lang->custom->conceptQuestions['overview'] = "1. 下述哪种组合方式更适合您公司的管理现状?";
$lang->custom->conceptQuestions['story'] = "2. 您公司是在使用需求概念还是用户故事概念?";
$lang->custom->conceptQuestions['storypoint'] = "3. 您公司是在使用工时还是故事点来做规模估算?";
$lang->custom->conceptOptions = new stdclass;
$lang->custom->conceptOptions->story = array();
$lang->custom->conceptOptions->story['0'] = '需求';
$lang->custom->conceptOptions->story['1'] = '故事';
$lang->custom->conceptOptions->hourPoint = array();
$lang->custom->conceptOptions->hourPoint['0'] = '工时';
$lang->custom->conceptOptions->hourPoint['1'] = '故事点';
+47
View File
@@ -490,4 +490,51 @@ class customModel extends model
$this->setting->deleteItems("owner=system&module={$moduleName}");
$this->setting->setItems("system.{$moduleName}", $requiredFields);
}
/**
* Set flow function.
*
* @param string $type productProject | storyRequirement
* @access public
* @return void
*/
public function setFlow()
{
$this->loadModel('setting')->setItem('system.custom.productProject', $this->post->productProject);
/* Change block title. */
$oldConfig = isset($this->config->custom->productProject) ? $this->config->custom->productProject : '0_0';
$newConfig = $this->post->productProject;
list($oldProductIndex, $oldProjectIndex) = explode('_', $oldConfig);
list($newProductIndex, $newProjectIndex) = explode('_', $newConfig);
foreach($this->config->productCommonList as $clientLang => $productCommonList)
{
$this->dao->update(TABLE_BLOCK)->set("`title` = REPLACE(`title`, '{$productCommonList[$oldProductIndex]}', '{$productCommonList[$newProductIndex]}')")->where('source')->eq('product')->exec();
}
foreach($this->config->projectCommonList as $clientLang => $projectCommonList)
{
$this->dao->update(TABLE_BLOCK)->set("`title` = REPLACE(`title`, '{$projectCommonList[$oldProjectIndex]}', '{$projectCommonList[$newProjectIndex]}')")->where('source')->eq('project')->exec();
}
}
public function setStoryRequirement()
{
$this->loadModel('setting')->setItem('system.custom.storyRequirement', $this->post->storyRequirement);
$oldIndex = isset($this->config->custom->storyRequirement) ? $this->config->custom->storyRequirement : '0';
$newIndex = $this->post->storyRequirement;
foreach($this->config->storyCommonList as $clientLang => $commonList)
{
$this->dao->update(TABLE_BLOCK)->set("`title` = REPLACE(`title`, '{$commonList[$oldIndex]}', '{$commonList[$newIndex]}')")->where('source')->eq('product')->exec();
}
}
public function setHourPoint()
{
$this->loadModel('setting')->setItem('system.custom.hourPoint', $this->post->hourPoint);
}
}
+60
View File
@@ -0,0 +1,60 @@
<?php
/**
* The html template file of deny method of user module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package ZenTaoPMS
* @version $Id: deny.html.php 4129 2013-01-18 01:58:14Z wwccss $
*/
?>
<?php if(isset($this->config->conceptSetted)):?>
<?php include 'header.html.php';?>
<?php else:?>
<?php include '../../common/view/header.lite.html.php';?>
<?php endif;?>
<?php if(isset($this->config->conceptSetted)):?>
<div id='mainContent' class='main-content'>
<div class='main-header'>
<div class='heading'>
<strong><?php echo $lang->custom->concept?></strong>
</div>
</div>
<?php else:?>
<div class='container'>
<div class='modal-dialog'>
<div class='modal-header'>
<strong><?php echo $lang->custom->concept?></strong>
</div>
<?php endif;?>
<form id='ajaxForm' method='post'>
<div class='modal-body'>
<div class="form-group">
<label><?php echo $lang->custom->conceptQuestions['overview']?></label>
<div class="checkbox"> <?php echo html::radio('productProject', $lang->custom->productProject->relation, zget($this->config->custom, 'productProject', '0_0'))?> </div>
</div>
<?php if(!common::checkNotCN()):?>
<div class="form-group">
<label><?php echo $lang->custom->conceptQuestions['story']?></label>
<div class="checkbox"> <?php echo html::radio('storyRequirement', $lang->custom->conceptOptions->story, zget($this->config->custom, 'storyRequirement', '0'));?></div>
</div>
<?php endif;?>
<div class="form-group">
<label><?php echo $lang->custom->conceptQuestions['storypoint'];?></label>
<div class="checkbox"> <?php echo html::radio('hourPoint', $lang->custom->conceptOptions->hourPoint, '0')?> </div>
</div>
<div class="form-group">
<label></label>
<div><?php echo html::submitButton();?></div>
</div>
</div>
</form>
<?php if(isset($this->config->conceptSetted)):?>
<?php include '../../common/view/footer.html.php';?>
<?php else:?>
</div>
</div>
</body>
</html>
<?php endif;?>
+1 -1
View File
@@ -20,7 +20,7 @@
<table class='table table-form'>
<tr>
<th class='w-300px'><?php echo $lang->custom->scoreTitle;?></th>
<td class='w-120px text-center'>
<td class='w-150px text-center'>
<?php $checkedKey = isset($config->global->scoreStatus) ? $config->global->scoreStatus : 0;?>
<?php foreach($lang->custom->scoreStatus as $key => $value):?>
<label class="radio-inline"><input type="radio" name="score" value="<?php echo $key?>"<?php echo $key == $checkedKey ? " checked='checked'" : ''?> id="score<?php echo $key;?>"><?php echo $value;?></label>
+2 -2
View File
@@ -28,14 +28,14 @@ class datatable extends control
* @access public
* @return void
*/
public function ajaxSave()
public function ajaxSave($type = '')
{
if(!empty($_POST))
{
$account = $this->app->user->account;
if($account == 'guest') $this->send(array('result' => 'fail', 'target' => $target, 'message' => 'guest.'));
$name = 'datatable.' . $this->post->target . '.' . $this->post->name;
$name = $type == 'allModule' ? 'project.task.allModule' : 'datatable.' . $this->post->target . '.' . $this->post->name;
$this->loadModel('setting')->setItem($account . '.' . $name, $this->post->value);
if($this->post->global) $this->setting->setItem('system.' . $name, $this->post->value);
+1 -1
View File
@@ -19,7 +19,7 @@ $lang->datatable->branch = 'Branch';
$lang->datatable->platform = 'Platform';
$lang->datatable->showModule = 'Show module names on the list page';
$lang->datatable->showModuleAB = 'Show Module Names';
$lang->datatable->showModuleAB = 'Show modules in the list';
$lang->datatable->showModuleList[] = 'N/A';
$lang->datatable->showModuleList['base'] = 'Base Node';
$lang->datatable->showModuleList['end'] = 'End Node';
+1 -1
View File
@@ -152,7 +152,7 @@ class datatableModel extends model
$title = (isset($col->name) and $col->name) ? "title='$col->name'" : $title;
if($id == 'id' and (int)$width < 90) $width = '90px';
$width = "data-width='$width' style='width:$width'";
$align = $id == 'actions' ? 'text-center' : '';
$align = ($id == 'actions' || $id == 'progress') ? 'text-center' : '';
echo "<th data-flex='$fixed' $width class='c-$id $align' $title>";
if($id == 'actions')
-2
View File
@@ -54,10 +54,8 @@ $config->dev->group['backup'] = 'admin';
$config->dev->group['cron'] = 'admin';
$config->dev->group['dev'] = 'admin';
$config->dev->group['custom'] = 'admin';
$config->dev->group['editor'] = 'admin';
$config->dev->group['score'] = 'admin';
$config->dev->group['config'] = 'admin';
$config->dev->group['translate'] = 'admin';
$config->dev->group['svn'] = 'repo';
$config->dev->group['git'] = 'repo';
$config->dev->group['api'] = 'api';
+30
View File
@@ -51,4 +51,34 @@ class dev extends control
$this->view->fields = $table ? $this->dev->getFields($table) : array();
$this->display();
}
/**
* Editor.
*
* @access public
* @return void
*/
public function editor()
{
$this->view->title = $this->lang->dev->editor;
$this->view->position[] = html::a(inlink('api'), $this->lang->dev->common);
$this->view->position[] = $this->lang->dev->editor;
$this->view->tab = 'editor';
$this->display();
}
/**
* Translate.
*
* @access public
* @return void
*/
public function translate()
{
$this->view->title = $this->lang->dev->translate;
$this->view->position[] = $this->lang->dev->translate;
$this->display();
}
}
+11 -10
View File
@@ -3,6 +3,7 @@ $lang->dev->common = '二次开发';
$lang->dev->api = 'API';
$lang->dev->db = '数据库';
$lang->dev->editor = '编辑器';
$lang->dev->translate = '翻译';
$lang->dev->dbList = '数据库';
$lang->dev->moduleList = '模块列表';
$lang->dev->params = '参数列表';
@@ -11,10 +12,12 @@ $lang->dev->desc = '描述';
$lang->dev->noParams = '无参数';
$lang->dev->post = 'POST参数';
$lang->dev->paramRange = '取值范围:%s';
$lang->dev->paramDate = '日期格式:YY-mm-dd,如:2019-01-01';
$lang->dev->paramColor = '颜色格式:#RGB,如:#3da7f5';
$lang->dev->paramMailto = "填写帐号,多个账号用','分隔。";
$lang->dev->paramRange = '取值范围:%s';
$lang->dev->paramDate = '日期格式:YY-mm-dd,如:2019-01-01';
$lang->dev->paramColor = '颜色格式:#RGB,如:#3da7f5';
$lang->dev->paramMailto = "填写帐号,多个账号用','分隔。";
$lang->dev->noteEditor = "编辑器功能因为安全原因被禁用。如果想用该功能,请到官网下载安装编辑器插件。";
$lang->dev->noteTranslate = "翻译功能因为安全原因被禁用。如果想用该功能,请到官网下载安装编辑器插件。";
$lang->dev->fields = array();
$lang->dev->fields['id'] = '序号';
@@ -49,10 +52,10 @@ $lang->dev->tableList['product'] = $lang->productCommon;
$lang->dev->tableList['productplan'] = $lang->productCommon . '计划';
$lang->dev->tableList['project'] = $lang->projectCommon;
$lang->dev->tableList['projectproduct'] = $lang->projectCommon . $lang->productCommon;
$lang->dev->tableList['projectstory'] = $lang->projectCommon . '需求';
$lang->dev->tableList['projectstory'] = $lang->projectCommon . $lang->storyCommon;
$lang->dev->tableList['release'] = '发布';
$lang->dev->tableList['story'] = '需求';
$lang->dev->tableList['storyspec'] = '需求描述';
$lang->dev->tableList['story'] = $lang->storyCommon;
$lang->dev->tableList['storyspec'] = "{$lang->storyCommon}描述";
$lang->dev->tableList['task'] = '任务';
$lang->dev->tableList['taskestimate'] = '任务预计';
$lang->dev->tableList['team'] = '团队';
@@ -71,7 +74,6 @@ $lang->dev->tableList['backup'] = '备份';
$lang->dev->tableList['common'] = '公有模块';
$lang->dev->tableList['convert'] = '导入';
$lang->dev->tableList['dev'] = '二次开发';
$lang->dev->tableList['editor'] = '编辑器';
$lang->dev->tableList['git'] = 'GIT';
$lang->dev->tableList['index'] = '首页';
$lang->dev->tableList['install'] = '安装';
@@ -93,8 +95,7 @@ $lang->dev->tableList['datatable'] = '数据表格';
$lang->dev->tableList['block'] = '区块';
$lang->dev->tableList['branch'] = '平台/分支';
$lang->dev->tableList['doccontent'] = '文档内容';
$lang->dev->tableList['storystage'] = '需求阶段';
$lang->dev->tableList['translate'] = '翻译';
$lang->dev->tableList['storystage'] = "{$lang->storyCommon}阶段";
$lang->dev->tableList['tutorial'] = '新手教程';
$lang->dev->tableList['suitecase'] = '套件用例';
$lang->dev->tableList['score'] = '积分';
@@ -1,18 +1,17 @@
<?php
/**
* The deny view file of editor module of ZenTaoPMS.
* The editor view file of dev module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package editor
* @package dev
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php include 'header.html.php';?>
<div id='mainContent' class='main-content'>
<div class='alert alert-warning'><?php echo $this->lang->editor->onlyLocalVisit;?></div>
<div class='alert alert-danger'><?php echo $lang->dev->noteEditor;?></div>
</div>
<?php include '../../common/view/footer.html.php';?>
@@ -1,23 +1,20 @@
<?php
/**
* The deny view file of editor module of ZenTaoPMS.
* The translate view file of dev module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package editor
* @package dev
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php include '../../common/view/header.html.php';?>
<style>
html{height:100%}
body{height:100%;padding-bottom:0px;}
#mainContent{height:100%}
#subNavbar li[data-id='dev'].active > a {font-weight: normal; color: #3c4353;}
</style>
<div id='mainContent' class='main-content'>
<div class='alert alert-warning'><?php echo $this->lang->editor->onlyLocalVisit;?></div>
<div class='alert alert-danger'><?php echo $lang->dev->noteTranslate;?></div>
</div>
<?php include '../../common/view/footer.lite.html.php';?>
<?php include '../../common/view/footer.html.php';?>
+2 -2
View File
@@ -176,8 +176,8 @@ $lang->doc->noCollectedDoc = '您还没有收藏任何文档。';
$lang->doc->noticeAcl['lib']['product']['default'] = '有所选产品访问权限的用户可以访问。';
$lang->doc->noticeAcl['lib']['product']['custom'] = '有所选产品访问权限或白名单里的用户可以访问。';
$lang->doc->noticeAcl['lib']['project']['default'] = '有所选项目访问权限的用户可以访问。';
$lang->doc->noticeAcl['lib']['project']['custom'] = '有所选项目访问权限或白名单里的用户可以访问。';
$lang->doc->noticeAcl['lib']['project']['default'] = "有所选{$lang->projectCommon}访问权限的用户可以访问。";
$lang->doc->noticeAcl['lib']['project']['custom'] = "有所选{$lang->projectCommon}访问权限或白名单里的用户可以访问。";
$lang->doc->noticeAcl['lib']['custom']['open'] = '所有人都可以访问。';
$lang->doc->noticeAcl['lib']['custom']['custom'] = '白名单的用户可以访问。';
$lang->doc->noticeAcl['lib']['custom']['private'] = '只有创建者自己可以访问。';
+1 -1
View File
@@ -167,7 +167,7 @@ js::set('sysurl', common::getSysUrl());
<tbody>
<?php if($doc->productName):?>
<tr>
<th class='w-80px'><?php echo $lang->doc->product;?></th>
<th class='w-90px'><?php echo $lang->doc->product;?></th>
<td><?php echo $doc->productName;?></td>
</tr>
<?php endif;?>
-18
View File
@@ -1,18 +0,0 @@
<?php
$config->editor->sort[] = 'model.php';
$config->editor->sort[] = 'control.php';
$config->editor->sort[] = 'view';
$config->editor->sort[] = 'lang';
$config->editor->sort[] = 'config.php';
$config->editor->sort[] = 'js';
$config->editor->sort[] = 'css';
$config->editor->sort[] = 'ext';
$config->editor->extSort[] = 'model';
$config->editor->extSort[] = 'control';
$config->editor->extSort[] = 'view';
$config->editor->extSort[] = 'lang';
$config->editor->extSort[] = 'js';
$config->editor->extSort[] = 'css';
$config->editor->extSort[] = 'config';
-193
View File
@@ -1,193 +0,0 @@
<?php
/**
* The control file of editor of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package editor
* @version $Id$
* @link http://www.zentao.net
*/
class editor extends control
{
/**
* Construct
*
* @param string $moduleName
* @param string $methodName
* @param string $appName
* @access public
* @return void
*/
public function __construct($moduleName = '', $methodName = '', $appName = '')
{
parent::__construct($moduleName, $methodName, $appName);
$remoteIp = helper::getRemoteIp();
$this->active = ($remoteIp == '127.0.0.1' or $remoteIp == '::1');
$methodName = $this->app->getMethodName();
if(!$this->active and $methodName != 'index' and $methodName != 'extend') die($this->display('editor', 'deny'));
}
/**
* Show module files and edit them.
*
* @access public
* @return void
*/
public function index($type = 'editor')
{
$this->app->loadLang('dev');
$this->view->title = $this->lang->editor->common;
$this->view->position[] = $this->lang->editor->common;
$this->view->modules = $this->loadModel('dev')->getModules();
$this->view->tab = $type;
$this->display();
}
/**
* Show files and methods of the module.
*
* @param string $moduleDir
* @access public
* @return void
*/
public function extend($moduleDir = '')
{
$moduleFiles = $this->editor->getModuleFiles($moduleDir);
$this->view->module = $moduleDir;
$this->view->tree = $this->editor->printTree($moduleFiles);
$this->display();
}
/**
* Edit extend.
*
* @param string $filePath
* @param string $action
* @param string $isExtends
* @access public
* @return void
*/
public function edit($filePath = '', $action = '', $isExtends = '')
{
$this->view->safeFilePath = $filePath;
$fileContent = '';
if($filePath)
{
$filePath = helper::safe64Decode($filePath);
if(strpos(strtolower($filePath), strtolower($this->app->getBasePath())) !== 0) die($this->lang->editor->editFileError);
if($action == 'extendOther' and file_exists($filePath))
{
$this->view->showContent = htmlspecialchars(file_get_contents($filePath));
}
if($action == 'edit' or $action == 'override')
{
if(file_exists($filePath))
{
$fileContent = file_get_contents($filePath);
if($action == 'override')
{
$fileContent = str_replace('../../', '../../../', $fileContent);
$fileContent = str_replace(array('\'./', '"./'), array('\'../../view/', '"../../view'), $fileContent);
}
}
else
{
$filePath = '';
}
}
elseif($action == 'extendModel')
{
$fileContent = $this->editor->extendModel($filePath);
}
elseif($action == 'extendControl')
{
$okUrl = $this->editor->getExtendLink($filePath, 'extendControl', 'yes');
$cancelUrl = $this->editor->getExtendLink($filePath, 'extendControl', 'no');
if(!$isExtends) die(js::confirm($this->lang->editor->extendConfirm, $okUrl, $cancelUrl));
$fileContent = $this->editor->extendControl($filePath, $isExtends);
}
elseif($action == 'newPage')
{
$fileContent = $this->editor->newControl($filePath);
}
elseif(strrpos(basename($filePath), '.php') !== false and empty($fileContent))
{
$fileContent = "<?php\n";
}
}
$this->view->fileContent = $fileContent;
$this->view->filePath = $filePath;
$this->view->action = $action;
$this->display();
}
/**
* Set Page name.
*
* @param string $filePath
* @access public
* @return void
*/
public function newPage($filePath)
{
$filePath = helper::safe64Decode($filePath);
if($_POST)
{
$saveFilePath = $this->editor->getSavePath($filePath, 'newMethod');
$extendLink = $this->editor->getExtendLink($saveFilePath, 'newPage');
if(file_exists($saveFilePath) and !$this->post->override) die(js::confirm($this->lang->editor->repeatPage, $extendLink, '', 'parent'));
die(js::locate($extendLink, 'parent'));
}
$this->view->filePath = $filePath;
$this->display();
}
/**
* Save file to extension.
*
* @param string $filePath
* @access public
* @return void
*/
public function save($filePath = '', $action = '')
{
$statusFile = $this->loadModel('upgrade')->checkSafeFile();
if($statusFile)
{
die(js::alert(sprintf($this->lang->editor->noticeOkFile, str_replace('\\', '/', $statusFile))));
}
if($filePath and $_POST)
{
$filePath = helper::safe64Decode($filePath);
if(strpos(strtolower($filePath), strtolower($this->app->getBasePath())) !== 0) die($this->lang->editor->editFileError);
if($action != 'edit' and $action != 'newPage') $filePath = $this->editor->getSavePath($filePath, $action);
if($action != 'edit' and $action != 'newPage' and file_exists($filePath) and !$this->post->override) die(js::error($this->lang->editor->repeatFile));
$this->editor->save($filePath);
echo js::reload('parent.parent.extendWin');
die(js::locate(inlink('edit', "filePath=" . helper::safe64Encode($filePath) . "&action=edit"), 'parent'));
}
}
/**
* Delete extension file.
*
* @param string $filePath
* @param string $confirm
* @access public
* @return void
*/
public function delete($filePath = '', $confirm = 'no')
{
if($confirm == 'no')
{
die(js::confirm($this->lang->editor->deleteConfirm, inlink('delete', "filePath=$filePath&confirm=yes")));
}
$filePath = helper::safe64Decode($filePath);
if(file_exists($filePath) and unlink($filePath)) die(js::reload('parent'));
die(js::alert($this->lang->editor->notDelete));
}
}
-2
View File
@@ -1,2 +0,0 @@
body{padding-bottom:0px;background-color:#fff;}
.main-content textarea.form-control {min-height: 450px; height: auto;}
-5
View File
@@ -1,5 +0,0 @@
body{padding-bottom:0px;background-color:#fff;}
.expandable > ul {display: none!important}
.collapsable > ul {display: block!important}
.tree li:before {margin-right: 4px;}
.tree li>a{display:inline;}
-6
View File
@@ -1,6 +0,0 @@
table td {padding: 0 10px; vertical-align: top;}
table tr > td:first-child {padding-left: 0;}
table tr > td:last-child {padding-right: 0;}
.modulegroup {font-weight:bold; padding-top:8px; border-top:1px solid #ddd;}
td.w-200px a:hover {font-weight:bold;}
.w-350px{width:350px;}
-1
View File
@@ -1 +0,0 @@
$(function(){ })
-12
View File
@@ -1,12 +0,0 @@
$(function()
{
var showHeight = $('#main').height() - $('#mainMenu').height() - 40;
$('#editWin').height(showHeight);
$('#extendWin').height(showHeight);
$('.side-col a').click(function()
{
$('.side-col a.active').removeClass('active');
$(this).addClass('active');
});
});
-76
View File
@@ -1,76 +0,0 @@
<?php
$lang->editor->common = 'Editor';
$lang->editor->api = 'API';
$lang->editor->index = 'Home';
$lang->editor->newMethod = 'Neue Methode';
$lang->editor->extend = 'Erweiterung';
$lang->editor->api = 'API';
$lang->editor->newLang = 'Neue Sprache';
$lang->editor->newConfig = 'Neue Konfiguration';
$lang->editor->newHook = 'Neuer Hook';
$lang->editor->newExtend = 'Neue Erweiterung';
$lang->editor->newPage = 'Neue Seite';
$lang->editor->override = 'Überschreiben';
$lang->editor->edit = 'Erweiterung bearbeiten';
$lang->editor->save = 'Seite speichern';
$lang->editor->delete = 'Seite löschen';
$lang->editor->moduleList = 'Module';
$lang->editor->filePath = "Erweiterung:";
$lang->editor->sourceFile = 'Source Datei:';
$lang->editor->fileName = "Dateiname:";
$lang->editor->isOverride = "Dublette überschrieben";
$lang->editor->exampleHook = "(z.B. ***.html.hook.php)";
$lang->editor->exampleJs = "(z.B. ***.js)";
$lang->editor->exampleCss = "(z.B. ***.css)";
$lang->editor->examplePHP = "(z.B. ***.php)";
$lang->editor->pageName = "Seitenname:";
$lang->editor->deleteConfirm = 'Möchten Sie das löschen?';
$lang->editor->extendConfirm = 'Möchten Sie den Originalcode verwenden?';
$lang->editor->repeatFile = 'Datei existiert bereits';
$lang->editor->repeatPage = 'Seite existiert bereits. Möchten Sie die Seite überschreiben?';
$lang->editor->noticeOkFile = 'Aus Sicherheitsgründen muss Ihr Adminkonto bestätigt werden. \n Bitte melden Sie sich an und erstellen Sie die Datei %s File.\n Hinweis:\n 1. Die Datei ist leer.\n 2. Wenn die Datei bereits existiert, löschen Sie sie und erstellen Sie eine neue Datei.';
$lang->editor->editFileError = 'Sie können nur ZenTao Dateien verändern!';
$lang->editor->notWritable = "Nicht beschreibbar. Berechtigung erforderlich. Bitte versuchen Sie chmod 777 -R ";
$lang->editor->notDelete = 'Kann nicht gelöscht werden. Bitte prüfen Sie Ihre Berechtigungen!';
$lang->editor->emptyFileName = 'Bitte geben Sie einen Dateinamen an!';
$lang->editor->onlyLocalVisit = "This feature only works when the IP is 127.0.0.1. <a href='https://api.zentao.pm/goto.php?item=howtodevelop&from=en' target='_blank'>Help</a>";
$lang->editor->translate['config.php'] = 'config';
$lang->editor->translate['control.php'] = 'control';
$lang->editor->translate['model.php'] = 'model';
$lang->editor->modules['action'] = 'System Log';
$lang->editor->modules['admin'] = 'Admin';
$lang->editor->modules['api'] = 'API';
$lang->editor->modules['bug'] = 'Bug';
$lang->editor->modules['build'] = 'Build';
$lang->editor->modules['common'] = 'Bekannte Module';
$lang->editor->modules['company'] = 'Unternehmen';
$lang->editor->modules['convert'] = 'Konvertieren';
$lang->editor->modules['dept'] = 'Abteilung';
$lang->editor->modules['doc'] = 'Dok';
$lang->editor->modules['extension'] = 'Erweiterung';
$lang->editor->modules['file'] = 'Datei';
$lang->editor->modules['group'] = 'Gruppe';
$lang->editor->modules['index'] = 'Homepage';
$lang->editor->modules['install'] = 'Installieren';
$lang->editor->modules['misc'] = 'Sonstiges';
$lang->editor->modules['my'] = 'Dashboard';
$lang->editor->modules['product'] = $lang->productCommon;
$lang->editor->modules['productplan'] = 'Plan';
$lang->editor->modules['project'] = $lang->projectCommon;
$lang->editor->modules['qa'] = 'QA';
$lang->editor->modules['release'] = 'Release';
$lang->editor->modules['report'] = 'Berichte';
$lang->editor->modules['search'] = 'Suche';
$lang->editor->modules['story'] = 'Story';
$lang->editor->modules['task'] = 'Aufgaben';
$lang->editor->modules['testcase'] = 'Fälle';
$lang->editor->modules['testtask'] = 'Testaufgaben';
$lang->editor->modules['todo'] = 'Todos';
$lang->editor->modules['tree'] = 'Module';
$lang->editor->modules['upgrade'] = 'Upgrade';
$lang->editor->modules['user'] = 'Benutzer';
-76
View File
@@ -1,76 +0,0 @@
<?php
$lang->editor->common = 'Editor';
$lang->editor->api = 'API';
$lang->editor->index = 'Home';
$lang->editor->newMethod = 'New Method';
$lang->editor->extend = 'Extension';
$lang->editor->api = 'API';
$lang->editor->newLang = 'New Language';
$lang->editor->newConfig = 'New Config';
$lang->editor->newHook = 'New Hook';
$lang->editor->newExtend = 'New Extension';
$lang->editor->newPage = 'New Page';
$lang->editor->override = 'Overwrite';
$lang->editor->edit = 'Edit Extension';
$lang->editor->save = 'Save Page';
$lang->editor->delete = 'Delete Page';
$lang->editor->moduleList = 'Module';
$lang->editor->filePath = "Extension:";
$lang->editor->sourceFile = 'Source File:';
$lang->editor->fileName = "File Name:";
$lang->editor->isOverride = "Override Duplicated File";
$lang->editor->exampleHook = "(e.g. ***.html.hook.php)";
$lang->editor->exampleJs = "(e.g. ***.js)";
$lang->editor->exampleCss = "(e.g. ***.css)";
$lang->editor->examplePHP = "(e.g. ***.php)";
$lang->editor->pageName = "Page Name:";
$lang->editor->deleteConfirm = 'Do you want to delete it?';
$lang->editor->extendConfirm = 'Do you want to use original code?';
$lang->editor->repeatFile = 'File Name Duplicated';
$lang->editor->repeatPage = 'This page exists. Do you want to overwrite it?';
$lang->editor->noticeOkFile = 'For security reasons, your Admin account has to be confirmed. \n Please login ZenTao server and create %s File.\n Note:\n 1. File is blank.\n 2. If the file existed, delete it and then create a new one.';
$lang->editor->editFileError = 'You can only modify ZenTao files!';
$lang->editor->notWritable = "Not wirtable. Permission is required. Please try chmod 777 -R ";
$lang->editor->notDelete = 'Cannot be deleted. Please check your permissions!';
$lang->editor->emptyFileName = 'Please enter a File Name!';
$lang->editor->onlyLocalVisit = "This feature only works when the IP is 127.0.0.1 for security. <a href='https://api.zentao.pm/goto.php?item=howtodevelop&from=en' target='_blank'>Help</a>";
$lang->editor->translate['config.php'] = 'config';
$lang->editor->translate['control.php'] = 'control';
$lang->editor->translate['model.php'] = 'model';
$lang->editor->modules['action'] = 'System Log';
$lang->editor->modules['admin'] = 'Admin';
$lang->editor->modules['api'] = 'API';
$lang->editor->modules['bug'] = 'Bug';
$lang->editor->modules['build'] = 'Build';
$lang->editor->modules['common'] = 'Common Module';
$lang->editor->modules['company'] = 'Company';
$lang->editor->modules['convert'] = 'Convert';
$lang->editor->modules['dept'] = 'Department';
$lang->editor->modules['doc'] = 'Doc';
$lang->editor->modules['extension'] = 'Extension';
$lang->editor->modules['file'] = 'File';
$lang->editor->modules['group'] = 'Group';
$lang->editor->modules['index'] = 'Homepage';
$lang->editor->modules['install'] = 'Install';
$lang->editor->modules['misc'] = 'Misc';
$lang->editor->modules['my'] = 'Dashboard';
$lang->editor->modules['product'] = $lang->productCommon;
$lang->editor->modules['productplan'] = 'Plan';
$lang->editor->modules['project'] = $lang->projectCommon;
$lang->editor->modules['qa'] = 'QA';
$lang->editor->modules['release'] = 'Release';
$lang->editor->modules['report'] = 'Report';
$lang->editor->modules['search'] = 'Search';
$lang->editor->modules['story'] = 'Story';
$lang->editor->modules['task'] = 'Task';
$lang->editor->modules['testcase'] = 'Case';
$lang->editor->modules['testtask'] = 'Request';
$lang->editor->modules['todo'] = 'Todo';
$lang->editor->modules['tree'] = 'Module Maintenance';
$lang->editor->modules['upgrade'] = 'Upgrade';
$lang->editor->modules['user'] = 'User';
-76
View File
@@ -1,76 +0,0 @@
<?php
$lang->editor->common = 'Editeur';
$lang->editor->api = 'API';
$lang->editor->index = 'Accueil';
$lang->editor->newMethod = 'New Méthode';
$lang->editor->extend = 'Extension';
$lang->editor->api = 'API';
$lang->editor->newLang = 'New Language';
$lang->editor->newConfig = 'New Config';
$lang->editor->newHook = 'New Hook';
$lang->editor->newExtend = 'New Extension';
$lang->editor->newPage = 'New Page';
$lang->editor->override = 'Ecraser';
$lang->editor->edit = 'Editer Extension';
$lang->editor->save = 'Sauver Page';
$lang->editor->delete = 'Supprimer Page';
$lang->editor->moduleList = 'Module';
$lang->editor->filePath = "Extension:";
$lang->editor->sourceFile = 'Fichier Source :';
$lang->editor->fileName = "Nom Fichier :";
$lang->editor->isOverride = "Override Duplicated File";
$lang->editor->exampleHook = "(e.g. ***.html.hook.php)";
$lang->editor->exampleJs = "(e.g. ***.js)";
$lang->editor->exampleCss = "(e.g. ***.css)";
$lang->editor->examplePHP = "(e.g. ***.php)";
$lang->editor->pageName = "Nom Page :";
$lang->editor->deleteConfirm = 'Voulez-vous le supprimer ?';
$lang->editor->extendConfirm = 'Voulez-vous utiliser le code original ?';
$lang->editor->repeatFile = 'Doublon';
$lang->editor->repeatPage = "Cette page existe. Voulez-vous l'écraser ?";
$lang->editor->noticeOkFile = 'Pour des raisons de sécurité, votre compte administrateur doit être confirmé. \n Please login ZenTao server and create %s File.\n Note:\n 1. File is blank.\n 2. If the file existed, delete it and then create a new one.';
$lang->editor->editFileError = 'Vous pouvez seulement modifier les fichiers ZenTao !';
$lang->editor->notWritable = "Non inscriptible. Permission requise. Essayez chmod 777 -R ";
$lang->editor->notDelete = 'Ne peut pas être supprimé. Vérifiez les permissions !';
$lang->editor->emptyFileName = 'Entrez un nom de fichier !';
$lang->editor->onlyLocalVisit = "Cette fonctionnalité ne fonctionne que pour une IP 127.0.0.1. <a href='https://api.zentao.pm/goto.php?item=howtodevelop&from=en' target='_blank'>Aide</a>";
$lang->editor->translate['config.php'] = 'config';
$lang->editor->translate['control.php'] = 'contrôle';
$lang->editor->translate['model.php'] = 'modèle';
$lang->editor->modules['action'] = 'System Log';
$lang->editor->modules['admin'] = 'Admin';
$lang->editor->modules['api'] = 'API';
$lang->editor->modules['bug'] = 'Bug';
$lang->editor->modules['build'] = 'Build';
$lang->editor->modules['common'] = 'Module Commun';
$lang->editor->modules['company'] = 'Entreprise';
$lang->editor->modules['convert'] = 'Convertir';
$lang->editor->modules['dept'] = 'Compartiment';
$lang->editor->modules['doc'] = 'Doc';
$lang->editor->modules['extension'] = 'Extension';
$lang->editor->modules['file'] = 'Fichier';
$lang->editor->modules['group'] = 'Groupe';
$lang->editor->modules['index'] = 'Accueil';
$lang->editor->modules['install'] = 'Installer';
$lang->editor->modules['misc'] = 'Divers';
$lang->editor->modules['my'] = 'Dashboard';
$lang->editor->modules['product'] = $lang->productCommon;
$lang->editor->modules['productplan'] = 'Plan';
$lang->editor->modules['project'] = $lang->projectCommon;
$lang->editor->modules['qa'] = 'QA';
$lang->editor->modules['release'] = 'Release';
$lang->editor->modules['report'] = 'Rapport';
$lang->editor->modules['search'] = 'Recherche';
$lang->editor->modules['story'] = 'Story';
$lang->editor->modules['task'] = 'Tâche';
$lang->editor->modules['testcase'] = 'CasTest';
$lang->editor->modules['testtask'] = 'Recette';
$lang->editor->modules['todo'] = 'Agenda';
$lang->editor->modules['tree'] = 'Module Maintenance';
$lang->editor->modules['upgrade'] = 'Upgrade';
$lang->editor->modules['user'] = 'User';
-76
View File
@@ -1,76 +0,0 @@
<?php
$lang->editor->common = '编辑器';
$lang->editor->api = 'API';
$lang->editor->index = '首页';
$lang->editor->newMethod = '新增方法';
$lang->editor->extend = '扩展';
$lang->editor->api = 'API';
$lang->editor->newLang = '新增语言';
$lang->editor->newConfig = '新增配置';
$lang->editor->newHook = '新增钩子';
$lang->editor->newExtend = '新增扩展';
$lang->editor->newPage = '新增页面';
$lang->editor->override = '覆盖';
$lang->editor->edit = '编辑扩展';
$lang->editor->save = '保存页面';
$lang->editor->delete = '删除页面';
$lang->editor->moduleList = '模块列表';
$lang->editor->filePath = "扩展:";
$lang->editor->sourceFile = '源文件:';
$lang->editor->fileName = "文件名:";
$lang->editor->isOverride = "覆盖重复文件";
$lang->editor->exampleHook = "(例如:***.html.hook.php)";
$lang->editor->exampleJs = "(例如:***.js)";
$lang->editor->exampleCss = "(例如:***.css)";
$lang->editor->examplePHP = "(例如:***.php)";
$lang->editor->pageName = "页面名称:";
$lang->editor->deleteConfirm = '是否要删除?';
$lang->editor->extendConfirm = '是否要重用原来代码?';
$lang->editor->repeatFile = '文件名重复';
$lang->editor->repeatPage = '已经有此页面。是否覆盖?';
$lang->editor->noticeOkFile = '为了安全起见,系统需要确认您的管理员身份。\n 请登录禅道所在的服务器,创建%s文件。\n 注意:\n 1. 文件内容为空。\n 2. 如果之前文件存在,删除之后重新创建。';
$lang->editor->editFileError = '只能修改禅道文件!';
$lang->editor->notWritable = "无法写入,可能没有权限。请尝试执行 chmod 777 -R ";
$lang->editor->notDelete = '无法删除,请检查权限!';
$lang->editor->emptyFileName = '请写入一个文件名!';
$lang->editor->onlyLocalVisit = "该功能只能在IP:127.0.0.1下访问。<a href='https://api.zentao.net/goto.php?item=howtodevelop' target='_blank'>说明文档</a>";
$lang->editor->translate['config.php'] = 'config';
$lang->editor->translate['control.php'] = 'control';
$lang->editor->translate['model.php'] = 'model';
$lang->editor->modules['action'] = '系统日志';
$lang->editor->modules['admin'] = '后台管理';
$lang->editor->modules['api'] = 'API接口';
$lang->editor->modules['bug'] = 'Bug管理';
$lang->editor->modules['build'] = 'Build';
$lang->editor->modules['common'] = '公有模块';
$lang->editor->modules['company'] = '组织视图';
$lang->editor->modules['convert'] = '从其他系统导入';
$lang->editor->modules['dept'] = '部门结构';
$lang->editor->modules['doc'] = '文档视图';
$lang->editor->modules['extension'] = '插件管理';
$lang->editor->modules['file'] = '附件';
$lang->editor->modules['group'] = '权限分组';
$lang->editor->modules['index'] = '首页';
$lang->editor->modules['install'] = '安装';
$lang->editor->modules['misc'] = '杂项';
$lang->editor->modules['my'] = '我的地盘';
$lang->editor->modules['product'] = $lang->productCommon . '视图';
$lang->editor->modules['productplan'] = '计划';
$lang->editor->modules['project'] = $lang->projectCommon . '视图';
$lang->editor->modules['qa'] = '测试视图';
$lang->editor->modules['release'] = '发布';
$lang->editor->modules['report'] = '报表';
$lang->editor->modules['search'] = '搜索';
$lang->editor->modules['story'] = '需求';
$lang->editor->modules['task'] = '任务';
$lang->editor->modules['testcase'] = '用例管理';
$lang->editor->modules['testtask'] = '测试任务';
$lang->editor->modules['todo'] = '待办';
$lang->editor->modules['tree'] = '模块维护';
$lang->editor->modules['upgrade'] = '升级';
$lang->editor->modules['user'] = '用户';
-76
View File
@@ -1,76 +0,0 @@
<?php
$lang->editor->common = '編輯器';
$lang->editor->api = 'API';
$lang->editor->index = '首頁';
$lang->editor->newMethod = '新增方法';
$lang->editor->extend = '擴展';
$lang->editor->api = 'API';
$lang->editor->newLang = '新增語言';
$lang->editor->newConfig = '新增配置';
$lang->editor->newHook = '新增鈎子';
$lang->editor->newExtend = '新增擴展';
$lang->editor->newPage = '新增頁面';
$lang->editor->override = '覆蓋';
$lang->editor->edit = '編輯擴展';
$lang->editor->save = '保存頁面';
$lang->editor->delete = '刪除頁面';
$lang->editor->moduleList = '模組列表';
$lang->editor->filePath = "擴展:";
$lang->editor->sourceFile = '源檔案:';
$lang->editor->fileName = "檔案名:";
$lang->editor->isOverride = "覆蓋重複檔案";
$lang->editor->exampleHook = "(例如:***.html.hook.php)";
$lang->editor->exampleJs = "(例如:***.js)";
$lang->editor->exampleCss = "(例如:***.css)";
$lang->editor->examplePHP = "(例如:***.php)";
$lang->editor->pageName = "頁面名稱:";
$lang->editor->deleteConfirm = '是否要刪除?';
$lang->editor->extendConfirm = '是否要重用原來代碼?';
$lang->editor->repeatFile = '檔案名重複';
$lang->editor->repeatPage = '已經有此頁面。是否覆蓋?';
$lang->editor->noticeOkFile = '為了安全起見,系統需要確認您的管理員身份。\n 請登錄禪道所在的伺服器,創建%s檔案。\n 注意:\n 1. 檔案內容為空。\n 2. 如果之前檔案存在,刪除之後重新創建。';
$lang->editor->editFileError = '只能修改禪道檔案!';
$lang->editor->notWritable = "無法寫入,可能沒有權限。請嘗試執行 chmod 777 -R ";
$lang->editor->notDelete = '無法刪除,請檢查權限!';
$lang->editor->emptyFileName = '請寫入一個檔案名!';
$lang->editor->onlyLocalVisit = "該功能只能在IP:127.0.0.1下訪問。<a href='https://api.zentao.net/goto.php?item=howtodevelop' target='_blank'>說明文檔</a>";
$lang->editor->translate['config.php'] = 'config';
$lang->editor->translate['control.php'] = 'control';
$lang->editor->translate['model.php'] = 'model';
$lang->editor->modules['action'] = '系統日誌';
$lang->editor->modules['admin'] = '後台管理';
$lang->editor->modules['api'] = 'API介面';
$lang->editor->modules['bug'] = 'Bug管理';
$lang->editor->modules['build'] = 'Build';
$lang->editor->modules['common'] = '公有模組';
$lang->editor->modules['company'] = '組織視圖';
$lang->editor->modules['convert'] = '從其他系統導入';
$lang->editor->modules['dept'] = '部門結構';
$lang->editor->modules['doc'] = '文檔視圖';
$lang->editor->modules['extension'] = '插件管理';
$lang->editor->modules['file'] = '附件';
$lang->editor->modules['group'] = '權限分組';
$lang->editor->modules['index'] = '首頁';
$lang->editor->modules['install'] = '安裝';
$lang->editor->modules['misc'] = '雜項';
$lang->editor->modules['my'] = '我的地盤';
$lang->editor->modules['product'] = $lang->productCommon . '視圖';
$lang->editor->modules['productplan'] = '計劃';
$lang->editor->modules['project'] = $lang->projectCommon . '視圖';
$lang->editor->modules['qa'] = '測試視圖';
$lang->editor->modules['release'] = '發佈';
$lang->editor->modules['report'] = '報表';
$lang->editor->modules['search'] = '搜索';
$lang->editor->modules['story'] = '需求';
$lang->editor->modules['task'] = '任務';
$lang->editor->modules['testcase'] = '用例管理';
$lang->editor->modules['testtask'] = '測試任務';
$lang->editor->modules['todo'] = '待辦';
$lang->editor->modules['tree'] = '模組維護';
$lang->editor->modules['upgrade'] = '升級';
$lang->editor->modules['user'] = '用戶';
-577
View File
@@ -1,577 +0,0 @@
<?php
/**
* The model file of editor module of ZenTaoCMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package editor
* @version $Id$
* @link http://www.zentao.net
*/
class editorModel extends model
{
/**
* Get all modules
*
* @access public
* @return string
*/
public function getModules()
{
$modules = glob($this->app->getModuleRoot() . '*');
$moduleList = "<div class='list-group'>";
foreach($modules as $module)
{
$module = basename($module);
if($module == 'editor' or $module == 'help' or $module == 'setting') continue;
$moduleName = !empty($this->lang->editor->modules[$module]) ? $this->lang->editor->modules[$module] : $module;
$moduleList .= html::a(inlink('extend', "moduleDir=$module"), $moduleName, 'extendWin', "class='list-group-item'");
}
$moduleList .= '</div>';
return $moduleList;
}
/**
* Get module files, contain control's methods and model's method but except ext.
*
* @access public
* @return array
*/
public function getModuleFiles($moduleDir)
{
$moduleRoot = $this->app->getModuleRoot();
$moduleFullDir = $moduleRoot . $moduleDir;
$moduleFiles = scandir($moduleFullDir);
foreach($moduleFiles as $moduleFile)
{
if($moduleFile == '.' or $moduleFile == '..' or $moduleFile == '.svn') continue;
$moduleFullFile = $moduleFullDir . DS . $moduleFile;
if($moduleFile == 'control.php' or $moduleFile == 'model.php')
{
$allModules[$moduleFullDir][$moduleFullFile] = $this->analysis($moduleFullFile);
}
elseif($moduleFile == 'ext')
{
$allModules[$moduleFullDir][$moduleFullFile] = $this->getExtensionFiles($moduleFullFile);
}
elseif(is_dir($moduleFullFile))
{
$ext = ($moduleFile == 'js' or $moduleFile == 'css') ? $moduleFile : 'php';
$extFiles = glob($moduleFullFile . DS . "*.$ext");
if(!empty($extFiles))
{
foreach($extFiles as $fileName) $allModules[$moduleFullDir][$moduleFullFile][$fileName] = basename($fileName);
}
}
else
{
$allModules[$moduleFullDir][$moduleFullFile] = $moduleFile;
}
}
$allModules = $this->sortModule($moduleFullDir, $allModules);
return $allModules;
}
/**
* Get extension files.
*
* @param int $extPath
* @access public
* @return void
*/
public function getExtensionFiles($extPath)
{
$extensionList = array();
$extensionDirs = scandir($extPath);
foreach($extensionDirs as $extensionDir)
{
if($extensionDir == '.' or $extensionDir == '..' or $extensionDir == '.svn') continue;
$extensionFullDir = $extPath . DS . $extensionDir;
if(is_dir($extensionFullDir))
{
$extensionList[$extensionFullDir] = array();
/* extend of lang is more a grade of directroy. */
if($extensionDir == 'lang' or $extensionDir == 'js' or $extensionDir == 'css')
{
$extensionList[$extensionFullDir] = $this->getTwoGradeFiles($extensionFullDir);
continue;
}
$extensionFiles = scandir($extensionFullDir);
foreach($extensionFiles as $extensionFile)
{
if($extensionFile == '.' or $extensionFile == '..' or $extensionFile == '.svn') continue;
$extensionFullFile = $extensionFullDir . DS . $extensionFile;
$extensionList[$extensionFullDir][$extensionFullFile] = $extensionFile;
}
}
}
$extensionList = $this->sortModule($extPath, $extensionList, true);
return $extensionList;
}
/**
* Sort module
*
* @param string $filePath
* @param string $moduleFiles
* @param bool $isExtension
* @access public
* @return array
*/
public function sortModule($filePath, $moduleFiles, $isExtension = false)
{
$sort = $isExtension ? 'extSort' : 'sort';
$sortModules = array();
if(!$isExtension) $moduleFiles = $moduleFiles[$filePath];
foreach($this->config->editor->$sort as $sort)
{
$sortKey = empty($sort) ? $filePath : $filePath . DS . $sort;
if(array_key_exists($sortKey, $moduleFiles)) $sortModules[$sortKey] = $moduleFiles[$sortKey];
}
return $sortModules;
}
/**
* if a directory has two grage, this method will get files
*
* @param string $extensionFullDir
* @access public
* @return string
*/
public function getTwoGradeFiles($extensionFullDir)
{
$fileList = array();
$langDirs = scandir($extensionFullDir);
foreach($langDirs as $langDir)
{
if($langDir == '.' or $langDir == '..' or $langDir == '.svn') continue;
$langFullDir = $extensionFullDir . DS . $langDir;
$fileList[$langFullDir] = array();
if(is_dir($langFullDir))
{
$langFiles = scandir($langFullDir);
foreach($langFiles as $langFile)
{
if($langFile == '.' or $langFile == '..' or $langFile == '.svn') continue;
$langFullFile = $langFullDir . DS . $langFile;
$fileList[$langFullDir][$langFullFile] = $langFile;
}
}
}
return $fileList;
}
/**
* Analysis methods of control and model.
*
* @param string $fileName
* @access public
* @return array
*/
public function analysis($fileName)
{
$classMethod = array();
$class = strstr($fileName, DS . 'module' . DS);
$class = substr($class, 0, strpos($class, DS, 9));
$class = basename($class);
if(strpos($fileName, 'model.php') !== false) $class .= 'Model';
if(!class_exists($class)) include $fileName;
$reflection = new ReflectionClass($class);
foreach($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method)
{
$methodName = $method->name;
if($method->getFileName() != $fileName) continue;
if($methodName == '__construct') continue;
$classMethod[$fileName . DS . $methodName] = $methodName;
}
return $classMethod;
}
/**
* Print tree from module files.
*
* @param int $files
* @access public
* @return void
*/
public function printTree($files, $isRoot = true)
{
if(empty($files) or !is_array($files)) return false;
$tree = $isRoot ? "<ul id='extendTree' class='tree tree-lines' data-ride='tree'>\n" : "<ul>\n";
if($isRoot)
{
$module = basename(dirname(key($files)));
$langFile = dirname(key($files)) . DS . 'lang' . DS . $this->cookie->lang. '.php';
if(file_exists($langFile))
{
if(!isset($lang)) $lang = $this->lang;
if(!isset($lang->$module)) $lang->$module = new stdclass();
include_once $langFile;
}
if(isset($lang->$module))
{
$this->module = $lang->$module;
}
elseif(isset($this->lang->$module))
{
$this->module = $this->lang->$module;
}
else
{
$this->module = '';
}
}
foreach($files as $key => $file)
{
$tree .= "<li>\n";
if(is_array($file))
{
$tree .= $this->addLink4Dir($key);
$tree .= $this->printTree($file, false);
}
else
{
$tree .= $this->addLink4File($key, $file);
}
$tree .= "</li>\n";
}
$tree .= "</ul>\n";
return $tree;
}
/**
* Add link for directory or has children grade
*
* @param string $filePath
* @access public
* @return string
*/
public function addLink4Dir($filePath)
{
$tree = '';
$fileName = basename($filePath);
if(isset($this->lang->editor->modules[$fileName]))
{
$file = "<span title='$fileName'>" . $this->lang->editor->modules[$fileName] . '</span>';
}
elseif(isset($this->lang->editor->translate[$fileName]))
{
$file = "<span title='$fileName'>" . $this->lang->editor->translate[$fileName] . '</span>';
}
else
{
$file = "<span title='$fileName'>$fileName</span>";
}
if(strpos($filePath, DS . 'ext' . DS) !== false)
{
switch($fileName)
{
case 'lang': $tree .= $file; break;
case 'js': $tree .= "$file " . html::a($this->getExtendLink($filePath, "newJS"), $this->lang->editor->newExtend, 'editWin'); break;
case 'css': $tree .= "$file " . html::a($this->getExtendLink($filePath, "newCSS"), $this->lang->editor->newExtend, 'editWin'); break;
default: $tree .= "$file " . html::a($this->getExtendLink($filePath, "newExtend"), $this->lang->editor->newExtend, 'editWin');
}
}
elseif($fileName == 'model.php')
{
$tree .= "$file " . html::a($this->getExtendLink($filePath, 'newMethod'), $this->lang->editor->newMethod, 'editWin');
}
elseif($fileName == 'control.php')
{
$tree .= "$file " . html::a(inlink('newPage', "filePath=" . helper::safe64Encode($filePath)), $this->lang->editor->newPage, 'editWin');
}
else
{
$tree .= $file;
}
return $tree;
}
/**
* Add link for file
*
* @param string $filePath
* @param string $file
* @access public
* @return string
*/
public function addLink4File($filePath, $file)
{
$tree = '';
$file = "<span title='$file'>$file</span>";
if(strpos($filePath, DS . 'ext' . DS) !== false)
{
$tree .= "$file " . html::a($this->getExtendLink($filePath, "edit"), $this->lang->edit, 'editWin');
$tree .= html::a(inlink('delete', 'path=' . helper::safe64Encode($filePath)), $this->lang->delete, 'hiddenwin') . "\n";
}
elseif(basename(dirname($filePath))== 'view')
{
$tree .= "$file " . html::a($this->getExtendLink($filePath, "override"), $this->lang->editor->override, 'editWin');
$tree .= html::a($this->getExtendLink($filePath, "newHook"), $this->lang->editor->newHook, 'editWin') . "\n";
}
else
{
$parentDir = basename(dirname($filePath));
$action = 'extendOther';
if($parentDir == 'control.php') $action = 'extendControl';
if($parentDir == 'model.php') $action = 'extendModel';
$tree .= "$file " . html::a($this->getExtendLink($filePath, $action), $this->lang->editor->extend, 'editWin');
if($action != 'extendOther') $tree .= html::a($this->getAPILink($filePath, $action), $this->lang->editor->api, 'editWin');
if($parentDir == 'lang') $tree .= html::a($this->getExtendLink($filePath, "new" . str_replace('-', '_', basename($filePath, '.php'))), $this->lang->editor->newLang, 'editWin');
if(basename($filePath) == 'config.php') $tree .= html::a($this->getExtendLink($filePath, "newConfig"), $this->lang->editor->newConfig, 'editWin');
}
return $tree;
}
/**
* Get extend link
*
* @param string $filePath
* @param string $action
* @param string $isExtends
* @access public
* @return string
*/
public function getExtendLink($filePath, $action, $isExtends = '')
{
return inlink('edit', "filePath=" . helper::safe64Encode($filePath) . "&action=$action&isExtends=$isExtends");
}
/**
* Get api link.
*
* @param int $filePath
* @param int $action
* @param string $type
* @access public
* @return string
*/
public function getAPILink($filePath, $action)
{
return helper::createLink('api', 'debug', "filePath=" . helper::safe64Encode($filePath) . "&action=$action");
}
/**
* Save file to extension.
*
* @param string $filePath
* @access public
* @return void
*/
public function save($filePath)
{
$statusFile = $this->loadModel('upgrade')->checkSafeFile();
if($statusFile) die(js::alert(sprintf($this->lang->editor->noticeOkFile, str_replace('\\', '/', $statusFile))));
if(strpos(strtolower($filePath), strtolower($this->app->getBasePath())) !== 0) die(js::alert($this->lang->editor->editFileError));
$fileContent = $this->post->fileContent;
$evils = array('eval', 'exec', 'passthru', 'proc_open', 'shell_exec', 'system', '$$', 'include', 'require', 'assert');
$gibbedEvils = array('e v a l', 'e x e c', ' p a s s t h r u', ' p r o c _ o p e n', 's h e l l _ e x e c', 's y s t e m', '$ $', 'i n c l u d e', 'r e q u i r e', 'a s s e r t');
$fileContent = str_ireplace($gibbedEvils, $evils, $fileContent);
if(get_magic_quotes_gpc()) $fileContent = stripslashes($fileContent);
$dirPath = dirname($filePath);
$extFilePath = substr($filePath, 0, strpos($filePath, DS . 'ext' . DS) + 4);
if(!is_dir($dirPath) and is_writable($extFilePath)) mkdir($dirPath, 0777, true);
if(is_writable($dirPath))
{
file_put_contents($filePath, $fileContent);
}
else
{
die(js::alert($this->lang->editor->notWritable . $extFilePath));
}
}
/**
* Extend model.php and get file content.
*
* @param string $filePath
* @access public
* @return string
*/
public function extendModel($filePath)
{
$className = basename(dirname(dirname($filePath)));
if(!class_exists($className)) helper::import(dirname($filePath));
$methodName = basename($filePath);
$methodParam = $this->getParam($className, $methodName, 'Model');
return $fileContent = <<<EOD
<?php
public function $methodName($methodParam)
{
return parent::$methodName($methodParam);
}
EOD;
}
/**
* Extend control.php and get file content.
*
* @param string $filePath
* @access public
* @return string
*/
public function extendControl($filePath, $isExtends)
{
$className = basename(dirname(dirname($filePath)));
if(!class_exists($className)) helper::import(dirname($filePath));
$methodName = basename($filePath);
if($isExtends == 'yes')
{
$methodParam = $this->getParam($className, $methodName);
return $fileContent = <<<EOD
<?php
include '../../control.php';
class my$className extends $className
{
public function $methodName($methodParam)
{
return parent::$methodName($methodParam);
}
}
EOD;
}
else
{
$methodCode = $this->getMethodCode($className, $methodName);
return $fileContent = <<<EOD
<?php
class $className extends control
{
$methodCode
}
EOD;
}
}
/**
* Add a control method.
*
* @param string $filePath
* @access public
* @return string
*/
public function newControl($filePath)
{
$className = strstr($filePath, DS . 'module' . DS);
$className = substr($className, 0, strpos($className, DS, 9));
$className = basename($className);
$methodName = basename($filePath, '.php');
return $fileContent = <<<EOD
<?php
class $className extends control
{
public function $methodName()
{
}
}
EOD;
}
/**
* Get method's parameters.
*
* @param string $className
* @param string $methodName
* @param string $ext
* @access public
* @return string
*/
public function getParam($className, $methodName, $ext = '')
{
$method = new ReflectionMethod($className . $ext, $methodName);
$methodParam = '';
foreach ($method->getParameters() as $param)
{
$methodParam .= '$' . $param->getName();
if($param->isOptional())
{
$defaultParam = $param->getDefaultValue();
if(is_string($defaultParam)) $methodParam .= "='$defaultParam', ";
else $methodParam .= "=$defaultParam, ";
}
else
{
$methodParam .= ', ';
}
}
$methodParam = rtrim($methodParam, ', ');
return $methodParam;
}
/**
* Get method code.
*
* @param string $className
* @param string $methodName
* @param string $ext value may be Model
* @access public
* @return string
*/
public function getMethodCode($className, $methodName, $ext = '')
{
$method = new ReflectionMethod($className . $ext, $methodName);
$fileName = $method->getFileName();
$startLine = $method->getStartLine();
$endLine = $method->getEndLine();
$file = file($fileName);
$code = '';
for($i = $startLine - 1; $i <= $endLine; $i++)
{
$code .= $file[$i];
}
return $code;
}
/**
* Get save path.
*
* @param string $filePath
* @param string $action
* @access public
* @return string
*/
public function getSavePath($filePath, $action)
{
$fileName = empty($_POST['fileName']) ? '' : trim($this->post->fileName);
$moduleName = strstr($filePath, DS . 'module' . DS);
$moduleName = substr($moduleName, 0, strpos($moduleName, DS, 9));
$moduleName = basename($moduleName);
$extPath = $this->app->getModuleRoot() . $moduleName . DS . 'ext' . DS;
switch($action)
{
case 'extendModel':
$fileName = empty($fileName) ? strtolower(basename($filePath)) . '.php' : $fileName;
return $extPath . 'model' . DS . $fileName;
case 'extendControl':
$fileName = strtolower(basename($filePath)) . '.php';
return $extPath . 'control' . DS . $fileName;
case 'override':
$fileName = basename($filePath);
return $extPath . 'view' . DS . $fileName;
case 'extendOther':
$editName = basename($filePath);
$fileName = empty($fileName) ? $editName: $fileName;
if($editName == 'config.php') return $extPath . 'config' .DS . $fileName;
elseif(strpos($editName, '.php') !== false) return $extPath . 'lang' . DS . str_replace('.php', '', $editName) . DS . $fileName;
else return $extPath . substr($editName, strrpos($editName, '.') + 1) . DS . substr($editName, 0, strrpos($editName, '.')) . DS . $fileName;
default:
if(empty($fileName)) die(js::error($this->lang->editor->emptyFileName));
$action = strtolower(str_replace('new', '', $action));
if($action == 'hook') return $extPath . 'view' . DS . $fileName;
elseif($action == 'method') return $extPath . basename($filePath, '.php') . DS . $fileName;
elseif($action == 'extend') return $filePath . DS . $fileName;
elseif($action == 'config') return $extPath . 'config' . DS . $fileName;
elseif($action == 'js') return $extPath . 'js' . DS . substr($fileName, 0, strrpos($fileName, '.')) . DS . $fileName;
elseif($action == 'css') return $extPath . 'css' . DS . substr($fileName, 0, strrpos($fileName, '.')) . DS . $fileName;
else return $extPath . 'lang' . DS . str_replace('_', '-', $action) . DS . $fileName;
}
}
}
-79
View File
@@ -1,79 +0,0 @@
<?php
/**
* The editor view file of dir module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package editor
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<div class='main-header'>
<div class='heading'>
<i class='icon-edit'></i>
<?php if($filePath):?>
<strong><?php echo $lang->editor->filePath;?></strong>
<code><?php echo $filePath?></code>
<?php endif?>
</div>
</div>
<form method='post' target='hiddenwin' action='<?php echo inlink('save', "filePath=$safeFilePath&action=$action")?>'>
<div class='main-content'>
<table class='table table-form'>
<?php if(!empty($showContent)):?>
<tr>
<td>
<?php echo "<span class='strong'>" . $lang->editor->sourceFile . '</span>'?><br />
<textarea id='showContent' class="form-control"> <?php echo $showContent?></textarea>
</td>
</tr>
<?php endif?>
<tr>
<td><?php echo html::textarea('fileContent', str_replace('&', '&amp;', $fileContent), "class='form-control'")?></td>
</tr>
<tr>
<td>
<?php if($action and $action != 'edit' and $action != 'newPage' and $action != 'override' and $action != 'extendControl'):?>
<div class='form-group'>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->editor->fileName;?></span>
<?php echo html::input('fileName', '', "class='form-control'");?>
<span class='input-group-addon'>
<?php
if($action == 'newHook')
{
echo $lang->editor->exampleHook;
}
elseif($action and $action == 'extendOther' and strpos(basename($filePath), '.js') !== false or $action == 'newJS')
{
echo $lang->editor->exampleJs;
}
elseif($action and $action == 'extendOther' and strpos(basename($filePath), '.css') !== false or $action == 'newCSS')
{
echo $lang->editor->exampleCss;
}
else
{
echo $lang->editor->examplePHP;
}
?>
</span>
</div>
</div>
<?php endif;?>
<?php if($action and $action != 'edit' and $action != 'newPage'):?>
<div class='checkbox-primary'>
<input type='checkbox' name='override' id='override' />
<label for='override'><?php echo $lang->editor->isOverride?></span>
</div>
<?php endif;?>
</td>
</tr>
<tr><td align='center'><?php echo html::submitButton()?></td></tr>
</table>
</div>
</form>
<?php include '../../common/view/footer.lite.html.php';?>
-42
View File
@@ -1,42 +0,0 @@
<?php
/**
* The editor view file of dir module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package editor
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<div class='main-header'>
<div class='heading'><i class='icon-list-ul'></i> <strong><?php echo isset($lang->editor->modules[$module])? $lang->editor->modules[$module] : $module;?></strong></div>
</div>
<div class='main-content'>
<?php echo $tree?>
</div>
<script>
$(function()
{
$('.hitarea').click(function()
{
var $this = $(this);
var parent = $this.parent();
if(parent.hasClass('expandable'))
{
parent.removeClass('expandable').addClass('collapsable');
$this.removeClass('expandable-hitarea').addClass('collapsable-hitarea');
}
else
{
parent.addClass('expandable').removeClass('collapsable');
$this.addClass('expandable-hitarea').removeClass('collapsable-hitarea');
}
});
});
</script>
<iframe frameborder='0' name='hiddenwin' id='hiddenwin' scrolling='no' class='hidden'></iframe>
<body>
</html>
-49
View File
@@ -1,49 +0,0 @@
<?php
/**
* The editor view file of dir module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package editor
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../dev/view/header.html.php';?>
<div id='mainContent' class='main-row'>
<div class='side-col' id='sidebar'>
<div class='cell'>
<div class='panel panel-sm with-list'>
<div class='panel-heading'><i class='icon-list'></i> <strong><?php echo $lang->editor->moduleList?></strong></div>
<?php foreach($lang->dev->groupList as $group => $groupName):?>
<?php if(!empty($modules[$group])):?>
<div class='modulegroup'><?php echo $groupName?></div>
<?php foreach($modules[$group] as $module):?>
<?php $moduleName = zget($lang->dev->tableList, $module, $module);?>
<?php echo html::a(inlink('extend', "moduleDir=$module"), $moduleName, 'extendWin');?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
<?php foreach($lang->dev->endGroupList as $group => $groupName):?>
<?php if(!empty($modules[$group])):?>
<div class='modulegroup'><?php echo $groupName?></div>
<?php foreach($modules[$group] as $module):?>
<?php $moduleName = zget($lang->dev->tableList, $module, $module);?>
<?php echo html::a(inlink('extend', "moduleDir=$module"), $moduleName, 'extendWin');?>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
</div>
</div>
</div>
<div class='side-col w-350px'>
<div class='cell'>
<iframe frameborder='0' name='extendWin' id='extendWin' width='100%'></iframe>
</div>
</div>
<div class='main-col main-content'>
<iframe frameborder='0' name='editWin' id='editWin' width='100%'></iframe>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
-37
View File
@@ -1,37 +0,0 @@
<?php
/**
* The editor view file of dir module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package editor
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<style>body{padding-bottom:0px;background-color:#fff;}</style>
<div class='main-header'>
<div class='heading'><i class='icon-plus'></i> <strong><?php echo $lang->editor->newPage?></strong></div>
</div>
<form method='post' target='hiddenwin'>
<div class='main-content'>
<table class='table table-form'>
<tr>
<th class='w-80px'><?php echo $lang->editor->filePath?></th>
<td><code><?php echo $filePath?></code></td>
</tr>
<tr>
<th><?php echo $lang->editor->pageName?></th>
<td>
<?php
echo html::input('fileName', '', "class='form-control' placeholder='{$lang->editor->examplePHP}'");
?>
</td>
</tr>
<tr><td colspan='2' align='center'><?php echo html::submitButton()?></td></tr>
</table>
</div>
</form>
<?php include '../../common/view/footer.lite.html.php';?>
-22
View File
@@ -9,28 +9,6 @@ $config->file->image2Compress = array('.jpg', '.bmp', '.jpeg');
$config->file->charset = array('UTF-8' => 'UTF-8', 'GBK' => 'GBK', 'BIG5' => 'BIG5');
$config->file->ueditor["imageActionName"] = "uploadimage";
$config->file->ueditor["imageFieldName"] = "upfile";
$config->file->ueditor["imageMaxSize"] = 2048000;
$config->file->ueditor["imageAllowFiles"] = array(".png", ".jpg", ".jpeg", ".gif", ".bmp");
$config->file->ueditor["imageCompressEnable"] = true;
$config->file->ueditor["imageCompressBorder"] = 1600;
$config->file->ueditor["imageInsertAlign"] = "none";
$config->file->ueditor["imageUrlPrefix"] = "";
$config->file->ueditor["imagePathFormat"] = "";
$config->file->ueditor["snapscreenActionName"] = "uploadimage";
$config->file->ueditor["snapscreenInsertAlign"] = "none";
$config->file->ueditor["snapscreenUrlPrefix"] = "";
$config->file->ueditor["snapscreenPathFormat"] = "";
$config->file->ueditor["videoActionName"] = "uploadvideo";
$config->file->ueditor["videoFieldName"] = "upfile";
$config->file->ueditor["videoMaxSize"] = 102400000;
$config->file->ueditor["videoAllowFiles"] = array(".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg", ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid");
$config->file->ueditor["videoUrlPrefix"] = "";
$config->file->ueditor["videoPathFormat"] = "";
$config->file->objectType['stepResult'] = 'testcase';
$config->file->convertURL['common']['view'] = '1';
+1 -42
View File
@@ -102,47 +102,6 @@ class file extends control
die(json_encode(array('status' => 'error', 'message' => $this->lang->file->uploadImagesExplain)));
}
/**
* AJAX: get upload request from the web editor.
*
* @access public
* @return void
*/
public function ajaxUeditorUpload($uid = '')
{
if($this->get->action == 'config')
{
die(json_encode($this->config->file->ueditor));
}
$file = $this->file->getUpload('upfile');
$file = $file[0];
if($file)
{
if($file['size'] == 0) die(json_encode(array('state' => $this->lang->file->errorFileUpload)));
if(@move_uploaded_file($file['tmpname'], $this->file->savePath . $this->file->getSaveName($file['pathname'])))
{
/* Compress image for jpg and bmp. */
$file = $this->file->compressImage($file);
$file['addedBy'] = $this->app->user->account;
$file['addedDate'] = helper::today();
unset($file['tmpname']);
$this->dao->insert(TABLE_FILE)->data($file)->exec();
$fileID = $this->dao->lastInsertID();
$url = $this->createLink('file', 'read', "fileID=$fileID", $file['extension']);
if($uid) $_SESSION['album'][$uid][] = $fileID;
die(json_encode(array('state' => 'SUCCESS', 'url' => $url)));
}
else
{
$error = strip_tags(sprintf($this->lang->file->errorCanNotWrite, $this->file->savePath, $this->file->savePath));
die(json_encode(array('state' => $error)));
}
}
}
/**
* Down a file.
*
@@ -395,7 +354,7 @@ class file extends control
$imageFiles = $this->session->$sessionName;
$this->session->set($module . 'ImagesFile', $imageFiles);
unset($_SESSION[$sessionName]);
die(js::locate($this->createLink($module, 'batchCreate', helper::safe64Decode($params)), 'parent.parent'));
die(js::locate($this->createLink($module, 'batchCreate', helper::safe64Decode($params)), 'parent'));
}
if($_FILES)
+6 -39
View File
@@ -43,7 +43,6 @@ $lang->moduleOrder[110] = 'user';
$lang->moduleOrder[115] = 'admin';
$lang->moduleOrder[120] = 'extension';
$lang->moduleOrder[125] = 'custom';
$lang->moduleOrder[130] = 'editor';
$lang->moduleOrder[140] = 'action';
$lang->moduleOrder[145] = 'mail';
@@ -1039,48 +1038,16 @@ $lang->cron->methodOrder[25] = 'toggle';
$lang->cron->methodOrder[30] = 'delete';
$lang->cron->methodOrder[35] = 'openProcess';
$lang->resource->translate = new stdclass();
$lang->resource->translate->index = 'index';
$lang->resource->translate->addLang = 'addLang';
$lang->resource->translate->chooseModule = 'chooseModule';
$lang->resource->translate->module = 'module';
$lang->resource->translate->review = 'reviewAction';
$lang->resource->translate->result = 'result';
$lang->resource->translate->batchPass = 'batchPass';
$lang->resource->translate->setting = 'setting';
$lang->resource->translate->export = 'export';
$lang->translate->methodOrder[5] = 'index';
$lang->translate->methodOrder[10] = 'addLang';
$lang->translate->methodOrder[15] = 'chooseModule';
$lang->translate->methodOrder[20] = 'module';
$lang->translate->methodOrder[25] = 'review';
$lang->translate->methodOrder[30] = 'result';
$lang->translate->methodOrder[35] = 'batchPass';
$lang->translate->methodOrder[40] = 'setting';
$lang->translate->methodOrder[45] = 'export';
$lang->resource->dev = new stdclass();
$lang->resource->dev->api = 'api';
$lang->resource->dev->db = 'db';
$lang->resource->dev->api = 'api';
$lang->resource->dev->db = 'db';
$lang->resource->dev->editor = 'editor';
$lang->resource->dev->translate = 'translate';
$lang->dev->methodOrder[5] = 'api';
$lang->dev->methodOrder[10] = 'db';
$lang->resource->editor = new stdclass();
$lang->resource->editor->index = 'index';
$lang->resource->editor->extend = 'extend';
$lang->resource->editor->edit = 'edit';
$lang->resource->editor->newPage = 'newPage';
$lang->resource->editor->save = 'save';
$lang->resource->editor->delete = 'delete';
$lang->editor->methodOrder[5] = 'index';
$lang->editor->methodOrder[10] = 'extend';
$lang->editor->methodOrder[15] = 'edit';
$lang->editor->methodOrder[20] = 'newPage';
$lang->editor->methodOrder[25] = 'save';
$lang->editor->methodOrder[30] = 'delete';
$lang->dev->methodOrder[15] = 'editor';
$lang->dev->methodOrder[20] = 'translate';
/* Every version of new privilege. */
$lang->changelog['1.0.1'][] = 'project-computeBurn';
+20
View File
@@ -290,6 +290,26 @@ class groupModel extends model
}
$actions['actions'] = $dynamic;
/* If not select any projects or products, set it empty. */
if(isset($actions['products']))
{
$isEmpty = true;
foreach($actions['products'] as $productID)
{
if(!empty($productID)) $isEmpty = false;
}
if($isEmpty) unset($actions['products']);
}
if(isset($actions['projects']))
{
$isEmpty = true;
foreach($actions['projects'] as $projectID)
{
if(!empty($projectID)) $isEmpty = false;
}
if($isEmpty) unset($actions['projects']);
}
$actions = empty($actions) ? '' : json_encode($actions);
$this->dao->update(TABLE_GROUP)->set('acl')->eq($actions)->where('id')->eq($groupID)->exec();
return dao::isError() ? false : true;
+1 -1
View File
@@ -109,7 +109,7 @@ $lang->install->requestTypes['PATH_INFO'] = '静态友好方式';
$lang->install->workingList['full'] = '完整研发管理工具';
$lang->install->workingList['onlyTest'] = '测试管理工具';
$lang->install->workingList['onlyStory'] = '需求管理工具';
$lang->install->workingList['onlyStory'] = "{$lang->storyCommon}管理工具";
$lang->install->workingList['onlyTask'] = '任务管理工具';
$lang->install->errorConnectDB = '数据库连接失败 ';
+2
View File
@@ -83,6 +83,7 @@ $lang->misc->feature = new stdclass();
$lang->misc->feature->lastest = 'Letzte Version';
$lang->misc->feature->detailed = 'Details';
$lang->misc->releaseDate['11.6.5'] = '2019-11-08';
$lang->misc->releaseDate['11.6.4'] = '2019-10-17';
$lang->misc->releaseDate['11.6.3'] = '2019-09-24';
$lang->misc->releaseDate['11.6.2'] = '2019-09-06';
@@ -117,6 +118,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['11.6.5'][] = array('title'=>'Fix bug.', 'desc' => '');
$lang->misc->feature->all['11.6.4'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
$lang->misc->feature->all['11.6.3'][] = array('title'=>'Fix bug.', 'desc' => '');
$lang->misc->feature->all['11.6.2'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
+2
View File
@@ -83,6 +83,7 @@ $lang->misc->feature = new stdclass();
$lang->misc->feature->lastest = 'Latest Version';
$lang->misc->feature->detailed = 'Detail';
$lang->misc->releaseDate['11.6.5'] = '2019-11-08';
$lang->misc->releaseDate['11.6.4'] = '2019-10-17';
$lang->misc->releaseDate['11.6.3'] = '2019-09-24';
$lang->misc->releaseDate['11.6.2'] = '2019-09-06';
@@ -117,6 +118,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['11.6.5'][] = array('title'=>'Fix bug.', 'desc' => '');
$lang->misc->feature->all['11.6.4'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
$lang->misc->feature->all['11.6.3'][] = array('title'=>'Fix bug.', 'desc' => '');
$lang->misc->feature->all['11.6.2'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
+2
View File
@@ -83,6 +83,7 @@ $lang->misc->feature = new stdclass();
$lang->misc->feature->lastest = 'Dernière Version';
$lang->misc->feature->detailed = 'Détail';
$lang->misc->releaseDate['11.6.5'] = '2019-11-08';
$lang->misc->releaseDate['11.6.4'] = '2019-10-17';
$lang->misc->releaseDate['11.6.3'] = '2019-09-24';
$lang->misc->releaseDate['11.6.2'] = '2019-09-06';
@@ -117,6 +118,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['11.6.5'][] = array('title'=>'Fix bug.', 'desc' => '');
$lang->misc->feature->all['11.6.4'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
$lang->misc->feature->all['11.6.3'][] = array('title'=>'Fix bug.', 'desc' => '');
$lang->misc->feature->all['11.6.2'][] = array('title'=>'Optimize details and fix bug.', 'desc' => '');
+8 -6
View File
@@ -83,6 +83,7 @@ $lang->misc->feature = new stdclass();
$lang->misc->feature->lastest = '最新版本';
$lang->misc->feature->detailed = '详情';
$lang->misc->releaseDate['11.6.5'] = '2019-11-08';
$lang->misc->releaseDate['11.6.4'] = '2019-10-17';
$lang->misc->releaseDate['11.6.3'] = '2019-09-24';
$lang->misc->releaseDate['11.6.2'] = '2019-09-06';
@@ -117,6 +118,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['11.6.5'][] = array('title'=>'修复Bug', 'desc' => '');
$lang->misc->feature->all['11.6.4'][] = array('title'=>'完善细节,修复Bug', 'desc' => '');
$lang->misc->feature->all['11.6.3'][] = array('title'=>'修复Bug', 'desc' => '');
$lang->misc->feature->all['11.6.2'][] = array('title'=>'完善细节,修复Bug', 'desc' => '');
@@ -134,7 +136,7 @@ $lang->misc->feature->all['11.5.stable'][] = array('title'=>'集成新版本客
$lang->misc->feature->all['11.4.1'][] = array('title'=>'完善细节,修复Bug', 'desc' => '');
$lang->misc->feature->all['11.4.stable'][] = array('title'=>'完善细节,修复Bug', 'desc' => '<p>增强测试任务管理</p><p>优化计划、发布、版本关联需求和bug的交互</p><p>文档库可以自定义是否显示子分类里的文档</p><p>修复bug,完善细节</p>');
$lang->misc->feature->all['11.4.stable'][] = array('title'=>'完善细节,修复Bug', 'desc' => '<p>增强测试任务管理</p><p>优化计划、发布、版本关联{$lang->storyCommon}和bug的交互</p><p>文档库可以自定义是否显示子分类里的文档</p><p>修复bug,完善细节</p>');
$lang->misc->feature->all['11.3.stable'][] = array('title'=>'完善细节,修复Bug', 'desc' => '<p>计划添加子计划功能</p><p>优化chosen交互</p><p>添加时区设置</p><p>优化文档库和文档</p>');
@@ -186,14 +188,14 @@ $lang->misc->feature->all['8.3.stable'][] = array('title'=>'调整文档功能',
$lang->misc->feature->all['8.2.stable'][] = array('title'=>'首页自定义', 'desc' => '<p>我的地盘由我做主。现在开始,你可以向首页添加多种多样的内容区块,而且还可以决定如何排列和显示他们。</p><p>我的地盘、产品、项目、测试模块下均支持首页自定义功能。</p>');
$lang->misc->feature->all['8.2.stable'][] = array('title'=>'导航定制', 'desc' => '<p>导航上显示的项目现在完全由你来决定,不仅仅可以决定在导航上展示哪些内容,还可以决定展示的顺序。</p><p>将鼠标悬浮在导航上稍后会在右侧显示定制按钮,点击打开定制对话框,通过点击切换是否显示,拖放操作来更改显示顺序。</p>');
$lang->misc->feature->all['8.2.stable'][] = array('title'=>'批量添加、编辑自定义', 'desc' => '<p>可以在批量添加和批量编辑页面自定义操作的字段。</p>');
$lang->misc->feature->all['8.2.stable'][] = array('title'=>'添加需求、任务、Bug、用例自定义', 'desc' => '<p>可以在添加需求、任务、Bug、用例页面,自定义部分字段是否显示。</p>');
$lang->misc->feature->all['8.2.stable'][] = array('title'=>'导出自定义', 'desc' => '<p>在导出需求、任务、Bug、用例的时候,用户可以自定义导出的字段,也可以保存模板方便每次导出。</p>');
$lang->misc->feature->all['8.2.stable'][] = array('title'=>'需求、任务、Bug、用例组合检索功能', 'desc' => '<p>在需求、任务、Bug、用例列表页面,可以实现模块和标签的组合检索。</p>');
$lang->misc->feature->all['8.2.stable'][] = array('title'=>'添加{$lang->storyCommon}、任务、Bug、用例自定义', 'desc' => '<p>可以在添加{$lang->storyCommon}、任务、Bug、用例页面,自定义部分字段是否显示。</p>');
$lang->misc->feature->all['8.2.stable'][] = array('title'=>'导出自定义', 'desc' => '<p>在导出{$lang->storyCommon}、任务、Bug、用例的时候,用户可以自定义导出的字段,也可以保存模板方便每次导出。</p>');
$lang->misc->feature->all['8.2.stable'][] = array('title'=>'{$lang->storyCommon}、任务、Bug、用例组合检索功能', 'desc' => '<p>在{$lang->storyCommon}、任务、Bug、用例列表页面,可以实现模块和标签的组合检索。</p>');
$lang->misc->feature->all['8.2.stable'][] = array('title'=>'增加新手教程', 'desc' => '<p>增加新手教程,方便新用户了解禅道使用。</p>');
$lang->misc->feature->all['7.4.beta'][] = array('title'=>'产品实现分支功能', 'desc' => '<p>产品增加分支/平台类型,相应的需求、计划、Bug、用例、模块等都增加分支。</p>');
$lang->misc->feature->all['7.4.beta'][] = array('title'=>'产品实现分支功能', 'desc' => '<p>产品增加分支/平台类型,相应的{$lang->storyCommon}、计划、Bug、用例、模块等都增加分支。</p>');
$lang->misc->feature->all['7.4.beta'][] = array('title'=>'调整发布模块', 'desc' => '<p>发布增加停止维护操作,当发布停止维护时,创建Bug将不显示这个发布。</p><p>发布中遗留的bug改为手工关联。</p>');
$lang->misc->feature->all['7.4.beta'][] = array('title'=>'调整需求和Bug的创建页面', 'desc' => '');
$lang->misc->feature->all['7.4.beta'][] = array('title'=>'调整{$lang->storyCommon}和Bug的创建页面', 'desc' => '');
$lang->misc->feature->all['7.2.stable'][] = array('title'=>'增强安全', 'desc' => '<p>加强对管理员弱口令的检查。</p><p>写插件,上传插件的时候需要创建ok文件。</p><p>敏感操作增加管理员口令的检查</p><p>对输入内容做striptags, specialchars处理。</p>');
$lang->misc->feature->all['7.2.stable'][] = array('title'=>'完善细节', 'desc' => '');
+2
View File
@@ -83,6 +83,7 @@ $lang->misc->feature = new stdclass();
$lang->misc->feature->lastest = '最新版本';
$lang->misc->feature->detailed = '詳情';
$lang->misc->releaseDate['11.6.5'] = '2019-11-08';
$lang->misc->releaseDate['11.6.4'] = '2019-10-17';
$lang->misc->releaseDate['11.6.3'] = '2019-09-24';
$lang->misc->releaseDate['11.6.2'] = '2019-09-06';
@@ -117,6 +118,7 @@ $lang->misc->releaseDate['7.2.stable'] = '2015-05-22';
$lang->misc->releaseDate['7.1.stable'] = '2015-03-07';
$lang->misc->releaseDate['6.3.stable'] = '2014-11-07';
$lang->misc->feature->all['11.6.5'][] = array('title'=>'修復Bug', 'desc' => '');
$lang->misc->feature->all['11.6.4'][] = array('title'=>'完善細節,修復Bug', 'desc' => '');
$lang->misc->feature->all['11.6.3'][] = array('title'=>'修復Bug', 'desc' => '');
$lang->misc->feature->all['11.6.2'][] = array('title'=>'完善細節,修復Bug', 'desc' => '');
+1 -1
View File
@@ -17,4 +17,4 @@
.dynamic.active .dynamic-date:before {background-color: #00a9fc;}
.dynamic.collapsed .timeline {max-height: 58px;}
.dynamic.collapsed .timeline > li + li {display: none;}
.dynamic.collapsed .dynamic-btn > .icon:before {content: '\f0d7'; }
.dynamic.collapsed .dynamic-btn > .icon:before {content: '\f0d8'; }
+8 -2
View File
@@ -10,8 +10,14 @@ $(document).ready(function()
$('#submit').click(function()
{
var password = $('input#originalPassword').val();
var rand = $('input#verifyRand').val();
var password = $('input#originalPassword').val();
var password1 = $('input#password1').val();
var passwordStrength = computePasswordStrength(password1);
var rand = $('input#verifyRand').val();
if($("form input[name=passwordStrength]").length == 0) $('#submit').after("<input type='hidden' name='passwordStrength' value='0' />");
$("form input[name=passwordStrength]").val(passwordStrength);
if(!originalEncrypted && password) $('input#originalPassword').val(md5(md5(password) + rand));
originalEncrypted = true;
+8 -2
View File
@@ -8,9 +8,15 @@ $(document).ready(function()
$('#password1').change(function(){password1Encrypted = false});
$('#password2').change(function(){password2Encrypted = false});
$('#dataform').submit(function()
$('#submit').click(function()
{
var password = $('input#verifyPassword').val();
var password = $('input#verifyPassword').val();
var password1 = $('input#password1').val();
var passwordStrength = computePasswordStrength(password1);
if($("form input[name=passwordStrength]").length == 0) $('#submit').after("<input type='hidden' name='passwordStrength' value='0' />");
$("form input[name=passwordStrength]").val(passwordStrength);
var rand = $('input#verifyRand').val();
if(!verifyEncrypted && password) $('input#verifyPassword').val(md5(md5(password) + rand));
verifyEncrypted = true;
+1 -1
View File
@@ -9,7 +9,7 @@ $lang->my->task = '我的任务';
$lang->my->bug = '我的Bug';
$lang->my->testTask = '我的版本';
$lang->my->testCase = '我的用例';
$lang->my->story = '我的需求';
$lang->my->story = "我的{$lang->storyCommon}";
$lang->my->myProject = "我的{$lang->projectCommon}";
$lang->my->profile = '我的档案';
$lang->my->dynamic = '我的动态';
+3 -2
View File
@@ -43,7 +43,7 @@
<span class="date-label"><?php echo $lang->action->dynamic->today;?></span>
<?php endif;?>
<span class="date-text"><?php echo $date;?></span>
<button type="button" class="btn btn-info btn-icon btn-sm dynamic-btn"><i class="icon icon-caret-up"></i></button>
<button type="button" class="btn btn-info btn-icon btn-sm dynamic-btn"><i class="icon icon-caret-down"></i></button>
</div>
<ul class="timeline timeline-tag-left">
<?php if($direction == 'next') $actions = array_reverse($actions);?>
@@ -53,7 +53,8 @@
<div>
<span class="timeline-tag"><?php echo $action->time?></span>
<span class="timeline-text">
<?php echo $app->user->realname . ' ' . $action->actionLabel;?>
<?php echo $app->user->realname;?>
<span class='label-action'><?php echo ' ' . $action->actionLabel;?></span>
<?php if($action->action != 'login' and $action->action != 'logout'):?>
<span class="text-muted"><?php echo $action->objectLabel;?></span>
<?php echo html::a($action->objectLink, $action->objectName);?>

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