web-dev-qa-db-fra.com

Exclure de la recherche toutes les publications personnalisées qui NE SONT PAS dans un terme de taxonomie

J'ai un message personnalisé avec une taxonomie associée. Cette taxonomie n'a qu'un terme, et les messages lui appartiennent ou non, de manière booléenne.

Dans les résultats de la recherche, je souhaite afficher les publications personnalisées qui appartiennent à la taxonomie et non celles qui n'appartiennent pas. J'ai pensé à deux façons de réaliser cela, mais je ne sais pas laquelle est la meilleure:

  • inclure uniquement les messages personnalisés qui appartiennent au terme de taxonomie;
  • exclut tous les messages personnalisés qui n'appartiennent pas au terme de taxonomie.

J'ai réussi à faire exactement le contraire de ce que je veux, avec le code suivant:

global $query_string;
$query_args = explode("&", $query_string);
$search_query = array();
foreach($query_args as $key => $string) {
    $query_split = explode("=", $string);
    $search_query[$query_split[0]] = urldecode($query_split[1]);
}

$custom_query = array();
$custom_query['tax_query'][] = array( 'taxonomy' => 'tax-whatever', 'terms' => array('term-whatever'), 'field' => 'slug', 'operator' => 'NOT IN' );
$args = array_merge( $wp_query->query, $custom_query );
query_posts( $args );

$search = new WP_Query($search_query);

Ceci, bien sûr, génère tous les messages personnalisés qui NE SONT PAS DANS le terme, peu importe. Comment puis-je accomplir le contraire?

MODIFIER

Je vais essayer d'expliquer un peu mieux mon problème. Utilisons un exemple.

Imaginez que j'ai une taxonomie appelée "Sélectionné" et un seul terme de taxonomie appelé "Oui" que les utilisateurs peuvent choisir avec une case à cocher. J'imagine que j'aurais dû utiliser deux cases à cocher ("Oui" et "Non"), mais je pensais que cela n'avait pas beaucoup de sens à l'époque.

Lorsque les utilisateurs recherchent quelque chose sur le site Web, toutes les pages, les publications et les publications personnalisées apparaissent dans les résultats. La seule chose que je veux supprimer des résultats de la recherche sont les messages personnalisés qui ne sont pas associés avec le terme de taxonomie "Oui", laissant tout le reste tel quel. Cela signifie que je veux éditer toutes les pages, tous les articles et tous les articles personnalisés "Oui".

Des idées comment je peux réaliser ceci? Merci.

METTRE À JOUR

Voici une idée que j'avais: est-il possible de faire deux requêtes et de fusionner les résultats?

  • Une requête avec toutes les publications et toutes les pages sauf la publication personnalisée ('exclude_from_search' => true);
  • Autre requête avec uniquement les publications personnalisées correspondant au terme de taxonomie ($custom_query['tax_query'][] = array( 'taxonomy' => 'tax-whatever', 'terms' => array('term-whatever'), 'field' => 'slug', 'operator' => 'IN' );).

Cependant, si j'utilise quelque chose comme:

$mergedposts = array_merge( $wp_query->query, $custom_query );
query_posts( $mergedposts );

Il ne me montrera que les messages personnalisés.

Je suppose que je pourrais faire une requête directe avec SQL mais je n’ai jamais travaillé avec. Bien que ce soit quelque chose que je souhaite apprendre à l'avenir, pour le moment, cela ne semble pas être un bon moyen de résoudre ce type de problème, car je ne comprendrai pas ce que je fais.

Pour le moment, ma meilleure option est de créer un nouveau terme de taxonomie et de classer toutes les publications personnalisées "non catégorisées". Cependant, ils sont quelques centaines, donc cela prendra un certain temps.

NOUVELLE MISE À JOUR

J'ai trouvé un moyen de détecter si une publication personnalisée appartient à un terme spécifique d'une taxonomie. C'est un morceau de code que j'ai ramassé quelque part, car je n'ai pas les connaissances PHP pour créer quelque chose comme cela tout seul. Cependant, je comprends ce qui se passe et je l’adapte à ma situation.

function is_selected( $selected, $_post = null ) {
    if ( empty( $selected ) )
        return false;

    if ( $_post )
        $_post = get_post( $_post );
    else
        $_post =& $GLOBALS['post'];

    if ( !$_post )
        return false;

    $r = is_object_in_term( $_post->ID, 'selected', $selected );

    if ( is_wp_error( $r ) )
        return false;

    return $r;
}

Cette fonction fonctionnera correctement mais uniquement si elle est utilisée dans la boucle. Toutefois, si je modifie la boucle une fois la requête de recherche effectuée, la pagination peut être gâchée et le nombre de résultats trouvés est peut-être erroné.

Pas sûr que ce soit un pas dans la bonne direction, mais au moins c'est un pas.

3
Cthulhu

Après avoir lu votre question révisée, il était plus facile de comprendre ce que vous essayez de faire. Ma nouvelle solution ressemble à ce que vous vouliez faire en premier lieu: elle exclut simplement tous les articles de votre type personnalisé mais ne comportant pas le terme "oui":

$custom_query = array();
$custom_query['post_type'] = 'any';

// first, query all the posts of your custom type
// that don't have the "yes"-term:
$tmp_wp_query = new WP_Query(array(
    'posts_per_page' => -1,
    'fields' => 'ids',
    'post_type' => 'your-post-type',
    'tax_query' => array(array(
        'taxonomy' => 'tax-whatever', 'terms' => array('term-whatever'),
        'field' => 'slug', 'operator' => 'NOT IN'
    ))
));

if(!empty($tmp_wp_query->posts)) {
    // Exclude the "yes"-less posts from the actual post query
    $custom_query['post__not_in'] = $tmp_wp_query->posts;
}

// now proceed with your original code and execute the definitive query
$args = array_merge( $wp_query->query, $custom_query );
query_posts( $args );

$search = new WP_Query($search_query);

Le seul inconvénient est qu'il y a maintenant deux requêtes à exécuter. Mais comme la première requête est relativement légère, la perte de performance ne devrait pas être aussi importante.

6
vstm