control.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. <?php
  2. /**
  3. * The control file of todo 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 Lanzongjun <lanzongjun@easycorp.ltd>
  8. * @package todo
  9. * @link https://www.zentao.net
  10. */
  11. class todo extends control
  12. {
  13. /**
  14. * 构造函数,日期的加载类,配置语言项。
  15. * Construct function, load class of date, lang of my.
  16. *
  17. * @access public
  18. * @return void
  19. */
  20. public function __construct()
  21. {
  22. parent::__construct();
  23. $this->app->loadClass('date');
  24. $this->app->loadLang('my');
  25. }
  26. /**
  27. * 创建待办。
  28. * Create a todo.
  29. *
  30. * @param string $date
  31. * @param string $from todo|feedback|block
  32. * @access public
  33. * @return void
  34. */
  35. public function create($date = 'today', $from = 'todo')
  36. {
  37. $this->app->loadClass('date');
  38. if($date == 'today') $date = date::today();
  39. if(!empty($_POST))
  40. {
  41. if($this->post->type != 'custom')
  42. {
  43. $this->config->todo->create->requiredFields = '';
  44. $this->config->todo->create->form['name']['required'] = false;
  45. }
  46. $form = form::data($this->config->todo->create->form);
  47. $form = $this->todoZen->addCycleYearConfig($form);
  48. $todoData = $this->todoZen->beforeCreate($form);
  49. $todo = $this->todoZen->prepareCreateData($todoData);
  50. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  51. $todoID = $this->todo->create($todo);
  52. if($todoID === false) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  53. $todo->id = $todoID;
  54. $this->todoZen->afterCreate($todo, $form);
  55. if(!empty($todoData->objectID)) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => true));
  56. if($from == 'block')
  57. {
  58. $todo = $this->todo->getByID($todoID);
  59. $todo->begin = date::formatTime($todo->begin);
  60. return $this->send(array('result' => 'success', 'id' => $todoID, 'name' => $todo->name, 'pri' => $todo->pri, 'priName' => $this->lang->todo->priList[$todo->pri], 'time' => date(DT_DATE4, strtotime($todo->date)) . ' ' . $todo->begin));
  61. }
  62. if(isInModal() || isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => true));
  63. if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $todoID));
  64. if($this->viewType == 'xhtml') return print(js::locate($this->createLink('todo', 'view', "todoID=$todoID", 'html'), 'parent'));
  65. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => $this->createLink('my', 'todo', 'type=all&userID=&status=all&orderBy=id_desc')));
  66. }
  67. unset($this->lang->todo->typeList['cycle']);
  68. $this->todoZen->buildCreateView($date);
  69. }
  70. /**
  71. * 批量创建待办。
  72. * Batch create todo.
  73. *
  74. * @param string $date
  75. * @access public
  76. * @return void
  77. */
  78. public function batchCreate($date = 'today')
  79. {
  80. if($date == 'today') $date = helper::today();
  81. if(!empty($_POST))
  82. {
  83. $form = form::batchData($this->config->todo->batchCreate->form);
  84. $todosData = $this->todoZen->beforeBatchCreate($form);
  85. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  86. $todoIdList = $this->todo->batchCreate($todosData);
  87. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  88. /* Locate the browser. */
  89. $date = str_replace('-', '', $this->post->date);
  90. if($this->post->futureDate) $date = 'future';
  91. if($date == date('Ymd')) $date = 'today';
  92. if(isInModal() || isonlybody()) return $this->send(array('result' => 'success', 'load' => true, 'closeModal' => true));
  93. if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'idList' => $todoIdList));
  94. return $this->sendSuccess(array('closeModal' => true, 'load' => $this->createLink('my', 'todo', "type={$date}")));
  95. }
  96. unset($this->lang->todo->typeList['cycle']);
  97. $this->todoZen->buildBatchCreateView($date);
  98. }
  99. /**
  100. * 编辑待办数据。
  101. * Edit a todo.
  102. *
  103. * @param int $todoID
  104. * @access public
  105. * @return void
  106. */
  107. public function edit($todoID)
  108. {
  109. if(!empty($_POST))
  110. {
  111. if($this->post->type != 'custom')
  112. {
  113. if($this->post->type && in_array($this->post->type, $this->config->todo->moduleList)) $this->config->todo->edit->requiredFields = str_replace(',name,', ',', ",{$this->config->todo->edit->requiredFields},");
  114. $this->config->todo->edit->form['name']['required'] = false;
  115. }
  116. $form = form::data($this->config->todo->edit->form)->setIF($this->post->private == 'on', 'private', '1');
  117. $form = $this->todoZen->addCycleYearConfig($form);
  118. /* Processing edit request data. */
  119. $todo = $this->todoZen->beforeEdit($todoID, $form);
  120. if(dao::isError()) return $this->send(array('status' => 'fail', 'message' => dao::getError()));
  121. /* update a todo. */
  122. $changes = $this->todo->update($todoID, $todo);
  123. if(dao::isError()) return $this->send(array('status' => 'fail', 'message' => dao::getError()));
  124. /* Handle data after edit todo. */
  125. $this->todoZen->afterEdit($todoID, $changes);
  126. if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'success'));
  127. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => $this->session->todoList ? $this->session->todoList : $this->createLink('my', 'todo')));
  128. }
  129. /* Judge a private todo or not, If private, die. */
  130. $todo = $this->todo->getByID($todoID);
  131. if($todo->private and $this->app->user->account != $todo->account) return print('private');
  132. unset($this->lang->todo->typeList['cycle']);
  133. /* Build create form data. */
  134. $this->todoZen->buildEditView($todo);
  135. }
  136. /**
  137. * 批量编辑待办。
  138. * Batch edit todo.
  139. *
  140. * @param string $from example:myTodo, todoBatchEdit.
  141. * @param string $type
  142. * @param int $userID
  143. * @param string $status
  144. * @access public
  145. * @return void
  146. */
  147. public function batchEdit($from = '', $type = 'today', $userID = 0, $status = 'all')
  148. {
  149. /* Get form data for my-todo. */
  150. if($from == 'myTodo')
  151. {
  152. if(!$this->post->todoIdList) return $this->locate($this->session->todoList ? $this->session->todoList : createLink('my', 'todo'));
  153. $this->todoZen->batchEditFromMyTodo($this->post->todoIdList, $type, $userID, $status);
  154. }
  155. /* Save the todo data for batch edit. */
  156. if($from == 'todoBatchEdit')
  157. {
  158. $this->config->todo->edit->requiredFields = str_replace(',name,', ',', ",{$this->config->todo->edit->requiredFields},");
  159. $formData = form::batchData($this->config->todo->batchEdit->form)->get();
  160. $todos = $this->todoZen->beforeBatchEdit($formData);
  161. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  162. $allChanges = $this->todo->batchUpdate($todos, array_keys($formData));
  163. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  164. $this->todoZen->afterBatchEdit($allChanges);
  165. return $this->sendSuccess(array('locate' => $this->session->todoList));
  166. }
  167. }
  168. /**
  169. * 开始一个待办事项。
  170. * Start a todo.
  171. *
  172. * @param int $todoID
  173. * @access public
  174. * @return void
  175. */
  176. public function start($todoID)
  177. {
  178. $todo = $this->todo->getByID($todoID);
  179. if($todo->status == 'wait')
  180. {
  181. $this->todo->start($todoID);
  182. if(dao::isError()) return print(js::error(dao::getError()));
  183. }
  184. if(in_array($todo->type, array('bug', 'task', 'story'))) return $this->todoZen->printStartConfirm($todo);
  185. if(isInModal()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true));
  186. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => $this->session->todoList ? $this->session->todoList : $this->createLink('my', 'todo')));
  187. }
  188. /**
  189. * 激活待办事项。
  190. * Activate a todo.
  191. *
  192. * @param int $todoID
  193. * @access public
  194. * @return void
  195. */
  196. public function activate($todoID)
  197. {
  198. $todo = $this->todo->getByID($todoID);
  199. if($todo->status == 'done' || $todo->status == 'closed')
  200. {
  201. $this->todo->activate($todoID);
  202. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  203. }
  204. if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'success'));
  205. if(isInModal()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true));
  206. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => $this->session->todoList ? $this->session->todoList : $this->createLink('my', 'todo')));
  207. }
  208. /**
  209. * 关闭待办。
  210. * Close one todo.
  211. *
  212. * @param int $todoID
  213. * @access public
  214. * @return void
  215. */
  216. public function close($todoID)
  217. {
  218. /* Close the todo with status done. */
  219. $todo = $this->todo->getByID($todoID);
  220. if($todo->status == 'done')
  221. {
  222. $isClosed = $this->todo->close($todoID);
  223. if(!$isClosed) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  224. }
  225. /* Return json if run mode is API. */
  226. if(defined('RUN_MODE') && RUN_MODE == 'api')
  227. {
  228. $this->send(array('status' => 'success'));
  229. }
  230. if(isInModal()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true));
  231. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => $this->session->todoList ? $this->session->todoList : $this->createLink('my', 'todo')));
  232. }
  233. /**
  234. * 指派待办。
  235. * Assign todo.
  236. *
  237. * @param int $todoID
  238. * @access public
  239. * @return void
  240. */
  241. public function assignTo($todoID)
  242. {
  243. if(!empty($_POST))
  244. {
  245. $formData = form::data($this->config->todo->assignTo->form);
  246. $todo = $this->todoZen->beforeAssignTo($formData);
  247. $todo->id = $todoID;
  248. $isAssigned = $this->todoZen->doAssignTo($todo);
  249. if(!$isAssigned) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  250. if(isInModal()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => true));
  251. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => $this->session->todoList ? $this->session->todoList : $this->createLink('my', 'todo')));
  252. }
  253. $this->todoZen->buildAssignToView($todoID);
  254. }
  255. /**
  256. * 获取待办的信息。
  257. * Get info of todo.
  258. *
  259. * @param int $todoID
  260. * @param string $from my|company
  261. * @access public
  262. * @return void
  263. */
  264. public function view($todoID, $from = 'company')
  265. {
  266. $todo = $this->todo->getByID($todoID, true);
  267. if(!$todo)
  268. {
  269. if((defined('RUN_MODE') && RUN_MODE == 'api') or $this->app->viewType == 'json') return $this->send(array('status' => 'fail', 'message' => '404 Not found'));
  270. if(isInModal()) return print(js::start() . "zui.Modal.hide($(document).find('.modal'));zui.Modal.alert('{$this->lang->notFound}');" . js::end());
  271. return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->notFound)));
  272. }
  273. $account = $this->app->user->account;
  274. if($todo->private && $todo->account != $account)
  275. {
  276. if(isInModal()) return print(js::start() . "zui.Modal.hide($(document).find('.modal'));zui.Modal.alert('{$this->lang->todo->thisIsPrivate}');" . js::end());
  277. return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->todo->thisIsPrivate)));
  278. }
  279. if(!isInModal()) $this->todoZen->setSessionUri($this->app->getURI(true));
  280. /* Fix bug #936. */
  281. if($account != $todo->account && $account != $todo->assignedTo and !common::hasPriv('my', 'team'))
  282. {
  283. $this->locate($this->createLink('user', 'deny', "module=my&method=team"));
  284. }
  285. $projects = $this->todoZen->getProjectPairsByModel((string)$todo->type);
  286. if(!isset($this->session->project)) $this->session->set('project', (int)key($projects));
  287. $this->todoZen->buildAssignToTodoView((object)$todo, (int)$this->session->project, (array)$projects, (string)$account, $from);
  288. }
  289. /**
  290. * 删除待办。
  291. * Delete a todo.
  292. *
  293. * @param int $todoID
  294. * @param string $confirm yes|no
  295. * @access public
  296. * @return void
  297. */
  298. public function delete($todoID, $confirm = 'no')
  299. {
  300. if($confirm == 'no') return $this->send(array('result' => 'success', 'load' => array('confirm' => $this->lang->todo->confirmDelete, 'confirmed' => $this->createLink('todo', 'delete', "todoID={$todoID}&confirm=yes"), 'canceled' => $this->session->todoList ? $this->session->todoList : $this->createLink('my', 'todo'))));
  301. $todo = $this->todo->getByID($todoID);
  302. $allowDelete = true;
  303. if(!$this->app->user->admin && $todo && $todo->account != $this->app->user->account && $todo->assignedTo != $this->app->user->account) $allowDelete = false;
  304. if(!$allowDelete)
  305. {
  306. if(isonlybody()) return print(js::alert($this->lang->error->accessDenied));
  307. if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'message' => $this->lang->error->accessDenied));
  308. if(helper::isAjaxRequest()) return $this->send(array('result' => 'fail', 'message' => $this->lang->error->accessDenied));
  309. }
  310. $this->todo->delete(TABLE_TODO, $todoID);
  311. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  312. if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'success'));
  313. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => $this->session->todoList ? $this->session->todoList : $this->createLink('my', 'todo')));
  314. }
  315. /**
  316. * 完成待办。
  317. * Finish a todo.
  318. *
  319. * @param int $todoID
  320. * @access public
  321. * @return void
  322. */
  323. public function finish($todoID)
  324. {
  325. $todo = $this->todo->getByID($todoID);
  326. if($todo->status != 'done' && $todo->status != 'closed')
  327. {
  328. $result = $this->todo->finish($todoID);
  329. if(!$result) return false;
  330. }
  331. $types = $this->config->todo->moduleList;
  332. array_pop($types);
  333. if(in_array($todo->type, $types))
  334. {
  335. $confirmNote = 'confirm' . ucfirst($todo->type);
  336. if($this->config->vision == 'or' && $todo->type == 'task') $todo->type = 'researchtask';
  337. $confirmURL = $this->createLink($todo->type, 'view', "id=$todo->objectID");
  338. $message = sprintf($this->lang->todo->{$confirmNote}, $todo->objectID);
  339. $tab = $this->app->tab;
  340. if($todo->type == 'bug') $tab = 'qa';
  341. if($todo->type == 'task') $tab = 'execution';
  342. if($todo->type == 'researchtask') $tab = 'market';
  343. if($todo->type == 'story') $tab = 'product';
  344. if($todo->type == 'epic') $tab = 'product';
  345. if($todo->type == 'requirement') $tab = 'product';
  346. if($todo->type == 'feedback') $tab = 'feedback';
  347. if(in_array($todo->type, array('issue', 'risk'))) $tab = 'project';
  348. return $this->send(array('result' => 'success', 'callback' => "zui.Modal.confirm({message: '{$message}', icon: 'icon-exclamation-sign', iconClass: 'warning-pale rounded-full icon-2x'}).then((res) => {if(res) openPage('{$confirmURL}', '{$tab}'); else reloadPage();});"));
  349. }
  350. if(defined('RUN_MODE') && RUN_MODE == 'api')
  351. {
  352. return $this->send(array('status' => 'success'));
  353. }
  354. if(isInModal()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true));
  355. return $this->sendSuccess(array('load' => $this->session->todoList ? $this->session->todoList : $this->createLink('my', 'todo'), 'closeModal' => true));
  356. }
  357. /**
  358. * 批量完成待办。
  359. * Batch finish todos.
  360. *
  361. * @access public
  362. * @return void
  363. */
  364. public function batchFinish()
  365. {
  366. $todoIdList = form::data($this->config->todo->batchFinish->form)->get('todoIdList');
  367. $todoList = $this->todo->getByList($todoIdList);
  368. foreach($todoList as $todoID => $todo)
  369. {
  370. if($todo->status == 'done' || $todo->status == 'closed') unset($todoList[$todoID]);
  371. }
  372. $isBatchFinished = $this->todo->batchFinish(array_keys($todoList));
  373. if(!$isBatchFinished) return false;
  374. return $this->send(array('result' => 'success', 'load' => true));
  375. }
  376. /**
  377. * 批量关闭待办。只有完成的待办才能关闭。
  378. * Batch close todos. The status of todo which need to close should be done.
  379. *
  380. * @access public
  381. * @return void
  382. */
  383. public function batchClose()
  384. {
  385. $waitIdList = array();
  386. $todoIdList = form::data($this->config->todo->batchClose->form)->get('todoIdList');
  387. foreach($todoIdList as $todoID)
  388. {
  389. $todoID = (int)$todoID;
  390. $todo = $this->todo->getByID($todoID);
  391. if($todo->status == 'done') $this->todo->close($todoID);
  392. if($todo->status != 'done' and $todo->status != 'closed') $waitIdList[] = $todoID;
  393. }
  394. if(!empty($waitIdList)) return $this->send(array('result' => 'fail', 'message' => sprintf($this->lang->todo->unfinishedTodo, implode(',', $waitIdList))));
  395. return $this->send(array('result' => 'success', 'load' => true));
  396. }
  397. /**
  398. * 修改选中待办的日期。
  399. * Import selected todos to today.
  400. *
  401. * @param string $todoID
  402. * @access public
  403. * @return void
  404. */
  405. public function import2Today($todoID = '')
  406. {
  407. if(!$_POST) $this->locate($this->createLink('my', 'todo'));
  408. $formData = form::data($this->config->todo->editDate->form);
  409. $todoIdList = !empty($formData->data->todoIdList) ? $formData->data->todoIdList : array($todoID);
  410. $date = !empty($formData->data->date) ? $formData->data->date : date::today();
  411. if(!$todoIdList) $this->locate((string)$this->session->todoList);
  412. $this->todo->editDate((array)$todoIdList, (string)$date);
  413. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true));
  414. }
  415. /**
  416. * 获取导出待办数据。
  417. * Get data to export.
  418. *
  419. * @param int $userID
  420. * @param string $orderBy
  421. * @access public
  422. * @return void
  423. */
  424. public function export($userID, $orderBy)
  425. {
  426. if($_POST)
  427. {
  428. $user = $this->todoZen->getUserById($userID);
  429. $todoLang = (object)$this->lang->todo;
  430. $configTime = $this->config->todo->times;
  431. $formData = form::data($this->config->todo->export->form);
  432. $checkedItem = $formData->data->exportType == 'selected' ? $this->cookie->checkedItem : '';
  433. $todos = $this->todo->getByExportList($orderBy, (string) $this->session->todoReportCondition, (string)$checkedItem);
  434. list($todos, $fields) = $this->todoZen->exportTodoInfo((array)$todos, (string)$this->config->todo->list->exportFields, $todoLang);
  435. list($users, $bugs, $stories, $epics, $requirements, $tasks, $testTasks) = $this->todoZen->exportAssociated('default', (string)$user->account);
  436. $times = date::buildTimeList((int)$configTime->begin, (int)$configTime->end, (int)$configTime->delta);
  437. $assemble = new stdclass();
  438. $assemble->users = $users;
  439. $assemble->bugs = $bugs;
  440. $assemble->stories = $stories;
  441. $assemble->epics = $epics;
  442. $assemble->requirements = $requirements;
  443. $assemble->tasks = $tasks;
  444. $assemble->testTasks = $testTasks;
  445. if(in_array($this->config->edition, array('max', 'ipd')))
  446. {
  447. $iroData = $this->todoZen->exportAssociated((string)$this->config->edition, (string)$user->account);
  448. $assemble->issues = $iroData[0];
  449. $assemble->risks = $iroData[1];
  450. $assemble->opportunities = $iroData[2];
  451. }
  452. $todos = $this->todoZen->assembleExportData((array)$todos, $assemble, $todoLang, (array)$times);
  453. $this->post->set('fields', $fields);
  454. $this->post->set('rows', $todos);
  455. $this->post->set('kind', 'todo');
  456. $this->fetch('file', 'export2' . $this->post->fileType, $_POST);
  457. }
  458. $this->view->fileName = $this->app->user->account . '-' . $this->lang->todo->common;
  459. $this->display();
  460. }
  461. /**
  462. * ajax请求:获得 todo 的动作。 用于 web 应用程序。
  463. * AJAX: get actions of a todo. for web app.
  464. *
  465. * @param int $todoID
  466. * @access public
  467. * @return void
  468. */
  469. public function ajaxGetDetail($todoID)
  470. {
  471. $this->view->actions = $this->loadModel('action')->getList('todo', $todoID);
  472. $this->display();
  473. }
  474. /**
  475. * ajax请求:获取程序id。
  476. * AJAX: get program id.
  477. *
  478. * @param int $objectID
  479. * @param string $objectType
  480. * @access public
  481. * @return void
  482. */
  483. public function ajaxGetProgramID($objectID, $objectType)
  484. {
  485. $table = $objectType == 'project' ? TABLE_PROJECT : TABLE_PRODUCT;
  486. $field = $objectType == 'project' ? 'parent' : 'program';
  487. echo $this->dao->select($field)->from($table)->where('id')->eq($objectID)->fetch($field);
  488. }
  489. /**
  490. * ajax请求:获取执行对。
  491. * AJAX: get execution pairs.
  492. *
  493. * @param int $projectID
  494. * @access public
  495. * @return void
  496. */
  497. public function ajaxGetExecutionPairs($projectID)
  498. {
  499. $this->session->set('project', $projectID);
  500. $project = $this->loadModel('project')->getByID($projectID);
  501. $executions = $this->loadModel('execution')->getByProject($projectID, 'undone');
  502. $items = array();
  503. foreach($executions as $id => $execution) $items[] = array('value' => $id, 'text' => $execution->name, 'keys' => $execution->name);
  504. return print(json_encode($items));
  505. }
  506. /**
  507. * ajax请求:获取产品对。
  508. * AJAX: get product pairs.
  509. *
  510. * @param int $projectID
  511. * @access public
  512. * @return void
  513. */
  514. public function ajaxGetProductPairs($projectID)
  515. {
  516. $this->session->set('project', $projectID);
  517. $products = $this->loadModel('product')->getProductPairsByProject($projectID);
  518. $items = array();
  519. foreach($products as $id => $name) $items[] = array('value' => $id, 'text' => $name, 'keys' => $name);
  520. return print(json_encode($items));
  521. }
  522. /**
  523. * 创建周期待办。
  524. * Create cycle.
  525. *
  526. * @access public
  527. * @return void
  528. */
  529. public function createCycle()
  530. {
  531. $todoList = $this->todo->getValidCycleList();
  532. $this->todo->createByCycle($todoList);
  533. }
  534. }