diff --git a/Makefile b/Makefile index 9e8da19a96..e747c93624 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,7 @@ clean: rm -fr zentaoxx rm -fr tmp/ rm -f *.sh + rm -f *.deb *.rpm common: mkdir zentaopms cp -fr api zentaopms/ @@ -176,7 +177,7 @@ deb: cp ZenTaoPMS.${VERSION}.zip buildroot/opt cd buildroot/opt; unzip ZenTaoPMS.${VERSION}.zip; mv zentaopms zentao; rm ZenTaoPMS.${VERSION}.zip sed -i 's/index.php/\/zentao\/index.php/' buildroot/opt/zentao/www/.htaccess - sudo dpkg -b buildroot/ ZenTaoPMS_${VERSION}_1_all.deb + sudo dpkg -b buildroot/ ZenTaoPMS.${VERSION}.1.all.deb rm -rf buildroot rpm: mkdir ~/rpmbuild/SPECS -p @@ -252,6 +253,9 @@ ciCommon: rm -fr zentaopms zentaoxx zentaoxx.*.zip make en rm -fr zentaopms zentaoxx zentaoxx.*.zip + rm -f $(BUILD_PATH)/ZenTao*.zip $(RELEASE_PATH)/ZenTaoPMS.$(VERSION).zip $(RELEASE_PATH)/ZenTaoALM.$(VERSION).int.zip + cp ZenTaoPMS.$(VERSION).zip $(BUILD_PATH) + cp ZenTaoPMS.$(VERSION).zip ZenTaoALM.$(VERSION).int.zip $(RELEASE_PATH) ci: make ciCommon php tools/packZip.php $(VERSION) @@ -263,12 +267,7 @@ ci: php tools/packRpm.php $(VERSION) sh rpm.sh rm -rf tmp/ - rm -f zentaobiz*.zip zentaomax*.zip $(BUILD_PATH)/ZenTaoPMS.$(VERSION).zip $(RELEASE_PATH)/ZenTaoALM.$(VERSION)*.zip $(RELEASE_PATH)/ZenTaoPMS.$(VERSION)*.zip $(RELEASE_PATH)/*.deb $(RELEASE_PATH)/*.rpm *.sh - cp ZenTaoPMS.$(VERSION).zip $(BUILD_PATH) - mv *.zip *.deb *.rpm $(RELEASE_PATH) -lite: - make ciCommon - php tools/packZip.php $(VERSION) $(LITEVERSION) - rm -f zentaobiz*.zip zentaomax*.zip $(BUILD_PATH)/ZenTaoPMS.$(VERSION).zip $(RELEASE_PATH)/ZenTaoALM.$(VERSION)*.zip $(RELEASE_PATH)/ZenTaoPMS.$(VERSION)*.zip $(RELEASE_PATH)/ZenTaoALM.$(LITEVERSION)*.zip $(RELEASE_PATH)/ZenTaoPMS.$(LITEVERSION)*.zip *.sh - cp ZenTaoPMS.$(VERSION).zip $(BUILD_PATH) - mv *.zip $(RELEASE_PATH) + rm -f zentaobiz*.zip zentaomax*.zip $(RELEASE_PATH)/ZenTaoALM.$(VERSION)*.zip $(RELEASE_PATH)/ZenTaoPMS.$(VERSION)*.zip $(RELEASE_PATH)/*.deb $(RELEASE_PATH)/*.rpm *.sh $(RELEASE_PATH)/pmsPack/*.zip $(RELEASE_PATH)/pmsPack/deb/* $(RELEASE_PATH)/pmsPack/rpm/* + mv ZenTaoALM.$(VERSION).int.php*.zip ZenTaoPMS.$(VERSION).php*.zip $(RELEASE_PATH)/pmsPack + mv *.deb $(RELEASE_PATH)/pmsPack/deb + mv *.rpm $(RELEASE_PATH)/pmsPack/rpm diff --git a/db/update17.0.sql b/db/update17.0.sql new file mode 100644 index 0000000000..cb87404930 --- /dev/null +++ b/db/update17.0.sql @@ -0,0 +1,5 @@ +ALTER TABLE `zt_review` ADD docVersion smallint(6) NOT NULL AFTER `doc`; + +DELETE FROM `zt_workflowaction` WHERE `module`='story' AND `action`='browse'; +DELETE FROM `zt_workflowaction` WHERE `module`='task' AND `action`='browse'; +DELETE FROM `zt_workflowaction` WHERE `module`='build' AND `action`='browse'; \ No newline at end of file diff --git a/db/zentao.sql b/db/zentao.sql index 2c8f08a0f3..c73404403f 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -9420,6 +9420,7 @@ CREATE TABLE IF NOT EXISTS `zt_review` ( `object` mediumint(8) NOT NULL, `template` mediumint(8) NOT NULL, `doc` mediumint(8) DEFAULT NULL, + `docVersion` smallint(6) DEFAULT NULL, `status` char(30) NOT NULL, `reviewedBy` varchar(255) NOT NULL, `auditedBy` varchar(255) NOT NULL, diff --git a/extension/lite/kanban/ext/model/lite.php b/extension/lite/kanban/ext/model/lite.php index 9ce3a29904..3406eb1c33 100644 --- a/extension/lite/kanban/ext/model/lite.php +++ b/extension/lite/kanban/ext/model/lite.php @@ -5,7 +5,7 @@ public function __construct($appName = '') if($this->app->getModuleName() == 'kanban') $this->lang->kanban->menu = new stdclass(); } -public function getKanban4Group($executionID, $browseType, $groupBy) +public function getKanban4Group($executionID, $browseType, $groupBy, $searchValue = '') { /* Get card data. */ $cardList = array(); @@ -135,7 +135,7 @@ public function getKanban4Group($executionID, $browseType, $groupBy) * @access public * @return array */ -public function getCardGroupByExecution($executionID, $browseType = 'all', $orderBy = 'id_asc') +public function getCardGroupByExecution($executionID, $browseType = 'all', $orderBy = 'id_asc', $searchValue = '') { $cards = $this->dao->select('t1.*, t2.type as columnType') ->from(TABLE_KANBANCELL)->alias('t1') diff --git a/framework/helper.class.php b/framework/helper.class.php index ddc4aecb30..c944daa477 100644 --- a/framework/helper.class.php +++ b/framework/helper.class.php @@ -285,7 +285,7 @@ function formatTime($time, $format = '') { $time = str_replace('0000-00-00', '', $time); $time = str_replace('00:00:00', '', $time); - if(trim($time) == '') return ; + if(trim($time) == '') return ''; if($format) return date($format, strtotime($time)); return trim($time); } diff --git a/framework/model.class.php b/framework/model.class.php index aa59671506..caf535c15a 100644 --- a/framework/model.class.php +++ b/framework/model.class.php @@ -103,10 +103,10 @@ class model extends baseModel if($action->extensionType == 'override') return $this->loadModel('flow')->buildActionMenu($moduleName, $action, $data, $type); $conditions = json_decode($action->conditions); - if($action->extensionType == 'extend' && $conditions) + if($action->extensionType == 'extend') { - $enabled = $this->loadModel('flow')->checkConditions($conditions, $data); - $label = $action->name; + $title = $action->name; + if($conditions) $enabled = $this->loadModel('flow')->checkConditions($conditions, $data); } else { diff --git a/lib/front/front.class.php b/lib/front/front.class.php index d9078b82f8..6913efb848 100644 --- a/lib/front/front.class.php +++ b/lib/front/front.class.php @@ -91,7 +91,7 @@ class html extends baseHTML $string .= "'; } return $string; @@ -391,6 +391,19 @@ class html extends baseHTML */ class js extends baseJS { + /** + * Open a new app window. + * + * @param string $app + * @param string $url + * @static + * @access public + * @return string + */ + static public function openEntry($app, $url) + { + return self::start() . "$.apps.open('$url', '$app')" . self::end(); + } } /** diff --git a/module/action/config.php b/module/action/config.php index 00ed8dfa4d..0e2a4fb2c5 100755 --- a/module/action/config.php +++ b/module/action/config.php @@ -67,3 +67,16 @@ $config->action->preferredTypeNum = 10; $config->action->preferredType = new stdclass(); $config->action->preferredType->new = array('user', 'story', 'task', 'bug', 'case', 'doc', 'program', 'product', 'project', 'execution'); $config->action->preferredType->classic = array('user', 'story', 'task', 'bug', 'case', 'doc', 'product', 'execution', 'productplan', 'build'); + +global $lang; +$config->trash = new stdclass(); +$config->trash->search['module'] = 'trash'; +$config->trash->search['fields']['objectName'] = $lang->action->objectName; +$config->trash->search['fields']['objectID'] = $lang->action->objectID; +$config->trash->search['fields']['actor'] = $lang->action->actor; +$config->trash->search['fields']['date'] = $lang->action->date; + +$config->trash->search['params']['objectName'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); +$config->trash->search['params']['objectID'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); +$config->trash->search['params']['actor'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); +$config->trash->search['params']['date'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); diff --git a/module/action/control.php b/module/action/control.php index 4457c1d211..808436a47d 100755 --- a/module/action/control.php +++ b/module/action/control.php @@ -40,6 +40,8 @@ class action extends control * * @param string $browseType * @param string $type all|hidden + * @param bool $byQuery + * @param int $queryID * @param string $orderBy * @param int $recTotal * @param int $recPerPage @@ -47,7 +49,7 @@ class action extends control * @access public * @return void */ - public function trash($browseType = 'all', $type = 'all', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + public function trash($browseType = 'all', $type = 'all', $byQuery = false, $queryID = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) { $this->loadModel('backup'); @@ -81,13 +83,18 @@ class action extends control $this->session->set('practiceLibList', $uri, 'assetlib'); $this->session->set('componentLibList', $uri, 'assetlib'); + /* Build the search form. */ + $queryID = (int)$queryID; + $actionURL = $this->createLink('action', 'trash', "browseType=$browseType&type=$type&byQuery=true&queryID=myQueryID"); + $this->action->buildTrashSearchForm($queryID, $actionURL); + /* Get deleted objects. */ $this->app->loadClass('pager', $static = true); $pager = pager::init($recTotal, $recPerPage, $pageID); /* Append id for secend sort. */ $sort = common::appendOrder($orderBy); - $trashes = $this->action->getTrashes($browseType, $type, $sort, $pager); + $trashes = $byQuery ? $this->action->getTrashesBySearch($browseType, $type, $queryID, $sort, $pager) : $this->action->getTrashes($browseType, $type, $sort, $pager); $objectTypeList = $this->action->getTrashObjectTypes($type); $objectTypeList = array_keys($objectTypeList); @@ -96,6 +103,7 @@ class action extends control $preferredTypeConfig = $this->config->systemMode == 'new' ? $this->config->action->preferredType->new : $this->config->action->preferredType->classic; foreach($objectTypeList as $objectType) { + if(!isset($this->config->objectTables[$objectType])) continue; in_array($objectType, $preferredTypeConfig) ? $preferredType[$objectType] = $objectType : $moreType[$objectType] = $objectType; } if(count($preferredType) < $this->config->action->preferredTypeNum) @@ -117,6 +125,9 @@ class action extends control $this->view->preferredType = $preferredType; $this->view->moreType = $moreType; $this->view->preferredTypeConfig = $preferredTypeConfig; + $this->view->byQuery = $byQuery; + $this->view->queryID = $queryID; + $this->display(); } diff --git a/module/action/css/trash.css b/module/action/css/trash.css index 2f9190111c..e5b7a61042 100755 --- a/module/action/css/trash.css +++ b/module/action/css/trash.css @@ -1,7 +1,8 @@ .table-footer .table-actions {width: auto; visibility: visible; opacity: 1;} .table-footer .table-actions .text {line-height: 28px;} -table tbody tr td {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} +#mainContent table tbody tr td {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} #mainMenu .btn-toolbar .btn-group .dropdown-menu .btn-active-text:hover .text {color: #fff} .dropdown-menu .btn-active-text:hover .text:after {border-bottom: 0px;} +#querybox #searchform{border-bottom: 1px solid #ddd; margin-bottom: 20px;} diff --git a/module/action/lang/en.php b/module/action/lang/en.php index ed491d4f85..e628f53cdf 100755 --- a/module/action/lang/en.php +++ b/module/action/lang/en.php @@ -42,6 +42,7 @@ $lang->action->hideAll = 'Hide All'; $lang->action->editComment = 'Edit Comment'; $lang->action->create = 'Add Comment'; $lang->action->comment = 'Comment'; +$lang->action->byQuery = 'Search'; $lang->action->undeleteAction = 'Reset Data'; $lang->action->hideOneAction = 'Hide Data'; diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php index 642141b8c3..ed6607abdd 100755 --- a/module/action/lang/zh-cn.php +++ b/module/action/lang/zh-cn.php @@ -42,6 +42,7 @@ $lang->action->hideAll = '全部隐藏'; $lang->action->editComment = '修改备注'; $lang->action->create = '添加备注'; $lang->action->comment = '备注'; +$lang->action->byQuery = '搜索'; $lang->action->undeleteAction = '还原数据'; $lang->action->hideOneAction = '隐藏数据'; diff --git a/module/action/model.php b/module/action/model.php index 1864ec1aac..db1d6c8eb3 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -683,6 +683,79 @@ class actionModel extends model return $trashes; } + /** + * Get deleted objects by search. + * + * @param string $objectType + * @param string $type all|hidden + * @param int $queryID + * @param string $orderBy + * @param object $pager + * @access public + * @return void + */ + public function getTrashesBySearch($objectType, $type, $queryID, $orderBy, $pager = null) + { + if($queryID and $queryID != 'myQueryID') + { + $query = $this->loadModel('search')->getQuery($queryID); + if($query) + { + $this->session->set('trashQuery', $query->sql); + $this->session->set('trashForm', $query->form); + } + else + { + $this->session->set('trashQuery', ' 1 = 1'); + } + } + else + { + if($this->session->trashQuery == false) $this->session->set('trashQuery', ' 1 = 1'); + } + + $extra = $type == 'hidden' ? self::BE_HIDDEN : self::CAN_UNDELETED; + $trashQuery = $this->session->trashQuery; + $trashQuery = preg_replace("/`objectID`/", 't1.`objectID`', $trashQuery); + $trashQuery = preg_replace("/`actor`/", 't1.`actor`', $trashQuery); + $trashQuery = preg_replace("/`date`/", 't1.`date`', $trashQuery); + $table = $this->config->objectTables[$objectType]; + $nameField = isset($this->config->action->objectNameFields[$objectType]) ? 't2.' . "`{$this->config->action->objectNameFields[$objectType]}`" : ''; + + if($nameField) $trashQuery = preg_replace("/`objectName`/", $nameField, $trashQuery); + + if($objectType != 'pipeline') + { + $trashes = $this->dao->select("t1.*, $nameField as objectName")->from(TABLE_ACTION)->alias('t1') + ->leftJoin($table)->alias('t2')->on('t1.objectID=t2.id') + ->where('t1.action')->eq('deleted') + ->andWhere($trashQuery) + ->andWhere('t1.extra')->eq($extra) + ->andWhere('t1.vision')->eq($this->config->vision) + ->beginIF($objectType != 'all')->andWhere('t1.objectType')->eq($objectType)->fi() + ->orderBy($orderBy) + ->page($pager) + ->fetchAll('objectID'); + } + else + { + $trashes = $this->dao->select("t1.*, t1.objectType as type, t2.name as objectName, t2.type as objectType")->from(TABLE_ACTION)->alias('t1') + ->leftJoin(TABLE_PIPELINE)->alias('t2')->on('t1.objectID=t2.id') + ->where('t1.action')->eq('deleted') + ->andWhere($trashQuery) + ->andWhere('t1.extra')->eq($extra) + ->andWhere('t1.vision')->eq($this->config->vision) + ->andWhere('(t2.type')->eq('gitlab') + ->orWhere('t2.type')->eq('jenkins') + ->markRight(1) + ->orderBy($orderBy) + ->page($pager) + ->fetchAll('objectID'); + } + + return $trashes; + } + /** * Get object type list of trashes. * @@ -1931,4 +2004,20 @@ class actionModel extends model return $actions; } + + /** + * Build search form. + * + * @param int $queryID + * @param string $actionURL + * @access public + * @return void + */ + public function buildTrashSearchForm($queryID, $actionURL) + { + $this->config->trash->search['actionURL'] = $actionURL; + $this->config->trash->search['queryID'] = $queryID; + + $this->loadModel('search')->setSearchParams($this->config->trash->search); + } } diff --git a/module/action/view/trash.html.php b/module/action/view/trash.html.php index 64d8b60b42..b17cedf64f 100755 --- a/module/action/view/trash.html.php +++ b/module/action/view/trash.html.php @@ -55,17 +55,20 @@ echo ''; } ?> + + action->byQuery;?> +
goback, '', "class='btn'");?> " . $lang->action->dynamic->hidden, '', "class='btn btn-danger'");?>
- +
- recTotal}&recPerPage={$pager->recPerPage}"; ?> + recTotal}&recPerPage={$pager->recPerPage}"; ?> diff --git a/module/bug/model.php b/module/bug/model.php index 49427c5fa2..723d90e267 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -938,10 +938,12 @@ class bugModel extends model ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) ->setDefault('assignedDate', $now) + ->stripTags($this->config->bug->editor->assignto['id'], $this->config->allowedTags) ->remove('comment,showModule') ->join('mailto', ',') ->get(); + $bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->assignto['id'], $this->post->uid); $this->dao->update(TABLE_BUG) ->data($bug) ->autoCheck() @@ -973,10 +975,12 @@ class bugModel extends model ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) ->setDefault('assignedDate', $now) + ->stripTags($this->config->bug->editor->confirmbug['id'], $this->config->allowedTags) ->remove('comment') ->join('mailto', ',') ->get(); + $bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->confirmbug['id'], $this->post->uid); $this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->checkFlow()->where('id')->eq($bugID)->exec(); if(!dao::isError()) @@ -1044,8 +1048,10 @@ class bugModel extends model ->setDefault('resolvedDate', $now) ->setDefault('assignedTo', $oldBug->openedBy) ->removeIF($this->post->resolution != 'duplicate', 'duplicateBug') + ->stripTags($this->config->bug->editor->resolve['id'], $this->config->allowedTags) ->remove('files,labels') ->get(); + $bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->resolve['id'], $this->post->uid); /* Set comment lang for alert error. */ $this->lang->bug->comment = $this->lang->comment; @@ -1319,6 +1325,7 @@ class bugModel extends model ->setDefault('lastEditedDate', $now) ->setDefault('activatedDate', $now) ->setDefault('activatedCount', (int)$oldBug->activatedCount) + ->stripTags($this->config->bug->editor->activate['id'], $this->config->allowedTags) ->add('id', $bugID) ->add('resolution', '') ->add('status', 'active') @@ -1334,6 +1341,7 @@ class bugModel extends model ->remove('comment,files,labels') ->get(); + $bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->activate['id'], $this->post->uid); $this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->checkFlow()->where('id')->eq((int)$bugID)->exec(); $this->dao->update(TABLE_BUG)->set('activatedCount = activatedCount + 1')->where('id')->eq((int)$bugID)->exec(); @@ -1380,9 +1388,11 @@ class bugModel extends model ->setDefault('lastEditedDate', $now) ->setDefault('closedBy', $this->app->user->account) ->setDefault('closedDate', $now) + ->stripTags($this->config->bug->editor->close['id'], $this->config->allowedTags) ->remove('comment') ->get(); + $bug = $this->loadModel('file')->processImgURL($bug, $this->config->bug->editor->close['id'], $this->post->uid); $this->dao->update(TABLE_BUG)->data($bug)->autoCheck()->checkFlow()->where('id')->eq((int)$bugID)->exec(); if($oldBug->execution) { diff --git a/module/common/model.php b/module/common/model.php index 54a3c34a61..5f392554d1 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -1920,7 +1920,7 @@ EOD; if(strtolower($key) == 'closeddate' && $value == '') continue; if(strtolower($key) == 'actualcloseddate' && $value == '') continue; - if(isset($old->$key) and $value != stripslashes($old->$key)) + if(array_key_exists($key, $old) and $value != stripslashes($old->$key)) { $diff = ''; if(substr_count($value, "\n") > 1 or diff --git a/module/custom/view/required.html.php b/module/custom/view/required.html.php index 4ed45dbd28..80dc184e47 100644 --- a/module/custom/view/required.html.php +++ b/module/custom/view/required.html.php @@ -16,7 +16,8 @@
custom->requiredModules as $requiredModule) + $reruiredModules = ksort($config->custom->requiredModules); + foreach($requiredModules as $requiredModule) { $requiredModuleName = zget($lang->custom->moduleName, $requiredModule, $lang->$requiredModule->common); echo html::a(inlink('required', "module=$requiredModule"), $requiredModuleName, '', "id='{$requiredModule}Tab'"); diff --git a/module/doc/control.php b/module/doc/control.php old mode 100644 new mode 100755 index 89c931c78e..101676c2de --- a/module/doc/control.php +++ b/module/doc/control.php @@ -792,6 +792,28 @@ class doc extends control return print($select); } + /** + * Ajax get docs by lib. + * + * @param int $libID + * @access public + * @return void + */ + public function ajaxGetDocs($libID) + { + if(!$libID) return print(html::select('doc', '', '', "class='form-control chosen'")); + + $docIdList = $this->doc->getPrivDocs($libID, 0); + $docs = $this->dao->select('id, title')->from(TABLE_DOC) + ->where('lib')->eq($libID) + ->andWhere('deleted')->eq(0) + ->andWhere('id')->in($docIdList) + ->orderBy('`order` asc') + ->fetchPairs(); + + return print(html::select('doc', $docs, '', "class='form-control chosen'")); + } + /** * Ajax save draft. * diff --git a/module/execution/control.php b/module/execution/control.php index e89d613e03..6c0e162839 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -3820,17 +3820,18 @@ class execution extends control * @param string $browseType * @param string $groupBy * @param string $from execution|RD + * @param string $searchValue * @access public * @return array */ - public function ajaxUpdateKanban($executionID = 0, $enterTime = '', $browseType = '', $groupBy = '', $from = 'execution') + public function ajaxUpdateKanban($executionID = 0, $enterTime = '', $browseType = '', $groupBy = '', $from = 'execution', $searchValue = '') { $enterTime = date('Y-m-d H:i:s', $enterTime); $lastEditedTime = $this->dao->select("max(lastEditedTime) as lastEditedTime")->from(TABLE_KANBANLANE)->where('execution')->eq($executionID)->fetch('lastEditedTime'); - if($lastEditedTime > $enterTime or $groupBy != 'default') + if($lastEditedTime > $enterTime or $groupBy != 'default' or !empty($searchValue)) { - $kanbanGroup = $from == 'execution' ? $this->loadModel('kanban')->getExecutionKanban($executionID, $browseType, $groupBy) : $this->loadModel('kanban')->getRDKanban($executionID, $browseType, 'id_asc', 0, $groupBy); + $kanbanGroup = $from == 'execution' ? $this->loadModel('kanban')->getExecutionKanban($executionID, $browseType, $groupBy) : $this->loadModel('kanban')->getRDKanban($executionID, $browseType, 'id_asc', 0, $groupBy, $searchValue); return print(json_encode($kanbanGroup)); } } diff --git a/module/execution/css/kanban.css b/module/execution/css/kanban.css index bb8b8d5bbd..8c3aff303c 100644 --- a/module/execution/css/kanban.css +++ b/module/execution/css/kanban.css @@ -110,3 +110,7 @@ #mainMenu .divider {margin: 10px} .modal-header {padding: 15px 0;} +#rdKanbanSearch.input-group {float: left; width: min-content;} +#rdKanbanSearchInput {width: 150px;} +#rdSearchBox {display: none; width: 150px;} +.btn-link.querybox-toggle {background-color: rgba(0,0,0,0);} diff --git a/module/execution/css/taskkanban.css b/module/execution/css/taskkanban.css index 0127f0157c..166278d2f0 100644 --- a/module/execution/css/taskkanban.css +++ b/module/execution/css/taskkanban.css @@ -54,7 +54,7 @@ #type_chosen .icon-kanban {padding-right: 10px; font-size: 15px;} .dropdown-menu a {text-align: left;} -.scrollbar-hover {max-height: 2000px; overflow: scroll !important;} +.scrollbar-hover {overflow: scroll !important;} .c-type {width: 150px !important; overflow: unset;} .c-group {width: 190px !important; overflow: unset;} .c-type {margin-left: 0px !important;} diff --git a/module/execution/js/kanban.js b/module/execution/js/kanban.js index 0ae0cece62..5c143b7fc3 100644 --- a/module/execution/js/kanban.js +++ b/module/execution/js/kanban.js @@ -478,7 +478,8 @@ function renderStoryItem(item, $item, col) .attr('href', $.createLink('story', 'view', 'storyID=' + item.id + '&version=0¶m=' + execution.id, '', true)).attr('data-toggle', 'modal').attr('data-width', '95%'); $title.appendTo($item); } - $title.attr('title', item.title).find('.text').text(item.title); + var title = rdSearchValue != '' ? "" + item.title.replaceAll(rdSearchValue, "" + rdSearchValue + "") + "": "" + item.title + ""; + $title.attr('title', item.title).find('.text').replaceWith(title); } if(scaleSize <= 2) @@ -542,7 +543,8 @@ function renderBugItem(item, $item, col) .attr('href', $.createLink('bug', 'view', 'bugID=' + item.id, '', true)).attr('data-toggle', 'modal').attr('data-width', '80%'); $title.appendTo($item); } - $title.attr('title', item.title).find('.text').text(item.title); + var title = rdSearchValue != '' ? "" + item.title.replaceAll(rdSearchValue, "" + rdSearchValue + "") + "": "" + item.title + ""; + $title.attr('title', item.title).find('.text').replaceWith(title); } if(scaleSize <= 2) @@ -608,7 +610,8 @@ function renderTaskItem(item, $item, col) .attr('href', $.createLink('task', 'view', 'taskID=' + item.id, '', true)).attr('data-toggle', 'modal').attr('data-width', '80%'); $title.appendTo($item); } - $title.attr('title', item.name).find('.text').text(item.name); + var name = rdSearchValue != '' ? "" + item.name.replaceAll(rdSearchValue, "" + rdSearchValue + "") + "": "" + item.name + ""; + $title.attr('title', item.name).find('.text').replaceWith(name); } if(scaleSize <= 2) @@ -792,6 +795,16 @@ function updateRegion(regionID, regionData = []) if(!regionData) regionData = regions[regionID]; var data = groupBy == 'default' ? regionData.groups : regionData; + if(data == null) + { + $("div[data-id^=" + regionID + "].region").hide(); + return false; + } + else + { + $("div[data-id^=" + regionID + "].region").show(); + } + $region.empty(); $region.data('zui.kanban').render(data); resetRegionHeight('open'); return true; @@ -1504,7 +1517,7 @@ $(function() var lastUpdateData; setInterval(function() { - $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=" + entertime + "&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD'), function(data) + $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=" + entertime + "&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD&searchValue' + rdSearchValue), function(data) { if(data && lastUpdateData !== data) { @@ -1580,3 +1593,58 @@ function resetRegionHeight(fold) $('.region').css('height', regionHeaderHeight); } } + +/** + * Toggle RDSearchBox. + * + * @access public + * @return void + */ +function toggleRDSearchBox() +{ + rdSearchValue = ''; + $('#rdSearchBox').toggle(); + if($('#rdSearchBox').css('display') == 'block') + { + $(".querybox-toggle").css("color", "#0c64eb"); + } + else + { + $(".querybox-toggle").css("color", ""); + $('#rdKanbanSearchInput').attr('value', ''); + searchCards(''); + } +} + +/** + * Search all cards. + * + * @param string $value + * @access public + * @return void + */ +function searchCards(value) +{ + rdSearchValue = value; + $.get(createLink('execution', 'ajaxUpdateKanban', "executionID=" + executionID + "&entertime=0&browseType=" + browseType + "&groupBy=" + groupBy + '&from=RD&searchValue=' + value), function(data) + { + var kanbanData = $.parseJSON(data); + var hideAll = true; + $('#kanban').children('.region').children("div[id^='kanban']").each(function() + { + var regionID = $(this).attr('data-id'); + if(kanbanData != null) data = groupBy == 'default' ? kanbanData[regionID] : kanbanData[groupBy]; + + hideAll = hideAll && !updateRegion(regionID, data); + }); + + if(hideAll && rdSearchValue != '') + { + if($('.table-empty-tip').length == 0) $('#kanban').append('

' + kanbanLang.empty + '

'); + } + else + { + $('.table-empty-tip').remove(); + } + }); +} diff --git a/module/execution/lang/en.php b/module/execution/lang/en.php index a4b945d24e..a6653e2522 100644 --- a/module/execution/lang/en.php +++ b/module/execution/lang/en.php @@ -396,6 +396,7 @@ $lang->execution->projectNotEmpty = 'Project cannot be empty.'; $lang->execution->confirmStoryToTask = $lang->SRCommon . '%s are converted to tasks in the current. Do you want to convert them anyways?'; $lang->execution->ge = "『%s』should be >= actual begin『%s』."; $lang->execution->storyDragError = "The {$lang->SRCommon} is still a draft or has been changed, please drag it after the review"; +$lang->execution->pleaseInput = "Enter"; /* Statistics. */ $lang->execution->charts = new stdclass(); diff --git a/module/execution/lang/zh-cn.php b/module/execution/lang/zh-cn.php index 66c76615ea..42264d001a 100644 --- a/module/execution/lang/zh-cn.php +++ b/module/execution/lang/zh-cn.php @@ -396,6 +396,7 @@ $lang->execution->projectNotEmpty = '所属项目不能为空。'; $lang->execution->confirmStoryToTask = '%s' . $lang->SRCommon . '已经在当前' . $lang->execution->common . '中转了任务,请确认是否重复转任务。'; $lang->execution->ge = "『%s』应当不小于实际开始时间『%s』。"; $lang->execution->storyDragError = "该{$lang->SRCommon}还是草稿或已变更状态,请评审通过后再拖动"; +$lang->execution->pleaseInput = "请输入"; /* 统计。*/ $lang->execution->charts = new stdclass(); diff --git a/module/execution/model.php b/module/execution/model.php index 2e19ffa8a4..e39021bc1f 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -818,9 +818,11 @@ class executionModel extends model ->setDefault('status', 'doing') ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) + ->stripTags($this->config->execution->editor->start['id'], $this->config->allowedTags) ->remove('comment') ->get(); + $execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->start['id'], $this->post->uid); $this->dao->update(TABLE_EXECUTION)->data($execution) ->autoCheck() ->check($this->config->execution->start->requiredFields, 'notempty') @@ -849,6 +851,7 @@ class executionModel extends model $execution = fixer::input('post') ->add('id', $executionID) + ->stripTags($this->config->execution->editor->putoff['id'], $this->config->allowedTags) ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) ->remove('comment') @@ -857,6 +860,7 @@ class executionModel extends model if($this->config->systemMode == 'new') $this->checkBeginAndEndDate($oldExecution->project, $execution->begin, $execution->end); if(dao::isError()) return false; + $execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->putoff['id'], $this->post->uid); $this->dao->update(TABLE_EXECUTION)->data($execution) ->autoCheck() ->checkFlow() @@ -884,8 +888,10 @@ class executionModel extends model ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) ->setDefault('suspendedDate', helper::today()) + ->stripTags($this->config->execution->editor->suspend['id'], $this->config->allowedTags) ->remove('comment')->get(); + $execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->suspend['id'], $this->post->uid); $this->dao->update(TABLE_EXECUTION)->data($execution) ->autoCheck() ->checkFlow() @@ -913,6 +919,7 @@ class executionModel extends model ->setDefault('status', 'doing') ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) + ->stripTags($this->config->execution->editor->activate['id'], $this->config->allowedTags) ->remove('comment,readjustTime,readjustTask') ->get(); @@ -922,6 +929,7 @@ class executionModel extends model unset($execution->end); } + $execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->activate['id'], $this->post->uid); $this->dao->update(TABLE_EXECUTION)->data($execution) ->autoCheck() ->checkFlow() @@ -995,11 +1003,13 @@ class executionModel extends model ->setDefault('closedDate', $now) ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) + ->stripTags($this->config->execution->editor->close['id'], $this->config->allowedTags) ->remove('comment') ->get(); $this->lang->error->ge = $this->lang->execution->ge; + $execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->close['id'], $this->post->uid); $this->dao->update(TABLE_EXECUTION)->data($execution) ->autoCheck() ->check($this->config->execution->close->requiredFields,'notempty') diff --git a/module/execution/view/kanban.html.php b/module/execution/view/kanban.html.php index ea835a478e..a1c1615e0a 100644 --- a/module/execution/view/kanban.html.php +++ b/module/execution/view/kanban.html.php @@ -52,6 +52,7 @@ js::set('vision', $this->config->vision); js::set('productCount', count($productNames)); js::set('executionID', $execution->id); js::set('reviewStoryParis', $reviewStoryParis); +js::set('rdSearchValue', ''); $canSortRegion = commonModel::hasPriv('kanban', 'sortRegion') && count($regions) > 1; $canEditRegion = commonModel::hasPriv('kanban', 'editRegion'); @@ -136,7 +137,13 @@ js::set('hasTaskButton', $hasTaskButton);
+
+ +
" . $lang->searchAB, '', "class='btn btn-link querybox-toggle'"); echo html::a('javascript:fullScreen()', " " . $lang->kanban->fullScreen, '', "class='btn btn-link'"); $actions = ''; $printCreateRegion = (common::hasPriv('kanban', 'createRegion') and $groupBy == 'default'); diff --git a/module/kanban/css/space.css b/module/kanban/css/space.css index 0af2b80557..a5e7c3e778 100644 --- a/module/kanban/css/space.css +++ b/module/kanban/css/space.css @@ -7,7 +7,9 @@ #spaceList .spaceActions > a{margin-left: 10px;} .space .menu {margin-left: 5px; margin-right:5px;} .space .table-empty-tip {padding: 40px 10px;} -.space .spaceTitle.pull-left {overflow: hidden; white-space: nowrap; max-width: calc(100% - 255px)} +.space .spaceTitle.pull-left {overflow: hidden; white-space: nowrap; max-width: calc(100% - 150px)} +.spaceDesc {font-size: 13px; color: #838A9D; margin: -5px 0 5px 18px;} +#more .setting {margin-left: -25px; min-width: 80px} .kanbans > .col {width: 25% !important;} @media screen and (max-width: 1500px) {.kanbans > .col {width: 25%;}} diff --git a/module/kanban/lang/en.php b/module/kanban/lang/en.php index 661b6b5100..ada1af7205 100644 --- a/module/kanban/lang/en.php +++ b/module/kanban/lang/en.php @@ -26,6 +26,7 @@ $lang->kanban->columnWidth = 'Column Width'; $lang->kanban->setColumnWidth = 'Set Column Width'; $lang->kanban->deleteLane = 'Delete Lane'; $lang->kanban->createColumn = 'Create Column'; +$lang->kanban->emptyDesc = 'No description'; $lang->kanban->editColumn = 'Edit Column'; $lang->kanban->sortColumn = 'Sort Column'; $lang->kanban->deleteColumn = 'Delete Column'; @@ -275,14 +276,14 @@ $lang->kanbanspace->empty = 'No Space'; $lang->kanbanspace->aclList['open'] = 'Open (Accessible with kanban view permissions)'; $lang->kanbanspace->aclList['private'] = 'Private (For the space owner, team and whitelist members only)'; -$lang->kanbanspace->featureBar['private'] = 'Private Space'; +$lang->kanbanspace->featureBar['involved'] = 'Involved'; $lang->kanbanspace->featureBar['cooperation'] = 'Cooperation Space'; $lang->kanbanspace->featureBar['public'] = 'Public Space'; -$lang->kanbanspace->featureBar['involved'] = 'Involved'; +$lang->kanbanspace->featureBar['private'] = 'Private Space'; -$lang->kanbanspace->typeList['private'] = 'Private Space'; $lang->kanbanspace->typeList['cooperation'] = 'Cooperation Space'; $lang->kanbanspace->typeList['public'] = 'Public Space'; +$lang->kanbanspace->typeList['private'] = 'Private Space'; $lang->kanbancolumn = new stdclass(); $lang->kanbancolumn->name = $lang->kanban->columnName; diff --git a/module/kanban/lang/zh-cn.php b/module/kanban/lang/zh-cn.php index a706e5927f..8fab1ef0f2 100644 --- a/module/kanban/lang/zh-cn.php +++ b/module/kanban/lang/zh-cn.php @@ -26,6 +26,7 @@ $lang->kanban->columnWidth = '列宽度'; $lang->kanban->setColumnWidth = '设置列宽度'; $lang->kanban->deleteLane = '删除泳道'; $lang->kanban->createColumn = '创建看板列'; +$lang->kanban->emptyDesc = '暂无描述'; $lang->kanban->editColumn = '编辑看板列'; $lang->kanban->sortColumn = '看板列排序'; $lang->kanban->deleteColumn = '删除看板列'; @@ -275,14 +276,14 @@ $lang->kanbanspace->empty = '暂时没有空间'; $lang->kanbanspace->aclList['open'] = '公开(有看板空间视图权限即可访问)'; $lang->kanbanspace->aclList['private'] = '私有(只有看板空间负责人、团队成员、白名单可访问)'; -$lang->kanbanspace->featureBar['private'] = '私人空间'; +$lang->kanbanspace->featureBar['involved'] = '我参与的'; $lang->kanbanspace->featureBar['cooperation'] = '协作空间'; $lang->kanbanspace->featureBar['public'] = '公共空间'; -$lang->kanbanspace->featureBar['involved'] = '我参与的'; +$lang->kanbanspace->featureBar['private'] = '私人空间'; -$lang->kanbanspace->typeList['private'] = '私人空间'; $lang->kanbanspace->typeList['cooperation'] = '协作空间'; $lang->kanbanspace->typeList['public'] = '公共空间'; +$lang->kanbanspace->typeList['private'] = '私人空间'; $lang->kanbancolumn = new stdclass(); $lang->kanbancolumn->name = $lang->kanban->columnName; diff --git a/module/kanban/model.php b/module/kanban/model.php index 0f814a8a07..1ec2c65282 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -808,13 +808,14 @@ class kanbanModel extends model * @param string $orderBy * @param int $regionID * @param string $groupBy + * @param string $searchValue * * @access public * @return array */ - public function getRDKanban($executionID, $browseType = 'all', $orderBy = 'id_desc', $regionID = 0, $groupBy = 'default') + public function getRDKanban($executionID, $browseType = 'all', $orderBy = 'id_desc', $regionID = 0, $groupBy = 'default', $searchValue = '') { - if($groupBy != 'default') return $this->getKanban4Group($executionID, $browseType, $groupBy); + if($groupBy != 'default') return $this->getKanban4Group($executionID, $browseType, $groupBy, $searchValue); $kanbanData = array(); $actions = array('sortGroup'); @@ -823,7 +824,7 @@ class kanbanModel extends model $groupGroup = $this->getGroupGroupByRegions($regionIDList); $laneGroup = $this->getLaneGroupByRegions($regionIDList, $browseType); $columnGroup = $this->getRDColumnGroupByRegions($regionIDList, array_keys($laneGroup)); - $cardGroup = $this->getCardGroupByExecution($executionID, $browseType, $orderBy); + $cardGroup = $this->getCardGroupByExecution($executionID, $browseType, $orderBy, $searchValue); foreach($regions as $regionID => $regionName) { @@ -838,13 +839,16 @@ class kanbanModel extends model $lanes = zget($laneGroup, $group->id, array()); if(!$lanes) continue; - foreach($lanes as $lane) + foreach($lanes as $key => $lane) { $this->refreshCards($lane); $lane->items = isset($cardGroup[$lane->id]) ? $cardGroup[$lane->id] : array(); $lane->defaultCardType = $lane->type; + if($searchValue != '' and count($lane->items) == 0) unset($lanes[$key]); } + $lanes = array_values($lanes); + if($searchValue != '' and empty($lanes)) continue; $group->columns = zget($columnGroup, $group->id, array()); $group->lanes = $lanes; $group->actions = array(); @@ -1250,10 +1254,12 @@ class kanbanModel extends model * @param int $kanbanID * @param string $browseType all|task|bug|story * @param string $orderBy + * @param string $searchValue + * * @access public * @return array */ - public function getCardGroupByExecution($executionID, $browseType = 'all', $orderBy = 'id_asc') + public function getCardGroupByExecution($executionID, $browseType = 'all', $orderBy = 'id_asc', $searchValue = '') { $cards = $this->dao->select('t1.*, t2.type as columnType') ->from(TABLE_KANBANCELL)->alias('t1') @@ -1297,12 +1303,14 @@ class kanbanModel extends model if($cell->type == 'task') { + if($searchValue != '' and strpos($object->name, $searchValue) === false) continue; $cardData['name'] = $object->name; $cardData['status'] = $object->status; $cardData['left'] = $object->left; } else { + if($searchValue != '' and strpos($object->title, $searchValue) === false) continue; $cardData['title'] = $object->title; } $cardGroup[$laneID][$cell->columnType][] = $cardData; @@ -1406,12 +1414,14 @@ class kanbanModel extends model if($lane->type == 'task') { + if($searchValue != '' and strpos($object->name, $searchValue) === false) continue; $cardData['name'] = $object->name; $cardData['status'] = $object->status; $cardData['left'] = $object->left; } else { + if($searchValue != '' and strpos($object->title, $searchValue) === false) continue; $cardData['title'] = $object->title; } @@ -1440,10 +1450,12 @@ class kanbanModel extends model * @param int $executionID * @param string $browseType * @param string $groupBy + * @param string $searchValue + * * @access public * @return array */ - public function getKanban4Group($executionID, $browseType, $groupBy) + public function getKanban4Group($executionID, $browseType, $groupBy, $searchValue = '') { /* Get card data. */ $cardList = array(); @@ -1551,21 +1563,24 @@ class kanbanModel extends model if($browseType == 'task') { + if($searchValue != '' and strpos($object->name, $searchValue) === false) continue; $cardData['name'] = $object->name; $cardData['status'] = $object->status; $cardData['left'] = $object->left; } else { + if($searchValue != '' and strpos($object->title, $searchValue) === false) continue; $cardData['title'] = $object->title; } $laneData['cards'][$column->columnType][] = $cardData; $cardOrder ++; } - if(!isset($laneData['cards'][$column->columnType])) $laneData['cards'][$column->columnType] = array(); + if(empty($searchValue) and !isset($laneData['cards'][$column->columnType])) $laneData['cards'][$column->columnType] = array(); } + if($searchValue != '' and empty($laneData['cards'])) continue; $kanbanGroup[$groupBy]['id'] = $groupBy . $laneID; $kanbanGroup[$groupBy]['columns'] = array_values($columnData); $kanbanGroup[$groupBy]['lanes'][] = $laneData; diff --git a/module/kanban/view/createspace.html.php b/module/kanban/view/createspace.html.php index 5b846d738a..924bfcf17f 100644 --- a/module/kanban/view/createspace.html.php +++ b/module/kanban/view/createspace.html.php @@ -20,7 +20,7 @@
action->objectType);?>
- + diff --git a/module/kanban/view/editspace.html.php b/module/kanban/view/editspace.html.php index 1087b3d4f3..13ca616cda 100644 --- a/module/kanban/view/editspace.html.php +++ b/module/kanban/view/editspace.html.php @@ -20,7 +20,7 @@
kanbanspace->type;?>
- + diff --git a/module/kanban/view/space.html.php b/module/kanban/view/space.html.php index c35594682e..389ba7e45a 100644 --- a/module/kanban/view/space.html.php +++ b/module/kanban/view/space.html.php @@ -47,17 +47,23 @@ name;?> +

desc) ? $lang->kanban->emptyDesc : $space->desc;?>

status == 'closed' ? 'disabled' : '';?> status != 'closed' and $browseType != 'involved' and !empty($unclosedSpace)) common::printLink('kanban', 'create', "spaceID={$space->id}&type={$space->type}", ' ' . $lang->kanban->create, '', "class='iframe' data-width='75%'", '', true);?> - id}", ' ' . $lang->kanban->setting, '', "class='iframe' data-width='75%'", '', true);?> - - id}", ' ' . $lang->activate, '', "class='iframe'", '', true);?> - - id}", ' ' . $lang->close, '', "class='iframe'", '', true);?> - - id}", ' ' . $lang->delete, 'hiddenwin', '', '', true);?> +
+ kanban->setting;?> +
kanbans)):?> diff --git a/module/my/control.php b/module/my/control.php index f0dfff94f5..428f26c3eb 100755 --- a/module/my/control.php +++ b/module/my/control.php @@ -75,18 +75,19 @@ class my extends control /** * My work view. * - * @param string $mode - * @param string $type - * @param string $orderBy - * @param int $recTotal - * @param int $recPerPage - * @param int $pageID + * @param string $mode + * @param string $type + * @param string|int $param + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID * @access public * @return void */ - public function work($mode = 'task', $type = 'assignedTo', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + public function work($mode = 'task', $type = 'assignedTo', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) { - echo $this->fetch('my', $mode, "type=$type&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"); + echo $this->fetch('my', $mode, "type=$type¶m=$param&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"); $this->showWorkCount($recTotal, $recPerPage, $pageID); } @@ -210,20 +211,21 @@ EOF; /** * My contribute view. * - * @param string $mode - * @param string $type - * @param string $orderBy - * @param int $recTotal - * @param int $recPerPage - * @param int $pageID + * @param string $mode + * @param string $type + * @param string|int $param + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID * @access public * @return void */ - public function contribute($mode = 'task', $type = 'openedBy', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + public function contribute($mode = 'task', $type = 'openedBy', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) { if(($mode == 'issue' or $mode == 'risk') and $type == 'openedBy') $type = 'createdBy'; - echo $this->fetch('my', $mode, "type=$type&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"); + echo $this->fetch('my', $mode, "type=$type¶m=$param&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"); } /** @@ -596,15 +598,16 @@ EOF; /** * My test case. * - * @param string $type assigntome|openedbyme - * @param string $orderBy - * @param int $recTotal - * @param int $recPerPage - * @param int $pageID + * @param string $type assigntome|openedbyme + * @param string|int $param + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID * @access public * @return void */ - public function testcase($type = 'assigntome', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + public function testcase($type = 'assigntome', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) { $this->loadModel('testcase'); $this->loadModel('testtask'); @@ -620,20 +623,24 @@ EOF; /* Append id for secend sort. */ $sort = common::appendOrder($orderBy); + $queryID = ($type == 'bysearch') ? (int)$param : 0; $cases = array(); - if($type == 'assigntome') - { - $cases = $this->testcase->getByAssignedTo($this->app->user->account, $sort, $pager, 'skip'); - } - elseif($type == 'openedbyme') - { - $cases = $this->testcase->getByOpenedBy($this->app->user->account, $sort, $pager, 'skip'); - } + if($type == 'assigntome') $cases = $this->testcase->getByAssignedTo($this->app->user->account, $sort, $pager, 'skip'); + if($type == 'openedbyme') $cases = $this->testcase->getByOpenedBy($this->app->user->account, $sort, $pager, 'skip'); + if($type == 'bysearch' and $this->app->rawMethod == 'contribute') $cases = $this->my->getTestcasesBySearch($queryID, 'openedbyme', $orderBy, $pager); + if($type == 'bysearch' and $this->app->rawMethod == 'work') $cases = $this->my->getTestcasesBySearch($queryID, 'assigntome', $orderBy, $pager); + $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', $type == 'assigntome' ? false : true); $cases = $this->testcase->appendData($cases, $type == 'assigntome' ? 'run' : 'case'); + /* Build the search form. */ + $currentMethod = $this->app->rawMethod; + $actionURL = $this->createLink('my', $currentMethod, "mode=testcase&type=bysearch¶m=myQueryID&orderBy={$orderBy}&recTotal={$recTotal}&recPerPage={$recPerPage}&pageID={$pageID}"); + $this->config->testcase->search['onMenuBar'] = 'yes'; + $this->my->buildTestcaseSearchForm($queryID, $actionURL, $currentMethod); + /* Assign. */ $this->view->title = $this->lang->my->common . $this->lang->colon . $this->lang->my->myTestCase; $this->view->position[] = $this->lang->my->myTestCase; diff --git a/module/my/lang/en.php b/module/my/lang/en.php index 344033dd8f..5aa236aa2a 100644 --- a/module/my/lang/en.php +++ b/module/my/lang/en.php @@ -43,6 +43,7 @@ $lang->my->testcase = 'My Case'; $lang->my->storyConcept = 'Story Concept'; $lang->my->pri = 'Priority'; $lang->my->alert = 'You can click on your profile at the top right and select "Preference" to modify your information. '; +$lang->my->assignedToMe = 'AssignedToMe'; $lang->my->indexAction = 'My Index'; $lang->my->calendarAction = 'My Calendar'; diff --git a/module/my/lang/zh-cn.php b/module/my/lang/zh-cn.php index a0a4e36334..265f0899b7 100644 --- a/module/my/lang/zh-cn.php +++ b/module/my/lang/zh-cn.php @@ -43,6 +43,7 @@ $lang->my->testcase = '我的用例'; $lang->my->storyConcept = $config->URAndSR ? '默认需求概念组合' : '默认需求概念'; $lang->my->pri = '优先级'; $lang->my->alert = '后续您可以点击右上方的头像,选择“个性化设置”修改信息。'; +$lang->my->assignedToMe = '指派给我'; $lang->my->indexAction = '地盘仪表盘'; $lang->my->calendarAction = '我的日程'; diff --git a/module/my/model.php b/module/my/model.php index bbe114d790..b36f80cd30 100644 --- a/module/my/model.php +++ b/module/my/model.php @@ -374,4 +374,88 @@ class myModel extends model } return $objectList; } + + /** + * Build search form. + * + * @param int $queryID + * @param string $actionURL + * @param string $type + * @access public + * @return void + */ + public function buildTestCaseSearchForm($queryID, $actionURL, $type) + { + $products = $this->dao->select('id,name')->from(TABLE_PRODUCT) + ->where('deleted')->eq(0) + ->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->products)->fi() + ->orderBy('order_asc') + ->fetchPairs(); + + $queryName = $type == 'contribute' ? 'contributeTestcase' : 'workTestcase'; + $this->app->loadConfig('testcase'); + $this->config->testcase->search['module'] = $queryName; + $this->config->testcase->search['queryID'] = $queryID; + $this->config->testcase->search['actionURL'] = $actionURL; + $this->config->testcase->search['params']['product']['values'] = $products; + $this->config->testcase->search['params']['lib']['values'] = $this->loadModel('caselib')->getLibraries(); + + unset($this->config->testcase->search['fields']['module']); + + $this->loadModel('search')->setSearchParams($this->config->testcase->search); + } + + /** + * Get testcases by search. + * + * @param int $queryID + * @param string $type + * @param string $orderBy + * @param int $pager + * @access public + * @return array + */ + public function getTestcasesBySearch($queryID, $type, $orderBy, $pager) + { + $queryName = $type == 'openedbyme' ? 'contributeTestcaseQuery' : 'workTestcaseQuery'; + if($queryID) + { + $query = $this->loadModel('search')->getQuery($queryID); + if($query) + { + $this->session->set($queryName, $query->sql); + $this->session->set($queryName . 'Form', $query->form); + } + else + { + $this->session->set($queryName, ' 1 = 1'); + } + } + else + { + if($this->session->$queryName == false) $this->session->set($queryName, ' 1 = 1'); + } + + $myTestcaseQuery = $this->session->$queryName; + $myTestcaseQuery = preg_replace('/`(\w+)`/', 't1.`$1`', $myTestcaseQuery); + + if($type == 'openedbyme') + { + $cases = $this->dao->select('*')->from(TABLE_CASE)->alias('t1') + ->where($myTestcaseQuery) + ->andWhere('t1.openedBy')->eq($this->app->user->account) + ->andWhere('t1.deleted')->eq(0) + ->orderBy($orderBy)->page($pager)->fetchAll('id'); + } + else + { + $cases = $this->dao->select('t1.*')->from(TABLE_CASE)->alias('t1') + ->leftJoin(TABLE_TESTRUN)->alias('t2')->on('t1.id = t2.case') + ->where($myTestcaseQuery) + ->andWhere('t2.assignedTo')->eq($this->app->user->account) + ->andWhere('t1.deleted')->eq(0) + ->orderBy($orderBy)->page($pager)->fetchAll('id'); + } + return $cases; + } } diff --git a/module/my/view/testcase.html.php b/module/my/view/testcase.html.php index c2e68cf59e..0aae03d69e 100644 --- a/module/my/view/testcase.html.php +++ b/module/my/view/testcase.html.php @@ -19,11 +19,20 @@
{$pager->recTotal}"; - if($app->rawMethod == 'contribute') echo html::a(inlink($app->rawMethod, "mode=$mode&type=openedbyme"), "{$lang->testcase->openedByMe}" . ($type == 'openedbyme' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'openedbyme' ? ' btn-active-text' : '') . "'"); + if($app->rawMethod == 'contribute') + { + echo html::a(inlink($app->rawMethod, "mode=$mode&type=openedbyme"), "{$lang->testcase->openedByMe}" . ($type == 'openedbyme' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'openedbyme' ? ' btn-active-text' : '') . "'"); + } + else + { + echo html::a(inlink($app->rawMethod, "mode=$mode&type=assigntome"), "{$lang->my->assignedToMe}" . ($type == 'assigntome' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'assigntome' ? ' btn-active-text' : '') . "'"); + } ?> + loadModel('search');echo $lang->search->common;?>
+
rawMethod == 'contribute' ? 'contributeTestcase' : 'workTestcase');?>>

testcase->noCase;?>

diff --git a/module/product/model.php b/module/product/model.php index 2d9261812f..f20a1b7d27 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -872,11 +872,14 @@ class productModel extends model { $oldProduct = $this->getById($productID); $now = helper::now(); - $product= fixer::input('post') + $product = fixer::input('post') ->add('id', $productID) ->setDefault('status', 'closed') - ->remove('comment')->get(); + ->stripTags($this->config->product->editor->close['id'], $this->config->allowedTags) + ->remove('comment') + ->get(); + $product = $this->loadModel('file')->processImgURL($product, $this->config->product->editor->close['id'], $this->post->uid); $this->dao->update(TABLE_PRODUCT)->data($product) ->autoCheck() ->checkFlow() diff --git a/module/productplan/config.php b/module/productplan/config.php index c9c405e5d0..2be831f271 100644 --- a/module/productplan/config.php +++ b/module/productplan/config.php @@ -15,3 +15,21 @@ $config->productplan->editor->view = array('id' => 'lastComment', 'tools' => ' $config->productplan->laneColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#FFC20E', '#00A78E', '#7FBB00', '#424BAC', '#C0E9FF', '#EC2761'); $config->productplan->future = '2030-01-01'; + +global $app, $lang; +$app->loadLang('productplan'); +$config->productplan->search['module'] = 'productplan'; + +$config->productplan->search['fields']['id'] = $lang->productplan->id; +$config->productplan->search['fields']['title'] = $lang->productplan->title; +$config->productplan->search['fields']['branch'] = $lang->productplan->branch; +$config->productplan->search['fields']['status'] = $lang->productplan->status; +$config->productplan->search['fields']['begin'] = $lang->productplan->begin; +$config->productplan->search['fields']['end'] = $lang->productplan->end; + +$config->productplan->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => ''); +$config->productplan->search['params']['title'] = array('operator' => 'include', 'control' => 'input', 'values' => ''); +$config->productplan->search['params']['branch'] = array('operator' => '=', 'control' => 'select', 'values' => ''); +$config->productplan->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => $lang->productplan->statusList); +$config->productplan->search['params']['begin'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); +$config->productplan->search['params']['end'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); diff --git a/module/productplan/control.php b/module/productplan/control.php index a0607f5396..4510cef8eb 100644 --- a/module/productplan/control.php +++ b/module/productplan/control.php @@ -283,15 +283,16 @@ class productplan extends control * * @param int $productID * @param int $branch - * @param string $orderBy * @param string $browseType + * @param int $queryID + * @param string $orderBy * @param int $recTotal * @param int $recPerPage * @param int $pageID * @access public * @return void */ - public function browse($productID = 0, $branch = '', $browseType = 'undone', $orderBy = 'begin_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1 ) + public function browse($productID = 0, $branch = '', $browseType = 'undone', $queryID = 0, $orderBy = 'begin_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1 ) { $branchID = $branch === '' ? 'all' : $branch; if(!$branch) $branch = 0; @@ -313,6 +314,11 @@ class productplan extends control $branchStatusList = array(); foreach($branchList as $productBranch) $branchStatusList[$productBranch->id] = $productBranch->status; + /* Build the search form. */ + $queryID = $browseType == 'bySearch' ? (int)$queryID : 0; + $actionURL = $this->createLink('productplan', 'browse', "productID=$productID&branch=$branch&browseType=bySearch&queryID=myQueryID&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"); + $this->productplan->buildSearchForm($queryID, $actionURL, $product); + if($viewType == 'kanban') { $branches = array(); @@ -353,10 +359,11 @@ class productplan extends control $this->view->browseType = $browseType; $this->view->viewType = $viewType; $this->view->orderBy = $orderBy; - $this->view->plans = $this->productplan->getList($productID, $branch, $browseType, $pager, $sort); + $this->view->plans = $this->productplan->getList($productID, $branch, $browseType, $pager, $sort, "", $queryID); $this->view->pager = $pager; $this->view->projects = $this->product->getProjectPairsByProduct($productID, $branch); $this->view->statusList = $this->lang->productplan->featureBar['browse']; + $this->view->queryID = $queryID; $this->display(); } diff --git a/module/productplan/model.php b/module/productplan/model.php index 1b5e2d5487..be0161beef 100644 --- a/module/productplan/model.php +++ b/module/productplan/model.php @@ -3,7 +3,7 @@ * The model file of productplan module of ZenTaoPMS. * * @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology 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) + * @license ZPL (http://zpl.pub/page/zplv12.html) * @author Chunsheng Wang * @package productplan * @version $Id: model.php 4639 2013-04-11 02:06:35Z chencongzhi520@gmail.com $ @@ -75,17 +75,39 @@ class productplanModel extends model * @param object $pager * @param string $orderBy * @param string $param skipparent + * @param int $queryID * @access public * @return object */ - public function getList($product = 0, $branch = 0, $browseType = 'undone', $pager = null, $orderBy = 'begin_desc', $param = '') + public function getList($product = 0, $branch = 0, $browseType = 'undone', $pager = null, $orderBy = 'begin_desc', $param = '', $queryID = 0) { + if(!empty($queryID)) + { + $query = $this->loadModel('search')->getQuery($queryID); + if($query) + { + $this->session->set('productplanQuery', $query->sql); + $this->session->set('productplanForm', $query->form); + } + else + { + $this->session->set('productplanQuery', ' 1 = 1'); + } + } + else + { + if($this->session->productplanQuery == false) $this->session->set('productplanQuery', ' 1 = 1'); + } + + $productplanQuery = $this->session->productplanQuery; + $date = date('Y-m-d'); $plans = $this->dao->select('*')->from(TABLE_PRODUCTPLAN)->where('product')->eq($product) ->andWhere('deleted')->eq(0) ->beginIF(!empty($branch) and $branch != 'all')->andWhere('branch')->eq($branch)->fi() - ->beginIF(strpos(',all,undone,', ",$browseType,") === false)->andWhere('status')->eq($browseType)->fi() + ->beginIF(strpos(',all,undone,bySearch,', ",$browseType,") === false)->andWhere('status')->eq($browseType)->fi() ->beginIF($browseType == 'undone')->andWhere('status')->in('wait,doing')->fi() + ->beginIF($browseType == 'bySearch')->andWhere($productplanQuery)->fi() ->beginIF(strpos($param, 'skipparent') !== false)->andWhere('parent')->ne(-1)->fi() ->orderBy($orderBy) ->page($pager) @@ -1182,4 +1204,23 @@ class productplanModel extends model return $menu; } + + /** + * Build search form. + * + * @param int $queryID + * @param string $actionURL + * @param object $product + * @access public + * @return void + */ + public function buildSearchForm($queryID, $actionURL, $product) + { + $this->config->productplan->search['actionURL'] = $actionURL; + $this->config->productplan->search['queryID'] = $queryID; + + if($product->type != 'normal') $this->config->productplan->search['params']['branch']['values'] = array('' => '', '0' => $this->lang->branch->main) + $this->loadModel('branch')->getPairs($product->id, 'noempty'); + if($product->type == 'normal') unset($this->config->productplan->search['fields']['branch']); + $this->loadModel('search')->setSearchParams($this->config->productplan->search); + } } diff --git a/module/productplan/view/browsebylist.html.php b/module/productplan/view/browsebylist.html.php index 2667fce216..f399b26b96 100644 --- a/module/productplan/view/browsebylist.html.php +++ b/module/productplan/view/browsebylist.html.php @@ -19,6 +19,7 @@ name == $browseType ? 'btn-active-text' : '';?> inlink('browse', "productID=$productID&branch=&browseType={$menuItem->name}"), $label, '', "class='btn btn-link $active' id='{$menuItem->name}'");?> + searchAB;?>
@@ -30,6 +31,7 @@
+
@@ -44,7 +46,7 @@
id&branch=$branch")?>'>
kanbanspace->type;?>
- recTotal}&recPerPage={$pager->recPerPage}"; ?> + recTotal}&recPerPage={$pager->recPerPage}"; ?> - - - - - + show) continue; + + $width = ($field->width && $field->width != 'auto' ? $field->width . 'px' : 'auto'); + $required = strpos(",$field->rules,", ",$notEmptyRule->id,") !== false ? 'required' : ''; + echo ""; + } + } + ?>
diff --git a/module/project/model.php b/module/project/model.php index e46187d781..70d521562f 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -1582,13 +1582,18 @@ class projectModel extends model $oldProject = $this->getById($projectID, $type); $now = helper::now(); + $editorIdList = $this->config->project->editor->start['id']; + if($this->app->rawModule == 'program') $editorIdList = $this->config->program->editor->start['id']; + $project = fixer::input('post') ->add('id', $projectID) ->setDefault('status', 'doing') ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) + ->stripTags($editorIdList, $this->config->allowedTags) ->remove('comment')->get(); + $project = $this->loadModel('file')->processImgURL($project, $editorIdList, $this->post->uid); $this->dao->update(TABLE_PROJECT)->data($project) ->autoCheck() ->check($this->config->project->start->requiredFields, 'notempty') @@ -1640,15 +1645,20 @@ class projectModel extends model */ public function suspend($projectID) { + $editorIdList = $this->config->project->editor->suspend['id']; + if($this->app->rawModule == 'program') $editorIdList = $this->config->program->editor->suspend['id']; + $oldProject = $this->getById($projectID); - $project = fixer::input('post') + $project = fixer::input('post') ->add('id', $projectID) ->setDefault('status', 'suspended') ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', helper::now()) ->setDefault('suspendedDate', helper::today()) + ->stripTags($editorIdList, $this->config->allowedTags) ->remove('comment')->get(); + $project = $this->loadModel('file')->processImgURL($project, $editorIdList, $this->post->uid); $this->dao->update(TABLE_PROJECT)->data($project) ->autoCheck() ->checkFlow() @@ -1670,6 +1680,9 @@ class projectModel extends model $oldProject = $this->getById($projectID); $now = helper::now(); + $editorIdList = $this->config->project->editor->activate['id']; + if($this->app->rawModule == 'program') $editorIdList = $this->config->program->editor->activate['id']; + $project = fixer::input('post') ->add('id', $projectID) ->setDefault('realEnd','') @@ -1677,6 +1690,7 @@ class projectModel extends model ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) ->setIF($oldProject->realBegan == '0000-00-00', 'realBegan', helper::today()) + ->stripTags($editorIdList, $this->config->allowedTags) ->remove('comment,readjustTime,readjustTask') ->get(); @@ -1686,6 +1700,7 @@ class projectModel extends model unset($project->end); } + $project = $this->loadModel('file')->processImgURL($project, $editorIdList, $this->post->uid); $this->dao->update(TABLE_PROJECT)->data($project) ->autoCheck() ->checkFlow() @@ -1742,6 +1757,9 @@ class projectModel extends model $oldProject = $this->getById($projectID); $now = helper::now(); + $editorIdList = $this->config->project->editor->close['id']; + if($this->app->rawModule == 'program') $editorIdList = $this->config->program->editor->close['id']; + $project = fixer::input('post') ->add('id', $projectID) ->setDefault('status', 'closed') @@ -1749,11 +1767,14 @@ class projectModel extends model ->setDefault('closedDate', $now) ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) + ->stripTags($editorIdList, $this->config->allowedTags) ->remove('comment') ->get(); $this->lang->error->ge = $this->lang->project->ge; + $project = $this->loadModel('file')->processImgURL($project, $editorIdList, $this->post->uid); + $this->dao->update(TABLE_PROJECT)->data($project) ->autoCheck() ->check($this->config->project->close->requiredFields, 'notempty') diff --git a/module/story/model.php b/module/story/model.php index 4d755e19d9..010b5ac810 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -830,7 +830,6 @@ class storyModel extends model if(isset($story->stage) and $oldStory->stage != $story->stage) $story->stagedBy = (strpos('tested|verified|released|closed', $story->stage) !== false) ? $this->app->user->account : ''; $story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->edit['id'], $this->post->uid); - if(isset($_POST['reviewer'])) { $_POST['reviewer'] = array_filter($_POST['reviewer']); @@ -1327,6 +1326,7 @@ class storyModel extends model ->setDefault('lastEditedDate', $now) ->setDefault('status', $oldStory->status) ->setDefault('reviewedDate', $date) + ->stripTags($this->config->story->editor->review['id'], $this->config->allowedTags) ->setIF($this->post->result == 'revert', 'version', $this->post->preVersion) ->setIF($this->post->result == 'clarify', 'assignedTo', $oldStory->lastEditedBy ? $oldStory->lastEditedBy : $oldStory->openedBy) ->removeIF($this->post->result != 'reject', 'closedReason, duplicateStory, childStories') @@ -1336,6 +1336,7 @@ class storyModel extends model ->add('id', $storyID) ->remove('result,preVersion,comment') ->get(); + $story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->review['id'], $this->post->uid); /* Fix bug #671. */ $this->lang->story->closedReason = $this->lang->story->rejectedReason; @@ -1563,6 +1564,7 @@ class storyModel extends model ->setDefault('closedDate', $now) ->setDefault('closedBy', $this->app->user->account) ->setDefault('assignedDate', $now) + ->stripTags($this->config->story->editor->close['id'], $this->config->allowedTags) ->removeIF($this->post->closedReason != 'duplicate', 'duplicateStory') ->removeIF($this->post->closedReason != 'subdivided', 'childStories') ->get(); @@ -1578,6 +1580,7 @@ class storyModel extends model } $this->lang->story->comment = $this->lang->comment; + $story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->close['id'], $this->post->uid); $this->dao->update(TABLE_STORY)->data($story, 'comment') ->autoCheck() ->batchCheck($this->config->story->close->requiredFields, 'notempty') @@ -1991,9 +1994,11 @@ class storyModel extends model ->add('lastEditedBy', $this->app->user->account) ->add('lastEditedDate', $now) ->add('assignedDate', $now) + ->stripTags($this->config->story->editor->assignto['id'], $this->config->allowedTags) ->remove('comment') ->get(); + $story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->assignto['id'], $this->post->uid); $this->dao->update(TABLE_STORY)->data($story)->autoCheck()->checkFlow()->where('id')->eq((int)$storyID)->exec(); if(!dao::isError()) return common::createChanges($oldStory, $story); return false; @@ -2054,8 +2059,10 @@ class storyModel extends model ->setDefault('lastEditedDate', $now) ->setDefault('assignedDate', $now) ->setDefault('activatedDate', $now) + ->stripTags($this->config->story->editor->activate['id'], $this->config->allowedTags) ->remove('comment') ->get(); + $story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->activate['id'], $this->post->uid); $this->dao->update(TABLE_STORY)->data($story)->autoCheck()->checkFlow()->where('id')->eq($storyID)->exec(); if($this->post->status == 'active') $this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($storyID)->exec(); diff --git a/module/task/js/create.js b/module/task/js/create.js index 7dfed22038..ec3449172a 100644 --- a/module/task/js/create.js +++ b/module/task/js/create.js @@ -555,7 +555,7 @@ $('#modalTeam .btn').click(function() } else { - if(config.onlybody == 'yes') + if(config.onlybody == 'yes' && vision == 'lite') { $('.close').parent().click(); } diff --git a/module/task/model.php b/module/task/model.php index 8d295377cd..a434100c1d 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -113,7 +113,7 @@ class taskModel extends model } } - $task = $this->file->processImgURL($task, $this->config->task->editor->create['id'], $this->post->uid); + $task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->create['id'], $this->post->uid); /* Fix Bug #1525 */ $executionType = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($executionID)->fetch('type'); @@ -1465,6 +1465,7 @@ class taskModel extends model ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) ->setDefault('assignedDate', $now) + ->stripTags($this->config->task->editor->assignto['id'], $this->config->allowedTags) ->remove('comment,showModule') ->get(); if($oldTask->status != 'done' and $oldTask->status != 'closed' and isset($task->left) and $task->left == 0) @@ -1489,6 +1490,7 @@ class taskModel extends model if($oldTask->parent > 0) $this->updateParentStatus($taskID); + $task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->assignto['id'], $this->post->uid); $this->dao->update(TABLE_TASK) ->data($task) ->autoCheck() @@ -1525,6 +1527,8 @@ class taskModel extends model } if(dao::isError()) return false; + $editorIdList = $this->config->task->editor->start['id']; + if($this->app->getMethodName() == 'restart') $editorIdList = $this->config->task->editor->restart['id']; $now = helper::now(); $task = fixer::input('post') ->add('id', $taskID) @@ -1532,9 +1536,11 @@ class taskModel extends model ->setDefault('lastEditedDate', $now) ->setDefault('status', 'doing') ->setIF($oldTask->assignedTo != $this->app->user->account, 'assignedDate', $now) + ->stripTags($editorIdList, $this->config->allowedTags) ->removeIF(!empty($oldTask->team), 'consumed,left') ->remove('comment')->get(); + $task = $this->loadModel('file')->processImgURL($task, $editorIdList, $this->post->uid); if($this->post->left == 0) { if(isset($task->consumed) and $task->consumed == 0) @@ -1763,6 +1769,7 @@ class taskModel extends model ->setDefault('status', 'done') ->setDefault('finishedBy, lastEditedBy', $this->app->user->account) ->setDefault('finishedDate, lastEditedDate', $now) + ->stripTags($this->config->task->editor->finish['id'], $this->config->allowedTags) ->removeIF(!empty($oldTask->team), 'finishedBy,status,left') ->remove('comment,files,labels,currentConsumed') ->get(); @@ -1857,6 +1864,7 @@ class taskModel extends model if($task->finishedDate == substr($now, 0, 10)) $task->finishedDate = $now; + $task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->finish['id'], $this->post->uid); $this->dao->update(TABLE_TASK)->data($task) ->autoCheck() ->checkFlow() @@ -1896,9 +1904,11 @@ class taskModel extends model ->setDefault('status', 'pause') ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', helper::now()) + ->stripTags($this->config->task->editor->pause['id'], $this->config->allowedTags) ->remove('comment') ->get(); + $task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->pause['id'], $this->post->uid); $this->dao->update(TABLE_TASK)->data($task)->autoCheck()->checkFlow()->where('id')->eq((int)$taskID)->exec(); if($oldTask->parent > 0) $this->updateParentStatus($taskID); @@ -1932,12 +1942,14 @@ class taskModel extends model ->setDefault('assignedDate', $now) ->setDefault('closedBy, lastEditedBy', $this->app->user->account) ->setDefault('closedDate, lastEditedDate', $now) + ->stripTags($this->config->task->editor->close['id'], $this->config->allowedTags) ->setIF($oldTask->status == 'done', 'closedReason', 'done') ->setIF($oldTask->status == 'cancel', 'closedReason', 'cancel') ->remove('_recPerPage') ->remove('comment') ->get(); + $task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->close['id'], $this->post->uid); $this->dao->update(TABLE_TASK)->data($task)->autoCheck()->checkFlow()->where('id')->eq((int)$taskID)->exec(); if(!dao::isError()) @@ -1980,9 +1992,11 @@ class taskModel extends model ->setDefault('finishedDate', '0000-00-00') ->setDefault('canceledBy, lastEditedBy', $this->app->user->account) ->setDefault('canceledDate, lastEditedDate', $now) + ->stripTags($this->config->task->editor->cancel['id'], $this->config->allowedTags) ->remove('comment') ->get(); + $task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->cancel['id'], $this->post->uid); $this->dao->update(TABLE_TASK)->data($task)->autoCheck()->checkFlow()->where('id')->eq((int)$taskID)->exec(); if($oldTask->fromBug) $this->dao->update(TABLE_BUG)->set('toTask')->eq(0)->where('id')->eq($oldTask->fromBug)->exec(); if($oldTask->parent > 0) $this->updateParentStatus($taskID); @@ -2044,6 +2058,7 @@ class taskModel extends model ->setDefault('lastEditedDate', helper::now()) ->setDefault('assignedDate', helper::now()) ->setDefault('activatedDate', helper::now()) + ->stripTags($this->config->task->editor->activate['id'], $this->config->allowedTags) ->remove('comment') ->get(); @@ -2064,6 +2079,7 @@ class taskModel extends model $task = $this->computeHours4Multiple($oldTask, $task); } + $task = $this->loadModel('file')->processImgURL($task, $this->config->task->editor->activate['id'], $this->post->uid); $this->dao->update(TABLE_TASK)->data($task) ->autoCheck() ->batchCheck($this->config->task->activate->requiredFields, 'notempty') diff --git a/module/task/view/create.html.php b/module/task/view/create.html.php index 02035da732..6985557d0f 100644 --- a/module/task/view/create.html.php +++ b/module/task/view/create.html.php @@ -16,6 +16,7 @@ id));?> task->error->teamMember);?> +vision);?> diff --git a/module/testcase/model.php b/module/testcase/model.php index e66df373fa..bf16af9520 100644 --- a/module/testcase/model.php +++ b/module/testcase/model.php @@ -61,6 +61,7 @@ class testcaseModel extends model ->setIF($this->config->systemMode == 'new' and $this->app->tab == 'project', 'project', $this->session->project) ->setIF($this->app->tab == 'execution', 'execution', $this->session->execution) ->setIF($this->post->story != false, 'storyVersion', $this->loadModel('story')->getVersion((int)$this->post->story)) + ->stripTags($this->config->testcase->editor->create['id'], $this->config->allowedTags) ->remove('steps,expects,files,labels,stepType,forceNotReview') ->setDefault('story', 0) ->cleanInt('story,product,branch,module') @@ -77,6 +78,7 @@ class testcaseModel extends model /* Value of story may be showmore. */ $case->story = (int)$case->story; + $case = $this->loadModel('file')->processImgURL($case, $this->config->testcase->editor->create['id'], $this->post->uid); $this->dao->insert(TABLE_CASE)->data($case)->autoCheck()->batchCheck($this->config->testcase->create->requiredFields, 'notempty')->checkFlow()->exec(); if(!$this->dao->isError()) { @@ -607,7 +609,7 @@ class testcaseModel extends model */ public function getByAssignedTo($account, $orderBy = 'id_desc', $pager = null, $auto = 'no') { - return $this->dao->select('t1.*,t2.project,t2.pri,t2.title,t2.type,t2.openedBy,t2.color,t2.product,t2.branch,t2.module,t2.status,t3.name as taskName')->from(TABLE_TESTRUN)->alias('t1') + return $this->dao->select('t1.task,t1.case,t1.version,t1.assignedTo,t1.lastRunner,t1.lastRunDate,t1.lastRunResult,t1.status,t2.id as id,t2.project,t2.pri,t2.title,t2.type,t2.openedBy,t2.color,t2.product,t2.branch,t2.module,t2.status,t3.name as taskName')->from(TABLE_TESTRUN)->alias('t1') ->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id') ->leftJoin(TABLE_TESTTASK)->alias('t3')->on('t1.task = t3.id') ->where('t1.assignedTo')->eq($account) @@ -768,6 +770,7 @@ class testcaseModel extends model ->join('linkCase', ',') ->setForce('status', $status) ->cleanInt('story,product,branch,module') + ->stripTags($this->config->testcase->editor->edit['id'], $this->config->allowedTags) ->remove('comment,steps,expects,files,labels,stepType') ->get(); @@ -780,6 +783,7 @@ class testcaseModel extends model array_splice($requiredFieldsArr, $fieldIndex, 1); $requiredFields = implode(',', $requiredFieldsArr); } + $case = $this->loadModel('file')->processImgURL($case, $this->config->testcase->editor->edit['id'], $this->post->uid); $this->dao->update(TABLE_CASE)->data($case)->autoCheck()->batchCheck($requiredFields, 'notempty')->checkFlow()->where('id')->eq((int)$caseID)->exec(); if(!$this->dao->isError()) { @@ -883,10 +887,12 @@ class testcaseModel extends model ->setDefault('reviewedDate', substr($now, 0, 10)) ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) + ->stripTags($this->config->testcase->editor->review['id'], $this->config->allowedTags) ->setForce('status', $status) ->join('reviewedBy', ',') ->get(); + $case = $this->loadModel('file')->processImgURL($case, $this->config->testcase->editor->review['id'], $this->post->uid); $this->dao->update(TABLE_CASE)->data($case)->autoCheck()->checkFlow()->where('id')->eq($caseID)->exec(); if(dao::isError()) return false; @@ -1268,11 +1274,26 @@ class testcaseModel extends model ->fetchGroup('case'); $oldCases = $this->dao->select('*')->from(TABLE_CASE)->where('id')->in($_POST['id'])->fetchAll('id'); } + + $cases = array(); + $line = 1; + $fieldNames = array(); $storyVersionPairs = $this->story->getVersions($data->story); - $cases = array(); - $line = 1; - $fieldNames = array(); + if($this->config->edition != 'open') + { + $extendFields = $this->getFlowExtendFields(); + $notEmptyRule = $this->loadModel('workflowrule')->getByTypeAndRule('system', 'notempty'); + + foreach($extendFields as $extendField) + { + if(strpos(",$extendField->rules,", ",$notEmptyRule->id,") !== false) + { + $this->config->testcase->create->requiredFields .= ',' . $extendField->field; + } + } + } + foreach($data->product as $key => $product) { $caseData = new stdclass(); @@ -1289,6 +1310,18 @@ class testcaseModel extends model $caseData->frequency = 1; $caseData->precondition = $data->precondition[$key]; + if($this->config->edition != 'open') + { + foreach($extendFields as $extendField) + { + $dataArray = $_POST[$extendField->field]; + $caseData->{$extendField->field} = $dataArray[$key]; + if(is_array($caseData->{$extendField->field})) $caseData->{$extendField->field} = join(',', $caseData->{$extendField->field}); + + $caseData->{$extendField->field} = htmlSpecialString($caseData->{$extendField->field}); + } + } + if(isset($this->config->testcase->create->requiredFields)) { $requiredFields = explode(',', $this->config->testcase->create->requiredFields); @@ -1300,16 +1333,6 @@ class testcaseModel extends model } } - if(isset($this->config->testcase->appendFields)) - { - foreach(explode(',', $this->config->testcase->appendFields) as $appendField) - { - if(empty($appendField)) continue; - $caseData->$appendField = zget($_POST[$appendField], $key, ''); - if(is_array($caseData->$appendField)) $caseData->$appendField = join(',', $caseData->$appendField); - } - } - $cases[$key] = $caseData; $line++; } @@ -1382,34 +1405,38 @@ class testcaseModel extends model $caseData->lastEditedBy = $this->app->user->account; $caseData->lastEditedDate = $now; if($stepChanged and !$forceNotReview) $caseData->status = 'wait'; - $this->dao->update(TABLE_CASE)->data($caseData)->where('id')->eq($caseID)->autoCheck()->exec(); - if($stepChanged) + $this->dao->update(TABLE_CASE)->data($caseData)->where('id')->eq($caseID)->autoCheck()->checkFlow()->exec(); + + if(!dao::isError()) { - $parentStepID = 0; - foreach($steps as $id => $step) + if($stepChanged) { - $step = (array)$step; - if(empty($step['desc'])) continue; - $stepData = new stdclass(); - $stepData->type = ($step['type'] == 'item' and $parentStepID == 0) ? 'step' : $step['type']; - $stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0; - $stepData->case = $caseID; - $stepData->version = $version; - $stepData->desc = $step['desc']; - $stepData->expect = $step['expect']; - $this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec(); - if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID(); - if($stepData->type == 'step') $parentStepID = 0; + $parentStepID = 0; + foreach($steps as $id => $step) + { + $step = (array)$step; + if(empty($step['desc'])) continue; + $stepData = new stdclass(); + $stepData->type = ($step['type'] == 'item' and $parentStepID == 0) ? 'step' : $step['type']; + $stepData->parent = ($stepData->type == 'item') ? $parentStepID : 0; + $stepData->case = $caseID; + $stepData->version = $version; + $stepData->desc = $step['desc']; + $stepData->expect = $step['expect']; + $this->dao->insert(TABLE_CASESTEP)->data($stepData)->autoCheck()->exec(); + if($stepData->type == 'group') $parentStepID = $this->dao->lastInsertID(); + if($stepData->type == 'step') $parentStepID = 0; + } } + $oldCase->steps = $this->joinStep($oldStep); + $caseData->steps = $this->joinStep($steps); + $changes = common::createChanges($oldCase, $caseData); + + $this->updateCase2Project($oldCase, $caseData, $caseID); + + $actionID = $this->action->create('case', $caseID, 'Edited'); + $this->action->logHistory($actionID, $changes); } - $oldCase->steps = $this->joinStep($oldStep); - $caseData->steps = $this->joinStep($steps); - $changes = common::createChanges($oldCase, $caseData); - - $this->updateCase2Project($oldCase, $caseData, $caseID); - - $actionID = $this->action->create('case', $caseID, 'Edited'); - $this->action->logHistory($actionID, $changes); } } else @@ -1421,7 +1448,7 @@ class testcaseModel extends model $caseData->branch = isset($data->branch[$key]) ? $data->branch[$key] : $branch; if($caseData->story) $caseData->storyVersion = zget($storyVersionPairs, $caseData->story, 1); $caseData->status = !$forceNotReview ? 'wait' : 'normal'; - $this->dao->insert(TABLE_CASE)->data($caseData)->autoCheck()->exec(); + $this->dao->insert(TABLE_CASE)->data($caseData)->autoCheck()->checkFlow()->exec(); if(!dao::isError()) { @@ -2123,7 +2150,13 @@ class testcaseModel extends model if(!$case->needconfirm) { - if(!isonlybody()) $menu .= $this->buildMenu('testcase', 'edit', $params, $case, 'view', '', '', 'showinonlybody'); + if(!isonlybody()) + { + $editParams = $params; + if($this->app->tab == 'project') $editParams .= "&comment=false&projectID={$this->session->project}"; + if($this->app->tab == 'execution') $editParams .= "&comment=false&executionID={$this->session->execution}"; + $menu .= $this->buildMenu('testcase', 'edit', $editParams, $case, 'view', '', '', 'showinonlybody'); + } if(!$case->isLibCase && $case->auto != 'unit') { $menu .= $this->buildMenu('testcase', 'create', "productID=$case->product&branch=$case->branch&moduleID=$case->module&from=testcase¶m=$case->id", $case, 'view', 'copy'); @@ -2161,7 +2194,12 @@ class testcaseModel extends model $menu .= $this->buildMenu('testtask', 'results', "runID=0&$params", $case, 'browse', '', '', 'iframe', true, "data-width='95%'"); $menu .= $this->buildMenu('testtask', 'runCase', "runID=0&$params&version=$case->version", $case, 'browse', 'play', '', 'runCase iframe', false, "data-width='95%'"); - $menu .= $this->buildMenu('testcase', 'edit', "caseID=$case->id", $case, 'browse'); + + $editParams = $params; + if($this->app->tab == 'project') $editParams .= "&comment=false&projectID={$this->session->project}"; + if($this->app->tab == 'execution') $editParams .= "&comment=false&executionID={$this->session->execution}"; + $menu .= $this->buildMenu('testcase', 'edit', $editParams, $case, 'browse'); + if($this->config->testcase->needReview || !empty($this->config->testcase->forceReview)) { common::printIcon('testcase', 'review', $params, $case, 'browse', 'glasses', '', 'iframe'); diff --git a/module/testcase/view/showimport.html.php b/module/testcase/view/showimport.html.php index 0a66864f54..44d00ea281 100644 --- a/module/testcase/view/showimport.html.php +++ b/module/testcase/view/showimport.html.php @@ -45,11 +45,19 @@ $(function() '>testcase->stage?> '>testcase->precondition?> '>testcase->keywords?>testcase->{$appendField->field}?>$field->name @@ -106,12 +114,18 @@ $(function() - - loadModel('flow');?> - - - - + loadModel('flow'); + foreach($appendFields as $field) + { + if(!$field->show) continue; + $value = $field->defaultValue ? $field->defaultValue : zget($case, $field->field, ''); + echo ''; + } + } + ?>
testcase->stageList, !empty($case->stage) ? $case->stage : ((!empty($case->id) and isset($cases[$case->id])) ? $cases[$case->id]->stage : ''), "multiple='multiple' class='form-control chosen'")?> precondition) ? htmlSpecialString($case->precondition) : "", "class='form-control'")?> keywords) ? $case->keywords : '', "class='form-control'")?>flow->buildControl($appendField, zget($case, $appendField->field, ''), "{$appendField->field}[$key]");?>' . $this->flow->buildControl($field, $value, "$field->field[$key]", true) . ' diff --git a/module/testtask/model.php b/module/testtask/model.php index af7c0c6b1c..b5930503f2 100644 --- a/module/testtask/model.php +++ b/module/testtask/model.php @@ -772,8 +772,10 @@ class testtaskModel extends model $testtask = fixer::input('post') ->add('id', $taskID) ->setDefault('status', 'doing') + ->stripTags($this->config->testtask->editor->start['id'], $this->config->allowedTags) ->remove('comment')->get(); + $testtask = $this->loadModel('file')->processImgURL($testtask, $this->config->testtask->editor->start['id'], $this->post->uid); $this->dao->update(TABLE_TESTTASK)->data($testtask) ->autoCheck() ->checkFlow() @@ -838,8 +840,10 @@ class testtaskModel extends model $testtask = fixer::input('post') ->add('id', $taskID) ->setDefault('status', 'blocked') + ->stripTags($this->config->testtask->editor->block['id'], $this->config->allowedTags) ->remove('comment')->get(); + $testtask = $this->loadModel('file')->processImgURL($testtask, $this->config->testtask->editor->block['id'], $this->post->uid); $this->dao->update(TABLE_TESTTASK)->data($testtask) ->autoCheck() ->checkFlow() @@ -861,8 +865,10 @@ class testtaskModel extends model $oldTesttask = $this->getById($taskID); $testtask = fixer::input('post') ->setDefault('status', 'doing') + ->stripTags($this->config->testtask->editor->activate['id'], $this->config->allowedTags) ->remove('comment')->get(); + $testtask = $this->loadModel('file')->processImgURL($testtask, $this->config->testtask->editor->activate['id'], $this->post->uid); $this->dao->update(TABLE_TESTTASK)->data($testtask) ->autoCheck() ->checkFlow() diff --git a/module/tree/control.php b/module/tree/control.php index 3c34f12db0..b88676aeef 100644 --- a/module/tree/control.php +++ b/module/tree/control.php @@ -229,6 +229,49 @@ class tree extends control $title = $this->lang->tree->manageTrainpost; $position[] = $this->lang->tree->manageTrainpost; } + elseif(strpos($viewType, 'datasource') !== false) + { + $params = explode('_', $viewType); + if(count($params) == 2) + { + $datasourceID = $params[1]; + $manageChild = 'manage' . ucfirst($viewType) . 'Child'; + $datasource = $this->loadModel('workflowdatasource', 'flow')->getByID($datasourceID); + if($datasource) + { + $this->app->rawModule = 'workflowdatasource'; + + $title = $datasource->name; + $position[] = $datasource->name; + + $this->lang->tree->$manageChild = $title; + + $root = new stdclass(); + $root->name = $title; + $this->view->root = $root; + } + } + } + /* viewType is workflow building category. */ + else if(strpos($viewType, '_') !== false) + { + $params = explode('_', $viewType); + if(count($params) == 2) + { + $this->app->rawModule = $params[0]; + + $manageChild = 'manage' . ucfirst($viewType) . 'Child'; + + $title = $this->lang->tree->common; + $position[] = $this->lang->tree->common; + + $this->lang->tree->$manageChild = $title; + + $root = new stdclass(); + $root->name = $title; + $this->view->root = $root; + } + } $parentModules = $this->tree->getParents($currentModuleID); $this->view->title = $title; diff --git a/module/user/control.php b/module/user/control.php index ad3c48a31e..da51d999e6 100755 --- a/module/user/control.php +++ b/module/user/control.php @@ -1187,19 +1187,21 @@ class user extends control * @param int $contactListID * @param string $dropdownName mailto|whitelist * @param string $oldUsers + * @param string $extra * @access public * @return string */ - public function ajaxGetContactUsers($contactListID, $dropdownName = 'mailto', $oldUsers = '') + public function ajaxGetContactUsers($contactListID, $dropdownName = 'mailto', $oldUsers = '', $extra = '') { $list = $contactListID ? $this->user->getContactListByID($contactListID) : ''; - $attr = $dropdownName == 'mailto' ? "data-placeholder='{$this->lang->chooseUsersToMail}'" : ''; $users = $this->user->getPairs('devfirst|nodeleted|noclosed', $list ? $list->userList : '', $this->config->maxCount); + if(!empty($extra) && $extra == 'flow') $users = array_merge(array('deptManager' => $this->lang->workflowdatasource->options['deptManager']), $users); if(isset($this->config->user->moreLink)) $this->config->moreLinks[$dropdownName . "[]"] = $this->config->user->moreLink; $defaultUsers = empty($contactListID) ? '' : $list->userList . ',' . trim($oldUsers); + if($extra == 'flow' && empty($defaultUsers)) $defaultUsers = trim($oldUsers); return print(html::select($dropdownName . "[]", $users, $defaultUsers, "class='form-control chosen' multiple $attr")); } diff --git a/tools/packDeb.php b/tools/packDeb.php index b38b578ff3..25545d2555 100644 --- a/tools/packDeb.php +++ b/tools/packDeb.php @@ -54,7 +54,7 @@ foreach(array('zh-cn', 'en') as $langType) $command .= "sed -i 's/index.php/\/zentao\/index.php/' zentao/www/.htaccess\n"; $command .= "cd ../../\n"; - $command .= "sudo dpkg -b buildroot/ {$packPrefix}_{$version}_php{$phpVersion}_1_all.deb\n"; + $command .= "sudo dpkg -b buildroot/ {$packPrefix}.{$version}.php{$phpVersion}.1.all.deb\n"; $command .= "mv *.deb ../../\n"; $command .= "rm -rf buildroot\n"; diff --git a/tools/packRpm.php b/tools/packRpm.php index 66d40ceb6f..349b307df6 100644 --- a/tools/packRpm.php +++ b/tools/packRpm.php @@ -60,9 +60,7 @@ foreach(array('zh-cn', 'en') as $langType) $command .= "cd ../../\n"; $command .= "rpmbuild --define \"_topdir \${PWD}/rpmbuild\" -ba rpmbuild/SPECS/zentaopms.spec\n"; - $command .= "cp rpmbuild/RPMS/noarch/$dirName-$version-1.noarch.rpm ./{$dirName}-{$version}-php{$phpVersion}-1.noarch.rpm\n"; - - $command .= "mv {$dirName}-{$version}-php{$phpVersion}-1.noarch.rpm ../../\n"; + $command .= "cp rpmbuild/RPMS/noarch/$dirName-$version-1.noarch.rpm ../../{$packPrefix}.{$version}.php{$phpVersion}.1.noarch.rpm\n"; $command .= "rm -rf rpmbuild\n"; diff --git a/www/theme/default/style.css b/www/theme/default/style.css index 42c66c6689..0263440d76 100644 --- a/www/theme/default/style.css +++ b/www/theme/default/style.css @@ -91,3 +91,4 @@ a.showMoreImage:hover {opacity: 1;} #headerActions .dropdown-menu:before, #headerActions .dropdown-menu:hover:before {position: absolute; top: -9px; right: 50%; width: 0; height: 0; content: ' '; border-color: transparent transparent #fff transparent; border-style: solid; border-width: 0 10px 10px 10px;} .icon-size-width:before {content: "\e9c5"; transform: rotate(90deg); -ms-transform: rotate(90deg); -moz-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg);} +.checkbox-primary > label{overflow: hidden;}