web-dev-qa-db-fra.com

Existe-t-il un moyen d'effectuer plusieurs commandes sur une méta_query multiple?

J'expérimente avec des recherches et des critères multiples et la commande. Supposons que nous avons un site immobilier, que tous les articles ont 2 champs personnalisés (price et surface), et que nous souhaitons que le visiteur puisse effectuer une recherche en entrant un:

  • prix minimum
  • prix maximum
  • surface minimale
  • surface maximale

Cela ferait le travail:

function mwm_register_search_filters( $query ) {

    // Only on archive post listings    
    if( $query->is_archive ) {

        $filters_a = array();

        if( !empty( $_GET['price_min'] ) ) $filters_a[] = array( 'key' => 'price', 'value' => $_GET['price_min'], 'compare' => '>=', 'type' => 'numeric' );
        if( !empty( $_GET['price_max'] ) ) $filters_a[] = array( 'key' => 'price', 'value' => $_GET['price_max'], 'compare' => '<=', 'type' => 'numeric' );
        if( !empty( $_GET['surface_min'] ) ) $filters_a[] = array( 'key' => 'surface', 'value' => $_GET['surface_min'], 'compare' => '>=', 'type' => 'numeric' );
        if( !empty( $_GET['surface_max'] ) ) $filters_a[] = array( 'key' => 'surface', 'value' => $_GET['surface_max'], 'compare' => '<=', 'type' => 'numeric' );

        if( !empty( $filters_a ) ) $query->set( 'meta_query' , $filters_a );

    }

    return $query;
}
add_filter( 'pre_get_posts' , 'mwm_register_search_filters' );

C'est génial et ça marche bien. Mais vient ensuite la commande ..

Autant que je sache, Wordpress n'autorise la commande que par une seule clé méta/valeur méta. C'est bien, mais pas assez quand il faut commander selon plusieurs critères. Y a-t-il un moyen de commander par exemple:

  • D'abord par prix ASC
  • Et à prix égal, commandez par surface ASC
3
mike23

À partir de WordPress 3.4.1, il n’ya aucun moyen de sortir de la boîte, par plusieurs méta-valeurs.

Puisque nous ne pouvons pas le faire proprement, nous devrons pirater quelque chose ensemble. Nous pouvons nous connecter à posts_orderby pour modifier manuellement la commande. Ce n'est pas tout à fait joli, mais ça va faire le travail. Voici un exemple:

add_filter('posts_orderby', 'wpse_28390_orderby' );
function wpse_28390_orderby( $orderby ) {
    return str_replace('postmeta.meta_value', 'postmeta.meta_value, mt1.meta_value ASC', $orderby);
}

Plus important encore, cela suppose que "surface" est la deuxième méta_key de votre requête (d'où vient mt1; mt1 est la deuxième clé méta, mt2 est la troisième et ainsi de suite), ce qui dans votre cas ne sera pas toujours correct . Par conséquent, l'appel add_filter doit être effectué après trois vérifications:

  1. si c'est la page où cela serait pertinent,
  2. si la méta_key surface est interrogée (si le paramètre $ _GET est présent), et
  3. quel numéro la méta_key surface est dans la séquence de jointure, puis ajustez mt1 en conséquence

C'est janky, mais encore une fois, ça va marcher.

1
Matthew Boynes