Расширение поискового запроса с дополнительным значением $ предложения

Далее в моем стремлении расширить WordPress изменяется то, как WordPress использует переменную $sentence в posts_search для включения дополнительной строки, когда переменная $sentence соответствует определенным критериям.

Конкретная информация о том, что когда кто-то вводит что-то вроде TL123 он также должен искать TL-123 , причем TL% является подстановочным знаком здесь. Это сокращение ошибок поиска (для тех, которые не включают дефис).

Я видел, как мы можем фильтровать в posts_search с дополнительными SQL-запросами (на самом деле я использую этот posts_search с довольно хорошим успехом), но я немного не понимаю, как это может работать. Любая помощь будет принята с благодарностью. Благодаря!

Изменить – включить дополнительную информацию о потребностях благодаря @kaiser

  • Поиски обычно выполняются путем ввода TL123 , когда в действительности фактическое название заголовка TL-123 в большинстве случаев – поэтому целью здесь является перехват, когда поисковый запрос включает TL (NUMBER), а также поиск TL- (NUMBER).

Опять же, фокус здесь в том, что некоторые сообщения не включают TL-, а только TL, поэтому я ищу поисковые запросы, которые соответствуют этому шаблону, а также поиск дополнительной «частичной фразы».

Благодаря!

Обновить

Хорошо, поэтому, основываясь на стартовой функции кайзера, я придумал следующее:

 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 не был корректно обертывается (с оператором AND / OR как @kaiser), поэтому я выделил их в свои собственные вставки массива.

 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 ), но я работаю над этой частью. Благодаря!

Solutions Collecting From Web of "Расширение поискового запроса с дополнительным значением $ предложения"

Я с радостью написал вчера два плагина:

Фильтр / Ядро

Вот как выглядит часть поискового запроса внутри фильтра posts_search :

 ' AND (((wp_XX_posts.post_title LIKE '%test%') OR (wp_XX_posts.post_content LIKE '%test%'))) ' 

где wp_XX_ – это $wpdb->prefix для моего тестового сайта WPSE внутри моей локальной установки MU.

Плагин №1 – отсканировать поисковые типы сообщений, которые нам не нужны.

Вот плагин, который модифицирует найденные типы сообщений, поскольку это часто требуется.

 <?php /** Plugin Name: (#66815) »kaiser« Limit search query post types */ /** * Alter the searched post types * * @param object $query * @return object $query */ add_action( 'pre_get_posts', 'wpse66815_pre_get_posts' ); function wpse66815_pre_get_posts( $query ) { if ( $query->is_main_query() ) { $query->set( 'post_type', 'YOUR_POST_TYPE' ); } return $query; } 

Плагин №2 – изменить строку поиска

Теперь, когда мы знаем, как выглядит строка поиска по умолчанию для заголовка и содержимого публикации, нам просто нужно перестроить его так, как нам это нужно:

 <?php /** Plugin Name: (#66815) »kaiser« Modify search query string */ function wpse66815_search_query_string( $search_string ) { global $wpdb; $searched_for = preg_match_all( // Match a prefix (%), but exclude it from the capture // Any character, any number of repetitions // Match a suffix (%), but exclude it from the capture "/(?<=\%)(.*)(?=\%)/", $search_string, $search_string_matches ); // We only need one element $searched_for = array_shift( $search_string_matches ); // Now we need to search for [LETTERS (min 1)][NUMBER (zero or more)][CHARACTER (zero or more)] preg_match_all( "/([^a-zA-Z][\d+]*[-_ ]*)/", $searched_for, $string_part_matches ); // Here we now got matches - if not, we can simply abort and leave the default $searched_for = array_shift( $string_part_matches ); if ( empty( $searched_for ) ) return $search_string; // Finally we need to split the string by all parts that are allowed // YOU NEED TO EDIT MY ANSWER HERE AND FILL IN WHAT WORKS FOR YOU $keywords = preg_split( "/([\s]*[\d+]*[-_ ]*)/", $searched_for, -1, // 0 & -1 are NO limit PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); // Now loop and build an array for further processing // Our first search string is - of course - the default string $string_parts = array( $search_string ); foreach ( $keywords as $keyword ) { $new_string_parts[] = $GLOBALS['wpdb']->prepare( " AND ((%s.post_title LIKE '%s') OR (%s.post_content LIKE '%s')) ", $wpdb->posts, $wpdb->esc_like( $keyword ), $wpdb->posts, $wpdb->esc_like( $keyword ) ); } // Now lets glue them together, return and see what we get... return implode( " ", $new_string_parts ); } 

Этот 2- й плагин не тестировался, так как мои потребности разные, и я думаю, что некоторые из регулярных выражений не совсем то, что вам нужно – вам придется исправить это и обновить этот ответ (это ваша роль в «предоставлении сообщества назад» в это Q / A). Хорошим инструментом для создания регулярного выражения, которое я только что нашел, является Expresso . Это чертовски уродливо (как присутствие в Интернете), но очень полезно.