我正在将wpDataTables用于家谱网站,到目前为止,该网站的运行非常出色。唯一的障碍是我的搜索过滤器不会在给定的搜索中返回该过滤器中的所有单词。例如,字符串Karl Friedrich Wilhelm将完全返回该字符串。我想更改编码以允许使用不同的单词顺序(例如Friedrich Karl Wilhelm等),当单词之间用空格分隔时,可以从该表列中以任何顺序从数据库中检索它们,但不能从整个表中检索它们
当前,我可以使用%和_通配符进行搜索而不会出现问题。我读了一些有关全文搜索的文章,该文章可能有用,但前提是可以保留我对通配符的使用,并使其在不破坏代码的情况下可以与我的所有列一起使用。 (我所有的SQL条目都是TEXT或VARCHAR格式。)我不确定在这种情况下全文搜索是否会更好,或者“ like”语句是否会更有效(我也读过这可能向我开放injection attacks)。我找到了article that might be of use,但我不知道如何实现。
代码分为两部分:第一部分是全局搜索。恐怕如果我更改它以进行全文搜索,可能会使查询花费更长的时间,因为它将搜索整个表而不是单个列。第二个是每个单独的过滤器,在我的网站上它适用于“姓名”,“出生地”等。
我需要对以下代码进行什么更改,以使过滤器以任意顺序返回结果?您可以在http://mypomerania.com/person-search/上的网站上看到一个示例,该示例当前如何在MySQL和PHP上同时使用PHP,并且我还无法弄清楚如何实现我在其他文章中所读到的内容。任何指导将不胜感激。谢谢!
// Global search
$search = '';
if (!empty($_POST['search']['value'])) {
$search = " (";
for ($i = 0; $i < count($aColumns); $i++) {
if ($_POST['columns'][$i]['searchable'] == "true") {
if (in_array($wdtParameters['data_types'][$_POST['columns'][$i]['name']], array('date', 'datetime', 'time'))) {
continue;
} else {
if (is_null($wdtParameters['foreignKeyRule'][$_POST['columns'][$i]['name']])) {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '%" . addslashes($_POST['search']['value']) . "%' OR ";
} else {
$foreignKeyRule = $wdtParameters['foreignKeyRule'][$_POST['columns'][$i]['name']];
$joinedTable = WPDataTable::loadWpDataTable($foreignKeyRule->tableId);
$distinctValues = $joinedTable->getDistinctValuesForColumns($foreignKeyRule);
$distinctValues = array_map('strtolower', $distinctValues);
$filteredValues = preg_grep('~' . preg_quote(strtolower($_POST['search']['value']), '~') . '~', $distinctValues);
if (!empty($filteredValues)) {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` IN (" . implode(', ', array_keys($filteredValues)) . ") OR ";
} else {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '" . addslashes($_POST['search']['value']) . "' OR ";
}
}
}
}
}
$search = substr_replace($search, "", -3);
$search .= ')';
}
// Individual column filtering
for ($i = 0; $i < count($aColumns); $i++) {
$columnSearchFromTable = false;
$columnSearchFromDefaultValue = false;
if (isset($_POST['columns'][$i]['search']) &&
$_POST['columns'][$i]['search']['value'] != '' &&
$_POST['columns'][$i]['search']['value'] != '|') {
$columnSearchFromTable = true;
}
if (($_POST['draw'] == 1 || $columnSearchFromTable == true) &&
(isset($wdtParameters['filterDefaultValue'][$i]) &&
$wdtParameters['filterDefaultValue'][$i] !== '' &&
$wdtParameters['filterDefaultValue'][$i] !== '|' )) {
$columnSearchFromDefaultValue = true;
}
if ($_POST['columns'][$i]['searchable'] == true && ($columnSearchFromTable || $columnSearchFromDefaultValue)) {
//Apply placeholders when they are set in filter predefined value
$wdtParameters['filterDefaultValue'][$i]= WDTTools::applyPlaceholders($wdtParameters['filterDefaultValue'][$i]);
$columnSearch = $columnSearchFromTable ? $_POST['columns'][$i]['search'][value] : $wdtParameters['filterDefaultValue'][$i];
if (!empty($search)) {
$search .= ' AND ';
}
if (isset($wdtParameters['filterTypes'][$aColumns[$i]])) {
switch ($wdtParameters['filterTypes'][$aColumns[$i]]) {
case 'number-range':
list($left, $right) = explode('|', $columnSearch);
if ($left !== '') {
$left = (float)$left;
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` >= $left ";
}
if ($right !== '') {
$right = (float)$right;
if (!empty($search) && $left !== '') {
$search .= ' AND ';
}
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` <= $right ";
}
break;
case 'date-range':
case 'time-range':
case 'datetime-range':
list($left, $right) = explode('|', $columnSearch);
$date_format = '';
if ($wdtParameters['filterTypes'][$aColumns[$i]] != 'time-range') {
$date_format = str_replace('m', '%m', get_option('wdtDateFormat'));
$date_format = str_replace('M', '%M', $date_format);
$date_format = str_replace('Y', '%Y', $date_format);
$date_format = str_replace('y', '%y', $date_format);
$date_format = str_replace('d', '%d', $date_format);
}
if ($wdtParameters['filterTypes'][$aColumns[$i]] == 'datetime-range'
|| $wdtParameters['filterTypes'][$aColumns[$i]] == 'time-range'
) {
$date_format .= ' ' . get_option('wdtTimeFormat');
$date_format = str_replace('H', '%H', $date_format);
$date_format = str_replace('h', '%h', $date_format);
$date_format = str_replace('i', '%i', $date_format);
$date_format = str_replace('A', '%p', $date_format);
}
if ($left && $right) {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` BETWEEN STR_TO_DATE('$left', '$date_format') AND STR_TO_DATE('$right', '$date_format') ";
} elseif ($left) {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` >= STR_TO_DATE('$left', '$date_format') ";
} elseif ($right) {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` <= STR_TO_DATE('$right', '$date_format') ";
}
break;
case 'select':
if ($columnSearch == 'possibleValuesAddEmpty') {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '' OR `" . $aColumns[$i] . "` IS NULL";
} else {
if ($wdtParameters['exactFiltering'][$aColumns[$i]] == 1) {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '" . $columnSearch . "' ";
} else {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '%" . $columnSearch . "%' ";
}
}
break;
case 'checkbox':
case 'multiselect':
if ($wdtParameters['exactFiltering'][$aColumns[$i]] == 1) {
// Trim regex parts for first and last one
if (strpos($columnSearch, '$') !== false) {
$checkboxSearches = explode('$|^', $columnSearch);
$checkboxSearches[0] = substr($checkboxSearches[0], 1);
if (count($checkboxSearches) > 1) {
$checkboxSearches[count($checkboxSearches) - 1] = substr($checkboxSearches[count($checkboxSearches) - 1], 0, -1);
} else {
$checkboxSearches[0] = substr($checkboxSearches[0], 0, -1);
}
} else {
$checkboxSearches = explode('|', $columnSearch);
}
} else {
$checkboxSearches = explode('|', $columnSearch);
}
$j = 0;
$search .= " (";
foreach ($checkboxSearches as $checkboxSearch) {
if ($j > 0) {
$search .= " OR ";
}
if ($wdtParameters['exactFiltering'][$aColumns[$i]] == 1) {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '" . $checkboxSearch . "' ";
} else {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '%" . $checkboxSearch . "%' ";
}
$j++;
}
$search .= ") ";
break;
case 'text':
case 'number':
if (is_null($wdtParameters['foreignKeyRule'][$_POST['columns'][$i]['name']])) {
if ($wdtParameters['exactFiltering'][$aColumns[$i]] == 1) {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '" . $columnSearch . "' ";
} else {
if ($wdtParameters['filterTypes'][$aColumns[$i]] == 'number') {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '" . $columnSearch . "%' ";
} else {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '%" . $columnSearch . "%' ";
}
}
} else {
$foreignKeyRule = $wdtParameters['foreignKeyRule'][$_POST['columns'][$i]['name']];
$joinedTable = WPDataTable::loadWpDataTable($foreignKeyRule->tableId);
$distinctValues = $joinedTable->getDistinctValuesForColumns($foreignKeyRule);
$distinctValues = array_map('strtolower', $distinctValues);
if ($wdtParameters['exactFiltering'][$aColumns[$i]] == 1) {
$filteredValues = preg_grep('~^' . preg_quote(strtolower($columnSearch), null) . '$~', $distinctValues);
} else {
$filteredValues = preg_grep('~' . preg_quote(strtolower($columnSearch), '~') . '~', $distinctValues);
}
if (!empty($filteredValues)) {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` IN (" . implode(', ', array_keys($filteredValues)) . ")";
} else {
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '" . $columnSearch . "' ";
}
}
break;
default:
$search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '%" . $columnSearch . "%' ";
}
}
}
}
if ($search) {
$search = 'WHERE ' . $search;
$parsedSearch = $parser->parse($search);
}
}
}