From e8010e951aee59df93e20f714bde89ffce23fad9 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Fri, 22 Oct 2021 09:22:54 +0800 Subject: [PATCH 1/6] * Add table of kanban. --- db/update15.7.sql | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 db/update15.7.sql diff --git a/db/update15.7.sql b/db/update15.7.sql new file mode 100644 index 0000000000..e901955fb3 --- /dev/null +++ b/db/update15.7.sql @@ -0,0 +1,26 @@ +-- DROP TABLE IF EXISTS `zt_kanbanlane`; +CREATE TABLE IF NOT EXISTS `zt_kanbanlane` ( + `id` int(8) NOT NULL AUTO_INCREMENT, + `execution` mediumint(8) NOT NULL DEFAULT '0', + `type` char(30) NOT NULL, + `name` varchar(255) NOT NULL DEFAULT '', + `color` char(30) NOT NULL, + `order` smallint(6) NOT NULL DEFAULT '0', + `deleted` enum('0','1') NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- DROP TABLE IF EXISTS `zt_kanbancolumn`; +CREATE TABLE IF NOT EXISTS `zt_kanbancolumn` ( + `id` int(8) NOT NULL AUTO_INCREMENT, + `lane` mediumint(8) NOT NULL DEFAULT '0', + `parent` mediumint(8) NOT NULL DEFAULT '0', + `type` char(30) NOT NULL, + `name` varchar(255) NOT NULL DEFAULT '', + `color` char(30) NOT NULL, + `limit` smallint(6) NOT NULL DEFAULT '-1', + `order` mediumint(8) NOT NULL DEFAULT '0', + `cards` text NULL, + `deleted` enum('0','1') NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; From 3d22a50a001fd71e03b36a3e255650f37ae5a8a0 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 25 Oct 2021 14:13:44 +0800 Subject: [PATCH 2/6] * Create the single execution Kanban lane and Kanban column. --- config/zentaopms.php | 2 + db/zentao.sql | 25 ++++ module/bug/model.php | 4 +- module/common/lang/common.php | 1 + module/execution/control.php | 17 +-- module/execution/model.php | 6 +- module/kanban/lang/zh-cn.php | 35 ++++++ module/kanban/model.php | 223 ++++++++++++++++++++++++++++++++++ module/upgrade/model.php | 23 ++++ 9 files changed, 325 insertions(+), 11 deletions(-) create mode 100644 module/kanban/lang/zh-cn.php create mode 100644 module/kanban/model.php diff --git a/config/zentaopms.php b/config/zentaopms.php index 8508db61cd..5acf07c756 100644 --- a/config/zentaopms.php +++ b/config/zentaopms.php @@ -228,6 +228,8 @@ define('TABLE_RELATION', '`' . $config->db->prefix . 'relation`'); define('TABLE_REPOHISTORY', '`' . $config->db->prefix . 'repohistory`'); define('TABLE_REPOFILES', '`' . $config->db->prefix . 'repofiles`'); define('TABLE_REPOBRANCH', '`' . $config->db->prefix . 'repobranch`'); +define('TABLE_KANBANLANE', '`' . $config->db->prefix . 'kanbanlane`'); +define('TABLE_KANBANCOLUMN', '`' . $config->db->prefix . 'kanbancolumn`'); if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`'); if(!defined('TABLE_PROJECTSPEC')) define('TABLE_PROJECTSPEC', '`' . $config->db->prefix . 'projectspec`'); diff --git a/db/zentao.sql b/db/zentao.sql index 72235445df..925ff437a2 100644 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -595,6 +595,31 @@ CREATE TABLE IF NOT EXISTS `zt_job` ( `deleted` enum('0','1') NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- DROP TABLE IF EXISTS `zt_kanbanlane`; +CREATE TABLE IF NOT EXISTS `zt_kanbanlane` ( + `id` int(8) NOT NULL AUTO_INCREMENT, + `execution` mediumint(8) NOT NULL DEFAULT '0', + `type` char(30) NOT NULL, + `name` varchar(255) NOT NULL DEFAULT '', + `color` char(30) NOT NULL, + `order` smallint(6) NOT NULL DEFAULT '0', + `deleted` enum('0','1') NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- DROP TABLE IF EXISTS `zt_kanbancolumn`; +CREATE TABLE IF NOT EXISTS `zt_kanbancolumn` ( + `id` int(8) NOT NULL AUTO_INCREMENT, + `lane` mediumint(8) NOT NULL DEFAULT '0', + `parent` mediumint(8) NOT NULL DEFAULT '0', + `type` char(30) NOT NULL, + `name` varchar(255) NOT NULL DEFAULT '', + `color` char(30) NOT NULL, + `limit` smallint(6) NOT NULL DEFAULT '-1', + `order` mediumint(8) NOT NULL DEFAULT '0', + `cards` text NULL, + `deleted` enum('0','1') NOT NULL default '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- DROP TABLE IF EXISTS `zt_lang`; CREATE TABLE IF NOT EXISTS `zt_lang` ( `id` mediumint(8) unsigned NOT NULL auto_increment, diff --git a/module/bug/model.php b/module/bug/model.php index 24718b5a6b..8cfa5e97a6 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -1575,7 +1575,9 @@ class bugModel extends model ->beginIF($type == 'noclosed')->andWhere('status')->ne('closed')->fi() ->beginIF($build)->andWhere("CONCAT(',', openedBuild, ',') like '%,$build,%'")->fi() ->beginIF($excludeBugs)->andWhere('id')->notIN($excludeBugs)->fi() - ->orderBy($orderBy)->page($pager)->fetchAll(); + ->orderBy($orderBy) + ->page($pager) + ->fetchAll('id'); } $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'bug'); diff --git a/module/common/lang/common.php b/module/common/lang/common.php index 57a3c16b1c..137b14fb8e 100644 --- a/module/common/lang/common.php +++ b/module/common/lang/common.php @@ -75,6 +75,7 @@ $lang->file = new stdclass(); $lang->misc = new stdclass(); $lang->acl = new stdclass(); $lang->curd = new stdclass(); +$lang->kanban = new stdclass(); $lang->projectbuild = new stdclass(); $lang->projectrelease = new stdclass(); diff --git a/module/execution/control.php b/module/execution/control.php index 3b71572c4a..f819837e60 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1825,26 +1825,27 @@ class execution extends control * Kanban. * * @param int $executionID - * @param string $type - * @param string $orderBy + * @param string $objectType + * @param string $groupBy * @access public * @return void */ - public function kanban($executionID, $type = 'story', $orderBy = 'order_asc') + public function kanban($executionID, $objectType = 'all', $groupBy = 'id_desc') { /* Save to session. */ $uri = $this->app->getURI(true); - $this->app->session->set('taskList', $uri, 'execution'); - $this->app->session->set('bugList', $uri, 'qa'); + $this->app->session->set('taskList', $uri, 'execution'); + $this->app->session->set('bugList', $uri, 'qa'); /* Compatibility IE8*/ if(strpos($this->server->http_user_agent, 'MSIE 8.0') !== false) header("X-UA-Compatible: IE=EmulateIE7"); + $lanes = $this->loadModel('kanban')->getLanesByExecution($executionID, $objectType); $this->execution->setMenu($executionID); $execution = $this->loadModel('execution')->getById($executionID); - $tasks = $this->execution->getKanbanTasks($executionID, "id"); - $bugs = $this->loadModel('bug')->getExecutionBugs($executionID); - $stories = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, $orderBy); + $tasks = $this->execution->getKanbanTasks($executionID, "id"); + $bugs = $this->loadModel('bug')->getExecutionBugs($executionID); + $stories = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, $orderBy); /* Determines whether an object is editable. */ $canBeChanged = common::canModify('execution', $execution); diff --git a/module/execution/model.php b/module/execution/model.php index a1ebf3927e..fa7539ccf2 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -379,6 +379,8 @@ class executionModel extends model $creatorExists = false; $teamMembers = array(); + $this->loadModel('kanban')->addKanbanLanes($executionID); + /* Save order. */ $this->dao->update(TABLE_EXECUTION)->set('`order`')->eq($executionID * 5)->where('id')->eq($executionID)->exec(); $this->file->updateObjectID($this->post->uid, $executionID, 'execution'); @@ -3154,7 +3156,7 @@ class executionModel extends model */ public function getKanbanTasks($executionID, $orderBy = 'status_asc, id_desc', $pager = null) { - $tasks = $this->dao->select('t1.*, t2.id AS storyID, t2.title AS storyTitle, t2.version AS latestStoryVersion, t2.status AS storyStatus, t3.realname AS assignedToRealName') + $tasks = $this->dao->select('t1.*, t1.id as id, t2.id AS storyID, t2.title AS storyTitle, t2.version AS latestStoryVersion, t2.status AS storyStatus, t3.realname AS assignedToRealName') ->from(TABLE_TASK)->alias('t1') ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id') ->leftJoin(TABLE_USER)->alias('t3')->on('t1.assignedTo = t3.account') @@ -3163,7 +3165,7 @@ class executionModel extends model ->andWhere('t1.parent')->ge(0) ->orderBy($orderBy) ->page($pager) - ->fetchAll(); + ->fetchAll('id'); $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'task'); diff --git a/module/kanban/lang/zh-cn.php b/module/kanban/lang/zh-cn.php new file mode 100644 index 0000000000..f61ea60e52 --- /dev/null +++ b/module/kanban/lang/zh-cn.php @@ -0,0 +1,35 @@ +kanban = new stdClass(); + +$lang->kanban->storyColumn = array(); +$lang->kanban->storyColumn['backlog'] = 'Backlog'; +$lang->kanban->storyColumn['ready'] = '准备好'; +$lang->kanban->storyColumn['develop'] = '开发'; +$lang->kanban->storyColumn['developing'] = '进行中'; +$lang->kanban->storyColumn['developed'] = '完成'; +$lang->kanban->storyColumn['test'] = '测试'; +$lang->kanban->storyColumn['testing'] = '进行中'; +$lang->kanban->storyColumn['tested'] = '完成'; +$lang->kanban->storyColumn['verified'] = '已验收'; +$lang->kanban->storyColumn['released'] = '已发布'; +$lang->kanban->storyColumn['closed'] = '已关闭'; + +$lang->kanban->bugColumn = array(); +$lang->kanban->bugColumn['unconfirmed'] = '待确认'; +$lang->kanban->bugColumn['confirmed'] = '已确认'; +$lang->kanban->bugColumn['resolving'] = '解决中'; +$lang->kanban->bugColumn['fixing'] = '进行中'; +$lang->kanban->bugColumn['fixed'] = '完成'; +$lang->kanban->bugColumn['test'] = '测试'; +$lang->kanban->bugColumn['testing'] = '进行中'; +$lang->kanban->bugColumn['tested'] = '完成'; +$lang->kanban->bugColumn['closed'] = '已关闭'; + +$lang->kanban->taskColumn = array(); +$lang->kanban->taskColumn['wait'] = '未开始'; +$lang->kanban->taskColumn['develop'] = '开发'; +$lang->kanban->taskColumn['developing'] = '研发中'; +$lang->kanban->taskColumn['developed'] = '研发完毕'; +$lang->kanban->taskColumn['pause'] = '已暂停'; +$lang->kanban->taskColumn['canceled'] = '已取消'; +$lang->kanban->taskColumn['closed'] = '已关闭'; diff --git a/module/kanban/model.php b/module/kanban/model.php new file mode 100644 index 0000000000..d709f69563 --- /dev/null +++ b/module/kanban/model.php @@ -0,0 +1,223 @@ + + * @package kanban + * @version $Id: model.php 5118 2021-10-22 10:18:41Z $ + * @link https://www.zentao.net + */ +?> +dao->select('*')->from(TABLE_KANBANLANE) + ->where('execution')->eq($executionID) + ->andWhere('deleted')->eq(0) + ->beginIF($objectType != 'all')->andWhere('type')->eq($objectType) + ->fetchAll('id'); + } + + /** + * Add execution Kanban lanes. + * + * @param int|array $executionIdList + * @access public + * @return void + */ + public function addKanbanLanes($executionIdList) + { + if(is_numeric($executionIdList)) $executionIdList = (array)$executionIdList; + if(!is_array($executionIdList) or empty($executionIdList)) return; + + /* Set lane Information. */ + global $lang; + $storyLane = clone $bugLane = clone $taskLane = new stdClass(); + $storyLane->type = 'story'; + $storyLane->name = $lang->SRCommon; + $storyLane->color = '#7ec5ff'; + $storyLane->order = '5'; + + $bugLane->type = 'bug'; + $bugLane->name = $lang->bug->common; + $bugLane->color = '#ba55d3'; + $bugLane->order = '10'; + + $taskLane->type = 'task'; + $taskLane->name = $lang->task->common; + $taskLane->color = '#4169e1'; + $taskLane->order = '15'; + + /* Get stories, bugs and tasks. */ + $stories = $this->dao->select('t1.*,t2.project as project')->from(TABLE_STORY)->alias('t1') + ->leftJoin(TABLE_PROJECTSTORY)->alias('t2')->on('t1.id=t2.story') + ->where('t1.deleted')->eq(0) + ->andWhere('t1.parent')->ne('-1') + ->andWhere('t2.project')->in($executionIdList) + ->fetchGroup('project', 'id'); + + $bugs = $this->dao->select('*')->from(TABLE_BUG) + ->where('deleted')->eq(0) + ->andWhere('execution')->in($executionIdList) + ->fetchGroup('execution', 'id'); + + $tasks = $this->dao->select('*')->from(TABLE_TASK) + ->where('deleted')->eq(0) + ->andWhere('parent')->ne('-1') + ->andWhere('execution')->in($executionIdList) + ->fetchGroup('execution', 'id'); + + foreach($executionIdList as $executionID) + { + $storyLaneID = 0; + $bugLaneID = 0; + $taskLaneID = 0; + $developColumn = 0; + $testColumn = 0; + $resolvingColumn = 0; + + $lanes[$executionID] = new stdClass(); + $storyLane->execution = $bugLane->execution = $taskLane->execution = $executionID; + + $this->dao->insert(TABLE_KANBANLANE)->data($storyLane)->exec(); + $storyLaneID = $this->dao->lastInsertId(); + + $this->dao->insert(TABLE_KANBANLANE)->data($bugLane)->exec(); + $bugLaneID = $this->dao->lastInsertId(); + + $this->dao->insert(TABLE_KANBANLANE)->data($taskLane)->exec(); + $taskLaneID = $this->dao->lastInsertId(); + + $executionStories = empty($stories[$executionID]) ? array() : $stories[$executionID]; + foreach($this->lang->kanban->storyColumn as $type => $name) + { + $data = new stdClass(); + $data->lane = $storyLaneID; + $data->name = $name; + $data->type = $type; + $data->cards = ''; + if(strpos(',developing,developed,', $type) !== false) $data->parent = $developColumn; + if(strpos(',testing,tested,', $type) !== false) $data->parent = $testColumn; + if(strpos(',ready,develop,test,', $type) === false) + { + foreach($executionStories as $storyID => $story) + { + if($type == 'backlog' and $story->status == 'active' and $story->stage == 'projected') + { + $data->cards .= $storyID . ','; + unset($executionStories[$storyID]); + } + + if($type == 'closed' and $story->status == 'closed' and $story->stage == 'closed') + { + $data->cards .= $storyID . ','; + unset($executionStories[$storyID]); + } + + if($story->stage == $type and strpos(',backlog,closed,', $type) === false and $story->status == 'active') + { + $data->cards .= $storyID . ','; + unset($executionStories[$storyID]); + } + } + if(!empty($data->cards)) $data->cards = ',' . $data->cards; + } + $this->dao->insert(TABLE_KANBANCOLUMN)->data($data)->exec(); + if($type == 'develop') $developColumn = $this->dao->lastInsertId(); + if($type == 'test') $testColumn = $this->dao->lastInsertId(); + } + + $executionBugs = empty($bugs[$executionID]) ? array() : $bugs[$executionID]; + foreach($this->lang->kanban->bugColumn as $type => $name) + { + $data = new stdClass(); + $data->lane = $bugLaneID; + $data->name = $name; + $data->type = $type; + $data->cards = ''; + if(strpos(',fixing,fixed,', $type) !== false) $data->parent = $resolvingColumn; + if(strpos(',testing,tested,', $type) !== false) $data->parent = $testColumn; + if(strpos(',resolving,fixing,test,testing,tested,', $type) === false) + { + foreach($executionBugs as $bugID => $bug) + { + if($type == 'unconfirmed' and $bug->status == 'active' and $bug->confirmed == 0) + { + $data->cards .= $bugID . ','; + unset($executionBugs[$bugID]); + } + + if($type == 'confirmed' and $bug->status == 'active' and $bug->confirmed == 1) + { + $data->cards .= $bugID . ','; + unset($executionBugs[$bugID]); + } + + if($type == 'fixed' and $bug->status == 'resolved') + { + $data->cards .= $bugID . ','; + unset($executionBugs[$bugID]); + } + + if($type == 'closed' and $bug->status == 'closed') + { + $data->cards .= $bugID . ','; + unset($executionBugs[$bugID]); + } + } + $this->dao->insert(TABLE_KANBANCOLUMN)->data($data)->exec(); + if($type == 'resolving') $resolvingColumn = $this->dao->lastInsertId(); + if($type == 'test') $testColumn = $this->dao->lastInsertId(); + } + } + + $executionTasks = empty($tasks[$executionID]) ? array() : $tasks[$executionID]; + foreach($this->lang->kanban->taskColumn as $type => $name) + { + $data = new stdClass(); + $data->lane = $taskLaneID; + $data->name = $name; + $data->type = $type; + $data->cards = ''; + if(strpos(',developing,developed,', $type) !== false) $data->parent = $developColumn; + if(strpos(',develop,', $type) === false) + { + foreach($executionTasks as $taskID => $task) + { + if($type == 'developing' and $task->status == 'doing') + { + $data->cards .= $taskID . ','; + unset($executionTasks[$taskID]); + } + + if($type == 'developed' and $task->status == 'done') + { + $data->cards .= $taskID . ','; + unset($executionTasks[$taskID]); + } + + if(strpos(',wait,pause,canceled,closed,', $type) !== false and $task->status == $type) + { + $data->cards .= $taskID . ','; + unset($executionTasks[$taskID]); + } + } + $this->dao->insert(TABLE_KANBANCOLUMN)->data($data)->exec(); + if($type == 'develop') $developColumn = $this->dao->lastInsertId(); + } + } + } + } +} diff --git a/module/upgrade/model.php b/module/upgrade/model.php index 48da796885..bb4db3301a 100644 --- a/module/upgrade/model.php +++ b/module/upgrade/model.php @@ -725,6 +725,11 @@ class upgradeModel extends model $this->saveLogs('Execute 15_6'); $this->execSQL($this->getUpgradeFile('15.6')); $this->appendExec('15_6'); + case '15_7': + $this->saveLogs('Execute 15_7'); + $this->execSQL($this->getUpgradeFile('15.7')); + $this->addKanbanLanes(); + $this->appendExec('15_7'); } $this->deletePatch(); @@ -5321,4 +5326,22 @@ class upgradeModel extends model $this->dao->update(TABLE_CONFIG)->set('`value`')->eq(trim($data->value, ','))->where('id')->eq($data->id)->exec(); return true; } + + /** + * Add single execution Kanban lanes. + * + * @access public + * @return bool + */ + public function addKanbanLanes() + { + $executionIdList = $this->dao->select('id')->from(TABLE_EXECUTION)->where('type')->in('sprint,stage')->fetchPairs(); + + if(empty($executionIdList)) return true; + + /* Create lanes. */ + $lanes = $this->loadModel('kanban')->addKanbanLanes($executionIdList); + + return true; + } } From a72b84e25762b8e065b6826dfa54326589364829 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 25 Oct 2021 15:03:27 +0800 Subject: [PATCH 3/6] * Get Kanban data. --- module/execution/control.php | 29 +++++++++++++++++++++++------ module/kanban/model.php | 19 +++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/module/execution/control.php b/module/execution/control.php index f819837e60..dea9973497 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1825,27 +1825,44 @@ class execution extends control * Kanban. * * @param int $executionID - * @param string $objectType - * @param string $groupBy + * @param string $orderBy + * @param string $type * @access public * @return void */ - public function kanban($executionID, $objectType = 'all', $groupBy = 'id_desc') + public function kanban($executionID, $orderBy = 'all', $type = 'id_desc') { /* Save to session. */ $uri = $this->app->getURI(true); $this->app->session->set('taskList', $uri, 'execution'); $this->app->session->set('bugList', $uri, 'qa'); - /* Compatibility IE8*/ + /* Compatibility IE8. */ if(strpos($this->server->http_user_agent, 'MSIE 8.0') !== false) header("X-UA-Compatible: IE=EmulateIE7"); - $lanes = $this->loadModel('kanban')->getLanesByExecution($executionID, $objectType); + $kanbanLanes = $this->loadModel('kanban')->getLanesByExecution($executionID); + $kanbanColumns = $this->kanban->getColumnsByLane(array_keys($kanbanLanes)); + $kanban = array(); + + foreach($kanbanLanes as $laneID => $lane) + { + $kanban[$lane->type] = $lane; + $kanban[$lane->type]->columns = array(); + foreach($kanbanColumns as $columnID => $column) + { + if($column->lane == $laneID) + { + $kanban[$lane->type]->columns[$columnID] = $column; + unset($kanbanColumns[$columnID]); + } + } + } + $this->execution->setMenu($executionID); $execution = $this->loadModel('execution')->getById($executionID); $tasks = $this->execution->getKanbanTasks($executionID, "id"); $bugs = $this->loadModel('bug')->getExecutionBugs($executionID); - $stories = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, $orderBy); + $stories = $this->loadModel('story')->getExecutionStories($executionID); /* Determines whether an object is editable. */ $canBeChanged = common::canModify('execution', $execution); diff --git a/module/kanban/model.php b/module/kanban/model.php index d709f69563..9825ac6c45 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -30,6 +30,25 @@ class kanbanModel extends model ->fetchAll('id'); } + /** + * Get Kanban columns by lane ID. + * + * @param int|array $lanes + * @param string $type + * @access public + * @return void + */ + public function getColumnsByLane($lanes, $type = 'all') + { + if(empty($lanes)) return array(); + return $this->dao->select('t2.id as id, t2.*')->from(TABLE_KANBANLANE)->alias('t1') + ->leftJoin(TABLE_KANBANCOLUMN)->alias('t2')->on('t1.id=t2.lane') + ->where('t2.deleted')->eq(0) + ->andWhere('t2.lane')->in($lanes) + ->beginIF($type !== 'all')->andWhere('t1.type')->eq($type)->fi() + ->fetchAll('id'); + } + /** * Add execution Kanban lanes. * From 546edae92a2049438b7978779a1b0befe3639dd0 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Mon, 25 Oct 2021 16:11:36 +0800 Subject: [PATCH 4/6] * Adjust code of kanban. --- config/zentaopms.php | 14 +++++++------- module/execution/control.php | 10 +++++----- module/kanban/model.php | 9 ++++++--- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/config/zentaopms.php b/config/zentaopms.php index 5acf07c756..8ce5a9a7cb 100644 --- a/config/zentaopms.php +++ b/config/zentaopms.php @@ -223,13 +223,13 @@ define('TABLE_JOB', '`' . $config->db->prefix . 'job`'); define('TABLE_COMPILE', '`' . $config->db->prefix . 'compile`'); define('TABLE_MR', '`' . $config->db->prefix . 'mr`'); -define('TABLE_REPO', '`' . $config->db->prefix . 'repo`'); -define('TABLE_RELATION', '`' . $config->db->prefix . 'relation`'); -define('TABLE_REPOHISTORY', '`' . $config->db->prefix . 'repohistory`'); -define('TABLE_REPOFILES', '`' . $config->db->prefix . 'repofiles`'); -define('TABLE_REPOBRANCH', '`' . $config->db->prefix . 'repobranch`'); -define('TABLE_KANBANLANE', '`' . $config->db->prefix . 'kanbanlane`'); -define('TABLE_KANBANCOLUMN', '`' . $config->db->prefix . 'kanbancolumn`'); +define('TABLE_REPO', '`' . $config->db->prefix . 'repo`'); +define('TABLE_RELATION', '`' . $config->db->prefix . 'relation`'); +define('TABLE_REPOHISTORY', '`' . $config->db->prefix . 'repohistory`'); +define('TABLE_REPOFILES', '`' . $config->db->prefix . 'repofiles`'); +define('TABLE_REPOBRANCH', '`' . $config->db->prefix . 'repobranch`'); +define('TABLE_KANBANLANE', '`' . $config->db->prefix . 'kanbanlane`'); +define('TABLE_KANBANCOLUMN', '`' . $config->db->prefix . 'kanbancolumn`'); if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`'); if(!defined('TABLE_PROJECTSPEC')) define('TABLE_PROJECTSPEC', '`' . $config->db->prefix . 'projectspec`'); diff --git a/module/execution/control.php b/module/execution/control.php index dea9973497..25b9c9c672 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1825,12 +1825,12 @@ class execution extends control * Kanban. * * @param int $executionID - * @param string $orderBy * @param string $type + * @param string $orderBy * @access public * @return void */ - public function kanban($executionID, $orderBy = 'all', $type = 'id_desc') + public function kanban($executionID, $type = 'story', $orderBy = 'order_asc') { /* Save to session. */ $uri = $this->app->getURI(true); @@ -1840,14 +1840,14 @@ class execution extends control /* Compatibility IE8. */ if(strpos($this->server->http_user_agent, 'MSIE 8.0') !== false) header("X-UA-Compatible: IE=EmulateIE7"); - $kanbanLanes = $this->loadModel('kanban')->getLanesByExecution($executionID); - $kanbanColumns = $this->kanban->getColumnsByLane(array_keys($kanbanLanes)); - $kanban = array(); + $kanbanLanes = $this->loadModel('kanban')->getLanesByExecution($executionID); + $kanban = array(); foreach($kanbanLanes as $laneID => $lane) { $kanban[$lane->type] = $lane; $kanban[$lane->type]->columns = array(); + $kanbanColumns = $this->kanban->getColumnsByLane(array_keys($kanbanLanes), $executionID, $lane->type); foreach($kanbanColumns as $columnID => $column) { if($column->lane == $laneID) diff --git a/module/kanban/model.php b/module/kanban/model.php index 9825ac6c45..cb4bc8a645 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -36,16 +36,16 @@ class kanbanModel extends model * @param int|array $lanes * @param string $type * @access public - * @return void + * @return array */ - public function getColumnsByLane($lanes, $type = 'all') + public function getColumnsByLane($lanes, $type) { if(empty($lanes)) return array(); return $this->dao->select('t2.id as id, t2.*')->from(TABLE_KANBANLANE)->alias('t1') ->leftJoin(TABLE_KANBANCOLUMN)->alias('t2')->on('t1.id=t2.lane') ->where('t2.deleted')->eq(0) ->andWhere('t2.lane')->in($lanes) - ->beginIF($type !== 'all')->andWhere('t1.type')->eq($type)->fi() + ->andWhere('t1.type')->eq($type)->fi() ->fetchAll('id'); } @@ -85,17 +85,20 @@ class kanbanModel extends model ->where('t1.deleted')->eq(0) ->andWhere('t1.parent')->ne('-1') ->andWhere('t2.project')->in($executionIdList) + ->orderBy('id_asc') ->fetchGroup('project', 'id'); $bugs = $this->dao->select('*')->from(TABLE_BUG) ->where('deleted')->eq(0) ->andWhere('execution')->in($executionIdList) + ->orderBy('id_asc') ->fetchGroup('execution', 'id'); $tasks = $this->dao->select('*')->from(TABLE_TASK) ->where('deleted')->eq(0) ->andWhere('parent')->ne('-1') ->andWhere('execution')->in($executionIdList) + ->orderBy('id_asc') ->fetchGroup('execution', 'id'); foreach($executionIdList as $executionID) From a71cacdaa8d7601f4de01aba3650040bfab48a27 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Tue, 26 Oct 2021 10:25:33 +0800 Subject: [PATCH 5/6] * Refactoring the Kanban function. --- module/execution/control.php | 19 +- module/execution/model.php | 6 +- module/kanban/config.php | 19 ++ module/kanban/model.php | 333 ++++++++++++++++++----------------- module/upgrade/model.php | 19 -- 5 files changed, 193 insertions(+), 203 deletions(-) create mode 100644 module/kanban/config.php diff --git a/module/execution/control.php b/module/execution/control.php index 25b9c9c672..3ed23adbd2 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1840,23 +1840,8 @@ class execution extends control /* Compatibility IE8. */ if(strpos($this->server->http_user_agent, 'MSIE 8.0') !== false) header("X-UA-Compatible: IE=EmulateIE7"); - $kanbanLanes = $this->loadModel('kanban')->getLanesByExecution($executionID); - - $kanban = array(); - foreach($kanbanLanes as $laneID => $lane) - { - $kanban[$lane->type] = $lane; - $kanban[$lane->type]->columns = array(); - $kanbanColumns = $this->kanban->getColumnsByLane(array_keys($kanbanLanes), $executionID, $lane->type); - foreach($kanbanColumns as $columnID => $column) - { - if($column->lane == $laneID) - { - $kanban[$lane->type]->columns[$columnID] = $column; - unset($kanbanColumns[$columnID]); - } - } - } + $kanban = $this->loadModel('kanban')->getExecutionKanban($executionID); + if(empty($kanban)) $this->kanban->createLane($executionID); $this->execution->setMenu($executionID); $execution = $this->loadModel('execution')->getById($executionID); diff --git a/module/execution/model.php b/module/execution/model.php index fa7539ccf2..971e014c96 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -78,7 +78,7 @@ class executionModel extends model global $lang; $this->app->loadLang('project'); $lang->executionCommon = $lang->project->stage; - include $this->app->getModulePath('execution') . 'lang/' . $this->app->getClientLang() . '.php'; + include $this->app->getModulePath('', 'execution') . 'lang/' . $this->app->getClientLang() . '.php'; } if($execution and $execution->lifetime == 'ops') @@ -379,7 +379,7 @@ class executionModel extends model $creatorExists = false; $teamMembers = array(); - $this->loadModel('kanban')->addKanbanLanes($executionID); + $this->loadModel('kanban')->createLane($executionID); /* Save order. */ $this->dao->update(TABLE_EXECUTION)->set('`order`')->eq($executionID * 5)->where('id')->eq($executionID)->exec(); @@ -3156,7 +3156,7 @@ class executionModel extends model */ public function getKanbanTasks($executionID, $orderBy = 'status_asc, id_desc', $pager = null) { - $tasks = $this->dao->select('t1.*, t1.id as id, t2.id AS storyID, t2.title AS storyTitle, t2.version AS latestStoryVersion, t2.status AS storyStatus, t3.realname AS assignedToRealName') + $tasks = $this->dao->select('t1.*, t2.id AS storyID, t2.title AS storyTitle, t2.version AS latestStoryVersion, t2.status AS storyStatus, t3.realname AS assignedToRealName') ->from(TABLE_TASK)->alias('t1') ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id') ->leftJoin(TABLE_USER)->alias('t3')->on('t1.assignedTo = t3.account') diff --git a/module/kanban/config.php b/module/kanban/config.php new file mode 100644 index 0000000000..7928dd1b39 --- /dev/null +++ b/module/kanban/config.php @@ -0,0 +1,19 @@ +kanban = new stdclass(); + +$config->kanban->default = new stdclass(); +$config->kanban->default->story = new stdclass(); +$config->kanban->default->story->name = $lang->SRCommon; +$config->kanban->default->story->color = '#7ec5ff'; +$config->kanban->default->story->order = '5'; + +$config->kanban->default->bug = new stdclass(); +$config->kanban->default->bug->name = $lang->bug->common; +$config->kanban->default->bug->color = '#ba55d3'; +$config->kanban->default->bug->order = '10'; + +$config->kanban->default->task = new stdclass(); +$config->kanban->default->task->name = $lang->task->common; +$config->kanban->default->task->color = '#4169e1'; +$config->kanban->default->task->order = '15'; diff --git a/module/kanban/model.php b/module/kanban/model.php index cb4bc8a645..67b9b8c00b 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -14,230 +14,235 @@ class kanbanModel extends model { /** - * Get lanes by execution id. + * Get Kanban by execution id. * * @param int $executionID * @param string $objectType all|story|bug|task * @access public * @return array */ - public function getLanesByExecution($executionID, $objectType = 'all') + public function getExecutionKanban($executionID, $objectType = 'all') { - return $this->dao->select('*')->from(TABLE_KANBANLANE) + $lanes = $this->dao->select('*')->from(TABLE_KANBANLANE) ->where('execution')->eq($executionID) ->andWhere('deleted')->eq(0) ->beginIF($objectType != 'all')->andWhere('type')->eq($objectType) ->fetchAll('id'); - } - /** - * Get Kanban columns by lane ID. - * - * @param int|array $lanes - * @param string $type - * @access public - * @return array - */ - public function getColumnsByLane($lanes, $type) - { if(empty($lanes)) return array(); - return $this->dao->select('t2.id as id, t2.*')->from(TABLE_KANBANLANE)->alias('t1') - ->leftJoin(TABLE_KANBANCOLUMN)->alias('t2')->on('t1.id=t2.lane') - ->where('t2.deleted')->eq(0) - ->andWhere('t2.lane')->in($lanes) - ->andWhere('t1.type')->eq($type)->fi() - ->fetchAll('id'); + $columns = $this->dao->select('*')->from(TABLE_KANBANCOLUMN) + ->where('deleted')->eq(0) + ->andWhere('lane')->in(array_keys($lanes)) + ->fetchGroup('lane', 'id'); + + foreach($columns as $laneID => $cols) + { + foreach($cols as $colID => $col) + { + if($col->parent > 0) + { + $cols[$col->parent]->childs[$colID] = $col; + unset($cols[$colID]); + } + } + } + + foreach($lanes as $laneID => $lane) $lane->columns = $columns[$laneID]; + return $lanes; } /** - * Add execution Kanban lanes. + * Add execution Kanban lanes and columns. * - * @param int|array $executionIdList + * @param int $executionID * @access public * @return void */ - public function addKanbanLanes($executionIdList) + public function createLane($executionID) { - if(is_numeric($executionIdList)) $executionIdList = (array)$executionIdList; - if(!is_array($executionIdList) or empty($executionIdList)) return; - - /* Set lane Information. */ - global $lang; - $storyLane = clone $bugLane = clone $taskLane = new stdClass(); - $storyLane->type = 'story'; - $storyLane->name = $lang->SRCommon; - $storyLane->color = '#7ec5ff'; - $storyLane->order = '5'; - - $bugLane->type = 'bug'; - $bugLane->name = $lang->bug->common; - $bugLane->color = '#ba55d3'; - $bugLane->order = '10'; - - $taskLane->type = 'task'; - $taskLane->name = $lang->task->common; - $taskLane->color = '#4169e1'; - $taskLane->order = '15'; - - /* Get stories, bugs and tasks. */ - $stories = $this->dao->select('t1.*,t2.project as project')->from(TABLE_STORY)->alias('t1') - ->leftJoin(TABLE_PROJECTSTORY)->alias('t2')->on('t1.id=t2.story') - ->where('t1.deleted')->eq(0) - ->andWhere('t1.parent')->ne('-1') - ->andWhere('t2.project')->in($executionIdList) - ->orderBy('id_asc') - ->fetchGroup('project', 'id'); - - $bugs = $this->dao->select('*')->from(TABLE_BUG) - ->where('deleted')->eq(0) - ->andWhere('execution')->in($executionIdList) - ->orderBy('id_asc') - ->fetchGroup('execution', 'id'); - - $tasks = $this->dao->select('*')->from(TABLE_TASK) - ->where('deleted')->eq(0) - ->andWhere('parent')->ne('-1') - ->andWhere('execution')->in($executionIdList) - ->orderBy('id_asc') - ->fetchGroup('execution', 'id'); - - foreach($executionIdList as $executionID) + foreach($this->config->kanban->default as $type => $lane) { - $storyLaneID = 0; - $bugLaneID = 0; - $taskLaneID = 0; - $developColumn = 0; - $testColumn = 0; - $resolvingColumn = 0; + $lane->type = $type; + $lane->execution = $executionID; + $this->dao->insert(TABLE_KANBANLANE)->data($lane)->exec(); - $lanes[$executionID] = new stdClass(); - $storyLane->execution = $bugLane->execution = $taskLane->execution = $executionID; + $laneID = $this->dao->lastInsertId(); + $this->createColumn($laneID, $type, $executionID); + } + } - $this->dao->insert(TABLE_KANBANLANE)->data($storyLane)->exec(); - $storyLaneID = $this->dao->lastInsertId(); + public function createColumn($laneID, $type, $executionID) + { + $objects = array(); + if($type == 'story') $objects = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, 't2.id_desc'); + if($type == 'bug') $objects = $this->loadModel('bug')->getExecutionBugs($executionID); + if($type == 'task') $objects = $this->loadModel('execution')->getKanbanTasks($executionID); - $this->dao->insert(TABLE_KANBANLANE)->data($bugLane)->exec(); - $bugLaneID = $this->dao->lastInsertId(); - - $this->dao->insert(TABLE_KANBANLANE)->data($taskLane)->exec(); - $taskLaneID = $this->dao->lastInsertId(); - - $executionStories = empty($stories[$executionID]) ? array() : $stories[$executionID]; - foreach($this->lang->kanban->storyColumn as $type => $name) + $devColumnID = $testColumnID = $resolvingColumnID = 0; + if($type == 'story') + { + foreach($this->lang->kanban->storyColumn as $colType => $name) { $data = new stdClass(); - $data->lane = $storyLaneID; + $data->lane = $laneID; $data->name = $name; - $data->type = $type; + $data->type = $colType; $data->cards = ''; - if(strpos(',developing,developed,', $type) !== false) $data->parent = $developColumn; - if(strpos(',testing,tested,', $type) !== false) $data->parent = $testColumn; - if(strpos(',ready,develop,test,', $type) === false) + if(strpos(',developing,developed,', $colType) !== false) $data->parent = $devColumnID; + if(strpos(',testing,tested,', $colType) !== false) $data->parent = $testColumnID; + if(strpos(',ready,develop,test,', $colType) === false) { - foreach($executionStories as $storyID => $story) + foreach($objects as $storyID => $story) { - if($type == 'backlog' and $story->status == 'active' and $story->stage == 'projected') - { - $data->cards .= $storyID . ','; - unset($executionStories[$storyID]); - } + if($colType == 'backlog' and $story->status == 'active' and $story->stage == 'projected') $data->cards .= $storyID . ','; - if($type == 'closed' and $story->status == 'closed' and $story->stage == 'closed') - { - $data->cards .= $storyID . ','; - unset($executionStories[$storyID]); - } + if($colType == 'closed' and $story->status == 'closed' and $story->stage == 'closed') $data->cards .= $storyID . ','; - if($story->stage == $type and strpos(',backlog,closed,', $type) === false and $story->status == 'active') - { - $data->cards .= $storyID . ','; - unset($executionStories[$storyID]); - } + if($story->stage == $colType and strpos(',backlog,closed,', $colType) === false and $story->status == 'active') $data->cards .= $storyID . ','; } if(!empty($data->cards)) $data->cards = ',' . $data->cards; } - $this->dao->insert(TABLE_KANBANCOLUMN)->data($data)->exec(); - if($type == 'develop') $developColumn = $this->dao->lastInsertId(); - if($type == 'test') $testColumn = $this->dao->lastInsertId(); - } - $executionBugs = empty($bugs[$executionID]) ? array() : $bugs[$executionID]; - foreach($this->lang->kanban->bugColumn as $type => $name) + $this->dao->insert(TABLE_KANBANCOLUMN)->data($data)->exec(); + if($colType == 'develop') $devColumnID = $this->dao->lastInsertId(); + if($colType == 'test') $testColumnID = $this->dao->lastInsertId(); + } + } + elseif($type == 'bug') + { + foreach($this->lang->kanban->bugColumn as $colType => $name) { $data = new stdClass(); - $data->lane = $bugLaneID; + $data->lane = $laneID; $data->name = $name; - $data->type = $type; + $data->type = $colType; $data->cards = ''; - if(strpos(',fixing,fixed,', $type) !== false) $data->parent = $resolvingColumn; - if(strpos(',testing,tested,', $type) !== false) $data->parent = $testColumn; - if(strpos(',resolving,fixing,test,testing,tested,', $type) === false) + if(strpos(',fixing,fixed,', $colType) !== false) $data->parent = $resolvingColumnID; + if(strpos(',testing,tested,', $colType) !== false) $data->parent = $testColumnID; + if(strpos(',resolving,fixing,test,testing,tested,', $colType) === false) { - foreach($executionBugs as $bugID => $bug) + foreach($objects as $bugID => $bug) { - if($type == 'unconfirmed' and $bug->status == 'active' and $bug->confirmed == 0) - { - $data->cards .= $bugID . ','; - unset($executionBugs[$bugID]); - } + if($colType == 'unconfirmed' and $bug->status == 'active' and $bug->confirmed == 0) $data->cards .= $bugID . ','; - if($type == 'confirmed' and $bug->status == 'active' and $bug->confirmed == 1) - { - $data->cards .= $bugID . ','; - unset($executionBugs[$bugID]); - } + if($colType == 'confirmed' and $bug->status == 'active' and $bug->confirmed == 1) $data->cards .= $bugID . ','; - if($type == 'fixed' and $bug->status == 'resolved') - { - $data->cards .= $bugID . ','; - unset($executionBugs[$bugID]); - } + if($colType == 'fixed' and $bug->status == 'resolved') $data->cards .= $bugID . ','; - if($type == 'closed' and $bug->status == 'closed') - { - $data->cards .= $bugID . ','; - unset($executionBugs[$bugID]); - } + if($colType == 'closed' and $bug->status == 'closed') $data->cards .= $bugID . ','; } $this->dao->insert(TABLE_KANBANCOLUMN)->data($data)->exec(); - if($type == 'resolving') $resolvingColumn = $this->dao->lastInsertId(); - if($type == 'test') $testColumn = $this->dao->lastInsertId(); + if($colType == 'resolving') $resolvingColumnID = $this->dao->lastInsertId(); + if($colType == 'test') $testColumnID = $this->dao->lastInsertId(); } } - - $executionTasks = empty($tasks[$executionID]) ? array() : $tasks[$executionID]; - foreach($this->lang->kanban->taskColumn as $type => $name) + } + elseif($type == 'task') + { + foreach($this->lang->kanban->taskColumn as $colType => $name) { $data = new stdClass(); - $data->lane = $taskLaneID; + $data->lane = $laneID; $data->name = $name; - $data->type = $type; + $data->type = $colType; $data->cards = ''; - if(strpos(',developing,developed,', $type) !== false) $data->parent = $developColumn; - if(strpos(',develop,', $type) === false) + if(strpos(',developing,developed,', $colType) !== false) $data->parent = $devColumnID; + if(strpos(',develop,', $colType) === false) { - foreach($executionTasks as $taskID => $task) + foreach($objects as $taskID => $task) { - if($type == 'developing' and $task->status == 'doing') - { - $data->cards .= $taskID . ','; - unset($executionTasks[$taskID]); - } + if($colType == 'developing' and $task->status == 'doing') $data->cards .= $taskID . ','; - if($type == 'developed' and $task->status == 'done') - { - $data->cards .= $taskID . ','; - unset($executionTasks[$taskID]); - } + if($colType == 'developed' and $task->status == 'done') $data->cards .= $taskID . ','; - if(strpos(',wait,pause,canceled,closed,', $type) !== false and $task->status == $type) - { - $data->cards .= $taskID . ','; - unset($executionTasks[$taskID]); - } + if(strpos(',wait,pause,canceled,closed,', $colType) !== false and $task->status == $colType) $data->cards .= $taskID . ','; + } + + $this->dao->insert(TABLE_KANBANCOLUMN)->data($data)->exec(); + if($colType == 'develop') $devColumnID = $this->dao->lastInsertId(); + } + } + } + } + + public function updateCards($executionID, $objectType, $columns) + { + $objects = array(); + if($objectType == 'story') $objects = $this->loadModel('story')->getExecutionStories($executionID); + if($objectType == 'bug') $objects = $this->loadModel('bug')->getExecutionBugs($executionID); + if($objectType == 'task') $objects = $this->loadModel('execution')->getKanbanTasks($executionID); + if($objectType == 'story') + { + $data = new stdClass(); + foreach($columns as $colID => $col) + { + foreach($objects as $storyID => $story) + { + if($col->type == 'backlog' and $story->status == 'active' and $story->stage == 'projected') $data->cards .= $storyID . ','; + + if($colType == 'closed' and $story->status == 'closed' and $story->stage == 'closed') $data->cards .= $storyID . ','; + + if($story->stage == $colType and strpos(',backlog,closed,', $colType) === false and $story->status == 'active') $data->cards .= $storyID . ','; + } + if(!empty($data->cards)) $data->cards = ',' . $data->cards; + } + + $this->dao->insert(TABLE_KANBANCOLUMN)->data($data)->exec(); + if($colType == 'develop') $devColumnID = $this->dao->lastInsertId(); + if($colType == 'test') $testColumnID = $this->dao->lastInsertId(); + } + elseif($type == 'bug') + { + foreach($this->lang->kanban->bugColumn as $colType => $name) + { + $data = new stdClass(); + $data->lane = $laneID; + $data->name = $name; + $data->type = $colType; + $data->cards = ''; + if(strpos(',fixing,fixed,', $colType) !== false) $data->parent = $resolvingColumnID; + if(strpos(',testing,tested,', $colType) !== false) $data->parent = $testColumnID; + if(strpos(',resolving,fixing,test,testing,tested,', $colType) === false) + { + foreach($objects as $bugID => $bug) + { + if($colType == 'unconfirmed' and $bug->status == 'active' and $bug->confirmed == 0) $data->cards .= $bugID . ','; + + if($colType == 'confirmed' and $bug->status == 'active' and $bug->confirmed == 1) $data->cards .= $bugID . ','; + + if($colType == 'fixed' and $bug->status == 'resolved') $data->cards .= $bugID . ','; + + if($colType == 'closed' and $bug->status == 'closed') $data->cards .= $bugID . ','; } $this->dao->insert(TABLE_KANBANCOLUMN)->data($data)->exec(); - if($type == 'develop') $developColumn = $this->dao->lastInsertId(); + if($colType == 'resolving') $resolvingColumnID = $this->dao->lastInsertId(); + if($colType == 'test') $testColumnID = $this->dao->lastInsertId(); + } + } + } + elseif($type == 'task') + { + foreach($this->lang->kanban->taskColumn as $colType => $name) + { + $data = new stdClass(); + $data->lane = $laneID; + $data->name = $name; + $data->type = $colType; + $data->cards = ''; + if(strpos(',developing,developed,', $colType) !== false) $data->parent = $devColumnID; + if(strpos(',develop,', $colType) === false) + { + foreach($objects as $taskID => $task) + { + if($colType == 'developing' and $task->status == 'doing') $data->cards .= $taskID . ','; + + if($colType == 'developed' and $task->status == 'done') $data->cards .= $taskID . ','; + + if(strpos(',wait,pause,canceled,closed,', $colType) !== false and $task->status == $colType) $data->cards .= $taskID . ','; + } + + $this->dao->insert(TABLE_KANBANCOLUMN)->data($data)->exec(); + if($colType == 'develop') $devColumnID = $this->dao->lastInsertId(); } } } diff --git a/module/upgrade/model.php b/module/upgrade/model.php index bb4db3301a..4ebce95de7 100644 --- a/module/upgrade/model.php +++ b/module/upgrade/model.php @@ -728,7 +728,6 @@ class upgradeModel extends model case '15_7': $this->saveLogs('Execute 15_7'); $this->execSQL($this->getUpgradeFile('15.7')); - $this->addKanbanLanes(); $this->appendExec('15_7'); } @@ -5326,22 +5325,4 @@ class upgradeModel extends model $this->dao->update(TABLE_CONFIG)->set('`value`')->eq(trim($data->value, ','))->where('id')->eq($data->id)->exec(); return true; } - - /** - * Add single execution Kanban lanes. - * - * @access public - * @return bool - */ - public function addKanbanLanes() - { - $executionIdList = $this->dao->select('id')->from(TABLE_EXECUTION)->where('type')->in('sprint,stage')->fetchPairs(); - - if(empty($executionIdList)) return true; - - /* Create lanes. */ - $lanes = $this->loadModel('kanban')->addKanbanLanes($executionIdList); - - return true; - } } From 4a2b7dae2459c4ad676ddb7390360802c955fc25 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Tue, 26 Oct 2021 10:49:42 +0800 Subject: [PATCH 6/6] * Add comment of kanban model.php --- module/execution/control.php | 2 +- module/execution/model.php | 2 +- module/kanban/model.php | 24 +++++++++++++++++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/module/execution/control.php b/module/execution/control.php index 3ed23adbd2..11c7079776 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1841,7 +1841,7 @@ class execution extends control if(strpos($this->server->http_user_agent, 'MSIE 8.0') !== false) header("X-UA-Compatible: IE=EmulateIE7"); $kanban = $this->loadModel('kanban')->getExecutionKanban($executionID); - if(empty($kanban)) $this->kanban->createLane($executionID); + if(empty($kanban)) $this->kanban->createLanes($executionID); $this->execution->setMenu($executionID); $execution = $this->loadModel('execution')->getById($executionID); diff --git a/module/execution/model.php b/module/execution/model.php index 971e014c96..f3f77330f0 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -379,7 +379,7 @@ class executionModel extends model $creatorExists = false; $teamMembers = array(); - $this->loadModel('kanban')->createLane($executionID); + $this->loadModel('kanban')->createLanes($executionID); /* Save order. */ $this->dao->update(TABLE_EXECUTION)->set('`order`')->eq($executionID * 5)->where('id')->eq($executionID)->exec(); diff --git a/module/kanban/model.php b/module/kanban/model.php index 67b9b8c00b..5b021797fa 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -58,7 +58,7 @@ class kanbanModel extends model * @access public * @return void */ - public function createLane($executionID) + public function createLanes($executionID) { foreach($this->config->kanban->default as $type => $lane) { @@ -67,11 +67,20 @@ class kanbanModel extends model $this->dao->insert(TABLE_KANBANLANE)->data($lane)->exec(); $laneID = $this->dao->lastInsertId(); - $this->createColumn($laneID, $type, $executionID); + $this->createColumns($laneID, $type, $executionID); } } - public function createColumn($laneID, $type, $executionID) + /** + * createColumn + * + * @param int $laneID + * @param string $type story|bug|task + * @param int $executionID + * @access public + * @return void + */ + public function createColumns($laneID, $type, $executionID) { $objects = array(); if($type == 'story') $objects = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, 't2.id_desc'); @@ -165,6 +174,15 @@ class kanbanModel extends model } } + /** + * Update column cards. + * + * @param int $executionID + * @param string $objectType story|bug|task + * @param object $columns + * @access public + * @return void + */ public function updateCards($executionID, $objectType, $columns) { $objects = array();