diff --git a/config/zentaopms.php b/config/zentaopms.php index 11edd730be..153ddb5044 100644 --- a/config/zentaopms.php +++ b/config/zentaopms.php @@ -205,6 +205,7 @@ $config->openMethods[] = 'sso.logout'; $config->openMethods[] = 'sso.bind'; $config->openMethods[] = 'sso.gettodolist'; $config->openMethods[] = 'file.read'; +$config->openMethods[] = 'file.buildoldform'; $config->openMethods[] = 'index.changelog'; $config->openMethods[] = 'my.preference'; $config->openMethods[] = 'my.changepassword'; @@ -247,6 +248,8 @@ $config->openMethods[] = 'testcase.savexmindimport'; $config->openMethods[] = 'search.buildzinform'; $config->openMethods[] = 'search.buildzinquery'; $config->openMethods[] = 'search.savezinquery'; +$config->openMethods[] = 'search.buildoldform'; +$config->openMethods[] = 'search.saveoldquery'; $config->openMethods[] = 'space.createapplication'; $config->openMethods[] = 'ai.adminindex'; $config->openMethods[] = 'sonarqube.create'; diff --git a/module/file/control.php b/module/file/control.php index 4f449532e5..383279f131 100755 --- a/module/file/control.php +++ b/module/file/control.php @@ -32,6 +32,16 @@ class file extends control $this->display(); } + /** + * Build the old upload form. + * + * @param int $fileCount + * @param float $percent + * @param string $filesName + * @param string $labelsName + * @access public + * @return void + */ public function buildOldForm(int $fileCount = 1, float $percent = 0.9, string $filesName = "files", string $labelsName = "labels") { if(!file_exists($this->file->savePath)) return printf($this->lang->file->errorNotExists, $this->file->savePath); diff --git a/module/search/config.php b/module/search/config.php index bba9406de1..25cec98dc3 100644 --- a/module/search/config.php +++ b/module/search/config.php @@ -159,6 +159,8 @@ $config->search->recPerPage = 10; $config->search->summaryLength = 120; $config->search->maxFileSize = 1024; +$config->search->oldQuery = array('issue'); + if($config->vision == 'rnd') { $config->search->searchObject = array('trash', 'productlibDoc', 'productapiDoc', 'projectlibDoc', 'projectapiDoc'); diff --git a/module/search/control.php b/module/search/control.php index 803e2df017..f58ead65d3 100644 --- a/module/search/control.php +++ b/module/search/control.php @@ -64,6 +64,56 @@ class search extends control $this->display(); } + /** + * 构建旧页面搜索表单。 + * Build old search form. + * + * @param string $module + * @param string $fields + * @param array $params + * @param string $actionURL + * @param int $queryID + * @param string $formName + * @access public + * @return void + */ + public function buildOldForm(string $module = '', string $fields = '', string $params = '', string $actionURL = '', int $queryID = 0, string $formName = '') + { + $module = empty($module) ? $this->session->searchParams['module'] : $module; + $searchParams = $module . 'searchParams'; + $searchForm = $module . 'Form'; + + $fields = empty($fields) ? json_decode($_SESSION[$searchParams]['searchFields'], true) : $fields; + $params = empty($params) ? json_decode($_SESSION[$searchParams]['fieldParams'], true) : $params; + + $_SESSION['searchParams']['module'] = $module; + if(empty($_SESSION[$searchForm])) $this->search->initOldSession($module, $fields, $params); + + if(in_array($module, $this->config->search->searchObject) && $this->session->objectName) + { + $space = common::checkNotCN() ? ' ' : ''; + $this->lang->search->common = $this->lang->search->common . $space . $this->session->objectName; + } + + $this->view->module = $module; + $this->view->groupItems = $this->config->search->groupItems; + $this->view->actionURL = empty($actionURL) ? $_SESSION[$searchParams]['actionURL'] : $actionURL; + $this->view->searchFields = $fields; + $this->view->fields = $fields; + $this->view->fieldParams = $this->searchZen->setDefaultParams($fields, $params); + $this->view->queries = $this->search->getQueryList($module); + $this->view->queryID = (empty($module) && empty($queryID)) ? $_SESSION[$searchParams]['queryID'] : $queryID; + $this->view->style = !empty($_SESSION[$searchParams]['style']) ? $_SESSION[$searchParams]['style'] : 'full'; + $this->view->onMenuBar = !empty($_SESSION[$searchParams]['onMenuBar']) ? $_SESSION[$searchParams]['onMenuBar'] : 'no'; + $this->view->formSession = $_SESSION[$module . 'Form']; + $this->view->formName = $formName; + + if($module == 'program') $this->view->options = $this->searchZen->setOptions($fields, $this->view->fieldParams, $this->view->queries); + + $this->app->loadModuleConfig('action'); + $this->display(); + } + /** * 构建搜索查询。 * Build search query. @@ -102,6 +152,35 @@ class search extends control return print(json_encode(array('result' => 'success', 'load' => $actionURL))); } + /** + * Build query + * + * @access public + * @return void + */ + public function buildOldQuery() + { + $this->search->buildOldQuery(); + + $actionURL = $this->post->actionURL; + $parsedURL = parse_url($actionURL); + if(isset($parsedURL['host'])) return; + if($this->config->requestType != 'GET') + { + $path = $parsedURL['path']; + $path = str_replace($this->config->webRoot, '', $path); + if(strpos($path, '.') !== false) $path = substr($path, 0, strpos($path, '.')); + if(preg_match("/^\w+{$this->config->requestFix}\w+/", $path) == 0) return; + } + else + { + $query = $parsedURL['query']; + if(preg_match("/^{$this->config->moduleVar}=\w+\&{$this->config->methodVar}=\w+/", $query) == 0) return; + } + + echo js::locate($actionURL, 'parent'); + } + /** * 保存搜索查询。 * Save search query. @@ -133,6 +212,32 @@ class search extends control $this->display(); } + /** + * Save old search query. + * + * @param string $module + * @param string $onMenuBar + * @access public + * @return void + */ + public function saveOldQuery(string $module, string $onMenuBar = 'no') + { + if($_POST) + { + $queryID = $this->search->saveQuery(); + if(!$queryID) return print(js::error(dao::getError())); + + $data = fixer::input('post')->get(); + $shortcut = empty($data->onMenuBar) ? 0 : 1; + + return print(js::closeModal('parent.parent', '', "function(){parent.parent.loadQueries($queryID, $shortcut, '{$data->title}')}")); + } + + $this->view->module = $module; + $this->view->onMenuBar = $onMenuBar; + $this->display(); + } + /** * 删除搜索查询。 * Delete current search query. @@ -148,6 +253,29 @@ class search extends control return $this->send(array('result' => 'success', 'load' => true)); } + /** + * Ajax get search query. + * + * @param string $module + * @param int $queryID + * @access public + * @return void + */ + public function ajaxGetQuery($module = '', $queryID = 0) + { + $query = $queryID ? $queryID : ''; + $module = empty($module) ? $this->session->searchParams['module'] : $module; + $queries = $this->search->getQueryList($module); + $html = ''; + foreach($queries as $query) + { + if(empty($query->id)) continue; + + $html .= '
  • ' . html::a("javascript:executeQuery({$query->id})", $query->title . ((common::hasPriv('search', 'deleteQuery') and $this->app->user->account == $query->account) ? '' : ''), '', "class='label user-query' data-query-id='$query->id' title='{$query->title}'") . '
  • '; + } + echo $html; + } + /** * 删除搜索查询菜单。 * Ajax remove from menu. diff --git a/module/search/model.php b/module/search/model.php index a194c159c8..dd13f62382 100644 --- a/module/search/model.php +++ b/module/search/model.php @@ -101,6 +101,153 @@ class searchModel extends model if($scoreNum > 2 && !dao::isError()) $this->loadModel('score')->create('search', 'saveQueryAdvanced'); } + /** + * Build the query to execute. + * + * @access public + * @return void + */ + public function buildOldQuery() + { + /* Init vars. */ + $where = ''; + $groupItems = $this->config->search->groupItems; + $groupAndOr = strtoupper($this->post->groupAndOr); + $module = $this->session->searchParams['module']; + $searchParams = $module . 'searchParams'; + $fieldParams = json_decode($_SESSION[$searchParams]['fieldParams']); + $scoreNum = 0; + + if($groupAndOr != 'AND' and $groupAndOr != 'OR') $groupAndOr = 'AND'; + + for($i = 1; $i <= $groupItems * 2; $i ++) + { + /* The and or between two groups. */ + if($i == 1) $where .= '(( 1 '; + if($i == $groupItems + 1) $where .= " ) $groupAndOr ( 1 "; + + /* Set var names. */ + $fieldName = "field$i"; + $andOrName = "andOr$i"; + $operatorName = "operator$i"; + $valueName = "value$i"; + + /* Fix bug #2704. */ + $field = $this->post->$fieldName; + if(isset($fieldParams->$field) and $fieldParams->$field->control == 'input' and $this->post->$valueName === '0') $this->post->$valueName = 'ZERO'; + if($field == 'id' and $this->post->$valueName === '0') $this->post->$valueName = 'ZERO'; + + /* Skip empty values. */ + if($this->post->$valueName == false) continue; + if($this->post->$valueName == 'ZERO') $this->post->$valueName = 0; // ZERO is special, stands to 0. + if(isset($fieldParams->$field) and $fieldParams->$field->control == 'select' and $this->post->$valueName === 'null') $this->post->$valueName = ''; // Null is special, stands to empty if control is select. Fix bug #3279. + + $scoreNum += 1; + + /* Set and or. */ + $andOr = strtoupper($this->post->$andOrName); + if($andOr != 'AND' and $andOr != 'OR') $andOr = 'AND'; + + /* Set operator. */ + $value = addcslashes(trim($this->post->$valueName), '%'); + $operator = $this->post->$operatorName; + if(!isset($this->lang->search->operators[$operator])) $operator = '='; + + /* Set condition. */ + $condition = ''; + if($operator == "include") + { + if($this->post->$fieldName == 'module') + { + $allModules = $this->loadModel('tree')->getAllChildId($value); + if($allModules) $condition = helper::dbIN($allModules); + } + else + { + $condition = ' LIKE ' . $this->dbh->quote("%$value%"); + } + } + elseif($operator == "notinclude") + { + if($this->post->$fieldName == 'module') + { + $allModules = $this->loadModel('tree')->getAllChildId($value); + if($allModules) $condition = " NOT " . helper::dbIN($allModules); + } + else + { + $condition = ' NOT LIKE ' . $this->dbh->quote("%$value%"); + } + } + elseif($operator == 'belong') + { + if($this->post->$fieldName == 'module') + { + $allModules = $this->loadModel('tree')->getAllChildId($value); + if($allModules) $condition = helper::dbIN($allModules); + } + elseif($this->post->$fieldName == 'dept') + { + $allDepts = $this->loadModel('dept')->getAllChildId($value); + $condition = helper::dbIN($allDepts); + } + else + { + $condition = ' = ' . $this->dbh->quote($value) . ' '; + } + } + else + { + if($operator == 'between' and !isset($this->config->search->dynamic[$value])) $operator = '='; + $condition = $operator . ' ' . $this->dbh->quote($value) . ' '; + + if($operator == '=' and $this->post->$fieldName == 'id' and preg_match('/^[0-9]+(,[0-9]*)+$/', $value) and !preg_match('/[\x7f-\xff]+/', $value)) + { + $values = array_filter(explode(',', trim($this->dbh->quote($value), "'"))); + foreach($values as $value) $value = "'" . $value . "'"; + + $value = implode(',', $values); + $operator = 'IN'; + $condition = $operator . ' (' . $value . ') '; + } + } + + /* Processing query criteria. */ + if($operator == '=' and preg_match('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/', $value)) + { + $condition = '`' . $this->post->$fieldName . "` >= '$value' AND `" . $this->post->$fieldName . "` <= '$value 23:59:59'"; + $where .= " $andOr ($condition)"; + } + elseif($operator == '!=' and preg_match('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/', $value)) + { + $condition = '`' . $this->post->$fieldName . "` < '$value' OR `" . $this->post->$fieldName . "` > '$value 23:59:59'"; + $where .= " $andOr ($condition)"; + } + elseif($operator == '<=' and preg_match('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/', $value)) + { + $where .= " $andOr " . '`' . $this->post->$fieldName . "` <= '$value 23:59:59'"; + } + elseif($operator == '>' and preg_match('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/', $value)) + { + $where .= " $andOr " . '`' . $this->post->$fieldName . "` > '$value 23:59:59'"; + } + elseif($condition) + { + $where .= " $andOr " . '`' . $this->post->$fieldName . '` ' . $condition; + } + } + + $where .=" ))"; + $where = $this->replaceDynamic($where); + + /* Save to session. */ + $querySessionName = $this->post->module . 'Query'; + $formSessionName = $this->post->module . 'Form'; + $this->session->set($querySessionName, $where); + $this->session->set($formSessionName, $_POST); + if($scoreNum > 2 && !dao::isError()) $this->loadModel('score')->create('search', 'saveQueryAdvanced'); + } + /** * 获取查询。 * Get a query. @@ -114,6 +261,8 @@ class searchModel extends model $query = $this->dao->findByID($queryID)->from(TABLE_USERQUERY)->fetch(); if(!$query) return false; + if(in_array($query->module, $this->config->search->oldQuery)) return $this->getOldQuery($queryID); + /* Decode html encode. */ $query->form = htmlspecialchars_decode($query->form, ENT_QUOTES); $query->sql = htmlspecialchars_decode($query->sql, ENT_QUOTES); @@ -155,6 +304,35 @@ class searchModel extends model return $query; } + /** + * Get a query. + * + * @param int $queryID + * @access public + * @return object + */ + public function getOldQuery(int $queryID) + { + $query = $this->dao->findByID($queryID)->from(TABLE_USERQUERY)->fetch(); + if(!$query) return false; + + /* Decode html encode. */ + $query->form = htmlspecialchars_decode($query->form, ENT_QUOTES); + $query->sql = htmlspecialchars_decode($query->sql, ENT_QUOTES); + + $hasDynamic = strpos($query->form, '$') !== false; + $query->form = unserialize($query->form); + if($hasDynamic) + { + $_POST = $query->form; + $this->buildQuery(); + $querySessionName = $query->form['module'] . 'Query'; + $query->sql = $_SESSION[$querySessionName]; + } + return $query; + } + + /** * 将搜索条件保存到session中。 * Save query to session. diff --git a/module/search/tao.php b/module/search/tao.php index 98ba20421e..721611149c 100644 --- a/module/search/tao.php +++ b/module/search/tao.php @@ -101,6 +101,42 @@ class searchTao extends searchModel return $queryForm; } + /** + * Init the old search session for the first time search. + * + * @param string $module + * @param array $fields + * @param array $fieldParams + * @access public + * @return void + */ + public function initOldSession(string $module, array $fields, array $fieldParams) + { + $formSessionName = $module . 'Form'; + if(isset($_SESSION[$formSessionName]) and $_SESSION[$formSessionName] != false) return; + + for($i = 1; $i <= $this->config->search->groupItems * 2; $i ++) + { + /* Var names. */ + $fieldName = "field$i"; + $andOrName = "andOr$i"; + $operatorName = "operator$i"; + $valueName = "value$i"; + + $currentField = key($fields); + $operator = isset($fieldParams[$currentField]['operator']) ? $fieldParams[$currentField]['operator'] : '='; + + $queryForm[$fieldName] = key($fields); + $queryForm[$andOrName] = 'and'; + $queryForm[$operatorName] = $operator; + $queryForm[$valueName] = ''; + + if(!next($fields)) reset($fields); + } + $queryForm['groupAndOr'] = 'and'; + $this->session->set($formSessionName, $queryForm); + } + /** * 处理查询表单的相关数据。 * Process query form datas. diff --git a/module/search/view/buildoldform.html.php b/module/search/view/buildoldform.html.php new file mode 100644 index 0000000000..e212be9699 --- /dev/null +++ b/module/search/view/buildoldform.html.php @@ -0,0 +1,607 @@ + + * @package search + * @version $Id: buildform.html.php 4129 2013-01-18 01:58:14Z wwccss $ + * @link https://www.zentao.net + */ +?> +app->getWebRoot() . "js/"; +include '../../common/view/datepicker.html.php'; +include '../../common/view/chosen.html.php'; +$formId = 'searchForm-' . uniqid(''); +?> + + +
    + +
    + +
    ' target='hiddenwin' id='' class='search-form no-stash'> + + + + + + + + + + + + + + + +
    + + + "; + + /* Get params of current field. */ + $currentField = $formSession["field$fieldNO"]; + if(!isset($fieldParams[$currentField])) + { + $currentField = key($searchFields); + $formSession["field$fieldNO"] = $currentField; + $formSession["operator$fieldNO"] = isset($fieldParams[$currentField]['operator']) ? $fieldParams[$currentField]['operator'] : '='; + $formSession["value$fieldNO"] = ''; + } + + $param = $fieldParams[$currentField]; + + /* Print and or. */ + echo "'; + + /* Print field. */ + echo "'; + + /* Print operator. */ + echo "'; + + /* Print value. */ + echo "'; + + $fieldNO ++; + echo ''; + } + ?> + +
    "; + if($i == 1) echo "{$lang->search->group1}" . html::hidden("andOr$fieldNO", 'AND'); + if($i > 1) echo html::select("andOr$fieldNO", $lang->search->andor, $formSession["andOr$fieldNO"], "class='form-control'"); + echo '" . html::select("field$fieldNO", $searchFields, $formSession["field$fieldNO"], "onchange='setField(this, $fieldNO, {$module}params)' class='form-control chosen'") . '" . html::select("operator$fieldNO", $lang->search->operators, $formSession["operator$fieldNO"], "class='form-control' onchange='setPlaceHolder($fieldNO)'") . '"; + if(isset($config->moreLinks["field{$currentField}"])) $config->moreLinks["value$fieldNO"] = $config->moreLinks["field{$currentField}"]; + if($param['control'] == 'select') echo html::select("value$fieldNO", $param['values'], $formSession["value$fieldNO"], "class='form-control searchSelect chosen' data-max_drop_width='0'"); + if($param['control'] == 'input') + { + $fieldName = $formSession["field$fieldNO"]; + $fieldValue = $formSession["value$fieldNO"]; + $extraClass = isset($param['class']) ? $param['class'] : ''; + + $placeholder = ''; + if($fieldValue && strpos('$lastWeek,$thisWeek,$today,$yesterday,$thisMonth,$lastMonth',$fieldValue) !== false) + { + $placeholder = "placeholder='{$fieldValue}'"; + } + elseif($fieldName == 'id' and $formSession["operator$fieldNO"] == '=') + { + $placeholder = "placeholder='{$lang->search->queryTips}'";; + } + + echo html::input("value$fieldNO", $fieldValue, "class='form-control $extraClass searchInput' $placeholder"); + } + echo '
    +
    search->andor, $formSession['groupAndOr'], "class='form-control'")?> + + + "; + + /* Get params of current field. */ + $currentField = $formSession["field$fieldNO"]; + if(!isset($fieldParams[$currentField])) + { + $currentField = key($searchFields); + $formSession["field$fieldNO"] = $currentField; + $formSession["operator$fieldNO"] = isset($fieldParams[$currentField]['operator']) ? $fieldParams[$currentField]['operator'] : '='; + $formSession["value$fieldNO"] = ''; + } + $param = $fieldParams[$currentField]; + + /* Print and or. */ + echo "'; + + /* Print field. */ + echo "'; + + /* Print operator. */ + echo "'; + + /* Print value. */ + echo "'; + + $fieldNO ++; + echo ''; + } + ?> + +
    "; + if($i == 1) echo "{$lang->search->group2}" . html::hidden("andOr$fieldNO", 'AND'); + if($i > 1) echo html::select("andOr$fieldNO", $lang->search->andor, $formSession["andOr$fieldNO"], "class='form-control'"); + echo '" . html::select("field$fieldNO", $searchFields, $formSession["field$fieldNO"], "onchange='setField(this, $fieldNO, {$module}params)' class='form-control chosen'") . '" . html::select("operator$fieldNO", $lang->search->operators, $formSession["operator$fieldNO"], "class='form-control' onchange='setPlaceHolder($fieldNO)'") . '"; + if(isset($config->moreLinks["field{$currentField}"])) + { + $selected = $formSession["value$fieldNO"]; + if(!isset($param['values'][$selected])) $config->moreLinks["value$fieldNO"] = $config->moreLinks["field{$currentField}"]; + } + if($param['control'] == 'select') echo html::select("value$fieldNO", $param['values'], $formSession["value$fieldNO"], "class='form-control searchSelect chosen' data-max_drop_width='0'"); + + if($param['control'] == 'input') + { + $fieldName = $formSession["field$fieldNO"]; + $fieldValue = $formSession["value$fieldNO"]; + $extraClass = isset($param['class']) ? $param['class'] : ''; + + $placeholder = ''; + if($fieldValue && strpos('$lastWeek,$thisWeek,$today,$yesterday,$thisMonth,$lastMonth',$fieldValue) !== false) + { + $placeholder = "placeholder='{$fieldValue}'"; + } + elseif($fieldName == 'id' and $formSession["operator$fieldNO"] == '=') + { + $placeholder = "placeholder='{$lang->search->queryTips}'";; + } + + echo html::input("value$fieldNO", $fieldValue, "class='form-control $extraClass searchInput' $placeholder data-max_drop_width='0'"); + } + echo '
    +
    + search->common, '', 'btn btn-primary') . "   "; + if($style != 'simple') echo html::commonButton($lang->search->reset, '', 'btn-reset-form btn'); + echo html::commonButton('', '', 'btn-expand-form btn btn-info pull-right'); + if($style != 'simple' and common::hasPriv('search', 'saveQuery')) echo html::a($this->createLink('search', 'saveOldQuery', "module=$module&onMenuBar=$onMenuBar"), ' ' . $lang->search->saveCondition . '', '', "class='btn-save-form btn btn-link btn-active-text text iframe' id='save-query'"); + echo html::hidden('formType', zget($formSession, 'formType', 'lite')); + ?> +
    +
    +search->custom);?> + + diff --git a/module/search/view/saveoldquery.html.php b/module/search/view/saveoldquery.html.php new file mode 100644 index 0000000000..a7154a18ef --- /dev/null +++ b/module/search/view/saveoldquery.html.php @@ -0,0 +1,34 @@ + + * @package search + * @version $Id$ + * @link https://www.zentao.net + */ +?> + +
    +
    + + +
    + + +
    +
    + + +
    + + +
    +
    + + +
    +
    +