From 69159b5520c1a3a7b8d0a416f735d558c2e22e7e Mon Sep 17 00:00:00 2001 From: zhaoke Date: Fri, 10 Feb 2023 07:30:45 +0000 Subject: [PATCH 01/18] * Fix bug #32037. --- module/zanode/control.php | 4 +++- module/zanode/lang/de.php | 5 +++-- module/zanode/lang/en.php | 5 +++-- module/zanode/lang/fr.php | 5 +++-- module/zanode/lang/zh-cn.php | 5 +++-- module/zanode/model.php | 3 +++ module/zanode/view/browsesnapshot.html.php | 4 ++-- 7 files changed, 20 insertions(+), 11 deletions(-) diff --git a/module/zanode/control.php b/module/zanode/control.php index 835d3a8465..245ecbd4c9 100644 --- a/module/zanode/control.php +++ b/module/zanode/control.php @@ -469,7 +469,9 @@ class zanode extends control if(dao::isError()) { - return print(js::alert(dao::getError()) . js::reload('parent')); + $errors = dao::getError(); + if(is_array($errors)) $errors = implode($errors, ','); + return print(js::alert($errors) . js::reload('parent')); } else { diff --git a/module/zanode/lang/de.php b/module/zanode/lang/de.php index 1200f7cf54..6fb124d62c 100644 --- a/module/zanode/lang/de.php +++ b/module/zanode/lang/de.php @@ -101,8 +101,9 @@ $lang->zanode->imageNameEmpty = 'Name can not be empty.'; $lang->zanode->runTimeout = 'Network connection timeout, please check the host and execution node status.'; -$lang->zanode->apiError['-10100'] = 'ZenAgent Node not found.'; -$lang->zanode->apiError['fail'] = 'Connection timeout, Please check the host and execution node status.'; +$lang->zanode->apiError['-10100'] = 'ZenAgent Node not found.'; +$lang->zanode->apiError['fail'] = 'Connection timeout, Please check the host and execution node status.'; +$lang->zanode->apiError['notRunning'] = 'Please check the execution node status.'; $lang->zanode->publicList[0] = 'Private'; $lang->zanode->publicList[1] = 'Public'; diff --git a/module/zanode/lang/en.php b/module/zanode/lang/en.php index 25a9e2dd6c..563d3eed23 100644 --- a/module/zanode/lang/en.php +++ b/module/zanode/lang/en.php @@ -105,8 +105,9 @@ $lang->zanode->snapRestoring = 'Snapshot is restoring.'; $lang->zanode->runTimeout = 'Network connection timeout, please check the host and execution node status.'; -$lang->zanode->apiError['-10100'] = 'ZenAgent Node not found.'; -$lang->zanode->apiError['fail'] = 'Connection timeout, Please check the host and execution node status.'; +$lang->zanode->apiError['-10100'] = 'ZenAgent Node not found.'; +$lang->zanode->apiError['fail'] = 'Connection timeout, Please check the host and execution node status.'; +$lang->zanode->apiError['notRunning'] = 'Please check the execution node status.'; $lang->zanode->publicList[0] = 'Private'; $lang->zanode->publicList[1] = 'Public'; diff --git a/module/zanode/lang/fr.php b/module/zanode/lang/fr.php index 1200f7cf54..6fb124d62c 100644 --- a/module/zanode/lang/fr.php +++ b/module/zanode/lang/fr.php @@ -101,8 +101,9 @@ $lang->zanode->imageNameEmpty = 'Name can not be empty.'; $lang->zanode->runTimeout = 'Network connection timeout, please check the host and execution node status.'; -$lang->zanode->apiError['-10100'] = 'ZenAgent Node not found.'; -$lang->zanode->apiError['fail'] = 'Connection timeout, Please check the host and execution node status.'; +$lang->zanode->apiError['-10100'] = 'ZenAgent Node not found.'; +$lang->zanode->apiError['fail'] = 'Connection timeout, Please check the host and execution node status.'; +$lang->zanode->apiError['notRunning'] = 'Please check the execution node status.'; $lang->zanode->publicList[0] = 'Private'; $lang->zanode->publicList[1] = 'Public'; diff --git a/module/zanode/lang/zh-cn.php b/module/zanode/lang/zh-cn.php index 27f9b1175c..220b61ae5e 100644 --- a/module/zanode/lang/zh-cn.php +++ b/module/zanode/lang/zh-cn.php @@ -106,8 +106,9 @@ $lang->zanode->snapRestoring = '快照正在还原中'; $lang->zanode->runTimeout = '自动执行失败,请检查宿主机和执行节点状态'; -$lang->zanode->apiError['-10100'] = '执行节点不存在'; -$lang->zanode->apiError['fail'] = '执行失败,请检查宿主机和执行节点状态'; +$lang->zanode->apiError['-10100'] = '执行节点不存在'; +$lang->zanode->apiError['fail'] = '执行失败,请检查宿主机和执行节点状态'; +$lang->zanode->apiError['notRunning'] = '请检查执行节点状态'; $lang->zanode->publicList[0] = '不共享'; $lang->zanode->publicList[1] = '共享'; diff --git a/module/zanode/model.php b/module/zanode/model.php index 5b7c426a5c..bd81193d76 100644 --- a/module/zanode/model.php +++ b/module/zanode/model.php @@ -187,6 +187,9 @@ class zanodemodel extends model $node = $this->getNodeByID($zanodeID); + if($node->status != 'running') dao::$errors['name'] = $this->lang->zanode->apiError['notRunning']; + if(dao::isError()) return false; + $newSnapshot = new stdClass(); $newSnapshot->host = $node->id; $newSnapshot->name = $data->name; diff --git a/module/zanode/view/browsesnapshot.html.php b/module/zanode/view/browsesnapshot.html.php index 067087af4a..055aa2fc9f 100644 --- a/module/zanode/view/browsesnapshot.html.php +++ b/module/zanode/view/browsesnapshot.html.php @@ -40,10 +40,10 @@ $editAttr = $snapshot->status == 'failed' ? 'class="btn disabled"' : "title={$lang->zanode->editSnapshot} onclick='window.parent.editSnapshot(\"" . $this->createLink('zanode', 'editSnapshot', "snapshotID={$snapshot->id}") . "\")' class='btn'"; $restoreAttr = "title='{$lang->zanode->restoreSnapshot}' target='hiddenwin'"; - $restoreAttr .= ($node->status !='running' or $snapshot->status == 'restoring' or $snapshot->status == 'failed') ? ' class="btn disabled"' : 'class="btn"'; + $restoreAttr .= ($node->status !='running' or in_array($snapshot->status, array('creating', 'failed', 'restoring'))) ? ' class="btn disabled"' : 'class="btn"'; $deleteAttr = "title='{$lang->zanode->deleteSnapshot}' target='hiddenwin'"; - $deleteAttr .= (($snapshot->status == 'restoring' and (time() - strtotime($snapshot->restoreDate)) <= 600) or $snapshot->status == 'failed') ? ' class="btn disabled"' : 'class="btn"'; + $deleteAttr .= ($snapshot->status == 'restoring' or $snapshot->status == 'creating') ? ' class="btn disabled"' : 'class="btn"'; ?> localName ? $snapshot->localName : $snapshot->name;?> zanode->snapshot->statusList, $snapshot->status, '');?> From e9c8ea6d7a6125c0a1909bb4ecee4c2fae23da73 Mon Sep 17 00:00:00 2001 From: liumengyi Date: Mon, 13 Feb 2023 13:26:31 +0800 Subject: [PATCH 02/18] * Fix bug #32064. --- module/productplan/model.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/module/productplan/model.php b/module/productplan/model.php index f4a4ac9cb0..db920d79e9 100644 --- a/module/productplan/model.php +++ b/module/productplan/model.php @@ -114,10 +114,12 @@ class productplanModel extends model $productplanQuery = $this->session->productplanQuery; - $date = date('Y-m-d'); - $plans = $this->dao->select('*')->from(TABLE_PRODUCTPLAN) + $date = date('Y-m-d'); + $products = (strpos($param, 'noproduct') !== false and empty($product)) ? $this->loadModel('product')->getList() : array(0); + $plans = $this->dao->select('*')->from(TABLE_PRODUCTPLAN) ->where('deleted')->eq(0) ->beginIF(strpos($param, 'noproduct') === false or !empty($product))->andWhere('product')->eq($product)->fi() + ->beginIF(strpos($param, 'noproduct') !== false and empty($product))->andWhere('product')->in(array_keys($products))->fi() ->beginIF(!empty($branch) and $branch != 'all')->andWhere('branch')->eq($branch)->fi() ->beginIF(strpos(',all,undone,bySearch,review,', ",$browseType,") === false)->andWhere('status')->eq($browseType)->fi() ->beginIF($browseType == 'undone')->andWhere('status')->in('wait,doing')->fi() From 6629a458a66685ff9908b43a885e979d196f1380 Mon Sep 17 00:00:00 2001 From: xieqiyu Date: Mon, 13 Feb 2023 13:41:14 +0800 Subject: [PATCH 03/18] * Code for bug#31983. --- module/story/model.php | 53 ++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/module/story/model.php b/module/story/model.php index fa3d8eabf6..ff9d879ff3 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -1247,15 +1247,9 @@ class storyModel extends model if(empty($childrenStatus)) return $this->dao->update(TABLE_STORY)->set('parent')->eq('0')->where('id')->eq($parentID)->exec(); $status = $oldParentStory->status; - if(count($childrenStatus) == 1) - { - $status = current($childrenStatus); - if($status == 'draft' or $status == 'changing') $status = 'active'; - } - elseif(count($childrenStatus) != 1 and $oldParentStory->status == 'closed') - { - $status = 'active'; - } + if(count($childrenStatus) == 1 and current($childrenStatus) == 'closed') $status = current($childrenStatus); // Close parent story. + if($oldParentStory->status == 'closed') $status = $this->getActivateStatus($parentID); // Activate parent story. + if($status and $oldParentStory->status != $status) { @@ -1263,7 +1257,7 @@ class storyModel extends model $story = new stdclass(); $story->status = $status; $story->stage = 'wait'; - if($status == 'active') + if(strpos('active,changing,draft', $status) !== false) { $story->assignedTo = $oldParentStory->openedBy; $story->assignedDate = $now; @@ -1293,13 +1287,21 @@ class storyModel extends model if(!$createAction) return $story; $newParentStory = $this->dao->select('*')->from(TABLE_STORY)->where('id')->eq($parentID)->fetch(); - $changes = common::createChanges($oldParentStory, $newParentStory); - $action = ''; - if($status == 'active') $action = 'Activated'; - if($status == 'closed') $action = 'closedbysystem'; + $changes = common::createChanges($oldParentStory, $newParentStory); + $action = ''; + $preStatus = ''; + if(strpos('active,draft,changing', $status) !== false) $action = 'Activated'; + if($status == 'closed') + { + /* Record the status before closed. */ + $action = 'closedbysystem'; + $preStatus = $oldParentStory->status; + $isChanged = $oldParentStory->changedBy ? true : false; + if($preStatus == 'reviewing') $preStatus = $isChanged ? 'changing' : 'draft'; + } if($action) { - $actionID = $this->loadModel('action')->create('story', $parentID, $action, '', '', '', false); + $actionID = $this->loadModel('action')->create('story', $parentID, $action, '', $preStatus, '', false); $this->action->logHistory($actionID, $changes); } @@ -6410,7 +6412,8 @@ class storyModel extends model public function getActivateStatus($storyID, $hasTwins = true) { $status = 'active'; - $action = $hasTwins ? 'closed,reviewrejected,synctwins' : 'closed,reviewrejected'; + $action = 'closed,reviewrejected,closedbysystem'; + $action = $hasTwins ? $action . ',synctwins' : $action; $lastRecord = $this->dao->select('action,extra')->from(TABLE_ACTION) ->where('objectType')->eq('story') ->andWhere('objectID')->eq($storyID) @@ -6419,11 +6422,27 @@ class storyModel extends model ->fetch(); $lastAction = $lastRecord->action; - if(strpos('closed,reviewrejected', $lastAction) !== false) + if(strpos(',closed,reviewrejected,', ",$lastAction,") !== false) { $status = strpos($lastRecord->extra, '|') !== false ? substr($lastRecord->extra, strpos($lastRecord->extra, '|') + 1) : 'active'; } + /* Activate parent story. */ + if($lastAction == 'closedbysystem') + { + $status = $lastRecord->extra ? $lastRecord->extra : 'active'; + if($status == 'active') + { + /* If the parent story is not reviewed before closing, it will be activated to the status in changing. */ + $hasNotReviewed = $this->dao->select('t1.*')->from(TABLE_STORYREVIEW)->alias('t1') + ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id and t2.version = t1.version') + ->where('t1.story')->eq($storyID) + ->andWhere('t1.result')->eq('') + ->fetchAll(); + if(!empty($hasNotReviewed)) $status = 'changing'; + } + } + /* When activating twin story, you need to check the status of the twin story selected when closing. */ if($lastAction == 'synctwins') { From f03bf51121d9507361ff60dc0739964e984f42b9 Mon Sep 17 00:00:00 2001 From: Wenrui LI Date: Mon, 13 Feb 2023 14:00:55 +0800 Subject: [PATCH 04/18] * use static:: instead of self:: to enable extending static functions, and inject script to make js alert work on zentao client. --- lib/base/front/front.class.php | 44 +++++++++++++++++----------------- lib/front/front.class.php | 37 +++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 23 deletions(-) diff --git a/lib/base/front/front.class.php b/lib/base/front/front.class.php index efcf8e826f..8462d2faee 100644 --- a/lib/base/front/front.class.php +++ b/lib/base/front/front.class.php @@ -851,7 +851,7 @@ class baseJS $message = str_replace("\\'", "'", $message); $message = str_replace("'", "\\'", $message); - return self::start($full) . "alert('" . $message . "')" . self::end() . self::resetForm(); + return static::start($full) . "alert('" . $message . "')" . static::end() . static::resetForm(); } /** @@ -864,7 +864,7 @@ class baseJS */ static public function close() { - return self::start() . "window.close()" . self::end(); + return static::start() . "window.close()" . static::end(); } /** @@ -903,7 +903,7 @@ class baseJS { $alertMessage = $message; } - return self::alert($alertMessage, $full); + return static::alert($alertMessage, $full); } /** @@ -916,7 +916,7 @@ class baseJS */ static public function resetForm() { - return self::start() . 'if(window.parent) window.parent.$.enableForm();' . self::end(); + return static::start() . 'if(window.parent) window.parent.$.enableForm();' . static::end(); } /** @@ -954,7 +954,7 @@ class baseJS return json_encode($output); } - $js = self::start(); + $js = static::start(); $confirmAction = ''; if(strtolower($okURL) == "back") @@ -1001,7 +1001,7 @@ EOT; $js .= $confirmAction; } - $js .= self::end(); + $js .= static::end(); return $js; } @@ -1038,7 +1038,7 @@ EOT; return json_encode($output); } - $js = self::start(); + $js = static::start(); if(strtolower($url) == "back") { $js .= "history.back(-1);\n"; @@ -1053,7 +1053,7 @@ EOT; if(strpos($url, '#app=') !== false) $url = substr($url, 0, strpos($url, '#app=')); $js .= "$target.location='$url';\n"; } - return $js . self::end(); + return $js . static::end(); } /** @@ -1066,7 +1066,7 @@ EOT; */ static public function closeWindow() { - return self::start(). "window.close();" . self::end(); + return static::start(). "window.close();" . static::end(); } /** @@ -1082,9 +1082,9 @@ EOT; */ static public function refresh($url, $target = "self", $time = 3000) { - $js = self::start(); + $js = static::start(); $js .= "setTimeout(\"$target.location='$url'\", $time);"; - $js .= self::end(); + $js .= static::end(); return $js; } @@ -1099,7 +1099,7 @@ EOT; */ static public function reload($window = 'self') { - $js = self::start(); + $js = static::start(); // See bug #2379 http://pms.zentao.net/bug-view-2379.html if($window !== 'self' && $window !== 'window') { @@ -1109,7 +1109,7 @@ EOT; { $js .= "$window.location.reload(true);\n"; } - $js .= self::end(); + $js .= static::end(); return $js; } @@ -1125,7 +1125,7 @@ EOT; */ static public function closeColorbox($window = 'self') { - return self::closeModal($window); + return static::closeModal($window); } /** @@ -1141,10 +1141,10 @@ EOT; */ static public function closeModal($window = 'self', $location = 'this', $callback = 'null') { - $js = self::start(); + $js = static::start(); $js .= "if($window.location.href == self.location.href){ $window.window.close();}"; $js .= "else{ $window.$.cookie('selfClose', 1);$window.$.closeModal($callback, '$location');}"; - $js .= self::end(); + $js .= static::end(); return $js; } @@ -1201,10 +1201,10 @@ EOT; $jsLang->expand = isset($lang->expand) ? $lang->expand : ''; $jsLang->timeout = isset($lang->timeout) ? $lang->timeout : ''; - $js = self::start(false); + $js = static::start(false); $js .= 'window.config=' . json_encode($jsConfig) . ";\n"; $js .= 'window.lang=' . json_encode($jsLang) . ";\n"; - $js .= self::end(); + $js .= static::end(); echo $js; } @@ -1219,9 +1219,9 @@ EOT; */ static public function execute($code) { - $js = self::start($full = false); + $js = static::start($full = false); $js .= $code; - $js .= self::end(); + $js .= static::end(); echo $js; } @@ -1241,7 +1241,7 @@ EOT; $prefix = (isset($config->framework->jsWithPrefix) and $config->framework->jsWithPrefix == false) ? '' : 'v.'; static $viewOBJOut; - $js = self::start(false); + $js = static::start(false); if(!$viewOBJOut and $prefix) { $js .= 'if(typeof(v) != "object") v = {};'; @@ -1278,7 +1278,7 @@ EOT; $value = addslashes($value); $js .= "{$prefix}{$key} = '{$value}';"; } - $js .= self::end($newline = false); + $js .= static::end($newline = false); echo $js; } } diff --git a/lib/front/front.class.php b/lib/front/front.class.php index a2026338ac..b0a9d249af 100644 --- a/lib/front/front.class.php +++ b/lib/front/front.class.php @@ -404,7 +404,42 @@ class js extends baseJS */ static public function openEntry($app, $url) { - return self::start() . "$.apps.open('$url', '$app')" . self::end(); + return static::start() . "$.apps.open('$url', '$app')" . static::end(); + } + + /** + * Generate the start of a js block, injects code for zentao client. + * + * @param bool $full + * @static + * @access public + * @return string + */ + static public function start($full = true) + { + if($full) + { + $document = "