下一步我要扩展WordPress,就是改变WordPress使用$sentence
变量输入posts_search
若要包含其他字符串,请在$sentence
变量符合特定标准。
这里的具体用例是,当有人键入TL123
它还应该搜索TL-123
, 具有TL%
在这里是通配符。这是为了减少搜索错误(对于不包含连字符的搜索错误)。
我看到了我们如何过滤posts_search
使用其他SQL查询(我实际上使用this one 到目前为止,取得了相当好的成功),但我对如何实现这一点有点模糊。任何帮助都将不胜感激。谢谢
编辑-感谢@kaiser,以包含更多有关需求的信息
搜索通常通过键入TL123来完成,而在大多数情况下,实际的帖子标题是TL-123,因此,这里的目标是在搜索查询包括TL(数字)和搜索TL(数字)时进行拦截再次强调,这里的诀窍是有些帖子不包含TL,而只包含TL,因此我正在寻找与该模式匹配的搜索查询,以同时搜索其他“部分短语”。
谢谢
更新
好的,基于kaiser的starter功能,我得出了以下结论:
function wpse66815_search_query_string( $search, &$wp_query )
{
if (!is_admin() && is_search()) {
print_r($search);
global $wp_query;
// get search term
$search_term = array_shift($wp_query->query_vars[\'search_terms\']);
// specify string we\'ll use to replace
$replace_var = \'TL\';
// find matches for that string
preg_match_all("/{$replace_var}(?:[^0-9]*)(\\d+)/i", $search_term, $out);
// if there\'s no matches, return the normal search
if ( empty($out[0]) )
return $search;
// find/generate the search term with the replacement
$modified_search_term = preg_replace("/{$replace_var}(?:[^0-9]*)(\\d+)/i", "{$replace_var}-$1", $search_term);
// combine both the regular and modified search term
$new_search[] = $search_term;
$new_search[] = $modified_search_term;
//var_dump($new_search);
// generate the new search query
foreach ( $new_search as $keyword )
{
$new_string_parts[] = $GLOBALS[\'wpdb\']->prepare(
"
AND ((%s.post_title LIKE \'%%%s%%\') OR (%s.post_content LIKE \'%%%s%%\'))
"
,"{$GLOBALS[\'wpdb\']->prefix}posts"
,like_escape( $keyword )
,"{$GLOBALS[\'wpdb\']->prefix}posts"
,like_escape( $keyword )
);
}
// set $search equal to results
$search = implode( " ", $new_string_parts );
//print_r($search);
}
return $search;
}
add_filter(\'posts_search\', \'wpse66815_search_query_string\',500,2);
我无法通过的部分实际上是实际的SQL查询->错误,如下所示:
WordPress database error: [You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'.post_title LIKE \'tl123\') OR (\'wp__posts\'.post_content LIKE \'tl123\')) \' at line 2]
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND ((\'wp__posts\'.post_title LIKE \'tl123\') OR (\'wp__posts\'.post_content LIKE \'tl123\')) AND ((\'wp__posts\'.post_title LIKE \'TL-123\') OR (\'wp__posts\'.post_content LIKE \'TL-123\')) AND wp_posts.post_type IN (\'post\', \'page\', \'attachment\', \'galleries\', \'idea_gallery\', \'moulding_profiles\', \'moulding_collection\', \'moulding_combination\') AND (wp_posts.post_status = \'publish\' OR wp_posts.post_author = 2 AND wp_posts.post_status = \'private\') ORDER BY wp_posts.post_date DESC LIMIT 0, 80
有没有关于我哪里出错的指示?谢谢
更新#2
我开始发现一些问题:
它正在做wp__posts
而不是wp_posts
(我更新了上面的内容)kaiser
如前所述LIKE %s
部分可能需要LIKE %%s%
但这并不能正确解析错误现在为:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND ((\'wp_posts\'.post_title LIKE \'tl123\') OR (\'wp_posts\'.post_content LIKE \'tl123\')) AND ((\'wp_posts\'.post_title LIKE \'TL-123\') OR (\'wp_posts\'.post_content LIKE \'TL-123\')) AND wp_posts.post_type IN (\'post\', \'page\', \'attachment\', \'galleries\', \'idea_gallery\', \'moulding_profiles\', \'moulding_collection\', \'moulding_combination\') AND (wp_posts.post_status = \'publish\' OR wp_posts.post_author = 2 AND wp_posts.post_status = \'private\') ORDER BY wp_posts.post_date DESC LIMIT 0, 80
上面的错误(据我所知)实际上是在寻找一篇既有
tl123
和
TL-123
, 但我认为
OR
是我想要的(因为我想在非此即彼的情况下返回帖子)。
更新#3
更新的函数以正确转义
%s
, 所以现在的错误是:
WordPress database error: [You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'.post_title LIKE \'%tl123%\') OR (\'wp_posts\'.post_content LIKE \'%tl123%\')) \' at line 2]
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND ((\'wp_posts\'.post_title LIKE \'%tl123%\') OR (\'wp_posts\'.post_content LIKE \'%tl123%\')) AND ((\'wp_posts\'.post_title LIKE \'%TL-123%\') OR (\'wp_posts\'.post_content LIKE \'%TL-123%\')) AND wp_posts.post_type IN (\'post\', \'page\', \'attachment\', \'galleries\', \'idea_gallery\', \'moulding_profiles\', \'moulding_collection\', \'moulding_combination\') AND (wp_posts.post_status = \'publish\' OR wp_posts.post_author = 2 AND wp_posts.post_status = \'private\') ORDER BY wp_posts.post_date DESC LIMIT 0, 80
更新#4
我最后做的是->foreach没有正确包装(使用了@kaiser提到的AND/OR操作符),所以我将它们分离到各自的数组插入中。
function wpse66815_search_query_string( $search, &$wp_query )
{
if (!is_admin() && is_search()) {
//print_r($search);
global $wp_query,$wpdb;
// get search term
$search_term = array_shift($wp_query->query_vars[\'search_terms\']);
// specify string we\'ll use to replace
$replace_var = \'TL\';
// find matches for that string
preg_match_all("/{$replace_var}(?:[^0-9]*)(\\d+)/i", $search_term, $out);
// if there\'s no matches, return the normal search
if ( empty($out[0]) )
return $search;
// find/generate the search term with the replacement
$modified_search_term = preg_replace("/{$replace_var}(?:[^0-9]*)(\\d+)/i", "{$replace_var}-$1", $search_term);
// combine both the regular and modified search term
$new_search[] = $search_term;
$new_search[] = $modified_search_term;
var_dump($new_search);
// generate the new search query
$new_string_parts[] = $wpdb->prepare( "AND ((({$wpdb->posts}.post_title LIKE \'%%%s%%\') OR ({$wpdb->posts}.post_content LIKE \'%%%s%%\'))",like_escape( $new_search[0] ),like_escape( $new_search[0] ));
$new_string_parts[] = $wpdb->prepare( "OR (({$wpdb->posts}.post_title LIKE \'%%%s%%\') OR ({$wpdb->posts}.post_content LIKE \'%%%s%%\')))",like_escape( $new_search[1] ),like_escape( $new_search[1] ));
// set $search equal to results
$search = implode( " ", $new_string_parts );
//print_r($search);
}
return $search;
}
add_filter(\'posts_search\', \'wpse66815_search_query_string\',500,2);
如果有人输入,确实会有一些麻烦
tl123 tl456
(两次出现
tl
关键字),但我正在处理那个部分。谢谢