I have the following code:
<div class="documents-posts">
<?php if (!empty($posts)) : ?>
<?php foreach ($posts as $post) : ?>
<?php set_query_var( 'taxonomy', $taxonomy ); ?>
<?php get_template_part('document'); ?>
<?php endforeach; ?>
<?php endif; ?>
</div>
which works fine as long as each post has only one category. When I assign a second category to a post the post is displayed twice. If I make it have 3 categories the post is displayed triple… Why?
Update: Declaration $posts variable
$post_type = 'press-release';
$taxonomy = 'press-release-types';
$categories = $xxxxxx->get_categories($taxonomy);
$posts = $xxxxxx->get_posts_ordered_by_categories($post_type, $taxonomy, $categories);
set_query_var( 'posts', $posts );
set_query_var( 'categories', $categories );
set_query_var( 'taxonomy', $taxonomy );
Update 2: From Helper php
public function get_posts_ordered_by_categories($post_type, $taxonomy, $categories) {
$posts = [];
foreach ($categories as $category) {
$category_posts = $this->get_posts_from_category($post_type, $taxonomy, $category->term_id);
$posts = array_merge($posts, $category_posts);
}
return $posts;
}
protected function get_posts_from_category($post_type, $taxonomy, $category_id) {
return get_posts([
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'term_id',
'terms' => (int) $category_id,
)
),
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
'post_status' => 'publish',
'post_type' => $post_type,
'suppress_filters' => false,
]);
}
In get_posts_ordered_by_categories
you're getting all posts from the category and put it in posts array. You have to check if post is existing in that array. For example:
public function get_posts_ordered_by_categories($post_type, $taxonomy, $categories) {
$posts = [];
foreach ($categories as $category) {
$category_posts = $this->get_posts_from_category($post_type, $taxonomy, $category->term_id);
foreach ($category_posts as $post) {
$posts[$post->ID] = $post;
}
}
return $posts;
}
That way you'll get list of unique posts.