zen.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <?php
  2. /**
  3. * The zen file of transfer module of ZenTaoPMS.
  4. *
  5. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
  6. * @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  7. * @author Tang Hucheng<tanghucheng@easycorp.ltd>
  8. * @package transfer
  9. * @link https://www.zentao.net
  10. */
  11. class transferZen extends transfer
  12. {
  13. /**
  14. * 将参数转成变量存到SESSION中。
  15. * Set SESSION by params.
  16. *
  17. * @param string $module
  18. * @param string $params
  19. * @access protected
  20. * @return array
  21. */
  22. protected function saveSession($module, $params = '')
  23. {
  24. if($params)
  25. {
  26. /* 按, 分隔params。*/
  27. /* Split parameters into variables (executionID=1,status=open). */
  28. $params = explode(',', $params);
  29. foreach($params as $key => $param)
  30. {
  31. $param = explode('=', $param);
  32. $params[$param[0]] = $param[1];
  33. unset($params[$key]);
  34. }
  35. /* Save params to session. */
  36. $this->session->set(($module . 'TransferParams'), $params);
  37. return $params;
  38. }
  39. return array();
  40. }
  41. /**
  42. * 处理Task模块导出模板数组。
  43. * Process Task module export template array.
  44. *
  45. * @param string $module
  46. * @param string $params
  47. * @access protected
  48. * @return string
  49. * @param int $executionID
  50. * @param string $fields
  51. */
  52. protected function processTaskTemplateFields($executionID = 0, $fields = '')
  53. {
  54. $execution = $this->loadModel('execution')->getByID($executionID);
  55. /* 运维类型的迭代和需求跟总结评审类型的阶段,在导出字段中隐藏需求字段。*/
  56. /* Hide requirement field in Ops type. */
  57. if(isset($execution) and $execution->type == 'ops' or in_array($execution->attribute, array('request', 'review'))) $fields = str_replace('story,', '', $fields);
  58. return $fields;
  59. }
  60. /**
  61. * 初始化字段列表并拼接下拉菜单数据。
  62. * Init field list and append dropdown menu data.
  63. *
  64. * @param string $module
  65. * @param string $fields
  66. * @access protected
  67. * @return void
  68. */
  69. protected function initTemplateFields($module, $fields = '')
  70. {
  71. /* 构造该模块的导出模板字段数据。*/
  72. /* Construct export template field data. */
  73. $fieldList = $this->transfer->initFieldList($module, $fields);
  74. /* 获取下拉字段的数据列表。*/
  75. /* Get dropdown field data list. */
  76. $list = $this->transfer->setListValue($module, $fieldList);
  77. if($list) foreach($list as $listName => $listValue) $this->post->set($listName, $listValue);
  78. $fields = $this->transfer->generateExportDatas($fieldList);
  79. $this->post->set('fields', $fields['fields']);
  80. $this->post->set('kind', isset($_POST['kind']) ? $_POST['kind'] : $module);
  81. $this->post->set('rows', array());
  82. $this->post->set('extraNum', $this->post->num);
  83. $this->post->set('fileName', isset($_POST['fileName']) ? $_POST['fileName'] : $module . 'Template');
  84. }
  85. /**
  86. * 处理导入字段。
  87. * Process import fields.
  88. *
  89. * @param string $module
  90. * @param array $fields
  91. * @access protected
  92. * @return array
  93. */
  94. protected function formatFields($module, $fields = array())
  95. {
  96. if($module == 'story')
  97. {
  98. $product = $this->loadModel('product')->getByID($this->session->storyTransferParams['productID']);
  99. if($product->type == 'normal') unset($fields['branch']);
  100. if($this->session->storyType == 'requirement') unset($fields['plan']);
  101. }
  102. if($module == 'bug')
  103. {
  104. $product = $this->loadModel('product')->getByID($this->session->bugTransferParams['productID']);
  105. if($product->type == 'normal') unset($fields['branch']);
  106. if($product->shadow and ($this->app->tab == 'execution' or $this->app->tab == 'project')) unset($fields['product']);
  107. }
  108. if($module == 'testcase')
  109. {
  110. $product = $this->loadModel('product')->getByID($this->session->testcaseTransferParams['productID']);
  111. if($product->type == 'normal') unset($fields['branch']);
  112. }
  113. return $fields;
  114. }
  115. /**
  116. * 构建Html表单。
  117. * Build NextList.
  118. *
  119. * @param array $list
  120. * @param int $lastID
  121. * @param array $fields
  122. * @param int $pagerID
  123. * @param string $module
  124. * @access protected
  125. * @return string
  126. */
  127. protected function buildNextList($list = array(), $lastID = 0, $fields = array(), $pagerID = 1, $module = '')
  128. {
  129. $html = '';
  130. $key = key($list);
  131. $addID = 1;
  132. /* 是否开启懒加载。*/
  133. /* Whether to enable lazy loading. */
  134. $showImportCount = $this->config->transfer->lazyLoading ? $this->config->transfer->showImportCount : $this->maxImport;
  135. $lastRow = $lastID + $key + $showImportCount;
  136. foreach($list as $row => $object)
  137. {
  138. if($row <= $lastID) continue;
  139. if($row > $lastRow) break;
  140. $tmpList[$row] = $object;
  141. $trClass = '';
  142. if($row == $lastRow) $trClass = 'showmore';
  143. $html .= $this->printRow($module, $row, $fields, $object, $trClass, $addID);
  144. }
  145. return $html;
  146. }
  147. /**
  148. * 构建Html表单。
  149. * Build Html Form.
  150. *
  151. * @param string $module
  152. * @param int $row
  153. * @param array $fields
  154. * @param object $object
  155. * @param string $trClass
  156. * @param int $addID
  157. * @access private
  158. * @return string
  159. */
  160. private function printRow($module, $row, $fields, $object, $trClass, $addID)
  161. {
  162. $html = '';
  163. $html .= "<tr class='text-top $trClass' data-id=$row> <td>";
  164. /* 是否显示ID。*/
  165. /* Whether to display ID. */
  166. if(!empty($object->id))
  167. {
  168. $html .= $object->id . html::hidden("id[$row]", $object->id);
  169. }
  170. else
  171. {
  172. /* 是否新建。*/
  173. /* Whether new. */
  174. $sub = " <sub style='vertical-align:sub;color:gray'>{$this->lang->transfer->new}</sub>";
  175. if($module == 'task') $sub = (strpos($object->name, '>') === 0) ? " <sub style='vertical-align:sub;color:red'>{$this->lang->task->children}</sub>" : $sub;
  176. $addID ++;
  177. $html .= $addID . $sub;
  178. }
  179. $html .= "</td>";
  180. foreach($fields as $field => $value)
  181. {
  182. $control = $value['control'];
  183. $values = $value['values'];
  184. $name = "{$field}[$row]";
  185. $selected = isset($object->$field) ? $object->$field : '';
  186. $options = array();
  187. $html .= $this->printCell($module, $field, $control, $name, $selected, $values, $row);
  188. }
  189. /* 是否显示删除按钮。*/
  190. /* Whether to display delete button. */
  191. if(in_array($module, $this->config->transfer->actionModule)) $html .= '<td><a onclick="delItem(this)"><i class="icon-close"></i></a></td>';
  192. $html .= '</tr>' . "\n";
  193. return $html;
  194. }
  195. /**
  196. * 处理表单。
  197. * Print cell.
  198. *
  199. * @param string $module
  200. * @param string $field
  201. * @param string $control
  202. * @param string $name
  203. * @param string $selected
  204. * @param array $values
  205. * @param int $row
  206. * @access private
  207. * @return string
  208. */
  209. private function printCell($module = '', $field = '', $control = '', $name = '', $selected = '', $values = array(), $row = 0)
  210. {
  211. $html = '';
  212. if($module and $control == 'hidden' and isset($this->session->{$module.'TransferParams'}[$field. 'ID'])) $selected = $this->session->{$module . 'TransferParams'}[$field. 'ID'];
  213. if($control == 'select')
  214. {
  215. if(!empty($values[$selected])) $options = array($selected => $values[$selected]);
  216. if(empty($options) and is_array($values)) $options = array_slice($values, 0, 1, true);
  217. if(!isset($options['']) and !in_array($field, $this->config->transfer->requiredFields)) $options[''] = '';
  218. }
  219. if($control == 'select') $html .= '<td>' . html::select("$name", $options, $selected, "class='form-control picker-select nopicker' data-field='{$field}' data-index='{$row}'") . '</td>';
  220. elseif($control == 'multiple') $html .= '<td>' . html::select($name . "[]", $values, $selected, "multiple class='form-control picker-select nopicker' data-field='{$field}' data-index='{$row}'") . '</td>';
  221. elseif($control == 'date') $html .= '<td>' . html::input("$name", $selected, "class='form-control form-date' autocomplete='off'") . '</td>';
  222. elseif($control == 'datetime') $html .= '<td>' . html::input("$name", $selected, "class='form-control form-datetime' autocomplete='off'") . '</td>';
  223. elseif($control == 'hidden') $html .= html::hidden("$name", $selected);
  224. elseif($control == 'textarea')
  225. {
  226. if($module == 'bug' and $field == 'steps') $selected = str_replace("\n\n\n\n\n\n", '', $selected);
  227. $html .= '<td>' . html::textarea("$name", $selected, "class='form-control' cols='50' rows='1'") . '</td>';
  228. }
  229. elseif($field == 'stepDesc' or $field == 'stepExpect' or $field == 'precondition') // 用例步骤和预期
  230. {
  231. $stepDesc = $this->process4Testcase($field, $tmpList, $row);
  232. if($stepDesc) $html .= '<td>' . $stepDesc . '</td>';
  233. }
  234. elseif($field == 'estimate') $html .= $this->processEstimate($row, $object); // 多人任务预计工时
  235. elseif(strpos($this->transferConfig->textareaFields, $field) !== false) $html .= '<td>' . html::textarea("$name", $selected, "class='form-control' style='overflow:hidden;'") . '</td>';
  236. else $html .= '<td>' . html::input("$name", $selected, "class='form-control autocomplete='off'") . '</td>';
  237. return $html;
  238. }
  239. /**
  240. * 处理预估工时字段。
  241. * Process estimate.
  242. *
  243. * @param int $row
  244. * @param object $object
  245. * @access private
  246. * @return string
  247. */
  248. private function processEstimate($row = 0, $object = null)
  249. {
  250. $members = $this->loadModel('user')->getTeamMemberPairs($this->session->taskTransferParams['executionID'], 'execution');
  251. $html = '<td>';
  252. if(!empty($object->estimate) and is_array($object->estimate))
  253. {
  254. $html .= "<table class='table-borderless'>";
  255. foreach($object->estimate as $account => $estimate)
  256. {
  257. $html .= '<tr>';
  258. $html .= '<td class="c-team">' . html::select("team[$row][]", $members, $account, "class='form-control chosen'") . '</td>';
  259. $html .= '<td class="c-estimate-1">' . html::input("estimate[$row][]", $estimate, "class='form-control' autocomplete='off'") . '</td>';
  260. $html .= '</tr>';
  261. }
  262. $html .= "</table>";
  263. }
  264. else
  265. {
  266. $html .= html::input("estimate[$row]", !empty($object->estimate) ? $object->estimate : '', "class='form-control'");
  267. }
  268. $html .= '</td>';
  269. return $html;
  270. }
  271. /**
  272. * 处理用例步骤描述和预期结果。
  273. * Process stepExpect、stepDesc and precondition for testcase.
  274. *
  275. * @param string $field
  276. * @param array $datas
  277. * @param int $key
  278. * @access protected
  279. * @return string
  280. */
  281. protected function process4Testcase($field, $datas, $key = 0)
  282. {
  283. $stepData = $this->loadModel('testcase')->processDatas($datas);
  284. $html = '';
  285. if($field == 'precondition' and isset($datas[$key])) return html::textarea("precondition[$key]", htmlSpecialString($datas[$key]->precondition), "class='form-control' style='overflow:hidden'");
  286. if($field == 'stepExpect') return $html;
  287. if(isset($stepData[$key]['desc']))
  288. {
  289. $html = "<table class='w-p100 bd-0'>";
  290. $hasStep = false;
  291. foreach($stepData[$key]['desc'] as $id => $desc)
  292. {
  293. if(empty($desc['content'])) continue;
  294. $hasStep = true;
  295. $html .= "<tr class='step'>";
  296. $html .= '<td>' . $id . html::hidden("stepType[$key][$id]", $desc['type']) . '</td>';
  297. $html .= '<td>' . html::textarea("desc[$key][$id]", htmlSpecialString($desc['content']), "class='form-control'") . '</td>';
  298. if($desc['type'] != 'group') $html .= '<td>' . html::textarea("expect[$key][$id]", isset($stepData[$key]['expect'][$id]['content']) ? htmlSpecialString($stepData[$key]['expect'][$id]['content']) : '', "class='form-control'") . '</td>';
  299. $html .= "</tr>";
  300. }
  301. if(!$hasStep)
  302. {
  303. $html .= "<tr class='step'>";
  304. $html .= "<td>1" . html::hidden("stepType[$key][1]", 'step') . " </td>";
  305. $html .= "<td>" . html::textarea("desc[$key][1]", '', "class='form-control'") . "</td>";
  306. $html .= "<td>" . html::textarea("expect[$key][1]", '', "class='form-control'") . "</td>";
  307. $html .= "</tr>";
  308. }
  309. $html .= "</table>";
  310. }
  311. else
  312. {
  313. $html = "<table class='w-p100 bd-0'>";
  314. $html .= "<tr class='step'>";
  315. $html .= "<td>1" . html::hidden("stepType[$key][1]", 'step') . " </td>";
  316. $html .= "<td>" . html::textarea("desc[$key][1]", '', "class='form-control'") . "</td>";
  317. $html .= "<td>" . html::textarea("expect[$key][1]", '', "class='form-control'") . "</td>";
  318. $html .= "</tr>";
  319. $html .= "</table>";
  320. }
  321. return $html;
  322. }
  323. }