| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645 |
- <?php
- /**
- * The control file of custom of ZenTaoPMS.
- *
- * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
- * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
- * @author Chunsheng Wang <chunsheng@cnezsoft.com>
- * @package custom
- * @version $Id$
- * @link https://www.zentao.net
- */
- class custom extends control
- {
- /**
- * Index.
- *
- * @access public
- * @return void
- */
- public function index()
- {
- if($this->config->vision == 'lite') return $this->locate(inlink('execution'));
- if(common::hasPriv('custom', 'set')) return $this->locate(inlink('set', "module=project&field=" . key($this->lang->custom->project->fields)));
- if(common::hasPriv('custom', 'product')) return $this->locate(inlink('product'));
- if(common::hasPriv('custom', 'execution')) return $this->locate(inlink('execution'));
- foreach($this->lang->custom->system as $sysObject)
- {
- if(common::hasPriv('custom', $sysObject)) return $this->locate(inlink($sysObject));
- }
- }
- /**
- * 设置对象字段的语言项。
- * Set the language items of the object fields.
- *
- * @param string $module todo|story|task|bug|testcase|testtask|user|project|block
- * @param string $field priList|typeList|statusList|sourceList|reasonList|stageList|reviewRules|reviewResultList|review|severityList|osList|browserList|resolutionList|longlife|resultList|roleList|contactField|deleted|unitList|closed
- * @param string $lang all|zh-cn|zh-tw|en|de|fr
- * @access public
- * @return void
- */
- public function set($module = 'story', $field = 'priList', $lang = '')
- {
- if(empty($lang)) $lang = $this->app->getClientLang();
- if($module == 'user' && $field == 'priList') $field = 'statusList';
- if($module == 'block' && $field == 'priList') $field = 'closed';
- $currentLang = $this->app->getClientLang();
- $this->customZen->assignVarsForSet($module, $field, $lang, $currentLang);
- if(strtolower($this->server->request_method) == "post")
- {
- $this->customZen->setFieldListForSet($module, $field);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- if($module == 'baseline' && $field == 'objectList') return $this->sendSuccess(array('load' => true));
- if($module == 'reviewcl') return $this->sendSuccess(array('load' => true));
- return $this->sendSuccess(array('load' => $this->createLink('custom', 'set', "module=$module&field=$field&lang=" . ($lang == 'all' ? $lang : ''))));
- }
- $this->view->title = $this->lang->custom->common . $this->lang->hyphen . $this->lang->$module->common;
- $this->view->field = $field;
- $this->view->module = $module;
- $this->view->currentLang = $currentLang;
- $this->view->canAdd = strpos($this->config->custom->canAdd[$module], $field) !== false;
- $this->display();
- }
- /**
- * 还原默认语言项。删除相关项。
- * Restore the default lang. Delete the related items.
- *
- * @param string $module
- * @param string $field
- * @access public
- * @return void
- */
- public function restore($module, $field)
- {
- if($module == 'user' && $field == 'contactField')
- {
- $this->loadModel('setting')->deleteItems("module={$module}&key={$field}");
- }
- else
- {
- $this->custom->deleteItems("module={$module}§ion={$field}");
- }
- return $this->sendSuccess(array('load' => true));
- }
- /**
- * 设置表单必填字段。
- * Set the required fields.
- *
- * @param string $moduleName product|story|productplan|release|execution|task|bug|testcase|testsuite|testtask|testreport|caselib|doc|user|project|build
- * @access public
- * @return void
- */
- public function required($moduleName = '')
- {
- if(empty($moduleName)) $moduleName = current($this->config->custom->requiredModules);
- if($this->server->request_method == 'POST')
- {
- $this->custom->saveRequiredFields($moduleName, $_POST);
- return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => inlink('required', "moduleName=$moduleName")));
- }
- foreach($this->config->custom->requiredModules as $requiredModule) $this->app->loadLang($requiredModule);
- /* Get this module requiredFields. */
- $this->loadModel($moduleName);
- if($moduleName == 'user') $this->app->loadModuleConfig($moduleName);
- $requiredFields = $this->custom->getRequiredFields($this->config->$moduleName);
- if($moduleName == 'doc')
- {
- unset($requiredFields['createlib']);
- unset($requiredFields['editlib']);
- }
- $this->view->title = $this->lang->custom->required;
- $this->view->requiredFields = $requiredFields;
- $this->view->module = $moduleName;
- $this->display();
- }
- /**
- * 时区。
- * Timezone.
- *
- * @access public
- * @return void
- */
- public function timezone()
- {
- if(strtolower($_SERVER['REQUEST_METHOD']) == "post")
- {
- $this->loadModel('setting')->setItems('system.common', $_POST);
- return $this->sendSuccess(array('load' => true));
- }
- unset($this->lang->admin->menu->custom['subModule']);
- $this->lang->admin->menu->system['subModule'] = 'custom';
- $this->view->title = $this->lang->custom->timezone;
- $this->display();
- }
- /**
- * 需求概念列表。
- * Browse story concept.
- *
- * @access public
- * @return void
- */
- public function browseStoryConcept()
- {
- $this->view->title = $this->lang->custom->browseStoryConcept;
- $this->view->URSRList = $this->custom->getURSRList();
- $this->view->module = 'product';
- $this->display();
- }
- /**
- * 设置需求概念。
- * Set story concept.
- *
- * @access public
- * @return void
- */
- public function setStoryConcept()
- {
- if($_POST)
- {
- $result = $this->custom->setURAndSR($_POST);
- if(!$result) return $this->send(array('result' => 'fail', 'message' => $this->lang->custom->notice->URSREmpty));
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
- }
- if(!common::hasPriv('custom', 'setDefaultConcept')) unset($this->config->custom->browseStoryConcept->dtable->fieldList['default']);
- $this->view->title = $this->lang->custom->setStoryConcept;
- $this->display();
- }
- /**
- * 编辑需求概念。
- * Edit story concept.
- *
- * @param int $key
- * @access public
- * @return void
- */
- public function editStoryConcept($key = 0)
- {
- if($_POST)
- {
- $result = $this->custom->updateURAndSR($key, '', $_POST);
- if(!$result) return $this->send(array('result' => 'fail', 'message' => $this->lang->custom->notice->URSREmpty));
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
- }
- $lang = $this->app->getClientLang();
- $URSR = $this->custom->getURSRConcept($key, $lang);
- $this->view->URSR = json_decode($URSR);
- $this->display();
- }
- /**
- * 设置默认需求概念。
- * Set story concept.
- *
- * @param int $key
- * @access public
- * @return void
- */
- public function setDefaultConcept($key = 0)
- {
- $this->loadModel('setting')->setItem('system.custom.URSR', $key);
- return $this->sendSuccess(array('load' => inlink('browsestoryconcept')));
- }
- /**
- * Delete story concept.
- *
- * @param int $key
- * @access public
- * @return void
- */
- public function deleteStoryConcept($key = 0)
- {
- $lang = $this->app->getClientLang();
- $this->custom->deleteItems("lang=$lang§ion=URSRList&key=$key");
- $defaultConcept = $this->loadModel('setting')->getItem('owner=system&module=custom&key=URSR');
- $this->dao->update(TABLE_CONFIG)
- ->set('`value`')->eq($defaultConcept)
- ->where('module')->eq('common')
- ->andWhere('`key`')->eq('URSR')
- ->andWhere('`value`')->eq($key)
- ->exec();
- return $this->send(array('result' => 'success', 'load' => inlink('browseStoryConcept')));
- }
- /**
- * 项目关闭设置。
- * Set whether the closed project is read-only.
- *
- * @access public
- * @return void
- */
- public function project()
- {
- if($_POST)
- {
- $this->loadModel('setting')->setItem("system.common.CRProject@{$this->config->vision}", $this->post->project);
- return $this->sendSuccess(array('load' => true));
- }
- $this->view->title = $this->lang->projectCommon;
- $this->view->module = 'project';
- $this->display();
- }
- /**
- * 执行关闭设置。
- * Set whether the closed execution is read-only.
- *
- * @access public
- * @return void
- */
- public function execution()
- {
- if($_POST)
- {
- $this->loadModel('setting')->setItem("system.common.CRExecution@{$this->config->vision}", $this->post->execution);
- return $this->sendSuccess(array('load' => true));
- }
- $this->view->title = $this->lang->custom->executionCommon;
- $this->view->module = 'execution';
- $this->display();
- }
- /**
- * 产品关闭设置。
- * Set whether the closed product is read-only.
- *
- * @access public
- * @return void
- */
- public function product()
- {
- if($_POST)
- {
- $this->loadModel('setting')->setItem('system.common.CRProduct', $this->post->product);
- return $this->sendSuccess(array('load' => true));
- }
- $this->view->title = $this->lang->custom->productName;
- $this->view->module = 'product';
- $this->display();
- }
- /**
- * 看板关闭设置。
- * Set whether the kanban is read-only.
- *
- * @param string $type closedSetting|expireReminder
- * @access public
- * @return void
- */
- public function kanban($type = 'closedSetting')
- {
- $this->loadModel('kanban');
- if($_POST)
- {
- if($type == 'closedSetting')
- {
- $this->loadModel('setting')->setItem("system.common.CRKanban", $this->post->kanban);
- }
- else
- {
- $this->loadModel('setting')->setItem('system.kanban.reminder.expireDays', (int)$this->post->expireDays);
- }
- return $this->sendSuccess(array('load' => true));
- }
- $this->view->title = $this->lang->custom->kanban;
- $this->view->type = $type;
- $this->display();
- }
- /**
- * 流程设置。
- * Set flow.
- *
- * @access public
- * @return void
- */
- public function flow()
- {
- if($_POST)
- {
- $this->custom->setConcept($_POST['sprintConcept']);
- $this->loadModel('setting')->setItem('system.custom.hourPoint', $this->post->hourPoint);
- return $this->sendSuccess(array('load' => true));
- }
- $this->view->title = $this->lang->custom->flow;
- $this->display();
- }
- /**
- * 模式管理。
- * Mode management.
- *
- * @access public
- * @return void
- */
- public function mode()
- {
- $mode = zget($this->config->global, 'mode', 'light');
- if($this->post->mode && $this->post->mode != $mode) // If mode value change.
- {
- $mode = $this->post->mode;
- $program = isset($_POST['program']) ? $_POST['program'] : 0;
- /* Create the program to which the project in light mode belongs. */
- if($mode == 'light' && empty($program)) $program = $this->loadModel('program')->createDefaultProgram();
- $this->loadModel('setting')->setItem('system.common.global.mode', $mode);
- $this->setting->setItem('system.common.global.defaultProgram', $program);
- $this->custom->disableFeaturesByMode($mode);
- if($mode == 'light') $this->custom->processProjectAcl();
- if($mode == 'ALM')
- {
- $closedFeatures = $this->setting->getItem('owner=system&module=common§ion=&key=closedFeatures');
- $this->loadModel('setting')->setItem('system.common.closedFeatures', $closedFeatures . ',otherOA');
- }
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- return $this->sendSuccess(array('callback' => '$.apps.updateAppsMenu(true);', 'load' => true, 'closeModel' => true));
- }
- list($disabledFeatures, $enabledProjectFeatures, $disabledProjectFeatures) = $this->custom->computeFeatures();
- $this->view->title = $this->lang->custom->mode;
- $this->view->mode = $mode;
- $this->view->programs = $this->loadModel('program')->getTopPairs('noclosed', true);
- $this->view->programID = isset($this->config->global->defaultProgram) ? $this->config->global->defaultProgram : 0;
- $this->view->disabledFeatures = $disabledFeatures;
- $this->view->enabledProjectFeatures = $enabledProjectFeatures;
- $this->view->disabledProjectFeatures = $disabledProjectFeatures;
- $this->view->currentModeTips = sprintf($this->lang->custom->currentModeTips, $this->lang->custom->modeList[$mode], $this->lang->custom->modeList[$mode == 'light' ? 'ALM' : 'light']);
- $this->display();
- }
- /**
- * 保存自定义字段。
- * Ajax save custom fields.
- *
- * @param string $module
- * @param string $section
- * @param string $key
- * @access public
- * @return void
- */
- public function ajaxSaveCustomFields($module, $section, $key)
- {
- if(!isset($this->config->custom->customFields[$module][$section])) return;
- if(!in_array($key, $this->config->custom->customFields[$module][$section])) return;
- $this->loadModel('setting');
- $global = $this->post->global;
- $action = $this->post->action;
- $account = $this->app->user->account;
- if($global) $account = 'system';
- if($this->server->request_method == 'POST' && $action != 'reset')
- {
- $fields = $this->post->fields;
- if(is_array($fields)) $fields = implode(',', $fields);
- if($module == 'execution' && $section == 'custom' && $key == 'createFields' && strpos(",{$fields},", ',team,') !== false) $fields .= ',teams';
- $this->setting->setItem("{$account}.{$module}.{$section}.{$key}", $fields);
- if(in_array($module, array('story', 'task', 'testcase')) && $section == 'custom' && $key == 'batchCreateFields') return;
- if($module == 'bug' && $section == 'custom' && $key == 'batchCreateFields') return;
- }
- else
- {
- $this->setting->deleteItems("owner={$account}&module={$module}§ion={$section}&key={$key}");
- }
- $this->loadModel('common')->loadConfigFromDB();
- $this->app->loadLang($module);
- $this->app->loadConfig($module, '', true);
- if($module == 'programplan' && $section == 'custom') $key = 'createFields';
- $customFields = zget(zget($this->config->$module, 'list', array()), $section . ucfirst($key), '');
- $showFields = zget(zget($this->config->$module, $section, array()), $key, '');
- if($module == 'marketresearch') return print(js::reload('parent'));
- return $this->send(array('result' => 'success', 'key' => $key, 'callback' => 'loadCurrentPage', 'customFields' => $customFields, 'showFields' => $showFields));
- }
- /**
- * 获取自定义列。
- * Ajax get custom fields.
- *
- * @param string $module
- * @param string $section
- * @param string $key
- * @access public
- * @return void
- */
- public function ajaxGetCustomFields($module, $section, $key)
- {
- return print($this->loadModel('setting')->getItem("owner={$this->app->user->account}&module={$module}§ion={$section}&key={$key}"));
- }
- /**
- * 重置必填字段。
- * Reset required.
- *
- * @param string $module
- * @access public
- * @return void
- */
- public function resetRequired($module)
- {
- $this->loadModel('setting')->deleteItems("owner=system&module={$module}&key=requiredFields");
- return $this->send(array('result' => 'success', 'load' => true));
- }
- /**
- * 设置代号。
- * Set code.
- *
- * @access public
- * @return void
- */
- public function code()
- {
- if($_POST)
- {
- $this->loadModel('setting')->setItem('system.common.setCode', $this->post->code);
- return $this->sendSuccess(array('load' => true));
- }
- $this->view->title = $this->lang->custom->code;
- $this->display();
- }
- /**
- * 设置是否启用工作量占比。
- * Set whether to enable the workload percent.
- * @access public
- * @return void
- */
- public function percent()
- {
- if($_POST)
- {
- $this->loadModel('setting')->setItem('system.common.setPercent', $this->post->percent);
- return $this->sendSuccess(array('load' => true));
- }
- $this->view->title = $this->lang->stage->percent;
- $this->display();
- }
- /**
- * 设置每日可用工时和休息日。
- * Set hours and weekend
- *
- * @param string $type hours|weekend
- * @access public
- * @return void
- */
- public function hours($type = 'hours')
- {
- if($_POST)
- {
- $data = $_POST;
- $type = $_POST['type'];
- unset($data['type']);
- if($data['weekend'] != 1) unset($data['restDay']);
- if($type == 'hours' && ($data['defaultWorkhours'] < 0 || $data['defaultWorkhours'] > 24)) $this->sendError($this->lang->custom->hoursError);
- $this->loadModel('setting')->setItems('system.execution', $data);
- return $this->sendSuccess(array('load' => inLink('hours', "type={$type}")));
- }
- $this->app->loadConfig('execution');
- $this->view->title = $this->lang->workingHour;
- $this->view->type = $type;
- $this->view->weekend = $this->config->execution->weekend;
- $this->view->workhours = $this->config->execution->defaultWorkhours;
- $this->view->restDay = zget($this->config->execution, 'restDay', 0);
- $this->view->module = 'setDate';
- $this->display();
- }
- /**
- * 设置是否限制任务开始和结束时间。
- * Set whether the task begin and end date is limited to the execution begin and end date.
- *
- * @access public
- * @return void
- */
- public function limitTaskDate()
- {
- if($_POST)
- {
- $this->loadModel('setting')->setItem('system.common.limitTaskDate', $this->post->limitTaskDate);
- return $this->sendSuccess(array('load' => true));
- }
- $this->view->title = $this->lang->custom->beginAndEndDate;
- $this->view->module = 'task';
- $this->display();
- }
- /**
- * Ajax set menu
- *
- * @access public
- * @return void
- */
- public function ajaxSetMenu()
- {
- if($_POST)
- {
- $menu = $this->post->menu; // 导航类型,nav(左侧主导航)|$app(顶部一级导航)|$app-home(项目集、项目的首页导航)|$app-$subMenu(顶部二级导航)|admin-$menuKey(后台导航)
- $items = $this->post->items; // 导航项
- $account = $this->app->user->account;
- $oldMenu = isset($this->config->customMenu->{$menu}) ? $this->config->customMenu->{$menu} : '';
- /* 之前隐藏的导航若没开启继续保持隐藏。 */
- if($oldMenu)
- {
- $oldMenus = json_decode($oldMenu);
- $menus = json_decode($items);
- $menuNames = array();
- foreach($menus as $item) $menuNames[] = $item->name;
- foreach($oldMenus as $key => $item)
- {
- if(!empty($item->hidden) && !in_array($item->name, $menuNames)) $menus[] = $item;
- }
- $items = json_encode($menus);
- }
- if($menu && $items) $this->loadModel('setting')->setItem("$account.common.customMenu.$menu@{$this->config->vision}", $items);
- }
- $this->send(array('result' => 'success'));
- }
- /**
- * Ajax restore menu
- *
- * @access public
- * @return void
- */
- public function ajaxRestoreMenu()
- {
- if($_POST)
- {
- $account = $this->app->user->account;
- $menu = $this->post->menu;
- $this->loadModel('setting')->deleteItems("owner={$account}&module=common§ion=customMenu&key=$menu");
- }
- $this->send(array('result' => 'success'));
- }
- }
|