web-dev-qa-db-fra.com

Recherche par trait d'union

J'utilise actuellement Wordpress sur la version 4.6.1 et j'essaie de rechercher des publications contenant le caractère - (trait d'union). Cependant, le paramètre de recherche prend mon trait d'union pour une négation.

À partir de WP_Query documentation:

La présélection d'un terme avec un trait d'union exclut les publications correspondant à ce terme. Par exemple, "pillow -sofa" renverra les messages contenant "pillow" mais pas "sofa" (disponible depuis la version 4.4).

Voici ma requête:

$query = new WP_Query(array(
    'post_type' => array('product', 'product_variation'),
    's' => '-',
    'posts_per_page' => 36
));

J'ai essayé d'échapper au trait d'union en faisant:

's' => '\-'

Cependant, le résultat reste le même (var_dump($query->request)):

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
WHERE
    1=1
    AND (((wp_posts.post_title NOT LIKE '%%')
    AND (wp_posts.post_excerpt NOT LIKE '%%')
    AND (wp_posts.post_content NOT LIKE '%%')))
    AND (wp_posts.post_password = '')
    AND wp_posts.post_type IN ('product', 'product_variation')
    AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'acf-disabled')
ORDER BY
    wp_posts.post_date DESC
LIMIT 0, 36
5
Chin Leung

Une solution consiste à modifier le préfixe d'exclusion à l'aide du filtre wp_query_search_exclusion_prefix pris en charge dans WP 4.7+. Voir billet # 38099 .

Voici un exemple comment nous pouvons le changer de - à ex. !:

add_filter( 'wp_query_search_exclusion_prefix', function( $prefix )
{
    return '!'; // adjust to your needs (default is -)
} );

où nous utiliserions !Apple au lieu de -Apple pour exclure Apple des résultats de la recherche. Ensuite, vous pouvez rechercher par -.

Il semble que le préfixe d'exclusion doit être un seul caractère (ou vide pour désactiver cette fonctionnalité), à cause de cela check in the core :

// If there is an $exclusion_prefix, terms prefixed with it should be excluded.
$exclude = $exclusion_prefix && ( $exclusion_prefix === substr( $term, 0, 1 ) );
if ( $exclude ) {
    $like_op  = 'NOT LIKE';
    $andor_op = 'AND';
    $term     = substr( $term, 1 );
} else {
    $like_op  = 'LIKE';
    $andor_op = 'OR';
}

Sinon, cela ressemble à un bug , pour ne pas pouvoir rechercher uniquement le préfixe d’exclusion du terme.

Je me demande s'il serait préférable d'ajouter un contrôle supplémentaire $exclusion_prefix !== $term pour confirmer cela:

$exclude = $exclusion_prefix 
    && $exclusion_prefix !== $term 
    && ( $exclusion_prefix === mb_substr( $term, 0, 1 ) );
if ( $exclude ) {
    $like_op  = 'NOT LIKE';
    $andor_op = 'AND';
    $term     = mb_substr( $term, 1 );
} else {
    $like_op  = 'LIKE';
    $andor_op = 'OR';
}

où nous utiliserions également mb_substr() au lieu de substr() pour un support de caractère plus large pour le préfixe d'exclusion.

Je suppose que je devrais créer un ticket pour ça ...

4
birgire

Vous pouvez utiliser le fait que NOT LIKE '%%' est très unique. Cela ne peut se produire que dans les cas où vous recherchez -.

add_filter( 'posts_where', function( $where, $q )
{        
    $where = str_replace( "NOT LIKE '%%'", "LIKE '%-%'", $where);           
    return $where;

}, 10, 2 );

$args = array(
    'post_type'     => 'post',
    'post_status'   => 'publish',
    's' => '-'

);

$q = new WP_Query( $args );
var_dump($query->request);

La requête résultante sera:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts 
WHERE 1=1 
AND (((wp_posts.post_title LIKE '%-%')
AND (wp_posts.post_excerpt LIKE '%-%')
AND (wp_posts.post_content LIKE '%-%'))) 
AND wp_posts.post_type = 'post'
AND ((wp_posts.post_status = 'publish')) 
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
2
prosti