web-dev-qa-db-fra.com

Comment commanderby meta_value_num avec le signe dollar ($)

Les champs personnalisés ont tous des prix comprenant des signes $ et un point comme séparateur.

$theQuery = new WP_Query(array(
'orderby' => 'meta_value_num',
'meta_key' => 'price',
'order' => ASC  
));

Tous formatés comme ceci:

24,95 $ 190,00 $ 1,40 $

Ils ne trieront pas correctement à cause du signe dollar. Est-il possible d'ignorer ou de supprimer le premier caractère/signe $ dans ce WP_Query?

1
coder

Vous pouvez également utiliser le filtre posts_orderby:

function wpse155827_posts_orderby_price( $orderby ) {
    return str_replace( 'wp_postmeta.meta_value', 'substr(wp_postmeta.meta_value, 1)', $orderby );
}
add_filter( 'posts_orderby', 'wpse155827_posts_orderby_price' );
$theQuery = new WP_Query( array(
    'orderby' => 'meta_value_num',
    'meta_key' => 'price',
    'order' => 'ASC',
    'suppress_filters' => false,
) );
remove_filter( 'posts_orderby', 'wpse155827_posts_orderby_price' );
3
bonger

Vous devrez utiliser le filtre post_clauses pour créer du code SQL personnalisé:

add_filter( 'posts_clauses', 'wpse155827_price_sort', 10, 2 );

function wpse155827_price_sort( $clauses, $wp_query ) {
    $orderby = $wp_query->get( 'orderby' ); 
    $order = ( $wp_query->get( 'order' ) == 'desc') ? 'DESC' : 'ASC';
    if( 'price' === $orderby ) {
        $clauses['join'] .= " LEFT JOIN {$wpdb->postmeta} price ON( {$wpdb->posts }.ID = price.post_id AND price.meta_key = 'price') ";
        $clauses['orderby'] = " CONVERT( REPLACE(price.meta_value, '$', ''), DECIMAL(13,2) ) " . $order;
    }

    return $clauses;
}

Fondamentalement, il s’agit d’un filtre qui crée un code mySQL personnalisé dans votre requête chaque fois que vous définissez orderby sur price. dans le code mySQL, il prend la méta-valeur, supprime le signe $, les convertit en décimal. Cela lui permettra de trier correctement maintenant.

0
Manny Fleurmond