web-dev-qa-db-fra.com

Comment sélectionner les produits WooCommerce par post_meta et les commander

J'utilise le code suivant pour sélectionner des produits avec les post_metas suivants:

_product_new, _product_almost_new, _product_old

add_action( 'woocommerce_product_query', 'custom_vtp_shop_order' );

function custom_vtp_shop_order($q){
    if ( ! $q->is_main_query() ) return;
    if (! is_admin() && (is_shop() || is_archive) ) {

        $q->set( 'tax_query', array(array(
            'taxonomy' => 'product_cat',
            'field' => 'slug',
            'terms' => array( 'Sold', 'Service' ),  
            'operator' => 'NOT IN'
        )));

        $q->set('meta_query', array(array(
            'relation' => 'OR',
                'product_new' => array(
                    'key' => '_product_new',
                    'value' => '1',
                ),
                'product_almost_new' => array(
                    'key' => '_product_almost_new',
                    'value' => '1',
                ), 
                'product_old' => array(
                    'key' => '_product_old',
                    'value' => '1',
                )
            )));

        /*THIS HAS NO EFFECT*/
        $q->set('orderby', array(array( 
                'product_new' => 'DESC',
                'product_old' => 'DESC',
                'product_almost_new' => 'DESC',
            )        
        ));

    }

}

Je souhaite que les produits soient ensuite affichés dans l'ordre suivant:

  1. nouveau produit
  2. produit_old
  3. product_almost_new

J'utilise $ q-> set ('orderby', array (......), mais cela n'a aucun effet. Mes produits sont toujours commandés product_old, product_almost_new, product_new.

Des idées pour lesquelles mon "orderby" ne fonctionne pas? Merci d'avance pour votre aide!

1
Richard Tinkler

Avec WP_Query, il est uniquement possible de trier une méta-valeur en définissant l'argument meta_key avec la clé à trier, et orderby à meta_value (ou meta_value_num si la valeur doit être triée numériquement).

Voici à quoi ressembleraient les arguments:

$args = array(
    'meta_key' => '_product_new',
    'orderby'  => 'meta_value_num',
    'meta_query' = array(
        'relation' => 'OR',
        array(
            'key'   => '_product_new',
            'value' => '1',
        ),
        array(
            'key'   => '_product_almost_new',
            'value' => '1',
        ), 
        array(
            'key'   => '_product_old',
            'value' => '1',
        )
    )
);

Cela interrogera tous les articles ayant _product_new, _product_almost_new ou _product_old et les classera de manière à ce que ceux avec _product_new soient en haut ou en bas (selon la variable order).

Le problème est que cela ne triera que par une méta-valeur, _product_new, et ignorera les autres. Mais ceci est juste une limitation de WP_Query. Il n'est pas possible de trier les résultats selon plusieurs méta-valeurs.

Une solution potentielle consiste à avoir une seule clé méta, par exemple _product_age, et à lui attribuer une valeur numérique représentant chacun des états dans lesquels vous souhaitez trier. Ainsi, au lieu d'avoir _product_new comme booléen, définissez _product_age sur 1, au lieu de _product_almost_new, définissez _product_age sur 3 et au lieu de _product_old, définissez _product_age sur 2.

Ensuite, vous pouvez utiliser ces arguments pour trier comme vous le souhaitez;

$args = array(
    'meta_key' => '_product_age',
    'orderby'  => 'meta_value_num',
    'order'    => 'ASC',
    'meta_query' = array(
        array(
            'key'     => '_product_age',
            'value'   => array( 1, 2, 3 ),
            'compare' => 'IN',
        ),
    )
);
2
Jacob Peattie