J'ai un système d'évaluation dans lequel l'utilisateur peut entrer un champ personnalisé "Étoiles" ou "Coeurs", mais quel que soit le choix choisi, il doit entrer une valeur comprise entre 1 et 5. À l'aide de wp_query, je peux trier avec succès l'un de ces éléments. champs personnalisés, mais je ne suis pas sûr de savoir comment trier par les deux. Voici le code que j'utilise pour trier l'un des champs personnalisés "Etoiles":
$args=array(
'posts_per_page' => $con_review_num,
'post_type' => 'con_product_reviews',
'paged' => $paged,
'orderby' => 'meta_value',
'order' => 'DESC',
'meta_key' => 'Stars'
);
Voici ce que j'aimerais que cette fonction fasse (remarquez la dernière ligne):
$args=array(
'posts_per_page' => $con_review_num,
'post_type' => 'con_product_reviews',
'paged' => $paged,
'orderby' => 'meta_value',
'order' => 'DESC',
'meta_key' => 'Stars Hearts'
);
Y a-t-il une autre façon de faire ça?
J'ai eu le même problème et ne pouvais pas trouver un moyen de faire ce travail avec wp_query seul. Au lieu de cela, j'ai attrapé le filtre posts_clauses et collé mon order_by ici. Cela signifiait également faire quelques jointures.
En gros, vous définissez une fonction pour intercepter les posts_clauses (ou l'un des filtres de requête les plus restrictifs; mais utilisons-le simplement pour l'instant), puis dans cette clause JOIN à la table post_meta pour les champs dont vous avez besoin, puis triez-les par ordre.
L'important est de configurer quelque chose pour ensuite supprimer le filtre de requête. Vous pouvez le faire à la fin de la fonction qui l'accompagne, mais je l'ai séparé dans mon plugin, donc je vais m'en tenir à cela. L'événement 'wp' fonctionne bien ici.
add_filter('posts_clauses', 'filterMarkets')
add_filter('wp', 'removeQueryFilter');
public static function removeQueryFilter() {
remove_filter('posts_clauses', 'filterMarkets');
}
public static function filterMarkets($clauses, $wp_query) {
global $wpdb;
$clauses['join'] .=<<<SQL
JOIN {$wpdb->postmeta} AS title_meta ON title_meta.post_id = {$wpdb->posts}.ID AND
title_meta.meta_key = 'fest_sortby'
JOIN {$wpdb->postmeta} AS start_date_meta ON start_date_meta.post_id = {$wpdb->posts}.ID
AND start_date_meta.meta_key = 'fest_market_start_date'
SQL;
$clauses['orderby'] .= " title_meta.meta_value ASC";
$clauses['orderby'] .= " start_date_meta.meta_value ASC";
}
return $clauses;
}
Pourquoi ne pas créer deux champs personnalisés:
rating_type = 'stars' or 'hearts'
rating_score = 1-5
alors vous pouvez commander par un champ personnalisé:
$args=array(
'posts_per_page' => $con_review_num,
'post_type' => 'con_product_reviews',
'paged' => $paged,
'orderby' => 'meta_value',
'order' => 'DESC',
'meta_key' => 'rating_score'
);
et pour savoir quel genre de notation montrer, il suffit d'utiliser:
$rating_type = get_post_meta($post->ID,'rating_type',true);
if ($rating_type == "stars"){
//show star rating
}else{
//show heartsrating
}
Voici comment j'ai accompli cela en utilisant un seul champ personnalisé. Au lieu d'utiliser "Stars" ou "Hearts" comme nom de champ personnalisé et "1", "2", "3", etc. comme valeur, j'ai utilisé "Rating" comme nom et "1 étoile", "2 étoiles "," 3 étoiles ", etc. (ou coeurs au lieu d'étoiles) comme valeur. Étant donné que l'unité de mesure est comprise entre 0 et 5 pour les coeurs et les étoiles, je peux effectuer un tri en fonction de la valeur de champ personnalisée de Notation, puis analyser la valeur à afficher. Voici mon code:
<?php
// setup the query
$args='&posts_per_page='.$con_review_num.'&post_type=con_movie_reviews&paged='.$paged.'&order=DESC&orderby='.$feedsort.'&meta_key=Rating';
$review_loop = new WP_Query($args);
if ($review_loop->have_posts()) : while ($review_loop->have_posts()) : $review_loop->the_post(); $postcount++;
// get the custom field value
$rating = get_post_meta($post->ID, "Rating", $single = true);
$unit = "star"; //default unit is star
if(strpos($rating," Hearts") || strpos($rating," hearts") || strpos($rating," Heart") || strpos($rating," heart")) {
$unit = "heart"; //find out if we're using hearts instead of stars
}
// extract just the number from the rating meta key
$rating = trim(str_replace(" star","",str_replace(" stars","",str_replace(" Star","",str_replace(" Stars","",str_replace(" heart","",str_replace(" hearts","",str_replace(" Heart","",str_replace(" Hearts","",$rating)))))))));
if($stars) { // are we using stars or hearts?
$rating = $stars;
$unit = "star";
} elseif($hearts) {
$rating = $hearts;
$unit = "heart";
}
?>
<div class="stars tooltip" title="<?php echo $rating; ?> / 5 <?php echo $overall; ?>">
<div class="<?php echo $unit; ?><?php if($rating>=1) { ?> full<?php } elseif($rating>0) { ?> half<?php } ?>"> </div>
<div class="<?php echo $unit; ?><?php if($rating>=2) { ?> full<?php } elseif($rating>1) { ?> half<?php } ?>"> </div>
<div class="<?php echo $unit; ?><?php if($rating>=3) { ?> full<?php } elseif($rating>2) { ?> half<?php } ?>"> </div>
<div class="<?php echo $unit; ?><?php if($rating>=4) { ?> full<?php } elseif($rating>3) { ?> half<?php } ?>"> </div>
<div class="<?php echo $unit; ?><?php if($rating>=5) { ?> full<?php } elseif($rating>4) { ?> half<?php } ?>"> </div>
</div>
<?php
}
endwhile;
endif;
?>