Ce que vous voulez est possible mais vous obligera à vous plonger dans SQL que j'aime éviter autant que possible (pas parce que je ne le sais pas, je suis un développeur SQL avancé, mais parce que dans WordPress, vous voulez utiliser l'API autant que possible pour minimiser les futurs problèmes de compatibilité liés aux futurs changements potentiels de la structure de la base de données.)
SQL avec un UNION
opérateur est une possibilité
Pour utiliser SQL, vous avez besoin d'un UNION
opérateur dans votre requête, quelque chose comme ceci en supposant que vos slugs de catégorie sont "category-1"
, "category-1"
et "category-3"
:
SELECT * FROM wp_posts WHERE ID IN (
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='category-1'
LIMIT 5
UNION
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='category-2'
LIMIT 5
UNION
SELECT tr.object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='category-3'
LIMIT 5
)
Vous pouvez utiliser SQL UNION avec un posts_join
filtre
En utilisant ce qui précède, vous pouvez simplement passer l'appel directement ou vous pouvez utiliser un posts_join
crochet de filtre comme suit; note J'utilise un hérédoc PHP, alors assurez-vous que le SQL;
flush est à gauche. Notez également que j'ai utilisé une var globale pour vous permettre de définir les catégories en dehors du hook en listant les slugs de catégorie dans un tableau. Vous pouvez mettre ce code dans un plugin ou dans le functions.php
fichier de votre thème :
<?php
global $top_5_for_each_category_join;
$top_5_for_each_category_join = array('category-1','category-2','category-3');
add_filter('posts_join','top_5_for_each_category_join',10,2);
function top_5_for_each_category_join($join,$query) {
global $top_5_for_each_category_join;
$unioned_selects = array();
foreach($top_5_for_each_category_join as $category) {
$unioned_selects[] =<<<SQL
SELECT object_id
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
INNER JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
WHERE tt.taxonomy='category' AND t.slug='{$category}'
LIMIT 5
SQL;
}
$unioned_selects = implode("\n\nUNION\n\n",$unioned_selects);
return $join . " INNER JOIN ($unioned_selects) categories ON wp_posts.ID=categories.object_id " ;
}
Mais il peut y avoir des effets secondaires
Bien sûr, l'utilisation des crochets de modification de requête, comme posts_join
toujours, provoque des effets secondaires dans la mesure où ils agissent globalement sur les requêtes et donc vous devez généralement envelopper vos modifications dans un if
qui ne l'utilise qu'en cas de besoin et quels critères pour tester peuvent être délicats.
Concentrez-vous plutôt sur l'optimisation?
Cependant, je suppose que votre question concerne plus l'optimisation que la possibilité de faire une requête top 5 en temps 3, non? Si tel est le cas, il existe peut-être d'autres options qui utilisent l'API WordPress?
Mieux utiliser l'API transitoires pour la mise en cache?
Je suppose que vos messages ne changeront pas souvent, n'est-ce pas? Que faire si vous acceptez périodiquement les trois (3) requêtes, puis mettez en cache les résultats à l'aide de l' API Transitoires ? Vous obtiendrez du code maintenable et de grandes performances; un peu mieux que la UNION
requête ci-dessus car WordPress stockera les listes de publications sous forme de tableau sérialisé dans un enregistrement de la wp_options
table.
Vous pouvez prendre l'exemple suivant et passer à la racine de votre site Web test.php
pour le tester:
<?php
$timeout = 4; // 4 hours
$categories = array('category-1','category-2','category-3');
include "wp-load.php";
$category_posts = get_transient('top5_posts_per_category');
if (!is_array($category_posts) || count($category_posts)==0) {
echo "Hello Every {$timeout} hours!";
$category_posts = array();
foreach($categories as $category) {
$posts = get_posts("post_type=post&numberposts=5&taxonomy=category&term={$category}");
foreach($posts as $post) {
$category_posts[$post->ID] = $post;
}
}
set_transient('top5_posts_per_category',$category_posts,60*60*$timeout);
}
header('Content-Type:text/plain');
print_r($category_posts);
Résumé
Bien que oui, vous pouvez faire ce que vous avez demandé en utilisant une UNION
requête SQL et le posts_join
crochet de filtre que vous proposez probablement mieux en utilisant la mise en cache avec l' API Transitoires à la place.
J'espère que cela t'aides?