diff --git a/.gitignore b/.gitignore index 8b5ad3eb44..5529453cfe 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/Makefile b/Makefile index e7f6d0ebde..9edf82cf88 100644 --- a/Makefile +++ b/Makefile @@ -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/* diff --git a/VERSION b/VERSION index 56b6be4ebb..cb90e90fa9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.1 +9.0.stable diff --git a/bin/ztcli b/bin/ztcli index d6f4fd96ad..027219cfa1 100755 --- a/bin/ztcli +++ b/bin/ztcli @@ -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 { diff --git a/config/config.php b/config/config.php index b1df1f5794..1c264e9944 100644 --- a/config/config.php +++ b/config/config.php @@ -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 = '
+ + + + admin->register->caption;?> - - admin->bind->caption, '', "class='btn btn-success'");?> - - - admin->register->bind, html::a(inlink('bind'), $lang->admin->register->click));?> - - - - - - user->account;?> - - - - admin->register->lblAccount;?> - - - - user->realname;?> - - - - user->company;?> - company, "class='form-control'");?> - - - user->phone;?> - - - - user->email;?> - email, "class='form-control'");?> - - - user->password;?> - - - - admin->register->lblPasswd;?> - - - - user->password2;?> - *';?> - - - - - admin->register->submit) . html::hidden('sn', $sn);?> - - - - + + + + admin->register->common?> + + + + user->account;?> + + + admin->register->lblAccount}' autocomplete='off'");?> + + + + user->realname;?> + + + + user->company;?> + company, "class='form-control' autocomplete='off'");?> + + + user->mobile;?> + + + + + admin->getCaptcha, '', "id='mobileSender' class='btn'")?> + + admin->captcha?> + + + + + + user->email;?> + + + + email, "class='form-control' autocomplete='off'");?> + admin->getCaptcha, '', "id='mailSender' class='btn'")?> + + admin->captcha?> + + + + + + user->password;?> + + + admin->register->lblPasswd}'");?> + + + + user->password2;?> + *';?> + + + + + admin->register->submit) . html::hidden('sn', $sn) . html::hidden('bindSite', common::getSysURL());?> + + + + + + + + + admin->register->bind?> + '> + + + user->account;?> + global, 'community', ''); + if($account == 'na') $account = ''; + ?> + + + + user->password;?> + + + + + + + + + + + diff --git a/module/admin/view/safe.html.php b/module/admin/view/safe.html.php index 392e15885c..278c709c78 100644 --- a/module/admin/view/safe.html.php +++ b/module/admin/view/safe.html.php @@ -21,18 +21,26 @@ - admin->safe->password?> - admin->safe->modeList, isset($config->safe->mode) ? $config->safe->mode : 0)?> + admin->safe->password?> + admin->safe->modeList, isset($config->safe->mode) ? $config->safe->mode : 0, "onclick=showModeRule(this.value)")?> admin->safe->noticeMode?> - + - admin->safe->noticeStrong;?> + admin->safe->modeRuleList[1] . $lang->admin->safe->noticeStrong;?> + + + + admin->safe->modeRuleList[2] . $lang->admin->safe->noticeStrong;?> admin->safe->weak?> safe->weak, "class='form-control' rows='4'")?> + + admin->safe->modifyPasswordFirstLogin?> + admin->safe->modifyPasswordList, isset($config->safe->modifyPasswordFirstLogin) ? $config->safe->modifyPasswordFirstLogin : 0)?> + @@ -40,4 +48,24 @@ + diff --git a/module/admin/view/sso.html.php b/module/admin/view/sso.html.php index f97a4ddf81..cb0d53acaa 100644 --- a/module/admin/view/sso.html.php +++ b/module/admin/view/sso.html.php @@ -26,15 +26,15 @@ sso->addr; ?> - sso->addrNotice}'");?> + sso->addrNotice}' autocomplete='off'");?> sso->code; ?> - + sso->key; ?> - + diff --git a/module/admin/view/ztcompany.html.php b/module/admin/view/ztcompany.html.php new file mode 100644 index 0000000000..ebae76dbbb --- /dev/null +++ b/module/admin/view/ztcompany.html.php @@ -0,0 +1,33 @@ + + * @package admin + * @version $Id$ + * @link http://www.zentao.net + */ +?> + + + + admin->ztCompany;?> + + + + + + company->name : $lang->user->$field;?> + + + + + + + + + + + diff --git a/module/api/view/debug.html.php b/module/api/view/debug.html.php index 3441874738..70e935c180 100644 --- a/module/api/view/debug.html.php +++ b/module/api/view/debug.html.php @@ -16,7 +16,7 @@ parameters as $param):?> name?> - name", $param->isOptional() ? $param->getDefaultValue() : '', "class='form-control'")?> + name", $param->isOptional() ? $param->getDefaultValue() : '', "class='form-control' autocomplete='off'")?> diff --git a/module/backup/lang/en.php b/module/backup/lang/en.php index c5a4f944ad..df62e32eef 100644 --- a/module/backup/lang/en.php +++ b/module/backup/lang/en.php @@ -1,6 +1,6 @@ backup->common = 'Backup'; -$lang->backup->index = 'Homepage'; +$lang->backup->index = 'Home'; $lang->backup->history = 'History'; $lang->backup->delete = 'Delete'; $lang->backup->backup = 'Backup'; diff --git a/module/backup/model.php b/module/backup/model.php index 9a9d53603f..4010d8e492 100644 --- a/module/backup/model.php +++ b/module/backup/model.php @@ -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(); diff --git a/module/backup/view/change.html.php b/module/backup/view/change.html.php index 1921373b0a..b0ba41fac5 100644 --- a/module/backup/view/change.html.php +++ b/module/backup/view/change.html.php @@ -23,7 +23,7 @@ - backup->holdDays, "class='form-control'");?> + backup->holdDays, "class='form-control' autocomplete='off'");?> day;?> diff --git a/module/block/control.php b/module/block/control.php index 1751a734f8..41c656f321 100644 --- a/module/block/control.php +++ b/module/block/control.php @@ -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'; diff --git a/module/block/css/admin.css b/module/block/css/admin.css index af8261c052..31ad83a92c 100644 --- a/module/block/css/admin.css +++ b/module/block/css/admin.css @@ -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;} diff --git a/module/block/js/admin.js b/module/block/js/admin.js index 3ff570046a..39aec0f8ec 100644 --- a/module/block/js/admin.js +++ b/module/block/js/admin.js @@ -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); diff --git a/module/block/js/dashboard.js b/module/block/js/dashboard.js index 0f9aa04f3d..5dbc235763 100644 --- a/module/block/js/dashboard.js +++ b/module/block/js/dashboard.js @@ -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 = $('').css('right', $panel.width() - $table.width()).css('min-width', $table.width()); + $header = $('').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()); diff --git a/module/block/lang/en.php b/module/block/lang/en.php index 712f6fb1b7..2b5ee2494c 100644 --- a/module/block/lang/en.php +++ b/module/block/lang/en.php @@ -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 %s %s %s."; @@ -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'); diff --git a/module/block/view/admin.html.php b/module/block/view/admin.html.php index 02c35401b9..463ebbff46 100644 --- a/module/block/view/admin.html.php +++ b/module/block/view/admin.html.php @@ -14,7 +14,7 @@ - + block->lblModule; ?> diff --git a/module/block/view/dashboard.html.php b/module/block/view/dashboard.html.php index 791654427a..50fbb4baf6 100644 --- a/module/block/view/dashboard.html.php +++ b/module/block/view/dashboard.html.php @@ -28,7 +28,7 @@ $useGuest = $this->app->user->account == 'guest'; moreLink)):?> - moreLink, $lang->more . " ", null, "class='panel-action drag-disabled panel-action-more'"); ?> + moreLink, " ", null, "class='panel-action drag-disabled panel-action-more'"); ?> diff --git a/module/block/view/productblock.html.php b/module/block/view/productblock.html.php index 5830f51f20..d96fbe3718 100644 --- a/module/block/view/productblock.html.php +++ b/module/block/view/productblock.html.php @@ -10,7 +10,7 @@ * @link http://www.zentao.net */ ?> - + product->name;?> diff --git a/module/block/view/publicform.html.php b/module/block/view/publicform.html.php index 659ba75bfb..1750271339 100644 --- a/module/block/view/publicform.html.php +++ b/module/block/view/publicform.html.php @@ -12,7 +12,7 @@ ?> block->name?> - title : '', "class='form-control'")?> + title : '', "class='form-control' autocomplete='off'")?> block->style;?> diff --git a/module/branch/control.php b/module/branch/control.php index fa7271c64b..8c712ad72c 100644 --- a/module/branch/control.php +++ b/module/branch/control.php @@ -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"))); } diff --git a/module/branch/css/manage.css b/module/branch/css/manage.css index 8578a15cfe..9add6b0a8a 100644 --- a/module/branch/css/manage.css +++ b/module/branch/css/manage.css @@ -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;} diff --git a/module/branch/js/manage.js b/module/branch/js/manage.js index 215d1a0549..7b371ff1ef 100644 --- a/module/branch/js/manage.js +++ b/module/branch/js/manage.js @@ -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}); + } + }); +}); diff --git a/module/branch/lang/en.php b/module/branch/lang/en.php index 37a22f923c..2d6f428b19 100644 --- a/module/branch/lang/en.php +++ b/module/branch/lang/en.php @@ -1,9 +1,11 @@ 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.'; diff --git a/module/branch/lang/zh-cn.php b/module/branch/lang/zh-cn.php index ac2e1d901f..3d327f9d12 100644 --- a/module/branch/lang/zh-cn.php +++ b/module/branch/lang/zh-cn.php @@ -1,9 +1,11 @@ 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@下已经有数据,不能删除!'; diff --git a/module/branch/lang/zh-tw.php b/module/branch/lang/zh-tw.php index dc1c545ee8..df6d1a0844 100644 --- a/module/branch/lang/zh-tw.php +++ b/module/branch/lang/zh-tw.php @@ -1,9 +1,11 @@ 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@下已經有數據,不能刪除!'; diff --git a/module/branch/model.php b/module/branch/model.php index 900d8404c7..111fa63718 100644 --- a/module/branch/model.php +++ b/module/branch/model.php @@ -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); + } } diff --git a/module/branch/view/manage.html.php b/module/branch/view/manage.html.php index de7afd9834..3b69f29938 100644 --- a/module/branch/view/manage.html.php +++ b/module/branch/view/manage.html.php @@ -22,12 +22,22 @@ $branch):?> - + + + + + + + ", 'hiddenwin')?> + + + + - + diff --git a/module/bug/config.php b/module/bug/config.php index 685f2e2e68..16974deeba 100644 --- a/module/bug/config.php +++ b/module/bug/config.php @@ -1,6 +1,7 @@ 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'); diff --git a/module/bug/control.php b/module/bug/control.php index 5ba5198478..a7e319b2bc 100644 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -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¶m={$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') . ''; } } diff --git a/module/bug/css/browse.css b/module/bug/css/browse.css index 8a01602e3b..4b05fd42c7 100644 --- a/module/bug/css/browse.css +++ b/module/bug/css/browse.css @@ -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;} diff --git a/module/bug/css/create.css b/module/bug/css/create.css index fac20ffe6a..5ea4470f14 100644 --- a/module/bug/css/create.css +++ b/module/bug/css/create.css @@ -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;} diff --git a/module/bug/css/report.css b/module/bug/css/report.css index 5f1588dcd3..b4d3ca6834 100644 --- a/module/bug/css/report.css +++ b/module/bug/css/report.css @@ -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;} diff --git a/module/bug/js/batchcreate.js b/module/bug/js/batchcreate.js index 96f0618678..28d0230bbd 100644 --- a/module/bug/js/batchcreate.js +++ b/module/bug/js/batchcreate.js @@ -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 = ''; + $('#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 = ''; + $('#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'); diff --git a/module/bug/js/browse.js b/module/bug/js/browse.js index 550b231de9..b939022371 100644 --- a/module/bug/js/browse.js +++ b/module/bug/js/browse.js @@ -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() { diff --git a/module/bug/js/create.js b/module/bug/js/create.js index 10ab55b57e..e7ec1fe87d 100644 --- a/module/bug/js/create.js +++ b/module/bug/js/create.js @@ -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(); + }); }); diff --git a/module/bug/lang/en.php b/module/bug/lang/en.php index df759a9c58..46a5913791 100644 --- a/module/bug/lang/en.php +++ b/module/bug/lang/en.php @@ -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 $actor and the solution is $extra $appendLink.', 'extra' => 'resolutionList'); -$lang->bug->action->tostory = array('main' => '$date, transferred by $actor to Story with ID $extra.'); -$lang->bug->action->totask = array('main' => '$date, imported by $actor as Task with ID $extra.'); -$lang->bug->action->linked2plan = array('main' => '$date, linked by $actor to Planning $extra.'); -$lang->bug->action->unlinkedfromplan = array('main' => '$date, deleted by $actor from Planning $extra.'); -$lang->bug->action->linkrelatedbug = array('main' => '$date, related by $actor to Bug $extra.'); -$lang->bug->action->unlinkrelatedbug = array('main' => '$date, removed by $actor from Bug $extra.'); +$lang->bug->action->resolved = array('main' => '$date, resolved by $actor and the solution is $extra $appendLink.', 'extra' => 'resolutionList'); +$lang->bug->action->tostory = array('main' => '$date, transferred by $actor to Story with ID $extra.'); +$lang->bug->action->totask = array('main' => '$date, imported by $actor as Task with ID $extra.'); +$lang->bug->action->linked2plan = array('main' => '$date, related by $actor to Plan $extra.'); +$lang->bug->action->unlinkedfromplan = array('main' => '$date, deleted by $actor from Plan $extra.'); +$lang->bug->action->linked2build = array('main' => '$date, related by $actor to Build $extra.'); +$lang->bug->action->unlinkedfrombuild = array('main' => '$date, removed by $actor from Build $extra.'); +$lang->bug->action->linked2release = array('main' => '$date, related by $actor to Release $extra.'); +$lang->bug->action->unlinkedfromrelease = array('main' => '$date, removed by $actor from Release $extra.'); +$lang->bug->action->linkrelatedbug = array('main' => '$date, related by $actor to Bug $extra.'); +$lang->bug->action->unlinkrelatedbug = array('main' => '$date, removed by $actor from Bug $extra.'); $lang->bug->placeholder = new stdclass(); $lang->bug->placeholder->chooseBuilds = 'Choose Build...'; diff --git a/module/bug/lang/zh-cn.php b/module/bug/lang/zh-cn.php index 7497c90135..ca736a251a 100644 --- a/module/bug/lang/zh-cn.php +++ b/module/bug/lang/zh-cn.php @@ -331,13 +331,17 @@ $lang->bug->report->bugHistories->graph->xAxisName = '处理步骤'; /* 操作记录。*/ $lang->bug->action = new stdclass(); -$lang->bug->action->resolved = array('main' => '$date, 由 $actor 解决,方案为 $extra $appendLink。', 'extra' => 'resolutionList'); -$lang->bug->action->tostory = array('main' => '$date, 由 $actor 转为需求,编号为 $extra。'); -$lang->bug->action->totask = array('main' => '$date, 由 $actor 导入为任务,编号为 $extra。'); -$lang->bug->action->linked2plan = array('main' => '$date, 由 $actor 关联到计划 $extra。'); -$lang->bug->action->unlinkedfromplan = array('main' => '$date, 由 $actor 从计划 $extra 移除。'); -$lang->bug->action->linkrelatedbug = array('main' => '$date, 由 $actor 关联相关Bug $extra。'); -$lang->bug->action->unlinkrelatedbug = array('main' => '$date, 由 $actor 移除相关Bug $extra。'); +$lang->bug->action->resolved = array('main' => '$date, 由 $actor 解决,方案为 $extra $appendLink。', 'extra' => 'resolutionList'); +$lang->bug->action->tostory = array('main' => '$date, 由 $actor 转为需求,编号为 $extra。'); +$lang->bug->action->totask = array('main' => '$date, 由 $actor 导入为任务,编号为 $extra。'); +$lang->bug->action->linked2plan = array('main' => '$date, 由 $actor 关联到计划 $extra。'); +$lang->bug->action->unlinkedfromplan = array('main' => '$date, 由 $actor 从计划 $extra 移除。'); +$lang->bug->action->linked2build = array('main' => '$date, 由 $actor 关联到版本 $extra。'); +$lang->bug->action->unlinkedfrombuild = array('main' => '$date, 由 $actor 从版本 $extra 移除。'); +$lang->bug->action->linked2release = array('main' => '$date, 由 $actor 关联到发布 $extra。'); +$lang->bug->action->unlinkedfromrelease = array('main' => '$date, 由 $actor 从发布 $extra 移除。'); +$lang->bug->action->linkrelatedbug = array('main' => '$date, 由 $actor 关联相关Bug $extra。'); +$lang->bug->action->unlinkrelatedbug = array('main' => '$date, 由 $actor 移除相关Bug $extra。'); $lang->bug->placeholder = new stdclass(); $lang->bug->placeholder->chooseBuilds = '选择相关版本...'; diff --git a/module/bug/lang/zh-tw.php b/module/bug/lang/zh-tw.php index 5a925d6bcc..f2a65f27c0 100644 --- a/module/bug/lang/zh-tw.php +++ b/module/bug/lang/zh-tw.php @@ -331,13 +331,17 @@ $lang->bug->report->bugHistories->graph->xAxisName = '處理步驟'; /* 操作記錄。*/ $lang->bug->action = new stdclass(); -$lang->bug->action->resolved = array('main' => '$date, 由 $actor 解決,方案為 $extra $appendLink。', 'extra' => 'resolutionList'); -$lang->bug->action->tostory = array('main' => '$date, 由 $actor 轉為需求,編號為 $extra。'); -$lang->bug->action->totask = array('main' => '$date, 由 $actor 導入為任務,編號為 $extra。'); -$lang->bug->action->linked2plan = array('main' => '$date, 由 $actor 關聯到計劃 $extra。'); -$lang->bug->action->unlinkedfromplan = array('main' => '$date, 由 $actor 從計劃 $extra 移除。'); -$lang->bug->action->linkrelatedbug = array('main' => '$date, 由 $actor 關聯相關Bug $extra。'); -$lang->bug->action->unlinkrelatedbug = array('main' => '$date, 由 $actor 移除相關Bug $extra。'); +$lang->bug->action->resolved = array('main' => '$date, 由 $actor 解決,方案為 $extra $appendLink。', 'extra' => 'resolutionList'); +$lang->bug->action->tostory = array('main' => '$date, 由 $actor 轉為需求,編號為 $extra。'); +$lang->bug->action->totask = array('main' => '$date, 由 $actor 導入為任務,編號為 $extra。'); +$lang->bug->action->linked2plan = array('main' => '$date, 由 $actor 關聯到計劃 $extra。'); +$lang->bug->action->unlinkedfromplan = array('main' => '$date, 由 $actor 從計劃 $extra 移除。'); +$lang->bug->action->linked2build = array('main' => '$date, 由 $actor 關聯到版本 $extra。'); +$lang->bug->action->unlinkedfrombuild = array('main' => '$date, 由 $actor 從版本 $extra 移除。'); +$lang->bug->action->linked2release = array('main' => '$date, 由 $actor 關聯到發佈 $extra。'); +$lang->bug->action->unlinkedfromrelease = array('main' => '$date, 由 $actor 從發佈 $extra 移除。'); +$lang->bug->action->linkrelatedbug = array('main' => '$date, 由 $actor 關聯相關Bug $extra。'); +$lang->bug->action->unlinkrelatedbug = array('main' => '$date, 由 $actor 移除相關Bug $extra。'); $lang->bug->placeholder = new stdclass(); $lang->bug->placeholder->chooseBuilds = '選擇相關版本...'; diff --git a/module/bug/model.php b/module/bug/model.php index 3982769215..c4cbf078d0 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -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) . ''; + foreach(explode(',', $bug->openedBuild) as $build) echo zget($builds, $build) . ''; 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 ''; } } + + /** + * 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())); + } } diff --git a/module/bug/view/batchcreate.html.php b/module/bug/view/batchcreate.html.php index e3083c0e16..afa9bc89c8 100644 --- a/module/bug/view/batchcreate.html.php +++ b/module/bug/view/batchcreate.html.php @@ -38,6 +38,7 @@ foreach(explode(',', $showFields) as $field) idAB;?> + '> product->branch;?> '> bug->module;?> '>bug->project;?> bug->openedBuild;?> @@ -78,13 +79,14 @@ foreach(explode(',', $showFields) as $field) ?> + '> ' style='overflow:visible'> ' style='overflow:visible'> bug->colorTag}' data-update-text='#title\\[{$i}\\]'");?> - + '> @@ -93,7 +95,7 @@ foreach(explode(',', $showFields) as $field) '>bug->severityList, '', "class='form-control'");?> '> bug->osList, $os, "class='form-control'");?> '> bug->browserList, $browser, "class='form-control'");?> - '> + '> @@ -110,13 +112,14 @@ foreach(explode(',', $showFields) as $field) ?> + '> ' style='overflow:visible'> ' style='overflow:visible'> bug->colorTag}' data-update-text='#title\\[{$i}\\]'");?> - + '> @@ -125,7 +128,7 @@ foreach(explode(',', $showFields) as $field) '>bug->severityList, '', "class='form-control'");?> '> bug->osList, $os, "class='form-control'");?> '> bug->browserList, $browser, "class='form-control'");?> - '> + '> @@ -138,13 +141,14 @@ foreach(explode(',', $showFields) as $field) %s + '> ' style='overflow:visible'> ' style='overflow:visible'> bug->colorTag}' data-update-text='#title\\[%s\\]'");?> - + '> @@ -153,7 +157,7 @@ foreach(explode(',', $showFields) as $field) '>bug->severityList, '', "class='form-control'");?> '> bug->osList, '', "class='form-control'");?> '> bug->browserList, '', "class='form-control'");?> - '> + '> diff --git a/module/bug/view/browse.html.php b/module/bug/view/browse.html.php index 5af222fd7c..4b773a9d01 100644 --- a/module/bug/view/browse.html.php +++ b/module/bug/view/browse.html.php @@ -58,28 +58,29 @@ js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrows - + - - - bug->common;?> - - - + createLink('tutorial', 'wizard', "module=bug&method=create¶ms=$wizardParams"), $lang->bug->create); + echo html::a($this->createLink('tutorial', 'wizard', "module=bug&method=create¶ms=$wizardParams"), "" . $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 "" . html::a($link, $lang->bug->create, '', $misc) . ""; + echo html::a($link, "" . $lang->bug->create, '', $misc); } + ?> + + + + + createLink('bug', 'batchCreate', "productID=$productID&branch=$branch&projectID=0&moduleID=$moduleID") : '#'; echo "" . html::a($link, $lang->bug->batchCreate, '', $misc) . ""; @@ -107,6 +108,7 @@ js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrows + moduleName . ucfirst($this->methodName); @@ -148,14 +150,16 @@ js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrows $withSearch = count($modules) > 8; echo ""; echo html::a('javascript:;', $lang->bug->moduleAB, '', "id='moduleItem'"); - echo ""; + echo ""; + echo ''; foreach($modules as $moduleId => $module) { $actionLink = $this->createLink('bug', 'batchChangeModule', "moduleID=$moduleId"); echo "" . html::a('#', $module, '', "onclick=\"setFormAction('$actionLink','hiddenwin')\"") . ""; } - if($withSearch) echo ""; - echo ''; + echo ""; + if($withSearch) echo ""; + echo ''; } else { @@ -178,7 +182,8 @@ js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrows $withSearch = count($builds) > 4; echo ""; echo html::a('javascript:;', $resolution, '', "id='fixedItem'"); - echo ""; + echo ""; + echo ''; 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 ""; } - if($withSearch) echo ""; - echo ''; + echo ""; + if($withSearch) echo ""; + echo ''; } else { @@ -210,15 +216,16 @@ js::set('bugBrowseType', ($browseType == 'bymodule' and $this->session->bugBrows echo html::select('assignedTo', $memberPairs, '', 'class="hidden"'); echo ""; echo html::a('javascript::', $lang->bug->assignedTo, 'id="assignItem"'); - echo ""; + echo ""; + echo ''; foreach ($memberPairs as $key => $value) { if(empty($key)) continue; echo "" . html::a("javascript:$(\".table-actions #assignedTo\").val(\"$key\");setFormAction(\"$actionLink\")", $value, '', '') . ''; } - if($withSearch) echo ""; echo ""; - echo ""; + if($withSearch) echo ""; + echo ""; } else { @@ -250,7 +257,7 @@ if($shortcut.size() > 0) app->loadConfig('qa', '', false);?> config->qa->homepage) and $this->config->qa->homepage != 'browse'):?> -$(function(){$('#modulemenu .nav li:last').after("homepage?>")}); +$(function(){$('#modulemenu .nav li:last').after(" homepage?>")}); diff --git a/module/bug/view/browsedata.html.php b/module/bug/view/browsedata.html.php index 909ce37559..e41d249dde 100644 --- a/module/bug/view/browsedata.html.php +++ b/module/bug/view/browsedata.html.php @@ -10,7 +10,7 @@ * @link http://www.zentao.net */ ?> - + idAB);?> @@ -46,7 +46,7 @@ id");?> - + id));?> @@ -89,7 +89,7 @@ assignedTo == $this->app->user->account) echo 'class="red"';?>>assignedTo, $bug->assignedTo);?> resolvedBy, $bug->resolvedBy)?> - bug->resolutionList[$bug->resolution];?> + bug->resolutionList, $bug->resolution);?> cookie->windowWidth >= $this->config->wideSize):?> resolvedDate, 5, 11)?> diff --git a/module/bug/view/confirmbug.html.php b/module/bug/view/confirmbug.html.php index 7689689b2f..905221cd1f 100755 --- a/module/bug/view/confirmbug.html.php +++ b/module/bug/view/confirmbug.html.php @@ -31,6 +31,10 @@ js::set('page', 'confirmbug'); assignedTo, "class='select-2 chosen'");?> + + bug->type;?> + bug->typeList, $bug->type, 'class=form-control');?> + bug->pri;?> bug->priList, $bug->pri, 'class=form-control');?> diff --git a/module/bug/view/create.html.php b/module/bug/view/create.html.php index 6253d8de3b..936c0118ff 100644 --- a/module/bug/view/create.html.php +++ b/module/bug/view/create.html.php @@ -1,4 +1,4 @@ -refresh); bug->openedBuild?> - - ', "class='btn btn-default' data-toggle='tooltip' onclick='loadAllBuilds()' title='{$lang->bug->allBuilds}'")?> + + bug->allBuilds, "class='btn btn-default' data-toggle='tooltip' onclick='loadAllBuilds()'")?> @@ -80,7 +80,7 @@ js::set('refresh', $lang->refresh); - ', "class='btn btn-default' onclick='loadAllUsers()' data-toggle='tooltip' title='{$lang->bug->allUsers}'");?> + bug->allUsers, "class='btn btn-default' onclick='loadAllUsers()' data-toggle='tooltip'");?> @@ -89,7 +89,7 @@ js::set('refresh', $lang->refresh); bug->type;?> - + bug->typeList['designchange']); diff --git a/module/bug/view/linkbugs.html.php b/module/bug/view/linkbugs.html.php index 88fac43337..caa7b26cdb 100644 --- a/module/bug/view/linkbugs.html.php +++ b/module/bug/view/linkbugs.html.php @@ -21,7 +21,7 @@ - + @@ -39,7 +39,7 @@ createLink('bug', 'view', "bugID=$bug2Link->id");?> - + id));?> diff --git a/module/bug/view/report.html.php b/module/bug/view/report.html.php index 1d7973e355..2b3242d339 100644 --- a/module/bug/view/report.html.php +++ b/module/bug/view/report.html.php @@ -39,7 +39,10 @@ - bug->report->common;?> + + bug->report->common;?> + report->notice->help?> + $chartOption):?> @@ -76,7 +79,6 @@ - report->notice->help?> diff --git a/module/bug/view/sendmail.html.php b/module/bug/view/sendmail.html.php index 2d79351921..bd70d8ee20 100644 --- a/module/bug/view/sendmail.html.php +++ b/module/bug/view/sendmail.html.php @@ -11,12 +11,12 @@ */ ?> id . ' ' . $bug->title;?> - +app->getModuleRoot() . 'common/view/mail.header.html.php';?> - createLink('bug', 'view', "bugID=$bug->id"), $mailTitle, '', "style='color: #333'");?> + config->mail, 'domain', common::getSysURL()) . helper::createLink('bug', 'view', "bugID=$bug->id"), $mailTitle, '', "style='color: #333; text-decoration: underline;'");?> @@ -24,9 +24,9 @@ - bug->legendSteps;?> + lang->bug->legendSteps;?> steps;?> - +app->getModuleRoot() . 'common/view/mail.footer.html.php';?> diff --git a/module/build/control.php b/module/build/control.php index 8d317090bb..d12bd46d4a 100644 --- a/module/build/control.php +++ b/module/build/control.php @@ -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 { diff --git a/module/build/css/view.css b/module/build/css/view.css index 5b8cf025f8..82742a2161 100644 --- a/module/build/css/view.css +++ b/module/build/css/view.css @@ -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;} diff --git a/module/build/lang/en.php b/module/build/lang/en.php index 9cb8582bec..367e263fca 100644 --- a/module/build/lang/en.php +++ b/module/build/lang/en.php @@ -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 = " This {$lang->projectCommon} has not linked to {$lang->productCommon}, so Build cannot be created. Please first link {$lang->productCommon}"; +$lang->build->generatedBugs = 'Remained Bug'; +$lang->build->noProduct = " This {$lang->projectCommon} has not relateed to {$lang->productCommon}, so Build cannot be created. Please first relate {$lang->productCommon}"; $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 $actor, Build $extra.' . "\n"; diff --git a/module/build/model.php b/module/build/model.php index 9d8502b6a4..582605d273 100644 --- a/module/build/model.php +++ b/module/build/model.php @@ -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); + } } } diff --git a/module/build/view/create.html.php b/module/build/view/create.html.php index 79ea9eea1b..29f05774c8 100644 --- a/module/build/view/create.html.php +++ b/module/build/view/create.html.php @@ -45,7 +45,7 @@ build->name;?> - + @@ -63,11 +63,11 @@ build->scmPath;?> - build->placeholder->scmPath}'");?> + build->placeholder->scmPath}' autocomplete='off'");?> build->filePath;?> - build->placeholder->filePath}'");?> + build->placeholder->filePath}' autocomplete='off'");?> build->files;?> diff --git a/module/build/view/edit.html.php b/module/build/view/edit.html.php index e2fa6e70dd..08fdecae59 100644 --- a/module/build/view/edit.html.php +++ b/module/build/view/edit.html.php @@ -40,7 +40,7 @@ build->name;?> - name, "class='form-control'");?> + name, "class='form-control' autocomplete='off'");?> build->builder;?> @@ -52,11 +52,11 @@ build->scmPath;?> - scmPath, "class='form-control' placeholder='{$lang->build->placeholder->scmPath}'");?> + scmPath, "class='form-control' placeholder='{$lang->build->placeholder->scmPath}' autocomplete='off'");?> build->filePath;?> - filePath, "class='form-control' placeholder='{$lang->build->placeholder->filePath}'");?> + filePath, "class='form-control' placeholder='{$lang->build->placeholder->filePath}' autocomplete='off'");?> build->files;?> diff --git a/module/build/view/linkbug.html.php b/module/build/view/linkbug.html.php index b52fad3445..8f6c4ed780 100644 --- a/module/build/view/linkbug.html.php +++ b/module/build/view/linkbug.html.php @@ -13,7 +13,7 @@ id}&browseType=$browseType¶m=$param");?>'> - + productplan->unlinkedBugs;?> @@ -29,8 +29,8 @@ bugs},", ",$bug->id,") !== false) continue;?> - - status == 'resolved' or $bug->status == 'closed') echo "checked";?> /> + + status == 'resolved' or $bug->status == 'closed') echo "checked";?> /> createLink('bug', 'view', "bugID=$bug->id"), $bug->id);?> bug->priList, $bug->pri, $bug->pri);?>'>bug->priList, $bug->pri, $bug->pri)?> diff --git a/module/build/view/linkstory.html.php b/module/build/view/linkstory.html.php index 07bcc2dd52..185c22f385 100644 --- a/module/build/view/linkstory.html.php +++ b/module/build/view/linkstory.html.php @@ -13,7 +13,7 @@ id}&browseType=$browseType¶m=$param");?>'> - + productplan->unlinkedStories;?> @@ -31,8 +31,8 @@ stories},", ",{$story->id},") !== false) continue; ?> - - stage == 'developed' or $story->status == 'closed') echo 'checked';?> /> + + stage == 'developed' or $story->status == 'closed') echo 'checked';?> /> createLink('story', 'view', "storyID=$story->id"), $story->id);?> story->priList, $story->pri, $story->pri);?>'>story->priList, $story->pri, $story->pri)?> diff --git a/module/build/view/view.html.php b/module/build/view/view.html.php index cb48826a6c..40aa7f315a 100644 --- a/module/build/view/view.html.php +++ b/module/build/view/view.html.php @@ -56,7 +56,7 @@ id}")?>' id='linkedStoriesForm'> - + idAB;?> @@ -73,9 +73,9 @@ $story):?> createLink('story', 'view', "storyID=$story->id", '', true);?> - + - + id);?> @@ -115,7 +115,7 @@ id");?>" id='linkedBugsForm'> - + idAB;?> @@ -132,9 +132,9 @@ createLink('bug', 'view', "bugID=$bug->id", '', true);?> - + - + id);?> title, '', "class='preview'");?> diff --git a/module/common/lang/en.php b/module/common/lang/en.php index f7612815d5..9fb9080949 100644 --- a/module/common/lang/en.php +++ b/module/common/lang/en.php @@ -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 = "Time %s MS, Memory %s KB, Query %s. "; @@ -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 = ' My Zone|my|index'; +$lang->menu->my = 'Dashboard|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' => ' %s' . $lang->arrow . '', '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' => " 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 = "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'; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index 7bfbf3d6aa..84e3673d7c 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -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'; diff --git a/module/common/lang/zh-tw.php b/module/common/lang/zh-tw.php index f0fef18183..7d7a78f11d 100644 --- a/module/common/lang/zh-tw.php +++ b/module/common/lang/zh-tw.php @@ -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'; diff --git a/module/common/model.php b/module/common/model.php index 7e115d43cf..b5b21ed7a6 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -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:;', "", '', "class='qrCode $color' id='qrcodeBtn' title='{$lang->user->mobileLogin}'"); - echo "{$lang->user->mobileLogin}"; + echo "{$lang->user->mobileLogin}"; echo ''; echo ''; } @@ -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 ""; - echo ""; - printf($this->lang->upgrade->setStatusFile, $statusFile, $statusFile, $statusFile); + echo ""; + printf($this->lang->upgrade->setStatusFile, $cmd, $statusFile); die(''); } } @@ -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(); diff --git a/module/common/view/action.html.php b/module/common/view/action.html.php index 78c01d3be9..36a1dc282d 100755 --- a/module/common/view/action.html.php +++ b/module/common/view/action.html.php @@ -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) diff --git a/module/common/view/chart.html.php b/module/common/view/chart.html.php index f5c5d1cd10..559362fe0d 100644 --- a/module/common/view/chart.html.php +++ b/module/common/view/chart.html.php @@ -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 = $('').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(); }); }()); diff --git a/module/common/view/datatable.html.php b/module/common/view/datatable.html.php index baeae690b2..80437955ef 100644 --- a/module/common/view/datatable.html.php +++ b/module/common/view/datatable.html.php @@ -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("datatable->switchToTable?>"); $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); }); } }); diff --git a/module/common/view/footer.html.php b/module/common/view/footer.html.php index ac9a678f9b..fe5cde58b7 100755 --- a/module/common/view/footer.html.php +++ b/module/common/view/footer.html.php @@ -8,14 +8,13 @@
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'; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index 7bfbf3d6aa..84e3673d7c 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -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'; diff --git a/module/common/lang/zh-tw.php b/module/common/lang/zh-tw.php index f0fef18183..7d7a78f11d 100644 --- a/module/common/lang/zh-tw.php +++ b/module/common/lang/zh-tw.php @@ -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'; diff --git a/module/common/model.php b/module/common/model.php index 7e115d43cf..b5b21ed7a6 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -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:;', "", '', "class='qrCode $color' id='qrcodeBtn' title='{$lang->user->mobileLogin}'"); - echo "