control.php 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823
  1. <?php
  2. /**
  3. * The control file of kanban module of ZenTaoPMS.
  4. *
  5. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
  6. * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  7. * @author Guangming Sun<sunguangming@easycorp.ltd>
  8. * @package kanban
  9. * @version $Id: control.php 4460 2021-10-26 11:03:02Z chencongzhi520@gmail.com $
  10. * @link https://www.zentao.net
  11. */
  12. class kanban extends control
  13. {
  14. /**
  15. * 看板空间列表。
  16. * Kanban space.
  17. *
  18. * @param string $browseType involved|cooperation|public|private
  19. * @param int $recTotal
  20. * @param int $recPerPage
  21. * @param int $pageID
  22. * @access public
  23. * @return void
  24. */
  25. public function space($browseType = 'involved', $recTotal = 0, $recPerPage = 15, $pageID = 1)
  26. {
  27. $this->session->set('regionID', 'all', 'kanban');
  28. /* Load pager. */
  29. $this->app->loadClass('pager', true);
  30. $pager = new pager($recTotal, $recPerPage, $pageID);
  31. $this->view->title = $this->lang->kanbanspace->common;
  32. $this->view->browseType = $browseType;
  33. $this->view->pager = $pager;
  34. $this->view->spaceList = $this->kanban->getSpaceList($browseType, $pager, $this->cookie->showClosed);
  35. $this->view->unclosedSpace = $this->kanban->getCanViewObjects('kanbanspace', 'noclosed');
  36. $this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted');
  37. $this->view->userIdPairs = $this->user->getPairs('noletter|nodeleted|showid');
  38. $this->view->usersAvatar = $this->user->getAvatarPairs();
  39. $this->display();
  40. }
  41. /**
  42. * 创建看板空间。
  43. * Create a space.
  44. *
  45. * @param string $type
  46. * @access public
  47. * @return void
  48. */
  49. public function createSpace($type = 'private')
  50. {
  51. if(!empty($_POST))
  52. {
  53. $this->lang->kanban->name = $this->lang->kanbanspace->name;
  54. $space = form::data($this->config->kanban->form->createSpace)
  55. ->setDefault('createdBy', $this->app->user->account)
  56. ->setDefault('createdDate', helper::now())
  57. ->get();
  58. $this->kanban->createSpace($space);
  59. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  60. $url = inlink('space', "browseType={$space->type}");
  61. return $this->send(array('result' => 'success', 'closeModal' => true, 'callback' => array('name' => '$.apps.open', 'params' => array($url)), 'message' => $this->lang->saveSuccess));
  62. }
  63. $this->view->title = $this->lang->kanban->createSpace;
  64. $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted');
  65. $this->view->type = $type;
  66. $this->display();
  67. }
  68. /**
  69. * 编辑看板空间。
  70. * Edit a space.
  71. *
  72. * @param int $spaceID
  73. * @access public
  74. * @return void
  75. */
  76. public function editSpace($spaceID)
  77. {
  78. if(!empty($_POST))
  79. {
  80. $this->lang->kanban->name = $this->lang->kanbanspace->name;
  81. $space = form::data($this->config->kanban->form->editSpace)
  82. ->setDefault('lastEditedBy', $this->app->user->account)
  83. ->setDefault('lastEditedDate', helper::now())
  84. ->get();
  85. $this->kanban->updateSpace($space, $spaceID);
  86. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  87. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
  88. }
  89. $space = $this->kanban->getSpaceById($spaceID);
  90. if(in_array($space->type, array('cooperation', 'public'))) unset($this->lang->kanbanspace->typeList['private']);
  91. $this->view->spaceID = $spaceID;
  92. $this->view->space = $space;
  93. $this->view->users = $this->loadModel('user')->getPairs('noclosed');
  94. $this->view->typeList = $this->lang->kanbanspace->typeList;
  95. $this->view->team = ($space->type == 'private') ? $space->whitelist : $space->team;
  96. $this->view->defaultType = $space->type;
  97. $this->display();
  98. }
  99. /**
  100. * 激活看板空间。
  101. * Activate a space.
  102. *
  103. * @param int $spaceID
  104. * @access public
  105. * @return void
  106. */
  107. public function activateSpace($spaceID)
  108. {
  109. $this->loadModel('action');
  110. if(!empty($_POST))
  111. {
  112. $space = form::data($this->config->kanban->form->activateSpace)
  113. ->add('closedBy', '')
  114. ->add('closedDate', null)
  115. ->add('activatedBy', $this->app->user->account)
  116. ->add('lastEditedBy', $this->app->user->account)
  117. ->get();
  118. $this->kanban->activateSpace($spaceID, $space);
  119. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  120. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
  121. }
  122. $this->view->space = $this->kanban->getSpaceById($spaceID);
  123. $this->view->actions = $this->action->getList('kanbanSpace', $spaceID);
  124. $this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed|nodeleted');
  125. $this->display();
  126. }
  127. /*
  128. * 关闭看板空间。
  129. * Close a space.
  130. *
  131. * @param int $spaceID
  132. * @access public
  133. * @return void
  134. */
  135. /**
  136. * @param int $spaceID
  137. */
  138. public function closeSpace($spaceID)
  139. {
  140. if(!empty($_POST))
  141. {
  142. $space = form::data($this->config->kanban->form->closeSpace)
  143. ->add('activatedBy', '')
  144. ->add('activatedDate', null)
  145. ->add('closedBy', $this->app->user->account)
  146. ->add('lastEditedBy', $this->app->user->account)
  147. ->get();
  148. $this->kanban->closeSpace($spaceID, $space);
  149. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  150. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
  151. }
  152. $this->view->space = $this->kanban->getSpaceById($spaceID);
  153. $this->view->actions = $this->loadModel('action')->getList('kanbanSpace', $spaceID);
  154. $this->view->users = $this->loadModel('user')->getPairs('noletter');
  155. $this->display();
  156. }
  157. /**
  158. * 删除看板空间。
  159. * Delete a space.
  160. *
  161. * @param int $spaceID
  162. * @access public
  163. * @return void
  164. */
  165. public function deleteSpace($spaceID)
  166. {
  167. $this->kanban->delete(TABLE_KANBANSPACE, $spaceID);
  168. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
  169. }
  170. /**
  171. * 创建看板。
  172. * Create a kanban.
  173. *
  174. * @param int $spaceID
  175. * @param string $type
  176. * @param int $copyKanbanID
  177. * @param string $extra
  178. * @access public
  179. * @return void
  180. */
  181. public function create($spaceID = 0, $type = 'private', $copyKanbanID = 0, $extra = '')
  182. {
  183. if(!empty($_POST))
  184. {
  185. $kanban = form::data($this->config->kanban->form->create)
  186. ->setDefault('createdBy', $this->app->user->account)
  187. ->get();
  188. $kanbanID = $this->kanban->create($kanban);
  189. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  190. $url = inlink('view', "kanbanID={$kanbanID}");
  191. return $this->send(array('result' => 'success', 'closeModal' => true, 'callback' => array('name' => '$.apps.open', 'params' => array($url)), 'message' => $this->lang->saveSuccess));
  192. }
  193. $this->kanbanZen->assignCreateVars($spaceID, $type, $copyKanbanID, $extra);
  194. }
  195. /**
  196. * 编辑看板。
  197. * Edit a kanban.
  198. *
  199. * @param int $kanbanID
  200. * @access public
  201. * @return void
  202. */
  203. public function edit($kanbanID = 0)
  204. {
  205. if(!empty($_POST))
  206. {
  207. $kanban = form::data($this->config->kanban->form->edit)
  208. ->setDefault('lastEditedBy', $this->app->user->account)
  209. ->get();
  210. $this->kanban->update($kanbanID, $kanban);
  211. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  212. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "loadCurrentPage('#header,#kanban-{$kanbanID}')"));
  213. }
  214. $kanban = $this->kanban->getByID($kanbanID);
  215. $space = $this->kanban->getSpaceById($kanban->space);
  216. $spaceUsers = trim($space->owner) . ',' . trim($space->team);
  217. $users = $this->loadModel('user')->getPairs('noclosed|nodeleted');
  218. $ownerPairs = $this->user->getPairs('noclosed|nodeleted', '', 0, $spaceUsers);
  219. $this->view->users = $users;
  220. $this->view->ownerPairs = $ownerPairs;
  221. $this->view->spacePairs = array($kanban->space => $space->name) + $this->kanban->getSpacePairs($space->type);
  222. $this->view->kanban = $kanban;
  223. $this->view->type = $space->type;
  224. $this->display();
  225. }
  226. /**
  227. * Setting kanban.
  228. *
  229. * @param int $kanbanID
  230. * @access public
  231. * @return void
  232. */
  233. public function setting($kanbanID = 0)
  234. {
  235. if(!empty($_POST))
  236. {
  237. $kanban = form::data($this->config->kanban->form->setting)->get();
  238. $this->kanban->setting($kanbanID, $kanban);
  239. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  240. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
  241. }
  242. $kanban = $this->kanban->getByID($kanbanID);
  243. $this->view->kanban = $kanban;
  244. $this->view->laneCount = $this->kanban->getLaneCount($kanbanID);
  245. $this->view->heightType = $kanban->displayCards > 2 ? 'custom' : 'auto';
  246. $this->view->displayCards = $kanban->displayCards ? $kanban->displayCards : '';
  247. $this->view->enableImport = empty($kanban->object) ? 'off' : 'on';
  248. $this->view->importObjects = empty($kanban->object) ? array() : explode(',', $kanban->object);
  249. $this->display();
  250. }
  251. /*
  252. * 激活看板。
  253. * Activate a kanban.
  254. *
  255. * @param int $kanbanID
  256. * @access public
  257. * @return void
  258. */
  259. /**
  260. * @param int $kanbanID
  261. */
  262. public function activate($kanbanID)
  263. {
  264. if(!empty($_POST))
  265. {
  266. $kanban = form::data($this->config->kanban->form->activate)
  267. ->setDefault('closedBy', '')
  268. ->setDefault('closedDate', null)
  269. ->setDefault('activatedBy', $this->app->user->account)
  270. ->setDefault('lastEditedBy', $this->app->user->account)
  271. ->get();
  272. $this->kanban->activate($kanbanID, $kanban);
  273. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  274. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
  275. }
  276. $this->view->kanban = $this->kanban->getByID($kanbanID);
  277. $this->view->actions = $this->loadModel('action')->getList('kanban', $kanbanID);
  278. $this->view->users = $this->loadModel('user')->getPairs('noletter');
  279. $this->display();
  280. }
  281. /*
  282. * 关闭看板。
  283. * Close a kanban.
  284. *
  285. * @param int $kanbanID
  286. * @access public
  287. * @return void
  288. */
  289. /**
  290. * @param int $kanbanID
  291. */
  292. public function close($kanbanID)
  293. {
  294. if(!empty($_POST))
  295. {
  296. $kanban = form::data($this->config->kanban->form->close)
  297. ->setDefault('activatedBy', '')
  298. ->setDefault('activatedDate', null)
  299. ->setDefault('closedBy', $this->app->user->account)
  300. ->setDefault('lastEditedBy', $this->app->user->account)
  301. ->get();
  302. $this->kanban->close($kanbanID, $kanban);
  303. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  304. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
  305. }
  306. $this->view->kanban = $this->kanban->getByID($kanbanID);
  307. $this->view->actions = $this->loadModel('action')->getList('kanban', $kanbanID);
  308. $this->view->users = $this->loadModel('user')->getPairs('noletter');
  309. $this->display();
  310. }
  311. /**
  312. * 看板视图页面。
  313. * View a kanban.
  314. *
  315. * @param int $kanbanID
  316. * @param string|int $regionID
  317. * @access public
  318. * @return void
  319. */
  320. public function view($kanbanID, $regionID = '')
  321. {
  322. $kanban = $this->kanban->getByID($kanbanID);
  323. if(!$kanban)
  324. {
  325. if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'code' => 404, 'message' => '404 Not found'));
  326. return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->notFound, 'locate' => $this->createLink('kanban', 'space'))));
  327. }
  328. $kanbanIdList = $this->kanban->getCanViewObjects();
  329. if(!$this->app->user->admin and !in_array($kanbanID, $kanbanIdList)) return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->kanban->accessDenied, 'locate' => $this->createLink('kanban', 'space'))));
  330. $regions = $this->kanban->getRegionPairs($kanbanID);
  331. if(!$regionID) $regionID = $this->session->regionID ? $this->session->regionID : 'all';
  332. $regionID = !isset($regions[$regionID]) ? 'all' : $regionID;
  333. $this->session->set('regionID', $regionID, 'kanban');
  334. $this->kanbanZen->setUserAvatar();
  335. $this->view->title = $this->lang->kanban->view;
  336. $this->view->kanban = $kanban;
  337. $this->view->regions = $regions;
  338. $this->view->kanbanList = $this->kanban->getKanbanData($kanbanID, $regionID == 'all' ? '' : array($regionID));
  339. $this->view->regionID = $regionID;
  340. $this->view->pageToolbar = $this->kanban->getPageToolBar($kanban);
  341. $this->display();
  342. }
  343. /**
  344. * 删除看板。
  345. * Delete a kanban.
  346. *
  347. * @param int $kanbanID
  348. * @access public
  349. * @return void
  350. */
  351. public function delete($kanbanID)
  352. {
  353. $this->kanban->delete(TABLE_KANBAN, $kanbanID);
  354. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => $this->createLink('kanban', 'space')));
  355. }
  356. /**
  357. * 创建看板区域。
  358. * Create a region.
  359. *
  360. * @param int $kanbanID
  361. * @param string $from kanban|execution
  362. * @access public
  363. * @return void
  364. */
  365. public function createRegion($kanbanID, $from = 'kanban')
  366. {
  367. if(!empty($_POST))
  368. {
  369. $kanban = $from == 'execution' ? $this->loadModel('execution')->getByID($kanbanID) : $this->kanban->getByID($kanbanID);
  370. $copyRegionID = $this->post->region == 'custom' ? 0 : $this->post->region;
  371. $regionID = $this->kanban->createRegion($kanban, null, (int)$copyRegionID, $from);
  372. $this->session->set('regionID', $regionID, 'kanban');
  373. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  374. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
  375. }
  376. $regionPairs = array();
  377. $regions = $this->kanban->getRegionPairs($kanbanID, 0, $from);
  378. foreach($regions as $regionID => $region)
  379. {
  380. if(mb_strlen($region, 'UTF-8') > 20) $region = mb_substr($region, 0, 20, 'UTF-8') . '...';
  381. $regionPairs[$regionID] = $this->lang->kanban->copy . '"' . $region . '"' . $this->lang->kanban->styleCommon;
  382. }
  383. $this->view->regions = array('custom' => $this->lang->kanban->custom) + $regionPairs;
  384. $this->display();
  385. }
  386. /*
  387. * 编辑区域。
  388. * Edit a region
  389. *
  390. * @param int $regionID
  391. * @access public
  392. * @return void
  393. */
  394. /**
  395. * @param int $regionID
  396. */
  397. public function editRegion($regionID = 0)
  398. {
  399. if(!empty($_POST))
  400. {
  401. $this->kanban->updateRegion($regionID);
  402. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  403. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
  404. }
  405. $this->view->region = $this->kanban->getRegionByID($regionID);
  406. $this->display();
  407. }
  408. /**
  409. * 排序区域。
  410. * Sort regions.
  411. *
  412. * @param string $regions
  413. * @access public
  414. * @return void
  415. */
  416. public function sortRegion($regions = '')
  417. {
  418. if(empty($regions)) return;
  419. $regionIdList = explode(',', trim($regions, ','));
  420. $this->kanban->updateRegionSort($regionIdList);
  421. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  422. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true));
  423. }
  424. /**
  425. * 排序分组。
  426. * Sort group.
  427. *
  428. * @param int $region
  429. * @param string $groups
  430. * @access public
  431. * @return void
  432. */
  433. public function sortGroup($region, $groups)
  434. {
  435. $groups = array_filter(explode(',', trim($groups, ',')));
  436. if(empty($groups)) return $this->send(array('result' => 'fail', 'message' => 'No groups to sort.'));
  437. $this->kanban->sortGroup($region, $groups);
  438. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  439. return $this->send(array('result' => 'success'));
  440. }
  441. /**
  442. * 删除区域。
  443. * Delete a region
  444. *
  445. * @param int $regionID
  446. * @access public
  447. * @return void
  448. */
  449. public function deleteRegion($regionID)
  450. {
  451. $this->kanban->delete(TABLE_KANBANREGION, $regionID);
  452. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true));
  453. }
  454. /**
  455. * 创建看板泳道。
  456. * Create a lane for a kanban.
  457. *
  458. * @param int $kanbanID
  459. * @param int $regionID
  460. * @param string $from kanban|execution
  461. * @access public
  462. * @return void
  463. */
  464. public function createLane($kanbanID, $regionID, $from = 'kanban')
  465. {
  466. if(!empty($_POST))
  467. {
  468. $this->lang->kanban->name = $this->lang->kanbanlane->name;
  469. $lane = form::data($this->config->kanban->form->createLane)->add('region', $regionID)->get();
  470. $this->kanban->createLane($kanbanID, $regionID, $lane, 'new');
  471. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  472. if($from == 'execution') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => true));
  473. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => true));
  474. }
  475. $laneType = $from == 'kanban' ? 'all' : 'story';
  476. if($this->config->vision == 'lite') $laneType = 'task';
  477. $this->view->lanes = $this->kanban->getLanePairsByRegion($regionID, $laneType);
  478. $this->view->from = $from;
  479. $this->view->regionID = $regionID;
  480. if($from == 'kanban') $this->display();
  481. if($from == 'execution') $this->display('kanban', 'createexeclane');
  482. }
  483. /**
  484. * 泳道排序。
  485. * Sort lanes.
  486. *
  487. * @param int $regionID
  488. * @param string $lanes
  489. * @access public
  490. * @return void
  491. */
  492. public function sortLane($regionID, $lanes = '')
  493. {
  494. if(empty($lanes)) return;
  495. $lanes = explode(',', trim($lanes, ','));
  496. $this->kanban->updateLaneSort($regionID, $lanes);
  497. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  498. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true));
  499. }
  500. /**
  501. * 排序看板列。
  502. * Sort columns.
  503. *
  504. * @param int $regionID
  505. * @param string $columns
  506. * @access public
  507. * @return void
  508. */
  509. public function sortColumn($regionID, $columns = '')
  510. {
  511. if(empty($columns)) return;
  512. $columns = explode(',', trim($columns, ','));
  513. $this->kanban->updateColumnSort($regionID, $columns);
  514. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  515. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true));
  516. }
  517. /**
  518. * 删除看板泳道。
  519. * Delete a lane.
  520. *
  521. * @param int $regionID
  522. * @param int $laneID
  523. * @access public
  524. * @return void
  525. */
  526. public function deleteLane($regionID, $laneID)
  527. {
  528. $this->kanban->delete(TABLE_KANBANLANE, $laneID);
  529. if($this->app->tab == 'execution')
  530. {
  531. if(dao::isError()) return $this->sendError(dao::getError());
  532. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true));
  533. }
  534. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true));
  535. }
  536. /**
  537. * 创建看板列。
  538. * Create a column for a kanban.
  539. *
  540. * @param int $fromColumnID
  541. * @param string $position left|right
  542. * @access public
  543. * @return void
  544. */
  545. public function createColumn($fromColumnID, $position = 'left')
  546. {
  547. $fromColumn = $this->kanban->getColumnByID($fromColumnID);
  548. if($_POST)
  549. {
  550. $this->lang->kanban->name = $this->lang->kanbancolumn->name;
  551. $order = $position == 'left' ? $fromColumn->order : $fromColumn->order + 1;
  552. $column = form::data($this->config->kanban->form->createColumn)
  553. ->setDefault('order', $order)
  554. ->setDefault('region', $fromColumn->region)
  555. ->get();
  556. $this->kanban->createColumn($fromColumn->region, $column, 'kanban', 'new');
  557. if(dao::isError()) $this->send(array('message' => dao::getError(), 'result' => 'fail'));
  558. $region = $this->kanban->getRegionByID($fromColumn->region);
  559. $callback = $this->kanban->getKanbanCallback($region->kanban, $region->id);
  560. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  561. }
  562. $this->view->title = $this->lang->kanban->createColumn;
  563. $this->view->fromColumn = $fromColumn;
  564. $this->view->position = $position;
  565. $this->display();
  566. }
  567. /**
  568. * 拆分看板列。
  569. * Split column.
  570. *
  571. * @param int $columnID
  572. * @access public
  573. * @return void
  574. */
  575. public function splitColumn($columnID)
  576. {
  577. if(!empty($_POST))
  578. {
  579. $this->lang->kanban->name = $this->lang->kanbancolumn->childName;
  580. $columns = form::batchData($this->config->kanban->form->splitColumn)->get();
  581. $this->kanban->splitColumn($columnID, $columns);
  582. if(dao::isError()) $this->send(array('message' => dao::getError(), 'result' => 'fail'));
  583. $column = $this->kanban->getColumnById($columnID);
  584. $region = $this->kanban->getRegionByID($column->region);
  585. $callback = $this->kanban->getKanbanCallback($region->kanban, $region->id);
  586. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  587. }
  588. $this->view->column = $this->kanban->getColumnByID($columnID);
  589. $this->display();
  590. }
  591. /**
  592. * 归档看板列。
  593. * Archive a column.
  594. *
  595. * @param int $columnID
  596. * @access public
  597. * @return void
  598. */
  599. public function archiveColumn($columnID)
  600. {
  601. $column = $this->kanban->getColumnById($columnID);
  602. if($column->parent) $this->kanban->updateColumnParent($column);
  603. $this->kanban->archiveColumn($columnID);
  604. if(dao::isError()) $this->send(array('message' => dao::getError(), 'result' => 'fail'));
  605. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => true));
  606. }
  607. /**
  608. * 还原看板列。
  609. * Restore a column.
  610. *
  611. * @param int $columnID
  612. * @access public
  613. * @return void
  614. */
  615. public function restoreColumn($columnID)
  616. {
  617. $this->kanban->restoreColumn($columnID);
  618. if(dao::isError()) $this->send(array('message' => dao::getError(), 'result' => 'fail'));
  619. return $this->send(array('result' => 'success', 'load' => true));
  620. }
  621. /**
  622. * 查看归档看板列。
  623. * View archived columns.
  624. *
  625. * @param int $regionID
  626. * @access public
  627. * @return void
  628. */
  629. public function viewArchivedColumn($regionID)
  630. {
  631. $region = $this->kanban->getRegionByID($regionID);
  632. $this->view->kanban = $this->kanban->getByID($region->kanban);
  633. $this->view->columns = $this->kanban->getColumnsByField('region', $regionID, '1');
  634. $this->display();
  635. }
  636. /**
  637. * 删除看板列。
  638. * Delete a column.
  639. *
  640. * @param int $columnID
  641. * @access public
  642. * @return void
  643. */
  644. public function deleteColumn($columnID)
  645. {
  646. $column = $this->kanban->getColumnById($columnID);
  647. if($column->parent > 0) $this->kanban->processCards($column);
  648. $this->dao->delete()->from(TABLE_KANBANCOLUMN)->where('id')->eq($columnID)->exec();
  649. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => true));
  650. }
  651. /**
  652. * Create a card.
  653. *
  654. * @param int $kanbanID
  655. * @param int $regionID
  656. * @param int $groupID
  657. * @param int $columnID
  658. * @access public
  659. * @return void
  660. */
  661. public function createCard($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0)
  662. {
  663. if($_POST)
  664. {
  665. $this->lang->kanban->name = $this->lang->kanbancard->name;
  666. $card = form::data($this->config->kanban->form->createCard)
  667. ->add('kanban', $kanbanID)
  668. ->add('region', $regionID)
  669. ->add('group', $groupID)
  670. ->setDefault('createdBy', $this->app->user->account)
  671. ->get();
  672. $this->kanban->createCard($columnID, $card);
  673. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  674. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => true));
  675. }
  676. $kanban = $this->kanban->getById($kanbanID);
  677. $kanbanUsers = $kanbanID == 0 ? ',' : trim($kanban->owner) . ',' . trim($kanban->team);
  678. $users = $this->loadModel('user')->getPairs('noclosed|nodeleted', '', 0, $kanbanUsers);
  679. $this->view->users = $users;
  680. $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
  681. $this->display();
  682. }
  683. /**
  684. * 批量创建卡片。
  685. * Batch create cards.
  686. *
  687. * @param int $kanbanID
  688. * @param int $regionID
  689. * @param int $groupID
  690. * @param int $columnID
  691. * @access public
  692. * @return void
  693. */
  694. public function batchCreateCard($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0)
  695. {
  696. $kanban = $this->kanban->getById($kanbanID);
  697. if($_POST)
  698. {
  699. $cards = form::batchData($this->config->kanban->form->batchCreateCard)->get();
  700. $this->kanban->batchCreateCard($kanbanID, $regionID, $groupID, $columnID, $cards);
  701. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  702. $callback = $this->kanban->getKanbanCallback($kanbanID, $regionID);
  703. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  704. }
  705. $kanbanUsers = $kanbanID == 0 ? ',' : trim($kanban->owner) . ',' . trim($kanban->team);
  706. $users = $this->loadModel('user')->getPairs('noclosed|nodeleted', '', 0, $kanbanUsers);
  707. $this->view->title = $this->lang->kanban->batchCreateCard;
  708. $this->view->users = $users;
  709. $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
  710. $this->display();
  711. }
  712. /**
  713. * 编辑看板卡片。
  714. * Edit a card.
  715. *
  716. * @param int $cardID
  717. * @access public
  718. * @return void
  719. */
  720. public function editCard($cardID)
  721. {
  722. if(!empty($_POST))
  723. {
  724. $this->lang->kanban->name = $this->lang->kanbancard->name;
  725. $card = form::data($this->config->kanban->form->editCard)
  726. ->setDefault('lastEditedBy', $this->app->user->account)
  727. ->get();
  728. $this->kanban->updateCard($cardID, $card);
  729. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  730. $card = $this->kanban->getCardByID($cardID);
  731. $callback = $this->kanban->getKanbanCallback($card->kanban, $card->region);
  732. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  733. }
  734. $card = $this->kanban->getCardByID($cardID);
  735. $kanban = $this->kanban->getById($card->kanban);
  736. $kanbanUsers = $card->kanban == 0 ? ',' : trim($kanban->owner) . ',' . trim($kanban->team);
  737. $kanbanUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted', '', 0, $kanbanUsers);
  738. $users = $this->user->getPairs('noclosed|nodeleted');
  739. $this->view->card = $card;
  740. $this->view->users = $users;
  741. $this->view->kanbanUsers = $kanbanUsers;
  742. $this->view->kanban = $kanban;
  743. $this->display();
  744. }
  745. /**
  746. * 完成卡片。
  747. * Finish a card.
  748. *
  749. * @param int $cardID
  750. * @access public
  751. * @return void
  752. */
  753. public function finishCard($cardID)
  754. {
  755. $oldCard = $this->kanban->getCardByID($cardID);
  756. $this->dao->update(TABLE_KANBANCARD)->set('progress')->eq(100)->set('status')->eq('done')->where('id')->eq($cardID)->exec();
  757. $card = $this->kanban->getCardByID($cardID);
  758. $changes = common::createChanges($oldCard, $card);
  759. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  760. $actionID = $this->loadModel('action')->create('kanbanCard', $cardID, 'finished');
  761. $this->action->logHistory($actionID, $changes);
  762. $callback = $this->kanban->getKanbanCallback($card->kanban, $card->region);
  763. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  764. }
  765. /**
  766. * 激活卡片。
  767. * Activate a card.
  768. *
  769. * @param int $cardID
  770. * @access public
  771. * @return void
  772. */
  773. public function activateCard($cardID)
  774. {
  775. $card = $this->kanban->getCardByID($cardID);
  776. if(!empty($_POST))
  777. {
  778. $this->kanban->activateCard($cardID);
  779. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  780. $callback = $this->kanban->getKanbanCallback($card->kanban, $card->region);
  781. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  782. }
  783. $this->view->card = $card;
  784. $this->view->actions = $this->loadModel('action')->getList('kanbancard', $cardID);
  785. $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted');
  786. $this->display();
  787. }
  788. /**
  789. * 查看看板卡片详情。
  790. * View a card.
  791. *
  792. * @param int $cardID
  793. * @access public
  794. * @return void
  795. */
  796. public function viewCard($cardID)
  797. {
  798. $card = $this->kanban->getCardByID($cardID);
  799. $kanban = $this->kanban->getByID($card->kanban);
  800. $space = $this->kanban->getSpaceById($kanban->space);
  801. $this->view->card = $card;
  802. $this->view->actions = $this->loadModel('action')->getList('kanbancard', $cardID);
  803. $this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted');
  804. $this->view->space = $space;
  805. $this->view->kanban = $kanban;
  806. $this->view->usersAvatar = $this->user->getAvatarPairs();
  807. $this->display();
  808. }
  809. /**
  810. * 看板移动卡片。
  811. * Move a card.
  812. *
  813. * @param int $cardID
  814. * @param int $fromColID
  815. * @param int $toColID
  816. * @param int $fromLaneID
  817. * @param int $toLaneID
  818. * @param int $kanbanID
  819. * @param bool $showModal
  820. * @access public
  821. * @return void
  822. */
  823. public function moveCard($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID = 0, $showModal = false)
  824. {
  825. if($showModal)
  826. {
  827. $this->kanbanZen->moveCardByModal($cardID);
  828. if(!$_POST) return;
  829. }
  830. else
  831. {
  832. $this->kanban->moveCard($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID);
  833. }
  834. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  835. $this->loadModel('action')->create('kanbanCard', $cardID, 'moved');
  836. $card = $this->kanban->getCardByID($cardID);
  837. $callback = $this->kanban->getKanbanCallback($card->kanban, $card->region);
  838. return $this->send(array('result' => 'success', 'callback' => $callback, 'closeModal' => true));
  839. }
  840. /**
  841. * 转入其它看板的卡片。
  842. * Import card.
  843. *
  844. * @param int $kanbanID
  845. * @param int $regionID
  846. * @param int $groupID
  847. * @param int $columnID
  848. * @param int $selectedKanbanID
  849. * @param int $recTotal
  850. * @param int $recPerPage
  851. * @param int $pageID
  852. * @access public
  853. * @return void
  854. */
  855. public function importCard($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedKanbanID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
  856. {
  857. /* Load pager. */
  858. $this->app->loadClass('pager', true);
  859. $pager = new pager($recTotal, $recPerPage, $pageID);
  860. $cards2Imported = $this->kanban->getCards2Import($selectedKanbanID, $kanbanID, $pager);
  861. if($_POST)
  862. {
  863. $importedIDList = $this->kanban->importCard($kanbanID, $regionID, $groupID, $columnID);
  864. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  865. foreach($importedIDList as $cardID)
  866. {
  867. $this->loadModel('action')->create('kanbancard', (int)$cardID, 'importedcard', '', $cards2Imported[$cardID]->kanban);
  868. }
  869. $callback = $this->kanban->getKanbanCallback($kanbanID, $regionID);
  870. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  871. }
  872. /* Find Kanban other than this kanban. */
  873. $kanbanPairs = $this->kanban->getKanbanPairs();
  874. unset($kanbanPairs[$kanbanID]);
  875. $this->view->cards2Imported = $cards2Imported;
  876. $this->view->kanbanPairs = array($this->lang->kanban->allKanban) + $kanbanPairs;
  877. $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
  878. $this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted');
  879. $this->view->pager = $pager;
  880. $this->view->selectedKanbanID = $selectedKanbanID;
  881. $this->view->kanbanID = $kanbanID;
  882. $this->view->regionID = $regionID;
  883. $this->view->groupID = $groupID;
  884. $this->view->columnID = $columnID;
  885. $this->display();
  886. }
  887. /**
  888. * 导入产品计划。
  889. * Import plan.
  890. *
  891. * @param int $kanbanID
  892. * @param int $regionID
  893. * @param int $groupID
  894. * @param int $columnID
  895. * @param int $selectedProductID
  896. * @param int $recTotal
  897. * @param int $recPerPage
  898. * @param int $pageID
  899. * @access public
  900. * @return void
  901. */
  902. public function importPlan($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProductID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
  903. {
  904. if($_POST)
  905. {
  906. $importedIDList = $this->kanban->importObject($kanbanID, $regionID, $groupID, $columnID, 'productplan');
  907. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  908. foreach($importedIDList as $cardID => $planID)
  909. {
  910. $this->loadModel('action')->create('kanbancard', $cardID, 'importedProductplan', '', $planID);
  911. }
  912. $callback = $this->kanban->getKanbanCallback($kanbanID, $regionID);
  913. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  914. }
  915. /* Load pager. */
  916. $this->app->loadClass('pager', true);
  917. $pager = new pager($recTotal, $recPerPage, $pageID);
  918. $productPairs = $this->kanban->getCanImportProducts('productplan');
  919. $selectedProductID = empty($selectedProductID) ? key($productPairs) : $selectedProductID;
  920. $this->view->products = $productPairs;
  921. $this->view->selectedProductID = $selectedProductID;
  922. $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
  923. $this->view->plans2Imported = $this->loadModel('productplan')->getList($selectedProductID, '0', 'all', $pager, 'begin_desc', 'skipparent|noproduct');
  924. $this->view->pager = $pager;
  925. $this->view->kanbanID = $kanbanID;
  926. $this->view->regionID = $regionID;
  927. $this->view->groupID = $groupID;
  928. $this->view->columnID = $columnID;
  929. $this->display();
  930. }
  931. /**
  932. * 导入产品发布。
  933. * Import release.
  934. *
  935. * @param int $kanbanID
  936. * @param int $regionID
  937. * @param int $groupID
  938. * @param int $columnID
  939. * @param int $selectedProductID
  940. * @param int $recTotal
  941. * @param int $recPerPage
  942. * @param int $pageID
  943. * @access public
  944. * @return void
  945. */
  946. public function importRelease($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProductID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
  947. {
  948. if($_POST)
  949. {
  950. $importedIDList = $this->kanban->importObject($kanbanID, $regionID, $groupID, $columnID, 'release');
  951. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  952. foreach($importedIDList as $cardID => $releaseID)
  953. {
  954. $this->loadModel('action')->create('kanbancard', $cardID, 'importedRelease', '', $releaseID);
  955. }
  956. $callback = $this->kanban->getKanbanCallback($kanbanID, $regionID);
  957. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  958. }
  959. /* Load pager. */
  960. $this->app->loadClass('pager', true);
  961. $pager = new pager($recTotal, $recPerPage, $pageID);
  962. $this->view->products = $this->kanban->getCanImportProducts('release');
  963. $this->view->selectedProductID = $selectedProductID;
  964. $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
  965. $this->view->releases2Imported = $this->loadModel('release')->getList($selectedProductID, 'all', 'all', 't1.date_desc', '', $pager);
  966. $this->view->pager = $pager;
  967. $this->view->kanbanID = $kanbanID;
  968. $this->view->regionID = $regionID;
  969. $this->view->groupID = $groupID;
  970. $this->view->columnID = $columnID;
  971. $this->view->appList = $this->loadModel('system')->getPairs();
  972. $this->display();
  973. }
  974. /**
  975. * 导入项目版本。
  976. * Import build.
  977. *
  978. * @param int $kanbanID
  979. * @param int $regionID
  980. * @param int $groupID
  981. * @param int $columnID
  982. * @param int $selectedProjectID
  983. * @param int $recTotal
  984. * @param int $recPerPage
  985. * @param int $pageID
  986. * @access public
  987. * @return void
  988. */
  989. public function importBuild($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProjectID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
  990. {
  991. if($_POST)
  992. {
  993. $importedIDList = $this->kanban->importObject($kanbanID, $regionID, $groupID, $columnID, 'build');
  994. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  995. foreach($importedIDList as $cardID => $buildID)
  996. {
  997. $this->loadModel('action')->create('kanbancard', $cardID, 'importedBuild', '', $buildID);
  998. }
  999. $callback = $this->kanban->getKanbanCallback($kanbanID, $regionID);
  1000. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  1001. }
  1002. /* Load pager. */
  1003. $this->app->loadClass('pager', true);
  1004. $pager = new pager($recTotal, $recPerPage, $pageID);
  1005. $builds2Imported = array();
  1006. $projects = array($this->lang->kanban->allProjects);
  1007. $projects += $this->loadModel('project')->getPairsByProgram(0, 'all', false, 'order_asc', 'kanban');
  1008. $builds2Imported = $this->loadModel('build')->getProjectBuilds($selectedProjectID, 'all', '0', 't1.date_desc,t1.id_desc', $pager);
  1009. $this->view->projects = $projects;
  1010. $this->view->selectedProjectID = $selectedProjectID;
  1011. $this->view->builds2Imported = $builds2Imported;
  1012. $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
  1013. $this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted');
  1014. $this->view->pager = $pager;
  1015. $this->view->kanbanID = $kanbanID;
  1016. $this->view->regionID = $regionID;
  1017. $this->view->groupID = $groupID;
  1018. $this->view->columnID = $columnID;
  1019. $this->view->appList = $this->loadModel('system')->getPairs();
  1020. $this->display();
  1021. }
  1022. /**
  1023. * 导入执行。
  1024. * Import execution.
  1025. *
  1026. * @param int $kanbanID
  1027. * @param int $regionID
  1028. * @param int $groupID
  1029. * @param int $columnID
  1030. * @param int $selectedProjectID
  1031. * @param int $recTotal
  1032. * @param int $recPerPage
  1033. * @param int $pageID
  1034. * @access public
  1035. * @return void
  1036. */
  1037. public function importExecution($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProjectID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
  1038. {
  1039. if($_POST)
  1040. {
  1041. $importedIDList = $this->kanban->importObject($kanbanID, $regionID, $groupID, $columnID, 'execution');
  1042. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  1043. foreach($importedIDList as $cardID => $executionID)
  1044. {
  1045. $this->loadModel('action')->create('kanbancard', $cardID, 'importedExecution', '', $executionID);
  1046. }
  1047. $callback = $this->kanban->getKanbanCallback($kanbanID, $regionID);
  1048. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  1049. }
  1050. /* Load pager. */
  1051. $this->app->loadClass('pager', true);
  1052. $pager = new pager($recTotal, $recPerPage, $pageID);
  1053. $this->view->projects = array($this->lang->kanban->allProjects) + $this->loadModel('project')->getPairsByProgram(0, 'all', false, '', '', '', 'multiple');
  1054. $this->view->selectedProjectID = $selectedProjectID;
  1055. $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
  1056. $this->view->executions2Imported = $this->loadModel('execution')->getStatData($selectedProjectID, 'undone', 0, 0, false, 'hasParentName', 'id_asc', $pager);
  1057. $this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted');
  1058. $this->view->pager = $pager;
  1059. $this->view->kanbanID = $kanbanID;
  1060. $this->view->regionID = $regionID;
  1061. $this->view->groupID = $groupID;
  1062. $this->view->columnID = $columnID;
  1063. $this->display();
  1064. }
  1065. /**
  1066. * 导入工单。
  1067. * Import ticket.
  1068. *
  1069. * @param int $kanbanID
  1070. * @param int $regionID
  1071. * @param int $groupID
  1072. * @param int $columnID
  1073. * @param int $selectedProductID
  1074. * @param int $recTotal
  1075. * @param int $recPerPage
  1076. * @param int $pageID
  1077. * @access public
  1078. * @return void
  1079. */
  1080. public function importTicket($kanbanID = 0, $regionID = 0, $groupID = 0, $columnID = 0, $selectedProductID = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
  1081. {
  1082. if($_POST)
  1083. {
  1084. $importedIDList = $this->kanban->importObject($kanbanID, $regionID, $groupID, $columnID, 'ticket');
  1085. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  1086. foreach($importedIDList as $cardID => $ticketID)
  1087. {
  1088. $this->loadModel('action')->create('kanbancard', $cardID, 'importedTicket', '', $ticketID);
  1089. }
  1090. return print(js::locate($this->createLink('kanban', 'view', "kanbanID=$kanbanID"), 'parent.parent'));
  1091. }
  1092. /* Load pager. */
  1093. $this->app->loadClass('pager', true);
  1094. $pager = new pager($recTotal, $recPerPage, $pageID);
  1095. $this->view->products = array('all' => $this->lang->kanban->allProducts) + $this->loadModel('feedback')->getGrantProducts();
  1096. $this->view->selectedProductID = $selectedProductID;
  1097. $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID);
  1098. $this->view->tickets2Imported = $this->loadModel('ticket')->getTicketByProduct($selectedProductID, 'noclosed|nodone', 'id_desc', $pager);
  1099. $this->view->users = $this->loadModel('user')->getPairs('noletter');
  1100. $this->view->pager = $pager;
  1101. $this->view->kanbanID = $kanbanID;
  1102. $this->view->regionID = $regionID;
  1103. $this->view->groupID = $groupID;
  1104. $this->view->columnID = $columnID;
  1105. $this->display();
  1106. }
  1107. /**
  1108. * 设置卡片颜色。
  1109. * Set a card's color.
  1110. *
  1111. * @param int $cardID
  1112. * @param string $color
  1113. * @access public
  1114. * @return string
  1115. */
  1116. public function setCardColor($cardID, $color)
  1117. {
  1118. $this->kanban->updateCardColor($cardID, $color);
  1119. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  1120. $card = $this->kanban->getCardByID($cardID);
  1121. $callback = $this->kanban->getKanbanCallback($card->kanban, $card->region);
  1122. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  1123. }
  1124. /**
  1125. * 排序卡片。
  1126. * Sort cards.
  1127. *
  1128. * @param int $kanbanID
  1129. * @param int $laneID
  1130. * @param int $columnID
  1131. * @param string $cards
  1132. * @access public
  1133. * @return void
  1134. */
  1135. public function sortCard($kanbanID, $laneID, $columnID, $cards = '')
  1136. {
  1137. if(empty($cards)) return;
  1138. $this->dao->update(TABLE_KANBANCELL)->set('cards')->eq(",$cards,")->where('kanban')->eq($kanbanID)->andWhere('lane')->eq($laneID)->andWhere('`column`')->eq($columnID)->exec();
  1139. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  1140. $lane = $this->kanban->getLaneById($laneID);
  1141. $callback = $this->kanban->getKanbanCallback($kanbanID, $lane->region);
  1142. return $this->send(array('result' => 'success', 'callback' => $callback));
  1143. }
  1144. /**
  1145. * 归档看板卡片。
  1146. * Archive a card.
  1147. *
  1148. * @param int $cardID
  1149. * @access public
  1150. * @return void
  1151. */
  1152. public function archiveCard($cardID)
  1153. {
  1154. $this->kanban->archiveCard($cardID);
  1155. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  1156. return $this->send(array('result' => 'success', 'load' => true, 'closeModal' => true));
  1157. }
  1158. /**
  1159. * 查看归档的卡片。
  1160. * View archived cards.
  1161. *
  1162. * @param int $regionID
  1163. * @access public
  1164. * @return void
  1165. */
  1166. public function viewArchivedCard($regionID)
  1167. {
  1168. $region = $this->kanban->getRegionByID($regionID);
  1169. $cards = $this->kanban->getCardsByObject('region', $regionID, '1');
  1170. foreach($this->config->kanban->fromType as $fromType)
  1171. {
  1172. $cards = $this->kanban->getImportedCards($region->kanban, $cards, $fromType, 1, $regionID);
  1173. }
  1174. $this->view->kanban = $this->kanban->getByID($region->kanban);
  1175. $this->view->cards = $cards;
  1176. $this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted');
  1177. $this->view->userIdPairs = $this->user->getPairs('noletter|nodeleted|showid');
  1178. $this->view->usersAvatar = $this->user->getAvatarPairs();
  1179. $this->display();
  1180. }
  1181. /**
  1182. * 还原看板卡片。
  1183. * Restore a card.
  1184. *
  1185. * @param int $cardID
  1186. * @access public
  1187. * @return void
  1188. */
  1189. public function restoreCard($cardID)
  1190. {
  1191. $this->kanban->restoreCard($cardID);
  1192. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  1193. return $this->send(array('result' => 'success', 'load' => true, 'closeModal' => true));
  1194. }
  1195. /**
  1196. * 删除看板卡片。
  1197. * Delete a card.
  1198. *
  1199. * @param int $cardID
  1200. * @access public
  1201. * @return void
  1202. */
  1203. public function deleteCard($cardID)
  1204. {
  1205. $card = $this->kanban->getCardByID($cardID);
  1206. if($card->fromType == '') $this->kanban->delete(TABLE_KANBANCARD, $cardID);
  1207. if($card->fromType != '') $this->dao->delete()->from(TABLE_KANBANCARD)->where('id')->eq($cardID)->exec();
  1208. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'load' => true, 'callback' => array('name' => 'updateKanbanRegion', 'params' => array('region' . $card->region, array('items' => array(array('key' => 'group' . $card->group, 'data' => array('items' => array(array('id' => $cardID, 'name' => $cardID, 'deleted' => true))))))))));
  1209. }
  1210. /**
  1211. * 设置看板在制品限制。
  1212. * Set WIP.
  1213. *
  1214. * @param int $columnID
  1215. * @param int $executionID
  1216. * @param string $from kanban|execution
  1217. * @access public
  1218. * @return void
  1219. */
  1220. public function setWIP($columnID, $executionID = 0, $from = 'kanban')
  1221. {
  1222. $this->app->loadLang('story');
  1223. $column = $this->kanban->getColumnById($columnID);
  1224. if(!$column) return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->notFound, 'locate' => $this->createLink('execution', 'kanban', "executionID=$executionID"))));
  1225. if($_POST)
  1226. {
  1227. $WIP = form::data($this->config->kanban->form->setWIP)->get();
  1228. $this->kanban->setWIP($columnID, $WIP);
  1229. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  1230. $this->loadModel('action')->create('kanbancolumn', $columnID, 'Edited', '', $executionID);
  1231. if($from != 'kanban') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "refreshKanban()"));
  1232. $region = $this->kanban->getRegionByID($column->region);
  1233. $callback = $this->kanban->getKanbanCallback($region->kanban, $region->id);
  1234. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  1235. }
  1236. $this->view->column = $column;
  1237. $this->view->from = $from;
  1238. if($from != 'kanban') $this->view->status = zget($this->config->kanban->{$column->laneType . 'ColumnStatusList'}, $column->type);
  1239. $this->display();
  1240. }
  1241. /**
  1242. * 设置泳道。
  1243. * Set lane info.
  1244. *
  1245. * @param int $laneID
  1246. * @param int $executionID
  1247. * @param string $from kanban|execution
  1248. * @access public
  1249. * @return void
  1250. */
  1251. public function setLane($laneID, $executionID = 0, $from = 'kanban')
  1252. {
  1253. if($_POST)
  1254. {
  1255. $lane = form::data($this->config->kanban->form->setLane)->get();
  1256. $this->kanban->setLane($laneID, $lane);
  1257. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  1258. $this->loadModel('action')->create('kanbanlane', $laneID, 'Edited', '', $executionID);
  1259. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => true, 'closeModal' => true));
  1260. }
  1261. $lane = $this->kanban->getLaneById($laneID);
  1262. if(!$lane) return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->notFound, 'locate' => $this->createLink('execution', 'kanban', "executionID=$executionID"))));
  1263. $this->view->lane = $lane;
  1264. $this->view->from = $from;
  1265. $this->display();
  1266. }
  1267. /**
  1268. * 编辑泳道名称。
  1269. * Edit lane's name
  1270. *
  1271. * @param int $laneID
  1272. * @param int $executionID
  1273. * @param string $from
  1274. * @access public
  1275. * @return void
  1276. */
  1277. public function editLaneName($laneID, $executionID = 0, $from = 'kanban')
  1278. {
  1279. if($_POST)
  1280. {
  1281. $lane = form::data($this->config->kanban->form->setLane)->remove('color')->get();
  1282. $this->kanban->setLane($laneID, $lane);
  1283. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  1284. $this->loadModel('action')->create('kanbanlane', $laneID, 'Edited', '', $executionID);
  1285. if($this->config->vision == 'lite') return $this->send(array('result' => 'success', 'closeModal' => true, 'load' => true));
  1286. $lane = $this->kanban->getLaneById($laneID);
  1287. $region = $this->kanban->getRegionByID($lane->region);
  1288. $callback = $this->kanban->getKanbanCallback($region->kanban, $region->id);
  1289. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  1290. }
  1291. $lane = $this->kanban->getLaneById($laneID);
  1292. if(!$lane) return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->notFound, 'locate' => $this->createLink('execution', 'kanban', "executionID=$executionID"))));
  1293. $this->view->lane = $lane;
  1294. $this->view->from = $from;
  1295. $this->display();
  1296. }
  1297. /**
  1298. * Edit lane's color
  1299. *
  1300. * @param int $laneID
  1301. * @param int $executionID
  1302. * @param string $from
  1303. * @access public
  1304. * @return void
  1305. */
  1306. public function editLaneColor($laneID, $executionID = 0, $from = 'kanban')
  1307. {
  1308. if($_POST)
  1309. {
  1310. $lane = form::data($this->config->kanban->form->setLane)->remove('name')->get();
  1311. $this->kanban->setLane($laneID, $lane);
  1312. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  1313. $this->loadModel('action')->create('kanbanlane', $laneID, 'Edited', '', $executionID);
  1314. $lane = $this->kanban->getLaneById($laneID);
  1315. $region = $this->kanban->getRegionByID($lane->region);
  1316. $callback = $this->kanban->getKanbanCallback($region->kanban, $region->id);
  1317. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  1318. }
  1319. $lane = $this->kanban->getLaneById($laneID);
  1320. if(!$lane) return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->notFound, 'locate' => $this->createLink('execution', 'kanban', "executionID=$executionID"))));
  1321. $this->view->lane = $lane;
  1322. $this->view->from = $from;
  1323. $this->display();
  1324. }
  1325. /**
  1326. * 编辑看板列。
  1327. * Set lane column info.
  1328. *
  1329. * @param int $columnID
  1330. * @param int $executionID
  1331. * @param string $from kanban|execution
  1332. * @access public
  1333. * @return void
  1334. */
  1335. public function setColumn($columnID, $executionID = 0, $from = 'kanban')
  1336. {
  1337. $column = $this->kanban->getColumnByID($columnID);
  1338. if($_POST)
  1339. {
  1340. $this->lang->kanban->name = $this->lang->kanbancolumn->name;
  1341. $formData = form::data($this->config->kanban->form->setColumn)->get();
  1342. $changes = $this->kanban->updateColumn($columnID, $formData);
  1343. if(dao::isError()) return $this->sendError(dao::getError());
  1344. if($changes)
  1345. {
  1346. $actionID = $this->loadModel('action')->create('kanbancolumn', $columnID, 'edited', '', $executionID);
  1347. $this->action->logHistory($actionID, $changes);
  1348. }
  1349. if($from == 'RDKanban') return $this->send(array('result' => 'success', 'closeModal' => true, 'callback' => "refreshKanban()"));
  1350. $region = $this->kanban->getRegionByID($column->region);
  1351. $callback = $this->kanban->getKanbanCallback($region->kanban, $region->id);
  1352. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => $callback));
  1353. }
  1354. $this->view->canEdit = $from == 'RDKanban' ? 0 : 1;
  1355. $this->view->column = $column;
  1356. $this->display();
  1357. }
  1358. /**
  1359. * 拖动看板卡片。
  1360. * Ajax move card.
  1361. *
  1362. * @param int $cardID
  1363. * @param int $fromColID
  1364. * @param int $toColID
  1365. * @param int $fromLaneID
  1366. * @param int $toLaneID
  1367. * @param int $executionID
  1368. * @param string $browseType
  1369. * @param string $groupBy
  1370. * @param int $regionID
  1371. * @param string $orderBy
  1372. * @access public
  1373. * @return void
  1374. */
  1375. public function ajaxMoveCard($cardID = 0, $fromColID = 0, $toColID = 0, $fromLaneID = 0, $toLaneID = 0, $executionID = 0, $browseType = 'all', $groupBy = '', $regionID = 0, $orderBy = '')
  1376. {
  1377. $fromCell = $this->dao->select('id, cards, lane')->from(TABLE_KANBANCELL)
  1378. ->where('kanban')->eq($executionID)
  1379. ->andWhere('`column`')->eq($fromColID)
  1380. ->beginIF(!$groupBy or $groupBy == 'default')->andWhere('lane')->eq($fromLaneID)->fi()
  1381. ->beginIF($groupBy and $groupBy != 'default')
  1382. ->andWhere('type')->eq($browseType)
  1383. ->andWhere('cards')->like("%,$cardID,%")
  1384. ->fi()
  1385. ->fetch();
  1386. if($groupBy and $groupBy != 'default') $fromLaneID = $toLaneID = $fromCell->lane;
  1387. $toCell = $this->dao->select('id, cards')->from(TABLE_KANBANCELL)
  1388. ->where('kanban')->eq($executionID)
  1389. ->andWhere('lane')->eq($toLaneID)
  1390. ->andWhere('`column`')->eq($toColID)
  1391. ->fetch();
  1392. $fromCards = str_replace(",$cardID,", ',', $fromCell->cards);
  1393. $fromCards = $fromCards == ',' ? '' : $fromCards;
  1394. $toCards = ',' . implode(',', array_unique(array_filter(explode(',', !empty($toCell->cards) ? $toCell->cards : '')))) . ",$cardID,";
  1395. $this->kanban->updateExecutionCell($executionID, $fromColID, $fromLaneID, $fromCards);
  1396. $this->kanban->updateExecutionCell($executionID, $toColID, $toLaneID, $toCards);
  1397. $toColumn = $this->kanban->getColumnByID($toColID);
  1398. if($toColumn->laneType == 'story' and in_array($toColumn->type, array('tested', 'verified', 'released', 'closed')))
  1399. {
  1400. $data = new stdclass();
  1401. $data->stage = $toColumn->type;
  1402. if($toColumn->type == 'released')
  1403. {
  1404. $fromColumn = $this->kanban->getColumnByID($fromColID);
  1405. if($fromColumn->type == 'closed') $data->status = 'active';
  1406. }
  1407. $this->dao->update(TABLE_STORY)->data($data)->where('id')->eq($cardID)->exec();
  1408. $this->dao->update(TABLE_STORYSTAGE)->set('stage')->eq($toColumn->type)->where('story')->eq($cardID)->exec();
  1409. }
  1410. $taskSearchValue = $this->session->taskSearchValue ? $this->session->taskSearchValue : '';
  1411. $rdSearchValue = $this->session->rdSearchValue ? $this->session->rdSearchValue : '';
  1412. if($regionID == 0)
  1413. {
  1414. list($kanbanGroup, $links) = $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy, $taskSearchValue);
  1415. }
  1416. else
  1417. {
  1418. $kanbanGroup = $this->kanban->getRDKanban($executionID, $browseType, $orderBy, $regionID, $groupBy, $rdSearchValue);
  1419. }
  1420. echo json_encode($kanbanGroup);
  1421. }
  1422. /**
  1423. * 获取看板左上角下拉菜单。
  1424. * Ajax get kanban menu.
  1425. *
  1426. * @param int $kanbanID
  1427. * @param string $moduleName
  1428. * @param string $methodName
  1429. * @access public
  1430. * @return void
  1431. */
  1432. public function ajaxGetDropMenu($kanbanID, $moduleName, $methodName)
  1433. {
  1434. $kanbanIdList = $this->kanban->getCanViewObjects();
  1435. $spacePairs = $this->kanban->getSpacePairs('showClosed');
  1436. $this->view->kanbanList = $this->dao->select('*')->from(TABLE_KANBAN)
  1437. ->where('deleted')->eq('0')
  1438. ->andWhere('id')->in($kanbanIdList)
  1439. ->andWhere('space')->in(array_keys($spacePairs))
  1440. ->fetchGroup('space');
  1441. $this->view->kanbanID = $kanbanID;
  1442. $this->view->spaceList = $spacePairs;
  1443. $this->view->module = $moduleName;
  1444. $this->view->method = $methodName;
  1445. $this->view->link = $this->createLink('kanban', 'view', 'id={id}');
  1446. $this->display();
  1447. }
  1448. /**
  1449. * 获取区域中的泳道。
  1450. * Ajax get lanes by region id.
  1451. *
  1452. * @param int $regionID
  1453. * @param string $type all|story|task|bug
  1454. * @param string $field otherLane|lane
  1455. * @param string $pageType
  1456. * @access public
  1457. * @return string
  1458. */
  1459. public function ajaxGetLanes($regionID, $type = 'all', $field = 'otherLane', $pageType = '')
  1460. {
  1461. $lanes = $this->kanban->getLanePairsByRegion($regionID, $type);
  1462. if($this->viewType == 'json') return print($lanes);
  1463. $laneList = array();
  1464. foreach($lanes as $laneID => $laneName) $laneList[] = array('value' => $laneID, 'text' => $laneName);
  1465. if($pageType == 'batch') return $this->send($laneList);
  1466. return print(json_encode(array('items' => $laneList, 'name' => $field)));
  1467. }
  1468. /**
  1469. * 获取泳道的列。
  1470. * Ajax get columns by lane id.
  1471. *
  1472. * @param int $laneID
  1473. * @access public
  1474. * @return string
  1475. */
  1476. public function ajaxGetColumns($laneID)
  1477. {
  1478. $lane = $this->kanban->getLaneByID($laneID);
  1479. $columns = $this->dao->select('id,name')->from(TABLE_KANBANCOLUMN)
  1480. ->where('deleted')->eq(0)
  1481. ->andWhere('`group`')->eq($lane->group)
  1482. ->andWhere('parent')->ne('-1')
  1483. ->orderBy('id_asc')
  1484. ->fetchPairs();
  1485. $columnList = array();
  1486. foreach($columns as $columnID => $columnName) $columnList[] = array('value' => $columnID, 'text' => $columnName);
  1487. return print(json_encode($columnList));
  1488. }
  1489. /**
  1490. * Ajax load space users.
  1491. *
  1492. * @param int $spaceID
  1493. * @param string $field team|whitelist|owner
  1494. * @param string $space all|space
  1495. * @access public
  1496. * @return string
  1497. * @param string $type
  1498. */
  1499. public function ajaxLoadUsers($spaceID, $field = '', $type = 'space')
  1500. {
  1501. $space = $this->kanban->getSpaceById($spaceID);
  1502. $accounts = '';
  1503. if(!empty($space) and $field == 'owner' and $type != 'all') $accounts = trim($space->owner) . ',' . trim($space->team);
  1504. $users = $this->loadModel('user')->getPairs('noclosed|nodeleted', '', 0, $accounts);
  1505. $userList = array();
  1506. foreach($users as $account => $user) $userList[] = array('text' => $user, 'value' => $account, 'key' => $user . $account);
  1507. return print(json_encode($userList));
  1508. }
  1509. /**
  1510. * 保存当前区域到Session。
  1511. * Ajax save regionID.
  1512. *
  1513. * @param int $regionID
  1514. * @access public
  1515. * @return void
  1516. */
  1517. public function ajaxSaveRegionID($regionID)
  1518. {
  1519. $this->session->set('regionID', $regionID, 'kanban');
  1520. }
  1521. /**
  1522. * 获取排序的列表。
  1523. * Ajax Get sort items.
  1524. *
  1525. * @param string $objectType
  1526. * @param int $objectID
  1527. * @access public
  1528. * @return void
  1529. */
  1530. public function ajaxGetSortItems($objectType, $objectID)
  1531. {
  1532. $itemList = array();
  1533. if($objectType == 'region')
  1534. {
  1535. $region = $this->kanban->getRegionByID($objectID);
  1536. $regionPairs = $this->kanban->getRegionPairs($region->kanban);
  1537. foreach($regionPairs as $regionID => $regionName) $itemList[] = array('id' => $regionID, 'text' => $regionName);
  1538. }
  1539. else if($objectType == 'column')
  1540. {
  1541. $column = $this->kanban->getColumnByID($objectID);
  1542. $columnPairs = $this->kanban->getColumnPairsByGroup($column->group, $column->parent);
  1543. foreach($columnPairs as $columnID => $columnName) $itemList[] = array('id' => $columnID, 'text' => $columnName);
  1544. }
  1545. else if($objectType == 'lane')
  1546. {
  1547. $lane = $this->kanban->getLaneById($objectID);
  1548. $lanePairs = $this->kanban->getLanePairsByGroup($lane->group);
  1549. foreach($lanePairs as $laneID => $laneName) $itemList[] = array('id' => $laneID, 'text' => $laneName);
  1550. }
  1551. return print(json_encode($itemList));
  1552. }
  1553. /**
  1554. * 获取空间的团队成员。
  1555. * Ajax get space team memebers.
  1556. *
  1557. * @param int $spaceID
  1558. * @access public
  1559. * @return void
  1560. */
  1561. public function ajaxGetSpaceTeam($spaceID)
  1562. {
  1563. $space = $this->loadModel('kanban')->getSpaceById($spaceID);
  1564. return print(json_encode($space->team));
  1565. }
  1566. }