Conflicts:
	module/project/css/tree.css
	module/project/lang/en.php
	module/project/view/tree.html.php
This commit is contained in:
Catouse
2017-02-03 15:45:42 +08:00
512 changed files with 38497 additions and 6204 deletions
+2
View File
@@ -2,6 +2,7 @@ config/my.php
www/data/
www/install.php
www/upgrade.php
www/ok.txt
tools/*
release/*
tmp/*
@@ -11,3 +12,4 @@ tmp/model/*
tmp/cache/*
tmp/extension/*
.gitkeep
.bak
+2
View File
@@ -22,6 +22,8 @@ pms:
cp -fr module zentaopms/
cp -fr www zentaopms && rm -fr zentaopms/www/data/ && mkdir -p zentaopms/www/data/upload
cp -fr tmp zentaopms
mv zentaopms/www/install.php.tmp zentaopms/www/install.php
mv zentaopms/www/upgrade.php.tmp zentaopms/www/upgrade.php
rm -fr zentaopms/tmp/cache/*
rm -fr zentaopms/tmp/extension/*
rm -fr zentaopms/tmp/log/*
+1 -1
View File
@@ -1 +1 @@
8.3.1
9.0.stable
+4 -2
View File
@@ -27,8 +27,8 @@ include './framework/router.class.php';
include './framework/control.class.php';
include './framework/model.class.php';
include './framework/helper.class.php';
include './config/config.php';
include realpath('./config/config.php');
/* Set the PATH_INFO variable. */
if($config->requestType == 'PATH_INFO')
{
@@ -52,6 +52,8 @@ if($config->requestType == 'PATH_INFO')
$_SERVER['PATH_INFO'] = '/';
}
}
$_SERVER['REQUEST_URI'] = $_SERVER['PATH_INFO'];
}
else
{
+3 -2
View File
@@ -17,7 +17,7 @@ if(!function_exists('getWebRoot')){function getWebRoot(){}}
/* Basic settings. */
$config = new config();
$config->version = '8.3.1'; // The version of zentaopms. Don't change it.
$config->version = '9.0'; // The version of zentaopms. Don't change it.
$config->charset = 'UTF-8'; // The charset of zentaopms.
$config->cookieLife = time() + 2592000; // The cookie life time.
$config->timezone = 'Asia/Shanghai'; // The time zone setting, for more see http://www.php.net/manual/en/timezones.php
@@ -31,7 +31,7 @@ $config->requestFix = '-'; // The divider in the url when PATH_IN
$config->moduleVar = 'm'; // requestType=GET: the module var name.
$config->methodVar = 'f'; // requestType=GET: the method var name.
$config->viewVar = 't'; // requestType=GET: the view var name.
$config->sessionVar = 'sid'; // requestType=GET: the session var name.
$config->sessionVar = 'zentaosid'; // requestType=GET: the session var name.
$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>';
$config->accountRule = '|^[a-zA-Z0-9_]{1}[a-zA-Z0-9_\.]{1,}[a-zA-Z0-9_]{1}$|';
@@ -189,6 +189,7 @@ $config->objectTables['doclib'] = TABLE_DOCLIB;
$config->objectTables['todo'] = TABLE_TODO;
$config->objectTables['custom'] = TABLE_LANG;
$config->objectTables['branch'] = TABLE_BRANCH;
$config->objectTables['module'] = TABLE_MODULE;
/* Include extension config files. */
$extConfigFiles = glob($configRoot . 'ext/*.php');
+2
View File
@@ -0,0 +1,2 @@
ALTER TABLE `zt_branch` ADD `order` smallint unsigned NOT NULL AFTER `name`;
ALTER TABLE `zt_module` ADD `deleted` enum('0','1') COLLATE 'utf8_general_ci' NOT NULL DEFAULT '0';
+1
View File
@@ -0,0 +1 @@
ALTER TABLE `zt_file` CHANGE `size` `size` int unsigned NOT NULL DEFAULT '0' AFTER `extension`;
+1
View File
@@ -0,0 +1 @@
ALTER TABLE `zt_burn` ADD `estimate` float NOT NULL AFTER `date`;
+40 -1
View File
@@ -35,6 +35,7 @@ CREATE TABLE IF NOT EXISTS `zt_branch` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`order` smallint unsigned NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product` (`product`)
@@ -112,6 +113,7 @@ CREATE TABLE IF NOT EXISTS `zt_build` (
CREATE TABLE IF NOT EXISTS `zt_burn` (
`project` mediumint(8) unsigned NOT NULL,
`date` date NOT NULL,
`estimate` float NOT NULL,
`left` float NOT NULL,
`consumed` float NOT NULL,
PRIMARY KEY (`project`,`date`)
@@ -325,7 +327,7 @@ CREATE TABLE IF NOT EXISTS `zt_file` (
`pathname` char(50) NOT NULL,
`title` char(90) NOT NULL,
`extension` char(30) NOT NULL,
`size` mediumint(8) unsigned NOT NULL default '0',
`size` int(10) unsigned NOT NULL default '0',
`objectType` char(30) NOT NULL,
`objectID` mediumint(9) NOT NULL,
`addedBy` char(30) NOT NULL default '',
@@ -391,6 +393,7 @@ CREATE TABLE IF NOT EXISTS `zt_module` (
`type` char(30) NOT NULL,
`owner` varchar(30) NOT NULL,
`short` varchar(30) NOT NULL,
`deleted` enum('0','1') NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `module` (`root`,`type`,`path`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@@ -901,6 +904,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(1, 'mail', 'batchDelete'),
(1, 'mail', 'browse'),
(1, 'mail', 'delete'),
(1, 'mail', 'resend'),
(1, 'mail', 'detect'),
(1, 'mail', 'edit'),
(1, 'mail', 'index'),
@@ -939,6 +943,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(1, 'product', 'view'),
(1, 'product', 'updateOrder'),
(1, 'branch', 'manage'),
(1, 'branch', 'sort'),
(1, 'branch', 'delete'),
(1, 'productplan', 'batchUnlinkBug'),
(1, 'productplan', 'batchUnlinkStory'),
@@ -1034,6 +1039,8 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(1, 'story', 'report'),
(1, 'story', 'review'),
(1, 'story', 'tasks'),
(1, 'story', 'bugs'),
(1, 'story', 'cases'),
(1, 'story', 'view'),
(1, 'story', 'zeroCase'),
(1, 'svn', 'apiSync'),
@@ -1066,6 +1073,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(1, 'testcase', 'batchDelete'),
(1, 'testcase', 'batchEdit'),
(1, 'testcase', 'browse'),
(1, 'testcase', 'bugs'),
(1, 'testcase', 'confirmChange'),
(1, 'testcase', 'confirmStoryChange'),
(1, 'testcase', 'create'),
@@ -1245,6 +1253,8 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(2, 'story', 'export'),
(2, 'story', 'report'),
(2, 'story', 'tasks'),
(2, 'story', 'bugs'),
(2, 'story', 'cases'),
(2, 'story', 'view'),
(2, 'svn', 'apiSync'),
(2, 'svn', 'cat'),
@@ -1272,6 +1282,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(2, 'task', 'start'),
(2, 'task', 'view'),
(2, 'testcase', 'browse'),
(2, 'testcase', 'bugs'),
(2, 'testcase', 'export'),
(2, 'testcase', 'groupCase'),
(2, 'testcase', 'index'),
@@ -1417,6 +1428,8 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(3, 'story', 'export'),
(3, 'story', 'report'),
(3, 'story', 'tasks'),
(3, 'story', 'bugs'),
(3, 'story', 'cases'),
(3, 'story', 'view'),
(3, 'story', 'zeroCase'),
(3, 'svn', 'apiSync'),
@@ -1447,6 +1460,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(3, 'testcase', 'batchCreate'),
(3, 'testcase', 'batchEdit'),
(3, 'testcase', 'browse'),
(3, 'testcase', 'bugs'),
(3, 'testcase', 'confirmChange'),
(3, 'testcase', 'confirmStoryChange'),
(3, 'testcase', 'create'),
@@ -1650,6 +1664,8 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(4, 'story', 'export'),
(4, 'story', 'report'),
(4, 'story', 'tasks'),
(4, 'story', 'bugs'),
(4, 'story', 'cases'),
(4, 'story', 'view'),
(4, 'story', 'zeroCase'),
(4, 'svn', 'apiSync'),
@@ -1679,6 +1695,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(4, 'task', 'start'),
(4, 'task', 'view'),
(4, 'testcase', 'browse'),
(4, 'testcase', 'bugs'),
(4, 'testcase', 'createBug'),
(4, 'testcase', 'export'),
(4, 'testcase', 'groupCase'),
@@ -1814,6 +1831,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(5, 'product', 'view'),
(5, 'product', 'updateOrder'),
(5, 'branch', 'manage'),
(5, 'branch', 'sort'),
(5, 'branch', 'delete'),
(5, 'productplan', 'batchUnlinkBug'),
(5, 'productplan', 'batchUnlinkStory'),
@@ -1908,6 +1926,8 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(5, 'story', 'report'),
(5, 'story', 'review'),
(5, 'story', 'tasks'),
(5, 'story', 'bugs'),
(5, 'story', 'cases'),
(5, 'story', 'view'),
(5, 'story', 'zeroCase'),
(5, 'svn', 'apiSync'),
@@ -1921,6 +1941,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(5, 'task', 'report'),
(5, 'task', 'view'),
(5, 'testcase', 'browse'),
(5, 'testcase', 'bugs'),
(5, 'testcase', 'createBug'),
(5, 'testcase', 'export'),
(5, 'testcase', 'groupCase'),
@@ -2112,6 +2133,8 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(6, 'story', 'export'),
(6, 'story', 'report'),
(6, 'story', 'tasks'),
(6, 'story', 'bugs'),
(6, 'story', 'cases'),
(6, 'story', 'view'),
(6, 'story', 'zeroCase'),
(6, 'svn', 'apiSync'),
@@ -2141,6 +2164,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(6, 'task', 'start'),
(6, 'task', 'view'),
(6, 'testcase', 'browse'),
(6, 'testcase', 'bugs'),
(6, 'testcase', 'export'),
(6, 'testcase', 'groupCase'),
(6, 'testcase', 'index'),
@@ -2274,6 +2298,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(7, 'product', 'view'),
(7, 'product', 'updateOrder'),
(7, 'branch', 'manage'),
(7, 'branch', 'sort'),
(7, 'branch', 'delete'),
(7, 'productplan', 'batchUnlinkBug'),
(7, 'productplan', 'batchUnlinkStory'),
@@ -2352,6 +2377,8 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(7, 'story', 'report'),
(7, 'story', 'review'),
(7, 'story', 'tasks'),
(7, 'story', 'bugs'),
(7, 'story', 'cases'),
(7, 'story', 'view'),
(7, 'story', 'zeroCase'),
(7, 'svn', 'apiSync'),
@@ -2365,6 +2392,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(7, 'task', 'report'),
(7, 'task', 'view'),
(7, 'testcase', 'browse'),
(7, 'testcase', 'bugs'),
(7, 'testcase', 'createBug'),
(7, 'testcase', 'export'),
(7, 'testcase', 'groupCase'),
@@ -2531,6 +2559,8 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(8, 'story', 'export'),
(8, 'story', 'report'),
(8, 'story', 'tasks'),
(8, 'story', 'bugs'),
(8, 'story', 'cases'),
(8, 'story', 'view'),
(8, 'story', 'zeroCase'),
(8, 'svn', 'apiSync'),
@@ -2563,6 +2593,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(8, 'testcase', 'batchDelete'),
(8, 'testcase', 'batchEdit'),
(8, 'testcase', 'browse'),
(8, 'testcase', 'bugs'),
(8, 'testcase', 'confirmChange'),
(8, 'testcase', 'confirmStoryChange'),
(8, 'testcase', 'create'),
@@ -2732,6 +2763,8 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(9, 'story', 'report'),
(9, 'story', 'review'),
(9, 'story', 'tasks'),
(9, 'story', 'bugs'),
(9, 'story', 'cases'),
(9, 'story', 'view'),
(9, 'story', 'zeroCase'),
(9, 'svn', 'apiSync'),
@@ -2744,6 +2777,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(9, 'task', 'report'),
(9, 'task', 'view'),
(9, 'testcase', 'browse'),
(9, 'testcase', 'bugs'),
(9, 'testcase', 'export'),
(9, 'testcase', 'groupCase'),
(9, 'testcase', 'index'),
@@ -2857,6 +2891,8 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(10, 'search', 'deleteQuery'),
(10, 'search', 'saveQuery'),
(10, 'story', 'tasks'),
(10, 'story', 'bugs'),
(10, 'story', 'cases'),
(10, 'story', 'view'),
(10, 'task', 'deleteEstimate'),
(10, 'task', 'editEstimate'),
@@ -2941,12 +2977,15 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(11, 'search', 'buildForm'),
(11, 'search', 'buildQuery'),
(11, 'story', 'tasks'),
(11, 'story', 'bugs'),
(11, 'story', 'cases'),
(11, 'story', 'view'),
(11, 'svn', 'cat'),
(11, 'svn', 'diff'),
(11, 'task', 'recordEstimate'),
(11, 'task', 'view'),
(11, 'testcase', 'browse'),
(11, 'testcase', 'bugs'),
(11, 'testcase', 'groupCase'),
(11, 'testcase', 'index'),
(11, 'testcase', 'view'),
+489 -217
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -18,7 +18,7 @@ Z PUBLIC LICENSE 由青岛易软天创网络科技有限公司(www.cnezsoft.co
电话: 4006-8899-23
Email: co@cnezsoft.com
QQ: 1492153927
地址: 青岛开发区井冈山路东方银座 C座 1106
地址: 青岛开发区武夷山路167号千禧龙花园 9-1-101室
约定:
@@ -121,7 +121,7 @@ Contact: Mr. Xu
Phone: 4006-8899-23
Email: co@cnezsoft.com
QQ: 1492153927
Address: Qingdao Development Zone, the Oriental Kenzo C 1106
Address: 9-1-101, 167 Wuyishan Lu, Kai Fa Qu, Qingdao
We agree:
+18 -5
View File
@@ -1216,8 +1216,9 @@ class baseRouter
*/
public function setModuleName($moduleName = '')
{
$moduleName = strip_tags(urldecode(strtolower($moduleName)));
if(!preg_match('/^[a-zA-Z0-9]+$/', $moduleName)) $this->triggerError("The modulename '$moduleName' illegal. ", __FILE__, __LINE__, $exit = true);
$this->moduleName = strip_tags(urldecode(strtolower($moduleName)));
$this->moduleName = $moduleName;
}
/**
@@ -1250,8 +1251,9 @@ class baseRouter
*/
public function setMethodName($methodName = '')
{
$methodName = strip_tags(urldecode(strtolower($methodName)));
if(!preg_match('/^[a-zA-Z0-9]+$/', $methodName)) $this->triggerError("The methodname '$methodName' illegal. ", __FILE__, __LINE__, $exit = true);
$this->methodName = strip_tags(urldecode(strtolower($methodName)));
$this->methodName = $methodName;
}
/**
@@ -1801,11 +1803,22 @@ class baseRouter
{
foreach($lang->db->custom[$moduleName] as $section => $fields)
{
foreach($fields as $key => $value)
if(isset($lang->{$moduleName}->{$section}['']))
{
unset($lang->{$moduleName}->{$section}[$key]);
$lang->{$moduleName}->{$section}[$key] = $value;
$nullKey = '';
$nullValue = $lang->{$moduleName}->{$section}[$nullKey];
}
elseif(isset($lang->{$moduleName}->{$section}[0]))
{
$nullKey = 0;
$nullValue = $lang->{$moduleName}->{$section}[0];
}
unset($lang->{$moduleName}->{$section});
if(isset($nullKey))$lang->{$moduleName}->{$section}[$nullKey] = $nullValue;
foreach($fields as $key => $value) $lang->{$moduleName}->{$section}[$key] = $value;
unset($nullKey);
unset($nullValue);
}
}
+36
View File
@@ -75,4 +75,40 @@ class helper extends baseHelper
$replacements = array("\\\\", "\\/", "\\\"", "\'", "\\n", "\\r", "\\t", "\\f", "\\b", "\\u");
return str_replace($escapers, $replacements, $json);
}
/**
* Convert encoding.
*
* @param string $string
* @param string $fromEncoding
* @param string $toEncoding
* @static
* @access public
* @return string
*/
static public function convertEncoding($string, $fromEncoding, $toEncoding = 'utf-8')
{
$toEncoding = str_replace('utf8', 'utf-8', $toEncoding);
if(function_exists('mb_convert_encoding'))
{
/* Remove like utf-8//TRANSLIT. */
$position = strpos($toEncoding, '//');
if($position !== false) $toEncoding = substr($toEncoding, 0, $position);
/* Check string encoding. */
$encoding = strtolower(mb_detect_encoding($string, array('ASCII','UTF-8','GB2312','GBK','BIG5')));
if($encoding == $toEncoding) return $string;
return mb_convert_encoding($string, $toEncoding, $encoding);
}
elseif(function_exists('iconv'))
{
if($fromEncoding == $toEncoding) return $string;
$convertString = @iconv($fromEncoding, $toEncoding, $string);
/* iconv error then return original. */
if(!$convertString) return $string;
return $convertString;
}
return $string;
}
}
+5 -5
View File
@@ -65,11 +65,11 @@ class router extends baseRouter
*/
public function saveError($level, $message, $file, $line)
{
$errorNO[E_ERROR] = E_ERROR;
$errorNO[E_PARSE] = E_PARSE;
$errorNO[E_CORE_ERROR] = E_CORE_ERROR;
$errorNO[E_USER_ERROR] = E_USER_ERROR;
if(isset($errorNO[$level]) and $this->config->debug == false) $this->config->debug = true;
$fatalLevel[E_ERROR] = E_ERROR;
$fatalLevel[E_PARSE] = E_PARSE;
$fatalLevel[E_CORE_ERROR] = E_CORE_ERROR;
$fatalLevel[E_USER_ERROR] = E_USER_ERROR;
if(isset($fatalLevel[$level])) $this->config->debug = true;
parent::saveError($level, $message, $file, $line);
}
}
+85
View File
@@ -81,6 +81,91 @@ class html extends baseHTML
global $lang;
return "<div class='checkbox $appendClass'><label><input type='checkbox' data-scope='$scope' class='rows-selector'> $lang->select</label></div>";
}
/**
* 生成select标签。
* Create tags like "<select><option></option></select>"
*
* @param string $name the name of the select tag.
* @param array $options the array to create select tag from.
* @param string $selectedItems the item(s) to be selected, can like item1,item2.
* @param string $attrib other params such as multiple, size and style.
* @param string $append adjust if add options[$selectedItems].
* @static
* @access public
* @return string
*/
static public function select($name = '', $options = array(), $selectedItems = "", $attrib = "", $append = false)
{
global $app;
static $dataKeys;
$options = (array)($options);
if($append and !isset($options[$selectedItems])) $options[$selectedItems] = $selectedItems;
if(!is_array($options) or empty($options)) return false;
/* The begin. */
$id = $name;
if(strpos($name, '[') !== false) $id = trim(str_replace(']', '', str_replace('[', '', $name)));
$id = "id='{$id}'";
if(strpos($attrib, 'id=') !== false) $id = '';
$string = "<select name='$name' {$id} $attrib>\n";
/* The options. */
static $pinyin;
if(empty($pinyin)) $pinyin = $app->loadClass('pinyin');
$joinOptions = '';
$sign = ' aNd ';
foreach($options as $value)
{
if(!isset($dataKeys[$value])) $joinOptions .= str_replace($sign, ' and ', $value) . $sign;
}
if($joinOptions)
{
$valuesPinyin = $pinyin->romanize($joinOptions);
$signLenth = strlen($sign);
$pinyinSign = trim($sign);
$pySignLenth = strlen($pinyinSign);
while($joinOptions)
{
$valuePinyin = '';
$value = '';
$pinyinPos = strpos($valuesPinyin, $pinyinSign);
if($pinyinPos !== false)
{
$valuePinyin = substr($valuesPinyin, 0, $pinyinPos);
$valuesPinyin = substr($valuesPinyin, $pinyinPos + $pySignLenth);
}
$valuePos = strpos($joinOptions, $sign);
if($valuePos === false) break;
$value = substr($joinOptions, 0, $valuePos);
$joinOptions = substr($joinOptions, $valuePos + $signLenth);
$valuePinyin = preg_split('/[^a-z]+/iu', trim($valuePinyin));
$valueAbbr = '';
foreach($valuePinyin as $wordPinyin) if($wordPinyin) $valueAbbr .= $wordPinyin[0];
$dataKeys[$value] = empty($valuePinyin) ? '' : join($valuePinyin) . ' ' . $valueAbbr;
}
}
if(is_array($selectedItems)) $selectedItems = implode(',', $selectedItems);
$selectedItems = ",$selectedItems,";
foreach($options as $key => $value)
{
$key = str_replace('item', '', $key);
$selected = strpos($selectedItems, ",$key,") !== false ? " selected='selected'" : '';
$string .= "<option value='$key'$selected data-keys='{$dataKeys[$value]}'>$value</option>\n";
}
/* End. */
return $string .= "</select>\n";
}
}
/**
+2 -1
View File
@@ -605,7 +605,7 @@ class hyperdown
break;
// table
case preg_match("/^((?:(?:(?:[ :]*\-[ :]*)+(?:\||\+))|(?:(?:\||\+)(?:[ :]*\-[ :]*)+)|(?:(?:[ :]*\-[ :]*)+(?:\||\+)(?:[ :]*\-[ :]*)+))+)$/", $line, $matches):
case preg_match("/^((?:(?:(?:[ :]*\-[ :]*)+(?:\||\+))|(?:(?:\||\+)(?:[ :]*\-[ :]*)+)|(?:(?:[ :]*\-[ :]*)+(?:\||\+)(?:[ :]*\-[ :]*)+))+)\s*$/", $line, $matches):
if ($this->isBlock('table')) {
$block[3][0][] = $block[3][2];
$block[3][2] ++;
@@ -1148,6 +1148,7 @@ class hyperdown
*/
public function cleanUrl($url)
{
return $url;
if (preg_match("/^\s*((http|https|ftp|mailto):[x80-xff_a-z0-9-\.\/%#@\?\+=~\|\,&\(\)]+)/i", $url, $matches)) {
return $matches[1];
} else if (preg_match("/^\s*([x80-xff_a-z0-9-\.\/%#@\?\+=~\|\,&]+)/i", $url, $matches)) {
+26656
View File
File diff suppressed because it is too large Load Diff
+64
View File
@@ -0,0 +1,64 @@
<?php
/*
* This file is part of the overtrue/pinyin.
*
* (c) 2016 overtrue <i@overtrue.me>
*/
class pinyin
{
/**
* Constructor.
*
*/
public function __construct()
{
$this->segments = array();
$segment = dirname(__FILE__) . '/data/words';
if(file_exists($segment)) $this->segments = include $segment;
}
/**
* Convert string to pinyin.
*
* @param string $string
* @param string $option
*
* @return array
*/
public function convert($string)
{
$pinyin = $this->romanize($string);
$split = array_filter(preg_split('/[^a-z]+/iu', $pinyin));
return array_values($split);
}
/**
* Preprocess.
*
* @param string $string
*
* @return string
*/
public function prepare($string)
{
$string = preg_replace_callback('/[a-z0-9_-]+/i', create_function('$matches', 'return "\t" . $matches[0];'), $string);
return preg_replace("/[^\p{Han}\p{P}\p{Z}\p{M}\p{N}\p{L}\t]/u", '', $string);
}
/**
* Convert Chinese to pinyin.
*
* @param string $string
* @param bool $isName
*
* @return string
*/
public function romanize($string)
{
$string = $this->prepare($string);
$string = strtr($string, $this->segments);
return $string;
}
}
+1
View File
@@ -67,6 +67,7 @@ class zfile
*/
public function removeDir($dir)
{
if(empty($dir)) return true;
$dir = realpath($dir) . '/';
if($dir == '/') return false;
+198
View File
@@ -0,0 +1,198 @@
<?php
class ztcloud
{
public $url = 'http://smtp.zentao.cn/index.php?m=mail&f=apiSend';
public $account = '';
public $secretKey = '';
public $from = '';
public $fromName = '';
public $toList = '';
public $ccList = '';
public $subject = '';
public $body = '';
public $files = '';
public $headers = '';
public $Subject = ''; //Compatible phpmailer.
/**
* Set from.
*
* @param string $from
* @param string $fromName
* @access public
* @return void
*/
public function setFrom($from, $fromName = '')
{
$this->from = $from;
$this->fromName = empty($fromName) ? $from : $fromName;
}
/**
* Add an address
*
* @param string $kind
* @param string $address
* @param string $name
* @access public
* @return bool
*/
public function addAnAddress($kind, $address, $name = '')
{
$kind = strtolower($kind);
if(!preg_match('/^(to|cc|bcc|replyto)$/', $kind))
{
$error = 'Invalid recipient array: ' . $kind;
throw new Exception($error);
echo $error;
return false;
}
$address = trim($address);
if(empty($address)) return true;
$key = $kind . 'List';
$this->$key .= $address . ';';
return true;
}
/**
* Send mail
*
* @access public
* @return bool
*/
public function send()
{
if(!empty($this->Subject) and empty($this->subject)) $this->subject = $this->Subject;
$param['account'] = $this->account;
$param['from'] = $this->from;
$param['fromName'] = $this->fromName;
$param['toList'] = $this->toList;
$param['ccList'] = $this->ccList;
$param['subject'] = $this->subject;
$param['body'] = $this->body;
$result = $this->queryZtcloud($this->url, $param);
if($result->result == 'fail')
{
throw new Exception($result->message . "(code:{$result->code})");
return false;
}
}
/**
* Query Ztcloud
*
* @param string $url
* @param array $param
* @access public
* @return object
*/
public function queryZtcloud($url, $param)
{
if(!isset($param['signature'])) $param['signature'] = $this->getSignature($param);
$data = http_build_query($param);
$options['http'] = array(
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => $data
);
$context = stream_context_create($options);
$result = file_get_contents($url, FILE_TEXT, $context);
return json_decode($result);
}
/**
* Compute Signature.
*
* @param array $param
* @access public
* @return string
*/
public function getSignature($param)
{
ksort($param);
$data = http_build_query($param);
return md5($this->secretKey . '&' . $data . '&' . $this->secretKey);
}
/**
* Add address
*
* @param string $address
* @param string $name
* @access public
* @return bool
*/
public function addAddress($address, $name = '')
{
return $this->addAnAddress('to', $address, $name);
}
/**
* Add cc.
*
* @param string $address
* @param string $name
* @access public
* @return bool
*/
public function addCC($address, $name = '')
{
return $this->addAnAddress('cc', $address, $name);
}
/**
* MsgHtml
*
* @param string $html
* @access public
* @return void
*/
public function msgHtml($html)
{
$this->body = $html;
}
/**
* Clear all recipients.
*
* @access public
* @return void
*/
public function clearAllRecipients()
{
$this->toList = '';
}
/**
* Clear attachments.
*
* @access public
* @return void
*/
public function clearAttachments()
{
$this->subject = '';
$this->html = '';
$this->files = '';
$this->headers = '';
$this->Subject = '';
}
/**
* Set language.
*
* @param string $langcode
* @param string $lang_path
* @access public
* @return bool
*/
public function setLanguage($langcode = 'en', $lang_path = '../phpmailer/language/')
{
return true;
}
}
+1
View File
@@ -15,5 +15,6 @@ $config->action->objectNameFields['doc'] = 'title';
$config->action->objectNameFields['doclib'] = 'name';
$config->action->objectNameFields['todo'] = 'name';
$config->action->objectNameFields['branch'] = 'name';
$config->action->objectNameFields['module'] = 'name';
$config->action->commonImgSize = 870;
+24 -21
View File
@@ -45,7 +45,7 @@ $lang->action->dynamic->search = 'Search';
$lang->action->objectTypes['product'] = $lang->productCommon;
$lang->action->objectTypes['story'] = 'Story';
$lang->action->objectTypes['productplan'] = 'Planning';
$lang->action->objectTypes['productplan'] = 'Plan';
$lang->action->objectTypes['release'] = 'Release';
$lang->action->objectTypes['project'] = $lang->projectCommon;
$lang->action->objectTypes['task'] = 'Task';
@@ -60,6 +60,7 @@ $lang->action->objectTypes['doc'] = 'Document';
$lang->action->objectTypes['doclib'] = 'Doc Lib';
$lang->action->objectTypes['todo'] = 'To-Dos';
$lang->action->objectTypes['branch'] = 'Branch';
$lang->action->objectTypes['module'] = 'Module';
/* 用来描述操作历史记录。*/
$lang->action->desc = new stdclass();
@@ -67,8 +68,8 @@ $lang->action->desc->common = '$date, <strong>$action</strong> by <stron
$lang->action->desc->extra = '$date, <strong>$action</strong> as <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->opened = '$date, created by <strong>$actor</strong> .' . "\n";
$lang->action->desc->created = '$date, created by <strong>$actor</strong> .' . "\n";
$lang->action->desc->changed = '$date, modified by <strong>$actor</strong> .' . "\n";
$lang->action->desc->edited = '$date, Edited by <strong>$actor</strong> .' . "\n";
$lang->action->desc->changed = '$date, changed by <strong>$actor</strong> .' . "\n";
$lang->action->desc->edited = '$date, edited by <strong>$actor</strong> .' . "\n";
$lang->action->desc->assigned = '$date, <strong>$actor</strong> assigned to <strong>$extra</strong>.' . "\n";
$lang->action->desc->closed = '$date, closed by <strong>$actor</strong> .' . "\n";
$lang->action->desc->deleted = '$date, deleted by <strong>$actor</strong> .' . "\n";
@@ -94,20 +95,20 @@ $lang->action->desc->deleteestimate = '$date, <strong>$actor</strong> delete man
$lang->action->desc->canceled = '$date, cancelled by <strong>$actor</strong>.' . "\n";
$lang->action->desc->svncommited = '$date, submitted by <strong>$actor</strong> and the version is <strong>#$extra</strong>.' . "\n";
$lang->action->desc->gitcommited = '$date, submitted by <strong>$actor</strong> and the version is <strong>#$extra</strong>.' . "\n";
$lang->action->desc->finished = '$date, accomplished by <strong>$actor</strong>.' . "\n";
$lang->action->desc->finished = '$date, finished by <strong>$actor</strong>.' . "\n";
$lang->action->desc->paused = '$date, paused by <strong>$actor</strong>.' . "\n";
$lang->action->desc->diff1 = '<strong><i>%s</i></strong> has been modified. Its value was "%s" and the new value is "%s".<br />' . "\n";
$lang->action->desc->diff2 = '<strong><i>%s</i></strong> has been modified. The difference is ' . "\n" . "<blockquote>%s</blockquote>" . "\n<div class='hidden'>%s</div>";
$lang->action->desc->diff1 = '<strong><i>%s</i></strong> has been changed. Its value was "%s" and the new value is "%s".<br />' . "\n";
$lang->action->desc->diff2 = '<strong><i>%s</i></strong> has been changed. The difference is ' . "\n" . "<blockquote>%s</blockquote>" . "\n<div class='hidden'>%s</div>";
$lang->action->desc->diff3 = 'File Name %s was changed to %s .' . "\n";
/* 关联用例和移除用例时的历史操作记录。*/
$lang->action->desc->linkrelatedcase = '$date, <strong>$actor</strong> linked relevant use case <strong>$extra</strong>.' . "\n";
$lang->action->desc->linkrelatedcase = '$date, <strong>$actor</strong> related relevant use case <strong>$extra</strong>.' . "\n";
$lang->action->desc->unlinkrelatedcase = '$date, <strong>$actor</strong> removed relevant use case <strong>$extra</strong>.' . "\n";
/* 用来显示动态信息。*/
$lang->action->label = new stdclass();
$lang->action->label->created = 'Created';
$lang->action->label->opened = 'Opened';
$lang->action->label->opened = 'Open';
$lang->action->label->changed = 'Changed';
$lang->action->label->edited = 'Edited';
$lang->action->label->assigned = 'Assigned';
@@ -130,23 +131,25 @@ $lang->action->label->frombug = 'Converted from Bug';
$lang->action->label->totask = 'Convert to Task';
$lang->action->label->svncommited = 'SVN Commit';
$lang->action->label->gitcommited = 'Git Commit';
$lang->action->label->linked2plan = 'Link to Planning';
$lang->action->label->unlinkedfromplan = 'Unlink from Planning';
$lang->action->label->linked2plan = 'Relate to Plan';
$lang->action->label->unlinkedfromplan = 'Unrelate';
$lang->action->label->changestatus = 'Change Status';
$lang->action->label->marked = 'Marked';
$lang->action->label->linked2project = "Link {$lang->projectCommon}";
$lang->action->label->linked2project = "Relate {$lang->projectCommon}";
$lang->action->label->unlinkedfromproject = "Remove {$lang->projectCommon}";
$lang->action->label->linkrelatedbug = "Link to Bug";
$lang->action->label->unlinkrelatedbug = "Removed Linked Bug";
$lang->action->label->linkrelatedcase = "Link to Case";
$lang->action->label->unlinkrelatedcase = "Unlink from Case";
$lang->action->label->linkrelatedstory = "Link to Story";
$lang->action->label->unlinkrelatedstory = "Unlink from Story";
$lang->action->label->linked2release = "Relate Release";
$lang->action->label->unlinkedfromrelease = "Remove Release";
$lang->action->label->linkrelatedbug = "Relate to Bug";
$lang->action->label->unlinkrelatedbug = "Unrelate";
$lang->action->label->linkrelatedcase = "Relate to Case";
$lang->action->label->unlinkrelatedcase = "Unrelate";
$lang->action->label->linkrelatedstory = "Relate to Story";
$lang->action->label->unlinkrelatedstory = "Unrelate";
$lang->action->label->subdividestory = "Decompose Story";
$lang->action->label->unlinkchildstory = "Unlink decomposed Story";
$lang->action->label->unlinkchildstory = "Unrelate";
$lang->action->label->started = 'Initiated';
$lang->action->label->restarted = 'Continued';
$lang->action->label->recordestimate = 'Historyed Man-Hour';
$lang->action->label->recordestimate = 'Recorded Man-Hour';
$lang->action->label->editestimate = 'Edited Man-Hour';
$lang->action->label->canceled = 'Cancelled';
$lang->action->label->finished = 'Finished';
@@ -159,7 +162,7 @@ $lang->action->label->deleteestimate = "Deleted Man-Hour";
/* 用来生成相应对象的链接。*/
$lang->action->label->product = $lang->productCommon . '|product|view|productID=%s';
$lang->action->label->productplan = 'Planning|productplan|view|productID=%s';
$lang->action->label->productplan = 'Plan|productplan|view|productID=%s';
$lang->action->label->release = 'Release|release|view|productID=%s';
$lang->action->label->story = 'Story|story|view|storyID=%s';
$lang->action->label->project = "{$lang->projectCommon}|project|view|projectID=%s";
@@ -191,7 +194,7 @@ $lang->action->search->objectTypeList['doclib'] = 'Doc Lib';
$lang->action->search->objectTypeList['todo'] = 'To-Dos';
$lang->action->search->objectTypeList['build'] = 'Build';
$lang->action->search->objectTypeList['release'] = 'Release';
$lang->action->search->objectTypeList['productplan'] = 'Planning';
$lang->action->search->objectTypeList['productplan'] = 'Plan';
$lang->action->search->objectTypeList['branch'] = 'Branch';
/* 用来在动态显示中显示动作 */
+3
View File
@@ -60,6 +60,7 @@ $lang->action->objectTypes['doc'] = '文档';
$lang->action->objectTypes['doclib'] = '文档库';
$lang->action->objectTypes['todo'] = '待办';
$lang->action->objectTypes['branch'] = '分支';
$lang->action->objectTypes['module'] = '模块';
/* 用来描述操作历史记录。*/
$lang->action->desc = new stdclass();
@@ -136,6 +137,8 @@ $lang->action->label->changestatus = '修改状态';
$lang->action->label->marked = '编辑了';
$lang->action->label->linked2project = "关联{$lang->projectCommon}";
$lang->action->label->unlinkedfromproject = "移除{$lang->projectCommon}";
$lang->action->label->linked2release = "关联发布";
$lang->action->label->unlinkedfromrelease = "移除发布";
$lang->action->label->linkrelatedbug = "关联了相关Bug";
$lang->action->label->unlinkrelatedbug = "移除了相关Bug";
$lang->action->label->linkrelatedcase = "关联了相关用例";
+3
View File
@@ -60,6 +60,7 @@ $lang->action->objectTypes['doc'] = '文檔';
$lang->action->objectTypes['doclib'] = '文檔庫';
$lang->action->objectTypes['todo'] = '待辦';
$lang->action->objectTypes['branch'] = '分支';
$lang->action->objectTypes['module'] = '模組';
/* 用來描述操作歷史記錄。*/
$lang->action->desc = new stdclass();
@@ -136,6 +137,8 @@ $lang->action->label->changestatus = '修改狀態';
$lang->action->label->marked = '編輯了';
$lang->action->label->linked2project = "關聯{$lang->projectCommon}";
$lang->action->label->unlinkedfromproject = "移除{$lang->projectCommon}";
$lang->action->label->linked2release = "關聯發佈";
$lang->action->label->unlinkedfromrelease = "移除發佈";
$lang->action->label->linkrelatedbug = "關聯了相關Bug";
$lang->action->label->unlinkrelatedbug = "移除了相關Bug";
$lang->action->label->linkrelatedcase = "關聯了相關用例";
+31 -3
View File
@@ -231,6 +231,16 @@ class actionModel extends model
$title = $this->dao->select('title')->from(TABLE_PRODUCTPLAN)->where('id')->eq($action->extra)->fetch('title');
if($title) $action->extra = html::a(helper::createLink('productplan', 'view', "planID=$action->extra"), $title);
}
elseif($actionName == 'linked2build')
{
$name = $this->dao->select('name')->from(TABLE_BUILD)->where('id')->eq($action->extra)->fetch('name');
if($name) $action->extra = html::a(helper::createLink('build', 'view', "builID=$action->extra&type={$action->objectType}"), $name);
}
elseif($actionName == 'linked2release')
{
$name = $this->dao->select('name')->from(TABLE_RELEASE)->where('id')->eq($action->extra)->fetch('name');
if($name) $action->extra = html::a(helper::createLink('release', 'view', "releaseID=$action->extra&type={$action->objectType}"), $name);
}
elseif($actionName == 'moved')
{
$name = $this->dao->select('name')->from(TABLE_PROJECT)->where('id')->eq($action->extra)->fetch('name');
@@ -245,6 +255,16 @@ class actionModel extends model
$name = $this->dao->select('name')->from(TABLE_PROJECT)->where('id')->eq($action->extra)->fetch('name');
if($name) $action->extra = html::a(helper::createLink('project', 'story', "projectID=$action->extra"), "#$action->extra " . $name);
}
elseif($actionName == 'unlinkedfrombuild')
{
$name = $this->dao->select('name')->from(TABLE_BUILD)->where('id')->eq($action->extra)->fetch('name');
if($name) $action->extra = html::a(helper::createLink('build', 'view', "builID=$action->extra&type={$action->objectType}"), $name);
}
elseif($actionName == 'unlinkedfromrelease')
{
$name = $this->dao->select('name')->from(TABLE_RELEASE)->where('id')->eq($action->extra)->fetch('name');
if($name) $action->extra = html::a(helper::createLink('release', 'view', "releaseID=$action->extra&type={$action->objectType}"), $name);
}
elseif($actionName == 'unlinkedfromplan')
{
$title = $this->dao->select('title')->from(TABLE_PRODUCTPLAN)->where('id')->eq($action->extra)->fetch('title');
@@ -419,7 +439,7 @@ class actionModel extends model
* 2. If no defined in the module language, search the common action define.
* 3. If not found in the lang->action->desc, use the $lang->action->desc->common or $lang->action->desc->extra as the default.
*/
if(isset($this->lang->$objectType->action->$actionType))
if(isset($this->lang->$objectType) && isset($this->lang->$objectType->action->$actionType))
{
$desc = $this->lang->$objectType->action->$actionType;
}
@@ -507,6 +527,12 @@ class actionModel extends model
if(strpos($this->app->company->admins, ',' . $this->app->user->account . ',') !== false) $condition = 1;
}
$this->loadModel('doc');
$docCondition = $this->doc->buildConditionSQL('doc');
$libCondition = $this->doc->buildConditionSQL('lib');
if($docCondition) $docCondition = $this->dao->select('id')->from(TABLE_DOC)->where($docCondition)->andWhere('deleted')->eq(0)->get();
if($libCondition) $libCondition = $this->dao->select('id')->from(TABLE_DOCLIB)->where($libCondition)->andWhere('deleted')->eq(0)->get();
/* Get actions. */
$actions = $this->dao->select('*')->from(TABLE_ACTION)
->where(1)
@@ -518,6 +544,8 @@ class actionModel extends model
->beginIF($productID == 'notzero')->andWhere('product')->gt(0)->fi()
->beginIF($projectID == 'notzero')->andWhere('project')->gt(0)->fi()
->beginIF($projectID == 'all' or $productID == 'all')->andWhere("($condition)")->fi()
->beginIF($docCondition)->andWhere("IF(objectType != 'doc', '1=1', objectID in ($docCondition))")->fi()
->beginIF($libCondition)->andWhere("IF(objectType != 'doclib', '1=1', objectID in ($libCondition))")->fi()
->orderBy($orderBy)->page($pager)->fetchAll();
if(!$actions) return array();
@@ -735,7 +763,7 @@ class actionModel extends model
foreach($histories as $history)
{
$fieldName = $history->field;
$history->fieldLabel = isset($this->lang->$objectType->$fieldName) ? $this->lang->$objectType->$fieldName : $fieldName;
$history->fieldLabel = (isset($this->lang->$objectType) && isset($this->lang->$objectType->$fieldName)) ? $this->lang->$objectType->$fieldName : $fieldName;
if(($length = strlen($history->fieldLabel)) > $maxLength) $maxLength = $length;
$history->diff ? $historiesWithDiff[] = $history : $historiesWithoutDiff[] = $history;
}
@@ -799,7 +827,7 @@ class actionModel extends model
/* Revert doclib when undelet product or project. */
if($action->objectType == 'project' or $action->objectType == 'product')
{
$this->dao->update(TABLE_DOCLIT)->set('deleted')->eq(0)->where($action->objectType)->eq($action->objectID)->exec();
$this->dao->update(TABLE_DOCLIB)->set('deleted')->eq(0)->where($action->objectType)->eq($action->objectID)->exec();
}
/* Update action record in action table. */
+2
View File
@@ -9,5 +9,7 @@ $config->url->extension = 'http://www.zentao.net/extension-browse.html';
$config->url->donation = 'http://www.zentao.net/help-donation.html';
$config->url->service = 'http://www.cnezsoft.com/article-browse-1078.html';
$config->admin->apiRoot = 'http://www.zentao.net';
if(!isset($config->safe)) $config->safe = new stdclass();
if(!isset($config->safe->weak)) $config->safe->weak = '123456,password,12345,12345678,qwerty,123456789,1234,1234567,abc123,111111,123123';
+131 -13
View File
@@ -47,7 +47,10 @@ class admin extends control
*/
public function ignore()
{
$this->loadModel('setting')->setItem('system.common.global.community', 'na');
$this->loadModel('setting');
$this->setting->deleteItems('owner=system&module=common&section=global&key=community');
$this->setting->deleteItems('owner=system&module=common&section=global&key=ztPrivateKey');
$this->setting->setItem('system.common.global.community', 'na');
die(js::locate(inlink('index'), 'parent'));
}
@@ -57,24 +60,46 @@ class admin extends control
* @access public
* @return void
*/
public function register()
public function register($from = 'admin')
{
if($_POST)
{
$response = $this->admin->registerByAPI();
if($response == 'success')
$response = json_decode($response);
if($response->result == 'success')
{
$this->loadModel('setting')->setItem('system.common.global.community', $this->post->account);
$user = $response->data;
$data['community'] = $user->account;
$data['ztPrivateKey'] = $user->private;
$this->loadModel('setting');
$this->setting->deleteItems('owner=system&module=common&section=global&key=community');
$this->setting->deleteItems('owner=system&module=common&section=global&key=ztPrivateKey');
$this->setting->setItems('system.common.global', $data);
echo js::alert($this->lang->admin->register->success);
die(js::locate(inlink('index'), 'parent'));
}
die($response);
}
if($from == 'admin') die(js::locate(inlink('index'), 'parent'));
if($from == 'mail') die(js::locate($this->createLink('mail', 'ztcloud'), 'parent'));
}
$alertMessage = '';
if(is_string($response->message))
{
$alertMessage = $response->message;
}
else
{
foreach($response->message as $item) $alertMessage .= is_array($item) ? join('\n', $item) . '\n' : $item . '\n';
}
$alertMessage = str_replace(array('<strong>', '</strong>'), '', $alertMessage);
die(js::alert($alertMessage));
}
$this->view->title = $this->lang->admin->register->caption;
$this->view->position[] = $this->lang->admin->register->caption;
$this->view->register = $this->admin->getRegisterInfo();
$this->view->sn = $this->config->global->sn;
$this->view->from = $from;
$this->display();
}
@@ -84,20 +109,29 @@ class admin extends control
* @access public
* @return void
*/
public function bind()
public function bind($from = 'admin')
{
if($_POST)
{
$response = $this->admin->bindByAPI();
if($response == 'success')
$response = json_decode($response);
if($response->result == 'success')
{
$this->loadModel('setting')->setItem('system.common.global.community', $this->post->account);
$user = $response->data;
$data['community'] = $user->account;
$data['ztPrivateKey'] = $user->private;
$this->loadModel('setting');
$this->setting->deleteItems('owner=system&module=common&section=global&key=community');
$this->setting->deleteItems('owner=system&module=common&section=global&key=ztPrivateKey');
$this->setting->setItems('system.common.global', $data);
echo js::alert($this->lang->admin->bind->success);
die(js::locate(inlink('index'), 'parent'));
if($from == 'admin') die(js::locate(inlink('index'), 'parent'));
if($from == 'mail') die(js::locate($this->createLink('mail', 'ztcloud'), 'parent'));
}
else
{
$response = json_decode($response);
if($response->result == 'fail') die(js::alert($response->message));
}
}
@@ -105,6 +139,7 @@ class admin extends control
$this->view->title = $this->lang->admin->bind->caption;
$this->view->position[] = $this->lang->admin->bind->caption;
$this->view->sn = $this->config->global->sn;
$this->view->from = $from;
$this->display();
}
@@ -192,4 +227,87 @@ class admin extends control
$this->view->code = isset($this->config->sso->code) ? $this->config->sso->code : '';
$this->display();
}
/**
* Certify ztEmail.
*
* @param string $email
* @access public
* @return void
*/
public function certifyZtEmail($email = '')
{
if($_POST)
{
$response = $this->admin->certifyByAPI('mail');
$response = json_decode($response);
if($response->result == 'fail') die(js::alert($response->message));
die(js::locate($this->createLink('mail', 'ztCloud'), 'parent'));
}
$this->view->title = $this->lang->admin->certifyEmail;
$this->view->position[] = $this->lang->admin->certifyEmail;
$this->view->email = helper::safe64Decode($email);
$this->display();
}
/**
* Certify ztMobile
*
* @param string $mobile
* @access public
* @return void
*/
public function certifyZtMobile($mobile = '')
{
if($_POST)
{
$response = $this->admin->certifyByAPI('mobile');
$response = json_decode($response);
if($response->result == 'fail') die(js::alert($response->message));
die(js::locate($this->createLink('mail', 'ztCloud'), 'parent'));
}
$this->view->title = $this->lang->admin->certifyMobile;
$this->view->position[] = $this->lang->admin->certifyMobile;
$this->view->mobile = helper::safe64Decode($mobile);
$this->display();
}
/**
* Set ztCompany.
*
* @access public
* @return void
*/
public function ztCompany($fields = 'company')
{
if($_POST)
{
$response = $this->admin->setCompanyByAPI();
$response = json_decode($response);
if($response->result == 'fail') die(js::alert($response->message));
die(js::locate($this->createLink('mail', 'ztCloud'), 'parent'));
}
$this->view->title = $this->lang->admin->ztCompany;
$this->view->position[] = $this->lang->admin->ztCompany;
$this->view->fields = explode(',', $fields);
$this->display();
}
/**
* Ajax send code.
*
* @param int $type
* @access public
* @return void
*/
public function ajaxSendCode($type)
{
die($this->admin->sendCodeByAPI($type));
}
}
+20 -7
View File
@@ -9,12 +9,17 @@
* @version $Id: en.php 4460 2013-02-26 02:28:02Z chencongzhi520@gmail.com $
* @link http://www.zentao.net
*/
$lang->admin->common = 'Administration';
$lang->admin->index = 'Admin Homepage';
$lang->admin->checkDB = 'Check Database Library';
$lang->admin->sso = 'RangerTeam';
$lang->admin->safeIndex = 'Security';
$lang->admin->checkWeak = 'Weak Password Check';
$lang->admin->common = 'Administration';
$lang->admin->index = 'Admin Home';
$lang->admin->checkDB = 'Check Database';
$lang->admin->sso = 'RangerTeam';
$lang->admin->safeIndex = 'Security';
$lang->admin->checkWeak = 'Weak Password Check';
$lang->admin->certifyMobile = 'Verify your mobilephone';
$lang->admin->certifyEmail = 'Verifu your Email';
$lang->admin->ztCompany = 'Verifu your company';
$lang->admin->captcha = 'Verification Code';
$lang->admin->getCaptcha = 'Get Verification Code';
$lang->admin->info = new stdclass();
$lang->admin->info->version = 'Current Version is %s,';
@@ -26,6 +31,7 @@ $lang->admin->notice->register = "Note: You haven't registered in ZenTao(www.zen
$lang->admin->notice->ignore = "Ignore";
$lang->admin->register = new stdclass();
$lang->admin->register->common = 'Account Binding';
$lang->admin->register->caption = 'Register';
$lang->admin->register->click = 'Click Here';
$lang->admin->register->lblAccount = 'must be 3 characters combination of letters and numbers at least.';
@@ -42,19 +48,26 @@ $lang->admin->safe = new stdclass();
$lang->admin->safe->common = 'Security';
$lang->admin->safe->set = 'Password Security Settings';
$lang->admin->safe->password = 'Password Security';
$lang->admin->safe->weak = 'Common Weak Password';
$lang->admin->safe->weak = 'Weak Password';
$lang->admin->safe->reason = 'Type';
$lang->admin->safe->checkWeak = 'Weak Password Check';
$lang->admin->safe->modifyPasswordFirstLogin = 'Modify password when login for the first time.';
$lang->admin->safe->modeList[0] = 'N/A';
$lang->admin->safe->modeList[1] = 'Medium';
$lang->admin->safe->modeList[2] = 'Strong';
$lang->admin->safe->modeRuleList[1] = 'Should be contain letters and numbers, at lease six characters.';
$lang->admin->safe->modeRuleList[2] = 'Should be contain letters, numbers and special characters, at lease 10 characters.';
$lang->admin->safe->reasonList['weak'] = 'Common Weak Password';
$lang->admin->safe->reasonList['account'] = 'Same as your account';
$lang->admin->safe->reasonList['mobile'] = 'Same as your mobile number';
$lang->admin->safe->reasonList['phone'] = 'Same as your phone number';
$lang->admin->safe->reasonList['birthday'] = 'Same as your DOB';
$lang->admin->safe->modifyPasswordList[1] = 'Must';
$lang->admin->safe->modifyPasswordList[0] = 'No';
$lang->admin->safe->noticeMode = 'User password will be checked when login, add/edit user password.';
$lang->admin->safe->noticeStrong = 'The more capitalized letters and numbers a password has, the more secure it is!';
+21 -8
View File
@@ -9,12 +9,17 @@
* @version $Id: zh-cn.php 4767 2013-05-05 06:10:13Z wwccss $
* @link http://www.zentao.net
*/
$lang->admin->common = '后台管理';
$lang->admin->index = '后台管理首页';
$lang->admin->checkDB = '检查数据库';
$lang->admin->sso = '然之集成';
$lang->admin->safeIndex = '安全';
$lang->admin->checkWeak = '弱口令检查';
$lang->admin->common = '后台管理';
$lang->admin->index = '后台管理首页';
$lang->admin->checkDB = '检查数据库';
$lang->admin->sso = '然之集成';
$lang->admin->safeIndex = '安全';
$lang->admin->checkWeak = '弱口令检查';
$lang->admin->certifyMobile = '认证手机';
$lang->admin->certifyEmail = '认证邮箱';
$lang->admin->ztCompany = '认证公司';
$lang->admin->captcha = '验证码';
$lang->admin->getCaptcha = '获取验证码';
$lang->admin->info = new stdclass();
$lang->admin->info->version = '当前系统的版本是%s,';
@@ -26,12 +31,13 @@ $lang->admin->notice->register = "友情提示:您还未在禅道社区(www.ze
$lang->admin->notice->ignore = "不再提示";
$lang->admin->register = new stdclass();
$lang->admin->register->common = '注册新帐号绑定';
$lang->admin->register->caption = '禅道社区登记';
$lang->admin->register->click = '点击此处';
$lang->admin->register->lblAccount = '请设置您的用户名,英文字母和数字的组合,三位以上。';
$lang->admin->register->lblPasswd = '请设置您的密码。数字和字母的组合,六位以上。';
$lang->admin->register->submit = '登记';
$lang->admin->register->bind = "如果您已经拥有社区帐号,%s关联账户";
$lang->admin->register->bind = "绑定已有帐号";
$lang->admin->register->success = "登记账户成功";
$lang->admin->bind = new stdclass();
@@ -45,16 +51,23 @@ $lang->admin->safe->password = '密码安全';
$lang->admin->safe->weak = '常用弱口令';
$lang->admin->safe->reason = '类型';
$lang->admin->safe->checkWeak = '弱口令扫描';
$lang->admin->safe->modifyPasswordFirstLogin = '首次登陆修改密码';
$lang->admin->safe->modeList[0] = '不检查';
$lang->admin->safe->modeList[1] = '中';
$lang->admin->safe->modeList[2] = '强';
$lang->admin->safe->modeRuleList[1] = '6位以上,包含大小写字母,数字。';
$lang->admin->safe->modeRuleList[2] = '10位以上,包含字母,数字,特殊字符。';
$lang->admin->safe->reasonList['weak'] = '常用弱口令';
$lang->admin->safe->reasonList['account'] = '与帐号相同';
$lang->admin->safe->reasonList['mobile'] = '与手机相同';
$lang->admin->safe->reasonList['phone'] = '与电话相同';
$lang->admin->safe->reasonList['birthday'] = '与生日相同';
$lang->admin->safe->modifyPasswordList[1] = '必须修改';
$lang->admin->safe->modifyPasswordList[0] = '不强制';
$lang->admin->safe->noticeMode = '系统会在登录、创建和修改用户、修改密码的时候检查用户口令。';
$lang->admin->safe->noticeStrong = '密码长度越长,含有大写字母或数字或特殊符合越多,密码字母越不重复,安全度越强!';
$lang->admin->safe->noticeStrong = '密码长度越长,含有大写字母或数字或特殊符号越多,密码字母越不重复,安全度越强!';
+21 -8
View File
@@ -9,12 +9,17 @@
* @version $Id: zh-tw.php 4767 2013-05-05 06:10:13Z wwccss $
* @link http://www.zentao.net
*/
$lang->admin->common = '後台管理';
$lang->admin->index = '後台管理首頁';
$lang->admin->checkDB = '檢查資料庫';
$lang->admin->sso = '然之整合';
$lang->admin->safeIndex = '安全';
$lang->admin->checkWeak = '弱口令檢查';
$lang->admin->common = '後台管理';
$lang->admin->index = '後台管理首頁';
$lang->admin->checkDB = '檢查資料庫';
$lang->admin->sso = '然之整合';
$lang->admin->safeIndex = '安全';
$lang->admin->checkWeak = '弱口令檢查';
$lang->admin->certifyMobile = '認證手機';
$lang->admin->certifyEmail = '認證郵箱';
$lang->admin->ztCompany = '認證公司';
$lang->admin->captcha = '驗證碼';
$lang->admin->getCaptcha = '獲取驗證碼';
$lang->admin->info = new stdclass();
$lang->admin->info->version = '當前系統的版本是%s,';
@@ -26,12 +31,13 @@ $lang->admin->notice->register = "友情提示:您還未在禪道社區(www.ze
$lang->admin->notice->ignore = "不再提示";
$lang->admin->register = new stdclass();
$lang->admin->register->common = '註冊新帳號綁定';
$lang->admin->register->caption = '禪道社區登記';
$lang->admin->register->click = '點擊此處';
$lang->admin->register->lblAccount = '請設置您的用戶名,英文字母和數字的組合,三位以上。';
$lang->admin->register->lblPasswd = '請設置您的密碼。數字和字母的組合,六位以上。';
$lang->admin->register->submit = '登記';
$lang->admin->register->bind = "如果您已經擁有社區帳號,%s關聯賬戶";
$lang->admin->register->bind = "綁定已有帳號";
$lang->admin->register->success = "登記賬戶成功";
$lang->admin->bind = new stdclass();
@@ -45,16 +51,23 @@ $lang->admin->safe->password = '密碼安全';
$lang->admin->safe->weak = '常用弱口令';
$lang->admin->safe->reason = '類型';
$lang->admin->safe->checkWeak = '弱口令掃瞄';
$lang->admin->safe->modifyPasswordFirstLogin = '首次登陸修改密碼';
$lang->admin->safe->modeList[0] = '不檢查';
$lang->admin->safe->modeList[1] = '中';
$lang->admin->safe->modeList[2] = '強';
$lang->admin->safe->modeRuleList[1] = '6位以上,包含大小寫字母,數字。';
$lang->admin->safe->modeRuleList[2] = '10位以上,包含字母,數字,特殊字元。';
$lang->admin->safe->reasonList['weak'] = '常用弱口令';
$lang->admin->safe->reasonList['account'] = '與帳號相同';
$lang->admin->safe->reasonList['mobile'] = '與手機相同';
$lang->admin->safe->reasonList['phone'] = '與電話相同';
$lang->admin->safe->reasonList['birthday'] = '與生日相同';
$lang->admin->safe->modifyPasswordList[1] = '必須修改';
$lang->admin->safe->modifyPasswordList[0] = '不強制';
$lang->admin->safe->noticeMode = '系統會在登錄、創建和修改用戶、修改密碼的時候檢查用戶口令。';
$lang->admin->safe->noticeStrong = '密碼長度越長,含有大寫字母或數字或特殊符合越多,密碼字母越不重複,安全度越強!';
$lang->admin->safe->noticeStrong = '密碼長度越長,含有大寫字母或數字或特殊符號越多,密碼字母越不重複,安全度越強!';
+157 -36
View File
@@ -62,9 +62,9 @@ class adminModel extends model
*/
public function postAPI($url, $formvars = "")
{
$this->agent->cookies['lang'] = $this->cookie->lang;
$this->agent->submit($url, $formvars);
return $this->agent->results;
$this->agent->cookies['lang'] = $this->cookie->lang;
$this->agent->submit($url, $formvars);
return $this->agent->results;
}
/**
@@ -101,41 +101,162 @@ class adminModel extends model
}
/**
* Register zentao by API.
*
* @access public
* @return void
*/
public function registerByAPI()
{
$apiURL = 'http://www.zentao.net/user-register.json';
return $this->postAPI($apiURL, $_POST);
}
/**
* Register zentao by API.
*
* @access public
* @return void
*/
public function registerByAPI()
{
$apiConfig = $this->getApiConfig();
$apiURL = $this->config->admin->apiRoot . "/user-apiRegister.json?HTTP_X_REQUESTED_WITH=XMLHttpRequest&{$apiConfig->sessionVar}={$apiConfig->sessionID}";
return $this->postAPI($apiURL, $_POST);
}
/**
* Login zentao by API.
*
* @access public
* @return void
*/
public function bindByAPI()
{
$apiURL = 'http://www.zentao.net/user-login.json';
return $this->postAPI($apiURL, $_POST);
}
/**
* Login zentao by API.
*
* @access public
* @return void
*/
public function bindByAPI()
{
$apiConfig = $this->getApiConfig();
$apiURL = $this->config->admin->apiRoot . "/user-bindChanzhi.json?HTTP_X_REQUESTED_WITH=XMLHttpRequest&{$apiConfig->sessionVar}={$apiConfig->sessionID}";
return $this->postAPI($apiURL, $_POST);
}
/**
* Get register information.
*
* @access public
* @return object
*/
public function getRegisterInfo()
/**
* Get secret key.
*
* @access public
* @return object
*/
public function getSecretKey()
{
$apiConfig = $this->getApiConfig();
$apiURL = $this->config->admin->apiRoot . "/user-secretKey.json";
$params['u'] = $this->config->global->community;
$params['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
$params[$apiConfig->sessionVar] = $apiConfig->sessionID;
$params['k'] = $this->getSignature($params);
$this->agent->cookies['lang'] = $this->cookie->lang;
$this->agent->fetch($apiURL . '?' . http_build_query($params));
$result = $this->agent->results;
$result = json_decode($result);
return $result;
}
/**
* Send code by API.
*
* @param string $type
* @access public
* @return string
*/
public function sendCodeByAPI($type)
{
$apiConfig = $this->getApiConfig();
$module = $type == 'mobile' ? 'sms' : 'mail';
$apiURL = $this->config->admin->apiRoot . "/{$module}-apiSendCode.json";
$params['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
$params[$apiConfig->sessionVar] = $apiConfig->sessionID;
if(isset($this->config->global->community) and $this->config->global->community != 'na') $this->post->set('account', $this->config->global->community);
$param = http_build_query($params);
return $this->postAPI($apiURL . '?' . $param, $_POST);
}
/**
* Certify by API.
*
* @param string $type
* @access public
* @return string
*/
public function certifyByAPI($type)
{
$apiConfig = $this->getApiConfig();
$module = $type == 'mobile' ? 'sms' : 'mail';
$apiURL = $this->config->admin->apiRoot . "/{$module}-apiCertify.json";
$params['u'] = $this->config->global->community;
$params['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
$params[$apiConfig->sessionVar] = $apiConfig->sessionID;
$params['k'] = $this->getSignature($params);
$param = http_build_query($params);
return $this->postAPI($apiURL . '?' . $param, $_POST);
}
/**
* Set company by API.
*
* @access public
* @return string
*/
public function setCompanyByAPI()
{
$apiConfig = $this->getApiConfig();
$apiURL = $this->config->admin->apiRoot . "/user-apiSetCompany.json";
$params['u'] = $this->config->global->community;
$params['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
$params[$apiConfig->sessionVar] = $apiConfig->sessionID;
$params['k'] = $this->getSignature($params);
$param = http_build_query($params);
return $this->postAPI($apiURL . '?' . $param, $_POST);
}
/**
* Get signature.
*
* @param array $params
* @access public
* @return string
*/
public function getSignature($params)
{
unset($params['u']);
$privateKey = $this->config->global->ztPrivateKey;
return md5(http_build_query($params) . md5($privateKey));
}
/**
* Get api config.
*
* @access public
* @return object
*/
public function getApiConfig()
{
if(!$this->session->apiConfig or time() - $this->session->apiConfig->serverTime > $this->session->apiConfig->expiredTime)
{
$config = file_get_contents($this->config->admin->apiRoot . "?mode=getconfig");
$config = json_decode($config);
if(empty($config) or empty($config->sessionID)) return null;
$this->session->set('apiConfig', $config);
}
return $this->session->apiConfig;
}
/**
* Get register information.
*
* @access public
* @return object
*/
public function getRegisterInfo()
{
$register = new stdclass();
$register->company = $this->app->company->name;
$register->email = $this->app->user->email;
return $register;
}
$register->company = $this->app->company->name;
$register->email = $this->app->user->email;
return $register;
}
}
+6 -2
View File
@@ -22,14 +22,18 @@
<table align='center' class='table table-form'>
<tr>
<th class='w-100px'><?php echo $lang->user->account;?></th>
<td><?php echo html::input('account', '', "class='form-control'");?></td>
<?php
$account = zget($config->global, 'community', '');
if($account == 'na') $account = '';
?>
<td><?php echo html::input('account', $account, "class='form-control' autocomplete='off'");?></td>
</tr>
<tr>
<th><?php echo $lang->user->password;?></th>
<td><?php echo html::password('password', '', "class='form-control'");?></td>
</tr>
<tr>
<th></th><td class="text-center"><?php echo html::submitButton() . html::hidden('sn', $sn);?></td>
<th></th><td class="text-center"><?php echo html::submitButton() . html::hidden('sn', $sn) . html::hidden('site', common::getSysURL());?></td>
</tr>
</table>
</form>
+62
View File
@@ -0,0 +1,62 @@
<?php
/**
* The certifyztmobile view file of admin 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 admin
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div class='container mw-700px' id='checkEmail'>
<div id='titlebar'>
<div class='heading'><strong><?php echo $lang->admin->certifyEmail;?></strong></div>
</div>
<form method='post' target='hiddenwin'>
<table class='table table-form'>
<tr>
<th><?php echo $lang->user->email;?></th>
<td><?php echo html::input('email', $email, "class='form-control' autocomplete='off'");?></td>
<td><?php echo html::a(inlink('ajaxsendcode', 'type=email'), $lang->admin->getCaptcha, '', "id='codeSender' class='btn'");?></td>
</tr>
<tr>
<th><?php echo $lang->admin->captcha;?></th>
<td><?php echo html::input('captcha', '', "class='form-control' autocomplete='off'");?></td>
</tr>
<tr>
<th></th>
<td><?php echo html::submitButton();?></td>
</tr>
</table>
</form>
</div>
<script>
$(function()
{
$('#codeSender').click(function()
{
var data = {email: $('#email').val()};
var url = $(this).attr('href');
$.post(url, data, function(response)
{
if(response.result == 'success')
{
$('#codeSender').popover({trigger:'manual', content:response.message, placement:'right'}).popover('show');
$('#codeSender').next('.popover').addClass('popover-success');
function distroy(){$('#codeSender').popover('destroy')}
setTimeout(distroy,2000);
}
else
{
bootbox.alert(response.message);
}
}, 'json')
return false;
})
});
</script>
<?php include '../../common/view/footer.html.php';?>
@@ -0,0 +1,62 @@
<?php
/**
* The certifyztmobile view file of admin 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 admin
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div class='container mw-700px' id='checkMobile'>
<div id='titlebar'>
<div class='heading'><strong><?php echo $lang->admin->certifyMobile;?></strong></div>
</div>
<form method='post' target='hiddenwin'>
<table class='table table-form'>
<tr>
<th><?php echo $lang->user->mobile;?></th>
<td><?php echo html::input('mobile', $mobile, "class='form-control' autocomplete='off'");?></td>
<td><?php echo html::a(inlink('ajaxsendcode', 'type=mobile'), $lang->admin->getCaptcha, '', "id='codeSender' class='btn'");?></td>
</tr>
<tr>
<th><?php echo $lang->admin->captcha;?></th>
<td><?php echo html::input('captcha', '', "class='form-control' autocomplete='off'");?></td>
</tr>
<tr>
<th></th>
<td><?php echo html::submitButton();?></td>
</tr>
</table>
</form>
</div>
<script>
$(function()
{
$('#codeSender').click(function()
{
var data = {mobile: $('#mobile').val()};
var url = $(this).attr('href');
$.post(url, data, function(response)
{
if(response.result == 'success')
{
$('#codeSender').popover({trigger:'manual', content:response.message, placement:'right'}).popover('show');
$('#codeSender').next('.popover').addClass('popover-success');
function distroy(){$('#codeSender').popover('destroy')}
setTimeout(distroy,2000);
}
else
{
bootbox.alert(response.message);
}
}, 'json')
return false;
})
});
</script>
<?php include '../../common/view/footer.html.php';?>
+149 -59
View File
@@ -11,65 +11,155 @@
*/
?>
<?php include '../../common/view/header.html.php';?>
<div class='container mw-700px'>
<div id='titlebar'>
<div class='heading'>
<span class='prefix'><?php echo html::icon('cloud');?></span>
<strong><?php echo $lang->admin->register->caption;?></strong>
</div>
<style>
.input-group .input-group-btn .popover{font-size:12px;}
.input-group-btn .btn{border-left:0px}
.input-group:last-child .input-group-addon {border-right:0px;}
</style>
<div id='featurebar'>
<div class='heading'>
<span class='prefix'><?php echo html::icon('cloud');?></span>
<strong><?php echo $lang->admin->register->caption;?></strong>
</div>
<div class='alert'>
<div class='pull-right'><?php echo html::a(inlink('bind'), $lang->admin->bind->caption, '', "class='btn btn-success'");?></div>
<i class='icon-info-sign'></i>
<div class='content'>
<?php echo sprintf($lang->admin->register->bind, html::a(inlink('bind'), $lang->admin->register->click));?>
</div>
</div>
<form class='form-condensed mw-600px' method="post" target="hiddenwin">
<table align='center' class='table table-form'>
<tr>
<th class='w-100px'><?php echo $lang->user->account;?></th>
<td>
<div class="required required-wrapper"></div>
<?php echo html::input('account', '', "class='form-control'");?>
<div class='help-block'><?php echo $lang->admin->register->lblAccount;?></div>
</td>
</tr>
<tr>
<th><?php echo $lang->user->realname;?></th>
<td><div class="required required-wrapper"></div><?php echo html::input('realname', '', "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->user->company;?></th>
<td><?php echo html::input('company', $register->company, "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->user->phone;?></th>
<td><?php echo html::input('phone', '', "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->user->email;?></th>
<td><div class="required required-wrapper"></div><?php echo html::input('email', $register->email, "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->user->password;?></th>
<td>
<div class="required required-wrapper"></div>
<?php echo html::password('password1', '', "class='form-control'");?>
<div class='help-block'><?php echo $lang->admin->register->lblPasswd;?></div>
</td>
</tr>
<tr>
<th><?php echo $lang->user->password2;?></th>
<td><?php echo html::password('password2', '', "class='form-control'") . '<span class="star">*</span>';?></td>
</tr>
<tr>
<th></th>
<td colspan="2">
<?php echo html::submitButton($lang->admin->register->submit) . html::hidden('sn', $sn);?>
</td>
</tr>
</table>
</form>
</div>
<div class='row'>
<div class='col-md-6'>
<div class='panel'>
<div class='panel-heading'><strong><?php echo $lang->admin->register->common?></strong></div>
<form class='form-condensed mw-600px' method="post" target="hiddenwin">
<table align='center' class='table table-form'>
<tr>
<th class='w-100px'><?php echo $lang->user->account;?></th>
<td>
<div class="required required-wrapper"></div>
<?php echo html::input('account', '', "class='form-control' placeholder='{$lang->admin->register->lblAccount}' autocomplete='off'");?>
</td>
</tr>
<tr>
<th><?php echo $lang->user->realname;?></th>
<td><div class="required required-wrapper"></div><?php echo html::input('realname', '', "class='form-control' autocomplete='off'");?></td>
</tr>
<tr>
<th><?php echo $lang->user->company;?></th>
<td><div class="required required-wrapper"></div><?php echo html::input('company', $register->company, "class='form-control' autocomplete='off'");?></td>
</tr>
<tr>
<th><?php echo $lang->user->mobile;?></th>
<td>
<div class="required required-wrapper"></div>
<div class='input-group'>
<?php echo html::input('mobile', '', "class='form-control' autocomplete='off'");?>
<span class='input-group-btn'><?php echo html::a(inlink('ajaxSendCode', 'type=mobile'), $lang->admin->getCaptcha, '', "id='mobileSender' class='btn'")?></span>
<span class='input-group-addon' style='border:0px;background:none'></span>
<span class='input-group-addon'><?php echo $lang->admin->captcha?></span>
<?php echo html::input('mobileCode', '', "class='form-control' autocomplete='off'");?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->user->email;?></th>
<td>
<div class="required required-wrapper"></div>
<div class='input-group'>
<?php echo html::input('email', $register->email, "class='form-control' autocomplete='off'");?>
<span class='input-group-btn'><?php echo html::a(inlink('ajaxSendCode', 'type=email'), $lang->admin->getCaptcha, '', "id='mailSender' class='btn'")?></span>
<span class='input-group-addon' style='border:0px;background:none'></span>
<span class='input-group-addon'><?php echo $lang->admin->captcha?></span>
<?php echo html::input('emailCode', '', "class='form-control' autocomplete='off'");?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->user->password;?></th>
<td>
<div class="required required-wrapper"></div>
<?php echo html::password('password1', '', "class='form-control' placeholder='{$lang->admin->register->lblPasswd}'");?>
</td>
</tr>
<tr>
<th><?php echo $lang->user->password2;?></th>
<td><?php echo html::password('password2', '', "class='form-control'") . '<span class="star">*</span>';?></td>
</tr>
<tr>
<th></th>
<td colspan="2">
<?php echo html::submitButton($lang->admin->register->submit) . html::hidden('sn', $sn) . html::hidden('bindSite', common::getSysURL());?>
</td>
</tr>
</table>
</form>
</div>
</div>
<div class='col-md-6'>
<div class='panel'>
<div class='panel-heading'><strong><?php echo $lang->admin->register->bind?></strong></div>
<form class='form-condensed mw-400px' method="post" target="hiddenwin" action='<?php echo inlink('bind', "from=$from")?>'>
<table align='center' class='table table-form'>
<tr>
<th class='w-100px'><?php echo $lang->user->account;?></th>
<?php
$account = zget($config->global, 'community', '');
if($account == 'na') $account = '';
?>
<td><?php echo html::input('account', $account, "class='form-control' autocomplete='off'");?></td>
</tr>
<tr>
<th><?php echo $lang->user->password;?></th>
<td><?php echo html::password('password', '', "class='form-control'");?></td>
</tr>
<tr>
<th></th><td class="text-center"><?php echo html::submitButton() . html::hidden('sn', $sn) . html::hidden('site', common::getSysURL());?></td>
</tr>
</table>
</form>
</div>
</div>
</div>
<script>
$(function()
{
$('#mobileSender').click(function()
{
var data = {mobile: $('#mobile').val()};
var url = $(this).attr('href');
$.post(url, data, function(response)
{
if(response.result == 'success')
{
$('#mobileSender').popover({trigger:'manual', content:response.message, placement:'right'}).popover('show');
$('#mobileSender').next('.popover').addClass('popover-success');
function distroy(){$('#mobileSender').popover('destroy')}
setTimeout(distroy,2000);
}
else
{
bootbox.alert(response.message);
}
}, 'json')
return false;
})
$('#mailSender').click(function()
{
var data = {email: $('#email').val()};
var url = $(this).attr('href');
$.post(url, data, function(response)
{
if(response.result == 'success')
{
$('#mailSender').popover({trigger:'manual', content:response.message, placement:'right'}).popover('show');
$('#mailSender').next('.popover').addClass('popover-success');
function distroy(){$('#mailSender').popover('destroy')}
setTimeout(distroy,2000);
}
else
{
bootbox.alert(response.message);
}
}, 'json')
return false;
})
});
</script>
<?php include '../../common/view/footer.html.php';?>
+32 -4
View File
@@ -21,18 +21,26 @@
<form method='post' target='hiddenwin'>
<table class='table table-form'>
<tr>
<th class='w-100px'><?php echo $lang->admin->safe->password?></th>
<td><?php echo html::radio('mode', $lang->admin->safe->modeList, isset($config->safe->mode) ? $config->safe->mode : 0)?></td>
<th class='w-130px'><?php echo $lang->admin->safe->password?></th>
<td><?php echo html::radio('mode', $lang->admin->safe->modeList, isset($config->safe->mode) ? $config->safe->mode : 0, "onclick=showModeRule(this.value)")?></td>
<td><?php echo $lang->admin->safe->noticeMode?></td>
</tr>
<tr>
<tr id='mode1Rule' class='hidden'>
<th></th>
<td colspan='2'><span style='color:#03b8cf;font-weight:bold;'><?php echo $lang->admin->safe->noticeStrong;?></span></td>
<td colspan='2'><span style='color:#03b8cf;font-weight:bold;'><?php echo $lang->admin->safe->modeRuleList[1] . $lang->admin->safe->noticeStrong;?></span></td>
</tr>
<tr id='mode2Rule' class='hidden'>
<th></th>
<td colspan='2'><span style='color:#03b8cf;font-weight:bold;'><?php echo $lang->admin->safe->modeRuleList[2] . $lang->admin->safe->noticeStrong;?></span></td>
</tr>
<tr>
<th><?php echo $lang->admin->safe->weak?></th>
<td colspan='2'><?php echo html::textarea('weak', $config->safe->weak, "class='form-control' rows='4'")?></td>
</tr>
<tr>
<th><?php echo $lang->admin->safe->modifyPasswordFirstLogin?></th>
<td colspan='2'><?php echo html::radio('modifyPasswordFirstLogin', $lang->admin->safe->modifyPasswordList, isset($config->safe->modifyPasswordFirstLogin) ? $config->safe->modifyPasswordFirstLogin : 0)?></td>
</tr>
<tr>
<th></th>
<td colspan='2'><?php echo html::submitButton();?></td>
@@ -40,4 +48,24 @@
</table>
</form>
</div>
<script>
$(function()
{
var mode = $("input[name='mode']:checked").val();
showModeRule(mode);
});
function showModeRule(mode)
{
if(mode == 0)
{
$('#mode1Rule').addClass('hidden');
$('#mode2Rule').addClass('hidden');
}
else
{
mode == 1 ? $('#mode1Rule').removeClass('hidden') : $('#mode1Rule').addClass('hidden');
mode == 2 ? $('#mode2Rule').removeClass('hidden') : $('#mode2Rule').addClass('hidden');
}
}
</script>
<?php include '../../common/view/footer.html.php';?>
+3 -3
View File
@@ -26,15 +26,15 @@
</tr>
<tr>
<th><?php echo $lang->sso->addr; ?></th>
<td><?php echo html::input('addr', $addr, "class='form-control' placeholder='{$lang->sso->addrNotice}'");?></td>
<td><?php echo html::input('addr', $addr, "class='form-control' placeholder='{$lang->sso->addrNotice}' autocomplete='off'");?></td>
</tr>
<tr>
<th><?php echo $lang->sso->code; ?></th>
<td><?php echo html::input('code', $code, "class='form-control'");?></td>
<td><?php echo html::input('code', $code, "class='form-control' autocomplete='off'");?></td>
</tr>
<tr>
<th><?php echo $lang->sso->key; ?></th>
<td><?php echo html::input('key', $key, "class='form-control'");?></td>
<td><?php echo html::input('key', $key, "class='form-control' autocomplete='off'");?></td>
</tr>
<tr>
<td colspan='2' class='text-center'>
+33
View File
@@ -0,0 +1,33 @@
<?php
/**
* The ztcomany view file of admin 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 admin
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<div class='container mw-500px'>
<div id='titlebar'>
<div class='heading'><strong><?php echo $lang->admin->ztCompany;?></strong></div>
</div>
<form method='post' target='hiddenwin'>
<table class='table table-form'>
<?php foreach($fields as $field):?>
<tr>
<th><?php echo $field == 'company' ? $lang->company->name : $lang->user->$field;?></th>
<td><?php echo html::input($field, '', "class='form-control' autocomplete='off'");?></td>
</tr>
<?php endforeach;?>
<tr>
<th></th>
<td><?php echo html::submitButton();?></td>
</tr>
</table>
</form>
</div>
<?php include '../../common/view/footer.html.php';?>
+1 -1
View File
@@ -16,7 +16,7 @@
<?php foreach($method->parameters as $param):?>
<tr>
<th class='w-80px'><?php echo $param->name?></th>
<td><?php echo html::input("$param->name", $param->isOptional() ? $param->getDefaultValue() : '', "class='form-control'")?></td>
<td><?php echo html::input("$param->name", $param->isOptional() ? $param->getDefaultValue() : '', "class='form-control' autocomplete='off'")?></td>
</tr>
<?php endforeach;?>
<tr>
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
$lang->backup->common = 'Backup';
$lang->backup->index = 'Homepage';
$lang->backup->index = 'Home';
$lang->backup->history = 'History';
$lang->backup->delete = 'Delete';
$lang->backup->backup = 'Backup';
+1 -1
View File
@@ -40,7 +40,7 @@ class backupModel extends model
$this->app->loadClass('pclzip', true);
$zip = new pclzip($backupFile);
$zip->create($this->app->getAppRoot() . 'www/data/', PCLZIP_OPT_REMOVE_PATH, $this->app->getAppRoot() . 'www/data/');
if($zip->errorCode != 0)
if($zip->errorCode() != 0)
{
$return->result = false;
$return->error = $zip->errorInfo();
+1 -1
View File
@@ -23,7 +23,7 @@
<tr>
<td>
<div class='input-group'>
<?php echo html::input('holdDays', $config->backup->holdDays, "class='form-control'");?>
<?php echo html::input('holdDays', $config->backup->holdDays, "class='form-control' autocomplete='off'");?>
<strong class='input-group-addon'><?php echo $lang->day;?></strong>
</div>
</td>
+2 -2
View File
@@ -90,7 +90,7 @@ class block extends control
}
$block = $this->block->getByID($id);
if($block) $type = $block->block;
if($block and empty($type)) $type = $block->block;
if(isset($this->lang->block->moduleList[$source]))
{
@@ -338,7 +338,7 @@ class block extends control
$sso = base64_decode($this->get->sso);
$this->view->sso = $sso;
$this->view->sign = strpos($sso, '&') === false ? '?' : '&';
$this->view->sign = strpos($sso, '?') === false ? '?' : '&';
}
$this->viewType = (isset($params->viewType) and $params->viewType == 'json') ? 'json' : 'html';
+2
View File
@@ -4,3 +4,5 @@
.dropdown-menu.buttons {padding: 5px; padding-bottom: 0; padding-right: 0;}
.dropdown-menu.buttons > li {margin-bottom: 5px; display: block; float: left; width: 33.333333%; padding-right: 5px}
.table.table-form{margin-bottom:0px;}
#blockParam{padding-right:100px;}
#blockParam .table td, #blockParam .table th{border-bottom:0px;}
+3
View File
@@ -60,6 +60,9 @@ function getNotSourceParams(type, blockID)
function getBlockParams(type, moduleID)
{
$('#blockParam').empty();
if(type == '') return;
$.get(createLink('block', 'set', 'id=' + blockID + '&type=' + type + '&source=' + moduleID), function(data)
{
$('#blockParam').html(data);
+3 -2
View File
@@ -87,9 +87,10 @@ function initTableHeader()
$panel.toggleClass('with-fixed-header', isFixed);
var $header = $panel.children('.table-header-fixed').toggle(isFixed);
if(!isFixed) return;
var tableWidth = $table.width();
if(!$header.length)
{
$header = $('<div class="table-header-fixed" style="position: absolute; left: 0; top: 0; right: 0;"><table class="table table-fixed"></table></div>').css('right', $panel.width() - $table.width()).css('min-width', $table.width());
$header = $('<div class="table-header-fixed" style="position: absolute; left: 0; top: 0; right: 0;"><table class="table table-fixed"></table></div>').css('right', $panel.width() - tableWidth).css('min-width', tableWidth);
$header.find('.table').addClass($table.attr('class')).append($table.find('thead').css('visibility', 'hidden').clone().css('visibility', 'visible'));
$panel.addClass('with-fixed-header').append($header);
var $heading = $panel.children('.panel-heading');
@@ -97,7 +98,7 @@ function initTableHeader()
}
else
{
var $fixedTh = $header.css('min-width', $table.width()).find('thead > tr > th');
var $fixedTh = $header.css('min-width', tableWidth).css('right', $panel.width() - tableWidth).find('thead > tr > th');
$table.find('thead > tr > th').each(function(idx)
{
$fixedTh.eq(idx).width($(this).width());
+28 -28
View File
@@ -10,27 +10,27 @@
* @link http://www.ranzhi.org
*/
$lang->block = new stdclass();
$lang->block->common = 'Block';
$lang->block->common = 'Widget';
$lang->block->name = 'Name';
$lang->block->style = 'Style';
$lang->block->grid = 'Grid';
$lang->block->color = 'Color';
$lang->block->lblModule = 'Module';
$lang->block->lblBlock = 'Block';
$lang->block->lblBlock = 'Widget';
$lang->block->lblNum = 'Number';
$lang->block->lblHtml = 'HTML';
$lang->block->dynamic = 'Dynamic';
$lang->block->lblFlowchart = 'Flowchart';
$lang->block->lblFlowchart = 'Workflow';
$lang->block->params = new stdclass();
$lang->block->params->name = 'Name';
$lang->block->params->value = 'Value';
$lang->block->createBlock = 'Add Block';
$lang->block->editBlock = 'Edit Block';
$lang->block->ordersSaved = 'Sequence saved.';
$lang->block->confirmRemoveBlock = 'Do you want to remove Block【{0}】?';
$lang->block->createBlock = 'Create Widget';
$lang->block->editBlock = 'Edit';
$lang->block->ordersSaved = 'Ranking is saved.';
$lang->block->confirmRemoveBlock = 'Do you want to remove Widget【{0}】?';
$lang->block->refresh = 'Refresh';
$lang->block->hidden = 'Hide';
$lang->block->dynamicInfo = "%s, %s <em>%s</em> %s <a href='%s'>%s</a>.";
@@ -118,21 +118,21 @@ $lang->block->default['my']['9']['source'] = 'qa';
$lang->block->num = 'Number';
$lang->block->type = 'Type';
$lang->block->orderBy = 'Sequence';
$lang->block->orderBy = 'Ranking';
$lang->block->availableBlocks = new stdclass();
$lang->block->availableBlocks->todo = 'My To-Dos';
$lang->block->availableBlocks->task = 'My Task';
$lang->block->availableBlocks->bug = 'My Bug';
$lang->block->availableBlocks->case = 'My Case';
$lang->block->availableBlocks->story = 'My Story';
$lang->block->availableBlocks->task = 'My Tasks';
$lang->block->availableBlocks->bug = 'My Bugs';
$lang->block->availableBlocks->case = 'My Cases';
$lang->block->availableBlocks->story = 'My Stories';
$lang->block->availableBlocks->product = $lang->productCommon . 'List';
$lang->block->availableBlocks->project = $lang->projectCommon . 'List';
$lang->block->availableBlocks->plan = 'Planning List';
$lang->block->availableBlocks->plan = 'Plans';
$lang->block->availableBlocks->release = 'Release List';
$lang->block->availableBlocks->build = 'Build List';
$lang->block->availableBlocks->testtask = 'Test Build List';
$lang->block->availableBlocks->build = 'Builds';
$lang->block->availableBlocks->testtask = 'Test Builds';
$lang->block->moduleList['product'] = $lang->productCommon;
$lang->block->moduleList['project'] = $lang->projectCommon;
@@ -142,22 +142,22 @@ $lang->block->moduleList['todo'] = 'To-Dos';
$lang->block->modules['product'] = new stdclass();
$lang->block->modules['product']->availableBlocks = new stdclass();
$lang->block->modules['product']->availableBlocks->list = $lang->productCommon . 'List';
$lang->block->modules['product']->availableBlocks->story = 'Story List';
$lang->block->modules['product']->availableBlocks->plan = 'Planning List';
$lang->block->modules['product']->availableBlocks->story = 'Stories';
$lang->block->modules['product']->availableBlocks->plan = 'Plans';
$lang->block->modules['product']->availableBlocks->release = 'Release List';
$lang->block->modules['project'] = new stdclass();
$lang->block->modules['project']->availableBlocks = new stdclass();
$lang->block->modules['project']->availableBlocks->list = $lang->projectCommon . 'List';
$lang->block->modules['project']->availableBlocks->task = 'Task List';
$lang->block->modules['project']->availableBlocks->build = 'Build List';
$lang->block->modules['project']->availableBlocks->task = 'Tasks';
$lang->block->modules['project']->availableBlocks->build = 'Builds';
$lang->block->modules['qa'] = new stdclass();
$lang->block->modules['qa']->availableBlocks = new stdclass();
$lang->block->modules['qa']->availableBlocks->bug = 'Bug List';
$lang->block->modules['qa']->availableBlocks->case = 'Case List';
$lang->block->modules['qa']->availableBlocks->testtask = 'Test Build List';
$lang->block->modules['qa']->availableBlocks->bug = 'Bugs';
$lang->block->modules['qa']->availableBlocks->case = 'Cases';
$lang->block->modules['qa']->availableBlocks->testtask = 'Test Builds';
$lang->block->modules['todo'] = new stdclass();
$lang->block->modules['todo']->availableBlocks = new stdclass();
$lang->block->modules['todo']->availableBlocks->list = 'To-Do List';
$lang->block->modules['todo']->availableBlocks->list = 'To-Dos';
$lang->block->orderByList = new stdclass();
@@ -247,8 +247,8 @@ $lang->block->modules['common']->moreLinkList = new stdclass();
$lang->block->modules['common']->moreLinkList->dynamic = 'company|dynamic|';
$lang->block->flowchart = array();
$lang->block->flowchart[] = array('Admin', 'Manage a Company', 'Add User', 'Maintain Privilege');
$lang->block->flowchart[] = array('Product Manager', 'Add Product', 'Maintain a Module', 'Maintain Planning', 'Maintain a Story', 'Create Release');
$lang->block->flowchart[] = array('Project Manager', 'Add Project', 'MaintainTeam', 'Link a Product', 'Link a Story', 'Decompose a Task');
$lang->block->flowchart[] = array('R&D Team', 'Claim a Task/Bug', 'Update Status', 'Finish a Task/Bug');
$lang->block->flowchart[] = array('Testing Team', 'Write a Case', 'Implement a Case', 'Submit a Bug', 'Bug', 'Off a Bug');
$lang->block->flowchart[] = array('Administration', 'Manage a Company', 'Add Users', 'Maintain Privileges');
$lang->block->flowchart[] = array('Product Manager', 'Add Products', 'Maintain Modules', 'Maintain Plans', 'Maintain Stories', 'Create Release');
$lang->block->flowchart[] = array('Project Manager', 'Add Projects', 'Maintain Teams', 'Link Products', 'Link Stories', 'Decompose Tasks');
$lang->block->flowchart[] = array('DEV Team', 'Claim TaskS/Bugs', 'Update Status', 'Finish Tasks/Bugs');
$lang->block->flowchart[] = array('Testing Team', 'Write Cases', 'Implement Cases', 'Report Bugs', 'Fix Bugs', 'Close Bugs');
+1 -1
View File
@@ -14,7 +14,7 @@
<?php js::set('blockID', $blockID)?>
<?php if(isset($pageJS)) js::execute($pageJS);?>
<table class='table table-form'>
<tr><th class='w-100px'></th><td></td></tr>
<tr><th class='w-100px'></th><td></td><td class='w-100px'></td></tr>
<?php if(!empty($modules)):?>
<tr>
<th class='w-100px'><?php echo $lang->block->lblModule; ?></th>
+1 -1
View File
@@ -28,7 +28,7 @@ $useGuest = $this->app->user->account == 'guest';
<div class='panel-heading'>
<div class='panel-actions'>
<?php if(!empty($block->moreLink)):?>
<?php echo html::a($block->moreLink, $lang->more . " <i class='icon-double-angle-right'></i>", null, "class='panel-action drag-disabled panel-action-more'"); ?>
<?php echo html::a($block->moreLink, " <i class='icon icon-more'></i>", null, "class='panel-action drag-disabled panel-action-more'"); ?>
<?php endif; ?>
<div class='dropdown'>
<a href='javascript:;' data-toggle='dropdown' class='panel-action'><i class='icon icon-ellipsis-v'></i></a>
+1 -1
View File
@@ -10,7 +10,7 @@
* @link http://www.zentao.net
*/
?>
<table class='table table-data table-hover table-fixed table-striped table-borderless block-product'>
<table class='table table-data table-hover table-fixed table-striped block-product'>
<thead>
<tr class='text-center'>
<th class='text-left'><?php echo $lang->product->name;?></th>
+1 -1
View File
@@ -12,7 +12,7 @@
?>
<tr>
<th class='w-100px'><?php echo $lang->block->name?></th>
<td><?php echo html::input('title', $block ? $block->title : '', "class='form-control'")?></td>
<td><?php echo html::input('title', $block ? $block->title : '', "class='form-control' autocomplete='off'")?></td>
</tr>
<tr>
<th><?php echo $lang->block->style;?></th>
+14 -2
View File
@@ -38,6 +38,17 @@ class branch extends control
$this->display();
}
/**
* Sort branch.
*
* @access public
* @return void
*/
public function sort()
{
$this->branch->sort();
}
/**
* Ajax get drop menu.
*
@@ -89,10 +100,11 @@ class branch extends control
*/
public function delete($branchID, $confirm = 'no')
{
$this->app->loadLang('product');
$productType = $this->branch->getProductType($branchID);
if(!$this->branch->checkBranchData($branchID)) die(js::alert(str_replace('@branch@', $this->lang->product->branchName[$productType], $this->lang->branch->canNotDelete)));
if($confirm == 'no')
{
$this->app->loadLang('product');
$productType = $this->branch->getProductType($branchID);
die(js::confirm(str_replace('@branch@', $this->lang->product->branchName[$productType], $this->lang->branch->confirmDelete), inlink('delete', "branchID=$branchID&confirm=yes")));
}
+5 -1
View File
@@ -1 +1,5 @@
#branches .input-group{margin-bottom:5px; width:100%}
#branches .input-group, #newbranches .input-group{margin-bottom:5px; width:100%}
#branches .input-group input, #newbranches .input-group input{border-right:0px;}
#branches .sort-handler{cursor: move}
#branches .input-group.drag-shadow{z-index:5;}
#branches .input-group.drag-row{opacity:0;}
+21 -4
View File
@@ -1,11 +1,28 @@
function addItem()
function addItem(obj)
{
var $inputgroup = $('#branches .input-group:last');
$('#branches').append($inputgroup.clone()).find('.input-group:last').find('input').val('');
var $inputgroup = $(obj).closest('.input-group').clone();
$inputgroup.find('input').val('');
$(obj).closest('.input-group').after($inputgroup);
}
function deleteItem(obj)
{
if($(obj).closest('#branches').find("input[id^='newbranch']").size() <= 1) return;
if($(obj).closest('#newbranches').find("input[id^='newbranch']").size() <= 1) return;
$(obj).closest('.input-group').remove();
}
$(function()
{
$('#branches').sortable(
{
selector: '.input-group',
dragCssClass: 'drag-row',
trigger: $('#branches').find('.sort-handler').length ? '.sort-handler' : null,
finish: function(e)
{
var list = '';
$('#branches').find('.input-group').each(function(){list += $(this).attr('data-id') + ',';});
$.post(createLink('branch', 'sort'), {'branches' : list});
}
});
});
+3 -1
View File
@@ -1,9 +1,11 @@
<?php
$lang->branch->common = 'Branch';
$lang->branch->manage = 'Manage a Branch';
$lang->branch->sort = 'Sort';
$lang->branch->delete = 'Delete Branch';
$lang->branch->manageTitle = '%s Management';
$lang->branch->all = 'All';
$lang->branch->confirmDelete = '@branch@ Delete will affect @branch@ related Story、Module、Planning、Release、Bug、Case, etc. Please think before you delete this @branch@.';
$lang->branch->confirmDelete = 'Do you want to delete this @branch@?';
$lang->branch->canNotDelete = 'There is data in @branch@. It cannot be deleted.';
+3 -1
View File
@@ -1,9 +1,11 @@
<?php
$lang->branch->common = '分支';
$lang->branch->manage = '分支管理';
$lang->branch->sort = '排序';
$lang->branch->delete = '分支删除';
$lang->branch->manageTitle = '%s管理';
$lang->branch->all = '所有';
$lang->branch->confirmDelete = '@branch@删除,会影响关联该@branch@的需求、模块、计划、发布、Bug、用例等等,请慎重考虑。是否删除该@branch@';
$lang->branch->confirmDelete = '是否删除该@branch@?';
$lang->branch->canNotDelete = '该@branch@下已经有数据,不能删除!';
+3 -1
View File
@@ -1,9 +1,11 @@
<?php
$lang->branch->common = '分支';
$lang->branch->manage = '分支管理';
$lang->branch->sort = '排序';
$lang->branch->delete = '分支刪除';
$lang->branch->manageTitle = '%s管理';
$lang->branch->all = '所有';
$lang->branch->confirmDelete = '@branch@刪除,會影響關聯該@branch@的需求、模組、計劃、發佈、Bug、用例等等,請慎重考慮。是否刪除該@branch@';
$lang->branch->confirmDelete = '是否刪除該@branch@?';
$lang->branch->canNotDelete = '該@branch@下已經有數據,不能刪除!';
+39 -4
View File
@@ -39,7 +39,7 @@ class branchModel extends model
*/
public function getPairs($productID, $params = '')
{
$branches = $this->dao->select('*')->from(TABLE_BRANCH)->where('product')->eq($productID)->andWhere('deleted')->eq(0)->orderBy('id_asc')->fetchPairs('id', 'name');
$branches = $this->dao->select('*')->from(TABLE_BRANCH)->where('product')->eq($productID)->andWhere('deleted')->eq(0)->orderBy('`order`')->fetchPairs('id', 'name');
if(strpos($params, 'noempty') === false)
{
$product = $this->loadModel('product')->getById($productID);
@@ -68,10 +68,10 @@ class branchModel extends model
if($oldBranches[$branchID] != $branch) $this->dao->update(TABLE_BRANCH)->set('name')->eq($branch)->where('id')->eq($branchID)->exec();
}
}
foreach($data->newbranch as $branch)
foreach($data->newbranch as $i => $branch)
{
if(empty($branch)) continue;
$this->dao->insert(TABLE_BRANCH)->set('name')->eq($branch)->set('product')->eq($productID)->exec();
$this->dao->insert(TABLE_BRANCH)->set('name')->eq($branch)->set('product')->eq($productID)->set('`order`')->eq(count($data->branch) + $i + 1)->exec();
}
return dao::isError();
@@ -87,7 +87,7 @@ class branchModel extends model
*/
public function getByProducts($products, $params = '')
{
$branches = $this->dao->select('*')->from(TABLE_BRANCH)->where('product')->in($products)->andWhere('deleted')->eq(0)->fetchAll();
$branches = $this->dao->select('*')->from(TABLE_BRANCH)->where('product')->in($products)->andWhere('deleted')->eq(0)->orderBy('`order`')->fetchAll();
$products = $this->loadModel('product')->getByIdList($products);
$branchGroups = array();
@@ -121,4 +121,39 @@ class branchModel extends model
->where('t1.id')->eq($branchID)
->fetch('type');
}
/**
* Sort branch.
*
* @access public
* @return void
*/
public function sort()
{
$data = fixer::input('post')->get();
$branches = trim($data->branches, ',');
foreach(explode(',', $branches) as $order => $branchID)
{
$this->dao->update(TABLE_BRANCH)->set('`order`')->eq($order)->where('id')->eq($branchID)->exec();
}
}
/**
* Check branch data.
*
* @param int $branchID
* @access public
* @return bool
*/
public function checkBranchData($branchID)
{
$module = $this->dao->select('id')->from(TABLE_MODULE)->where('branch')->eq($branchID)->andWhere('deleted')->eq(0)->limit(1)->fetch();
$story = $this->dao->select('id')->from(TABLE_STORY)->where('branch')->eq($branchID)->andWhere('deleted')->eq(0)->limit(1)->fetch();
$plan = $this->dao->select('id')->from(TABLE_PRODUCTPLAN)->where('branch')->eq($branchID)->andWhere('deleted')->eq(0)->limit(1)->fetch();
$bug = $this->dao->select('id')->from(TABLE_BUG)->where('branch')->eq($branchID)->andWhere('deleted')->eq(0)->limit(1)->fetch();
$case = $this->dao->select('id')->from(TABLE_CASE)->where('branch')->eq($branchID)->andWhere('deleted')->eq(0)->limit(1)->fetch();
$release = $this->dao->select('id')->from(TABLE_RELEASE)->where('branch')->eq($branchID)->andWhere('deleted')->eq(0)->limit(1)->fetch();
$build = $this->dao->select('id')->from(TABLE_BUILD)->where('branch')->eq($branchID)->andWhere('deleted')->eq(0)->limit(1)->fetch();
return empty($module) and empty($story) and empty($bug) and empty($case) and empty($release) and empty($build) and empty($plan);
}
}
+12 -2
View File
@@ -22,12 +22,22 @@
<td class="w-300px">
<div id='branches'>
<?php foreach($branches as $branchID => $branch):?>
<div class='input-group'><?php echo html::input("branch[$branchID]", $branch, "class='form-control'")?></div>
<div class='input-group' data-id='<?php echo $branchID?>'>
<?php echo html::input("branch[$branchID]", $branch, "class='form-control'")?>
<?php if(common::hasPriv('branch', 'sort')):?>
<span class='input-group-addon sort-handler'><a><i class='icon icon-move'></i></a></span>
<?php endif;?>
<?php if(common::hasPriv('branch', 'delete')):?>
<span class='input-group-addon'><?php echo html::a(inlink('delete', "branchID=$branchID"), "<i class='icon icon-remove'></i>", 'hiddenwin')?></span>
<?php endif;?>
</div>
<?php endforeach;?>
</div>
<div id='newbranches'>
<?php for($i = 0; $i < 2; $i++):?>
<div class='input-group'>
<?php echo html::input("newbranch[]", '', "class='form-control'")?>
<span class='input-group-addon'><a href='javascript:;' onclick='addItem()'><i class='icon icon-plus'></i></a></span>
<span class='input-group-addon'><a href='javascript:;' onclick='addItem(this)'><i class='icon icon-plus'></i></a></span>
<span class='input-group-addon'><a href='javascript:;' onclick='deleteItem(this)'><i class='icon icon-remove'></i></a></span>
</div>
<?php endfor;?>
+6 -5
View File
@@ -1,6 +1,7 @@
<?php
$config->bug = new stdClass();
$config->bug->batchCreate = 10;
$config->bug->longlife = 7;
$config->bug->create = new stdclass();
$config->bug->edit = new stdclass();
@@ -135,11 +136,11 @@ $config->bug->search['params']['mailto'] = array('operator' => '=',
$config->bug->search['params']['openedBuild'] = array('operator' => 'include', 'control' => 'select', 'values' => 'builds');
$config->bug->search['params']['resolvedBuild'] = array('operator' => '=', 'control' => 'select', 'values' => 'builds');
$config->bug->search['params']['openedDate'] = array('operator' => '>=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->bug->search['params']['assignedDate'] = array('operator' => '>=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->bug->search['params']['resolvedDate'] = array('operator' => '>=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->bug->search['params']['closedDate'] = array('operator' => '>=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->bug->search['params']['lastEditedDate']= array('operator' => '>=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->bug->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->bug->search['params']['assignedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->bug->search['params']['resolvedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->bug->search['params']['closedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->bug->search['params']['lastEditedDate']= array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->bug->datatable = new stdclass();
$config->bug->datatable->defaultField = array('id', 'severity', 'pri', 'title', 'status', 'openedBy', 'openedDate', 'assignedTo', 'resolvedBy', 'resolution', 'resolvedDate', 'actions');
+38 -78
View File
@@ -151,11 +151,12 @@ class bug extends control
*
* @param int $productID
* @param string $browseType
* @param int $branchID
* @param int $moduleID
* @access public
* @return void
*/
public function report($productID, $browseType, $moduleID)
public function report($productID, $browseType, $branchID, $moduleID)
{
$this->loadModel('report');
$this->view->charts = array();
@@ -174,7 +175,7 @@ class bug extends control
}
}
$this->bug->setMenu($this->products, $productID);
$this->bug->setMenu($this->products, $productID, $branchID);
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->bug->common . $this->lang->colon . $this->lang->bug->reportChart;
$this->view->position[] = html::a($this->createLink('bug', 'browse', "productID=$productID"), $this->products[$productID]);
$this->view->position[] = $this->lang->bug->reportChart;
@@ -221,7 +222,7 @@ class bug extends control
}
$actionID = $this->action->create('bug', $bugID, 'Opened');
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
$location = $this->createLink('bug', 'browse', "productID={$this->post->product}&branch=$branch&type=byModule&param={$this->post->module}");
$response['locate'] = isset($_SESSION['bugList']) ? $this->session->bugList : $location;
@@ -361,7 +362,7 @@ class bug extends control
if(!empty($_POST))
{
$actions = $this->bug->batchCreate($productID, $branch);
foreach($actions as $bugID => $actionID) $this->sendmail($bugID, $actionID);
foreach($actions as $bugID => $actionID) $this->bug->sendmail($bugID, $actionID);
die(js::locate($this->session->bugList, 'parent'));
}
@@ -395,14 +396,26 @@ class bug extends control
}
/* Set custom. */
foreach(explode(',', $this->config->bug->list->customBatchCreateFields) as $field) $customFields[$field] = $this->lang->bug->$field;
$product = $this->product->getById($productID);
foreach(explode(',', $this->config->bug->list->customBatchCreateFields) as $field)
{
if($product->type != 'normal') $customFields[$product->type] = $this->lang->product->branchName[$product->type];
$customFields[$field] = $this->lang->bug->$field;
}
$showFields = $this->config->bug->custom->batchCreateFields;
if($product->type == 'normal')
{
$showFields = str_replace(array(0 => ",branch,", 1 => ",platform,"), '', ",$showFields,");
$showFields = trim($showFields, ',');
}
$this->view->customFields = $customFields;
$this->view->showFields = $this->config->bug->custom->batchCreateFields;
$this->view->showFields = $showFields;
$this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->bug->batchCreate;
$this->view->position[] = html::a($this->createLink('bug', 'browse', "productID=$productID&branch=$branch"), $this->products[$productID]);
$this->view->position[] = $this->lang->bug->batchCreate;
$this->view->product = $product;
$this->view->productID = $productID;
$this->view->stories = $stories;
$this->view->builds = $builds;
@@ -432,6 +445,8 @@ class bug extends control
if($bug->project and !$this->loadModel('project')->checkPriv($this->project->getByID($bug->project)))
{
echo(js::alert($this->lang->project->accessDenied));
$loginLink = $this->config->requestType == 'GET' ? "?{$this->config->moduleVar}=user&{$this->config->methodVar}=login" : "user{$this->config->requestFix}login";
if(strpos($this->server->http_referer, $loginLink) !== false) die(js::locate(inlink('index')));
die(js::locate('back'));
}
@@ -490,7 +505,7 @@ class bug extends control
if(!empty($files)) $fileAction = $this->lang->addFiles . join(',', $files) . "\n" ;
$actionID = $this->action->create('bug', $bugID, $action, $fileAction . $this->post->comment);
$this->action->logHistory($actionID, $changes);
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
}
$bug = $this->bug->getById($bugID);
@@ -585,7 +600,7 @@ class bug extends control
$actionID = $this->action->create('bug', $bugID, 'Edited');
$this->action->logHistory($actionID, $changes);
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
$bug = $this->bug->getById($bugID);
if($bug->toTask != 0)
@@ -689,7 +704,7 @@ class bug extends control
if(dao::isError()) die(js::error(dao::getError()));
$actionID = $this->action->create('bug', $bugID, 'Assigned', $this->post->comment, $this->post->assignedTo);
$this->action->logHistory($actionID, $changes);
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
if(isonlybody()) die(js::closeModal('parent.parent'));
die(js::locate($this->createLink('bug', 'view', "bugID=$bugID"), 'parent'));
@@ -725,7 +740,7 @@ class bug extends control
$this->loadModel('action');
$actionID = $this->action->create('bug', $bugID, 'Edited');
$this->action->logHistory($actionID, $changes);
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
}
}
die(js::locate($this->session->bugList, 'parent'));
@@ -751,10 +766,11 @@ class bug extends control
if(dao::isError()) die(js::error(dao::getError()));
$actionID = $this->action->create('bug', $bugID, 'Assigned', $this->post->comment, $this->post->assignedTo);
$this->action->logHistory($actionID, $changes);
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
}
}
if($type == 'product') die(js::locate($this->createLink('bug', 'browse', "productID=$projectID")));
if($type == 'my') die(js::locate($this->createLink('my', 'bug')));
die(js::locate($this->createLink('project', 'bug', "projectID=$projectID")));
}
@@ -769,10 +785,11 @@ class bug extends control
{
if(!empty($_POST))
{
$this->bug->confirm($bugID);
$changes = $this->bug->confirm($bugID);
if(dao::isError()) die(js::error(dao::getError()));
$actionID = $this->action->create('bug', $bugID, 'bugConfirmed', $this->post->comment);
$this->sendmail($bugID, $actionID);
$this->action->logHistory($actionID, $changes);
$this->bug->sendmail($bugID, $actionID);
if(isonlybody()) die(js::closeModal('parent.parent'));
die(js::locate($this->createLink('bug', 'view', "bugID=$bugID"), 'parent'));
}
@@ -805,7 +822,7 @@ class bug extends control
foreach($bugIDList as $bugID)
{
$actionID = $this->action->create('bug', $bugID, 'bugConfirmed');
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
}
die(js::locate($this->session->bugList, 'parent'));
}
@@ -827,7 +844,7 @@ class bug extends control
$fileAction = !empty($files) ? $this->lang->addFiles . join(',', $files) . "\n" : '';
$actionID = $this->action->create('bug', $bugID, 'Resolved', $fileAction . $this->post->comment, $this->post->resolution . ($this->post->duplicateBug ? ':' . (int)$this->post->duplicateBug : ''));
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
$bug = $this->bug->getById($bugID);
if($bug->toTask != 0)
@@ -883,7 +900,7 @@ class bug extends control
foreach($bugIDList as $bugID)
{
$actionID = $this->action->create('bug', $bugID, 'Resolved', '', $resolution);
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
}
die(js::locate($this->session->bugList, 'parent'));
}
@@ -903,7 +920,7 @@ class bug extends control
if(dao::isError()) die(js::error(dao::getError()));
$files = $this->loadModel('file')->saveUpload('bug', $bugID);
$actionID = $this->action->create('bug', $bugID, 'Activated', $this->post->comment);
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
if(isonlybody()) die(js::closeModal('parent.parent'));
die(js::locate($this->createLink('bug', 'view', "bugID=$bugID"), 'parent'));
}
@@ -938,7 +955,7 @@ class bug extends control
$this->bug->close($bugID);
if(dao::isError()) die(js::error(dao::getError()));
$actionID = $this->action->create('bug', $bugID, 'Closed', $this->post->comment);
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
if(isonlybody()) die(js::closeModal('parent.parent'));
die(js::locate($this->createLink('bug', 'view', "bugID=$bugID"), 'parent'));
}
@@ -1070,7 +1087,7 @@ class bug extends control
$this->bug->close($bugID);
$actionID = $this->action->create('bug', $bugID, 'Closed');
$this->sendmail($bugID, $actionID);
$this->bug->sendmail($bugID, $actionID);
}
if(isset($skipBugs)) echo js::alert(sprintf($this->lang->bug->skipClose, join(',', $skipBugs)));
@@ -1250,64 +1267,6 @@ class bug extends control
$this->display();
}
/**
* Send email.
*
* @param int $bugID
* @param int $actionID
* @access public
* @return void
*/
public function sendmail($bugID, $actionID)
{
/* Reset $this->output. */
$this->clear();
/* Set toList and ccList. */
$bug = $this->bug->getByID($bugID);
$productName = $this->products[$bug->product];
$toList = $bug->assignedTo;
$ccList = trim($bug->mailto, ',');
if($toList == '')
{
if($ccList == '') return;
if(strpos($ccList, ',') === false)
{
$toList = $ccList;
$ccList = '';
}
else
{
$commaPos = strpos($ccList, ',');
$toList = substr($ccList, 0, $commaPos);
$ccList = substr($ccList, $commaPos + 1);
}
}
elseif(strtolower($toList) == 'closed')
{
$toList = $bug->resolvedBy;
}
/* Get action info. */
$actions = $this->action->getList('bug', $bugID);
$action = zget($actions, $actionID, null);
$history = $this->action->getHistory($actionID);
$action->history = isset($history[$actionID]) ? $history[$actionID] : array();
if(strtolower($action->action) == 'opened') $action->comment = $bug->steps;
/* Create the mail content. */
if($action->action == 'opened') $action->comment = '';
$this->view->bug = $bug;
$this->view->action = $action;
$this->view->users = $this->user->getPairs('noletter');
$mailContent = $this->parse($this->moduleName, 'sendmail');
/* Send it. */
$this->loadModel('mail')->send($toList, 'BUG #'. $bug->id . ' ' . $bug->title . ' - ' . $productName, $mailContent, $ccList);
if($this->mail->isError()) trigger_error(join("\n", $this->mail->getError()));
}
/**
* Get data to export
*
@@ -1320,6 +1279,7 @@ class bug extends control
{
if($_POST)
{
$this->loadModel('file');
$bugLang = $this->lang->bug;
$bugConfig = $this->config->bug;
@@ -1456,7 +1416,7 @@ class bug extends control
{
foreach($relatedFiles[$bug->id] as $file)
{
$fileURL = 'http://' . $this->server->http_host . $this->config->webRoot . "data/upload/{$this->app->company->id}/" . $file->pathname;
$fileURL = common::getSysURL() . $this->file->webPath . $file->pathname;
$bug->files .= html::a($fileURL, $file->title, '_blank') . '<br />';
}
}
+8 -2
View File
@@ -5,7 +5,13 @@
.confirm1 {color:green; font-size:9px}
.red{color:red;}
.dropdown-menu.with-search {padding-bottom: 34px; min-width: 150px; overflow: hidden; max-height: 305px}
.dropdown-menu > .menu-search {padding: 0; position: absolute; z-index: 0; bottom: 0; left: 0; right: 0}
#createActionMenu .dropdown-menu {width:100%;}
.dropdown-menu.with-search {padding: 0; min-width: 150px; overflow: hidden; max-height: 302px;}
.dropdown-menu > .menu-search .input-group {width:100%;}
.dropdown-menu > .menu-search .input-group-addon {position: absolute; right: 10px; top: 0; z-index: 10; background: none; border: none; color: #666}
.dropdown-menu > .menu-search .form-control {border: none!important; box-shadow: none!important; border-top: 1px solid #ddd!important;}
.dropdown-list {display: block; padding: 0; max-height: 270px; overflow-y: auto;}
.dropdown-list > li > a {display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 1.53846154; color: #141414; white-space: nowrap;}
.dropdown-list > li > a:hover,
.dropdown-list > li > a:focus {color: #1a4f85;text-decoration: none;background-color: #ddd;}
+7
View File
@@ -28,9 +28,16 @@
#keywordsAddonLabel:before {content: '空'; color: transparent}
#contactListGroup .input-group-btn > .btn {margin-left: -1px!important;}
#contactListGroup .chosen-container-single a {border-left-width: 0px;}
.chosen-container {max-width: 533px;}
.minw-80px {min-width: 80px;}
.colorpicker.input-group-btn > .btn {border-right: none}
#branch {border-left-width: 0px;}
#bugTypeInputGroup {max-height: 30px; overflow: hidden}
#bugTypeInputGroup .form-control, #bugTypeInputGroup .input-group-addon {float: left; width: auto;}
#bugTypeInputGroup .input-group-addon {padding: 5px 10px; line-height: 18px;}
+2
View File
@@ -3,3 +3,5 @@
.table-bordered tr > th:last-child, .table-bordered tr > td:last-child {border-right: 1px solid #ddd!important}
.col-side {width: 250px}
.panel-heading > strong > span {float: right; color: #29a8cd;}
+61 -13
View File
@@ -5,25 +5,49 @@ $(function()
})
/**
* Load project builds
*
* @param int $productID
* @param int $projectID
* @param int $index
* Set branch related.
*
* @param int $branchID
* @param int $productID
* @param int $num
* @access public
* @return void
*/
function loadProjectBuilds(productID, projectID, index)
function setBranchRelated(branchID, productID, num)
{
if(projectID)
moduleLink = createLink('tree', 'ajaxGetModules', 'productID=' + productID + '&viewType=bug&branch=' + branchID + '&num=' + num);
$.get(moduleLink, function(modules)
{
link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + "&varName=openedBuilds&build=&branch=" + branch + "&index=" + index);
}
else
{
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + "&varName=openedBuilds&build=&branch=" + branch + "&index=" + index);
}
if(!modules) modules = '<select id="modules' + num + '" name="modules[' + num + ']" class="form-control"></select>';
$('#modules' + num).replaceWith(modules);
$("#modules" + num + "_chosen").remove();
$("#modules" + num).chosen(defaultChosenOptions);
});
projectLink = createLink('product', 'ajaxGetProjects', 'productID=' + productID + '&projectID=0&branch=' + branchID + '&num=' + num);
$.get(projectLink, function(projects)
{
if(!projects) projects = '<select id="projects' + num + '" name="projects[' + num + ']" class="form-control"></select>';
$('#projects' + num).replaceWith(projects);
$("#projects" + num + "_chosen").remove();
$("#projects" + num).chosen(defaultChosenOptions);
});
buildLink = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + "&varName=openedBuilds&build=&branch=" + branchID + "&index=" + num);
setOpenedBuilds(buildLink, num);
}
/**
* Set opened builds.
*
* @param string $link
* @param int $index
* @access public
* @return void
*/
function setOpenedBuilds(link, index)
{
$.get(link, function(builds)
{
var row = $('#buildBox' + index).closest('tbody').find('tr').size()
@@ -45,6 +69,30 @@ function loadProjectBuilds(productID, projectID, index)
});
}
/**
* Load project builds
*
* @param int $productID
* @param int $projectID
* @param int $index
* @access public
* @return void
*/
function loadProjectBuilds(productID, projectID, index)
{
branch = $('#branches' + index).val();
if(projectID)
{
link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + "&varName=openedBuilds&build=&branch=" + branch + "&index=" + index);
}
else
{
link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + productID + "&varName=openedBuilds&build=&branch=" + branch + "&index=" + index);
}
setOpenedBuilds(link, index);
}
$(document).on('click', '.chosen-with-drop', function()
{
var select = $(this).prev('select');
+1 -1
View File
@@ -9,7 +9,7 @@ $(document).ready(function()
}).on('keyup change paste', 'input', function()
{
var val = $(this).val().toLowerCase();
var $options = $(this).closest('ul.dropdown-menu.with-search').find('.option');
var $options = $(this).closest('.dropdown-menu.with-search').find('.option');
if(val == '') return $options.removeClass('hide');
$options.each(function()
{
+20 -2
View File
@@ -103,11 +103,29 @@ $(function()
$('[data-toggle=tooltip]').tooltip();
// ajust style for file box
// adjust size of bug type input group
var adjustBugTypeGroup = function()
{
var $group = $('#bugTypeInputGroup');
var width = $group.width(), addonWidth = 0;
var $controls = $group.children('.form-control');
$group.children('.input-group-addon').each(function()
{
addonWidth += $(this).outerWidth();
});
$controls.css('width', Math.floor((width - addonWidth)/$controls.length));
};
adjustBugTypeGroup();
// adjust style for file box
var ajustFilebox = function()
{
applyCssStyle('.fileBox > tbody > tr > td:first-child {transition: none; width: ' + ($('#contactListGroup').width() - 2) + 'px}', 'filebox')
};
ajustFilebox();
$(window).resize(ajustFilebox);
$(window).resize(function()
{
ajustFilebox();
adjustBugTypeGroup();
});
});
+56 -52
View File
@@ -26,49 +26,49 @@ $lang->bug->pri = 'Priority';
$lang->bug->type = 'Type';
$lang->bug->os = 'OS';
$lang->bug->browser = 'Browser';
$lang->bug->steps = 'STR';
$lang->bug->steps = 'Repro Steps';
$lang->bug->status = 'Status';
$lang->bug->statusAB = 'Status';
$lang->bug->activatedCount = 'Activated Count';
$lang->bug->activatedCountAB = 'Activated Count';
$lang->bug->activatedCount = 'Active';
$lang->bug->activatedCountAB = 'Active';
$lang->bug->confirmed = 'Confirmed';
$lang->bug->toTask = 'Convert to Task';
$lang->bug->toStory = 'Convert to Story';
$lang->bug->mailto = 'Mail To';
$lang->bug->openedBy = 'Opened By';
$lang->bug->openedDate = 'Opened Date';
$lang->bug->openedDateAB = 'Opened Date';
$lang->bug->openedBuild = 'Opened Build';
$lang->bug->openedBy = 'Open By';
$lang->bug->openedDate = 'Open On';
$lang->bug->openedDateAB = 'Open On';
$lang->bug->openedBuild = 'Open Build';
$lang->bug->assignedTo = 'Assigned To';
$lang->bug->assignedDate = 'Assigned Date';
$lang->bug->assignedDate = 'Assigned On';
$lang->bug->resolvedBy = 'Resolved By';
$lang->bug->resolvedByAB = 'Resolved';
$lang->bug->resolution = 'Resolution';
$lang->bug->resolution = 'Solution';
$lang->bug->resolutionAB = 'Solution';
$lang->bug->resolvedBuild = 'Resolved Build';
$lang->bug->resolvedDate = 'Resolved Date';
$lang->bug->resolvedDateAB = 'Resolved Date';
$lang->bug->resolvedDate = 'Resolved On';
$lang->bug->resolvedDateAB = 'Resolved On';
$lang->bug->closedBy = 'Closed By';
$lang->bug->closedDate = 'Closed Date';
$lang->bug->closedDate = 'Closed On';
$lang->bug->duplicateBug = 'Duplicate';
$lang->bug->lastEditedBy = 'Last Edited By';
$lang->bug->linkBug = 'Linked';
$lang->bug->linkBugs = 'Link Bug';
$lang->bug->unlinkBug = 'Unlink Bug';
$lang->bug->linkBug = 'Related';
$lang->bug->linkBugs = 'Relate Bug';
$lang->bug->unlinkBug = 'Unrelate';
$lang->bug->case = 'Case';
$lang->bug->files = 'File';
$lang->bug->keywords = 'Keyword';
$lang->bug->keywords = 'Keywords';
$lang->bug->lastEditedByAB = 'Edited By';
$lang->bug->lastEditedDateAB = 'Edit Date';
$lang->bug->lastEditedDate = 'Edit Date';
$lang->bug->lastEditedDateAB = 'Edit On';
$lang->bug->lastEditedDate = 'Edit On';
$lang->bug->fromCase = 'From a Case';
$lang->bug->toCase = 'To a Case';
$lang->bug->colorTag = 'Color Tag';
/* 方法列表。*/
$lang->bug->index = 'Homepage';
$lang->bug->create = 'Create Bug';
$lang->bug->batchCreate = 'Batch Create';
$lang->bug->index = 'Home';
$lang->bug->create = 'Report Bug';
$lang->bug->batchCreate = 'Batch Report';
$lang->bug->confirmBug = 'Confirm';
$lang->bug->batchConfirm = 'Batch Confirm';
$lang->bug->edit = 'Edit';
@@ -79,7 +79,7 @@ $lang->bug->assignTo = 'Assign';
$lang->bug->batchAssignTo = 'Batch Assign';
$lang->bug->browse = 'Bug List';
$lang->bug->view = 'Bug Details';
$lang->bug->resolve = 'Solve';
$lang->bug->resolve = 'Resolve';
$lang->bug->batchResolve = 'Batch Resolve';
$lang->bug->close = 'Close';
$lang->bug->activate = 'Activate';
@@ -87,7 +87,7 @@ $lang->bug->reportChart = 'Report';
$lang->bug->export = 'Export Data';
$lang->bug->delete = 'Delete Bug';
$lang->bug->deleted = 'Deleted';
$lang->bug->saveTemplate = 'Save Template';
$lang->bug->saveTemplate = 'Save as Template';
$lang->bug->setPublic = 'Set as Public';
$lang->bug->deleteTemplate = 'Delete Template';
$lang->bug->confirmStoryChange = 'Story Change Confirmation';
@@ -99,7 +99,7 @@ $lang->bug->openedByMe = 'Created by Me';
$lang->bug->resolvedByMe = 'Resolved by Me';
$lang->bug->closedByMe = 'Closed by Me';
$lang->bug->assignToNull = 'Unassigned';
$lang->bug->unResolved = 'Unsolve';
$lang->bug->unResolved = 'Unresolve';
$lang->bug->toClosed = 'To Be Closed';
$lang->bug->unclosed = 'Open';
$lang->bug->longLifeBugs = 'Pending';
@@ -113,10 +113,10 @@ $lang->bug->ditto = 'Ditto';
$lang->bug->dittoNotice = 'This bug does not affiliate to the same product as the last one!';
/* 页面标签。*/
$lang->bug->lblAssignedTo = 'Current Assign';
$lang->bug->lblAssignedTo = 'Assignee';
$lang->bug->lblMailto = 'Mail To';
$lang->bug->lblLastEdited = 'Last Edited';
$lang->bug->lblResolved = 'Solved By';
$lang->bug->lblResolved = 'Resolved By';
$lang->bug->allUsers = 'All User';
$lang->bug->allBuilds = 'All';
@@ -126,9 +126,9 @@ $lang->bug->legendAttatch = 'Attachment';
$lang->bug->legendPrjStoryTask = $lang->projectCommon . '/Story/Task';
$lang->bug->lblTypeAndSeverity = 'Type/Priority Level';
$lang->bug->lblSystemBrowserAndHardware = 'System/Browser';
$lang->bug->legendSteps = 'STR';
$lang->bug->legendSteps = 'Repro Steps';
$lang->bug->legendComment = 'Note';
$lang->bug->legendLife = 'Bug Lifecycle';
$lang->bug->legendLife = 'Lifecycle';
$lang->bug->legendMisc = 'Miscellaneous';
/* 功能按钮。*/
@@ -139,7 +139,7 @@ $lang->bug->confirmChangeProduct = "Modification on {$lang->productCommon} will
$lang->bug->confirmDelete = 'Do you want to delete this bug?';
$lang->bug->setTemplateTitle = 'Please enter the title of template.';
$lang->bug->remindTask = 'This Bug has been converted to Task. Do you want to update Status of Task(ID %s)?';
$lang->bug->skipClose = 'Bug %s is not solved. You cannot close it.';
$lang->bug->skipClose = 'Bug %s is not resolved. You cannot close it.';
$lang->bug->applyTemplate = 'Apply Template';
/* 模板。*/
@@ -220,8 +220,8 @@ $lang->bug->typeList['trackthings'] = 'Issue Tracking';
$lang->bug->typeList['others'] = 'Other';
$lang->bug->statusList[''] = '';
$lang->bug->statusList['active'] = 'Activate';
$lang->bug->statusList['resolved'] = 'Solved';
$lang->bug->statusList['active'] = 'Active';
$lang->bug->statusList['resolved'] = 'Reolved';
$lang->bug->statusList['closed'] = 'Closed';
$lang->bug->confirmedList[1] = 'Confirmed';
@@ -229,12 +229,12 @@ $lang->bug->confirmedList[0] = 'Not Confirmed';
$lang->bug->resolutionList[''] = '';
$lang->bug->resolutionList['bydesign'] = 'Design Issue';
$lang->bug->resolutionList['duplicate'] = 'Duplicate Bug';
$lang->bug->resolutionList['external'] = 'External Reasons';
$lang->bug->resolutionList['fixed'] = 'Solved';
$lang->bug->resolutionList['duplicate'] = 'Duplicated';
$lang->bug->resolutionList['external'] = 'External';
$lang->bug->resolutionList['fixed'] = 'Resolved';
$lang->bug->resolutionList['notrepro'] = 'Irreproducible';
$lang->bug->resolutionList['postponed'] = 'Postponed';
$lang->bug->resolutionList['willnotfix'] = "Not to Solve";
$lang->bug->resolutionList['willnotfix'] = "Not to Resolve";
$lang->bug->resolutionList['tostory'] = 'Transfer to Story';
/* 统计报表。*/
@@ -243,21 +243,21 @@ $lang->bug->report->common = 'Report';
$lang->bug->report->select = 'Select Report Type ';
$lang->bug->report->create = 'Generate a Report';
$lang->bug->report->charts['bugsPerProject'] = $lang->projectCommon . 'Bug Count';
$lang->bug->report->charts['bugsPerBuild'] = 'Bug Count Per Build';
$lang->bug->report->charts['bugsPerModule'] = 'Bug Count Per Module';
$lang->bug->report->charts['openedBugsPerDay'] = 'Bug Count Per Day';
$lang->bug->report->charts['resolvedBugsPerDay'] = 'Solved Bug Per Day';
$lang->bug->report->charts['closedBugsPerDay'] = 'Closed Bug Per Day';
$lang->bug->report->charts['openedBugsPerUser'] = 'Submitted Bug Per User';
$lang->bug->report->charts['resolvedBugsPerUser'] = 'Solved Bug Per User';
$lang->bug->report->charts['closedBugsPerUser'] = 'Closed Bug Per User';
$lang->bug->report->charts['bugsPerProject'] = $lang->projectCommon . 'Bugs';
$lang->bug->report->charts['bugsPerBuild'] = 'Bugs Per Build';
$lang->bug->report->charts['bugsPerModule'] = 'Bugs Per Module';
$lang->bug->report->charts['openedBugsPerDay'] = 'Reported Bugs Per Day';
$lang->bug->report->charts['resolvedBugsPerDay'] = 'Resolved Bugs Per Day';
$lang->bug->report->charts['closedBugsPerDay'] = 'Closed Bugs Per Day';
$lang->bug->report->charts['openedBugsPerUser'] = 'Reported Bugs Per User';
$lang->bug->report->charts['resolvedBugsPerUser'] = 'Resolved Bugs Per User';
$lang->bug->report->charts['closedBugsPerUser'] = 'Closed Bugs Per User';
$lang->bug->report->charts['bugsPerSeverity'] = 'Bug Priority Report';
$lang->bug->report->charts['bugsPerResolution'] = 'Bug Solution Report';
$lang->bug->report->charts['bugsPerStatus'] = 'Bug Status Report';
$lang->bug->report->charts['bugsPerActivatedCount'] = 'Bug Activation Report';
$lang->bug->report->charts['bugsPerType'] = 'Bug Type Report';
$lang->bug->report->charts['bugsPerAssignedTo'] = 'Assignment Report';
$lang->bug->report->charts['bugsPerAssignedTo'] = 'Bug Assignment Report';
//$lang->bug->report->charts['bugLiveDays'] = 'Bug Handling Time Report';
//$lang->bug->report->charts['bugHistories'] = 'Bug Handling Steps Report';
@@ -331,13 +331,17 @@ $lang->bug->report->bugHistories->graph->xAxisName = 'Handling Steps';
/* 操作记录。*/
$lang->bug->action = new stdclass();
$lang->bug->action->resolved = array('main' => '$date, solved by <strong>$actor</strong> and the solution is <strong>$extra</strong> $appendLink.', 'extra' => 'resolutionList');
$lang->bug->action->tostory = array('main' => '$date, transferred by <strong>$actor</strong> to <strong>Story</strong> with ID <strong>$extra</strong>.');
$lang->bug->action->totask = array('main' => '$date, imported by <strong>$actor</strong> as <strong>Task</strong> with ID <strong>$extra</strong>.');
$lang->bug->action->linked2plan = array('main' => '$date, linked by <strong>$actor</strong> to Planning <strong>$extra</strong>.');
$lang->bug->action->unlinkedfromplan = array('main' => '$date, deleted by <strong>$actor</strong> from Planning <strong>$extra</strong>.');
$lang->bug->action->linkrelatedbug = array('main' => '$date, related by <strong>$actor</strong> to Bug <strong>$extra</strong>.');
$lang->bug->action->unlinkrelatedbug = array('main' => '$date, removed by <strong>$actor</strong> from Bug <strong>$extra</strong>.');
$lang->bug->action->resolved = array('main' => '$date, resolved by <strong>$actor</strong> and the solution is <strong>$extra</strong> $appendLink.', 'extra' => 'resolutionList');
$lang->bug->action->tostory = array('main' => '$date, transferred by <strong>$actor</strong> to <strong>Story</strong> with ID <strong>$extra</strong>.');
$lang->bug->action->totask = array('main' => '$date, imported by <strong>$actor</strong> as <strong>Task</strong> with ID <strong>$extra</strong>.');
$lang->bug->action->linked2plan = array('main' => '$date, related by <strong>$actor</strong> to Plan <strong>$extra</strong>.');
$lang->bug->action->unlinkedfromplan = array('main' => '$date, deleted by <strong>$actor</strong> from Plan <strong>$extra</strong>.');
$lang->bug->action->linked2build = array('main' => '$date, related by <strong>$actor</strong> to Build <strong>$extra</strong>.');
$lang->bug->action->unlinkedfrombuild = array('main' => '$date, removed by <strong>$actor</strong> from Build <strong>$extra</strong>.');
$lang->bug->action->linked2release = array('main' => '$date, related by <strong>$actor</strong> to Release <strong>$extra</strong>.');
$lang->bug->action->unlinkedfromrelease = array('main' => '$date, removed by <strong>$actor</strong> from Release <strong>$extra</strong>.');
$lang->bug->action->linkrelatedbug = array('main' => '$date, related by <strong>$actor</strong> to Bug <strong>$extra</strong>.');
$lang->bug->action->unlinkrelatedbug = array('main' => '$date, removed by <strong>$actor</strong> from Bug <strong>$extra</strong>.');
$lang->bug->placeholder = new stdclass();
$lang->bug->placeholder->chooseBuilds = 'Choose Build...';
+11 -7
View File
@@ -331,13 +331,17 @@ $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->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> 移除。');
$lang->bug->action->linkrelatedbug = array('main' => '$date, 由 <strong>$actor</strong> 关联相关Bug <strong>$extra</strong>。');
$lang->bug->action->unlinkrelatedbug = array('main' => '$date, 由 <strong>$actor</strong> 移除相关Bug <strong>$extra</strong>。');
$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->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> 移除。');
$lang->bug->action->linked2build = array('main' => '$date, 由 <strong>$actor</strong> 关联到版本 <strong>$extra</strong>。');
$lang->bug->action->unlinkedfrombuild = array('main' => '$date, 由 <strong>$actor</strong> 从版本 <strong>$extra</strong> 移除。');
$lang->bug->action->linked2release = array('main' => '$date, 由 <strong>$actor</strong> 关联到发布 <strong>$extra</strong>。');
$lang->bug->action->unlinkedfromrelease = array('main' => '$date, 由 <strong>$actor</strong> 从发布 <strong>$extra</strong> 移除。');
$lang->bug->action->linkrelatedbug = array('main' => '$date, 由 <strong>$actor</strong> 关联相关Bug <strong>$extra</strong>。');
$lang->bug->action->unlinkrelatedbug = array('main' => '$date, 由 <strong>$actor</strong> 移除相关Bug <strong>$extra</strong>。');
$lang->bug->placeholder = new stdclass();
$lang->bug->placeholder->chooseBuilds = '选择相关版本...';
+11 -7
View File
@@ -331,13 +331,17 @@ $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->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> 移除。');
$lang->bug->action->linkrelatedbug = array('main' => '$date, 由 <strong>$actor</strong> 關聯相關Bug <strong>$extra</strong>。');
$lang->bug->action->unlinkrelatedbug = array('main' => '$date, 由 <strong>$actor</strong> 移除相關Bug <strong>$extra</strong>。');
$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->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> 移除。');
$lang->bug->action->linked2build = array('main' => '$date, 由 <strong>$actor</strong> 關聯到版本 <strong>$extra</strong>。');
$lang->bug->action->unlinkedfrombuild = array('main' => '$date, 由 <strong>$actor</strong> 從版本 <strong>$extra</strong> 移除。');
$lang->bug->action->linked2release = array('main' => '$date, 由 <strong>$actor</strong> 關聯到發佈 <strong>$extra</strong>。');
$lang->bug->action->unlinkedfromrelease = array('main' => '$date, 由 <strong>$actor</strong> 從發佈 <strong>$extra</strong> 移除。');
$lang->bug->action->linkrelatedbug = array('main' => '$date, 由 <strong>$actor</strong> 關聯相關Bug <strong>$extra</strong>。');
$lang->bug->action->unlinkrelatedbug = array('main' => '$date, 由 <strong>$actor</strong> 移除相關Bug <strong>$extra</strong>。');
$lang->bug->placeholder = new stdclass();
$lang->bug->placeholder->chooseBuilds = '選擇相關版本...';
+163 -24
View File
@@ -87,7 +87,7 @@ class bugModel extends model
$data = fixer::input('post')->get();
$batchNum = count(reset($data));
$result = $this->loadModel('common')->removeDuplicate('bug', $data, "product={$productID} and branch={$branch}");
$result = $this->loadModel('common')->removeDuplicate('bug', $data, "product={$productID}");
$data = $result['data'];
for($i = 0; $i < $batchNum; $i++)
@@ -132,7 +132,7 @@ class bugModel extends model
$bug->openedBy = $this->app->user->account;
$bug->openedDate = $now;
$bug->product = $productID;
$bug->branch = $branch;
$bug->branch = $data->branches[$i];
$bug->module = $data->modules[$i];
$bug->project = $data->projects[$i];
$bug->openedBuild = implode(',', $data->openedBuilds[$i]);
@@ -415,7 +415,7 @@ class bugModel extends model
krsort($moduleIDList);
if($moduleIDList)
{
$modules = $this->dao->select('*')->from(TABLE_MODULE)->where('id')->in($moduleIDList)->fetchAll('id');
$modules = $this->dao->select('*')->from(TABLE_MODULE)->where('id')->in($moduleIDList)->andWhere('deleted')->eq(0)->fetchAll('id');
foreach($moduleIDList as $moduleID)
{
if(isset($modules[$moduleID]))
@@ -640,7 +640,8 @@ class bugModel extends model
*/
public function confirm($bugID)
{
$now = helper::now();
$now = helper::now();
$oldBug = $this->getById($bugID);
$bug = fixer::input('post')
->setDefault('confirmed', 1)
@@ -651,6 +652,8 @@ class bugModel extends model
->get();
$this->dao->update(TABLE_BUG)->data($bug)->where('id')->eq($bugID)->exec();
if(!dao::isError()) return common::createChanges($oldBug, $bug);
}
/**
@@ -691,12 +694,12 @@ class bugModel extends model
$oldBug = $this->getById($bugID);
$bug = fixer::input('post')
->add('resolvedBy', $this->app->user->account)
->add('resolvedDate', $now)
->add('status', 'resolved')
->add('confirmed', 1)
->add('assignedDate', $now)
->add('lastEditedBy', $this->app->user->account)
->add('lastEditedDate', $now)
->setDefault('resolvedDate', $now)
->setDefault('duplicateBug', 0)
->setDefault('assignedTo', $oldBug->openedBy)
->remove('comment,files,labels')
@@ -900,7 +903,7 @@ class bugModel extends model
if($browseType == 'bySearch')
{
$bug = $this->getById($bugID);
$bugs2Link = $this->getBySearch($bug->product, $queryID, 'id', null);
$bugs2Link = $this->getBySearch($bug->product, $queryID, 'id', null, $bug->branch);
foreach($bugs2Link as $key => $bug2Link)
{
if($bug2Link->id == $bugID) unset($bugs2Link[$key]);
@@ -969,6 +972,7 @@ class bugModel extends model
$this->config->bug->search['params']['plan']['values'] = $this->loadModel('productplan')->getPairs($productID);
$this->config->bug->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($productID, $viewType = 'bug', $startModuleID = 0);
$this->config->bug->search['params']['project']['values'] = $this->product->getProjectPairs($productID);
$this->config->bug->search['params']['severity']['values'] = array(0 => '') + $this->lang->bug->severityList; //Fix bug #939.
$this->config->bug->search['params']['openedBuild']['values'] = $this->loadModel('build')->getProductBuildPairs($productID, 0, $params = '');
$this->config->bug->search['params']['resolvedBuild']['values'] = $this->config->bug->search['params']['openedBuild']['values'];
if($this->session->currentProductType == 'normal')
@@ -979,7 +983,7 @@ class bugModel extends model
else
{
$this->config->bug->search['fields']['branch'] = $this->lang->product->branch;
$this->config->bug->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty');
$this->config->bug->search['params']['branch']['values'] = array('' => '') + $this->loadModel('branch')->getPairs($productID, 'noempty') + array('all' => $this->lang->branch->all);
}
$this->loadModel('search')->setSearchParams($this->config->bug->search);
@@ -1110,19 +1114,55 @@ class bugModel extends model
/**
* Get bugs of a project.
*
* @param int $projectID
* @param string $orderBy
* @param object $pager
* @param int $projectID
* @param int $build
* @param string $type
* @param int $param
* @param string $orderBy
* @param object $pager
* @access public
* @return array
*/
public function getProjectBugs($projectID, $orderBy = 'id_desc', $pager = null, $build = 0)
public function getProjectBugs($projectID, $build = 0, $type = '', $param = 0, $orderBy = 'id_desc', $pager = null)
{
$bugs = $this->dao->select('*')->from(TABLE_BUG)
->where('deleted')->eq(0)
->beginIF(empty($build))->andWhere('project')->eq($projectID)->fi()
->beginIF($build)->andWhere("CONCAT(',', openedBuild, ',') like '%,$build,%'")->fi()
->orderBy($orderBy)->page($pager)->fetchAll();
if($type == 'bySearch')
{
$queryID = (int)$param;
$products = $this->loadModel('project')->getProducts($projectID);
if($this->session->projectBugQuery == false) $this->session->set('projectBugQuery', ' 1 = 1');
if($queryID)
{
$query = $this->loadModel('search')->getQuery($queryID);
if($query)
{
$this->session->set('projectBugQuery', $query->sql);
$this->session->set('projectBugForm', $query->form);
}
}
$allProduct = "`product` = 'all'";
$bugQuery = $this->session->projectBugQuery;
if(strpos($this->session->projectBugQuery, $allProduct) !== false)
{
$bugQuery = str_replace($allProduct, '1', $this->session->projectBugQuery);
}
$bugs = $this->dao->select('*')->from(TABLE_BUG)
->where($bugQuery)
->andWhere('project')->eq((int)$projectID)
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
}
else
{
$bugs = $this->dao->select('*')->from(TABLE_BUG)
->where('deleted')->eq(0)
->beginIF(empty($build))->andWhere('project')->eq($projectID)->fi()
->beginIF($build)->andWhere("CONCAT(',', openedBuild, ',') like '%,$build,%'")->fi()
->orderBy($orderBy)->page($pager)->fetchAll();
}
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'bug');
@@ -1222,13 +1262,33 @@ class bugModel extends model
*/
public function getStoryBugs($storyID)
{
return $this->dao->select('id, title, type, status, assignedTo, resolvedBy, resolution')
return $this->dao->select('id, title, pri, type, status, assignedTo, resolvedBy, resolution')
->from(TABLE_BUG)
->where('story')->eq((int)$storyID)
->andWhere('deleted')->eq(0)
->fetchAll('id');
}
/**
* Get case bugs.
*
* @param int $runID
* @param int $caseID
* @param int $version
* @access public
* @return void
*/
public function getCaseBugs($runID, $caseID = 0, $version = 0)
{
return $this->dao->select('*')->from(TABLE_BUG)
->where('1=1')
->beginIF($runID)->andWhere('`result`')->eq($runID)->fi()
->beginIF($runID == 0 and $caseID)->andWhere('`case`')->eq($caseID)->fi()
->beginIF($version)->andWhere('`caseVersion`')->eq($version)->fi()
->andWhere('deleted')->eq(0)
->fetchAll('id');
}
/**
* Get counts of some stories' bugs.
*
@@ -1842,11 +1902,12 @@ class bugModel extends model
*/
public function getByLonglifebugs($productID, $branch, $modules, $projects, $orderBy, $pager)
{
return $this->dao->findByLastEditedDate("<", date(DT_DATE1, strtotime('-7 days')))->from(TABLE_BUG)->andWhere('product')->eq($productID)
$lastEditedDate = date(DT_DATE1, time() - $this->config->bug->longlife * 24 * 3600);
return $this->dao->findByLastEditedDate("<", $lastEditedDate)->from(TABLE_BUG)->andWhere('product')->eq($productID)
->andWhere('project')->in(array_keys($projects))
->beginIF($branch)->andWhere('branch')->in($branch)->fi()
->beginIF($modules)->andWhere('module')->in($modules)->fi()
->andWhere('openedDate')->lt(date(DT_DATE1,strtotime('-7 days')))
->andWhere('openedDate')->lt($lastEditedDate)
->andWhere('deleted')->eq(0)
->andWhere('status')->ne('closed')->orderBy($orderBy)->page($pager)->fetchAll();
}
@@ -1939,7 +2000,9 @@ class bugModel extends model
$bugQuery = str_replace($allProduct, '1', $bugQuery);
$bugQuery = $bugQuery . ' AND `product` ' . helper::dbIN($products);
}
if($branch) $bugQuery .= " AND `branch` in('0','$branch')";
$allBranch = "`branch` = 'all'";
if($branch and strpos($bugQuery, '`branch` =') === false) $bugQuery .= " AND `branch` in('0','$branch')";
if(strpos($bugQuery, $allBranch) !== false) $bugQuery = str_replace($allBranch, '1', $bugQuery);
$bugs = $this->dao->select('*')->from(TABLE_BUG)->where($bugQuery)
->andWhere('deleted')->eq(0)
->orderBy($orderBy)->page($pager)->fetchAll();
@@ -2114,13 +2177,13 @@ class bugModel extends model
echo $bug->activatedCount;
break;
case 'openedBy':
echo zget($users, $bug->openedBy, $bug->openedBy);
echo zget($users, $bug->openedBy);
break;
case 'openedDate':
echo substr($bug->openedDate, 5, 11);
break;
case 'openedBuild':
foreach(explode(',', $bug->openedBuild) as $build) echo zget($builds, $build, $build) . '<br />';
foreach(explode(',', $bug->openedBuild) as $build) echo zget($builds, $build) . '<br />';
break;
case 'assignedTo':
echo zget($users, $bug->assignedTo, $bug->assignedTo);
@@ -2132,7 +2195,7 @@ class bugModel extends model
echo zget($users, $bug->resolvedBy, $bug->resolvedBy);
break;
case 'resolution':
echo $this->lang->bug->resolutionList[$bug->resolution];
echo zget($this->lang->bug->resolutionList, $bug->resolution);
break;
case 'resolvedDate':
echo substr($bug->resolvedDate, 5, 11);
@@ -2141,7 +2204,7 @@ class bugModel extends model
echo $bug->resolvedBuild;
break;
case 'closedBy':
echo zget($users, $bug->closedBy, $bug->closedBy);
echo zget($users, $bug->closedBy);
break;
case 'lastEditedDate':
echo substr($bug->lastEditedDate, 5, 11);
@@ -2162,4 +2225,80 @@ class bugModel extends model
echo '</td>';
}
}
/**
* Send mail
*
* @param int $bugID
* @param int $actionID
* @access public
* @return void
*/
public function sendmail($bugID, $actionID)
{
$this->loadModel('mail');
$bug = $this->getByID($bugID);
$productName = $this->loadModel('product')->getById($bug->product)->name;
$users = $this->loadModel('user')->getPairs('noletter');
/* Get action info. */
$action = $this->loadModel('action')->getById($actionID);
$history = $this->action->getHistory($actionID);
$action->history = isset($history[$actionID]) ? $history[$actionID] : array();
$action->appendLink = '';
if(strpos($action->extra, ':')!== false)
{
list($extra, $id) = explode(':', $action->extra);
$action->extra = $extra;
if($id)
{
$name = $this->dao->select('title')->from(TABLE_BUG)->where('id')->eq($id)->fetch('title');
if($name) $action->appendLink = html::a(zget($this->config->mail, 'domain', common::getSysURL()) . helper::createLink($action->objectType, 'view', "id=$id"), "#$id " . $name);
}
}
/* Get mail content. */
$modulePath = $this->app->getModulePath($appName = '', 'bug');
$oldcwd = getcwd();
$viewFile = $modulePath . 'view/sendmail.html.php';
chdir($modulePath . 'view');
if(file_exists($modulePath . 'ext/view/sendmail.html.php'))
{
$viewFile = $modulePath . 'ext/view/sendmail.html.php';
chdir($modulePath . 'ext/view');
}
ob_start();
include $viewFile;
foreach(glob($modulePath . 'ext/view/sendmail.*.html.hook.php') as $hookFile) include $hookFile;
$mailContent = ob_get_contents();
ob_end_clean();
chdir($oldcwd);
/* Set toList and ccList. */
$toList = $bug->assignedTo;
$ccList = trim($bug->mailto, ',');
if(empty($toList))
{
if(empty($ccList)) return;
if(strpos($ccList, ',') === false)
{
$toList = $ccList;
$ccList = '';
}
else
{
$commaPos = strpos($ccList, ',');
$toList = substr($ccList, 0, $commaPos);
$ccList = substr($ccList, $commaPos + 1);
}
}
elseif(strtolower($toList) == 'closed')
{
$toList = $bug->resolvedBy;
}
/* Send it. */
$this->mail->send($toList, 'BUG #'. $bug->id . ' ' . $bug->title . ' - ' . $productName, $mailContent, $ccList);
if($this->mail->isError()) trigger_error(join("\n", $this->mail->getError()));
}
}
+10 -6
View File
@@ -38,6 +38,7 @@ foreach(explode(',', $showFields) as $field)
<thead>
<tr>
<th class='w-50px'> <?php echo $lang->idAB;?></th>
<th class='w-120px<?php echo zget($visibleFields, $product->type, ' hidden')?>'> <?php echo $lang->product->branch;?></th>
<th class='w-120px<?php echo zget($visibleFields, 'module', ' hidden')?>'> <?php echo $lang->bug->module;?></th>
<th class='w-130px<?php echo zget($visibleFields, 'project', ' hidden')?>'><?php echo $lang->bug->project;?></th>
<th><?php echo $lang->bug->openedBuild;?> <span class='required'></span></th>
@@ -78,13 +79,14 @@ foreach(explode(',', $showFields) as $field)
?>
<tr class='text-center'>
<td><?php echo $i+1;?></td>
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?>'><?php echo html::select("branches[$i]", $branches, $branch, "class='form-control' onchange='setBranchRelated(this.value, $productID, $i)'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?>' style='overflow:visible'><?php echo html::select("modules[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'project', ' hidden')?>' style='overflow:visible'><?php echo html::select("projects[$i]", $projects, $projectID, "class='form-control chosen' onchange='loadProjectBuilds($productID, this.value, $i)'");?></td>
<td class='text-left' style='overflow:visible' id='buildBox<?php echo $i;?>'><?php echo html::select("openedBuilds[$i][]", $builds, 'trunk', "class='form-control chosen' multiple");?></td>
<td style='overflow:visible'>
<div class='input-group'>
<?php echo html::hidden("color[$i]", '', "data-provide='colorpicker' data-wrapper='input-group-btn fix-border-right' data-pull-menu-right='false' data-btn-tip='{$lang->bug->colorTag}' data-update-text='#title\\[{$i}\\]'");?>
<?php echo html::input("title[$i]", $bugTitle, 'class=form-control') . html::hidden("uploadImage[$i]", $fileName);?>
<?php echo html::input("title[$i]", $bugTitle, "class='form-control' autocomplete='off'") . html::hidden("uploadImage[$i]", $fileName);?>
</div>
</td>
<td class='<?php echo zget($visibleFields, 'steps', 'hidden')?>'> <?php echo html::textarea("stepses[$i]", '', "rows='1' class='form-control autosize'");?></td>
@@ -93,7 +95,7 @@ foreach(explode(',', $showFields) as $field)
<td class='<?php echo zget($visibleFields, 'severity', 'hidden')?>'><?php echo html::select("severities[$i]", $lang->bug->severityList, '', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'os', 'hidden')?>'> <?php echo html::select("oses[$i]", $lang->bug->osList, $os, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'browser', 'hidden')?>'> <?php echo html::select("browsers[$i]", $lang->bug->browserList, $browser, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'><?php echo html::input("keywords[$i]", '', 'class=form-control');?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'><?php echo html::input("keywords[$i]", '', "class='form-control' autocomplete='off'");?></td>
</tr>
<?php $i++;?>
<?php endforeach;?>
@@ -110,13 +112,14 @@ foreach(explode(',', $showFields) as $field)
?>
<tr class='text-center'>
<td><?php echo $i+1;?></td>
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?>'><?php echo html::select("branches[$i]", $branches, $branch, "class='form-control' onchange='setBranchRelated(this.value, $productID, $i)'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?>' style='overflow:visible'><?php echo html::select("modules[$i]", $moduleOptionMenu, $moduleID, "class='form-control chosen'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'project', ' hidden')?>' style='overflow:visible'><?php echo html::select("projects[$i]", $projects, $projectID, "class='form-control chosen' onchange='loadProjectBuilds($productID, this.value, $i)'");?></td>
<td class='text-left' style='overflow:visible' id='buildBox<?php echo $i;?>'><?php echo html::select("openedBuilds[$i][]", $builds, '', "class='form-control chosen' multiple");?></td>
<td style='overflow:visible'>
<div class='input-group'>
<?php echo html::hidden("color[$i]", '', "data-provide='colorpicker' data-wrapper='input-group-btn fix-border-right' data-pull-menu-right='false' data-btn-tip='{$lang->bug->colorTag}' data-update-text='#title\\[{$i}\\]'");?>
<?php echo html::input("title[$i]", '', 'class=form-control');?>
<?php echo html::input("title[$i]", '', "class='form-control' autocomplete='off'");?>
</div>
</td>
<td class='<?php echo zget($visibleFields, 'steps', 'hidden')?>'> <?php echo html::textarea("stepses[$i]", '', "rows='1' class='form-control autosize'");?></td>
@@ -125,7 +128,7 @@ foreach(explode(',', $showFields) as $field)
<td class='<?php echo zget($visibleFields, 'severity', 'hidden')?>'><?php echo html::select("severities[$i]", $lang->bug->severityList, '', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'os', 'hidden')?>'> <?php echo html::select("oses[$i]", $lang->bug->osList, $os, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'browser', 'hidden')?>'> <?php echo html::select("browsers[$i]", $lang->bug->browserList, $browser, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'><?php echo html::input("keywords[$i]", '', 'class=form-control');?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'><?php echo html::input("keywords[$i]", '', "class='form-control' autocomplete='off'");?></td>
</tr>
<?php endfor;?>
</tbody>
@@ -138,13 +141,14 @@ foreach(explode(',', $showFields) as $field)
<tbody>
<tr class='text-center'>
<td>%s</td>
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?>'><?php echo html::select("branches[%s]", $branches, $branch, "class='form-control' onchange='setBranchRelated(this.value, $productID, \"%s\")'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?>' style='overflow:visible'><?php echo html::select("modules[%s]", $moduleOptionMenu, $moduleID, "class='form-control'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'project', ' hidden')?>' style='overflow:visible'><?php echo html::select("projects[%s]", $projects, $projectID, "class='form-control' onchange='loadProjectBuilds($productID, this.value, \"%s\")'");?></td>
<td class='text-left' style='overflow:visible' id='buildBox%s'><?php echo html::select("openedBuilds[%s][]", $builds, '', "class='form-control' multiple");?></td>
<td style='overflow:visible'>
<div class='input-group'>
<?php echo html::hidden("color[%s]", '', "data-wrapper='input-group-btn fix-border-right' data-pull-menu-right='false' data-btn-tip='{$lang->bug->colorTag}' data-update-text='#title\\[%s\\]'");?>
<?php echo html::input("title[%s]", '', 'class=form-control');?>
<?php echo html::input("title[%s]", '', "class='form-control' autocomplete='off'");?>
</div>
</td>
<td class='<?php echo zget($visibleFields, 'steps', 'hidden')?>'> <?php echo html::textarea("stepses[%s]", '', "rows='1' class='form-control autosize'");?></td>
@@ -153,7 +157,7 @@ foreach(explode(',', $showFields) as $field)
<td class='<?php echo zget($visibleFields, 'severity', 'hidden')?>'><?php echo html::select("severities[%s]", $lang->bug->severityList, '', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'os', 'hidden')?>'> <?php echo html::select("oses[%s]", $lang->bug->osList, '', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'browser', 'hidden')?>'> <?php echo html::select("browsers[%s]", $lang->bug->browserList, '', "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'><?php echo html::input("keywords[%s]", '', 'class=form-control');?></td>
<td class='<?php echo zget($visibleFields, 'keywords', 'hidden')?>'><?php echo html::input("keywords[%s]", '', "class='form-control' autocomplete='off'");?></td>
</tr>
</tbody>
</table>
+27 -20
View File
@@ -58,28 +58,29 @@ js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrows
</ul>
</div>
<div class='btn-group'>
<?php common::printIcon('bug', 'report', "productID=$productID&browseType=$browseType&moduleID=$moduleID"); ?>
<?php common::printIcon('bug', 'report', "productID=$productID&browseType=$browseType&branchID=$branch&moduleID=$moduleID"); ?>
</div>
</div>
<div class='btn-group'>
<div class='btn-group'>
<button type='button' class='btn btn-default dropdown-toggle' data-toggle='dropdown'>
<i class='icon icon-plus'></i> <?php echo $lang->bug->common;?>
<span class='caret'></span>
</button>
<ul class='dropdown-menu' id='createBugActionMenu'>
<div class='btn-group' id='createActionMenu'>
<?php
if(commonModel::isTutorialMode())
{
$wizardParams = helper::safe64Encode("productID=$productID&branch=$branch&extra=moduleID=$moduleID");
echo html::a($this->createLink('tutorial', 'wizard', "module=bug&method=create&params=$wizardParams"), $lang->bug->create);
echo html::a($this->createLink('tutorial', 'wizard', "module=bug&method=create&params=$wizardParams"), "<i class='icon-plus'></i>" . $lang->bug->create, '', "class='btn btn-primary btn-bug-create'");
}
else
{
$misc = common::hasPriv('bug', 'create') ? '' : "class=disabled";
$misc = common::hasPriv('bug', 'create') ? "class='btn btn-primary'" : "class='btn btn-primary disabled'";
$link = common::hasPriv('bug', 'create') ? $this->createLink('bug', 'create', "productID=$productID&branch=$branch&extra=moduleID=$moduleID") : '#';
echo "<li>" . html::a($link, $lang->bug->create, '', $misc) . "</li>";
echo html::a($link, "<i class='icon icon-plus'></i>" . $lang->bug->create, '', $misc);
}
?>
<button type='button' class='btn btn-primary dropdown-toggle' data-toggle='dropdown'>
<span class='caret'></span>
</button>
<ul class='dropdown-menu pull-right'>
<?php
$misc = common::hasPriv('bug', 'batchCreate') ? '' : "class=disabled";
$link = common::hasPriv('bug', 'batchCreate') ? $this->createLink('bug', 'batchCreate', "productID=$productID&branch=$branch&projectID=0&moduleID=$moduleID") : '#';
echo "<li>" . html::a($link, $lang->bug->batchCreate, '', $misc) . "</li>";
@@ -107,6 +108,7 @@ js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrows
</div>
</div>
<div class='main'>
<script>setTreeBox();</script>
<form method='post' id='bugForm'>
<?php
$datatableId = $this->moduleName . ucfirst($this->methodName);
@@ -148,14 +150,16 @@ js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrows
$withSearch = count($modules) > 8;
echo "<li class='dropdown-submenu'>";
echo html::a('javascript:;', $lang->bug->moduleAB, '', "id='moduleItem'");
echo "<ul class='dropdown-menu" . ($withSearch ? ' with-search':'') . "'>";
echo "<div class='dropdown-menu" . ($withSearch ? ' with-search':'') . "'>";
echo '<ul class="dropdown-list">';
foreach($modules as $moduleId => $module)
{
$actionLink = $this->createLink('bug', 'batchChangeModule', "moduleID=$moduleId");
echo "<li class='option' data-key='$moduleID'>" . html::a('#', $module, '', "onclick=\"setFormAction('$actionLink','hiddenwin')\"") . "</li>";
}
if($withSearch) echo "<li class='menu-search'><div class='input-group input-group-sm'><input type='text' class='form-control' placeholder=''><span class='input-group-addon'><i class='icon-search'></i></span></div></li>";
echo '</ul></li>';
echo "</ul>";
if($withSearch) echo "<div class='menu-search'><div class='input-group input-group-sm'><input type='text' class='form-control' placeholder=''><span class='input-group-addon'><i class='icon-search'></i></span></div></div>";
echo '</div></li>';
}
else
{
@@ -178,7 +182,8 @@ js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrows
$withSearch = count($builds) > 4;
echo "<li class='dropdown-submenu'>";
echo html::a('javascript:;', $resolution, '', "id='fixedItem'");
echo "<ul class='dropdown-menu" . ($withSearch ? ' with-search':'') . "'>";
echo "<div class='dropdown-menu" . ($withSearch ? ' with-search':'') . "'>";
echo '<ul class="dropdown-list">';
unset($builds['']);
foreach($builds as $key => $build)
{
@@ -187,8 +192,9 @@ js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrows
echo html::a('javascript:;', $build, '', "onclick=\"setFormAction('$actionLink','hiddenwin')\"");
echo "</li>";
}
if($withSearch) echo "<li class='menu-search'><div class='input-group input-group-sm'><input type='text' class='form-control' placeholder=''><span class='input-group-addon'><i class='icon-search'></i></span></div></li>";
echo '</ul></li>';
echo "</ul>";
if($withSearch) echo "<div class='menu-search'><div class='input-group input-group-sm'><input type='text' class='form-control' placeholder=''><span class='input-group-addon'><i class='icon-search'></i></span></div></div>";
echo '</div></li>';
}
else
{
@@ -210,15 +216,16 @@ js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrows
echo html::select('assignedTo', $memberPairs, '', 'class="hidden"');
echo "<li class='dropdown-submenu'>";
echo html::a('javascript::', $lang->bug->assignedTo, 'id="assignItem"');
echo "<ul class='dropdown-menu" . ($withSearch ? ' with-search':'') . "'>";
echo "<div class='dropdown-menu" . ($withSearch ? ' with-search':'') . "'>";
echo '<ul class="dropdown-list">';
foreach ($memberPairs as $key => $value)
{
if(empty($key)) continue;
echo "<li class='option' data-key='$key'>" . html::a("javascript:$(\".table-actions #assignedTo\").val(\"$key\");setFormAction(\"$actionLink\")", $value, '', '') . '</li>';
}
if($withSearch) echo "<li class='menu-search'><div class='input-group input-group-sm'><input type='text' class='form-control' placeholder=''><span class='input-group-addon'><i class='icon-search'></i></span></div></li>";
echo "</ul>";
echo "</li>";
if($withSearch) echo "<div class='menu-search'><div class='input-group input-group-sm'><input type='text' class='form-control' placeholder=''><span class='input-group-addon'><i class='icon-search'></i></span></div></div>";
echo "</div></li>";
}
else
{
@@ -250,7 +257,7 @@ if($shortcut.size() > 0)
<?php endif;?>
<?php $this->app->loadConfig('qa', '', false);?>
<?php if(isset($this->config->qa->homepage) and $this->config->qa->homepage != 'browse'):?>
$(function(){$('#modulemenu .nav li:last').after("<li class='right'><a style='font-size:12px' href='javascript:setHomepage(\"qa\", \"browse\")'><i class='icon icon-cog'></i><?php echo $lang->homepage?></a></li>")});
$(function(){$('#modulemenu .nav li:last').after("<li class='right'><a style='font-size:12px' href='javascript:setHomepage(\"qa\", \"browse\")'><i class='icon icon-cog'></i> <?php echo $lang->homepage?></a></li>")});
<?php endif;?>
</script>
<?php include '../../common/view/footer.html.php';?>
+3 -3
View File
@@ -10,7 +10,7 @@
* @link http://www.zentao.net
*/
?>
<table class='table table-condensed table-hover table-striped tablesorter table-fixed' id='bugList'>
<table class='table table-condensed table-hover table-striped tablesorter table-fixed table-selectable' id='bugList'>
<thead>
<tr>
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
@@ -46,7 +46,7 @@
<?php foreach($bugs as $bug):?>
<?php $bugLink = inlink('view', "bugID=$bug->id");?>
<tr class='text-center'>
<td class='bug-<?php echo $bug->status;?> strong text-left'>
<td class='cell-id bug-<?php echo $bug->status;?> strong text-left'>
<input type='checkbox' name='bugIDList[]' value='<?php echo $bug->id;?>'/>
<?php echo html::a($bugLink, sprintf('%03d', $bug->id));?>
</td>
@@ -89,7 +89,7 @@
<td <?php if($bug->assignedTo == $this->app->user->account) echo 'class="red"';?>><?php echo zget($users, $bug->assignedTo, $bug->assignedTo);?></td>
<td><?php echo zget($users, $bug->resolvedBy, $bug->resolvedBy)?></td>
<td><?php echo $lang->bug->resolutionList[$bug->resolution];?></td>
<td><?php echo zget($lang->bug->resolutionList, $bug->resolution);?></td>
<?php if($this->cookie->windowWidth >= $this->config->wideSize):?>
<td><?php echo substr($bug->resolvedDate, 5, 11)?></td>
+4
View File
@@ -31,6 +31,10 @@ js::set('page', 'confirmbug');
<td class='w-p25-f'><?php echo html::select('assignedTo', $users, $bug->assignedTo, "class='select-2 chosen'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->bug->type;?></th>
<td><?php echo html::select('type', $lang->bug->typeList, $bug->type, 'class=form-control');?></td>
</tr>
<tr>
<th><?php echo $lang->bug->pri;?></th>
<td><?php echo html::select('pri', $lang->bug->priList, $bug->pri, 'class=form-control');?></td>
+5 -5
View File
@@ -1,4 +1,4 @@
<?php
<?php
/**
* The create view of bug module of ZenTaoPMS.
*
@@ -70,8 +70,8 @@ js::set('refresh', $lang->refresh);
<span class='input-group-addon'><?php echo $lang->bug->openedBuild?></span>
<?php endif;?>
<span id='buildBox'><?php echo html::select('openedBuild[]', $builds, $buildID, "size=4 multiple=multiple class='chosen form-control'");?></span>
<span class='input-group-addon' id='buildBoxActions'></span>
<span class='input-group-btn'><?php echo html::commonButton('<i class="icon icon-filter"></i>', "class='btn btn-default' data-toggle='tooltip' onclick='loadAllBuilds()' title='{$lang->bug->allBuilds}'")?></span>
<span class='input-group-addon fix-border' id='buildBoxActions'></span>
<span class='input-group-btn'><?php echo html::commonButton($lang->bug->allBuilds, "class='btn btn-default' data-toggle='tooltip' onclick='loadAllBuilds()'")?></span>
</div>
</td>
</tr>
@@ -80,7 +80,7 @@ js::set('refresh', $lang->refresh);
<td>
<div class='input-group'>
<span id='assignedToBox'><?php echo html::select('assignedTo', $projectMembers, $assignedTo, "class='form-control chosen'");?></span>
<span class='input-group-btn'><?php echo html::commonButton('<i class="icon icon-filter"></i>', "class='btn btn-default' onclick='loadAllUsers()' data-toggle='tooltip' title='{$lang->bug->allUsers}'");?></span>
<span class='input-group-btn'><?php echo html::commonButton($lang->bug->allUsers, "class='btn btn-default' onclick='loadAllUsers()' data-toggle='tooltip'");?></span>
</div>
</td>
</tr>
@@ -89,7 +89,7 @@ js::set('refresh', $lang->refresh);
<tr>
<th><?php echo $lang->bug->type;?></th>
<td>
<div class='input-group'>
<div class='clearfix' id='bugTypeInputGroup'>
<?php
/* Remove the unused types. */
unset($lang->bug->typeList['designchange']);
+2 -2
View File
@@ -21,7 +21,7 @@
<div id='querybox' class='show'></div>
</div>
<form method='post' class='form-condensed' target='hiddenwin' id='linkBugsForm'>
<table class='table table-condensed table-hover table-striped tablesorter' id='bugList'>
<table class='table table-condensed table-hover table-striped tablesorter table-selectable' id='bugList'>
<?php if($bugs2Link):?>
<thead>
<tr>
@@ -39,7 +39,7 @@
<?php foreach($bugs2Link as $bug2Link):?>
<?php $bugLink = $this->createLink('bug', 'view', "bugID=$bug2Link->id");?>
<tr class='text-center'>
<td class='text-left'>
<td class='cell-id'>
<input type='checkbox' name='bugs[]' value='<?php echo $bug2Link->id;?>'/>
<?php echo html::a($bugLink, sprintf('%03d', $bug2Link->id));?>
</td>
+4 -2
View File
@@ -39,7 +39,10 @@
<div class='col-main'>
<div class='panel panel-sm'>
<div class='panel-heading'>
<strong><?php echo $lang->bug->report->common;?></strong>
<strong>
<?php echo $lang->bug->report->common;?>
<span><?php echo $lang->report->notice->help?></span>
</strong>
</div>
<table class='table active-disabled'>
<?php foreach($charts as $chartType => $chartOption):?>
@@ -76,7 +79,6 @@
<?php endforeach;?>
</table>
</div>
<div class='alert alert-info'><?php echo $lang->report->notice->help?></div>
</div>
</div>
<?php include '../../common/view/footer.html.php';?>
+4 -4
View File
@@ -11,12 +11,12 @@
*/
?>
<?php $mailTitle = 'BUG #' . $bug->id . ' ' . $bug->title;?>
<?php include '../../common/view/mail.header.html.php';?>
<?php include $this->app->getModuleRoot() . 'common/view/mail.header.html.php';?>
<tr>
<td>
<table cellpadding='0' cellspacing='0' width='600' style='border: none; border-collapse: collapse;'>
<tr>
<td style='padding: 10px; background-color: #F8FAFE; border: none; font-size: 14px; font-weight: 500; border-bottom: 1px solid #e5e5e5;'><?php echo html::a(common::getSysURL() . $this->createLink('bug', 'view', "bugID=$bug->id"), $mailTitle, '', "style='color: #333'");?></td>
<td style='padding: 10px; background-color: #F8FAFE; border: none; font-size: 14px; font-weight: 500; border-bottom: 1px solid #e5e5e5;'><?php echo html::a(zget($this->config->mail, 'domain', common::getSysURL()) . helper::createLink('bug', 'view', "bugID=$bug->id"), $mailTitle, '', "style='color: #333; text-decoration: underline;'");?></td>
</tr>
</table>
</td>
@@ -24,9 +24,9 @@
<tr>
<td style='padding: 10px; border: none;'>
<fieldset style='border: 1px solid #e5e5e5'>
<legend style='color: #114f8e'><?php echo $lang->bug->legendSteps;?></legend>
<legend style='color: #114f8e'><?php echo $this->lang->bug->legendSteps;?></legend>
<div style='padding:5px;'><?php echo $bug->steps;?></div>
</fieldset>
</td>
</tr>
<?php include '../../common/view/mail.footer.html.php';?>
<?php include $this->app->getModuleRoot() . 'common/view/mail.footer.html.php';?>
+2 -2
View File
@@ -148,7 +148,7 @@ class build extends control
$this->view->title = "BUILD #$build->id $build->name - " . $projects[$build->project];
$this->view->position[] = html::a($this->createLink('project', 'task', "projectID=$build->project"), $projects[$build->project]);
$this->view->position[] = $this->lang->build->view;
$this->view->generatedBugs = $this->bug->getProjectBugs($build->project, 'status_desc,id_desc', null, $build->id);
$this->view->generatedBugs = $this->bug->getProjectBugs($build->project, $build->id, '', 0, 'status_desc,id_desc', null);
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->build = $build;
$this->view->stories = $stories;
@@ -333,7 +333,7 @@ class build extends control
if($browseType == 'bySearch')
{
$allStories = $this->story->getBySearch($build->product, $queryID, 'id', null, $build->project);
$allStories = $this->story->getBySearch($build->product, $queryID, 'id', null, $build->project, $build->branch);
}
else
{
+1 -1
View File
@@ -8,4 +8,4 @@
.tabs .tab-content .tab-pane #querybox{margin:0px; border-left:1px solid #ddd; border-right:1px solid #ddd;}
.tabs .tab-content .tab-pane #querybox form {padding-left:0px;}
.table-actions {padding-left: 8px;}
.table-actions {padding-left: 5px;}
+5 -5
View File
@@ -12,8 +12,8 @@
$lang->build->common = "Build";
$lang->build->create = "Create";
$lang->build->edit = "Edit";
$lang->build->linkStory = "Link Story";
$lang->build->linkBug = "Link Bug";
$lang->build->linkStory = "Relate Story";
$lang->build->linkBug = "Relate Bug";
$lang->build->delete = "Delete Build";
$lang->build->deleted = "Deleted";
$lang->build->view = "Build Details";
@@ -41,8 +41,8 @@ $lang->build->unlinkStory = 'Remove Story';
$lang->build->unlinkBug = 'Remove Bug';
$lang->build->stories = 'Finished Story';
$lang->build->bugs = 'Solved Bug';
$lang->build->generatedBugs = 'Generated Bug';
$lang->build->noProduct = " <span style='color:red'>This {$lang->projectCommon} has not linked to {$lang->productCommon}, so Build cannot be created. Please first <a href='%s'> link {$lang->productCommon}</a></span>";
$lang->build->generatedBugs = 'Remained Bug';
$lang->build->noProduct = " <span style='color:red'>This {$lang->projectCommon} has not relateed to {$lang->productCommon}, so Build cannot be created. Please first <a href='%s'> relate {$lang->productCommon}</a></span>";
$lang->build->finishStories = ' %s Stories have been finished.';
$lang->build->resolvedBugs = ' %s Bugs have been solved.';
@@ -50,7 +50,7 @@ $lang->build->createdBugs = ' %s Bugs have been created.';
$lang->build->placeholder = new stdclass();
$lang->build->placeholder->scmPath = ' Source code repository, e.g. Subversion/Git Library path';
$lang->build->placeholder->filePath = ' Path of this Build package for download.';
$lang->build->placeholder->filePath = ' Path of this Build package for downloading.';
$lang->build->action = new stdclass();
$lang->build->action->buildopened = '$date, created by <strong>$actor</strong>, Build <strong>$extra</strong>.' . "\n";
+18
View File
@@ -289,6 +289,10 @@ class buildModel extends model
$build->stories .= ',' . join(',', $this->post->stories);
$this->dao->update(TABLE_BUILD)->set('stories')->eq($build->stories)->where('id')->eq((int)$buildID)->exec();
foreach($this->post->stories as $storyID)
{
$this->loadModel('action')->create('story', $storyID, 'linked2build', '', $buildID);
}
}
/**
@@ -304,6 +308,7 @@ class buildModel extends model
$build = $this->getByID($buildID);
$build->stories = trim(str_replace(",$storyID,", ',', ",$build->stories,"), ',');
$this->dao->update(TABLE_BUILD)->set('stories')->eq($build->stories)->where('id')->eq((int)$buildID)->exec();
$this->loadModel('action')->create('story', $storyID, 'unlinkedfrombuild', '', $buildID);
}
/**
@@ -323,6 +328,10 @@ class buildModel extends model
foreach($storyList as $storyID) $build->stories = str_replace(",$storyID,", ',', $build->stories);
$build->stories = trim($build->stories, ',');
$this->dao->update(TABLE_BUILD)->set('stories')->eq($build->stories)->where('id')->eq((int)$buildID)->exec();
foreach($this->post->unlinkStories as $unlinkStoryID)
{
$this->loadModel('action')->create('story', $unlinkStoryID, 'unlinkedfrombuild', '', $buildID);
}
}
/**
@@ -339,6 +348,10 @@ class buildModel extends model
$build->bugs .= ',' . join(',', $this->post->bugs);
$this->updateLinkedBug($build);
$this->dao->update(TABLE_BUILD)->set('bugs')->eq($build->bugs)->where('id')->eq((int)$buildID)->exec();
foreach($this->post->bugs as $bugID)
{
$this->loadModel('action')->create('bug', $bugID, 'linked2build', '', $buildID);
}
}
/**
@@ -354,6 +367,7 @@ class buildModel extends model
$build = $this->getByID($buildID);
$build->bugs = trim(str_replace(",$bugID,", ',', ",$build->bugs,"), ',');
$this->dao->update(TABLE_BUILD)->set('bugs')->eq($build->bugs)->where('id')->eq((int)$buildID)->exec();
$this->loadModel('action')->create('bug', $bugID, 'unlinkedfrombuild', '', $buildID);
}
/**
@@ -374,5 +388,9 @@ class buildModel extends model
foreach($bugList as $bugID) $build->bugs = str_replace(",$bugID,", ',', $build->bugs);
$build->bugs = trim($build->bugs, ',');
$this->dao->update(TABLE_BUILD)->set('bugs')->eq($build->bugs)->where('id')->eq((int)$buildID)->exec();
foreach($this->post->unlinkBugs as $unlinkBugID)
{
$this->loadModel('action')->create('bug', $unlinkBugID, 'unlinkedfrombuild', '', $buildID);
}
}
}
+3 -3
View File
@@ -45,7 +45,7 @@
<tr>
<th><?php echo $lang->build->name;?></th>
<td class='w-p25-f'>
<?php echo html::input('name', '', "class='form-control'");?>
<?php echo html::input('name', '', "class='form-control' autocomplete='off'");?>
</td>
<td>
<?php if($lastBuild):?>
@@ -63,11 +63,11 @@
</tr>
<tr>
<th><?php echo $lang->build->scmPath;?></th>
<td colspan='2'><?php echo html::input('scmPath', '', "class='form-control' placeholder='{$lang->build->placeholder->scmPath}'");?></td>
<td colspan='2'><?php echo html::input('scmPath', '', "class='form-control' placeholder='{$lang->build->placeholder->scmPath}' autocomplete='off'");?></td>
</tr>
<tr>
<th><?php echo $lang->build->filePath;?></th>
<td colspan='2'><?php echo html::input('filePath', '', "class='form-control' placeholder='{$lang->build->placeholder->filePath}'");?></td>
<td colspan='2'><?php echo html::input('filePath', '', "class='form-control' placeholder='{$lang->build->placeholder->filePath}' autocomplete='off'");?></td>
</tr>
<tr>
<th><?php echo $lang->build->files;?></th>
+3 -3
View File
@@ -40,7 +40,7 @@
</tr>
<tr>
<th><?php echo $lang->build->name;?></th>
<td><?php echo html::input('name', $build->name, "class='form-control'");?></td>
<td><?php echo html::input('name', $build->name, "class='form-control' autocomplete='off'");?></td>
</tr>
<tr>
<th><?php echo $lang->build->builder;?></th>
@@ -52,11 +52,11 @@
</tr>
<tr>
<th><?php echo $lang->build->scmPath;?></th>
<td colspan='2'><?php echo html::input('scmPath', $build->scmPath, "class='form-control' placeholder='{$lang->build->placeholder->scmPath}'");?></td>
<td colspan='2'><?php echo html::input('scmPath', $build->scmPath, "class='form-control' placeholder='{$lang->build->placeholder->scmPath}' autocomplete='off'");?></td>
</tr>
<tr>
<th><?php echo $lang->build->filePath;?></th>
<td colspan='2'><?php echo html::input('filePath', $build->filePath, "class='form-control' placeholder='{$lang->build->placeholder->filePath}'");?></td>
<td colspan='2'><?php echo html::input('filePath', $build->filePath, "class='form-control' placeholder='{$lang->build->placeholder->filePath}' autocomplete='off'");?></td>
</tr>
<tr>
<th><?php echo $lang->build->files;?></th>
+3 -3
View File
@@ -13,7 +13,7 @@
<div id='querybox' class='show'></div>
<div id='unlinkBugList'>
<form method='post' id='unlinkedBugsForm' target='hiddenwin' action='<?php echo $this->createLink('build', 'linkBug', "buildID={$build->id}&browseType=$browseType&param=$param");?>'>
<table class='table table-condensed table-hover table-striped tablesorter table-fixed'>
<table class='table table-condensed table-hover table-striped tablesorter table-fixed table-selectable'>
<caption class='text-left text-special'><?php echo html::icon('unlink');?> &nbsp;<strong><?php echo $lang->productplan->unlinkedBugs;?></strong></caption>
<thead>
<tr class='colhead'>
@@ -29,8 +29,8 @@
<?php foreach($allBugs as $bug):?>
<?php if(strpos(",{$build->bugs},", ",$bug->id,") !== false) continue;?>
<tr>
<td class='text-left'>
<input class='ml-10px' type='checkbox' name='bugs[<?php echo $bug->id?>]' value='<?php echo $bug->id;?>' <?php if($bug->status == 'resolved' or $bug->status == 'closed') echo "checked";?> />
<td class='cell-id'>
<input type='checkbox' name='bugs[<?php echo $bug->id?>]' value='<?php echo $bug->id;?>' <?php if($bug->status == 'resolved' or $bug->status == 'closed') echo "checked";?> />
<?php echo html::a($this->createLink('bug', 'view', "bugID=$bug->id"), $bug->id);?>
</td>
<td><span class='<?php echo 'pri' . zget($lang->bug->priList, $bug->pri, $bug->pri);?>'><?php echo zget($lang->bug->priList, $bug->pri, $bug->pri)?></span></td>
+3 -3
View File
@@ -13,7 +13,7 @@
<div id='querybox' class='show'></div>
<div id='unlinkStoryList'>
<form method='post' id='unlinkedStoriesForm' target='hiddenwin' action='<?php echo $this->createLink('build', 'linkStory', "buildID={$build->id}&browseType=$browseType&param=$param");?>'>
<table class='table table-condensed table-hover table-striped tablesorter table-fixed'>
<table class='table table-condensed table-hover table-striped tablesorter table-fixed table-selectable'>
<caption class='text-left text-special'><?php echo html::icon('unlink');?> &nbsp;<strong><?php echo $lang->productplan->unlinkedStories;?></strong></caption>
<thead>
<tr>
@@ -31,8 +31,8 @@
<?php foreach($allStories as $story):?>
<?php if(strpos(",{$build->stories},", ",{$story->id},") !== false) continue; ?>
<tr>
<td class='text-left'>
<input class='ml-10px' type='checkbox' name='stories[]' value='<?php echo $story->id;?>' <?php if($story->stage == 'developed' or $story->status == 'closed') echo 'checked';?> />
<td class='cell-id'>
<input type='checkbox' name='stories[]' value='<?php echo $story->id;?>' <?php if($story->stage == 'developed' or $story->status == 'closed') echo 'checked';?> />
<?php echo html::a($this->createLink('story', 'view', "storyID=$story->id"), $story->id);?>
</td>
<td><span class='<?php echo 'pri' . zget($lang->story->priList, $story->pri, $story->pri);?>'><?php echo zget($lang->story->priList, $story->pri, $story->pri)?></span></td>
+6 -6
View File
@@ -56,7 +56,7 @@
<div class='linkBox'></div>
<?php endif;?>
<form method='post' target='hiddenwin' action='<?php echo inlink('batchUnlinkStory', "buildID={$build->id}")?>' id='linkedStoriesForm'>
<table class='table table-hover table-condensed table-striped tablesorter table-fixed' id='storyList'>
<table class='table table-hover table-condensed table-striped tablesorter table-fixed table-selectable' id='storyList'>
<thead>
<tr>
<th class='w-id'><?php echo $lang->idAB;?></th>
@@ -73,9 +73,9 @@
<?php foreach($stories as $storyID => $story):?>
<?php $storyLink = $this->createLink('story', 'view', "storyID=$story->id", '', true);?>
<tr class='text-center'>
<td>
<td class='cell-id'>
<?php if($canBatchUnlink):?>
<input class='ml-10px' type='checkbox' name='unlinkStories[]' value='<?php echo $story->id;?>'/>
<input type='checkbox' name='unlinkStories[]' value='<?php echo $story->id;?>'/>
<?php endif;?>
<?php echo sprintf('%03d', $story->id);?>
</td>
@@ -115,7 +115,7 @@
<div class='linkBox'></div>
<?php endif;?>
<form method='post' target='hiddenwin' action="<?php echo inLink('batchUnlinkBug', "build=$build->id");?>" id='linkedBugsForm'>
<table class='table table-hover table-condensed table-striped tablesorter table-fixed' id='bugList'>
<table class='table table-hover table-condensed table-striped tablesorter table-fixed table-selectable' id='bugList'>
<thead>
<tr>
<th class='w-id'><?php echo $lang->idAB;?></th>
@@ -132,9 +132,9 @@
<?php foreach($bugs as $bug):?>
<?php $bugLink = $this->createLink('bug', 'view', "bugID=$bug->id", '', true);?>
<tr class='text-center'>
<td>
<td class='cell-id'>
<?php if($canBatchUnlink):?>
<input class='ml-10px' type='checkbox' name='unlinkBugs[]' value='<?php echo $bug->id;?>'/>
<input type='checkbox' name='unlinkBugs[]' value='<?php echo $bug->id;?>'/>
<?php endif;?>
<?php echo sprintf('%03d', $bug->id);?>
<td class='text-left nobr' title='<?php echo $bug->title?>'><?php echo html::a($bugLink, $bug->title, '', "class='preview'");?></td>
+23 -23
View File
@@ -23,7 +23,7 @@ $lang->welcome = "%s PMS";
$lang->logout = 'Logout';
$lang->login = 'Login';
$lang->help = 'Help';
$lang->aboutZenTao = 'About ZenTao';
$lang->aboutZenTao = 'ZenTao';
$lang->profile = 'Profile';
$lang->changePassword = 'Password';
$lang->runInfo = "<div class='row'><div class='u-1 a-center' id='debugbar'>Time %s MS, Memory %s KB, Query %s. </div></div>";
@@ -34,7 +34,7 @@ $lang->refresh = 'Refresh';
$lang->edit = 'Edit';
$lang->delete = 'Delete';
$lang->close = 'Close';
$lang->unlink = 'Unlink';
$lang->unlink = 'Unrelate';
$lang->import = 'Import';
$lang->export = 'Export';
$lang->setFileName = 'File Name';
@@ -54,7 +54,7 @@ $lang->comment = 'Note';
$lang->history = 'History';
$lang->attatch = 'Attachment';
$lang->reverse = 'Reverse';
$lang->switchDisplay = 'Toggle Show';
$lang->switchDisplay = 'Toggle';
$lang->addFiles = 'Add';
$lang->files = 'File ';
$lang->pasteText = 'Paste';
@@ -83,12 +83,12 @@ $lang->loading = 'Loading...';
$lang->notFound = 'Not found!';
$lang->showAll = '[[Show All]]';
$lang->future = 'Coming';
$lang->future = 'Pending';
$lang->year = 'Year';
$lang->workingHour = 'Man-Hour';
$lang->idAB = 'ID';
$lang->priAB = 'Privilege';
$lang->priAB = 'P';
$lang->statusAB = 'Status';
$lang->openedByAB = 'Open';
$lang->assignedToAB = 'To';
@@ -99,7 +99,7 @@ $lang->common->common = 'Common Module';
/* 主导航菜单。*/
$lang->menu = new stdclass();
$lang->menu->my = '<i class="icon-home"></i><span> My Zone</span>|my|index';
$lang->menu->my = '<i class="icon-home"></i><span>Dashboard</span>|my|index';
$lang->menu->product = $lang->productCommon . '|product|index';
$lang->menu->project = $lang->projectCommon . '|project|index';
$lang->menu->qa = 'Testing|qa|index';
@@ -118,8 +118,8 @@ $lang->searchObjects['product'] = $lang->productCommon;
$lang->searchObjects['user'] = 'User';
$lang->searchObjects['build'] = 'Build';
$lang->searchObjects['release'] = 'Release';
$lang->searchObjects['productplan'] = $lang->productCommon . 'Planning';
$lang->searchObjects['testtask'] = 'Testing Build';
$lang->searchObjects['productplan'] = $lang->productCommon . 'Plan';
$lang->searchObjects['testtask'] = 'Test Task';
$lang->searchObjects['doc'] = 'Document';
$lang->searchTips = 'ID (ctrl+g)';
@@ -159,11 +159,11 @@ $lang->my = new stdclass();
$lang->my->menu = new stdclass();
$lang->my->menu->account = array('link' => '<span id="myname"><i class="icon-user"></i> %s' . $lang->arrow . '</span>', 'fixed' => true);
$lang->my->menu->index = 'Homepage|my|index';
$lang->my->menu->index = 'Home|my|index';
$lang->my->menu->todo = array('link' => 'To-Do|my|todo|', 'subModule' => 'todo');
$lang->my->menu->task = array('link' => 'Task|my|task|', 'subModule' => 'task');
$lang->my->menu->bug = array('link' => 'Bug|my|bug|', 'subModule' => 'bug');
$lang->my->menu->testtask = array('link' => 'Testing|my|testtask|', 'subModule' => 'testcase,testtask', 'alias' => 'testcase');
$lang->my->menu->testtask = array('link' => 'Test Task|my|testtask|', 'subModule' => 'testcase,testtask', 'alias' => 'testcase');
$lang->my->menu->story = array('link' => 'Story|my|story|', 'subModule' => 'story');
$lang->my->menu->myProject = "{$lang->projectCommon}|my|project|";
$lang->my->menu->dynamic = 'Dynamic|my|dynamic|';
@@ -181,10 +181,10 @@ $lang->product->menu = new stdclass();
$lang->product->menu->list = array('link' => '%s', 'fixed' => true);
$lang->product->menu->story = array('link' => 'Story|product|browse|productID=%s', 'alias' => 'batchedit', 'subModule' => 'story');
$lang->product->menu->dynamic = 'Dynamic|product|dynamic|productID=%s';
$lang->product->menu->plan = array('link' => 'Planning|productplan|browse|productID=%s', 'subModule' => 'productplan');
$lang->product->menu->plan = array('link' => 'Plan|productplan|browse|productID=%s', 'subModule' => 'productplan');
$lang->product->menu->release = array('link' => 'Release|release|browse|productID=%s', 'subModule' => 'release');
$lang->product->menu->roadmap = 'Roadmap|product|roadmap|productID=%s';
$lang->product->menu->doc = array('link' => 'Document|product|doc|productID=%s', 'subModule' => 'doc');
$lang->product->menu->doc = array('link' => 'Document|doc|objectLibs|type=product&objectID=%s&from=product', 'subModule' => 'doc');
$lang->product->menu->branch = '@branch@|branch|manage|productID=%s';
$lang->product->menu->module = 'Module|tree|browse|productID=%s&view=story';
$lang->product->menu->view = array('link' => 'Overview|product|view|productID=%s', 'alias' => 'edit');
@@ -213,9 +213,9 @@ $lang->project->menu->story = array('link' => 'Story|project|story|projectID
$lang->project->menu->bug = 'Bug|project|bug|projectID=%s';
$lang->project->menu->dynamic = 'Dynamic|project|dynamic|projectID=%s';
$lang->project->menu->build = array('link' => 'Build|project|build|projectID=%s', 'subModule' => 'build');
$lang->project->menu->testtask = 'Testing|project|testtask|projectID=%s';
$lang->project->menu->testtask = 'Test Task|project|testtask|projectID=%s';
$lang->project->menu->team = array('link' => 'Team|project|team|projectID=%s', 'alias' => 'managemembers');
$lang->project->menu->doc = array('link' => 'Document|project|doc|porjectID=%s', 'subModule' => 'doc');
$lang->project->menu->doc = array('link' => 'Document|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
$lang->project->menu->view = array('link' => 'Overview|project|view|projectID=%s', 'alias' => 'edit,start,suspend,putoff,close');
$lang->project->menu->create = array('link' => "<i class='icon-plus'></i>&nbsp;Add{$lang->projectCommon}|project|create", 'float' => 'right');
@@ -304,14 +304,13 @@ $lang->admin = new stdclass();
$lang->admin->menu = new stdclass();
$lang->admin->menu->index = array('link' => 'Homepage|admin|index');
$lang->admin->menu->extension = array('link' => 'Extension|extension|browse', 'subModule' => 'extension');
$lang->admin->menu->custom = array('link' => 'Custom|custom|index', 'subModule' => 'custom');
$lang->admin->menu->custom = array('link' => 'Custom|custom|set', 'subModule' => 'custom');
$lang->admin->menu->mail = array('link' => 'Email|mail|index', 'subModule' => 'mail');
$lang->admin->menu->convert = array('link' => 'Import|convert|index', 'subModule' => 'convert');
$lang->admin->menu->backup = array('link' => 'Backup|backup|index', 'subModule' => 'backup');
$lang->admin->menu->safe = array('link' => 'Security|admin|safe', 'alias' => 'checkweak');
$lang->admin->menu->cron = array('link' => 'Cron|cron|index', 'subModule' => 'cron');
$lang->admin->menu->trashes = array('link' => 'Recycle|action|trash', 'subModule' => 'action');
$lang->admin->menu->dev = array('link' => 'Reproduct|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor');
$lang->admin->menu->dev = array('link' => 'Develop|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor');
$lang->admin->menu->sso = 'RangerTeam|admin|sso';
$lang->convert = new stdclass();
@@ -385,7 +384,7 @@ $lang->error->passwordrule = "Password should meet requirements. It should be
$lang->error->accessDenied = 'Access is denied.';
$lang->error->pasteImg = 'Paste Image is not allowed in your browser!';
$lang->error->noData = 'No Data';
$lang->error->editedByOther = 'This record might have been modified. Please refresh and try to edit again!';
$lang->error->editedByOther = 'This record might have been changed. Please refresh and try to edit again!';
$lang->error->tutorialData = 'No data can be imported in tutorial mode. Please exit tutorial first!';
/* 分页信息。*/
@@ -408,8 +407,9 @@ $lang->noticeImport = "<p style='font-size:14px'>Imported data contains data th
$lang->noResultsMatch = "No results match!";
$lang->searchMore = "More results:";
$lang->chooseUsersToMail = "Choose users you want send Email to...";
$lang->chooseUsersToMail = "Choose users you will send notifications to...";
$lang->browserNotice = 'Your current browser might not show the best effect. Please use Chrome, Firefox, IE9+, Opera or Safari.';
$lang->noticePasteImg = "Paste image to editor.";
/* 时间格式设置。*/
define('DT_DATETIME1', 'Y-m-d H:i:s');
@@ -464,12 +464,12 @@ $lang->icons['test'] = 'check';
$lang->icons['testtask'] = 'check';
$lang->icons['group'] = 'group';
$lang->icons['team'] = 'group';
$lang->icons['company'] = 'building';
$lang->icons['company'] = 'sitemap';
$lang->icons['user'] = 'user';
$lang->icons['dept'] = 'sitemap';
$lang->icons['tree'] = 'sitemap';
$lang->icons['usecase'] = 'sitemap';
$lang->icons['testcase'] = 'smile';
$lang->icons['testcase'] = 'sitemap';
$lang->icons['result'] = 'list-alt';
$lang->icons['mail'] = 'envelope';
$lang->icons['trash'] = 'trash';
@@ -501,8 +501,8 @@ $lang->icons['assignTo'] = 'hand-right';
$lang->icons['change'] = 'random';
$lang->icons['link'] = 'link';
$lang->icons['close'] = 'off';
$lang->icons['activate'] = 'off';
$lang->icons['review'] = 'search';
$lang->icons['activate'] = 'magic';
$lang->icons['review'] = 'review';
$lang->icons['confirm'] = 'search';
$lang->icons['confirmBug'] = 'search';
$lang->icons['putoff'] = 'calendar';
+6 -6
View File
@@ -304,9 +304,8 @@ $lang->admin = new stdclass();
$lang->admin->menu = new stdclass();
$lang->admin->menu->index = array('link' => '首页|admin|index');
$lang->admin->menu->extension = array('link' => '插件|extension|browse', 'subModule' => 'extension');
$lang->admin->menu->custom = array('link' => '自定义|custom|index', 'subModule' => 'custom');
$lang->admin->menu->custom = array('link' => '自定义|custom|set', 'subModule' => 'custom');
$lang->admin->menu->mail = array('link' => '发信|mail|index', 'subModule' => 'mail');
$lang->admin->menu->convert = array('link' => '导入|convert|index', 'subModule' => 'convert');
$lang->admin->menu->backup = array('link' => '备份|backup|index', 'subModule' => 'backup');
$lang->admin->menu->safe = array('link' => '安全|admin|safe', 'alias' => 'checkweak');
$lang->admin->menu->cron = array('link' => '计划任务|cron|index', 'subModule' => 'cron');
@@ -410,6 +409,7 @@ $lang->noResultsMatch = "没有匹配结果";
$lang->searchMore = "搜索此关键字的更多结果:";
$lang->chooseUsersToMail = "选择要发信通知的用户...";
$lang->browserNotice = '你目前使用的浏览器可能无法得到最佳浏览效果,建议使用Chrome、火狐、IE9+、Opera、Safari浏览器。';
$lang->noticePasteImg = "可以在编辑器直接贴图。";
/* 时间格式设置。*/
define('DT_DATETIME1', 'Y-m-d H:i:s');
@@ -464,12 +464,12 @@ $lang->icons['test'] = 'check';
$lang->icons['testtask'] = 'check';
$lang->icons['group'] = 'group';
$lang->icons['team'] = 'group';
$lang->icons['company'] = 'building';
$lang->icons['company'] = 'sitemap';
$lang->icons['user'] = 'user';
$lang->icons['dept'] = 'sitemap';
$lang->icons['tree'] = 'sitemap';
$lang->icons['usecase'] = 'sitemap';
$lang->icons['testcase'] = 'smile';
$lang->icons['testcase'] = 'sitemap';
$lang->icons['result'] = 'list-alt';
$lang->icons['mail'] = 'envelope';
$lang->icons['trash'] = 'trash';
@@ -501,8 +501,8 @@ $lang->icons['assignTo'] = 'hand-right';
$lang->icons['change'] = 'random';
$lang->icons['link'] = 'link';
$lang->icons['close'] = 'off';
$lang->icons['activate'] = 'off';
$lang->icons['review'] = 'search';
$lang->icons['activate'] = 'magic';
$lang->icons['review'] = 'review';
$lang->icons['confirm'] = 'search';
$lang->icons['confirmBug'] = 'search';
$lang->icons['putoff'] = 'calendar';
+10 -6
View File
@@ -74,6 +74,7 @@ $lang->tutorialConfirm = '檢測到你尚未退出新手教程模式,是否現
$lang->preShortcutKey = '[快捷鍵:←]';
$lang->nextShortcutKey = '[快捷鍵:→]';
$lang->backShortcutKey = '[快捷鍵:Alt+↑]';
$lang->select = '選擇';
$lang->selectAll = '全選';
@@ -274,6 +275,9 @@ $lang->report->menu->prj = array('link' => $lang->projectCommon . '|report|p
$lang->report->menu->test = array('link' => '測試|report|bugcreate', 'alias' => 'bugassign');
$lang->report->menu->staff = array('link' => '組織|report|workload');
$lang->report->notice = new stdclass();
$lang->report->notice->help = '註:統計報表的數據,來源於列表頁面的檢索結果,生成統計報表前請先在列表頁面進行檢索。';
/* 組織結構視圖菜單設置。*/
$lang->company = new stdclass();
$lang->company->menu = new stdclass();
@@ -300,9 +304,8 @@ $lang->admin = new stdclass();
$lang->admin->menu = new stdclass();
$lang->admin->menu->index = array('link' => '首頁|admin|index');
$lang->admin->menu->extension = array('link' => '插件|extension|browse', 'subModule' => 'extension');
$lang->admin->menu->custom = array('link' => '自定義|custom|index', 'subModule' => 'custom');
$lang->admin->menu->custom = array('link' => '自定義|custom|set', 'subModule' => 'custom');
$lang->admin->menu->mail = array('link' => '發信|mail|index', 'subModule' => 'mail');
$lang->admin->menu->convert = array('link' => '導入|convert|index', 'subModule' => 'convert');
$lang->admin->menu->backup = array('link' => '備份|backup|index', 'subModule' => 'backup');
$lang->admin->menu->safe = array('link' => '安全|admin|safe', 'alias' => 'checkweak');
$lang->admin->menu->cron = array('link' => '計劃任務|cron|index', 'subModule' => 'cron');
@@ -406,6 +409,7 @@ $lang->noResultsMatch = "沒有匹配結果";
$lang->searchMore = "搜索此關鍵字的更多結果:";
$lang->chooseUsersToMail = "選擇要發信通知的用戶...";
$lang->browserNotice = '你目前使用的瀏覽器可能無法得到最佳瀏覽效果,建議使用Chrome、火狐、IE9+、Opera、Safari瀏覽器。';
$lang->noticePasteImg = "可以在編輯器直接貼圖。";
/* 時間格式設置。*/
define('DT_DATETIME1', 'Y-m-d H:i:s');
@@ -460,12 +464,12 @@ $lang->icons['test'] = 'check';
$lang->icons['testtask'] = 'check';
$lang->icons['group'] = 'group';
$lang->icons['team'] = 'group';
$lang->icons['company'] = 'building';
$lang->icons['company'] = 'sitemap';
$lang->icons['user'] = 'user';
$lang->icons['dept'] = 'sitemap';
$lang->icons['tree'] = 'sitemap';
$lang->icons['usecase'] = 'sitemap';
$lang->icons['testcase'] = 'smile';
$lang->icons['testcase'] = 'sitemap';
$lang->icons['result'] = 'list-alt';
$lang->icons['mail'] = 'envelope';
$lang->icons['trash'] = 'trash';
@@ -497,8 +501,8 @@ $lang->icons['assignTo'] = 'hand-right';
$lang->icons['change'] = 'random';
$lang->icons['link'] = 'link';
$lang->icons['close'] = 'off';
$lang->icons['activate'] = 'off';
$lang->icons['review'] = 'search';
$lang->icons['activate'] = 'magic';
$lang->icons['review'] = 'review';
$lang->icons['confirm'] = 'search';
$lang->icons['confirmBug'] = 'search';
$lang->icons['putoff'] = 'calendar';
+23 -24
View File
@@ -168,20 +168,16 @@ class commonModel extends model
if($module == 'sso' and $method == 'logout') return true;
if($module == 'sso' and $method == 'bind') return true;
if($module == 'sso' and $method == 'gettodolist') return true;
if($module == 'product' and $method == 'showerrornone') return true;
if($module == 'block' and $method == 'printblock') return true;
if($module == 'block' and $method == 'main') return true;
if($this->loadModel('user')->isLogon())
if($this->loadModel('user')->isLogon() or ($this->app->company->guest and $this->app->user->account == 'guest'))
{
if(stripos($method, 'ajax') !== false) return true;
if(stripos($method, 'downnotify') !== false) return true;
if($module == 'tutorial') return true;
if($module == 'block') return true;
if($module == 'product' and $method == 'showerrornone') return true;
}
if(stripos($method, 'ajaxgetdropmenu') !== false) return true;
if(stripos($method, 'ajaxgetmatcheditems') !== false) return true;
return false;
}
@@ -589,7 +585,7 @@ class commonModel extends model
{
global $lang;
echo html::a('javascript:;', "<i class='icon-qrcode'></i>", '', "class='qrCode $color' id='qrcodeBtn' title='{$lang->user->mobileLogin}'");
echo "<div class='popover top' id='qrcodePopover'><div class='arrow'></div><h3 class='popover-title'>{$lang->user->mobileLogin}</h3><div class='popover-content'><img src=\"javascript:;\"></div></div>";
echo "<div class='popover top' id='qrcodePopover'><div class='arrow'></div><h3 class='popover-title'>{$lang->user->mobileLogin}</h3><div class='popover-content'><img src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'></div></div>";
echo '<script>$(function(){$("#qrcodeBtn").click(function(){$("#qrcodePopover").toggleClass("show");}); $("#wrap").click(function(){$("#qrcodePopover").removeClass("show");});});</script>';
echo '<script>$(function(){$("#qrcodeBtn").hover(function(){$(".popover-content img").attr("src", "' . helper::createLink('misc', 'qrCode') . '");});});</script>';
}
@@ -870,6 +866,7 @@ class commonModel extends model
if(strtolower($key) == 'assigneddate') continue;
if(strtolower($key) == 'editedby') continue;
if(strtolower($key) == 'editeddate') continue;
if(strtolower($key) == 'uid') continue;
if($magicQuote) $value = stripslashes($value);
if($value != stripslashes($old->$key))
@@ -937,7 +934,6 @@ class commonModel extends model
* Get the previous and next object.
*
* @param string $type story|task|bug|case
* @param string $objectIDs
* @param string $objectID
* @access public
* @return void
@@ -952,7 +948,7 @@ class commonModel extends model
$existObject = $type . 'PreAndNext';
if(isset($_SESSION[$existObject]) and $_SESSION[$existObject]['objectID'] == $objectID) return $_SESSION[$existObject]['preAndNextObject'];
/* Get objectIDs. */
/* Get objectIDList. */
$table = $this->config->objectTables[$type];
$queryCondition = $type . 'QueryCondition';
$typeOnlyCondition = $type . 'OnlyCondition';
@@ -1015,10 +1011,12 @@ class commonModel extends model
if($onlyCondition)
{
$queryCondition = explode('WHERE', $sql);
if(!isset($queryCondition[1])) return true;
$queryCondition = explode('ORDER', $queryCondition[1]);
$queryCondition = str_replace('t1.', '', $queryCondition[0]);
$queryCondition = isset($queryCondition[1]) ? $queryCondition[1] : '';
if($queryCondition)
{
$queryCondition = explode('ORDER', $queryCondition);
$queryCondition = str_replace('t1.', '', $queryCondition[0]);
}
}
else
{
@@ -1033,17 +1031,14 @@ class commonModel extends model
/* Set the query condition session. */
$orderBy = explode('ORDER BY', $sql);
if(isset($orderBy[1]))
$orderBy = isset($orderBy[1]) ? $orderBy[1] : '';
if($orderBy)
{
$orderBy = explode('limit', $orderBy[1]);
$orderBy = str_replace('t1.', '', $orderBy[0]);
$this->session->set($objectType . 'OrderBy', $orderBy);
}
else
{
$this->session->set($objectType . 'OrderBy', '');
$orderBy = explode('limit', $orderBy);
$orderBy = $orderBy[0];
if($onlyCondition) $orderBy = str_replace('t1.', '', $orderBy);
}
$this->session->set($objectType . 'OrderBy', $orderBy);
}
/**
@@ -1132,9 +1127,12 @@ class commonModel extends model
$statusFile = $this->loadModel('upgrade')->checkSafeFile();
if($statusFile)
{
$cmd = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? $this->lang->upgrade->createFileWinCMD : $this->lang->upgrade->createFileLinuxCMD;
$cmd = sprintf($cmd, $statusFile);
echo "<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /></head><body>";
echo "<table align='center' style='margin-top:100px; border:1px solid gray; font-size:14px;'><tr><td>";
printf($this->lang->upgrade->setStatusFile, $statusFile, $statusFile, $statusFile);
echo "<table align='center' style='margin-top:100px; border:1px solid gray; font-size:14px;padding:8px;'><tr><td>";
printf($this->lang->upgrade->setStatusFile, $cmd, $statusFile);
die('</td></tr></table></body></html>');
}
}
@@ -1149,6 +1147,7 @@ class commonModel extends model
{
$module = $this->app->getModuleName();
$method = $this->app->getMethodName();
if(isset($this->app->user->modifyPassword) and $this->app->user->modifyPassword and $module != 'my' and $method != 'changepassword') die(js::locate(helper::createLink('my', 'changepassword')));
if($this->isOpenMethod($module, $method)) return true;
if(!$this->loadModel('user')->isLogon() and $this->server->php_auth_user) $this->user->identifyByPhpAuth();
if(!$this->loadModel('user')->isLogon() and $this->cookie->za) $this->user->identifyByCookie();
+2
View File
@@ -79,6 +79,8 @@ function toggleOrder(obj)
$(obj).find('.log-desc').attr('class', 'icon- log-asc');
}
$("#historyItem li").reverseOrder();
window.editor['lastComment'].remove();
initKindeditor();
}
function toggleComment(actionID)
+49
View File
@@ -87,9 +87,58 @@ if($config->debug)
});
};
jQuery.fn.progressPie = function(setting)
{
$(this).each(function()
{
var $this = $(this);
var $canvas = $this.is('canvas') ? $this : $this.find('canvas');
var options = $.extend(
{
value: 0,
color: '#4CAF50',
backColor: '#ddd',
doughnut: true,
doughnutSize: 85,
width: 20,
height: 20,
showTip: false,
name: '',
tipTemplate: "<%=value%>%",
animation: false
}, setting, $this.data());
var hasCanvas = $canvas.length;
if(!hasCanvas) $canvas = $('<canvas>').appendTo($this);
if($canvas.attr('width') !== undefined) options.width = $canvas.attr('width');
else $canvas.attr('width', options.width);
if($canvas.attr('height') !== undefined) options.height = $canvas.attr('height');
else $canvas.attr('height', options.height);
if(!hasCanvas && $.zui.browser.ie == 8) G_vmlCanvasManager.initElement($canvas[0]);
options.value = Math.max(0, Math.min(100, options.value));
var data =
[
{value: options.value, label: options.name, color: options.color},
{value: 100 - options.value, label: '', color: options.backColor}
];
$canvas[options.doughnut ? 'doughnutChart' : 'pieChart'](data, $.extend(
{
segmentShowStroke: false,
animation: options.animation,
showTooltips: options.showTip,
tooltipTemplate: options.tipTemplate,
percentageInnerCutout: options.doughnutSize,
}, options.chartOptions));
});
};
$(function()
{
$('.table-chart').tableChart();
$('.progress-pie').progressPie();
});
}());
</script>
+13 -4
View File
@@ -50,7 +50,15 @@ $(document).ready(function()
scrollPos : 'out',
tableClass : 'tablesorter',
storage : false,
selectable : {clickBehavior: 'multi'},
selectable :
{
clickBehavior: 'multi',
startDrag: function(e)
{
if(!this.multiKey && !$(e.target).closest('td[data-index="0"]').length) return false;
}
},
fixedHeader: true,
ready: function()
{
if(!this.$table) return;
@@ -62,14 +70,15 @@ $(document).ready(function()
$dropmenu.append("<li><a href='javascript:;' id='switchToTable'><?php echo $lang->datatable->switchToTable?></a></li>");
$dropdown.children('.dropdown').append($dropmenu);
this.$datatable.before($dropdown);
this.$datatable.find('[data-toggle=modal], a.iframe').modalTrigger();
$("a[data-toggle='showModuleModal']").click(function(){$('#showModuleModal').modal('show')});
this.$datatable.find('[data-toggle="modal"], a.iframe').modalTrigger();
if($.fn.progressPie) this.$datatable.find('.progress-pie').progressPie();
$('a[data-toggle="showModuleModal"]').click(function(){$('#showModuleModal').modal('show')});
$('#customBtn').modalTrigger();
$('#switchToTable').click(function()
{
saveDatatableConfig('mode', 'table', true)
saveDatatableConfig('mode', 'table', true);
});
}
});
+2 -3
View File
@@ -8,14 +8,13 @@
<?php if($onlybody != 'yes'):?>
</div><?php /* end '#wrap' in 'header.html.php'. */ ?>
<div id='footer'>
<div id="crumbs">
<div id='crumbs'>
<?php commonModel::printBreadMenu($this->moduleName, isset($position) ? $position : ''); ?>
</div>
<div id="poweredby">
<div id='poweredby'>
<a href='http://www.zentao.net' target='_blank' class='text-primary'><i class='icon-zentao'></i> <?php echo $lang->zentaoPMS . $config->version;?></a> &nbsp;
<?php echo $lang->proVersion;?>
<?php commonModel::printNotifyLink();?>
<?php commonModel::printQRCodeLink();?>
</div>
</div>
<?php endif;?>
+1 -1
View File
@@ -21,7 +21,7 @@ $clientTheme = $this->app->getClientTheme();
{
js::import($jsRoot . 'jquery/lib.js');
js::import($jsRoot . 'zui/min.js');
js::import($jsRoot . 'my.min.js');
js::import($jsRoot . 'my.full.js');
css::import($themeRoot . 'zui/css/min.css');
css::import($defaultTheme . 'style.css');
+48 -7
View File
@@ -42,6 +42,7 @@ var fullTools =
$(document).ready(initKindeditor);
function initKindeditor(afterInit)
{
$(':input[type=submit]').next('#uid').remove();
$(':input[type=submit]').after("<input type='hidden' id='uid' name='uid' value=" + kuid + ">");
var nextFormControl = 'input:not([type="hidden"]), textarea:not(.ke-edit-textarea), button[type="submit"], select';
$.each(editor.id, function(key, editorID)
@@ -51,6 +52,9 @@ function initKindeditor(afterInit)
if(editor.tools == 'fullTools') editorTool = fullTools;
var K = KindEditor, $editor = $('#' + editorID);
var placeholderText = $editor.attr('placeholder');
if(placeholderText == undefined) placeholderText = '';
var pasted;
var options =
{
cssPath:[themeRoot + 'zui/css/min.css'],
@@ -62,13 +66,13 @@ function initKindeditor(afterInit)
uploadJson: createLink('file', 'ajaxUpload', 'uid=' + kuid),
allowFileManager:true,
langType:'<?php echo $editorLang?>',
afterBlur: function(){this.sync();$editor.prev('.ke-container').removeClass('focus');},
afterFocus: function(){$editor.prev('.ke-container').addClass('focus');},
afterChange: function(){$editor.change().hide();},
afterCreate : function()
{
var doc = this.edit.doc;
var cmd = this.edit.cmd;
var frame = this.edit;
var doc = this.edit.doc;
var cmd = this.edit.cmd;
pasted = true;
if(!K.WEBKIT && !K.GECKO)
{
var pasted = false;
@@ -90,6 +94,12 @@ function initKindeditor(afterInit)
})
}, 10);
}
if(pasted && placeholderText.indexOf('<?php echo $this->lang->noticePasteImg?>') < 0)
{
if(placeholderText) placeholderText += '<br />';
placeholderText += ' <?php echo $this->lang->noticePasteImg?>';
}
/* Paste in chrome.*/
/* Code reference from http://www.foliotek.com/devblog/copy-images-from-clipboard-in-javascript/. */
if(K.WEBKIT)
@@ -104,7 +114,6 @@ function initKindeditor(afterInit)
var reader = new FileReader();
reader.onload = function(evt)
{
var result = evt.target.result;
var result = evt.target.result;
var arr = result.split(",");
var data = arr[1]; // raw base64
@@ -127,13 +136,45 @@ function initKindeditor(afterInit)
var html = K(doc.body).html();
if(html.search(/<img src="data:.+;base64,/) > -1)
{
K(doc.body).html(html.replace(/<img src="data:.+;base64,.*".*\/>/, ''));
$.post(createLink('file', 'ajaxPasteImage', 'uid=' + kuid), {editor: html}, function(data){K(doc.body).html(data);});
$.post(createLink('file', 'ajaxPasteImage', 'uid=' + kuid), {editor: html}, function(data)
{
if(data.indexOf('<img') == 0) data = '<p>' + data + '</p>';
frame.html(data);
});
}
}, 80);
});
}
/* End */
/* Add for placeholder. */
$(this.edit.doc).find('body').after('<span class="kindeditor-ph" style="width:100%;color:#888; padding:5px 5px 5px 7px; background-color:transparent; position:absolute;z-index:10;top:2px;border:0;overflow:auto;resize:none; font-size:13px;"></span>');
var $placeholder = $(this.edit.doc).find('.kindeditor-ph');
$placeholder.html(placeholderText);
$placeholder.css('pointerEvents', 'none');
$placeholder.click(function(){frame.doc.body.focus()});
if(frame.html() != '') $placeholder.hide();
},
afterFocus: function()
{
var frame = this.edit;
var $placeholder = $(frame.doc).find('.kindeditor-ph');
if($placeholder.size() == 0)
{
setTimeout(function(){$(frame.doc).find('.kindeditor-ph').hide();}, 50);
}
else
{
$placeholder.hide();
}
$editor.prev('.ke-container').addClass('focus');
},
afterBlur: function()
{
this.sync();
$editor.prev('.ke-container').removeClass('focus');
var frame = this.edit;
if(K(frame.doc.body).html() == '') $(frame.doc).find('.kindeditor-ph').show();
},
afterTab: function(id)
{
+19 -6
View File
@@ -1,20 +1,33 @@
<?php
$extViewFile = $this->app->getModuleRoot() . 'ext/view/' . basename(__FILE__);
if(file_exists($extViewFile))
{
include $extViewFile;
return;
}
?>
<?php if(!empty($action)): ?>
<?php if(!empty($action->comment)):?>
<tr>
<td style="padding:0px 10px 10px 10px; border: none;">
<fieldset style="border: 1px solid #e5e5e5">
<legend style="color: #114f8e"><?php echo $this->lang->comment?></legend>
<div style="padding:5px;"><?php echo $action->comment?></div>
</fieldset>
</td>
</tr>
<?php endif;?>
<tr>
<td style='padding: 10px; background-color: #FFF0D5'>
<?php if($extView = $this->getExtViewFile(__FILE__)){include $extView; return helper::cd();}?>
<?php if(isset($users[$action->actor])) $action->actor = $users[$action->actor];?>
<?php if(isset($users[$action->extra])) $action->extra = $users[$action->extra];?>
<span style='font-size: 16px; color: #F1A325'>●</span> &nbsp;<span><?php $this->action->printAction($action);?></span>
</td>
</tr>
<?php if(!empty($action->comment) or !empty($action->history)):?>
<?php if(!empty($action->history)):?>
<tr>
<td style='padding: 10px;'>
<div><?php echo $this->action->printChanges($action->objectType, $action->history);?></div>
<?php if(!empty($action->comment)): ?>
<p style='padding: 0; padding-left: 10px; margin: 0; margin-top: 8px; border-left: 4px solid #ddd; color: #666'><?php echo $action->comment;?></p>
<?php endif;?>
</div>
</td>
</tr>
<?php endif;?>
+1 -1
View File
@@ -16,7 +16,7 @@ if($onlybody) $_GET['onlybody'] = 'no';
<td>
<table align='center' border='0' cellpadding='0' cellspacing='0' width='600' style='border: none; border-collapse: collapse;'>
<tr>
<td style='padding: 10px 0; border: none; vertical-align: middle;'><strong style='font-size: 16px'><?php echo $app->company->name ?></strong></td>
<td style='padding: 10px 0; border: none; vertical-align: middle;'><strong style='font-size: 16px'><?php echo $this->app->company->name ?></strong></td>
</tr>
</table>
<table align='center' border='0' cellpadding='0' cellspacing='0' width='600' style='border-collapse: collapse; background-color: #fff; border: 1px solid #cfcfcf; box-shadow: 0 0px 6px rgba(0, 0, 0, 0.1); margin-bottom: 20px; font-size:13px;'>

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