El siguiente paso en mi búsqueda para extender WordPress es alterar la forma en que WordPress utiliza la variable $sentence
en posts_search
para incluir una cadena adicional, cuando la variable $sentence
cumple un cierto criterio.
El caso de uso específico aquí es que cuando alguien escribe algo como TL123
, también debería buscar TL-123
, con TL%
como comodín aquí. Esto es para reducir los errores de búsqueda (para aquellos que no incluyen el guión).
He visto cómo podemos filtrar en posts_search
con consultas SQL adicionales (en realidad estoy usando este con bastante éxito hasta ahora), pero estoy un poco confuso sobre cómo podría funcionar esto. Cualquier ayuda sería muy apreciada. Gracias!
Editar: para incluir más información sobre las necesidades gracias a @kaiser
- Las búsquedas se realizan normalmente escribiendo TL123 , cuando en realidad el título real de la publicación es TL-123 en la mayoría de los casos; por lo tanto, el objetivo aquí es interceptar cuando la consulta de búsqueda incluye TL (NÚMERO) y también busca TL- (NÚMERO).
Una vez más, el truco aquí es que algunas publicaciones no incluyen TL, sino solo TL, por eso busco consultas de búsqueda que coincidan con ese patrón para buscar también una "frase parcial" adicional.
Gracias!
Actualizar
Bien, basado en la función de inicio de Kaiser, he encontrado lo siguiente:
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);
La parte que no puedo pasar es en realidad es la consulta SQL real - > error abajo:
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
¿Algún indicador sobre dónde me equivoqué? Gracias!
Actualización # 2
He empezado a ver algunos problemas:
- Estaba haciendo
wp__posts
en lugar dewp_posts
(lo actualicé arriba) - Como se mencionó
kaiser
, es posible que la parteLIKE %s
tenga que serLIKE %%s%
pero eso no se analiza correctamente.
El error es ahora:
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
El error anterior (por lo que puedo decir) en realidad está intentando buscar una publicación que sea a la vez tl123
y TL-123
, pero creo que OR
es lo que quiero (ya que quiero devolver las publicaciones en una u otra situación).
Actualización # 3
Se actualizó la función para que escape correctamente %s
, por lo que el error es ahora:
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
Actualización # 4
Esto es lo que terminé haciendo - > el foreach no estaba envolviendo correctamente (con el operador AND / OR como @kaiser mencionado), así que los separé en sus propias inserciones de matriz.
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);
Tiene algunos problemas si alguien escribe tl123 tl456
(dos apariciones de la palabra clave tl
), pero estoy trabajando en esa parte. Gracias!