2023-05-16 10:47:08 +08:00

506 lines
19 KiB
PHP
Executable File

<?php
/**
* The model file of design module of ZenTaoPMS.
*
* @copyright Copyright 2009-2020 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Shujie Tian <tianshujie@easycorp.ltd>
* @package design
* @version $Id: model.php 5107 2020-09-02 09:46:12Z tianshujie@easycorp.ltd $
* @link http://www.zentao.net
*/
?>
<?php
class designModel extends model
{
/**
* Create a design.
*
* @param int $projectID
* @access public
* @return void
*/
public function create($projectID)
{
$design = fixer::input('post')
->stripTags('desc', $this->config->allowedTags)
->add('createdBy', $this->app->user->account)
->add('createdDate', helper::now())
->add('project', $projectID)
->add('version', 1)
->remove('files,labels')
->get();
$design = $this->loadModel('file')->processImgURL($design, 'desc', $this->post->uid);
$this->dao->insert(TABLE_DESIGN)->data($design)
->autoCheck()
->batchCheck($this->config->design->create->requiredFields, 'notempty')
->exec();
if(!dao::isError())
{
$designID = $this->dao->lastInsertID();
$this->file->updateObjectID($this->post->uid, $designID, 'design');
$files = $this->file->saveUpload('design', $designID);
$spec = new stdclass();
$spec->design = $designID;
$spec->version = 1;
$spec->name = $design->name;
$spec->desc = $design->desc;
$spec->files = empty($files) ? '' : implode(',', array_keys($files));
$this->dao->insert(TABLE_DESIGNSPEC)->data($spec)->exec();
return $designID;
}
return false;
}
/**
* Batch create designs.
*
* @param int $projectID
* @param int $productID
* @access public
* @return bool
*/
public function batchCreate($projectID = 0, $productID = 0)
{
$data = fixer::input('post')->get();
$this->loadModel('action');
foreach($data->name as $i => $name)
{
if(!trim($name)) continue;
$design = new stdclass();
$design->story = isset($data->story[$i]) ? $data->story[$i] : '';
$design->type = $data->type[$i];
$design->name = $name;
$design->product = $productID;
$design->project = $projectID;
$design->desc = nl2br($data->desc[$i]);
$design->createdBy = $this->app->user->account;
$design->createdDate = helper::now();
$this->dao->insert(TABLE_DESIGN)->data($design)->autoCheck()->batchCheck($this->config->design->create->requiredFields, 'notempty')->exec();
$designID = $this->dao->lastInsertID();
$this->action->create('design', $designID, 'Opened');
}
return true;
}
/**
* Update a design.
*
* @param int $designID
* @access public
* @return bool
*/
public function update($designID = 0)
{
$oldDesign = $this->getByID($designID);
$design = fixer::input('post')
->add('editedBy', $this->app->user->account)
->add('editedDate', helper::now())
->stripTags($this->config->design->editor->edit['id'], $this->config->allowedTags)
->remove('file,files,labels,children,toList')
->get();
$design = $this->loadModel('file')->processImgURL($design, 'desc', $this->post->uid);
$this->dao->update(TABLE_DESIGN)->data($design)->autoCheck()->batchCheck('name,type', 'notempty')->where('id')->eq($designID)->exec();
if(!dao::isError())
{
$this->file->updateObjectID($this->post->uid, $designID, 'design');
$files = $this->file->saveUpload('design', $designID);
$designChanged = ($oldDesign->name != $design->name || $oldDesign->desc != $design->desc || !empty($files));
if($designChanged)
{
$design = $this->getByID($designID);
$version = $design->version + 1;
$spec = new stdclass();
$spec->design = $designID;
$spec->version = $version;
$spec->name = $design->name;
$spec->desc = $design->desc;
$spec->files = empty($files) ? '' : implode(',', array_keys($files));
$this->dao->insert(TABLE_DESIGNSPEC)->data($spec)->exec();
$this->dao->update(TABLE_DESIGN)->set('version')->eq($version)->where('id')->eq($designID)->exec();
}
return common::createChanges($oldDesign, $design);
}
return false;
}
/**
* Assign a design.
*
* @param int $designID
* @access public
* @return array|bool
*/
public function assign($designID = 0)
{
$oldDesign = $this->getByID($designID);
$design = fixer::input('post')
->add('editedBy', $this->app->user->account)
->add('editedDate', helper::today())
->setDefault('assignedDate', helper::today())
->stripTags($this->config->design->editor->assignto['id'], $this->config->allowedTags)
->remove('uid,comment,files,label')
->get();
$this->dao->update(TABLE_DESIGN)->data($design)->autoCheck()->where('id')->eq((int)$designID)->exec();
if(!dao::isError()) return common::createChanges($oldDesign, $design);
return false;
}
/**
* LinkCommit a design.
*
* @param int $designID
* @param int $repoID
* @access public
* @return void
*/
public function linkCommit($designID = 0, $repoID = 0)
{
$revisions = $_POST['revision'];
foreach($revisions as $revision)
{
$data = new stdclass();
$data->project = $this->session->project;
$data->product = $this->session->product;
$data->AType = 'design';
$data->AID = $designID;
$data->BType = 'commit';
$data->BID = $revision;
$data->relation = 'completedin';
$data->extra = $repoID;
$this->dao->replace(TABLE_RELATION)->data($data)->autoCheck()->exec();
$data->AType = 'commit';
$data->AID = $revision;
$data->BType = 'design';
$data->BID = $designID;
$data->relation = 'completedfrom';
$this->dao->replace(TABLE_RELATION)->data($data)->autoCheck()->exec();
}
$oldCommit = $this->dao->findByID($designID)->from(TABLE_DESIGN)->fetch('commit');
$revisions = join(',', $revisions);
$commit = $oldCommit ? $oldCommit . ',' . $revisions : $revisions;
$design = new stdclass();
$design->commit = $commit;
$design->commitedBy = $this->app->user->account;
$this->dao->update(TABLE_DESIGN)->data($design)->autoCheck()->where('id')->eq($designID)->exec();
}
/**
* Unlink commit.
*
* @param int $designID
* @param int $commitID
* @access public
* @return void
*/
public function unlinkCommit($designID = 0, $commitID = 0)
{
/* Delete data in the zt_relation.*/
$this->dao->delete()->from(TABLE_RELATION)->where('AType')->eq('design')->andwhere('AID')->eq($designID)->andwhere('BType')->eq('commit')->andwhere('relation')->eq('completedin')->andWhere('BID')->eq($commitID)->exec();
$this->dao->delete()->from(TABLE_RELATION)->where('AType')->eq('commit')->andwhere('BID')->eq($designID)->andwhere('BType')->eq('design')->andwhere('relation')->eq('completedfrom')->andWhere('AID')->eq($commitID)->exec();
/* Commit after unlinking. */
$commit = $this->dao->select('BID')->from(TABLE_RELATION)->where('AType')->eq('design')->andWhere('AID')->eq($designID)->andWhere('BType')->eq('commit')->andwhere('relation')->eq('completedin')->fetchAll('BID');
$commit = implode(",", array_keys($commit));
$this->dao->update(TABLE_DESIGN)->set('commit')->eq($commit)->where('id')->eq($designID)->exec();
}
/**
* Get a design by id.
*
* @param int $designID
* @access public
* @return object
*/
public function getByID($designID = 0)
{
$this->app->loadLang('product');
$design = $this->dao->select('*')->from(TABLE_DESIGN)->where('id')->eq($designID)->fetch();
if(!$design) return false;
$design->files = $this->loadModel('file')->getByObject('design', $designID);
$design->productName = $design->product ? $this->dao->findByID($design->product)->from(TABLE_PRODUCT)->fetch('name') : $this->lang->product->all;
$design->commit = '';
$relations = $this->loadModel('common')->getRelations('design', $designID, 'commit');
foreach($relations as $relation) $design->commit .= html::a(helper::createLink('design', 'revision', "repoID=$relation->BID&projectID={$design->project}"), "#$relation->BID");
return $this->loadModel('file')->replaceImgURL($design, 'desc');
}
/**
* Get design pairs.
*
* @param int $productID
* @param string $type all|HLDS|DDS|DBDS|ADS
* @access public
* @return object
*/
public function getPairs($productID = 0, $type = 'all')
{
$designs = $this->dao->select('id, name')->from(TABLE_DESIGN)
->where('product')->eq($productID)
->andWhere('deleted')->eq(0)
->andWhere('type')->eq($type)
->fetchPairs();
foreach($designs as $id => $name) $designs[$id] = $id . ':' . $name;
return $designs;
}
/**
* Get affected scope.
*
* @param int $design
* @access public
* @return object
*/
public function getAffectedScope($design = 0)
{
/* Get affected tasks. */
$design->tasks = $this->dao->select('*')->from(TABLE_TASK)
->where('deleted')->eq(0)
->andWhere('status')->ne('closed')
->andWhere('design')->eq($design->id)
->orderBy('id desc')->fetchAll();
return $design;
}
/**
* Get design list.
*
* @param int $productID
* @param int $projectID
* @param string $type all|bySearch|HLDS|DDS|DBDS|ADS
* @param int $param
* @param string $orderBy
* @param int $pager
* @access public
* @return array
*/
public function getList($projectID = 0, $productID = 0, $type = 'all', $param = 0, $orderBy = 'id_desc', $pager = null)
{
if($type == 'bySearch')
{
$designs = $this->getBySearch($projectID, $productID, $param, $orderBy, $pager);
}
else
{
$designs = $this->dao->select('*')->from(TABLE_DESIGN)
->where('deleted')->eq(0)
->beginIF($projectID)->andWhere('project')->eq($projectID)->fi()
->beginIF($type != 'all')->andWhere('type')->in($type)->fi()
->beginIF($productID)->andWhere('product')->eq($productID)->fi()
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
}
return $designs;
}
/**
* Get commit.
*
* @param int $designID
* @param int $pager
* @access public
* @return object
*/
public function getCommit($designID = 0, $pager = null)
{
$design = $this->dao->select('*')->from(TABLE_DESIGN)->where('id')->eq($designID)->fetch();
$design->commit = $this->dao->select('*')->from(TABLE_REPOHISTORY)->where('id')->in($design->commit)->page($pager)->fetchAll('id');
return $design;
}
/**
* Get designs by search.
*
* @param int $projectID
* @param int $productID
* @param int $queryID
* @param string $orderBy
* @param int $pager
* @access public
* @return object
*/
public function getBySearch($projectID = 0, $productID = 0, $queryID = 0, $orderBy = 'id_desc', $pager = null)
{
if($queryID)
{
$query = $this->loadModel('search')->getQuery($queryID);
if($query)
{
$this->session->set('designQuery', $query->sql);
$this->session->set('designForm', $query->form);
}
else
{
$this->session->set('designQuery', ' 1 = 1');
}
}
else
{
if($this->session->designQuery == false) $this->session->set('designQuery', ' 1 = 1');
}
$designQuery = $this->session->designQuery;
$designs = $this->dao->select('*')->from(TABLE_DESIGN)
->where($designQuery)
->andWhere('deleted')->eq('0')
->andWhere('project')->eq($projectID)
->beginIF($productID)->andWhere('product')->eq($productID)->fi()
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
return $designs;
}
/**
* Set design menu.
*
* @param int $projectID
* @param int $products
* @param int $productID
* @param string $currentModule
* @param string $currentMethod
* @param string $extra
* @param int $branch
* @access public
* @return void
*/
public function setMenu($projectID, $products, $productID = 0)
{
$project = $this->loadModel('project')->getByID($projectID);
if(!empty($project) and $project->model == 'waterfall') $typeList = 'typeList';
if(!empty($project) and $project->model == 'waterfallplus') $typeList = 'plusTypeList';
/* Show custom design types. */
$this->lang->waterfall->menu->design['subMenu'] = new stdclass();
$this->lang->waterfall->menu->design['subMenu']->all = array('link' => "{$this->lang->all}|design|browse|projectID=%s&productID=0&browseType=all");
$count = 1;
foreach(array_filter($this->lang->design->{$typeList}) as $key => $value)
{
$key = strtolower($key);
if($count <= 4) $this->lang->waterfall->menu->design['subMenu']->$key = array('link' => "{$value}|design|browse|projectID=%s&productID=0&browseType={$key}");
if($count == 5)
{
$this->lang->waterfall->menu->design['subMenu']->more = array('link' => "{$this->lang->design->more}|design|browse|projectID=%s&productID=0&browseType={$key}", 'class' => 'dropdown dropdown-hover');
$this->lang->waterfall->menu->design['subMenu']->more['dropMenu'] = new stdclass();
}
if($count >= 5) $this->lang->waterfall->menu->design['subMenu']->more['dropMenu']->$key = array('link' => "{$value}|design|browse|projectID=%s&productID=0&browseType={$key}");
$count ++;
}
if($this->app->rawMethod == 'browse') $this->lang->waterfall->menu->design['subMenu']->bysearch = array('link' => '<a href="javascript:;" class="querybox-toggle"><i class="icon-search icon"></i> ' . $this->lang->searchAB . '</a>');
if(empty($products) || !$productID) return '';
if($productID)
{
$currentProduct = $this->loadModel('product')->getById($productID);
setCookie("lastProduct", $productID, $this->config->cookieLife, $this->config->webRoot, '', false, true);
}
else
{
$currentProduct = new stdclass();
$currentProduct->name = $this->lang->product->all;
}
$currentProduct = $this->loadModel('product')->getById($productID);
if(!empty($currentProduct->shadow)) return '';
$output = '';
if(!empty($products))
{
$dropMenuLink = helper::createLink('design', 'ajaxGetDropMenu', "projectID=$projectID&productID=$productID");
$output = "<div class='btn-group angle-btn'><div class='btn-group'><button data-toggle='dropdown' type='button' class='btn btn-limit' id='currentItem' title='{$currentProduct->name}'><span class='text'>{$currentProduct->name}</span> <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
$output .= "</div></div></div>";
}
return $output;
}
/**
* Build search form.
*
* @param int $queryID
* @param string $actionURL
* @access public
* @return void
*/
public function buildSearchForm($queryID = 0, $actionURL = '')
{
$this->config->design->search['actionURL'] = $actionURL;
$this->config->design->search['queryID'] = $queryID;
$this->loadModel('search')->setSearchParams($this->config->design->search);
}
/**
* Print assignedTo html.
*
* @param object $design
* @param array $users
* @access public
* @return string
*/
public function printAssignedHtml($design = '', $users = '')
{
$btnTextClass = '';
$btnClass = '';
$assignedToText = zget($users, $design->assignedTo);
if(empty($design->assignedTo))
{
$btnClass = $btnTextClass = 'assigned-none';
$assignedToText = $this->lang->design->noAssigned;
}
if($design->assignedTo == $this->app->user->account) $btnClass = $btnTextClass = 'assigned-current';
if(!empty($design->assignedTo) and $design->assignedTo != $this->app->user->account) $btnClass = $btnTextClass = 'assigned-other';
$btnClass .= $design->assignedTo == 'closed' ? ' disabled' : '';
$btnClass .= ' iframe btn btn-icon-left btn-sm';
$assignToLink = helper::createLink('design', 'assignTo', "designID=$design->id", '', true);
$assignToHtml = html::a($assignToLink, "<i class='icon icon-hand-right'></i> <span title='" . zget($users, $design->assignedTo) . "'>{$assignedToText}</span>", '', "class='$btnClass'");
echo !common::hasPriv('design', 'assignTo', $design) ? "<span style='padding-left: 21px' class='{$btnTextClass}'>{$assignedToText}</span>" : $assignToHtml;
}
}