| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- <?php
- /**
- * The zen file of custom module of ZenTaoPMS.
- *
- * @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 Shujie Tian <tianshujie@easycorp.ltd>
- * @package custom
- * @link https://www.zentao.net
- */
- class customZen extends custom
- {
- /**
- * 设置自定义字段列表。
- * Set the list of custom fields.
- *
- * @param string $module todo|story|task|bug|testcase|testtask|user|project
- * @param string $field priList|typeList|statusList|sourceList|reasonList|stageList|reviewRules|reviewResultList|review|severityList|osList|browserList|resolutionList|longlife|resultList|roleList|contactField|deleted|unitList
- * @param string $lang all|zh-cn|zh-tw|en|de|fr
- * @param string $currentLang all|zh-cn|zh-tw|en|de|fr
- * @access protected
- * @return void
- */
- protected function assignFieldListForSet($module = 'story', $field = 'priList', $lang = '', $currentLang = '')
- {
- $this->app->loadLang($module);
- if($lang == 'all')
- {
- $fieldList = array();
- $items = $this->custom->getItems("lang=all&module={$module}§ion={$field}&vision={$this->config->vision}");
- foreach($items as $key => $item)
- {
- $fieldList[$key] = $item->value;
- }
- }
- else
- {
- $fieldList = zget($this->lang->$module, $field, array());
- }
- /* Check whether the current language has been customized. */
- $lang = str_replace('_', '-', $lang);
- $dbFields = $this->custom->getItems("lang={$lang}&module={$module}§ion={$field}&vision={$this->config->vision}");
- if(empty($dbFields)) $dbFields = $this->custom->getItems("lang=" . ($lang == $currentLang ? 'all' : $currentLang) . "&module={$module}§ion={$field}");
- if($dbFields)
- {
- $dbField = reset($dbFields);
- if($lang != $dbField->lang)
- {
- $lang = str_replace('-', "_", $dbField->lang);
- foreach($fieldList as $key => $value)
- {
- if(isset($dbFields[$key]) && $value != $dbFields[$key]->value) $fieldList[$key] = $dbFields[$key]->value;
- }
- }
- }
- $this->view->fieldList = $fieldList;
- $this->view->dbFields = $dbFields;
- $this->view->lang2Set = str_replace('_', '-', $lang);
- }
- /**
- * 设置自定义列表变量。
- * Set the list of custom variables.
- *
- * @param string $module todo|story|task|bug|testcase|testtask|user|project
- * @param string $field priList|typeList|statusList|sourceList|reasonList|stageList|reviewRules|reviewResultList|review|severityList|osList|browserList|resolutionList|longlife|resultList|roleList|contactField|deleted|unitList
- * @param string $lang all|zh-cn|zh-tw|en|de|fr
- * @param string $currentLang all|zh-cn|zh-tw|en|de|fr
- * @access protected
- * @return void
- */
- protected function assignVarsForSet($module = 'story', $field = 'priList', $lang = '', $currentLang = '')
- {
- $this->assignFieldListForSet($module, $field, $lang, $currentLang);
- if($module == 'project' && $field == 'unitList')
- {
- $this->app->loadConfig($module);
- $unitList = zget($this->config->$module, 'unitList', '');
- $this->view->unitList = explode(',', $unitList);
- $this->view->defaultCurrency = zget($this->config->$module, 'defaultCurrency', 'CNY');
- }
- if(in_array($module, array('story', 'demand', 'requirement', 'epic')) && $field == 'reviewRules')
- {
- $this->app->loadConfig($module);
- $this->view->reviewRule = zget($this->config->$module, 'reviewRules', 'allpass');
- $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted');
- $this->view->superReviewers = zget($this->config->$module, 'superReviewers', '');
- }
- if(in_array($module, array('story', 'requirement', 'epic')) && $field == 'gradeRule')
- {
- $this->app->loadConfig($module);
- $this->view->gradeRule = zget($this->config->$module, 'gradeRule', '');
- }
- if(in_array($module, array('story', 'requirement', 'epic')) && $field == 'grade')
- {
- $this->view->storyGrades = $this->loadModel('story')->getGradeList($module);
- }
- if(in_array($module, array('story', 'testcase', 'demand', 'requirement', 'epic')) && $field == 'review')
- {
- $this->app->loadConfig($module);
- $this->loadModel('user');
- if(in_array($module, array('story', 'requirement', 'demand', 'epic')))
- {
- $this->view->depts = $this->loadModel('dept')->getDeptPairs();
- $this->view->forceReviewRoles = zget($this->config->$module, 'forceReviewRoles', '');
- $this->view->forceReviewDepts = zget($this->config->$module, 'forceReviewDepts', '');
- $this->view->forceNotReviewRoles = zget($this->config->$module, 'forceNotReviewRoles', '');
- $this->view->forceNotReviewDepts = zget($this->config->$module, 'forceNotReviewDepts', '');
- }
- $this->view->users = $module == 'story' ? $this->user->getCanCreateStoryUsers() : $this->user->getPairs('noclosed|nodeleted');
- $this->view->needReview = zget($this->config->$module, 'needReview', 1);
- $this->view->forceReview = zget($this->config->$module, 'forceReview', '');
- $this->view->forceNotReview = zget($this->config->$module, 'forceNotReview', '');
- }
- if($module == 'bug' && $field == 'longlife')
- {
- $this->app->loadConfig('bug');
- $this->view->longlife = $this->config->bug->longlife;
- }
- if($module == 'block' && $field == 'closed')
- {
- $this->loadModel('block');
- $closedBlock = isset($this->config->block->closed) ? $this->config->block->closed : '';
- $this->view->blockPairs = $this->block->getClosedBlockPairs($closedBlock);
- $this->view->closedBlock = $closedBlock;
- }
- if($module == 'user' && $field == 'deleted')
- {
- $this->app->loadConfig('user');
- $this->view->showDeleted = isset($this->config->user->showDeleted) ? $this->config->user->showDeleted : '0';
- }
- }
- /**
- * 设置自定义字段的值。
- * Set the value of the custom field.
- *
- * @param string $module todo|story|task|bug|testcase|testtask|user|project
- * @param string $field priList|typeList|statusList|sourceList|reasonList|stageList|reviewRules|reviewResultList|review|severityList|osList|browserList|resolutionList|longlife|resultList|roleList|contactField|deleted|unitList
- * @access protected
- * @return string|bool
- */
- protected function setFieldListForSet($module = 'story', $field = 'priList')
- {
- $data = $_POST;
- if($module == 'project' && $field == 'unitList')
- {
- if(empty($data['unitList'])) return dao::$errors['message'] = $this->lang->custom->currencyNotEmpty;
- if(empty($data['defaultCurrency'])) return dao::$errors['message'] = $this->lang->custom->defaultNotEmpty;
- $data['unitList'] = implode(',', $data['unitList']);
- $this->loadModel('setting')->setItems("system.$module", $data);
- }
- elseif(in_array($module, array('story', 'demand', 'requirement', 'epic')) && $field == 'review')
- {
- $this->setStoryReview($module, $data);
- }
- elseif(in_array($module, array('story', 'requirement', 'epic')) && $field == 'gradeRule')
- {
- $this->setGradeRule($module, $data);
- }
- elseif(in_array($module, array('story', 'requirement', 'epic')) && $field == 'grade')
- {
- $this->custom->setStoryGrade($module, $data);
- }
- elseif(in_array($module, array('story', 'demand', 'requirement', 'epic')) && $field == 'reviewRules')
- {
- if(!isset($data['superReviewers'])) $data['superReviewers'] = array();
- $data['superReviewers'] = implode(',', $data['superReviewers']);
- $this->loadModel('setting')->setItems("system.$module@{$this->config->vision}", $data);
- }
- elseif($module == 'testcase' && $field == 'review')
- {
- $this->setTestcaseReview($data);
- }
- elseif($module == 'bug' && $field == 'longlife')
- {
- $this->loadModel('setting')->setItems('system.bug', $data);
- }
- elseif($module == 'block' && $field == 'closed')
- {
- $data['closed'] = implode(',', $data['closed']);
- $this->loadModel('setting')->setItem('system.block.closed', zget($data, 'closed', ''));
- }
- elseif($module == 'user' && $field == 'contactField')
- {
- if(!isset($data['contactField'])) $data['contactField']= array();
- $data['contactField'] = implode(',', $data['contactField']);
- $this->loadModel('setting')->setItem('system.user.contactField', $data['contactField']);
- }
- elseif($module == 'user' && $field == 'deleted')
- {
- $this->loadModel('setting')->setItem('system.user.showDeleted', $data['showDeleted']);
- }
- else
- {
- if(!$this->post->keys) return dao::$errors['message'] = sprintf($this->lang->error->notempty, $this->lang->custom->key);
- $this->checkKeysForSet($module, $field);
- }
- return !dao::isError();
- }
- /**
- * 检查自定义key值是否合法。
- * Check whether the key of custom is valid.
- *
- * @param string $module todo|story|task|bug|testcase|testtask|user|project
- * @param string $field priList|typeList|statusList|sourceList|reasonList|stageList|reviewRules|reviewResultList|review|severityList|osList|browserList|resolutionList|longlife|resultList|roleList|contactField|deleted|unitList
- * @access protected
- * @return bool
- */
- protected function checkKeysForSet($module = 'story', $field = 'priList')
- {
- $this->checkDuplicateKeys($module, $field);
- if(dao::$errors) return false;
- $oldCustoms = $this->checkInvalidKeys($module, $field);
- if(dao::$errors) return false;
- $lang = $_POST['lang'];
- $currentLang = $this->app->getClientLang();
- $this->custom->deleteItems("lang={$lang}&module={$module}§ion={$field}&vision={$this->config->vision}");
- if($lang == 'all') $this->custom->deleteItems("lang={$currentLang}&module={$module}§ion={$field}&vision={$this->config->vision}");
- $this->checkEmptyKeys($module, $field);
- if($module == 'testcase' && $field == 'stageList')
- {
- $oldItems = array();
- foreach($oldCustoms as $key => $item) $oldItems[$key] = $item->value;
- $oldItems = arrayUnion($oldItems, zget($this->lang->$module, $field, array()));
- $newItems = array();
- $newCustoms = $this->custom->getItems("lang={$lang}&module={$module}§ion={$field}");
- foreach($newCustoms as $key => $item) $newItems[$key] = $item->value;
- $addItems = array_diff_key($newItems, $oldItems);
- $delItems = array_diff_key($oldItems, $newItems);
- $changeItems = array();
- foreach($oldItems as $key => $item)
- {
- if(!empty($newItems[$key]) && $newItems[$key] != $item) $changeItems[$key] = $newItems[$key];
- }
- $this->loadModel('upgrade');
- if($addItems) $this->upgrade->createTestcaseDeliverable($addItems);
- if($delItems) $this->upgrade->deleteTestcaseDeliverable($delItems);
- if($changeItems) $this->upgrade->changeTestcaseDeliverable($changeItems);
- }
- return !dao::isError();
- }
- /**
- * 检查自定义key值是否重复。
- * Check whether the key of custom is duplicate.
- *
- * @param string $module todo|story|task|bug|testcase|testtask|user|project
- * @param string $field priList|typeList|statusList|sourceList|reasonList|stageList|reviewRules|reviewResultList|review|severityList|osList|browserList|resolutionList|longlife|resultList|roleList|contactField|deleted|unitList
- * @access protected
- * @return bool|string
- */
- protected function checkDuplicateKeys($module = 'story', $field = 'priList')
- {
- $keys = array();
- if(isset($_POST['keys']))
- {
- foreach($_POST['keys'] as $key)
- {
- if($module == 'testtask' && $field == 'typeList' && empty($key)) continue;
- if($key && in_array($key, $keys)) return dao::$errors['message'] = sprintf($this->lang->custom->notice->repeatKey, $key);
- $keys[] = $key;
- }
- }
- return true;
- }
- /**
- * 检查自定义key值是否正确。
- * Check whether the key of custom is valid.
- *
- * @param string $module todo|story|task|bug|testcase|testtask|user|project
- * @param string $field priList|typeList|statusList|sourceList|reasonList|stageList|reviewRules|reviewResultList|review|severityList|osList|browserList|resolutionList|longlife|resultList|roleList|contactField|deleted|unitList
- * @access protected
- * @return array|string
- */
- protected function checkInvalidKeys($module = 'story', $field = 'priList')
- {
- $lang = $_POST['lang'];
- $oldCustoms = $this->custom->getItems("lang={$lang}&module={$module}§ion={$field}");
- foreach($_POST['keys'] as $index => $key)
- {
- if(!empty($key)) $key = trim($key);
- /* Invalid key. It should be numbers. (It includes severityList in bug module && priList in story, task, bug, testcasea, testtask && todo module.) */
- if(($field == 'priList' || $field == 'severityList') && (!is_numeric($key) || $key > 255)) return dao::$errors['message'] = $this->lang->custom->notice->invalidNumberKey;
- if(!empty($key) && !isset($oldCustoms[$key]) && $key != 'n/a' && !validater::checkREG($key, '/^[a-z_A-Z_0-9]+$/')) return dao::$errors['message'] = $this->lang->custom->notice->invalidStringKey;
- /* The length of roleList in user module is less than 10. check it when saved. */
- if($module == 'user' && $field == 'roleList' && strlen($key) > 10) return dao::$errors['message'] = $this->lang->custom->notice->invalidStrlen['ten'];
- /* The length of typeList in todo module is less than 15. check it when saved. */
- if($module == 'todo' && $field == 'typeList' && strlen($key) > 15) return dao::$errors['message'] = $this->lang->custom->notice->invalidStrlen['fifteen'];
- /* The length of sourceList in story module && typeList in task module is less than 20, check it when saved. */
- if((($module == 'story' && $field == 'sourceList') || ($module == 'task' && $field == 'typeList')) && strlen($key) > 20) return dao::$errors['message'] = $this->lang->custom->notice->invalidStrlen['twenty'];
- /* The length of field that in bug && testcase module && reasonList in story && task module is less than 30, check it when saved. */
- if((in_array($module, array('bug', 'testcase')) || (in_array($module, array('story', 'task')) && $field == 'reasonList')) && strlen($key) > 30) return dao::$errors['message'] = $this->lang->custom->notice->invalidStrlen['thirty'];
- }
- return $oldCustoms;
- }
- /**
- * 检查自定义key值是否为空。
- * Check whether the key of custom is empty.
- *
- * @param string $module todo|story|task|bug|testcase|testtask|user|project
- * @param string $field priList|typeList|statusList|sourceList|reasonList|stageList|reviewRules|reviewResultList|review|severityList|osList|browserList|resolutionList|longlife|resultList|roleList|contactField|deleted|unitList
- * @access protected
- * @return bool|string
- */
- protected function checkEmptyKeys($module = 'story', $field = 'priList')
- {
- $lang = $_POST['lang'];
- $emptyKey = false;
- $keys = array();
- foreach($_POST['keys'] as $index => $key)
- {
- if(!$key && $emptyKey) continue;
- $value = $_POST['values'][$index];
- $system = $_POST['systems'][$index];
- if($key && trim($value) === '') return dao::$errors['message'] = $this->lang->custom->notice->valueEmpty; // Fix bug #23538.
- $this->custom->setItem("{$lang}.{$module}.{$field}.{$key}.{$system}", $value);
- if(!$key) $emptyKey = true;
- }
- return true;
- }
- /**
- * 设置需求评审规则。
- * Set the review rules of story.
- *
- * @param string $module
- * @param array $data
- * @access protected
- * @return bool
- */
- protected function setStoryReview($module, $data)
- {
- $forceFields = array('forceReview', 'forceNotReview', 'forceReviewRoles', 'forceNotReviewRoles', 'forceReviewDepts', 'forceNotReviewDepts');
- foreach($forceFields as $forceField)
- {
- if(!isset($data[$forceField])) $data[$forceField] = array();
- $data[$forceField] = implode(',', $data[$forceField]);
- }
- foreach($data as $key => $value)
- {
- if($key == 'needReview') continue;
- if(strpos($key, 'Not') && $data['needReview'] == 0) $data[$key] = '';
- if(!strpos($key, 'Not') && $data['needReview'] == 1) $data[$key] = '';
- }
- $this->loadModel('setting')->setItems("system.{$module}@{$this->config->vision}", $data);
- return !dao::isError();
- }
- /**
- * 设置需求细分流程。
- * Set the rule of story grade.
- *
- * @param string $module
- * @param array $data
- * @access protected
- * @return bool
- */
- public function setGradeRule($module, $data)
- {
- $this->loadModel('setting')->setItems("system.{$module}", $data);
- return !dao::isError();
- }
- /**
- * 设置用例评审规则。
- * Set testcase review rules.
- *
- * @param array $data
- * @access protected
- * @return bool
- */
- protected function setTestcaseReview($data)
- {
- if($data['needReview'])
- {
- unset($data['forceReview']);
- if(!isset($data['forceNotReview'])) $data['forceNotReview'] = array();
- $data['forceNotReview'] = implode(',', $data['forceNotReview']);
- }
- else
- {
- unset($data['forceNotReview']);
- if(!isset($data['forceReview'])) $data['forceReview'] = array();
- $data['forceReview'] = implode(',', $data['forceReview']);
- }
- $this->loadModel('setting')->setItems("system.testcase", $data);
- return !dao::isError();
- }
- }
|