app->loadLang('workflow'); $this->app->loadConfig('workflow'); if(!empty($this->config->workflow->buildin)) { foreach($this->config->workflow->buildin->modules as $appModules) { if(isset($appModules->$flowModule)) { $buildin = true; break; } } } if(!$buildin) return $searchConfig; $fields = $this->loadModel('workflowfield')->getList($flowModule, 'searchOrder, `order`, id'); $maxCount = $this->config->maxCount; $this->config->maxCount = 0; $fieldValues = array(); $formName = $module . 'Form'; if($this->session->$formName) { foreach($this->session->$formName as $formField) { $field = zget($formField, 'field', ''); $value = zget($formField, 'value', ''); if(empty($field)) continue; if($value) $fieldValues[$formField->field][$value] = $value; } } foreach($fields as $field) { if($field->canSearch == 0 || $field->buildin) continue; if(in_array($field->control, $this->config->workflowfield->optionControls)) { $field->options = $this->workflowfield->getFieldOptions($field, true, zget($fieldValues, $field->field, ''), '', $this->config->flowLimit); } $searchConfig['fields'][$field->field] = $field->name; $searchConfig['params'][$field->field] = $this->loadModel('flow', 'sys')->processSearchParams($field->control, $field->options); } $this->config->maxCount = $maxCount; return $searchConfig; } /** * 处理查询表单的相关数据。 * Process query form datas. * * @param object $fieldParams * @param string $field * @param string $andOrName * @param string $operatorName * @param string $valueName * @access protected * @return array */ protected function processQueryFormDatas(object $fieldParams, string $field, string $andOrName, string $operatorName, string $valueName): array { /* 设置分组之间的逻辑关系。*/ /* Set and or. */ $andOr = strtoupper($this->post->$andOrName); if($andOr != 'AND' && $andOr != 'OR') $andOr = 'AND'; /* 设置操作符。*/ /* Set operator. */ $operator = $this->post->$operatorName; if(!isset($this->lang->search->operators[$operator])) $operator = '='; /* 设置字段的值。*/ /* Skip empty values. */ if($this->post->$valueName == 'ZERO') $this->post->$valueName = 0; // ZERO is special, stands to 0. if(isset($fieldParams->$field) && $fieldParams->$field->control == 'select' && $this->post->$valueName === 'null') $this->post->$valueName = ''; // Null is special, stands to empty if control is select. Fix bug #3279. $value = addcslashes(trim($this->post->$valueName), '%'); return array($andOr, $operator, $value); } /** * 根据字段,操作符和值设置查询条件。 * Set condition by field, operator and value. * * @param string $field * @param string $operator * @param string $value * @access protected * @return string */ protected function setCondition(string $field, string $operator, string $value): string { $condition = ''; if($operator == 'include') { if($field == 'module') { $allModules = $this->loadModel('tree')->getAllChildId($value); if($allModules) $condition = helper::dbIN($allModules); } else { $condition = ' LIKE ' . $this->dbh->quote("%$value%"); } } elseif($operator == "notinclude") { if($field == 'module') { $allModules = $this->loadModel('tree')->getAllChildId($value); if($allModules) { if(count($allModules) > 1) $condition = " NOT " . helper::dbIN($allModules); else $condition = " !" . helper::dbIN($allModules); } } else { $condition = ' NOT LIKE ' . $this->dbh->quote("%$value%"); } } elseif($operator == 'belong') { if($field == 'module') { $allModules = $this->loadModel('tree')->getAllChildId($value); if($allModules) $condition = helper::dbIN($allModules); } elseif($field == 'dept') { $allDepts = $this->loadModel('dept')->getAllChildId($value); $condition = helper::dbIN($allDepts); } elseif($field == 'scene') { $allScenes = $value === '0' ? array() : ($value === '' ? array(0) : $this->loadModel('testcase')->getAllChildId($value)); if(count($allScenes)) $condition = helper::dbIN($allScenes); } 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 $field == '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 . ') '; } } return $condition; } /** * 设置 where 查询条件。 * Set where condition. * * @param string $where * @param string $field * @param string $operator * @param string $value * @param string $andOr * @access protected * @return string */ protected function setWhere(string $where, string $field, string $operator, string $value, string $andOr): string { $condition = $this->setCondition($field, $operator, $value); if($operator == '=' && preg_match('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/', $value)) { $condition = '`' . $field . "` >= '$value' AND `" . $field . "` <= '$value 23:59:59'"; $where .= " $andOr ($condition)"; } elseif($operator == '!=' && preg_match('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/', $value)) { $condition = '`' . $field . "` < '$value' OR `" . $field . "` > '$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 " . '`' . $field . "` <= '$value 23:59:59'"; } elseif($operator == '>' and preg_match('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/', $value)) { $where .= " $andOr " . '`' . $field . "` > '$value 23:59:59'"; } elseif($condition) { $where .= " $andOr " . '`' . $field . '` ' . $condition; } return $where; } /** * 如果搜索框的选项是users,products, executions, 获取相对应的列表。 * Get user, product and execution value of the param. * * @param array $fields * @access public * @return array */ public function getParamValues(array $fields, array $params): array { $hasProduct = false; $hasExecution = false; $hasUser = false; foreach($fields as $fieldName) { if(empty($params[$fieldName])) continue; if($params[$fieldName]['values'] == 'products') $hasProduct = true; if($params[$fieldName]['values'] == 'users') $hasUser = true; if($params[$fieldName]['values'] == 'executions') $hasExecution = true; } /* 将用户的值追加到获取到的用户列表。*/ $appendUsers = array(); $module = $_SESSION['searchParams']['module']; $formSessionName = $module . 'Form'; if(isset($_SESSION[$formSessionName])) { for($i = 1; $i <= $this->config->search->groupItems; $i ++) { if(!isset($_SESSION[$formSessionName][$i - 1])) continue; $fieldName = $_SESSION[$formSessionName][$i - 1]['field']; if(isset($params[$fieldName]) and $params[$fieldName]['values'] == 'users') { if($_SESSION[$formSessionName][$i - 1]['value']) $appendUsers[] = $_SESSION[$formSessionName][$i - 1]['value']; } } } $users = $products = $executions = array(); if($hasUser) { $users = $this->loadModel('user')->getPairs('realname|noclosed', $appendUsers, $this->config->maxCount); $users['$@me'] = $this->lang->search->me; } if($hasProduct) $products = $this->loadModel('product')->getPairs('', $this->session->project); if($hasExecution) $executions = $this->loadModel('execution')->getPairs($this->session->project); return array($users, $products, $executions); } /** * 获取 sql 语句的参数。 * Get list sql params. * * @param string $keywords * @param string $type * @access protected * @return array */ protected function getSqlParams(string $keywords, string|array $type): array { $spliter = $this->app->loadClass('spliter'); $words = explode(' ', self::unify($keywords, ' ')); $against = ''; $againstCond = ''; foreach($words as $word) { /* 将 utf-8 字符串拆分为单词,为每个单词计算 unicode. */ $splitedWords = $spliter->utf8Split($word); $trimmedWord = trim($splitedWords['words']); $against .= '"' . $trimmedWord . '" '; $againstCond .= '(+"' . $trimmedWord . '") '; if(is_numeric($word) && strpos($word, '.') === false and strlen($word) == 5) $againstCond .= "(-\" $word \") "; } $likeCondition = ''; /* Assisted lookup by like condition when only one word. */ if(count($words) == 1 and strpos($words[0], ' ') === false and !is_numeric($words[0])) $likeCondition = "OR title like '%{$trimmedWord}%' OR content like '%{$trimmedWord}%'"; $words = str_replace('"', '', $against); $words = str_pad($words, 5, '_'); return array($words, $againstCond, $likeCondition); } /** * 获取允许的模块。 * Get allowed objects. * * @param string|array $type * @access protected * @return array */ protected function getAllowedObjects(string|array $type): array { $allowedObjects = array(); if($type != 'all') { foreach($type as $module) $allowedObjects[] = $module; return $allowedObjects; } if($this->config->systemMode == 'light') unset($this->config->search->fields->program); foreach($this->config->search->fields as $objectType => $fields) { $module = $objectType; if($module == 'case') $module = 'testcase'; if(common::hasPriv($module, 'view')) $allowedObjects[] = $objectType; if($module == 'deploystep' && common::haspriv('deploy', 'viewstep')) $allowedobjects[] = $objectType; } return $allowedObjects; } }