diff --git a/framework/helper.class.php b/framework/helper.class.php index 53bc042d1c..1ef5f1ac61 100644 --- a/framework/helper.class.php +++ b/framework/helper.class.php @@ -96,7 +96,8 @@ class helper extends baseHelper if($position !== false) $toEncoding = substr($toEncoding, 0, $position); /* Check string encoding. */ - $encoding = strtolower(mb_detect_encoding($string, mb_list_encodings())); + $encodings = array_merge(array('GB2312','GBK','BIG5'), mb_list_encodings()); + $encoding = strtolower(mb_detect_encoding($string, $encodings)); if($encoding == $toEncoding) return $string; return mb_convert_encoding($string, $toEncoding, $encoding); } diff --git a/module/block/control.php b/module/block/control.php index ffb3c3522d..a16ca26ac6 100644 --- a/module/block/control.php +++ b/module/block/control.php @@ -713,8 +713,20 @@ class block extends control $pager = pager::init(0, $num , 1); $productStats = $this->loadModel('product')->getStats('order_desc', $this->viewType != 'json' ? $pager : '', $type); + $projects = $this->loadModel('project')->getPairs(); $productIdList = array(); - foreach($productStats as $product) $productIdList[] = $product->id; + $this->loadModel('action'); + foreach($productStats as $product) + { + $currentProjectID = $this->dao->select('objectID')->from(TABLE_ACTION) + ->where('objectType')->eq('project') + ->andWhere('action')->eq('managed') + ->andWhere("CONCAT(extra, ',,')")->like("%$product->id,,") + ->orderBy('id_desc') + ->fetch('objectID'); + $product->currentProject = zget($projects, $currentProjectID, ''); + $productIdList[] = $product->id; + } $this->view->projects = $this->dao->select('t1.product,t2.name')->from(TABLE_PROJECTPRODUCT)->alias('t1') ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id') diff --git a/module/block/view/productblock.html.php b/module/block/view/productblock.html.php index 7f2b3cab12..d6d00ede50 100644 --- a/module/block/view/productblock.html.php +++ b/module/block/view/productblock.html.php @@ -39,8 +39,8 @@ > name?> - id, '');?> - id, '');?> + currentProject ? $product->currentProject : zget($projects, $product->id, '');?> + plans?> releases?> diff --git a/module/bug/css/create.css b/module/bug/css/create.css index f006a70179..2aa61ebd72 100644 --- a/module/bug/css/create.css +++ b/module/bug/css/create.css @@ -41,4 +41,6 @@ html[lang='en'] #deadlineTd .input-group-addon{padding: 5px 18px} #mainContent .center-block{padding-bottom:40px;} #typeBox {width:180px;} +#typeBox .required:after {right: 1px;} +#osBox .required:after {right: 1px;} #osBox {width:190px;} diff --git a/module/common/model.php b/module/common/model.php index 3ecdd29e41..a87dd8e0a4 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -1716,6 +1716,8 @@ EOD; $user->admin = strpos($this->app->company->admins, ",{$user->account},") !== false; $this->session->set('user', $user); $this->app->user = $user; + $this->loadModel('action')->create('user', $user->id, 'login'); + $this->loadModel('score')->create('user', 'login'); if($isFreepasswd) die(js::locate($this->config->webRoot)); diff --git a/module/common/view/action.html.php b/module/common/view/action.html.php index 3041029907..f60e12998c 100755 --- a/module/common/view/action.html.php +++ b/module/common/view/action.html.php @@ -64,9 +64,10 @@ comment)):?> ', "title='{$lang->action->editComment}'", 'btn btn-link btn-icon btn-sm btn-edit-comment');?> +
- comment) == $action->comment ? nl2br($action->comment) : $action->comment;?> +
comment) == $action->comment ? nl2br($action->comment) : $action->comment;?>
id")?>'> diff --git a/module/dev/model.php b/module/dev/model.php index f86506eb45..7f93038002 100644 --- a/module/dev/model.php +++ b/module/dev/model.php @@ -41,7 +41,7 @@ class devModel extends model { if(isset($this->config->dev->tableMap[$module])) $aliasModule = $this->config->dev->tableMap[$module]; if(strpos($aliasModule, '-') !== false) list($aliasModule, $subLang) = explode('-', $aliasModule); - $this->app->loadLang($aliasModule ? $aliasModule : $module); + if(strpos($module, 'im_') === false) $this->app->loadLang($aliasModule ? $aliasModule : $module); } catch(PDOException $e) { diff --git a/module/doc/model.php b/module/doc/model.php index 1a250d74f9..5c226aedf9 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -566,7 +566,7 @@ class docModel extends model $doc->content = isset($docContent->content) ? $docContent->content : ''; $doc->contentType = isset($docContent->type) ? $docContent->type : ''; - $doc = $this->loadModel('file')->replaceImgURL($doc, 'content'); + if($doc->type != 'url') $doc = $this->loadModel('file')->replaceImgURL($doc, 'content'); if($setImgSize) $doc->content = $this->file->setImgSize($doc->content); $doc->files = $docFiles; diff --git a/module/product/css/roadmap.css b/module/product/css/roadmap.css index fbea14a1a2..c2c833d057 100644 --- a/module/product/css/roadmap.css +++ b/module/product/css/roadmap.css @@ -7,3 +7,4 @@ .release-line > li > a:before {border-color: #00da88;} .release-line > li:nth-child(even) > a {padding-bottom: 38px;} .release-link-line {pointer-events: none; background-image: url(data:image/png;base64,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); height: 196px; position: absolute; left: 10px; right: 100px; top: 97px; background-size: 100% 100%; background-repeat: no-repeat;} +.release-line li .title{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap} diff --git a/module/product/view/roadmap.html.php b/module/product/view/roadmap.html.php index e1f6e4be90..e3e5892c6d 100644 --- a/module/product/view/roadmap.html.php +++ b/module/product/view/roadmap.html.php @@ -66,7 +66,8 @@
- build) ? $roadmap->name : $roadmap->title;?> + build) ? $roadmap->name : $roadmap->title;?> + build) ? $roadmap->date : ($roadmap->end == '2030-01-01' ? $lang->productplan->future : $roadmap->begin . '~' . $roadmap->end);?>
diff --git a/module/project/model.php b/module/project/model.php index 828660c9ee..0bb60729cb 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -1566,6 +1566,8 @@ class projectModel extends model $lastOrder = reset($linkedStories); foreach($stories as $key => $storyID) { + $status = $this->dao->findById($storyID)->from(TABLE_STORY)->fetch('status'); + if($status == 'draft') continue; if(isset($linkedStories[$storyID])) continue; $productID = (int)$products[$storyID]; diff --git a/module/task/lang/en.php b/module/task/lang/en.php index 6d175a2b54..8124efd61b 100644 --- a/module/task/lang/en.php +++ b/module/task/lang/en.php @@ -207,6 +207,7 @@ $lang->task->error->skipClose = 'Task: %s is not "Finished” or “Cance $lang->task->error->consumed = 'Task: %s hour must be < 0. Ignore changes to this task.'; $lang->task->error->assignedTo = 'Multi-user task in the current status cannot be assigned to a member who is not in the task team.'; $lang->task->error->consumedEmpty = '"Current Cost" should not be empty.'; +$lang->task->error->deadlineSmall = '"Deadline" must be greater than "StartDate".'; /* Report. */ $lang->task->report = new stdclass(); diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php index 5b9fd3ca27..f0e26822d3 100644 --- a/module/task/lang/zh-cn.php +++ b/module/task/lang/zh-cn.php @@ -207,6 +207,7 @@ $lang->task->error->skipClose = '任务:%s 不是“已完成”或“ $lang->task->error->consumed = '任务:%s工时不能小于0,忽略该任务工时的改动'; $lang->task->error->assignedTo = '当前状态的多人任务不能指派给任务团队外的成员。'; $lang->task->error->consumedEmpty = '"本次消耗"不能为空'; +$lang->task->error->deadlineSmall = '"截止日期"必须大于"预计开始"'; /* Report. */ $lang->task->report = new stdclass(); diff --git a/module/task/model.php b/module/task/model.php index 565eedc1f5..1ae5daec92 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -272,6 +272,12 @@ class taskModel extends model /* check data. */ foreach($data as $i => $task) { + + if($task->deadline != '0000-00-00' and $task->deadline <= $task->estStarted) + { + dao::$errors['message'][] = $this->lang->task->error->deadlineSmall; + return false; + } if($task->estimate and !preg_match("/^[0-9]+(.[0-9]{1,3})?$/", $task->estimate)) { dao::$errors['message'][] = $this->lang->task->error->estimateNumber; @@ -413,6 +419,7 @@ class taskModel extends model if($parentID <= 0) return true; $oldParentTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($parentID)->fetch(); + if($oldParentTask->parent != '-1') $this->dao->update(TABLE_TASK)->set('parent')->eq('-1')->where('id')->eq($parentID)->exec(); $this->computeWorkingHours($parentID); $childrenStatus = $this->dao->select('id,status')->from(TABLE_TASK)->where('parent')->eq($parentID)->andWhere('deleted')->eq(0)->fetchPairs('status', 'status'); @@ -2760,7 +2767,7 @@ class taskModel extends model case 'actions': if($storyChanged) { - common::printIcon('task', 'confirmStoryChange', "taskid=$task->id", '', 'list', '', 'hiddenwin', 'btn-wide'); + common::printIcon('task', 'confirmStoryChange', "taskid=$task->id", '', 'list', '', 'hiddenwin'); break; } diff --git a/module/testcase/control.php b/module/testcase/control.php index 1a2cc6b21f..1fe27641a1 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -1681,8 +1681,9 @@ class testcase extends control */ public function ajaxGetStatus($methodName, $caseID = 0) { - $status = $this->testcase->getStatus($methodName, $caseID); - + $case = $this->testcase->getByID($caseID); + $status = $this->testcase->getStatus($methodName, $case); + if($methodName == 'update') $status = zget($status, 1, ''); die($status); } } diff --git a/module/testcase/model.php b/module/testcase/model.php index 8b72d22218..62ba6d8121 100644 --- a/module/testcase/model.php +++ b/module/testcase/model.php @@ -1592,7 +1592,7 @@ class testcaseModel extends model return false; } - $status = $this->post->status; + $status = $this->post->status ? $this->post->status : $case->status; $stepChanged = false; $steps = array(); diff --git a/module/tree/view/browse.html.php b/module/tree/view/browse.html.php index b3ae64b327..9b849c2c0d 100644 --- a/module/tree/view/browse.html.php +++ b/module/tree/view/browse.html.php @@ -14,7 +14,6 @@ diff --git a/module/user/model.php b/module/user/model.php index 6c7532e5cc..8672b54beb 100644 --- a/module/user/model.php +++ b/module/user/model.php @@ -277,7 +277,7 @@ class userModel extends model if(!validater::checkAccount($users->account[$i])) die(js::error(sprintf($this->lang->user->error->account, $i + 1))); if($users->realname[$i] == '') die(js::error(sprintf($this->lang->user->error->realname, $i + 1))); if($users->email[$i] and !validater::checkEmail($users->email[$i])) die(js::error(sprintf($this->lang->user->error->mail, $i + 1))); - $users->password[$i] = (isset($prev['password']) and $users->ditto[$i] == 'on' and empty($users->password[$i])) ? $prev['password'] : $users->password[$i]; + $users->password[$i] = (isset($prev['password']) and $users->ditto[$i] == 'on' and !$this->post->password[$i]) ? $prev['password'] : $this->post->password[$i]; if(!validater::checkReg($users->password[$i], '|(.){6,}|')) die(js::error(sprintf($this->lang->user->error->password, $i + 1))); $role = $users->role[$i] == 'ditto' ? (isset($prev['role']) ? $prev['role'] : '') : $users->role[$i]; @@ -328,7 +328,7 @@ class userModel extends model $prev['dept'] = $data[$i]->dept; $prev['role'] = $data[$i]->role; $prev['group'] = $data[$i]->group; - $prev['password'] = $users->password[$i]; + $prev['password'] = $this->post->password[$i]; } }