web-dev-qa-db-fra.com

Utilisez pre_get_posts pour trier meta_key par un tableau de valeurs

Scénario: J'ai un groupe de revendeurs chargés sous un type de message "revendeur". Chacun de ces revendeurs a un "rating" qui est une valeur de chaîne telle que Gold, Bronze, Silver - indique leur statut en tant que revendeur. Chaque revendeur est également classé dans un pays.

Ce que j'ai: J'ai utilisé l'action pre_get_posts pour trier meta_value, asc ou desc. Cela fonctionne bien.

function my_pre_get_posts( $query ) {
    // do not modify queries in the admin
    if( is_admin() ) {
        return $query;   
    }

    if( isset($query->query_vars['country']) ) {  
        $query->set('orderby', 'meta_value');
        $query->set('meta_key', 'partner_status');   
        $query->set('order', 'ASC'); 
    }

    return $query;
}

add_action('pre_get_posts', 'my_pre_get_posts');

Je veux plutôt pouvoir spécifier l'ordre de tri de sorte que les revendeurs Gold soient d'abord, ensuite les revendeurs Silver, puis les revendeurs Bronze, etc. Ainsi, le pseudo-code:

function my_pre_get_posts( $query ) {
    // do not modify queries in the admin
    if( is_admin() ) {
        return $query;   
    }

    if( isset($query->query_vars['country']) ) {  
        $query->set('orderby', ['Gold','Bronze','Silver']); // pseudo here
        $query->set('meta_key', 'partner_status');   
        $query->set('order', 'ASC'); 
    }

    return $query;
}

add_action('pre_get_posts', 'my_pre_get_posts');

J'espère que cela a du sens pour quelqu'un! :)

1
RiaanP

Après quelques essais supplémentaires, il est apparu que les résultats ne consistaient pas en un tri naturel. J'ai fait quelques changements. C'est moche ... mais ça marche.

Okidokes, je ne pouvais donc pas obtenir que cela trie comme je le souhaitais avec les fonctions de tri de Wordpress. (sauf pour un avertissement PHP qui est apparemment un bogue .)

Voici ce que j'ai fait. (J'aurais dû mentionner que j'utilise le plugin ACF.)

Dans archive.php, juste avant la boucle de la requête:

<?php if (have_posts()) : 
        // here we are going to populate the "menu_order"
        $statusArr = ['Gold','Silver','Bronze']; // set up the desired order in which the posts should arrive
        while (have_posts()) : the_post(); // start a loop
            $position = array_search(get_field('partner_status'), $statusArr); // find the index number of the post's "partner_status" relevant to everything in the array
            //$post->menu_order = $position; // update the menu order for the post with that index number (thus building a layered reference)
            if ( empty( $post->menu_order ) ) wp_update_post( array('ID'=>$post->ID,'menu_order'=>$position) ); // here we physically write a menu order into the post so that on subsequent visits, it will sort correctly
        endwhile;

        function home_orderby( $a, $b ) { // this function does the comparison for the usort
            global $posts;
            $apos = $a->menu_order; // compare menu_orders
            $bpos = $b->menu_order;
            return ( $apos < $bpos ) ? -1 : 1;
        }
        //@usort( $wp_query->posts, "home_orderby" ); // If all you want is to sort by the order, then you could still use this

    rewind_posts(); // rewind posts to use in the main loop that creates the HTML ?>

Dans functions.php, j'utilise ensuite le hook d'action pre_get_posts comme ceci:

function my_pre_get_posts( $query ) {
    // do not modify queries in the admin
    if( is_admin() ) {
        return $query;   
    }

    if( isset($query->query_vars['country']) ) {  
        $query->set('orderby',array( 'menu_order' => 'ASC', 'title' => 'ASC' ));
    }
}

add_action('pre_get_posts', 'my_pre_get_posts');

Je vois maintenant les articles de mon type personnalisé commandés dans l'ordre que j'ai spécifié en haut de mon $ statusArray. Jours heureux!

Merci pour votre contribution, Pieter. Cela m'a fait réfléchir sur le bon chemin. :)

1
RiaanP