Phân tách từ tìm kiếm cho wp_postmeta.meta_value phần 2 (ok)
// === Phân tách các từ ra để tìm kiếm ===
if(!class_exists('parse_search_custom')) {
global $test;
class parse_search_custom {
function parse_search($s) {
$q = array();
$q['s'] = $s;
global $wpdb;
$search = '';
// Added slashes screw with quote grouping when done early, so done later.
$q['s'] = stripslashes($q['s']);
if (empty($_GET['s']) && is_main_query()) {
$q['s'] = urldecode($q['s']);
}
// There are no line breaks in <input /> fields.
$q['s'] = str_replace(array("\r", "\n"), '', $q['s']);
$q['search_terms_count'] = 1;
if (!empty($q['sentence'])) {
$q['search_terms'] = array($q['s']);
} else {
if (preg_match_all('/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $q['s'], $matches)) {
$q['search_terms_count'] = count($matches[0]);
$q['search_terms'] = $this->parse_search_terms($matches[0]);
// If the search string has only short terms or stopwords, or is 10+ terms long, match it as sentence.
if (empty($q['search_terms']) || count($q['search_terms']) > 9) {
$q['search_terms'] = array($q['s']);
}
} else {
$q['search_terms'] = array($q['s']);
}
}
$n = !empty($q['exact']) ? '' : '%';
$searchand = '';
$q['search_orderby_title'] = array();
/**
* Filters the prefix that indicates that a search term should be excluded from results.
*
* @since 4.7.0
*
* @param string $exclusion_prefix The prefix. Default '-'. Returning
* an empty value disables exclusions.
*/
$exclusion_prefix = apply_filters('wp_query_search_exclusion_prefix', '-');
foreach ($q['search_terms'] as $term) {
// If there is an $exclusion_prefix, terms prefixed with it should be excluded.
$exclude = $exclusion_prefix && (substr($term, 0, 1) === $exclusion_prefix);
if ($exclude) {
$like_op = 'NOT LIKE';
$andor_op = 'AND';
$term = substr($term, 1);
} else {
$like_op = 'LIKE';
$andor_op = 'OR';
}
if ($n && !$exclude) {
$like = '%' . $wpdb->esc_like($term) . '%';
$q['search_orderby_title'][] = $wpdb->prepare("{$wpdb->postmeta}.meta_value LIKE %s", $like);
}
$like = $n . $wpdb->esc_like($term) . $n;
$search .= $wpdb->prepare("{$searchand}(({$wpdb->postmeta}.meta_value $like_op %s) AND {$wpdb->posts}.post_status = 'publish' )", $like);
$searchand = ' AND ';
}
return $search;
}
function parse_search_terms($terms) {
$strtolower = function_exists('mb_strtolower') ? 'mb_strtolower' : 'strtolower';
$checked = array();
$stopwords = $this->get_search_stopwords();
foreach ($terms as $term) {
// Keep before/after spaces when term is for exact match.
if (preg_match('/^".+"$/', $term)) {
$term = trim($term, "\"'");
} else {
$term = trim($term, "\"' ");
}
// Avoid single A-Z and single dashes.
if (!$term || (1 === strlen($term) && preg_match('/^[a-z\-]$/i', $term))) {
continue;
}
if (in_array(call_user_func($strtolower, $term), $stopwords, true)) {
continue;
}
$checked[] = $term;
}
return $checked;
}
function get_search_stopwords() {
/*
* translators: This is a comma-separated list of very common words that should be excluded from a search,
* like a, an, and the. These are usually called "stopwords". You should not simply translate these individual
* words into your language. Instead, look for and provide commonly accepted stopwords in your language.
*/
$words = explode(
',',_x('about,an,are,as,at,be,by,com,for,from,how,in,is,it,of,on,or,that,the,this,to,was,what,when,where,who,will,with,www','Comma-separated list of search stopwords in your language')
);
$stopwords = array();
foreach ($words as $word) {
$word = trim($word, "\r\n\t ");
if ($word) {
$stopwords[] = $word;
}
}
/**
* Filters stopwords used when parsing search terms.
*
* @since 3.7.0
*
* @param string[] $stopwords Array of stopwords.
*/
$stopwords = apply_filters('wp_search_stopwords_ct', $stopwords);
return $stopwords;
}
}
$test = new parse_search_custom();
}
add_filter( 'posts_where' , 'posts_where',10,2 );
function posts_where( $where, $query ) {
global $wpdb, $test;
if($query->is_search && !$query->is_admin) {
$string = $query->query_vars['s'];
$tests = $test->parse_search($string);
$where .= " OR ($tests) ";
}
return $where;
}
function custom_posts_join($join){
global $wpdb;
$join .= " LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id ";
return $join;
}
add_filter( 'posts_join' , 'custom_posts_join');
add_filter( 'posts_groupby', 'my_posts_groupby' );
function my_posts_groupby($groupby) {
global $wpdb;
$groupby = " {$wpdb->posts}.ID ";
return $groupby;
}
PreviousPhân tách các từ ra để tìm kiếm giống với tìm kiếm post_title, post_excerpt, post_content phần 1(ok)NextDùng Fulltext search kết hợp với tìm kiếm truyền thống phần 3 (ok)
Last updated
Was this helpful?