diff --git a/module/product/control.php b/module/product/control.php index a0c2fa25e1..15962a371e 100755 --- a/module/product/control.php +++ b/module/product/control.php @@ -57,10 +57,10 @@ class product extends control if($locate == 'yes') $this->locate($this->createLink($this->moduleName, 'browse')); if($this->app->getViewType() != 'mhtml') unset($this->lang->product->menu->index); - $productID = $this->productZen->saveVisitState($productID, $this->products); + $productID = $this->product->saveVisitState($productID, $this->products); $branch = (int)$this->cookie->preBranch; - if($this->app->viewType == 'mhtml') $this->productZen->setMenu($productID, $branch); + if($this->app->viewType == 'mhtml') $this->product->setMenu($productID, $branch); if(common::hasPriv('product', 'create')) $this->lang->TRActions = html::a($this->createLink('product', 'create'), " " . $this->lang->product->create, '', "class='btn btn-primary'"); @@ -123,7 +123,7 @@ class product extends control $pageID = (int)$pageID; $projectID = (int)$projectID; - $productID = $this->app->tab != 'project' ? $this->saveVisitState($productID, $this->products) : $productID; + $productID = $this->app->tab != 'project' ? $this->product->saveVisitState($productID, $this->products) : $productID; $product = $this->product->getById($productID); if($product && !isset($this->products[$product->id])) $this->products[$product->id] = $product->name; @@ -150,7 +150,7 @@ class product extends control $this->session->set('storyList', $this->app->getURI(true), 'product'); $this->session->set('productList', $this->app->getURI(true), 'product'); - $this->productZen->setMenu($productID, $branch, 0, '', "storyType=$storyType"); + $this->product->setMenu($productID, $branch, 0, '', "storyType=$storyType"); } /* Lower browse type. */ @@ -435,7 +435,7 @@ class product extends control $this->productZen->setEditMenu($productID, $programID); $product = $this->product->getByID($productID); - $productID = $this->productZen->saveVisitState($productID, $this->products); + $productID = $this->product->saveVisitState($productID, $this->products); $this->productZen->buildEditForm($product); } @@ -567,7 +567,7 @@ class product extends control return print(js::reload('parent.parent')); } - $this->productZen->setMenu($productID); + $this->product->setMenu($productID); $this->view->product = $product; $this->view->title = $this->view->product->name . $this->lang->colon .$this->lang->close; @@ -596,7 +596,7 @@ class product extends control } $product->desc = $this->loadModel('file')->setImgSize($product->desc); - $this->productZen->setMenu($productID); + $this->product->setMenu($productID); /* Load pager. */ $this->app->loadClass('pager', $static = true); @@ -655,7 +655,7 @@ class product extends control */ public function roadmap($productID, $branch = 'all') { - $this->productZen->setMenu($productID, $branch); + $this->product->setMenu($productID, $branch); $this->session->set('releaseList', $this->app->getURI(true), 'product'); $this->session->set('productPlanList', $this->app->getURI(true), 'product'); @@ -701,7 +701,7 @@ class product extends control $this->session->set('caseList', $uri, 'qa'); $this->session->set('testtaskList', $uri, 'qa'); - $this->productZen->setMenu($productID, 0, 0, '', $type); + $this->product->setMenu($productID, 0, 0, '', $type); /* Append id for secend sort. */ $orderBy = $direction == 'next' ? 'date_desc' : 'date_asc'; @@ -757,12 +757,12 @@ class product extends control $this->session->set('productPlanList', $uri, 'product'); $this->session->set('releaseList', $uri, 'product'); - $productID = $this->productZen->saveVisitState($productID, $this->products); + $productID = $this->product->saveVisitState($productID, $this->products); $product = $this->product->getStatByID($productID); if(!$product) return print(js::locate('product', 'all')); $product->desc = $this->loadModel('file')->setImgSize($product->desc); - $this->productZen->setMenu($productID); + $this->product->setMenu($productID); /* Load pager. */ $this->app->loadClass('pager', $static = true); @@ -989,7 +989,7 @@ class product extends control */ public function whitelist($productID = 0, $module = 'product', $objectType = 'product', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) { - $this->productZen->setMenu($productID, 0); + $this->product->setMenu($productID, 0); $this->lang->modulePageNav = ''; echo $this->fetch('personnel', 'whitelist', "objectID=$productID&module=product&browseType=$objectType&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"); @@ -1007,7 +1007,7 @@ class product extends control */ public function addWhitelist($productID = 0, $deptID = 0, $copyID = 0) { - $this->productZen->setMenu($productID); + $this->product->setMenu($productID); $this->lang->modulePageNav = ''; echo $this->fetch('personnel', 'addWhitelist', "objectID=$productID&dept=$deptID©ID=$copyID&objectType=product&module=product"); @@ -1132,9 +1132,9 @@ class product extends control if(!$projectID) { $products = $this->product->getPairs(); - $productID = $this->productZen->saveVisitState($productID, $products); - $this->product->products = $this->productZen->saveVisitState($productID, $products); - $this->productZen->setMenu($productID, $branch); + $productID = $this->product->saveVisitState($productID, $products); + $this->product->products = $this->product->saveVisitState($productID, $products); + $this->product->setMenu($productID, $branch); } /* Save session. */ diff --git a/module/product/model.php b/module/product/model.php index ab6b3484e3..658e053c4c 100755 --- a/module/product/model.php +++ b/module/product/model.php @@ -1162,7 +1162,6 @@ class productModel extends model if(empty($projects)) return array(); $projectKeys = array_keys($projects); - $stats = array(); /* Get all tasks and compute totalEstimate, totalConsumed, totalLeft, progress according to them. */ $tasks = $this->dao->select('id, project, estimate, consumed, `left`, status, closedReason') @@ -1181,8 +1180,7 @@ class productModel extends model ->andWhere('t2.deleted')->eq(0) ->fetchGroup('root', 'account'); - $stats = $this->program->appendStatToProjects($projects, 'hours,teamCount', array('hours' => $hours, 'teams' => $teams)); - return $stats; + return $this->program->appendStatToProjects($projects, 'hours,teamCount', array('hours' => $hours, 'teams' => $teams)); } /** @@ -2231,4 +2229,132 @@ class productModel extends model return $row; } + + /** + * 把访问的产品ID等状态信息保存到session和cookie中。 + * Save the product id user last visited to session and cookie. + * + * @param int $productID + * @param array $products + * @access protected + * @return int + */ + protected function saveVisitState(int $productID, array $products): int + { + if(defined('TUTORIAL')) return $productID; + + $productID = $this->getAccessableProductID($productID, $products); + + $this->session->set('product', $productID, $this->app->tab); + + setcookie('preProductID', (string)$productID, $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true); + + /* If preProductID changed, then reset preBranch. */ + if($this->cookie->preProductID != $this->session->product) + { + $this->cookie->set('preBranch', 0); + setcookie('preBranch', '0', $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true); + } + + return $productID; + } + + /** + * 获取可访问的产品ID。 + * Get accessable product ID. + * + * @param int $productID + * @param array $products + * @access protected + * @return int + */ + protected function getAccessableProductID(int $productID, array $products): int + { + if(empty($productID)) + { + if($this->cookie->preProductID and isset($products[$this->cookie->preProductID])) $productID = $this->cookie->preProductID; + if(empty($this->session->product)) $productID = (int)key($products); + } + + /* 产品ID已经被删除,不存在于产品列表中。*/ + /* Product ID does not exsit in products list, it may be deleted. */ + if(!isset($products[$productID])) + { + /* Confirm if product exist. */ + $product = $this->product->getById($productID); + if(empty($product) or $product->deleted == 1) $productID = (int)key($products); + /* If product is invisable for curren user, then response access denied message. */ + if($productID && strpos(",{$this->app->user->view->products},", ",{$productID},") === false) + { + $productID = (int)key($products); + $this->accessDenied($this->lang->product->accessDenied); + } + } + + return $productID; + } + + /** + * 输出访问被拒绝提示信息。 + * Show accessDenied response. + * + * @param string $tips + * @access private + * @return void + */ + public function accessDenied($tips) + { + if(defined('TUTORIAL')) return true; + + echo js::alert($tips); + + if(!$this->server->http_referer) return print(js::locate(helper::createLink('product', 'index'))); + + $loginLink = $this->config->requestType == 'GET' ? "?{$this->config->moduleVar}=user&{$this->config->methodVar}=login" : "user{$this->config->requestFix}login"; + if(strpos($this->server->http_referer, $loginLink) !== false) return print(js::locate(helper::createLink('product', 'index'))); + + echo js::locate('back'); + } + + /** + * 设置导航菜单。 + * Set menu. + * + * @param int $productID + * @param int|string $branch + * @param int $module + * @param string $moduleType + * @param string $extra + * @access public + * @return void + */ + public function setMenu($productID = 0, $branch = '', $module = 0, $moduleType = '', $extra = ''): void + { + if(!$this->app->user->admin and strpos(",{$this->app->user->view->products},", ",$productID,") === false and $productID != 0 and !defined('TUTORIAL')) + { + $this->accessDenied($this->lang->product->accessDenied); + return; + } + + $product = $this->getByID($productID); + + $params = array('branch' => $branch); + common::setMenuVars('product', $productID, $params); + if(!$product) return; + + $this->lang->switcherMenu = $this->getSwitcher($productID, $extra, $branch); + + if($product->type == 'normal') + { + unset($this->lang->product->menu->settings['subMenu']->branch); + } + else + { + $branchLink = $this->lang->product->menu->settings['subMenu']->branch['link']; + $this->lang->product->menu->settings['subMenu']->branch['link'] = str_replace('@branch@', $this->lang->product->branchName[$product->type], $branchLink); + $this->lang->product->branch = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]); + } + + if(strpos($extra, 'requirement') !== false) unset($this->lang->product->moreSelects['willclose']); + } } diff --git a/module/product/zen.php b/module/product/zen.php index 1114a802d8..88988a4c58 100644 --- a/module/product/zen.php +++ b/module/product/zen.php @@ -596,132 +596,4 @@ class productZen extends product return $data; } - - /** - * 把访问的产品ID等状态信息保存到session和cookie中。 - * Save the product id user last visited to session and cookie. - * - * @param int $productID - * @param array $products - * @access protected - * @return int - */ - protected function saveVisitState(int $productID, array $products): int - { - if(defined('TUTORIAL')) return $productID; - - $productID = $this->getAccessableProductID($productID, $products); - - $this->session->set('product', $productID, $this->app->tab); - - setcookie('preProductID', (string)$productID, $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true); - - /* If preProductID changed, then reset preBranch. */ - if($this->cookie->preProductID != $this->session->product) - { - $this->cookie->set('preBranch', 0); - setcookie('preBranch', '0', $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, true); - } - - return $productID; - } - - /** - * 获取可访问的产品ID。 - * Get accessable product ID. - * - * @param int $productID - * @param array $products - * @access protected - * @return int - */ - protected function getAccessableProductID(int $productID, array $products): int - { - if(empty($productID)) - { - if($this->cookie->preProductID and isset($products[$this->cookie->preProductID])) $productID = $this->cookie->preProductID; - if(empty($this->session->product)) $productID = (int)key($products); - } - - /* 产品ID已经被删除,不存在于产品列表中。*/ - /* Product ID does not exsit in products list, it may be deleted. */ - if(!isset($products[$productID])) - { - /* Confirm if product exist. */ - $product = $this->product->getById($productID); - if(empty($product) or $product->deleted == 1) $productID = (int)key($products); - /* If product is invisable for curren user, then response access denied message. */ - if($productID && strpos(",{$this->app->user->view->products},", ",{$productID},") === false) - { - $productID = (int)key($products); - $this->accessDenied($this->lang->product->accessDenied); - } - } - - return $productID; - } - - /** - * 输出访问被拒绝提示信息。 - * Show accessDenied response. - * - * @param string $tips - * @access private - * @return void - */ - public function accessDenied($tips) - { - if(defined('TUTORIAL')) return true; - - echo(js::alert($tips)); - - if(!$this->server->http_referer) return print(js::locate(helper::createLink('product', 'index'))); - - $loginLink = $this->config->requestType == 'GET' ? "?{$this->config->moduleVar}=user&{$this->config->methodVar}=login" : "user{$this->config->requestFix}login"; - if(strpos($this->server->http_referer, $loginLink) !== false) return print(js::locate(helper::createLink('product', 'index'))); - - echo js::locate('back'); - } - - /** - * 设置导航菜单。 - * Set menu. - * - * @param int $productID - * @param int|string $branch - * @param int $module - * @param string $moduleType - * @param string $extra - * @access public - * @return void - */ - public function setMenu($productID = 0, $branch = '', $module = 0, $moduleType = '', $extra = ''): void - { - if(!$this->app->user->admin and strpos(",{$this->app->user->view->products},", ",$productID,") === false and $productID != 0 and !defined('TUTORIAL')) - { - $this->accessDenied($this->lang->product->accessDenied); - return; - } - - $product = $this->product->getByID($productID); - - $params = array('branch' => $branch); - common::setMenuVars('product', $productID, $params); - if(!$product) return; - - $this->lang->switcherMenu = $this->product->getSwitcher($productID, $extra, $branch); - - if($product->type == 'normal') - { - unset($this->lang->product->menu->settings['subMenu']->branch); - } - else - { - $branchLink = $this->lang->product->menu->settings['subMenu']->branch['link']; - $this->lang->product->menu->settings['subMenu']->branch['link'] = str_replace('@branch@', $this->lang->product->branchName[$product->type], $branchLink); - $this->lang->product->branch = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]); - } - - if(strpos($extra, 'requirement') !== false) unset($this->lang->product->moreSelects['willclose']); - } } diff --git a/module/programplan/config.php b/module/programplan/config.php index e5745773c6..f5933e928d 100644 --- a/module/programplan/config.php +++ b/module/programplan/config.php @@ -1,4 +1,7 @@ programplan->create = new stdclass(); $config->programplan->edit = new stdclass(); $config->programplan->create->requiredFields = 'name,begin,end'; diff --git a/module/programplan/config/form.php b/module/programplan/config/form.php index d46882ce28..e8f79f8933 100644 --- a/module/programplan/config/form.php +++ b/module/programplan/config/form.php @@ -14,3 +14,11 @@ $config->programplan->edit->form['realBegan'] = array('required' => false, 'type $config->programplan->edit->form['realEnd'] = array('required' => false, 'type' => 'string', 'default' => '0000-00-00'); $config->programplan->edit->form['output'] = array('required' => false, 'type' => 'array', 'default' => array()); +$config->programplan->ajaxCustom = new stdClass(); +$config->programplan->ajaxCustom->form = array(); +$config->programplan->ajaxCustom->form['type'] = array('required' => true, 'type' => 'string'); +$config->programplan->ajaxCustom->form['name'] = array('required' => true, 'type' => 'string'); +$config->programplan->ajaxCustom->form['status'] = array('required' => true, 'type' => 'string'); +$config->programplan->ajaxCustom->form['pri'] = array('required' => true, 'type' => 'int'); +$config->programplan->ajaxCustom->form['date'] = array('required' => false, 'type' => 'string', 'default' => helper::today()); + diff --git a/module/programplan/control.php b/module/programplan/control.php index e0ea815075..1a676c8bfe 100644 --- a/module/programplan/control.php +++ b/module/programplan/control.php @@ -149,7 +149,7 @@ class programplan extends control if($_POST) { $formData = form::data($this->config->programplan->create->form); - $this->programplan->create($formData, $projectID, $this->productID, $planID); + $this->programplan->create($formData, $projectID, $productID, $planID); if(dao::isError()) { $errors = dao::getError(); @@ -173,7 +173,7 @@ class programplan extends control $this->view->position[] = $this->lang->programplan->create; $executions = !empty($planID) ? $this->loadModel('execution')->getChildExecutions($planID, 'order_asc') : array(); - $plans = $this->programplan->getStage($planID ? $planID : $projectID, $this->productID, 'parent', 'order_asc'); + $plans = $this->programplan->getStage($planID ? $planID : $projectID, $productID, 'parent', 'order_asc'); if(!empty($planID) and !empty($plans) and $project->model == 'waterfallplus') { $executionType = 'stage'; @@ -266,6 +266,7 @@ class programplan extends control } /** + * 通过ajax请求保存自定义设置。 * Save custom settings via ajax. * * @access public @@ -279,34 +280,18 @@ class programplan extends control $this->loadModel('datatable'); $this->loadModel('setting'); - $stageCustom = $this->setting->getItem("owner=$owner&module=$module§ion=browse&key=stageCustom"); - $ganttFields = $this->setting->getItem("owner=$owner&module=$module§ion=ganttCustom&key=ganttFields"); - $zooming = $this->setting->getItem("owner=$owner&module=$module§ion=ganttCustom&key=zooming"); - if($_POST) { - $data = fixer::input('post')->get(); - $zooming = empty($data->zooming) ? '' : $data->zooming; - $stageCustom = empty($data->stageCustom) ? '' : implode(',', $data->stageCustom); - $ganttFields = empty($data->ganttFields) ? '' : implode(',', $data->ganttFields); - - $this->setting->setItem("$owner.$module.browse.stageCustom", $stageCustom); - $this->setting->setItem("$owner.$module.ganttCustom.ganttFields", $ganttFields); - $this->setting->setItem("$owner.$module.ganttCustom.zooming", $zooming); + $formData = form::data($this->config->product->form->create); + $this->programplanZen->beforeAjaxCustom($formData, $owner, $module); return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent')); } /* Set Custom. */ foreach(explode(',', $this->config->programplan->custom->customGanttFields) as $field) $customFields[$field] = $this->lang->programplan->ganttCustom[$field]; - - $this->view->zooming = $zooming; - $this->view->customFields = $customFields; - $this->view->showFields = $this->config->programplan->ganttCustom->ganttFields; - $this->view->ganttFields = $ganttFields; - $this->view->stageCustom = $stageCustom; - - $this->display(); + + $this->programplanZen->buildAjaxCustomView($owner, $module, $customFields); } /** diff --git a/module/programplan/model.php b/module/programplan/model.php index 4b12ef74ac..acc1506e53 100755 --- a/module/programplan/model.php +++ b/module/programplan/model.php @@ -767,12 +767,14 @@ class programplanModel extends model $plans[] = $plan; } + /* Set dao error and return false if the programplan has no name. */ if(empty($plans)) { dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->programplan->name); return false; } + /* Check every plan is valid. */ $totalPercent = 0; $milestone = 0; foreach($plans as $index => $plan) @@ -861,7 +863,7 @@ class programplanModel extends model { $orderIndex = empty($orders) ? 0 : count($orders); $lastID = $this->dao->select('id')->from(TABLE_EXECUTION)->orderBy('id_desc')->fetch('id'); - for($i = $orderIndex; $i < count($datas); $i ++) + for($i = $orderIndex; $i < count($plans); $i ++) { $lastID ++; $orders[$i] = $lastID * 5; @@ -881,33 +883,29 @@ class programplanModel extends model $linkProducts = array_keys($productList); foreach($linkProducts as $index => $productID) $linkBranches[$index] = $productList[$productID]->branches; } - $this->post->set('products', $linkProducts); - $this->post->set('branch', $linkBranches); - foreach($datas as $data) + foreach($plans as $plan) { /* Set planDuration and realDuration. */ if($this->config->edition == 'max') { - $data->planDuration = $this->getDuration($data->begin, $data->end); - $data->realDuration = $this->getDuration($data->realBegan, $data->realEnd); + $plan->planDuration = $this->getDuration($plan->begin, $plan->end); + $plan->realDuration = $this->getDuration($plan->realBegan, $plan->realEnd); } - $projectChanged = false; - $data->days = helper::diffDate($data->end, $data->begin) + 1; - $data->order = current($orders); + $plan->days = helper::diffDate($plan->end, $plan->begin) + 1; + $plan->order = current($orders); - - if($data->id) + if($plan->id) { - $stageID = $data->id; - unset($data->id, $data->type); + $stageID = $plan->id; + unset($plan->id, $plan->type); $oldStage = $this->getByID($stageID); - $planChanged = ($oldStage->name != $data->name || $oldStage->milestone != $data->milestone || $oldStage->begin != $data->begin || $oldStage->end != $data->end); + $planChanged = ($oldStage->name != $plan->name || $oldStage->milestone != $plan->milestone || $oldStage->begin != $plan->begin || $oldStage->end != $plan->end); - if($planChanged) $data->version = $oldStage->version + 1; - $this->dao->update(TABLE_PROJECT)->data($data) + if($planChanged) $plan->version = $oldStage->version + 1; + $this->dao->update(TABLE_PROJECT)->data($plan) ->autoCheck() ->batchCheck($this->config->programplan->edit->requiredFields, 'notempty') ->checkIF($plan->percent != '' and $setPercent, 'percent', 'float') @@ -915,56 +913,56 @@ class programplanModel extends model ->exec(); /* Add PM to stage teams and project teams. */ - if(!empty($data->PM)) + if(!empty($plan->PM)) { $team = $this->user->getTeamMemberPairs($stageID, 'execution'); - if(isset($team[$data->PM])) continue; + if(isset($team[$plan->PM])) continue; - $roles = $this->user->getUserRoles($data->PM); + $roles = $this->user->getUserRoles($plan->PM); $member = new stdclass(); $member->root = $stageID; - $member->account = $data->PM; - $member->role = zget($roles, $data->PM, ''); + $member->account = $plan->PM; + $member->role = zget($roles, $plan->PM, ''); $member->join = $now; $member->type = 'execution'; - $member->days = $data->days; + $member->days = $plan->days; $member->hours = $this->config->execution->defaultWorkhours; $this->dao->insert(TABLE_TEAM)->data($member)->exec(); - $this->execution->addProjectMembers($data->project, array($data->PM => $member)); + $this->execution->addProjectMembers($plan->project, array($plan->PM => $member)); } - if($data->acl != 'open') $this->user->updateUserView($stageID, 'sprint'); + if($plan->acl != 'open') $this->user->updateUserView($stageID, 'sprint'); /* Record version change information. */ if($planChanged) { $spec = new stdclass(); $spec->project = $stageID; - $spec->version = $data->version; - $spec->name = $data->name; - $spec->milestone = $data->milestone; - $spec->begin = $data->begin; - $spec->end = $data->end; + $spec->version = $plan->version; + $spec->name = $plan->name; + $spec->milestone = $plan->milestone; + $spec->begin = $plan->begin; + $spec->end = $plan->end; $this->dao->insert(TABLE_PROJECTSPEC)->data($spec)->exec(); } - $changes = common::createChanges($oldStage, $data); + $changes = common::createChanges($oldStage, $plan); $actionID = $this->action->create('execution', $stageID, 'edited'); $this->action->logHistory($actionID, $changes); } else { - unset($data->id); - $data->status = 'wait'; - $data->division = $project->division; - $data->version = 1; - $data->parentVersion = $data->parent == 0 ? 0 : $this->dao->findByID($data->parent)->from(TABLE_PROJECT)->fetch('version'); - $data->team = substr($data->name,0, 30); - $data->openedBy = $account; - $data->openedDate = $now; - $data->openedVersion = $this->config->version; - if(!isset($data->acl)) $data->acl = $this->dao->findByID($data->parent)->from(TABLE_PROJECT)->fetch('acl'); - $this->dao->insert(TABLE_PROJECT)->data($data) + unset($plan->id); + $plan->status = 'wait'; + $plan->division = $project->division; + $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); + $plan->openedBy = $account; + $plan->openedDate = $now; + $plan->openedVersion = $this->config->version; + if(!isset($plan->acl)) $plan->acl = $this->dao->findByID($plan->parent)->from(TABLE_PROJECT)->fetch('acl'); + $this->dao->insert(TABLE_PROJECT)->data($plan) ->autoCheck() ->batchCheck($this->config->programplan->create->requiredFields, 'notempty') ->checkIF($plan->percent != '' and $setPercent, 'percent', 'float') @@ -973,13 +971,13 @@ class programplanModel extends model if(!dao::isError()) { $stageID = $this->dao->lastInsertID(); - if($data->type == 'kanban') + if($plan->type == 'kanban') { $execution = $this->execution->getByID($stageID); $this->loadModel('kanban')->createRDKanban($execution); } - if($data->acl != 'open') $this->user->updateUserView($stageID, 'sprint'); + if($plan->acl != 'open') $this->user->updateUserView($stageID, 'sprint'); /* Create doc lib. */ $lib = new stdclass(); @@ -995,7 +993,7 @@ class programplanModel extends model /* Add creators and PM to stage teams and project teams. */ $teamMembers = array(); - $members = array($this->app->user->account, $data->PM); + $members = array($this->app->user->account, $plan->PM); $roles = $this->user->getUserRoles(array_values($members)); $team = $this->user->getTeamMemberPairs($stageID, 'execution'); foreach($members as $teamMember) @@ -1008,29 +1006,29 @@ class programplanModel extends model $member->role = zget($roles, $teamMember, ''); $member->join = $now; $member->type = 'execution'; - $member->days = $data->days; + $member->days = $plan->days; $member->hours = $this->config->execution->defaultWorkhours; $this->dao->insert(TABLE_TEAM)->data($member)->exec(); $teamMembers[$teamMember] = $member; } - $this->execution->addProjectMembers($data->project, $teamMembers); + $this->execution->addProjectMembers($plan->project, $teamMembers); $this->setTreePath($stageID); - if($data->acl != 'open') $this->user->updateUserView($stageID, 'sprint'); + if($plan->acl != 'open') $this->user->updateUserView($stageID, 'sprint'); /* Record version change information. */ $spec = new stdclass(); $spec->project = $stageID; - $spec->version = $data->version; - $spec->name = $data->name; - $spec->milestone = $data->milestone; - $spec->begin = $data->begin; - $spec->end = $data->end; + $spec->version = $plan->version; + $spec->name = $plan->name; + $spec->milestone = $plan->milestone; + $spec->begin = $plan->begin; + $spec->end = $plan->end; $this->dao->insert(TABLE_PROJECTSPEC)->data($spec)->exec(); - if($project->hasProduct) + if($project->hasProduct and !empty($linkProducts)) { - $this->action->create('execution', $stageID, 'opened', '', join(',', $_POST['products'])); + $this->action->create('execution', $stageID, 'opened', '', implode(',', $linkProducts)); } else { diff --git a/module/programplan/zen.php b/module/programplan/zen.php index 56b4940a69..ce8e94b748 100644 --- a/module/programplan/zen.php +++ b/module/programplan/zen.php @@ -73,6 +73,54 @@ class programplanZen extends programplan $this->view->isTopStage = $this->programplan->checkTopStage($plan->id); $this->view->isLeafStage = $this->programplan->checkLeafStage($plan->id); $this->view->PMUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $plan->PM); + } + + /** + * 处理请求数据 + * Processing request data. + * + * @param object $formData + * @param string $owner + * @param string $module + * @access protected + * @return object + */ + protected function beforeAjaxCustom(object $formData, string $owner, string $module): object + { + $data = $formData->get(); + + $zooming = empty($data->zooming) ? '' : $data->zooming; + $stageCustom = empty($data->stageCustom) ? '' : implode(',', $data->stageCustom); + $ganttFields = empty($data->ganttFields) ? '' : implode(',', $data->ganttFields); + + $this->setting->setItem("$owner.$module.browse.stageCustom", $stageCustom); + $this->setting->setItem("$owner.$module.ganttCustom.ganttFields", $ganttFields); + $this->setting->setItem("$owner.$module.ganttCustom.zooming", $zooming); + + return $data; + } + + /** + * 生成自定义设置视图。 + * Build custom setting view form data. + * + * @param string $owner + * @param string $module + * @access protected + * @return void + */ + protected function buildAjaxCustomView(string $owner, string $module, array $customFields) + { + $stageCustom = $this->setting->getItem("owner=$owner&module=$module§ion=browse&key=stageCustom"); + $ganttFields = $this->setting->getItem("owner=$owner&module=$module§ion=ganttCustom&key=ganttFields"); + $zooming = $this->setting->getItem("owner=$owner&module=$module§ion=ganttCustom&key=zooming"); + + $this->view->zooming = $zooming; + $this->view->customFields = $customFields; + $this->view->showFields = $this->config->programplan->ganttCustom->ganttFields; + $this->view->ganttFields = $ganttFields; + $this->view->stageCustom = $stageCustom; + $this->display(); } } diff --git a/module/todo/model.php b/module/todo/model.php index 2984d8e56e..080ca32168 100755 --- a/module/todo/model.php +++ b/module/todo/model.php @@ -123,7 +123,7 @@ class todoModel extends model { $oldTodo = $oldTodos[$todoID]; if(in_array($todo->type, $this->config->todo->moduleList)) $oldTodo->name = ''; - $this->updateTodoDataByID($todoID, $todo); + $this->todoTao->updateRow($todoID, $todo); if($oldTodo->status != 'done' and $todo->status == 'done') $this->loadModel('action')->create('todo', $todoID, 'finished', '', 'done'); @@ -538,7 +538,7 @@ class todoModel extends model */ public function getTodosByIdList(array $todoIdList): array { - return $this->todoTao->fetchRows($todoIdList); + return $this->dao->select('*')->from(TABLE_TODO)->where('id')->in(array_values($todoIdList))->fetchAll('id'); } /** @@ -553,20 +553,6 @@ class todoModel extends model return $this->dao->select('*')->from(TABLE_TODO)->where('cycle')->eq(1)->andWhere('deleted')->eq(0)->fetchAll('id'); } - /** - * 根据待办ID更新待办数据。 - * Update todo data by id. - * - * @param int $todoID - * @param object $todo - * @access public - * @return bool - */ - public function updateTodoDataByID(int $todoID, object $todo): bool - { - return $this->todoTao->updateRow($todoID, $todo); - } - /** * 根据待办类型获取优先级。 * Get pri by todo type. diff --git a/module/todo/test/model/create.php b/module/todo/test/model/create.php index 9ad2c7b3ec..951ec5ca21 100755 --- a/module/todo/test/model/create.php +++ b/module/todo/test/model/create.php @@ -11,13 +11,13 @@ title=测试 todoModel->create(); timeout=0 cid=1 -- 执行todoTest模块的createTest方法,参数是$todoWithoutName, $formData @0 +- 执行todoTest模块的createTest方法,参数是$todoWithoutName @0 -- 执行todoTest模块的createTest方法,参数是$todoInvalidEnd, $formData @0 +- 执行todoTest模块的createTest方法,参数是$todoInvalidObjectID @0 -- 执行todoTest模块的createTest方法,参数是$todo, $formData @2 +- 执行todoTest模块的createTest方法,参数是$todo @6 -- 执行todoTest模块的createTest方法,参数是$todoWithCycle, $formData @3 +- 执行todoTest模块的createTest方法,参数是$todoWithCycle @7 */ @@ -27,10 +27,6 @@ $tester->loadModel('todo'); zdTable('todo')->config('create')->gen(5); $today = date('Y-m-d'); -$formData = new stdClass; -$formData->rawdata = new stdclass; -$formData->rawdata->uid = ''; - $todo = new stdclass; $todo->name = 'TODO Create Test'; $todo->account = 'admin'; @@ -45,19 +41,20 @@ $todo->assignedDate = $today; $todoWithoutName = clone $todo; $todoWithoutName->name = ''; -$todoInvalidEnd = clone $todo; -$todoInvalidEnd->name = 'todoInvalidDate'; -$todoInvalidEnd->begin = '1000'; -$todoInvalidEnd->end = '0800'; +$todoInvalidObjectID = clone $todo; +$randModuleKey = array_rand($tester->config->todo->moduleList, 1); +$todoInvalidObjectID->name = 'todoInvalidObjectID'; +$todoInvalidObjectID->type = $tester->config->todo->moduleList[$randModuleKey]; +$todoInvalidObjectID->objectID = 0; $todoWithCycle = clone $todo; $todoWithCycle->type = 'cycle'; $todoWithCycle->cycle = 1; -$todoWithCycle->config = array('day' => 1, 'specify' => array('month' => 0, 'day' => 1), 'type' => 'day', 'beforeDays' => 1, 'end' => ''); +$todoWithCycle->config = json_encode(array('day' => 1, 'specify' => array('month' => 0, 'day' => 1), 'type' => 'day', 'beforeDays' => 1, 'end' => '')); $todoWithCycle->objectID = 0; $todoTest = new todoTest(); -r($todoTest->createTest($todoWithoutName, $formData)) && p() && e('0'); -r($todoTest->createTest($todoInvalidEnd, $formData)) && p() && e('0'); -r($todoTest->createTest($todo, $formData)) && p() && e('6'); -r($todoTest->createTest($todoWithCycle, $formData)) && p() && e('7'); +r($todoTest->createTest($todoWithoutName)) && p() && e('0'); +r($todoTest->createTest($todoInvalidObjectID)) && p() && e('0'); +r($todoTest->createTest($todo)) && p() && e('6'); +r($todoTest->createTest($todoWithCycle)) && p() && e('7'); diff --git a/module/todo/test/todo.class.php b/module/todo/test/todo.class.php index 6bc6a314da..fd14258ae8 100755 --- a/module/todo/test/todo.class.php +++ b/module/todo/test/todo.class.php @@ -13,13 +13,12 @@ class todoTest * Test create a todo. * * @param object $todoData - * @param object $formData * @access public * @return int */ - public function createTest($todoData, $formData) + public function createTest($todoData) { - $objectID = $this->objectModel->create($todoData, $formData); + $objectID = $this->objectModel->create($todoData); return $objectID ?: 0; } @@ -86,7 +85,7 @@ class todoTest */ public function batchUpdateTest(array $todos, int $todoID) { - $todoIDList = array($todoID => $todoID); + $todoIDList = array($todoID); $changes = $this->objectModel->batchUpdate($todos, $todoIDList); if(dao::isError()) return dao::getError();