316 lines
13 KiB
PHP
316 lines
13 KiB
PHP
<?php
|
|
/**
|
|
* The model file of kanban module of ZenTaoPMS.
|
|
*
|
|
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
|
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
|
* @author Shujie Tian <tianshujie@easycorp.ltd>
|
|
* @package kanban
|
|
* @version $Id: model.php 5118 2021-10-22 10:18:41Z $
|
|
* @link https://www.zentao.net
|
|
*/
|
|
?>
|
|
<?php
|
|
class kanbanModel extends model
|
|
{
|
|
/**
|
|
* Get Kanban by execution id.
|
|
*
|
|
* @param int $executionID
|
|
* @param string $objectType all|story|bug|task
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function getExecutionKanban($executionID, $objectType = 'all')
|
|
{
|
|
$lanes = $this->dao->select('*')->from(TABLE_KANBANLANE)
|
|
->where('execution')->eq($executionID)
|
|
->andWhere('deleted')->eq(0)
|
|
->beginIF($objectType != 'all')->andWhere('type')->eq($objectType)
|
|
->fetchAll('id');
|
|
|
|
if(empty($lanes)) return array();
|
|
$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 and columns.
|
|
*
|
|
* @param int $executionID
|
|
* @access public
|
|
* @return void
|
|
*/
|
|
public function createLanes($executionID)
|
|
{
|
|
foreach($this->config->kanban->default as $type => $lane)
|
|
{
|
|
$lane->type = $type;
|
|
$lane->execution = $executionID;
|
|
$this->dao->insert(TABLE_KANBANLANE)->data($lane)->exec();
|
|
|
|
$laneID = $this->dao->lastInsertId();
|
|
$this->createColumns($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');
|
|
if($type == 'bug') $objects = $this->loadModel('bug')->getExecutionBugs($executionID);
|
|
if($type == 'task') $objects = $this->loadModel('execution')->getKanbanTasks($executionID);
|
|
|
|
$devColumnID = $testColumnID = $resolvingColumnID = 0;
|
|
if($type == 'story')
|
|
{
|
|
foreach($this->lang->kanban->storyColumn 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(',testing,tested,', $colType) !== false) $data->parent = $testColumnID;
|
|
if(strpos(',ready,develop,test,', $colType) === false)
|
|
{
|
|
foreach($objects as $storyID => $story)
|
|
{
|
|
if($colType == '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($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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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();
|
|
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($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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get column by id.
|
|
*
|
|
* @param int $columnID
|
|
* @access public
|
|
* @return object
|
|
*/
|
|
public function getColumnById($columnID)
|
|
{
|
|
$column = $this->dao->select('t1.*, t2.type as laneType')->from(TABLE_KANBANCOLUMN)->alias('t1')
|
|
->leftjoin(TABLE_KANBANLANE)->alias('t2')->on('t1.lane=t2.id')
|
|
->where('t1.id')->eq($columnID)
|
|
->andWhere('t1.deleted')->eq(0)
|
|
->fetch();
|
|
|
|
if(!empty($column->parent)) $column->parentName = $this->dao->findById($column->parent)->from(TABLE_KANBANCOLUMN)->fetch('name');
|
|
|
|
return $column;
|
|
}
|
|
|
|
/**
|
|
* Set WIP limit.
|
|
*
|
|
* @param int $columnID
|
|
* @access public
|
|
* @return bool
|
|
*/
|
|
public function setWIP($columnID)
|
|
{
|
|
$column = $this->getColumnById($columnID);
|
|
$data = fixer::input('post')
|
|
->remove('WIPCount,noLimit')
|
|
->get();
|
|
|
|
$this->lang->kanbancolumn = new stdclass();
|
|
$this->lang->kanbancolumn->limit = $this->lang->kanban->WIPCount;
|
|
|
|
$this->dao->update(TABLE_KANBANCOLUMN)->data($data)
|
|
->autoCheck()
|
|
->check(is_numeric($data->limit), 'limit', 'gt', 0)
|
|
->batchcheck($this->config->kanban->setwip->requiredFields, 'notempty')
|
|
->where('id')->eq($columnID)
|
|
->exec();
|
|
|
|
return dao::isError();
|
|
}
|
|
}
|