From 3b4d86500a1a8ac7f23b62912c172363a57fb901 Mon Sep 17 00:00:00 2001 From: zhaoke Date: Sat, 6 May 2023 18:18:34 +0800 Subject: [PATCH 01/33] * Modify testDB name. --- test/lib/init.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/lib/init.php b/test/lib/init.php index 1de60d8704..235f5197e3 100644 --- a/test/lib/init.php +++ b/test/lib/init.php @@ -58,12 +58,12 @@ include $frameworkRoot . 'helper.class.php'; $app = router::createApp('pms', dirname(dirname(__FILE__)), 'router'); $poolID = getenv('ZTF_POOL_ID'); -$testDB = empty($config->testDB) ? array() : $config->testDB; +$dbPool = empty($config->dbPool) ? array() : $config->dbPool; /* 根据ztf设置的poolID环境变量设置连接的数据库 */ -if(!empty($testDB) && !empty($poolID)) +if(!empty($dbPool) && !empty($poolID)) { - $selectDB = $testDB[$poolID%count($testDB)]; + $selectDB = $dbPool[$poolID%count($dbPool)]; !empty($selectDB['host']) && $config->db->host = $selectDB['host']; !empty($selectDB['port']) && $config->db->port = $selectDB['port']; From 6c7930fcb35d0d79f0d7083679438dc4d855448a Mon Sep 17 00:00:00 2001 From: wangyidong Date: Mon, 8 May 2023 08:34:19 +0800 Subject: [PATCH 02/33] * fix bug. --- module/product/zen.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/product/zen.php b/module/product/zen.php index 3c8288c06d..2a79977c37 100644 --- a/module/product/zen.php +++ b/module/product/zen.php @@ -300,7 +300,7 @@ class productZen extends product $initArray = strpos($params, 'hasempty') !== false ? array('') : array(); $linePairs = $initArray; foreach($programIdList as $programID) $linePairs[$programID] = $initArray; - foreach($productLines as $line) $linePairs[$programID][$line->id] = $line->name; + foreach($productLines as $programID => $line) $linePairs[$programID][$line->id] = $line->name; return array($productLines, $linePairs); } From fa3b70e111c4f8e046176b5f113da8d99e8dfde7 Mon Sep 17 00:00:00 2001 From: liuyue Date: Mon, 8 May 2023 00:35:23 +0000 Subject: [PATCH 03/33] * Add return value type of form widget. --- lib/zin/wg/form/v1.php | 4 ++-- lib/zin/wg/formbase/v1.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/zin/wg/form/v1.php b/lib/zin/wg/form/v1.php index 4121410604..65faaa2e79 100644 --- a/lib/zin/wg/form/v1.php +++ b/lib/zin/wg/form/v1.php @@ -37,13 +37,13 @@ class form extends formBase return new formGroup(inherit($item)); } - protected function buildActions(): wg + protected function buildActions(): wg|null { $actions = parent::buildActions(); if($this->prop('grid') && !empty($actions)) $actions = div(setClass('form-row'), $actions); return $actions; } - + protected function buildProps(): array { list($grid, $labelWidth) = $this->prop(array('grid', 'labelWidth')); diff --git a/lib/zin/wg/formbase/v1.php b/lib/zin/wg/formbase/v1.php index 3e7f41a893..16aaf643c4 100644 --- a/lib/zin/wg/formbase/v1.php +++ b/lib/zin/wg/formbase/v1.php @@ -35,7 +35,7 @@ class formBase extends wg 'actions' => ['submit', 'cancel'], ); - protected function buildActions(): wg + protected function buildActions(): wg|null { $actions = $this->prop('actions'); if(empty($actions)) return NULL; From beba0cfb6c8b82898bd3c9a577b89bbc906a1e30 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 8 May 2023 08:57:59 +0800 Subject: [PATCH 04/33] * Fix bug of sonarqube. --- module/task/control.php | 14 +++++++------- module/task/zen.php | 26 +++++++++++++------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/module/task/control.php b/module/task/control.php index ab7ebb3043..5e59077bf8 100755 --- a/module/task/control.php +++ b/module/task/control.php @@ -70,7 +70,7 @@ class task extends control if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); list($task, $testTasks, $existTaskID) = $result; - if($existTaskID) return $this->send(array('result' => 'success', 'message' => sprintf($this->lang->duplicate, $this->lang->task->common), 'locate' => $this->createLink('task', 'view', "taskID={$existTaskID}"))); + if($existTaskID) return $this->send(array('result' => 'success', 'message' => sprintf($this->lang->duplicate, $this->lang->task->common), 'locate' => $this->createLink('task', 'view', "taskID={$existTaskID}"))); /* Create task. */ $taskIdList = $this->task->create($task, $this->post->assignedTo, (int)$this->post->multiple, $this->post->team, (bool)$this->post->selectTestStory); @@ -81,7 +81,7 @@ class task extends control $columnID = isset($output['columnID']) ? (int)$output['columnID'] : 0; $this->task->afterCreate($task, $taskIdList, $bugID, $todoID, $testTasks); $this->task->updateKanbanData($execution, $task, (int)$_POST['lane'], $columnID); - setcookie('lastTaskModule', (int)$_POST['module'], $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, false); + setcookie('lastTaskModule', (int)$_POST['module'], $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true); /* Get the information returned after a task is created. */ $response = $this->taskZen->responseAfterCreate($task, $execution, $_POST['after']); @@ -704,7 +704,7 @@ class task extends control $kanbanData = $this->loadModel('kanban')->getRDKanban($task->execution, $execLaneType, 'id_desc', 0, $execGroupBy, $rdSearchValue); $kanbanData = json_encode($kanbanData); - return print(js::reload('parent') . js::execute("parent.parent.updateKanban($kanbanData)")); + return print(js::reload('parent')); } if($from == 'taskkanban') { @@ -714,9 +714,9 @@ class task extends control $kanbanData = $kanbanData[$kanbanType]; $kanbanData = json_encode($kanbanData); - return print(js::reload('parent') . js::execute("parent.parent.updateKanban(\"task\", $kanbanData)")); + return print(js::reload('parent')); } - return print(js::reload('parent') . js::execute("if(typeof(parent.parent.ajaxRefresh) == 'function') parent.parent.ajaxRefresh()")); + return print(js::reload('parent')); } return print(js::locate($this->createLink('task', 'view', "taskID=$taskID"), 'parent')); } @@ -1521,7 +1521,7 @@ class task extends control ->limit(50) ->fetchAll('id'); - if(empty($tasks)) die(''); + if(empty($tasks)) return print(''); $parentGroup = $this->dao->select('*')->from(TABLE_TASK) ->where('parent')->in(array_keys($tasks)) @@ -1550,7 +1550,7 @@ class task extends control $list .= $this->task->buildNestedList($execution, $task, false, $showmore, $users); } - die($list); + return print($list); } /** diff --git a/module/task/zen.php b/module/task/zen.php index f2e628c0ca..a286ceafbd 100644 --- a/module/task/zen.php +++ b/module/task/zen.php @@ -358,7 +358,7 @@ class taskZen extends task /** * 展示看板相关变量。 * Show related variable about the Kanban. - * + * * @param int $executionID * @param array $output * @access private @@ -459,8 +459,8 @@ class taskZen extends task * 处理创建任务的请求数据。 * Process the request data for the creation task. * - * @param int $executionID - * @param object $formData + * @param int $executionID + * @param object $formData * @access private * @return object */ @@ -521,10 +521,10 @@ class taskZen extends task } /** - * 检查规定时间内是否创建了同名任务。 + * 检查规定时间内是否创建了同名任务。 * Check whether a task with the same name is created within the specified time. - * - * @param object $task + * + * @param object $task * @access private * @return int */ @@ -542,9 +542,9 @@ class taskZen extends task /** * 处理关联需求的测试子任务的请求数据。 * Process request data for test subtasks related to stories. - * - * @param int $executionID - * @param object $formData + * + * @param int $executionID + * @param object $formData * @access private * @return array|bool */ @@ -579,10 +579,10 @@ class taskZen extends task } /** - * 检查关联需求的测试类型任务数据格式是否符合要求。 + * 检查关联需求的测试类型任务数据格式是否符合要求。 * Check if the test type task data format of the linked stories meets the requirements. - * - * @param object[] $tasks + * + * @param object[] $tasks * @access private * @return bool */ @@ -713,7 +713,7 @@ class taskZen extends task /* Set the response to return task list. */ elseif($afterChoice == 'toTaskList') { - setcookie('moduleBrowseParam', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, false); + setcookie('moduleBrowseParam', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, true); $response['locate'] = $this->createLink('execution', 'task', "executionID=$executionID&status=unclosed¶m=0&orderBy=id_desc"); } /* Set the response to return story list. */ From 93b37e12962df6c4a79c6cccca0b201c2f11efce Mon Sep 17 00:00:00 2001 From: jukui Date: Mon, 8 May 2023 09:09:10 +0800 Subject: [PATCH 05/33] + Add getlistby function test case and fix model test case for todo tao. --- .../test/model/getselfandchildrenlist.php | 2 ++ module/programplan/test/model/getsiblings.php | 3 +- module/todo/test/model/getbyexportlist.php | 2 ++ module/todo/test/model/getlist.php | 13 +++++--- module/todo/test/tao/getlistby.php | 32 +++++++++++++++++++ .../test/tao/yaml/getlistby/getlistby.yaml | 24 ++++++++++++++ 6 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 module/todo/test/tao/getlistby.php create mode 100644 module/todo/test/tao/yaml/getlistby/getlistby.yaml diff --git a/module/programplan/test/model/getselfandchildrenlist.php b/module/programplan/test/model/getselfandchildrenlist.php index 991c2cea60..7da68b75a0 100755 --- a/module/programplan/test/model/getselfandchildrenlist.php +++ b/module/programplan/test/model/getselfandchildrenlist.php @@ -1,5 +1,7 @@ #!/usr/bin/env php gen(5); su('admin'); /** diff --git a/module/todo/test/model/getbyexportlist.php b/module/todo/test/model/getbyexportlist.php index 8f82b47e4f..870111877f 100644 --- a/module/todo/test/model/getbyexportlist.php +++ b/module/todo/test/model/getbyexportlist.php @@ -1,5 +1,7 @@ #!/usr/bin/env php getListTest($typeList[2]) == $thisWeekNum ? '1' : '0'; -$lastweek = $todo->getListTest($typeList[3]) == $lastWeekNum ? '1' : '0'; -$thismonth = $todo->getListTest($typeList[4]) == $thisMonthNum ? '1' : '0'; -$lastmonth = $todo->getListTest($typeList[5]) == $lastMonthNum ? '1' : '0'; +$thisweek = $todo->getListTest($typeList[2]) == $thisWeekNum ? '1' : '0'; +$lastweek = $todo->getListTest($typeList[3]) == $lastWeekNum ? '1' : '0'; +$thismonth = $todo->getListTest($typeList[4]) == $thisMonthNum ? '1' : '0'; +$lastmonth = $todo->getListTest($typeList[5]) == $lastMonthNum ? '1' : '0'; $thisSeason = $todo->getListTest($typeList[6]) == $thisSeasonNum ? '1' : '0'; r($thisweek) && p() && e('1'); // 获取type为thisweek 当前用户的代办数量 diff --git a/module/todo/test/tao/getlistby.php b/module/todo/test/tao/getlistby.php new file mode 100644 index 0000000000..ae7922e455 --- /dev/null +++ b/module/todo/test/tao/getlistby.php @@ -0,0 +1,32 @@ +#!/usr/bin/env php +config('getlistby')->gen(5); + +/** + +title=测试 todoModel->getListBy(); +cid=1 +pid=0 + +*/ + +global $tester; +$tester->loadModel('todo')->todoTao; + + +$type = 'before'; +$account = 'admin'; +$status = 'all'; +$begin = '2021-02-03'; +$end = '2024-04-04'; +$limit = 5; +$orderBy = 'date_desc'; + +$result = $tester->todo->getListBy($type, $account, $status, $begin, $end, $limit, $orderBy); + +r(count($result)) && p() && e('5'); +r($result[0]) && p('name,status') && e('待办5,doing'); diff --git a/module/todo/test/tao/yaml/getlistby/getlistby.yaml b/module/todo/test/tao/yaml/getlistby/getlistby.yaml new file mode 100644 index 0000000000..af08e92bb3 --- /dev/null +++ b/module/todo/test/tao/yaml/getlistby/getlistby.yaml @@ -0,0 +1,24 @@ +title: zt_getlistby +author: jukui +version: '1.0' +fields: + - field: id + range: 1-5 + - field: name + range: 1-5 + prefix: '待办' + - field: account + range: 'admin' + - field: date + range: 1-9 + prefix: '2023-03-0' + - field: desc + range: 1-5 + prefix: '待办描述' + - field: finishedDate + range: 1-9 + prefix: '2023-05-0' + - field: status + range: 'wait,doing,closed,wait,doing' + - field: assignedTo + range: 'admin' From 13cc6e53c4e81ba7427d248c521c7f143c97acf1 Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 8 May 2023 09:08:52 +0800 Subject: [PATCH 06/33] * zin: fix prop circle not work --- lib/zin/wg/avatar/v1.php | 2 +- lib/zin/wg/featurebar/v1.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/zin/wg/avatar/v1.php b/lib/zin/wg/avatar/v1.php index dccd598b81..243b0833ef 100644 --- a/lib/zin/wg/avatar/v1.php +++ b/lib/zin/wg/avatar/v1.php @@ -96,7 +96,7 @@ class avatar extends wg /* Set circle. */ if($circle) { - $this->finalClass[] = 'circle'; + $this->finalClass[] = 'rounded-full'; } else if($rounded) { diff --git a/lib/zin/wg/featurebar/v1.php b/lib/zin/wg/featurebar/v1.php index 9d43702412..a9e3e01809 100644 --- a/lib/zin/wg/featurebar/v1.php +++ b/lib/zin/wg/featurebar/v1.php @@ -77,7 +77,7 @@ class featureBar extends wg 'text' => $item->text, 'active' => $isActive, 'url' => str_replace('{key}', $item->name, $link), - 'badge' => $isActive && !empty($recTotal) ? array('text' => $recTotal, 'class' => 'size-sm circle white') : NULL, + 'badge' => $isActive && !empty($recTotal) ? array('text' => $recTotal, 'class' => 'size-sm rounded-full white') : NULL, 'type' => 'dropdown', 'items' => $subItems, 'props' => ['data-id' => $item->name, 'data-load' => 'table'] @@ -92,7 +92,7 @@ class featureBar extends wg 'text' => $item->text, 'active' => $isActive, 'url' => str_replace('{key}', $item->name, $link), - 'badge' => $isActive && !empty($recTotal) ? array('text' => $recTotal, 'class' => 'size-sm circle white') : NULL, + 'badge' => $isActive && !empty($recTotal) ? array('text' => $recTotal, 'class' => 'size-sm rounded-full white') : NULL, 'props' => ['data-id' => $item->name, 'data-load' => 'table'] ); } From 105a6089053ae7886313bab3ca74f522e9588135 Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 8 May 2023 09:09:11 +0800 Subject: [PATCH 07/33] * zin: refactor --- lib/zin/wg/control/v1.php | 1 - lib/zin/wg/formgroup/v1.php | 7 ++++--- lib/zin/wg/formlabel/v1.php | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/zin/wg/control/v1.php b/lib/zin/wg/control/v1.php index 9982c89a41..1a307d66e9 100644 --- a/lib/zin/wg/control/v1.php +++ b/lib/zin/wg/control/v1.php @@ -21,7 +21,6 @@ class control extends wg 'required?: bool', 'placeholder?: string', 'disabled?: bool', - 'form?: string', 'items?: array' ); diff --git a/lib/zin/wg/formgroup/v1.php b/lib/zin/wg/formgroup/v1.php index 9d9812b406..41cb1903a4 100644 --- a/lib/zin/wg/formgroup/v1.php +++ b/lib/zin/wg/formgroup/v1.php @@ -6,11 +6,12 @@ require_once dirname(__DIR__) . DS . 'control' . DS . 'v1.php'; class formGroup extends wg { - protected static $defineProps = array( + protected static $defineProps = array + ( 'name?: string', - 'label?:string|bool', - 'labelClass?: string', + 'label?: string|bool', 'labelClass?: string', + 'labelProps?: string', 'required?:bool|string="auto"', 'tip?: string', 'tipClass?: string|array', diff --git a/lib/zin/wg/formlabel/v1.php b/lib/zin/wg/formlabel/v1.php index 31c8969010..d28c4b18df 100644 --- a/lib/zin/wg/formlabel/v1.php +++ b/lib/zin/wg/formlabel/v1.php @@ -3,7 +3,8 @@ namespace zin; class formLabel extends wg { - protected static $defineProps = array( + protected static $defineProps = array + ( 'text?:string', 'required?:bool', 'for?:string' From 603e128f2521da73c6d85153f5abed936000ca1f Mon Sep 17 00:00:00 2001 From: shenshulong Date: Mon, 8 May 2023 01:12:59 +0000 Subject: [PATCH 08/33] * Adjusted programplan ajaxGetStageAttr and ajaxGetAttribute function. --- module/programplan/control.php | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/module/programplan/control.php b/module/programplan/control.php index 4f28f3837d..b2ab1274d7 100644 --- a/module/programplan/control.php +++ b/module/programplan/control.php @@ -307,15 +307,16 @@ class programplan extends control * ajax请求:获取阶段ID的属性。 * AJAX: Get stageID attributes. * - * @param int $stageID + * @param string $stageID * @param string $attribute * @access public * @return int */ - public function ajaxGetAttribute(int $stageID, string $attribute): int + public function ajaxGetAttribute(string $stageID, string $attribute): int { $this->app->loadLang('stage'); + $stageID = (int)$stageID; $stageAttribute = $this->programplan->getStageAttribute($stageID); if(empty($stageAttribute) || $stageAttribute == 'mix') @@ -327,15 +328,20 @@ class programplan extends control } /** - * AJAX: Get stage's attribute. + * ajax请求:获取阶段ID的属性。 + * AJAX: Get stageID attribute. * - * @param int $stageID + * @param string $stageID * @access public * @return int */ - public function ajaxGetStageAttr($stageID) + public function ajaxGetStageAttr(string $stageID): int { - $stage = $this->dao->select('attribute')->from(TABLE_EXECUTION)->where('id')->eq($stageID)->fetch('attribute'); - return print($stage); + $stageID = (int)$stageID; + $stageAttribute = $this->programplan->getStageAttribute($stageID); + + if(!$stageAttribute) return print(js::error(dao::getError())); + + return print($stageAttribute); } } From d51a99c3a313030f0ae89f53b46c9c0b0d6bcc91 Mon Sep 17 00:00:00 2001 From: Guanxiying Date: Mon, 8 May 2023 09:39:35 +0800 Subject: [PATCH 09/33] * Adjust ztf report. --- test/lib/coverage.php | 22 +++++++++++--- www/coverage.php | 71 +++++++++---------------------------------- 2 files changed, 32 insertions(+), 61 deletions(-) diff --git a/test/lib/coverage.php b/test/lib/coverage.php index 4e612f5228..dd6618870b 100644 --- a/test/lib/coverage.php +++ b/test/lib/coverage.php @@ -23,7 +23,7 @@ class coverage * @access private * @return bool */ - private function initTraceFile(): bool + public function initTraceFile(): bool { $tracePath = $this->zentaoRoot . "/tmp/coverage/"; $this->traceFile = $tracePath . "traces.json"; @@ -66,7 +66,7 @@ class coverage * @access public * @return array|string */ - private function loadTraceFromFile(string $key = ''): array|string + public function loadTraceFromFile(string $key = ''): array|string { $report = json_decode(file_get_contents($this->traceFile), true); if($key == '') return $report; @@ -78,11 +78,24 @@ class coverage * * @access public * @return string + */ public function getTraceFile(): string { return $this->traceFile; } + /** + * Reset traceFile. + * + * @access public + * @return bool + */ + public function reset() + { + if(!is_file($this->traceFile)) return true; + return exec("rm $this->traceFile") !== false; + } + /** * Merge traces form local file and this called trace. * @@ -372,8 +385,9 @@ EOT; $report = json_decode($content); if(!is_object($report) || !isset($report->funcResult)) return false; - $report->funcResult = ''; - $report->log = ''; + $report->logFile = $reportFile; + $report->funcResult = ''; + $report->log = ''; $report->time = date('Y-m-d H:i:s', $report->endTime); $report->passPercent = round($report->pass / $report->total * 100, 2); diff --git a/www/coverage.php b/www/coverage.php index 4d6dd4a760..ec23587e07 100644 --- a/www/coverage.php +++ b/www/coverage.php @@ -9,12 +9,14 @@ $report = ''; $ztfReport = $coverage->getZtfReport(); if($ztfReport) { - $ztfHtml = "

%s 执行%s个用例,耗时%s秒。%s(%s%%) 通过,%s(%s%%) 失败,%s(%s%%) 忽略。

"; + $ztfHtml = "
%s 执行 %s个用例,耗时 %s秒。%s (%s%%) 通过,%s (%s%%) 失败,%s (%s%%) 忽略。
"; $ztfHtml = sprintf($ztfHtml, $ztfReport->time, $ztfReport->total, $ztfReport->duration, $ztfReport->pass, $ztfReport->passPercent, $ztfReport->fail, $ztfReport->failPercent, $ztfReport->skip, $ztfReport->skipPercent); + //$ztfHtml .= "

Ztf log File: {$ztfReport->logFile}

"; } else { - $ztfHtml = "

没有找到ZTF测试报告。

"; + $ztfPath = $coverage->loadTraceFromFile('ztfPath'); + $ztfHtml = "

在{$ztfPath}/ 没有找到ZTF测试报告。

"; } @@ -39,61 +41,16 @@ switch($type) 单元测试行覆盖率报告

单元测试行覆盖率报告

From 02bf7ad2be19f480388d724fc2590c363a56a339 Mon Sep 17 00:00:00 2001 From: Guanxiying Date: Mon, 8 May 2023 09:50:51 +0800 Subject: [PATCH 10/33] * Replace die and exit with helper::end(). --- framework/base/router.class.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/framework/base/router.class.php b/framework/base/router.class.php index 7de7d523d4..b299627094 100644 --- a/framework/base/router.class.php +++ b/framework/base/router.class.php @@ -2164,7 +2164,7 @@ class baseRouter if($extension == '302') { header("location: $url"); - exit; + helper::end(); } if($extension == 'api') @@ -2186,7 +2186,7 @@ class baseRouter $output .= $response; if(isset($viewFiles['hookFiles'])) foreach($viewFiles['hookFiles'] as $hookFile) $output .= $this->control->printViewFile($hookFile); $output .= $this->control->printViewFile($footFile); - die($output); + helper::end($output); } } @@ -2437,14 +2437,14 @@ class baseRouter $nameRule = $filter->{$this->moduleName}->{$this->methodName}->paramName ?? $filter->default->paramName; foreach($passedParams as $param => $value) { - if(!validater::checkByRule($param, $nameRule)) die('Bad Request!'); + if(!validater::checkByRule($param, $nameRule)) helper::end('Bad Request!'); $valueRule = $filter->default->paramValue; if(isset($filter->{$this->moduleName}->{$this->methodName}->paramValue[$param])) { $valueRule = $filter->{$this->moduleName}->{$this->methodName}->paramValue[$param]; } - if($value and !validater::checkByRule($value, $valueRule)) die('Bad Request!'); + if($value and !validater::checkByRule($value, $valueRule)) helper::end('Bad Request!'); } $passedParams = array_values($passedParams); @@ -2873,7 +2873,7 @@ class baseRouter if(preg_match('/[^\x00-\x80]/', $message)) $message = helper::convertEncoding($message, 'gbk'); /* Only show error when debug is open. */ - if(!$this->config->debug) die(); + if(!$this->config->debug) helper::end(); $log = "ERROR: $message in $file on line $line"; if(isset($_SERVER['SCRIPT_URI'])) $log .= ", request: $_SERVER[SCRIPT_URI]";; @@ -2983,12 +2983,12 @@ class baseRouter * */ if($level == E_ERROR or $level == E_PARSE or $level == E_CORE_ERROR or $level == E_COMPILE_ERROR or $level == E_USER_ERROR) { - if(empty($this->config->debug)) die(); - if(PHP_SAPI == 'cli') die($errorLog); + if(empty($this->config->debug)) helper::end(); + if(PHP_SAPI == 'cli') helper::end($errorLog); $htmlError = ""; $htmlError .= "" . nl2br($errorLog) . ""; - die($htmlError); + helper::end($htmlError); } } From fdf72471aa4ed8a274b8b1874f8c13b0d5c6f07f Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 8 May 2023 09:58:53 +0800 Subject: [PATCH 11/33] * zin: set this to event handler --- lib/zin/core/wg.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zin/core/wg.class.php b/lib/zin/core/wg.class.php index ff167c1d63..0f8ae6077e 100644 --- a/lib/zin/core/wg.class.php +++ b/lib/zin/core/wg.class.php @@ -215,7 +215,7 @@ class wg if($stop) $code[] = "e.stopPropagation();"; if($prevent) $code[] = "e.preventDefault();"; - if(preg_match('/^[$A-Z_][0-9A-Z_$\[\]."\']*$/i', $handler)) $code[] = "($handler)(e);"; + if(preg_match('/^[$A-Z_][0-9A-Z_$\[\]."\']*$/i', $handler)) $code[] = "($handler).call(e.target,e);"; else $code[] = $handler; $code[] = '}' . (empty($binding) ? '' : (', ' . json_encode($binding))) . ');'; From 78c0931ffd95299772231910aed7b22fad9f6887 Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 8 May 2023 09:59:14 +0800 Subject: [PATCH 12/33] * zin: refactor, remove debug code --- lib/zin/core/context.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/zin/core/context.class.php b/lib/zin/core/context.class.php index 711eb73931..bb4692bb6a 100644 --- a/lib/zin/core/context.class.php +++ b/lib/zin/core/context.class.php @@ -99,7 +99,6 @@ class context extends \zin\utils\dataset { if(!method_exists($wg, 'buildEvents')) { - \a(['> getEventsBindings', 'no buildEvents', $wg]); continue; } $code = $wg->buildEvents(); From 70655a0b9871ab4b1570edcf1d05c5e985ea7662 Mon Sep 17 00:00:00 2001 From: Wangyuting <851424971@qq.com> Date: Mon, 8 May 2023 10:16:36 +0800 Subject: [PATCH 13/33] * Adjust project block css. --- .../block/ui/projectstatisticblock.html.php | 82 +++++++++++-------- module/block/ui/projectteamblock.html.php | 23 ++++++ module/block/ui/recentprojectblock.html.php | 28 +++++-- 3 files changed, 90 insertions(+), 43 deletions(-) create mode 100644 module/block/ui/projectteamblock.html.php diff --git a/module/block/ui/projectstatisticblock.html.php b/module/block/ui/projectstatisticblock.html.php index c38ce084a5..39dd54d3da 100644 --- a/module/block/ui/projectstatisticblock.html.php +++ b/module/block/ui/projectstatisticblock.html.php @@ -15,6 +15,8 @@ $isChineseLang = in_array($this->app->getClientLang(), array('zh-cn','zh-tw')); $blockNavID = 'nav-' . uniqid(); $selected = key($projects); $navTabs = array(); + +/* 展示左侧的项目列表。 */ foreach($projects as $project) { $navTabs[] = li @@ -44,57 +46,64 @@ foreach($projects as $project) $tabItems = array(); foreach($projects as $project) { - $cells = array(); - foreach($config->block->projectstatistic->dtable as $module => $items) + if(in_array($project->model, array('scrum', 'kanban', 'agileplus'))) { - $cellItems = array(); - foreach($items as $item) + /* 展示右侧的项目统计项。 */ + $cells = array(); + foreach($config->block->projectstatistic->dtable as $module => $items) { - $field = $item['field']; - $unit = $item['unit']; - $cellItems[] = div + $cellItems = array(); + foreach($items as $item) + { + $field = $item['field']; + $unit = $item['unit']; + $cellItems[] = div + ( + set('class', 'flex py-4'), + cell + ( + set('width', '50%'), + set('class', 'text-right text-gray'), + span($lang->block->projectstatistic->{$field} . ' :') + ), + cell + ( + set('width', '50%'), + set('class', 'text-left'), + span + ( + set('class', 'font-bold text-black'), + zget($project, $field, 0) + ), + span($lang->block->projectstatistic->{$unit}) + ) + ); + } + $cells[] = cell ( - set('class', 'flex py-4'), - cell + set('class', 'flex-1 px-2 py-4'), + div ( - set('width', '50%'), - set('class', 'text-right text-gray'), - span($lang->block->projectstatistic->{$field} . ' :') - ), - cell - ( - set('width', '50%'), - set('class', 'text-left'), + set('class', 'px-2'), span ( - set('class', 'font-bold text-black'), - zget($project, $field, 0) + set('class', 'font-bold'), + $lang->block->projectstatistic->{$module} ), - span($lang->block->projectstatistic->{$unit}) - ) + ), + $cellItems ); } - $cells[] = cell - ( - set('class', 'flex-1 px-2 py-4'), - div - ( - set('class', 'px-2'), - span - ( - set('class', 'font-bold'), - $lang->block->projectstatistic->{$module} - ), - ), - $cellItems - ); } + /* 展示右侧顶部的项目状况。 */ $tabItems[] = div ( set('class', 'tab-pane' . ($project->id == $selected ? ' active' : '')), set('id', "tab3{$blockNavID}Content{$project->id}"), + in_array($project->model, array('scrum', 'kanban', 'agileplus')) ? div ( + /* 敏捷、看板等项目展示概况。 */ div ( set('class', 'flex bg-white h-10 leading-9 px-4 shadow-sm'), @@ -158,8 +167,9 @@ foreach($projects as $project) set('class', 'flex'), $cells ) - ) : div + ) : div ( + /* 瀑布项目展示概况。 */ set('class', 'weekly-row'), div ( diff --git a/module/block/ui/projectteamblock.html.php b/module/block/ui/projectteamblock.html.php new file mode 100644 index 0000000000..7dd0346d77 --- /dev/null +++ b/module/block/ui/projectteamblock.html.php @@ -0,0 +1,23 @@ + +* @package block +* @link https://www.zentao.net +*/ + +namespace zin; + +panel +( + set('class', 'projectteam-block'), + div + ( + '暂无新UI设计' + ) +); + +render(); diff --git a/module/block/ui/recentprojectblock.html.php b/module/block/ui/recentprojectblock.html.php index 677e33c472..2e6d548b57 100644 --- a/module/block/ui/recentprojectblock.html.php +++ b/module/block/ui/recentprojectblock.html.php @@ -15,13 +15,13 @@ $cards = array(); foreach($projects as $projectID => $project) { $viewLink = $this->createLink('project', 'index', "projectID=$project->id"); - $cards[] = div + $cards[] = cell ( - set('class', 'card flex-1'), + set('width', '33%'), + set('class', 'border m-2 p-4'), div ( - set('class', 'card-header'), - span($lang->project->{$project->model}), + set('class', 'pb-2'), a ( set('href', $viewLink), @@ -33,9 +33,23 @@ foreach($projects as $projectID => $project) set('class', 'card-body'), div ( - set('class', 'project-infos'), - span(sprintf($lang->project->membersUnit, $project->teamCount)), - span(sprintf($lang->project->hoursUnit, $project->estimate)) + set('class', 'py-1.5'), + span('近期执行 : XXX'), + label + ( + set('class', 'warning-outline ml-4'), + '进行中' + ) + ), + div + ( + set('class', 'py-1.5'), + span('项目成员 : 共 5 人') + ), + div + ( + set('class', 'py-1.5'), + span('计划完成 : 2022-09-30') ) ) ); From f956d5b3948fb9688688377feebef6995091feb2 Mon Sep 17 00:00:00 2001 From: Lufei Date: Mon, 8 May 2023 10:21:59 +0800 Subject: [PATCH 14/33] * Fix roadrunner error. --- .gitignore | 1 + bin/roadrunner/.rr.yaml | 17 +++++++++++------ bin/roadrunner/README.md | 12 ++++++++++-- bin/roadrunner/composer.json | 9 +++++++-- bin/roadrunner/cron-worker.php | 12 ++++++------ framework/base/router.class.php | 2 +- 6 files changed, 36 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 2795b1f58e..86394e36f4 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ test/runtime/* test/www !/**/.gitkeep .scannerwork +bin/roadrunner/rr diff --git a/bin/roadrunner/.rr.yaml b/bin/roadrunner/.rr.yaml index e98c8a112c..6255bea7e1 100644 --- a/bin/roadrunner/.rr.yaml +++ b/bin/roadrunner/.rr.yaml @@ -1,7 +1,12 @@ +version: '3' + +metrics: + address: '127.0.0.1:2112' + service: - cron: - command: php cron-worker.php - process_num: 4 - exec_timeout: 0 - remain_after_exit: true - restart_sec: 1 + cron: + command: php cron-worker.php + process_num: 2 + exec_timeout: 0 + remain_after_exit: true + restart_sec: 1 diff --git a/bin/roadrunner/README.md b/bin/roadrunner/README.md index 741026a58a..2a4ca899ff 100644 --- a/bin/roadrunner/README.md +++ b/bin/roadrunner/README.md @@ -4,10 +4,18 @@ 安装 RoadRunner: -Composer: `composer update` +Composer: `composer install` + +## 获取执行文件 + +```shell +composer get-rr +``` ## 启动服务 ```shell -rr serve +composer serve +# or +./rr serve ``` diff --git a/bin/roadrunner/composer.json b/bin/roadrunner/composer.json index 67092734e8..8670544a0a 100644 --- a/bin/roadrunner/composer.json +++ b/bin/roadrunner/composer.json @@ -1,6 +1,11 @@ { "require": { - "spiral/roadrunner": "^2.6", - "nyholm/psr7": "^1.4" + "spiral/roadrunner": "^2023.1", + "nyholm/psr7": "^1.4", + "spiral/roadrunner-cli": "^2.5" + }, + "scripts": { + "get-rr": "./vendor/bin/rr get-binary", + "serve": "./rr serve -c .rr.yaml" } } diff --git a/bin/roadrunner/cron-worker.php b/bin/roadrunner/cron-worker.php index 3d5ec659e0..a79801d73a 100644 --- a/bin/roadrunner/cron-worker.php +++ b/bin/roadrunner/cron-worker.php @@ -12,19 +12,19 @@ * @link http://www.zentao.net */ /* Set the error reporting. */ -error_reporting(0); +//error_reporting(0); /* Load the framework. */ -include '../framework/router.class.php'; -include '../framework/control.class.php'; -include '../framework/model.class.php'; -include '../framework/helper.class.php'; +include '../../framework/router.class.php'; +include '../../framework/control.class.php'; +include '../../framework/model.class.php'; +include '../../framework/helper.class.php'; /* Log the time and define the run mode. */ $startTime = getTime(); /* Instance the app. */ -$app = router::createApp('pms', dirname(__DIR__), 'router'); +$app = router::createApp('pms', dirname(__DIR__, 2), 'router'); /* Run the app. */ $common = $app->loadCommon(); diff --git a/framework/base/router.class.php b/framework/base/router.class.php index b299627094..9d64eea4be 100644 --- a/framework/base/router.class.php +++ b/framework/base/router.class.php @@ -255,7 +255,7 @@ class baseRouter * @var string * @access public */ - public $viewType; + public $viewType = 'html'; /** * 全局$config对象。 From 4bfe21f0c6b2697d7a690a33252b3114da1c6540 Mon Sep 17 00:00:00 2001 From: liyang Date: Mon, 8 May 2023 10:22:51 +0800 Subject: [PATCH 15/33] * Fix pipeline stage order. --- Jenkinsfile | 258 ++++++++++++++++++++++++++-------------------------- 1 file changed, 129 insertions(+), 129 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 16d04b6293..089a7b2238 100755 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -21,145 +21,145 @@ pipeline { } stages { - stage("checkout code") { + stage("checkout code") { steps { echo "checkout code success" } - } + } - stage('Sonar Scanner') { - parallel { - stage('SonarQube') { - steps { - container('sonar') { - withSonarQubeEnv('sonarqube') { - sh 'git config --global --add safe.directory $(pwd)' - sh 'sonar-scanner -Dsonar.analysis.user=$(git show -s --format=%an)' - } - } - } - post { - success { - container('xuanimbot') { - sh 'git config --global --add safe.directory $(pwd)' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "sonar scanner" --url "https://sonar.qc.oop.cc/dashboard?id=zentaopms&branch=${GIT_BRANCH}" --content "sonar scanner success" --debug --custom' - } - } - failure { - container('xuanimbot') { - sh 'git config --global --add safe.directory $(pwd)' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "sonar scanner" --url "https://sonar.qc.oop.cc/dashboard?id=zentaopms&branch=${GIT_BRANCH}" --content "sonar scanner failure" --debug --custom' - } + parallel { + stage('Sonar Qube') { + steps { + container('sonar') { + withSonarQubeEnv('sonarqube') { + sh 'git config --global --add safe.directory $(pwd)' + sh 'sonar-scanner -Dsonar.analysis.user=$(git show -s --format=%an)' + } } } + post { + success { + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "sonar scanner" --url "https://sonar.qc.oop.cc/dashboard?id=zentaopms&branch=${GIT_BRANCH}" --content "sonar scanner success" --debug --custom' + } + } + failure { + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "sonar scanner" --url "https://sonar.qc.oop.cc/dashboard?id=zentaopms&branch=${GIT_BRANCH}" --content "sonar scanner failure" --debug --custom' + } + } } + } - stage('Build Image') { - steps { - container('docker') { - sh 'docker build --pull . -f Dockerfile.test --build-arg VERSION=${ZENTAO_VERSION} --build-arg MIRROR=true --build-arg MYSQL_HOST=${MYSQL_SERVER_HOST} --build-arg MYSQL_PASSWORD=${MYSQL_ROOT_PASSWORD} -t ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' - sh 'docker push ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' - } - } - post { - success { - echo 'build image success' - } - failure { - container('xuanimbot') { - sh 'git config --global --add safe.directory $(pwd)' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "build image" --url "${RUN_DISPLAY_URL}" --content "Build unit test image failure" --debug --custom' - } - } - } + stage('Unit Test'){ + + stages{ + + stage('Build Image') { + steps { + container('docker') { + sh 'docker build --pull . -f Dockerfile.test --build-arg VERSION=${ZENTAO_VERSION} --build-arg MIRROR=true --build-arg MYSQL_HOST=${MYSQL_SERVER_HOST} --build-arg MYSQL_PASSWORD=${MYSQL_ROOT_PASSWORD} -t ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' + sh 'docker push ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' + } + } + post { + success { + echo 'build image success' + } + failure { + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "build image" --url "${RUN_DISPLAY_URL}" --content "Build unit test image failure" --debug --custom' + } + } + } + } + + stage('Init') { + agent { + kubernetes { + inheritFrom "xuanim" + containerTemplate { + name "zentao" + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command "sleep" + args "99d" + } + } + } + options { skipDefaultCheckout() } + + steps { + container('zentao') { + sh 'cat /usr/bin/initdb.php; initdb.php ; /apps/zentao/test/ztest init' + } + } + post { + success { + sh 'echo "stage unit init success"' + } + failure { + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest init" --url "${RUN_DISPLAY_URL}" --content "Unit test database initialization failed" --debug --custom' + } + } + } + } + + stage('Run') { + matrix { + agent { + kubernetes { + inheritFrom "xuanim" + containerTemplate { + name "zentao" + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command "sleep" + args "99d" + } + } + } + + options { skipDefaultCheckout() } + + axes { + axis { + name "SEQUENCE" + values "P1", "P2", "P3", "P4", "P5", "P6", "P7" + } + } + stages { + stage("Run") { + steps { + container('zentao') { + sh 'initdb.php config' + sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest ${SEQUENCE} | tee /apps/zentao/test/${SEQUENCE}.log' + sh 'pipeline-unittest.sh /apps/zentao/test/${SEQUENCE}.log' + } + } + } + } + } + post{ + success{ + container('xuanimbot') { + sh 'git config --global --add safe.directory /home/jenkins/agent/workspace/pangu_pangu_xuanimbot_master' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test passed" --debug --custom' + } + } + failure{ + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test failed" --debug --custom' + } + } + } + }//End unittest } } } - - stage('Unit Test'){ - stages{ - stage('Init') { - agent { - kubernetes { - inheritFrom "xuanim" - containerTemplate { - name "zentao" - image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" - command "sleep" - args "99d" - } - } - } - options { skipDefaultCheckout() } - - steps { - container('zentao') { - sh 'cat /usr/bin/initdb.php; initdb.php ; /apps/zentao/test/ztest init' - } - } - post { - success { - sh 'echo "stage unit init success"' - } - failure { - container('xuanimbot') { - sh 'git config --global --add safe.directory $(pwd)' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest init" --url "${RUN_DISPLAY_URL}" --content "Unit test database initialization failed" --debug --custom' - } - } - } - } - - stage('Run') { - matrix { - agent { - kubernetes { - inheritFrom "xuanim" - containerTemplate { - name "zentao" - image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" - command "sleep" - args "99d" - } - } - } - - options { skipDefaultCheckout() } - - axes { - axis { - name "SEQUENCE" - values "P1", "P2", "P3", "P4", "P5", "P6", "P7" - } - } - stages { - stage("Run") { - steps { - container('zentao') { - sh 'initdb.php config' - sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest ${SEQUENCE} | tee /apps/zentao/test/${SEQUENCE}.log' - sh 'pipeline-unittest.sh /apps/zentao/test/${SEQUENCE}.log' - } - } - } - } - } - post{ - success{ - container('xuanimbot') { - sh 'git config --global --add safe.directory /home/jenkins/agent/workspace/pangu_pangu_xuanimbot_master' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test passed" --debug --custom' - } - } - failure{ - container('xuanimbot') { - sh 'git config --global --add safe.directory $(pwd)' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test failed" --debug --custom' - } - } - } - }//End unittest - } - } } // End Root Stages } // End pipeline From f97194cde301719c89cf76b3237924f306042420 Mon Sep 17 00:00:00 2001 From: Lufei Date: Mon, 8 May 2023 10:25:42 +0800 Subject: [PATCH 16/33] * Fix cron log content error. --- bin/roadrunner/.rr.yaml | 3 --- bin/roadrunner/cron-worker.php | 18 ++++++++---------- module/cron/control.php | 3 +-- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/bin/roadrunner/.rr.yaml b/bin/roadrunner/.rr.yaml index 6255bea7e1..00d3c624f1 100644 --- a/bin/roadrunner/.rr.yaml +++ b/bin/roadrunner/.rr.yaml @@ -1,8 +1,5 @@ version: '3' -metrics: - address: '127.0.0.1:2112' - service: cron: command: php cron-worker.php diff --git a/bin/roadrunner/cron-worker.php b/bin/roadrunner/cron-worker.php index a79801d73a..0e983a9b60 100644 --- a/bin/roadrunner/cron-worker.php +++ b/bin/roadrunner/cron-worker.php @@ -1,18 +1,15 @@ - * @package ZenTaoPMS - * @version $Id: index.php 5036 2013-07-06 05:26:44Z wyd621@gmail.com $ - * @link http://www.zentao.net + * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net) + * @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html) + * @author Lu Fei + * @package cron + * @link https://www.zentao.net */ /* Set the error reporting. */ -//error_reporting(0); +error_reporting(0); /* Load the framework. */ include '../../framework/router.class.php'; @@ -27,6 +24,7 @@ $startTime = getTime(); $app = router::createApp('pms', dirname(__DIR__, 2), 'router'); /* Run the app. */ +$app->setStartTime($startTime); $common = $app->loadCommon(); $app->moduleName = 'cron'; diff --git a/module/cron/control.php b/module/cron/control.php index bf8be43f5d..48320f9b78 100644 --- a/module/cron/control.php +++ b/module/cron/control.php @@ -224,8 +224,7 @@ class cron extends control $log = ''; $time = $now->format('G:i:s'); $output = "\n" . $output; - - $log = "$time task " . $id . " executed,\ncommand: $cron[command].\nreturn : $return.\noutput : $output\n"; + $log = "$time task " . $id . " executed,\ncommand: {$cron['command']}.\nreturn : $return.\noutput : $output\n"; $this->cron->logCron($log); unset($log); } From 05e5f82230b806ba6ae97e0a94d6c27016f90559 Mon Sep 17 00:00:00 2001 From: liyang Date: Mon, 8 May 2023 10:34:02 +0800 Subject: [PATCH 17/33] * Fix jenkinsfile sync. --- Jenkinsfile | 106 ++++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 089a7b2238..987218dfd6 100755 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,7 +1,7 @@ pipeline { agent { kubernetes { - inheritFrom "build-docker code-scan xuanim" + inheritFrom 'build-docker code-scan xuanim' } } @@ -13,7 +13,7 @@ pipeline { MYSQL_SERVER_HOST = 'ci-mysql-0' MYSQL_ROOT_PASSWORD = 'pass4ci' - MIDDLE_IMAGE_REPO = "hub.qc.oop.cc/zentao-ztf" + MIDDLE_IMAGE_REPO = 'hub.qc.oop.cc/zentao-ztf' MIDDLE_IMAGE_TAG = """${sh( returnStdout: true, script: 'echo $BUILD_ID-${GIT_COMMIT}' @@ -21,20 +21,21 @@ pipeline { } stages { - stage("checkout code") { - steps { - echo "checkout code success" - } + stage('checkout code') { + steps { + echo 'checkout code success' + } } - parallel { - stage('Sonar Qube') { + stage('quality scan') { + parallel { + stage('Sonar Qube') { steps { container('sonar') { withSonarQubeEnv('sonarqube') { sh 'git config --global --add safe.directory $(pwd)' sh 'sonar-scanner -Dsonar.analysis.user=$(git show -s --format=%an)' - } + } } } post { @@ -49,51 +50,49 @@ pipeline { sh 'git config --global --add safe.directory $(pwd)' sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "sonar scanner" --url "https://sonar.qc.oop.cc/dashboard?id=zentaopms&branch=${GIT_BRANCH}" --content "sonar scanner failure" --debug --custom' } + } } } - } - stage('Unit Test'){ - - stages{ - - stage('Build Image') { - steps { - container('docker') { + stage('Unit Test') { + stages { + stage('Build Image') { + steps { + container('docker') { sh 'docker build --pull . -f Dockerfile.test --build-arg VERSION=${ZENTAO_VERSION} --build-arg MIRROR=true --build-arg MYSQL_HOST=${MYSQL_SERVER_HOST} --build-arg MYSQL_PASSWORD=${MYSQL_ROOT_PASSWORD} -t ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' sh 'docker push ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' + } } - } - post { - success { + post { + success { echo 'build image success' - } - failure { + } + failure { container('xuanimbot') { sh 'git config --global --add safe.directory $(pwd)' sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "build image" --url "${RUN_DISPLAY_URL}" --content "Build unit test image failure" --debug --custom' } + } } } - } - stage('Init') { + stage('Init') { agent { kubernetes { - inheritFrom "xuanim" - containerTemplate { - name "zentao" - image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" - command "sleep" - args "99d" - } + inheritFrom 'xuanim' + containerTemplate { + name 'zentao' + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command 'sleep' + args '99d' + } } } options { skipDefaultCheckout() } steps { container('zentao') { - sh 'cat /usr/bin/initdb.php; initdb.php ; /apps/zentao/test/ztest init' + sh 'cat /usr/bin/initdb.php; initdb.php ; /apps/zentao/test/ztest init' } } post { @@ -107,18 +106,18 @@ pipeline { } } } - } + } - stage('Run') { + stage('Run') { matrix { agent { kubernetes { - inheritFrom "xuanim" + inheritFrom 'xuanim' containerTemplate { - name "zentao" - image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" - command "sleep" - args "99d" + name 'zentao' + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command 'sleep' + args '99d' } } } @@ -127,30 +126,30 @@ pipeline { axes { axis { - name "SEQUENCE" - values "P1", "P2", "P3", "P4", "P5", "P6", "P7" + name 'SEQUENCE' + values 'P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7' } } stages { - stage("Run") { - steps { - container('zentao') { - sh 'initdb.php config' - sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest ${SEQUENCE} | tee /apps/zentao/test/${SEQUENCE}.log' - sh 'pipeline-unittest.sh /apps/zentao/test/${SEQUENCE}.log' - } - } + stage('Run') { + steps { + container('zentao') { + sh 'initdb.php config' + sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest ${SEQUENCE} | tee /apps/zentao/test/${SEQUENCE}.log' + sh 'pipeline-unittest.sh /apps/zentao/test/${SEQUENCE}.log' + } + } } } } - post{ - success{ + post { + success { container('xuanimbot') { sh 'git config --global --add safe.directory /home/jenkins/agent/workspace/pangu_pangu_xuanimbot_master' sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test passed" --debug --custom' } } - failure{ + failure { container('xuanimbot') { sh 'git config --global --add safe.directory $(pwd)' sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test failed" --debug --custom' @@ -158,8 +157,9 @@ pipeline { } } }//End unittest + } } } - } + }// quality scan } // End Root Stages } // End pipeline From 9c558abe87f510c0e07545191489ec4c446a5649 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 8 May 2023 10:37:07 +0800 Subject: [PATCH 18/33] * Refactoer task-manageTaskTeam. --- module/task/control.php | 2 +- module/task/model.php | 94 ++++++------------- module/task/tao.php | 75 ++++++++++++++- .../test/tao/removecreaterequiredfields.php | 1 - module/task/zen.php | 2 + 5 files changed, 102 insertions(+), 72 deletions(-) diff --git a/module/task/control.php b/module/task/control.php index 5e59077bf8..bcffece62e 100755 --- a/module/task/control.php +++ b/module/task/control.php @@ -73,7 +73,7 @@ class task extends control if($existTaskID) return $this->send(array('result' => 'success', 'message' => sprintf($this->lang->duplicate, $this->lang->task->common), 'locate' => $this->createLink('task', 'view', "taskID={$existTaskID}"))); /* Create task. */ - $taskIdList = $this->task->create($task, $this->post->assignedTo, (int)$this->post->multiple, $this->post->team, (bool)$this->post->selectTestStory); + $taskIdList = $this->task->create($task, $this->post->assignedTo, (int)$this->post->multiple, $this->post->team, (bool)$this->post->selectTestStory, $this->post->teamSource, $this->post->teamEstimate, $this->post->teamConsumed, $this->post->teamLeft); if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); /* Update other data related to the task after it is created. */ diff --git a/module/task/model.php b/module/task/model.php index 62b6a5e667..16eef621d6 100755 --- a/module/task/model.php +++ b/module/task/model.php @@ -543,81 +543,44 @@ class taskModel extends model /** * Manage multi task team members. * - * @param string $mode - * @param int $taskID - * @param string $taskStatus + * @param string $mode + * @param object $taskID + * @param array $teamList + * @param array $teamSourceList + * @param array $teamEstimateList + * @param array $teamConsumedList + * @param array $teamLeftList * @access public * @return array */ - public function manageTaskTeam($mode, $taskID, $taskStatus) + public function manageTaskTeam(string $mode, object $task, array $teamList, array $teamSourceList, array $teamEstimateList, array $teamConsumedList, array $teamLeftList): array { - $oldTeams = $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->fetchAll(); + /* Get old team member, and delete old task team. */ + $oldTeams = $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->eq($task->id)->fetchAll(); $oldMembers = array_map(function($team){return $team->account;}, $oldTeams); + $this->dao->delete()->from(TABLE_TASKTEAM)->where('task')->eq($task->id)->exec(); - $this->dao->delete()->from(TABLE_TASKTEAM)->where('task')->eq($taskID)->exec(); - - if($taskStatus == 'doing') + /* If status of the task is doing, get the person who did not complete the task. */ + if($task->status == 'doing') { - $efforts = $this->getTaskEfforts($taskID); - $doingUsers = array(); + $efforts = $this->getTaskEfforts($task->id); + $undoneUsers = array(); foreach($efforts as $effort) { - if($effort->left != 0) $doingUsers[$effort->account] = $effort->account; - if($effort->left == 0) unset($doingUsers[$effort->account]); + if($effort->left != 0) $undoneUsers[$effort->account] = $effort->account; + if($effort->left == 0) unset($undoneUsers[$effort->account]); } } $teams = array(); $minStatus = 'done'; $changeUsers = array(); - foreach($this->post->team as $row => $account) + foreach($teamList as $row => $account) { if(empty($account)) continue; - $teamSource = $this->post->teamSource[$row]; - $member = new stdClass(); - $member->task = $taskID; - $member->order = $row; - $member->account = $account; - $member->estimate = zget($this->post->teamEstimate, $row, 0); - $member->consumed = $this->post->teamConsumed ? zget($this->post->teamConsumed, $row, 0) : 0; - $member->left = $this->post->teamLeft ? zget($this->post->teamLeft, $row, 0) : 0; - $member->status = 'wait'; - if($taskStatus == 'wait' and $member->estimate > 0 and $member->left == 0) $member->left = $member->estimate; - if($taskStatus == 'done') $member->left = 0; - - if($member->left == 0 and $member->consumed > 0) - { - $member->status = 'done'; - } - elseif($taskStatus == 'doing') - { - if(!empty($teamSource) and $teamSource != $account and isset($doingUsers[$teamSource])) $member->transfer = $teamSource; - if(isset($doingUsers[$account]) and ($mode == 'multi' or ($mode == 'linear' and $minStatus != 'wait'))) $member->status = 'doing'; - } - if($minStatus != 'wait' and $member->status == 'doing') $minStatus = 'doing'; - if($member->status == 'wait') $minStatus = 'wait'; - - /* Doing status is only one in linear task. */ - if($mode == 'linear' and $member->status == 'doing') $minStatus = 'wait'; - if($member->status == 'wait') $minStatus = 'wait'; - if($minStatus != 'wait' and $member->status == 'doing') $minStatus = 'doing'; - - /* Insert or update team. */ - if($mode == 'multi' and isset($teams[$account])) - { - $this->dao->update(TABLE_TASKTEAM) - ->beginIF($member->estimate)->set("estimate= estimate + {$member->estimate}")->fi() - ->beginIF($member->left)->set("`left` = `left` + {$member->left}")->fi() - ->beginIF($member->consumed)->set("`consumed` = `consumed` + {$member->consumed}")->fi() - ->where('task')->eq($member->task) - ->andWhere('account')->eq($member->account) - ->exec(); - } - else - { - $this->dao->insert(TABLE_TASKTEAM)->data($member)->autoCheck()->exec(); - } + /* Manage task team member. */ + $minStatus = $this->taskTao->manageTaskTeamMember(string $mode, object $task, int $row, string $account, string $minStatus, array $undoneUsers, array $teamSourceList, array $teamEstimateList, array $teamConsumedList, array $teamLeftList, isset($teams[$account])); /* Set effort left = 0 when linear task members be changed. */ if($mode == 'linear' and isset($oldTeams[$row]) and $oldTeams[$row]->account != $account) $changeUsers[] = $oldTeams[$row]->account; @@ -631,7 +594,7 @@ class taskModel extends model $removedMembers = array_diff($oldMembers, $teams); $changeUsers = array_merge($changeUsers, $removedMembers); } - if($changeUsers) $this->resetEffortLeft($taskID, $changeUsers); + if($changeUsers) $this->resetEffortLeft($task->id, $changeUsers); return $teams; } @@ -3902,13 +3865,13 @@ class taskModel extends model } /** - * 创建任务后的其他数据处理。 + * 创建任务后的其他数据处理。 * Other data processing after task creation. - * - * @param object $task - * @param array $taskIdList - * @param int $bugID - * @param object $rawData + * + * @param object $task + * @param array $taskIdList + * @param int $bugID + * @param object $rawData * @access public * @return bool */ @@ -3950,7 +3913,7 @@ class taskModel extends model /* If the current task has test subtasks, create test subtasks and update the task information. */ if(!empty($testTasks)) { - $this->taskTao->createTestChildTasks($taskID, $testTasks); + $this->createTestChildTasks($taskID, $testTasks); $this->computeWorkingHours($taskID); $this->computeBeginAndEnd($taskID); $this->dao->update(TABLE_TASK)->set('`parent`')->eq(-1)->where('id')->eq($taskID)->exec(); @@ -3961,7 +3924,6 @@ class taskModel extends model $this->file->updateObjectID($this->post->uid, $taskID, 'task'); $this->score->create('task', 'create', $taskID); } - return true; } diff --git a/module/task/tao.php b/module/task/tao.php index b700df1209..22a05706cb 100644 --- a/module/task/tao.php +++ b/module/task/tao.php @@ -14,9 +14,9 @@ class taskTao extends taskModel { /** * 创建一个任务。 - * Create a task. - * - * @param object $task + * Create a task. + * + * @param object $task * @access protected * @return int|bool */ @@ -512,7 +512,7 @@ class taskTao extends taskModel /** * 批量创建前检查必填项 * Check required fields before batch create tasks. - * + * * @param object $execution * @param object[] $data * @access protected @@ -608,4 +608,71 @@ class taskTao extends taskModel $task->lastEditedDate = helper::now(); $this->dao->update(TABLE_TASK)->data($task)->where('id')->eq($parentID)->exec(); } + + /** + * Manage multi task team member. + * + * @param string $mode + * @param object $task + * @param int $row + * @param string $account + * @param string $minStatus + * @param array $undoneUsers + * @param array $teamSourceList + * @param array $teamEstimateList + * @param array $teamConsumedList + * @param array $teamLeftList + * @param bool $inTeams + * @access protected + * @return string + */ + protected function manageTaskTeamMember(string $mode, object $task, int $row, string $account, string $minStatus, array $undoneUsers, array $teamSourceList, array $teamEstimateList, array $teamConsumedList, array $teamLeftList, bool $inTeams): string + { + /* Set member information. */ + $member = new stdClass(); + $member->task = $task->id; + $member->order = $row; + $member->account = $account; + $member->estimate = zget($teamEstimateList, $row, 0); + $member->consumed = $teamConsumedList ? zget($teamConsumedList, $row, 0) : 0; + $member->left = $teamLeftList ? zget($teamLeftList, $row, 0) : 0; + $member->status = 'wait'; + if($task->status == 'wait' and $member->estimate > 0 and $member->left == 0) $member->left = $member->estimate; + if($task->status == 'done') $member->left = 0; + + /* Compute task status of member. */ + if($member->left == 0 and $member->consumed > 0) + { + $member->status = 'done'; + } + elseif($task->status == 'doing') + { + $teamSource = $teamSourceList[$row]; + + if(!empty($teamSource) and $teamSource != $account and isset($undoneUsers[$teamSource])) $member->transfer = $teamSource; + if(isset($undoneUsers[$account]) and ($mode == 'multi' or ($mode == 'linear' and $minStatus != 'wait'))) $member->status = 'doing'; + } + + /* Compute multi-task status, and in a linear task, there is only one doing status. */ + if(($mode == 'linear' and $member->status == 'doing') or $member->status == 'wait') $minStatus = 'wait'; + if($minStatus != 'wait' and $member->status == 'doing') $minStatus = 'doing'; + + /* Insert or update team. */ + if($mode == 'multi' and $inTeams) + { + $this->dao->update(TABLE_TASKTEAM) + ->beginIF($member->estimate)->set("estimate= estimate + {$member->estimate}")->fi() + ->beginIF($member->left)->set("`left` = `left` + {$member->left}")->fi() + ->beginIF($member->consumed)->set("`consumed` = `consumed` + {$member->consumed}")->fi() + ->where('task')->eq($member->task) + ->andWhere('account')->eq($member->account) + ->exec(); + } + else + { + $this->dao->insert(TABLE_TASKTEAM)->data($member)->autoCheck()->exec(); + } + + return $minStatus; + } } diff --git a/module/task/test/tao/removecreaterequiredfields.php b/module/task/test/tao/removecreaterequiredfields.php index 0fc2d4fb32..7fd9a53e30 100755 --- a/module/task/test/tao/removecreaterequiredfields.php +++ b/module/task/test/tao/removecreaterequiredfields.php @@ -14,7 +14,6 @@ for($i = 0; $i < 18; $i ++) if($i < 9) $tasks[$i]->type = 'dev'; if($i >= 9) $tasks[$i]->type = 'test'; } -global $tester; /** diff --git a/module/task/zen.php b/module/task/zen.php index a286ceafbd..19a97048f7 100644 --- a/module/task/zen.php +++ b/module/task/zen.php @@ -478,6 +478,8 @@ class taskZen extends task ->stripTags($this->config->task->editor->create['id'], $this->config->allowedTags) ->join('mailto', ',') ->get(); + if(empty($formData->estStarted)) unset($task->estStarted); + if(empty($formData->deadline)) unset($task->deadline); /* Processing image link. */ return $this->loadModel('file')->processImgURL($task, $this->config->task->editor->create['id'], $rawData->uid); From 0a6d3e57b3d407d1ace55e376be27c42df6a14a1 Mon Sep 17 00:00:00 2001 From: liyang Date: Mon, 8 May 2023 10:39:48 +0800 Subject: [PATCH 19/33] * revert jenkinsfile. --- Jenkinsfile | 232 ++++++++++++++++++++++++++-------------------------- 1 file changed, 116 insertions(+), 116 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 987218dfd6..c784fd6c56 100755 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -27,139 +27,139 @@ pipeline { } } - stage('quality scan') { + stage('Sonar Scanner') { parallel { - stage('Sonar Qube') { + stage('SonarQube') { steps { container('sonar') { - withSonarQubeEnv('sonarqube') { - sh 'git config --global --add safe.directory $(pwd)' - sh 'sonar-scanner -Dsonar.analysis.user=$(git show -s --format=%an)' - } + withSonarQubeEnv('sonarqube') { + sh 'git config --global --add safe.directory $(pwd)' + sh 'sonar-scanner -Dsonar.analysis.user=$(git show -s --format=%an)' + } } } post { success { - container('xuanimbot') { - sh 'git config --global --add safe.directory $(pwd)' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "sonar scanner" --url "https://sonar.qc.oop.cc/dashboard?id=zentaopms&branch=${GIT_BRANCH}" --content "sonar scanner success" --debug --custom' - } + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "sonar scanner" --url "https://sonar.qc.oop.cc/dashboard?id=zentaopms&branch=${GIT_BRANCH}" --content "sonar scanner success" --debug --custom' + } } failure { - container('xuanimbot') { - sh 'git config --global --add safe.directory $(pwd)' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "sonar scanner" --url "https://sonar.qc.oop.cc/dashboard?id=zentaopms&branch=${GIT_BRANCH}" --content "sonar scanner failure" --debug --custom' - } + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "sonar scanner" --url "https://sonar.qc.oop.cc/dashboard?id=zentaopms&branch=${GIT_BRANCH}" --content "sonar scanner failure" --debug --custom' + } } } } - stage('Unit Test') { - stages { - stage('Build Image') { - steps { - container('docker') { - sh 'docker build --pull . -f Dockerfile.test --build-arg VERSION=${ZENTAO_VERSION} --build-arg MIRROR=true --build-arg MYSQL_HOST=${MYSQL_SERVER_HOST} --build-arg MYSQL_PASSWORD=${MYSQL_ROOT_PASSWORD} -t ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' - sh 'docker push ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' - } - } - post { - success { - echo 'build image success' - } - failure { - container('xuanimbot') { - sh 'git config --global --add safe.directory $(pwd)' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "build image" --url "${RUN_DISPLAY_URL}" --content "Build unit test image failure" --debug --custom' - } - } + stage('Build Image') { + steps { + container('docker') { + sh 'docker build --pull . -f Dockerfile.test --build-arg VERSION=${ZENTAO_VERSION} --build-arg MIRROR=true --build-arg MYSQL_HOST=${MYSQL_SERVER_HOST} --build-arg MYSQL_PASSWORD=${MYSQL_ROOT_PASSWORD} -t ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' + sh 'docker push ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' + } + } + post { + success { + echo 'build image success' + } + failure { + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "build image" --url "${RUN_DISPLAY_URL}" --content "Build unit test image failure" --debug --custom' } } - - stage('Init') { - agent { - kubernetes { - inheritFrom 'xuanim' - containerTemplate { - name 'zentao' - image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" - command 'sleep' - args '99d' - } - } - } - options { skipDefaultCheckout() } - - steps { - container('zentao') { - sh 'cat /usr/bin/initdb.php; initdb.php ; /apps/zentao/test/ztest init' - } - } - post { - success { - sh 'echo "stage unit init success"' - } - failure { - container('xuanimbot') { - sh 'git config --global --add safe.directory $(pwd)' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest init" --url "${RUN_DISPLAY_URL}" --content "Unit test database initialization failed" --debug --custom' - } - } - } - } - - stage('Run') { - matrix { - agent { - kubernetes { - inheritFrom 'xuanim' - containerTemplate { - name 'zentao' - image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" - command 'sleep' - args '99d' - } - } - } - - options { skipDefaultCheckout() } - - axes { - axis { - name 'SEQUENCE' - values 'P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7' - } - } - stages { - stage('Run') { - steps { - container('zentao') { - sh 'initdb.php config' - sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest ${SEQUENCE} | tee /apps/zentao/test/${SEQUENCE}.log' - sh 'pipeline-unittest.sh /apps/zentao/test/${SEQUENCE}.log' - } - } - } - } - } - post { - success { - container('xuanimbot') { - sh 'git config --global --add safe.directory /home/jenkins/agent/workspace/pangu_pangu_xuanimbot_master' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test passed" --debug --custom' - } - } - failure { - container('xuanimbot') { - sh 'git config --global --add safe.directory $(pwd)' - sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test failed" --debug --custom' - } - } - } - }//End unittest } } } - }// quality scan + } + + stage('Unit Test') { + stages { + stage('Init') { + agent { + kubernetes { + inheritFrom 'xuanim' + containerTemplate { + name 'zentao' + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command 'sleep' + args '99d' + } + } + } + options { skipDefaultCheckout() } + + steps { + container('zentao') { + sh 'cat /usr/bin/initdb.php; initdb.php ; /apps/zentao/test/ztest init' + } + } + post { + success { + sh 'echo "stage unit init success"' + } + failure { + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest init" --url "${RUN_DISPLAY_URL}" --content "Unit test database initialization failed" --debug --custom' + } + } + } + } + + stage('Run') { + matrix { + agent { + kubernetes { + inheritFrom 'xuanim' + containerTemplate { + name 'zentao' + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command 'sleep' + args '99d' + } + } + } + + options { skipDefaultCheckout() } + + axes { + axis { + name 'SEQUENCE' + values 'P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7' + } + } + stages { + stage('Run') { + steps { + container('zentao') { + sh 'initdb.php config' + sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest ${SEQUENCE} | tee /apps/zentao/test/${SEQUENCE}.log' + sh 'pipeline-unittest.sh /apps/zentao/test/${SEQUENCE}.log' + } + } + } + } + } + post { + success { + container('xuanimbot') { + sh 'git config --global --add safe.directory /home/jenkins/agent/workspace/pangu_pangu_xuanimbot_master' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test passed" --debug --custom' + } + } + failure { + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%an)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test failed" --debug --custom' + } + } + } + }//End unittest + } + } } // End Root Stages } // End pipeline From ef292185e786e58ede204de06208edb361917b41 Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 8 May 2023 10:45:38 +0800 Subject: [PATCH 20/33] * refactor the a() method, support multi vars and return count of vars to fix sonar wrong judgment --- framework/base/helper.class.php | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/framework/base/helper.class.php b/framework/base/helper.class.php index 550192b768..5c4e6b6429 100644 --- a/framework/base/helper.class.php +++ b/framework/base/helper.class.php @@ -841,17 +841,23 @@ function getTime() } /** - * 打印变量的信息 - * dump a var. + * 打印变量的信息,支持传入多个变量信息。 + * dump a var, support multi vars. * * @access public - * @return void + * @param mixed ...$vars the vars to be dumped. + * @return int return the count of vars. */ -function a($var) +function a(): int { - echo ""; - print_r($var); - echo ""; + $vars = func_get_args(); + foreach($vars as $var) + { + echo "
";
+        print_r($var);
+        echo "
"; + } + return count($vars); } /** From c2000637f18482676b9c7333f8c59417ebf4a18b Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 8 May 2023 10:54:52 +0800 Subject: [PATCH 21/33] * Fix bug of task-manageTaskTeam. --- module/task/model.php | 18 +++++++++--------- module/task/tao.php | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/module/task/model.php b/module/task/model.php index 16eef621d6..25037bec25 100755 --- a/module/task/model.php +++ b/module/task/model.php @@ -543,17 +543,17 @@ class taskModel extends model /** * Manage multi task team members. * - * @param string $mode - * @param object $taskID - * @param array $teamList - * @param array $teamSourceList - * @param array $teamEstimateList - * @param array $teamConsumedList - * @param array $teamLeftList + * @param string $mode + * @param object $taskID + * @param array $teamList + * @param array $teamSourceList + * @param array $teamEstimateList + * @param array|bool $teamConsumedList + * @param array|bool $teamLeftList * @access public * @return array */ - public function manageTaskTeam(string $mode, object $task, array $teamList, array $teamSourceList, array $teamEstimateList, array $teamConsumedList, array $teamLeftList): array + public function manageTaskTeam(string $mode, object $task, array $teamList, array $teamSourceList, array $teamEstimateList, array|bool $teamConsumedList, array|bool $teamLeftList): array { /* Get old team member, and delete old task team. */ $oldTeams = $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->eq($task->id)->fetchAll(); @@ -580,7 +580,7 @@ class taskModel extends model if(empty($account)) continue; /* Manage task team member. */ - $minStatus = $this->taskTao->manageTaskTeamMember(string $mode, object $task, int $row, string $account, string $minStatus, array $undoneUsers, array $teamSourceList, array $teamEstimateList, array $teamConsumedList, array $teamLeftList, isset($teams[$account])); + $minStatus = $this->taskTao->manageTaskTeamMember($mode, $task, $row, $account, $minStatus, $undoneUsers, $teamSourceList, $teamEstimateList, $teamConsumedList, $teamLeftList, isset($teams[$account])); /* Set effort left = 0 when linear task members be changed. */ if($mode == 'linear' and isset($oldTeams[$row]) and $oldTeams[$row]->account != $account) $changeUsers[] = $oldTeams[$row]->account; diff --git a/module/task/tao.php b/module/task/tao.php index 22a05706cb..ddd628665f 100644 --- a/module/task/tao.php +++ b/module/task/tao.php @@ -612,21 +612,21 @@ class taskTao extends taskModel /** * Manage multi task team member. * - * @param string $mode - * @param object $task - * @param int $row - * @param string $account - * @param string $minStatus - * @param array $undoneUsers - * @param array $teamSourceList - * @param array $teamEstimateList - * @param array $teamConsumedList - * @param array $teamLeftList - * @param bool $inTeams + * @param string $mode + * @param object $task + * @param int $row + * @param string $account + * @param string $minStatus + * @param array $undoneUsers + * @param array $teamSourceList + * @param array $teamEstimateList + * @param array|bool $teamConsumedList + * @param array|bool $teamLeftList + * @param bool $inTeams * @access protected * @return string */ - protected function manageTaskTeamMember(string $mode, object $task, int $row, string $account, string $minStatus, array $undoneUsers, array $teamSourceList, array $teamEstimateList, array $teamConsumedList, array $teamLeftList, bool $inTeams): string + protected function manageTaskTeamMember(string $mode, object $task, int $row, string $account, string $minStatus, array $undoneUsers, array $teamSourceList, array $teamEstimateList, array|bool $teamConsumedList, array|bool $teamLeftList, bool $inTeams): string { /* Set member information. */ $member = new stdClass(); From 5fedf3e02c23fa9267a5b9db1d95fe56631c3130 Mon Sep 17 00:00:00 2001 From: sunhao Date: Mon, 8 May 2023 11:01:09 +0800 Subject: [PATCH 22/33] * zin: refactor "static" keyword instead of "self". --- lib/zin/core/wg.class.php | 2 +- lib/zin/core/zin.class.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/zin/core/wg.class.php b/lib/zin/core/wg.class.php index 0f8ae6077e..d661ba8d2f 100644 --- a/lib/zin/core/wg.class.php +++ b/lib/zin/core/wg.class.php @@ -64,7 +64,7 @@ class wg { $this->props = new props(); - $this->gid = self::nextGid(); + $this->gid = static::nextGid(); $this->setDefaultProps(static::getDefaultProps()); $this->add(func_get_args()); $this->created(); diff --git a/lib/zin/core/zin.class.php b/lib/zin/core/zin.class.php index 61cb210a55..6417b47bc4 100644 --- a/lib/zin/core/zin.class.php +++ b/lib/zin/core/zin.class.php @@ -25,28 +25,28 @@ class zin public static function getData($namePath, $defaultValue = NULL) { - return \zin\utils\deepGet(self::$data, $namePath, $defaultValue); + return \zin\utils\deepGet(static::$data, $namePath, $defaultValue); } public static function setData($namePath, $value) { - \zin\utils\deepSet(self::$data, $namePath, $value); + \zin\utils\deepSet(static::$data, $namePath, $value); } public static function enableGlobalRender() { - self::$enabledGlobalRender = true; + static::$enabledGlobalRender = true; } public static function disableGlobalRender() { - self::$enabledGlobalRender = false; + static::$enabledGlobalRender = false; } public static function renderInGlobal() { - if(!self::$enabledGlobalRender) return false; + if(!static::$enabledGlobalRender) return false; - self::$globalRenderList = array_merge(self::$globalRenderList, func_get_args()); + static::$globalRenderList = array_merge(static::$globalRenderList, func_get_args()); } } From 4f852d7641afe64b196cf8190b628dc2ba119a05 Mon Sep 17 00:00:00 2001 From: Guanxiying Date: Mon, 8 May 2023 11:03:30 +0800 Subject: [PATCH 23/33] * Fix code smell of $$statusVar. --- module/execution/model.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/module/execution/model.php b/module/execution/model.php index 5a3b2cef7e..862121cec9 100755 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -4334,34 +4334,37 @@ class executionModel extends model */ public function summary($tasks) { - $taskSum = $statusWait = $statusDone = $statusDoing = $statusClosed = $statusCancel = $statusPause = 0; + $taskSum = 0; $totalEstimate = $totalConsumed = $totalLeft = 0.0; + $summations = array(); + $this->app->loadLang('task'); + /* 当前只需要显示wait 和 doing 状态,但是从代码分析将来可能需要统计其他状态的,所以取全部状态。 */ + foreach($this->lang->task->statusList as $statusCode => $statusName) $summations[$statusCode] = 0; + foreach($tasks as $task) { if(!isset($tasks[$task->parent]) or $task->parent <= 0) { - $totalEstimate += $task->estimate; - $totalConsumed += $task->consumed; + $totalEstimate += $task->estimate; + $totalConsumed += $task->consumed; if($task->status != 'cancel' and $task->status != 'closed') $totalLeft += $task->left; } - $statusVar = 'status' . ucfirst($task->status); - $$statusVar ++; + if(isset($summations[$task->status])) $summations[$task->status] ++; if(isset($task->children)) { - foreach($task->children as $children) + foreach($task->children as $child) { - $statusVar = 'status' . ucfirst($children->status); - $$statusVar ++; + if(isset($summations[$child->status])) $summations[$child->status] ++; $taskSum ++; } } $taskSum ++; } - return sprintf($this->lang->execution->taskSummary, $taskSum, $statusWait, $statusDoing, round($totalEstimate, 1), round($totalConsumed, 1), round($totalLeft, 1)); + return sprintf($this->lang->execution->taskSummary, $taskSum, $summations['wait'], $summations['doing'], round($totalEstimate, 1), round($totalConsumed, 1), round($totalLeft, 1)); } /** From e6b85b927e1ebc84c276fac499f4f3fc854ed369 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Mon, 8 May 2023 11:05:06 +0800 Subject: [PATCH 24/33] * Modify test case. --- module/execution/model.php | 2 -- module/project/test/project.class.php | 18 ++++++++++++ module/project/test/tao/createproduct.php | 34 +++++++++++------------ 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/module/execution/model.php b/module/execution/model.php index 5a3b2cef7e..bc05d638ce 100755 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -1767,7 +1767,6 @@ class executionModel extends model ->andWhere('vision')->eq($this->config->vision) ->beginIF($type == 'all')->andWhere('type')->in('sprint,stage,kanban')->fi() ->beginIF($type != 'all')->andWhere('type')->eq($type)->fi() - ->beginIF($projectID)->andWhere('project')->eq($projectID)->fi() ->beginIF($status == 'undone')->andWhere('status')->notIN('done,closed')->fi() ->beginIF($status != 'all' and $status != 'undone')->andWhere('status')->in($status)->fi() ->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->sprints)->fi() @@ -1820,7 +1819,6 @@ class executionModel extends model ->orWhere('t2.account')->eq($this->app->user->account) ->markRight(1) ->andWhere('t1.type')->in('sprint,stage,kanban') - ->beginIF($projectID)->andWhere('t1.project')->eq($projectID)->fi() ->orderBy('t1.order_desc') ->beginIF($limit)->limit($limit)->fi() ->fetchAll('id'); diff --git a/module/project/test/project.class.php b/module/project/test/project.class.php index 05aa216d19..238a34e4f3 100644 --- a/module/project/test/project.class.php +++ b/module/project/test/project.class.php @@ -252,4 +252,22 @@ class Project $projects = $this->project->fetchProjectListByQuery($queryType, $param, $orderBy, 15, ''); return $projects; } + + /** + * testCreateProduct + * + * @param int $projectID + * @param object $project + * @param object $postData + * @param object $program + * @access public + * @return string|array + */ + public function testCreateProduct($projectID, $project, $postData, $program) + { + $result = $this->project->createProduct($projectID, $project, $postData, $program); + if(!$result) return dao::getError(); + + return '1'; + } } diff --git a/module/project/test/tao/createproduct.php b/module/project/test/tao/createproduct.php index c39df607c9..442cabed7b 100755 --- a/module/project/test/tao/createproduct.php +++ b/module/project/test/tao/createproduct.php @@ -12,24 +12,15 @@ $program->code->range('项目集代号'); $program->desc->range('测试项目集'); $program->gen(1); +zdTable('team')->gen(0); +zdTable('product')->gen(0); + /** title=测试 projectModel->create(); timeout=0 cid=1 -- 执行projectClass模块的create方法,参数是$normalProject, $postData属性name @测试新增项目一 - -- 执行projectClass模块的create方法,参数是$emptyNameProject, $postData @『项目名称』不能为空。 - -- 执行projectClass模块的create方法,参数是$emptyEndProject, $postData @『计划完成』不能为空。 - -- 执行projectClass模块的create方法,参数是$beginGtEndProject, $postData @『计划完成』应当大于『2022-02-07』。 - -- 执行projectClass模块的create方法,参数是$emptyBeginProject, $postData @『计划开始』不能为空。 - - - */ global $tester; @@ -54,16 +45,23 @@ $project->hasProduct = 1; $project->openedBy = 'admin'; $project->openedDate = '2023-01-01'; +$emptyNameProject = clone $project; +unset($emptyNameProject->name); + +$hasProductProject = clone $project; +$hasProductProject->hasProduct = 1; +$hasProductProject->name = '测试新增产品一'; + $postData = new stdclass(); $postData->rawdata = clone $project; $postData->rawdata->uid = '64dda2xc'; $postData->rawdata->delta = 0; $postData->rawdata->products = array(1); -$projectID = $projectClass->create($normalProject, $postData); +$project = $projectClass->create($project, $postData); +$projectID = $project->id; -r($projectClass->createProduct($projectID, $project, $postData, $program)) && p('name') && e('测试新增项目一'); -//r($projectClass->createProduct($emptyNameProject, $postData)) && p('message[name]:0') && e('『项目名称』不能为空。'); -//r($projectClass->createProduct($emptyEndProject, $postData)) && p('message[end]:0') && e('『计划完成』不能为空。'); -//r($projectClass->createProduct($beginGtEndProject, $postData)) && p('message[end]:0') && e('『计划完成』应当大于『2022-02-07』。'); -//r($projectClass->createProduct($emptyBeginProject, $postData)) && p('message[begin]:0') && e('『计划开始』不能为空。'); +r($projectClass->testCreateProduct($projectID, $project, $postData, $program)) && p() && e('1'); +r($projectClass->testCreateProduct($projectID, $emptyNameProject, $postData, $program)) && p('name:0') && e('『产品名称』不能为空。'); +r($projectClass->testCreateProduct($projectID, $project, $postData, $program)) && p('name:0') && e('『产品名称』已经有『测试新增项目一』这条记录了。'); +r($projectClass->testCreateProduct($projectID, $hasProductProject, $postData, $program)) && p() && e('1'); From 0e30961651af96edf0be9724a49cbf6d5179bcb4 Mon Sep 17 00:00:00 2001 From: xushenjie Date: Mon, 8 May 2023 03:06:36 +0000 Subject: [PATCH 25/33] + Added the unit test script of todoTao::buildCycleTodo() method. --- module/todo/test/tao/buildcycletodo.php | 30 ++++++++++++++++ .../yaml/buildcycletodo/buildcycletodo.yaml | 36 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100755 module/todo/test/tao/buildcycletodo.php create mode 100644 module/todo/test/tao/yaml/buildcycletodo/buildcycletodo.yaml diff --git a/module/todo/test/tao/buildcycletodo.php b/module/todo/test/tao/buildcycletodo.php new file mode 100755 index 0000000000..b2d9f2e7fe --- /dev/null +++ b/module/todo/test/tao/buildcycletodo.php @@ -0,0 +1,30 @@ +#!/usr/bin/env php +config('buildcycletodo')->gen(5); +} + +/** + +title=测试 todoTao::buildCycleTodo(); +timeout=0 +cid=1 + +- 执行todo模块的buildCycleTodo方法,参数是$todo + - 属性name @我的待办 + - 属性type @cycle + - 属性status @wait + +*/ + +initData(); + +global $tester; +$tester->loadModel('todo'); +$todo = $tester->todo->getByID(1); + +r($tester->todo->buildCycleTodo($todo)) && p('name,type,status') && e('我的待办,cycle,wait'); diff --git a/module/todo/test/tao/yaml/buildcycletodo/buildcycletodo.yaml b/module/todo/test/tao/yaml/buildcycletodo/buildcycletodo.yaml new file mode 100644 index 0000000000..0e201a83f7 --- /dev/null +++ b/module/todo/test/tao/yaml/buildcycletodo/buildcycletodo.yaml @@ -0,0 +1,36 @@ +title: buildcycletodo +author: xushenjie +version: "1.0" +fields: + - field: id + range: 1-100 + - field: account + range: 'admin' + - field: name + range: '我的待办' + - field: date + range: 1-9 + prefix: '2023-04-2' + - field: begin + range: 1000-1100 + - field: end + range: 1200-1300 + - field: type + range: 'custom' + - field: cycle + range: 0 + - field: pri + range: 3 + - field: desc + range: 1-5 + prefix: '这是待办描述' + - field: status + range: 'wait,doing,done' + - field: vision + range: 'rnd,litle' + - field: finishedDate + range: 1-9 + prefix: '2023-04-2' + - field: closedDate + range: 1-9 + prefix: '2023-04-2' From 90529a68fee4c23ceec275d994f9691b1867529e Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Mon, 8 May 2023 11:10:51 +0800 Subject: [PATCH 26/33] * Modify dao error and page style. --- module/project/model.php | 5 ++++- module/project/tao.php | 12 ++++++++++-- module/project/ui/create.html.php | 13 +++++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/module/project/model.php b/module/project/model.php index 8222494957..16d3c05fd4 100755 --- a/module/project/model.php +++ b/module/project/model.php @@ -1226,7 +1226,10 @@ class projectModel extends model /* If $_POST has product name, create it. */ $linkedProductsCount = $this->projectTao->getLinkedProductsCount($project, $postData->rawdata); - if(!$project->hasProduct or isset($postData->rawdata->newProduct) or (!$project->parent and empty($linkedProductsCount))) $this->createProduct($projectID, $project, $postData, $program); + if(!$project->hasProduct or isset($postData->rawdata->newProduct) or (!$project->parent and empty($linkedProductsCount))) + { + if(!$this->createProduct($projectID, $project, $postData, $program)) return false; + } /* Save order. */ $this->dao->update(TABLE_PROJECT)->set('`order`')->eq($projectID * 5)->where('id')->eq($projectID)->exec(); diff --git a/module/project/tao.php b/module/project/tao.php index f13ad36510..5309562ff8 100755 --- a/module/project/tao.php +++ b/module/project/tao.php @@ -215,6 +215,8 @@ class projectTao extends projectModel */ protected function setProjectTeam(int $projectID, object $project, object $postData): array { + $this->loadModel('execution'); + /* Set team of project. */ $members = isset($postData->rawdata->teamMembers) ? $postData->rawdata->teamMembers : array(); array_push($members, $project->PM, $project->openedBy); @@ -304,7 +306,7 @@ class projectTao extends projectModel { /* If parent not empty, link products or create products. */ $product = new stdclass(); - $product->name = $project->hasProduct && $postData->rawdata->productName ? $postData->rawdata->productName : $project->name; + $product->name = $project->hasProduct && !empty($postData->rawdata->productName) ? $postData->rawdata->productName : zget($project, 'name', ''); $product->shadow = zget($project, 'vision', 'rnd') == 'rnd' ? (int)empty($project->hasProduct) : 1; $product->bind = $postData->rawdata->parent ? 0 : 1; $product->program = $project->parent ? current(array_filter(explode(',', $program->path))) : 0; @@ -321,7 +323,13 @@ class projectTao extends projectModel $product->createdVersion = $this->config->version; $product->vision = zget($project, 'vision', 'rnd'); - $this->dao->insert(TABLE_PRODUCT)->data($product)->exec(); + $this->app->loadConfig('product'); + $this->dao->insert(TABLE_PRODUCT)->data($product) + ->batchCheck($this->config->product->create->requiredFields, 'notempty') + ->checkIF(!empty($product->name), 'name', 'unique', "`program` = {$product->program} and `deleted` = '0'") + ->exec(); + if(dao::isError()) return false; + $productID = $this->dao->lastInsertId(); if(!$project->hasProduct) $this->loadModel('personnel')->updateWhitelist($whitelist, 'product', $productID); $this->loadModel('action')->create('product', $productID, 'opened'); diff --git a/module/project/ui/create.html.php b/module/project/ui/create.html.php index f213abafc6..828143061c 100644 --- a/module/project/ui/create.html.php +++ b/module/project/ui/create.html.php @@ -9,7 +9,7 @@ foreach($lang->project->modelList as $key => $text) $projectModelItems[] = array ( 'active' => ($key == $model), - 'url' => '', + 'url' => $this->createLink("project", "create", "model=$key&programID=$programID©ProjectID=0&extra=productID=$productID,branchID=$branchID"), 'text' => $text, 'data-type' => 'ajax' ); @@ -110,12 +110,16 @@ formPanel set::seg(true), btn ( - setClass('primary-pale'), + setClass('primary-pale project-type-1'), + on::click('changeType(1)'), $lang->project->projectTypeList[1] ), - btn($lang->project->projectTypeList[0]) + btn( + setClass('project-type-0'), + on::click('changeType(0)'), + $lang->project->projectTypeList[0] + ) ), - /* TODO change value with button click event */ formHidden('hasProduct', 1) ), formGroup @@ -215,6 +219,7 @@ formPanel formGroup ( set::width('1/2'), + set('id', 'linkProduct'), set::label($lang->project->manageProducts), inputGroup ( From cacfce57c1482af5ac9a0227c93ba6963171bd1a Mon Sep 17 00:00:00 2001 From: Lufei Date: Mon, 8 May 2023 11:13:21 +0800 Subject: [PATCH 27/33] + Support make xhprof. --- Makefile | 14 +++++++++++--- framework/base/router.class.php | 8 ++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 61bf4d6b48..081ac8421a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ -VERSION = $(shell head -n 1 VERSION) -XUANVERSION = $(shell head -n 1 extension/xuanxuan/XUANVERSION) -XVERSION = $(shell head -n 1 extension/xuanxuan/XVERSION) +VERSION = $(shell head -n 1 VERSION) +XUANVERSION = $(shell head -n 1 extension/xuanxuan/XUANVERSION) +XVERSION = $(shell head -n 1 extension/xuanxuan/XVERSION) +XHPROF_VERSION = 2.3.9 XUANPATH := $(XUANXUAN_SRC_PATH) BUILD_PATH := $(if $(ZENTAO_BUILD_PATH),$(ZENTAO_BUILD_PATH),$(shell pwd)) @@ -345,3 +346,10 @@ ci: mv ZenTaoALM.$(VERSION).int.php*.zip ZenTaoPMS.$(VERSION).php*.zip $(RELEASE_PATH)/pmsPack mv *.deb $(RELEASE_PATH)/pmsPack/deb/ mv *.rpm $(RELEASE_PATH)/pmsPack/rpm/ +xhprof: + wget https://pecl.php.net/get/xhprof-$(XHPROF_VERSION).tgz + tar -zxvf xhprof-$(XHPROF_VERSION).tgz + rm -rf www/xhprof/xhprof_html www/xhprof/xhprof_lib + mkdir -p www/xhprof + mv xhprof-$(XHPROF_VERSION)/xhprof_html xhprof-$(XHPROF_VERSION)/xhprof_lib www/xhprof/ + rm -rf xhprof-$(XHPROF_VERSION)* package.xml diff --git a/framework/base/router.class.php b/framework/base/router.class.php index 9d64eea4be..6e0bb6f523 100644 --- a/framework/base/router.class.php +++ b/framework/base/router.class.php @@ -750,16 +750,12 @@ class baseRouter $outputDir = ini_get('xhprof.output_dir'); if(!is_dir($xhprofPath)) return false; + if(!$outputDir) $outputDir = $xhprofPath . DS . 'xhprof_runs'; + if(!is_dir($outputDir)) mkdir($outputDir, 0777, true); include_once $libUtilsPath . 'xhprof_lib.php'; include_once $libUtilsPath . 'xhprof_runs.php'; - if(!$outputDir) - { - $outputDir = $xhprofPath . DS . 'xhprof_runs'; - if(!is_dir($outputDir)) mkdir($outputDir, 0777, true); - } - $xhprofRuns = new \XHProfRuns_Default($outputDir); $type = "{$this->moduleName}_{$this->methodName}"; $runID = $xhprofRuns->save_run($log, $type); From c0511322e63aa10b4efa6cf3381d073ad1c9ef2f Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Mon, 8 May 2023 11:15:33 +0800 Subject: [PATCH 28/33] * Modify test case ignore comment line. --- test/lib/init.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lib/init.php b/test/lib/init.php index 8817f52152..653c7b5b23 100644 --- a/test/lib/init.php +++ b/test/lib/init.php @@ -74,7 +74,7 @@ $poolID = getenv('ZTF_POOL_ID'); $dbPool = empty($config->dbPool) ? array() : $config->dbPool; /* 根据ztf设置的poolID环境变量设置连接的数据库 */ -if(!empty($dbPool) && !empty($poolID)) +if(!empty($dbPool) && !empty($poolID)) { $selectDB = $dbPool[$poolID%count($dbPool)]; @@ -346,7 +346,7 @@ function genModuleAndMethod($rParams) */ function genParamsByRPE($rpe) { - preg_match_all("/r\((.*?)\)\s*&&\s*p\((.*?)\)\s*&&\s*e\((.*?)\);(.*)/", $rpe, $matches); + preg_match_all("/^r\((.*?)\)\s*&&\s*p\((.*?)\)\s*&&\s*e\((.*?)\);(.*)/", $rpe, $matches); $rParams = !empty($matches[1]) ? $matches[1] : array(); $pParams = !empty($matches[2]) ? $matches[2] : array(); $eParams = !empty($matches[3]) ? $matches[3] : array(); From 4bb7e6d32754a48405011fe33f461787ffe5ccde Mon Sep 17 00:00:00 2001 From: Wangyuting <851424971@qq.com> Date: Mon, 8 May 2023 11:23:39 +0800 Subject: [PATCH 29/33] * Optimize project statistic block code. --- .../block/ui/projectstatisticblock.html.php | 529 ++++++++++-------- 1 file changed, 298 insertions(+), 231 deletions(-) diff --git a/module/block/ui/projectstatisticblock.html.php b/module/block/ui/projectstatisticblock.html.php index 39dd54d3da..96a93ba55e 100644 --- a/module/block/ui/projectstatisticblock.html.php +++ b/module/block/ui/projectstatisticblock.html.php @@ -11,275 +11,342 @@ declare(strict_types=1); namespace zin; -$isChineseLang = in_array($this->app->getClientLang(), array('zh-cn','zh-tw')); -$blockNavID = 'nav-' . uniqid(); -$selected = key($projects); -$navTabs = array(); - -/* 展示左侧的项目列表。 */ -foreach($projects as $project) +/** + * 获取区块左侧的项目列表. + * Get project tabs on the left side. + * + * @param array $projects + * @param string $blockNavCode + * @access public + * @return array + */ +function getProjectTabs($projects, $blockNavCode): array { - $navTabs[] = li - ( - set('class', 'nav-item' . ($project->id == $selected ? ' active' : '')), - a + $navTabs = array(); + $selected = key($projects); + foreach($projects as $project) + { + $navTabs[] = li ( - set('class', 'ellipsis'), - set('data-toggle', 'tab'), - set('href', "#tab3{$blockNavID}Content{$project->id}"), - $project->name - - ), - a - ( - set('class', 'link flex-1 text-right hidden'), - set('href', helper::createLink('project', 'index', "projectID=$project->id")), - icon + set('class', 'nav-item' . ($project->id == $selected ? ' active' : '')), + a ( - set('class', 'rotate-90 text-primary'), - 'export' + set('class', 'ellipsis'), + set('data-toggle', 'tab'), + set('href', "#tab3{$blockNavCode}Content{$project->id}"), + $project->name + + ), + a + ( + set('class', 'link flex-1 text-right hidden'), + set('href', helper::createLink('project', 'index', "projectID=$project->id")), + icon + ( + set('class', 'rotate-90 text-primary'), + 'export' + ) ) - ) - ); + ); + } + return $navTabs; } -$tabItems = array(); -foreach($projects as $project) +/** + * 获取区块右侧显示的项目信息. + * Get project statistical information. + * + * @param object $projects + * @param string $blockNavID + * @access public + * @return array + */ +function getProjectInfo($projects, $blockNavID): array { - if(in_array($project->model, array('scrum', 'kanban', 'agileplus'))) + $selected = key($projects); + $tabItems = array(); + foreach($projects as $project) { - /* 展示右侧的项目统计项。 */ - $cells = array(); - foreach($config->block->projectstatistic->dtable as $module => $items) - { - $cellItems = array(); - foreach($items as $item) - { - $field = $item['field']; - $unit = $item['unit']; - $cellItems[] = div - ( - set('class', 'flex py-4'), - cell - ( - set('width', '50%'), - set('class', 'text-right text-gray'), - span($lang->block->projectstatistic->{$field} . ' :') - ), - cell - ( - set('width', '50%'), - set('class', 'text-left'), - span - ( - set('class', 'font-bold text-black'), - zget($project, $field, 0) - ), - span($lang->block->projectstatistic->{$unit}) - ) - ); - } - $cells[] = cell + $tabItems[] = div + ( + set('class', 'tab-pane' . ($project->id == $selected ? ' active' : '')), + set('id', "tab3{$blockNavID}Content{$project->id}"), + in_array($project->model, array('scrum', 'kanban', 'agileplus')) ? getScrumProjectInfo($project) : getWaterfallProjectInfo($project) + ); + } + return $tabItems; +} + +/** + * 获取敏捷类项目的统计信息. + * Get scrum project info. + * + * @param object $project + * @access public + * @return void + */ +function getScrumProjectInfo($project) +{ + global $lang; + + $scrumProjectInfo = div + ( + /* 区块右侧顶部的项目概况。 */ + div + ( + set('class', 'flex bg-white h-10 leading-9 px-4 shadow-sm'), + cell ( - set('class', 'flex-1 px-2 py-4'), - div + set('class', 'text-left mr-6'), + span ( - set('class', 'px-2'), + set('class', 'text-gray'), + '距离项目结束还剩', span ( - set('class', 'font-bold'), - $lang->block->projectstatistic->{$module} + set('class', 'font-bold text-black px-1'), + zget($project, 'remainingDays' , 0) ), + $lang->block->projectstatistic->day + ) + ), + cell + ( + set('class', 'flex-1 text-left'), + span + ( + set('class', 'text-gray mr-5'), + '存在风险 : ', + span + ( + set('class', 'font-bold text-warning'), + '3' + ) ), - $cellItems + span + ( + set('class', 'text-gray'), + '存在问题 : ', + span + ( + set('class', 'font-bold text-warning'), + '1' + ) + ) + ), + (!empty($project->executions) and $project->multiple) ? cell + ( + /* 项目最近的一次执行。 */ + set('class', 'flex-1 text-right'), + span + ( + set('class', 'text-gray'), + '最近执行 ', + a + ( + set('href', helper::createLink('execution', 'task', "executionID={$project->executions[0]->id}")), + set('title', $project->executions[0]->name), + $project->executions[0]->name, + ) + ) + ) : null + ), + div + ( + /* 区块右侧主体显示的项目统计项。 */ + set('class', 'flex'), + getProjectStatisticItems($project) + ) + ); + return $scrumProjectInfo; +} + +/** + * 获取项目的统计项. + * get project statistic items. + * + * @param object $project + * @access public + * @return array + */ +function getProjectStatisticItems($project): array +{ + global $config, $lang; + + $cells = array(); + foreach($config->block->projectstatistic->dtable as $module => $items) + { + $cellItems = array(); + foreach($items as $item) + { + $field = $item['field']; + $unit = $item['unit']; + $cellItems[] = div + ( + set('class', 'flex py-4'), + cell + ( + set('width', '50%'), + set('class', 'text-right text-gray'), + span($lang->block->projectstatistic->{$field} . ' :') + ), + cell + ( + set('width', '50%'), + set('class', 'text-left'), + span + ( + set('class', 'font-bold text-black'), + zget($project, $field, 0) + ), + span($lang->block->projectstatistic->{$unit}) + ) ); } + $cells[] = cell + ( + set('class', 'flex-1 px-2 py-4'), + div + ( + set('class', 'px-2'), + span + ( + set('class', 'font-bold'), + $lang->block->projectstatistic->{$module} + ), + ), + $cellItems + ); } - /* 展示右侧顶部的项目状况。 */ - $tabItems[] = div - ( - set('class', 'tab-pane' . ($project->id == $selected ? ' active' : '')), - set('id', "tab3{$blockNavID}Content{$project->id}"), + return $cells; +} - in_array($project->model, array('scrum', 'kanban', 'agileplus')) ? div +/** + * 获取瀑布类项目的统计信息. + * get waterfall project info. + * + * @param object $project + * @access public + * @return void + */ +function getWaterfallProjectInfo($project) +{ + global $app, $lang; + $isChineseLang = in_array($app->getClientLang(), array('zh-cn','zh-tw')); + $waterfallProjectInfo = div + ( + /* 瀑布项目展示概况。 */ + set('class', 'weekly-row'), + div ( - /* 敏捷、看板等项目展示概况。 */ - div + span ( - set('class', 'flex bg-white h-10 leading-9 px-4 shadow-sm'), - cell - ( - set('class', 'text-left mr-6'), - span - ( - set('class', 'text-gray'), - '距离项目结束还剩', - span - ( - set('class', 'font-bold text-black px-1'), - zget($project, 'remainingDays' , 0) - ), - $lang->block->projectstatistic->day - ) - ), - cell - ( - set('class', 'flex-1 text-left'), - span - ( - set('class', 'text-gray mr-5'), - '存在风险 : ', - span - ( - set('class', 'font-bold text-warning'), - '3' - ) - ), - span - ( - set('class', 'text-gray'), - '存在问题 : ', - span - ( - set('class', 'font-bold text-warning'), - '1' - ) - ) - ), - (!empty($project->executions) and $project->multiple) ? cell - ( - set('class', 'flex-1 text-right'), - span - ( - set('class', 'text-gray'), - '最近执行 ', - a - ( - set('href', $this->createLink('execution', 'task', "executionID={$project->executions[0]->id}")), - set('title', $project->executions[0]->name), - $project->executions[0]->name, - ) - ) - ) : null + set('class', 'weekly-title'), + $lang->project->weekly ), - div + span ( - set('class', 'flex'), - $cells + set('class', 'weekly-stage'), + $project->current ) - ) : div + ), + div ( - /* 瀑布项目展示概况。 */ - set('class', 'weekly-row'), + set('class', 'flex'), div ( - span - ( - set('class', 'weekly-title'), - $lang->project->weekly - ), - span - ( - set('class', 'weekly-stage'), - $project->current - ) - ), - div - ( - set('class', 'flex'), + set('class', 'flex-1'), div ( - set('class', 'flex-1'), + set('class', 'progress'), + span + ( + set('class', 'mr-4'), + $lang->project->progress . ' : ' . $project->progress . '%' + ), div ( - set('class', 'progress'), - span - ( - set('class', 'mr-4'), - $lang->project->progress . ' : ' . $project->progress . '%' - ), - div - ( - set('class', 'progress-bar'), - set('role', 'progressbar'), - setStyle(['width' => $project->progress . '%']), - ) + set('class', 'progress-bar'), + set('role', 'progressbar'), + setStyle(['width' => $project->progress . '%']), ) - ), - div - ( - set('class', 'flex-1 text-center'), - $lang->project->teamCount . ' : ' . $project->teamCount - ), - div - ( - set('class', 'flex-1 text-left'), - $lang->project->budget . ' : ' . ($project->budget != 0 ? $project->budget : $this->lang->project->future) - ), - div(set('class', 'flex-1')) - ), - div - ( - set('class', 'flex'), - div - ( - set('class', 'flex-1'), - $isChineseLang ? $lang->project->pv . '(' . $lang->project->pvTitle . ')' : $lang->project->pv - ), - div - ( - set('class', 'flex-1'), - $isChineseLang ? $lang->project->ev . '(' . $lang->project->evTitle . ')' : $lang->project->ev - ), - div - ( - set('class', 'flex-1'), - $isChineseLang ? $lang->project->ac . '(' . $lang->project->acTitle . ')' : $lang->project->ac - ), - div - ( - set('class', 'flex-1'), - $isChineseLang ? $lang->project->sv . '(' . $lang->project->svTitle . ')' : $lang->project->sv - ), - div - ( - set('class', 'flex-1'), - $isChineseLang ? $lang->project->cv . '(' . $lang->project->cvTitle . ')' : $lang->project->cv ) ), div ( - set('class', 'flex'), - div - ( - set('class', 'flex-1'), - $project->pv - ), - div - ( - set('class', 'flex-1'), - $project->ev - ), - div - ( - set('class', 'flex-1'), - $project->ac - ), - div - ( - set('class', 'flex-1'), - $project->sv - ), - div - ( - set('class', 'flex-1'), - $project->cv - ) + set('class', 'flex-1 text-center'), + $lang->project->teamCount . ' : ' . $project->teamCount + ), + div + ( + set('class', 'flex-1 text-left'), + $lang->project->budget . ' : ' . ($project->budget != 0 ? $project->budget : $lang->project->future) + ), + div(set('class', 'flex-1')) + ), + div + ( + set('class', 'flex'), + div + ( + set('class', 'flex-1'), + $isChineseLang ? $lang->project->pv . '(' . $lang->project->pvTitle . ')' : $lang->project->pv + ), + div + ( + set('class', 'flex-1'), + $isChineseLang ? $lang->project->ev . '(' . $lang->project->evTitle . ')' : $lang->project->ev + ), + div + ( + set('class', 'flex-1'), + $isChineseLang ? $lang->project->ac . '(' . $lang->project->acTitle . ')' : $lang->project->ac + ), + div + ( + set('class', 'flex-1'), + $isChineseLang ? $lang->project->sv . '(' . $lang->project->svTitle . ')' : $lang->project->sv + ), + div + ( + set('class', 'flex-1'), + $isChineseLang ? $lang->project->cv . '(' . $lang->project->cvTitle . ')' : $lang->project->cv + ) + ), + div + ( + set('class', 'flex'), + div + ( + set('class', 'flex-1'), + $project->pv + ), + div + ( + set('class', 'flex-1'), + $project->ev + ), + div + ( + set('class', 'flex-1'), + $project->ac + ), + div + ( + set('class', 'flex-1'), + $project->sv + ), + div + ( + set('class', 'flex-1'), + $project->cv ) ) ); + return $waterfallProjectInfo; } +$blockNavCode = 'nav-' . uniqid(); div ( set('class', 'projectstatistic-block'), @@ -293,14 +360,14 @@ div ul ( set('class', 'nav nav-tabs nav-stacked'), - $navTabs, + getProjectTabs($projects, $blockNavCode) ), ), cell ( set('class', 'tab-content'), set('width', '75%'), - $tabItems + getProjectInfo($projects, $blockNavCode) ) ) ); From 4ce1b83e3cac2036ee6d56f926e73b85cb47b827 Mon Sep 17 00:00:00 2001 From: chentao Date: Mon, 8 May 2023 11:24:37 +0800 Subject: [PATCH 30/33] * product: fix param type. --- module/product/tao.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/product/tao.php b/module/product/tao.php index a1c405497b..76d4c5ba05 100644 --- a/module/product/tao.php +++ b/module/product/tao.php @@ -608,14 +608,14 @@ class productTao extends productModel * Get products by project ID. * * @param int $projectID - * @param array $views + * @param string $productIdListStr '1,2,3' * @param string $status * @param string $orderBy * @param bool $noDeleted * @access protected * @return int */ - protected function getProductsByProjectID(int $projectID, array $views, string $status, string $orderBy, bool $noDeleted): array + protected function getProductsByProjectID(int $projectID, string $productIdListStr, string $status, string $orderBy, bool $noDeleted): array { return $this->dao->select("t1.branch, t1.plan, t2.*") ->from(TABLE_PROJECTPRODUCT)->alias('t1') @@ -623,7 +623,7 @@ class productTao extends productModel ->where('1=1') ->beginIF($noDeleted)->andWhere('t2.deleted')->eq(0)->fi() ->beginIF(!empty($projectID))->andWhere('t1.project')->in($projectID)->fi() - ->beginIF(!$this->app->user->admin and $this->config->vision == 'rnd')->andWhere('t2.id')->in($views)->fi() + ->beginIF(!$this->app->user->admin and $this->config->vision == 'rnd')->andWhere('t2.id')->in($productIdListStr)->fi() ->andWhere('t2.vision')->eq($this->config->vision) ->beginIF(strpos($status, 'noclosed') !== false)->andWhere('t2.status')->ne('closed')->fi() ->orderBy($orderBy . 't2.order asc') From 509ca47047256eb7c3e5deb30c549b912971fb65 Mon Sep 17 00:00:00 2001 From: guofeilong Date: Mon, 8 May 2023 11:25:26 +0800 Subject: [PATCH 31/33] * Code for function refactors project update. --- .../test/tao/deleteextramembersbyproject.php | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 module/project/test/tao/deleteextramembersbyproject.php diff --git a/module/project/test/tao/deleteextramembersbyproject.php b/module/project/test/tao/deleteextramembersbyproject.php new file mode 100644 index 0000000000..900f25d99a --- /dev/null +++ b/module/project/test/tao/deleteextramembersbyproject.php @@ -0,0 +1,22 @@ +#!/usr/bin/env php +loadModel('project'); + +$project = new stdClass; +$team = new stdClass; +$members = new stdClass; + +r($tester->project->deleteextramembersbyproject(2, $project, $team, $members)) && p() && e(1); From 595999ff6655a7d51c8ae7316a44bc6f4be788d0 Mon Sep 17 00:00:00 2001 From: guofeilong Date: Mon, 8 May 2023 11:26:20 +0800 Subject: [PATCH 32/33] * Code refactors for function project update . --- db/update18.4.alpha1.sql | 4 + db/zentao.sql | 2 +- module/execution/control.php | 4 +- module/execution/model.php | 6 +- .../execution/test/model/data/sql/project.sql | 2 +- module/execution/view/create.html.php | 8 +- module/execution/view/edit.html.php | 8 +- module/programplan/model.php | 4 +- module/programplan/view/create.html.php | 2 +- module/programplan/view/gantt.html.php | 2 +- module/project/control.php | 2 +- module/project/css/create.css | 2 +- module/project/js/create.js | 12 +- module/project/js/edit.js | 8 +- module/project/js/execution.js | 2 +- module/project/js/manageproducts.js | 8 +- module/project/lang/de.php | 12 +- module/project/lang/en.php | 12 +- module/project/lang/fr.php | 12 +- module/project/lang/vi.php | 8 +- module/project/lang/zh-cn.php | 12 +- module/project/model.php | 344 +++++++++++------- module/project/tao.php | 7 +- module/project/test/model/stageProduct.php | 21 ++ .../test/model/unlinkproductsbyproject.php | 23 ++ module/project/test/model/update.php | 19 +- .../test/model/updateteammembersbyproject.php | 23 ++ .../test/model/updateuserviewbyproject.php | 23 ++ .../test/model/updatewhitelistbyproject.php | 23 ++ .../test/model/yaml/stageproduct/project.yaml | 24 ++ .../yaml/unLinkproductsbyproject/project.yaml | 24 ++ .../test/model/yaml/update/project.yaml | 24 ++ .../project.yaml | 0 .../projectproduct.yaml | 0 .../updateteammembersbyproject/project.yaml | 24 ++ .../yaml/updateuserviewbyproject/project.yaml | 24 ++ .../updatewhitelistbyproject/project.yaml | 24 ++ module/project/view/create.html.php | 8 +- module/project/view/edit.html.php | 10 +- module/project/view/execution.html.php | 6 +- module/project/view/manageproducts.html.php | 4 +- module/project/zen.php | 63 +++- module/task/model.php | 2 +- module/tutorial/model.php | 2 +- module/user/test/model/data/sql/project.sql | 2 +- 45 files changed, 633 insertions(+), 223 deletions(-) create mode 100644 db/update18.4.alpha1.sql create mode 100644 module/project/test/model/stageProduct.php create mode 100644 module/project/test/model/unlinkproductsbyproject.php create mode 100644 module/project/test/model/updateteammembersbyproject.php create mode 100644 module/project/test/model/updateuserviewbyproject.php create mode 100644 module/project/test/model/updatewhitelistbyproject.php create mode 100644 module/project/test/model/yaml/stageproduct/project.yaml create mode 100644 module/project/test/model/yaml/unLinkproductsbyproject/project.yaml create mode 100644 module/project/test/model/yaml/update/project.yaml rename module/project/test/model/yaml/{updatePlanIdListByProject => updateplanIdlistbyproject}/project.yaml (100%) rename module/project/test/model/yaml/{updatePlanIdListByProject => updateplanIdlistbyproject}/projectproduct.yaml (100%) create mode 100644 module/project/test/model/yaml/updateteammembersbyproject/project.yaml create mode 100644 module/project/test/model/yaml/updateuserviewbyproject/project.yaml create mode 100644 module/project/test/model/yaml/updatewhitelistbyproject/project.yaml diff --git a/db/update18.4.alpha1.sql b/db/update18.4.alpha1.sql new file mode 100644 index 0000000000..e3cec0f886 --- /dev/null +++ b/db/update18.4.alpha1.sql @@ -0,0 +1,4 @@ +ALTER TABLE `zt_project` ADD `stageBy` enum('project', 'product') NOT NULL DEFAULT 'product' AFTER `division`; +UPDATE `zt_project` SET `stageBy` = 'project' WHERE `division` = '0'; +UPDATE `zt_project` SET `stageBy` = 'product' WHERE `division` = '1'; +ALTER TABLE `zt_project` DROP `division`; diff --git a/db/zentao.sql b/db/zentao.sql index 06b2dea9c9..1f1fca3af5 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -1354,7 +1354,7 @@ CREATE TABLE IF NOT EXISTS `zt_project` ( `whitelist` text NULL, `order` mediumint(8) unsigned NOT NULL DEFAULT '0', `vision` varchar(10) NOT NULL DEFAULT 'rnd', - `division` enum('0','1') NOT NULL DEFAULT '1', + `stageBy` enum('project','product') NOT NULL DEFAULT 'product', `displayCards` smallint(6) NOT NULL default '0', `fluidBoard` enum('0','1') NOT NULL DEFAULT '0', `multiple` enum('0','1') NOT NULL DEFAULT '1', diff --git a/module/execution/control.php b/module/execution/control.php index e6dc952c14..ca6f804aee 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1770,7 +1770,7 @@ class execution extends control $this->view->linkedBranches = $linkedBranches; } - if(!empty($project) and !$project->division) + if(!empty($project) and $project->stageBy == 'project') { $products = $this->loadModel('product')->getProducts($projectID); $branches = $this->project->getBranchesByProject($projectID); @@ -1916,7 +1916,7 @@ class execution extends control $this->view->from = $this->app->tab; $this->view->isStage = (isset($project->model) and ($project->model == 'waterfall' or $project->model == 'waterfallplus')) ? true : false; $this->view->project = $project; - $this->view->division = !empty($project) ? $project->division : 1; + $this->view->stageBy = $project->stageBy; $this->view->type = $type; $this->display(); } diff --git a/module/execution/model.php b/module/execution/model.php index 44bf967d40..f1aa8f66c7 100755 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -2052,7 +2052,7 @@ class executionModel extends model if(isset($project->model) and in_array($project->model, array('waterfall', 'waterfallplus'))) { $executionProducts = array(); - if($project->hasProduct and $project->division) + if($project->hasProduct and ($project->stageBy == 'product')) { $executionList = array(); $executionProducts = $this->dao->select('t1.project, t2.name')->from(TABLE_PROJECTPRODUCT)->alias('t1') @@ -5267,7 +5267,7 @@ class executionModel extends model } } } - if(!empty($execution->division) and $execution->hasProduct) echo "{$execution->productName}"; + if(($execution->stageBy == 'project') and $execution->hasProduct) echo "{$execution->productName}"; echo "" . zget($this->lang->project->statusList, $execution->status) . ''; echo '' . zget($users, $execution->PM) . ''; echo helper::isZeroDate($execution->begin) ? '' : '' . $execution->begin . ''; @@ -5322,7 +5322,7 @@ class executionModel extends model { foreach($execution->children as $child) { - $child->division = $execution->division; + $child->stageBy = $execution->stageBy; $this->printNestedList($child, true, $users, $productID); } } diff --git a/module/execution/test/model/data/sql/project.sql b/module/execution/test/model/data/sql/project.sql index bb14bbcb80..4a40c242e7 100644 --- a/module/execution/test/model/data/sql/project.sql +++ b/module/execution/test/model/data/sql/project.sql @@ -73,7 +73,7 @@ CREATE TABLE `zt_project` ( `whitelist` text NOT NULL, `order` mediumint(8) unsigned NOT NULL, `vision` varchar(10) NOT NULL DEFAULT 'rnd', - `division` enum('0','1') NOT NULL DEFAULT '1', + `stageBy` enum('product','project') NOT NULL DEFAULT 'product', `displayCards` smallint(6) NOT NULL DEFAULT 0, `fluidBoard` enum('0','1') NOT NULL DEFAULT '0', `multiple` enum('0','1') NOT NULL DEFAULT '1', diff --git a/module/execution/view/create.html.php b/module/execution/view/create.html.php index 2781a20e1a..a3876d7efb 100644 --- a/module/execution/view/create.html.php +++ b/module/execution/view/create.html.php @@ -157,9 +157,9 @@ type != 'normal' and isset($branchGroups[$product->id]);?>
'> productCommon;?> - division) ? "disabled='disabled'" : '';?> + stageBy == 'project') ? "disabled='disabled'" : '';?> id, "class='form-control chosen' $disabled onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?> - division) echo html::hidden("products[$i]", $product->id);?> + stageBy == 'project') echo html::hidden("products[$i]", $product->id);?>
'> @@ -177,7 +177,7 @@ product->plan;?> id)) echo html::select("plans[$product->id][]", isset($productPlans[$product->id]) ? $productPlans[$product->id] : array(), isset($product->plans) ? $product->plans : '', "class='form-control chosen' multiple");?> id) echo html::select("plans[$product->id][]", !empty($productPlan) ? $productPlan : array(), isset($productPlan[$plan->id]) ? $plan->id : '', "class='form-control chosen' multiple");?> - division)):?> + stageBy == 'project')):?>
> @@ -225,7 +225,7 @@
product->plan;?> - division)):?> + stageBy == 'product')):?>
diff --git a/module/execution/view/edit.html.php b/module/execution/view/edit.html.php index e3b878b4ef..d420db2c7e 100644 --- a/module/execution/view/edit.html.php +++ b/module/execution/view/edit.html.php @@ -169,9 +169,9 @@ type != 'normal' and isset($branchGroups[$product->id]);?>
'> productCommon;?> - type == 'stage' and !$execution->division) ? "disabled='disabled'" : '';?> + type == 'stage' and $execution->stageBy == 'project') ? "disabled='disabled'" : '';?> id, "class='form-control chosen' $disabled onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?> - type == 'stage' and !$execution->division) echo html::hidden("products[$i]", $product->id);?> + type == 'stage' and $execution->stageBy == 'project') echo html::hidden("products[$i]", $product->id);?>
'> @@ -187,7 +187,7 @@
> product->plan;?> id][]", isset($productPlans[$product->id]) ? $productPlans[$product->id] : array(), $product->plans, "class='form-control chosen' multiple");?> - type == 'stage' and !$execution->division)):?> + type == 'stage' and $execution->stageBy == 'project')):?>
> @@ -262,7 +262,7 @@ productCommon;?> model == 'waterfall' or $project->model == 'waterfallplus') ? "disabled='disabled'" : '';?> id, "class='form-control chosen' $disabled onchange='loadBranches(this)' data-last='" . $product->id . "' data-type='" . $product->type . "'");?> - type == 'stage' and !$project->division) echo html::hidden("products[$i]", $product->id);?> + type == 'stage' and $project->stageBy == 'product') echo html::hidden("products[$i]", $product->id);?>
'> diff --git a/module/programplan/model.php b/module/programplan/model.php index d98a32ecc9..c8e7ea712a 100755 --- a/module/programplan/model.php +++ b/module/programplan/model.php @@ -873,7 +873,7 @@ class programplanModel extends model $linkProducts = array(); $linkBranches = array(); $productList = $this->loadModel('product')->getProducts($projectID); - if($project->division) + if($project->stageBy == 'product') { $linkProducts = array(0 => $productID); $linkBranches = array(0 => $productList[$productID]->branches); @@ -954,7 +954,7 @@ class programplanModel extends model { unset($plan->id); $plan->status = 'wait'; - $plan->division = $project->division; + $plan->stageBy = $project->stageBy; $plan->version = 1; $plan->parentVersion = $plan->parent == 0 ? 0 : $this->dao->findByID($plan->parent)->from(TABLE_PROJECT)->fetch('version'); $plan->team = substr($plan->name,0, 30); diff --git a/module/programplan/view/create.html.php b/module/programplan/view/create.html.php index 22981125a1..b40b383cad 100644 --- a/module/programplan/view/create.html.php +++ b/module/programplan/view/create.html.php @@ -23,7 +23,7 @@ echo "{$title}"; ?> - division):?> + stageBy == 'product'):?>
diff --git a/module/programplan/view/gantt.html.php b/module/programplan/view/gantt.html.php index f8cc583dcd..eccfe89e77 100755 --- a/module/programplan/view/gantt.html.php +++ b/module/programplan/view/gantt.html.php @@ -86,7 +86,7 @@ form {display: block; margin-top: 0em; margin-block-end: 1em;} app->getModuleName() == 'programplan'):?>
- division)):?> + stageBy == 'product'):?> product->allProduct;?>