web-dev-qa-db-ja.com

カスタム分類条件に従って複数のカスタム投稿タイプから投稿を取得する方法

私は2つのカスタム投稿タイプを持ち、それぞれにtaxonomiesを分けています。

  1. 投稿の種類 - dramas ---------分類法 - drama_taxonomy
  2. 投稿の種類 - reality_shows - 分類法 - reality_shows_taxonomy

今のところ、私はそれが用語名の下に表示されているページにdramas投稿タイプの投稿を表示しています。

コード :

<?php       
//fetching the terms for the 'drama_taxonomy' taxonomy
//HERE I WANT TO INCLUDE 'reality_shows_taxonomy' taxonomy too
$terms = get_terms( 'drama_taxonomy', array(
    'orderby'    => 'count',
    'hide_empty' => 0
) );

// now run a query for each dramas terms
foreach( $terms as $term ) {

    // Define the query
    $args = array(
        'post_type' => 'dramas', //HERE I WANT TO INCLUDE 'reality_shows' custom post type too
        'drama_taxonomy' => $term->slug
    );
    $query = new WP_Query( $args ); 
?>
<div class="white-theme">
    <div class="wrapper space">
        <div class="latest-sec">
            <div class="schedule-header">
                <ul class="nav">
                    <li class="content-title"><?php echo $term->name ?></li>
                </ul>
            </div>
            <div style="margin-top:25px;position:relative;padding:0 2%;">
                <div class="video-list-container" id="video-content">
                    <?php 
                        while ( $query->have_posts() ) : $query->the_post(); 
                        $image_id = get_post_thumbnail_id();
                        $image_url = wp_get_attachment_image_src($image_id,'drama_realityshow_home_page_thumb', true);  
                        if ( 'reality_shows' == get_post_type() ) { 
                            $terms = get_the_terms( $post->ID, 'reality_shows_taxonomy' );
                        }
                        else {
                            $terms = get_the_terms( $post->ID, 'drama_taxonomy' );
                        }
                    ?>                                                                              
                    <div class="item">
                        <a href="<?php the_permalink(); ?>" class="standard-height">
                        <img src="<?php echo $image_url[0]; ?>" width="300" height="168" class="hoverZoomLink">
                        </a>
                        <div class="new-cat">
                            <?php 
                                foreach($terms as $term) {
                                  echo $term->name; // HERE I WANT TO GET TERMS FROM BOTH TAXONOMIES
                                } ?>
                        </div>
                    </div>
                    <?php endwhile; ?>
                </div>
                <a class="load-more" href="javascript:load_more()" style="display: none;"></a>
            </div>
        </div>
    </div>
</div>
<?php } ?

私もreality_showsからの投稿を受け取りたいと思います、そしてそれはtermsという名前で表示されるべきです。

上記の必要性に従って、どうやってこのコードを修正/更新できますか?

1
Foolish Coder

ここでのあなたの最善の解決策は、あなたが問い合わせるところで single queryを実行することでしょう。

  • すべての投稿タイプ

  • 分類法に関係なくすべてからの投稿

これらがすべて揃ったら、usort()を使って結果をソートすることができます。投稿タイプの並べ替え方法がわかりませんが、投稿タイプと用語で並べ替えたいとします。

それでは、コードを見てみましょう。しかし、その前に、いくつかの重要な注意事項を見てみましょう。

考慮すべき重要事項

  • 次のコードはテストされていないため、バグがある可能性があります。デバッグをオンにしてローカルで最初に実行することをお勧めします。

  • コードは少なくともPHP5.4を必要とし、短い配列構文と直接的な配列参照解除のために古いバージョンで致命的エラーを引き起こします。まだ古いバージョンを使用している場合は、アップグレードすることをお勧めします。 PHP5.4より前のすべてのバージョンはEOLされています。これらのバージョンをまだ使用している場合、サイトに大きなセキュリティ上のリスクがあります。

  • 非常に重要 usort()のソート関数は、クエリに1つまたは2つの投稿タイプがある場合にのみ正常に機能します。2つ以上の投稿タイプがある場合、関数内のロジックは正しく機能しません。また、各投稿タイプに1つの分類法が割り当てられている場合でも、ロジックは期待どおりに機能します。さらに、投稿に複数の用語が割り当てられている場合は、最初の用語のみがソート目的に使用されます。

  • 理解しやすくするために、コード自体に沿って進むにつれて、コードについて説明します。

コード

// Define our query arguments
$args = [
    'post_type' => ['dramas', 'reality_shows'], // Get posts from these two post types
    // Define any additional arguments here, but do not add taxonomy parameters
];
$q = new WP_Query( $args );

/**
 * We now need to sort the returned array of posts stored in $q->posts, we will use usort()
 *
 * There is a bug in usort causing the following error:
 * usort(): Array was modified by the user comparison function
 * @see https://bugs.php.net/bug.php?id=50688
 * This bug has yet to be fixed, when, no one knows. The only workaround is to suppress the error reporting
 * by using the @ sign before usort
 *
 * UPDATE FROM COMMENTS FROM @ birgire
 * The usort bug has been fixed in PHP 7, yeah!!
 */
@usort( $q->posts, function ( $a, $b )
{
    // Sort by post type if two posts being compared does not share the same post type
    if ( $a->post_type != $b->post_type )
        return strcasecmp( $a->post_type, $b->post_type ); // Swop the two variable around for desc sorting

    /**
     * I we reach this point, it means the two posts being compared has the same post type
     * We will now sort by taxonomy terms

     * The logic for the code directly below is, we have two post types, and a single post can only be assigned to 
     * one post type, so a post can only be from the dramas post type or from the reality_shows post type. We also just
     * need to check one of the two posts being compared as we know both posts are from the same post type. If they
     * they were not, we would not have been here
     *
     * The socond part of the logic is that the drama_taxonomy is only assigned to the dramas post type and the 
     * reality_shows_taxonomy is only assigned to the reality_shows post type, so we can set the taxonomy according
     * to post type
     */
    $taxonomy = ( $a->post_type == 'dramas' ) ? 'drama_taxonomy' : 'reality_shows_taxonomy';
    $terms_a = get_the_terms( $a->ID, $taxonomy );
    $array_a = ( $terms_a && !is_wp_error( $terms_a ) ) ? $terms_a[0]->name : 'zzzzz'; // zzzz is some crappy fallback

    $terms_b = get_the_terms( $b->ID, $taxonomy );
    $array_b = ( $terms_b && !is_wp_error( $terms_b ) ) ? $terms_b[0]->name : 'zzzzz'; // zzzz is some crappy fallback

    // We will now sort by terms, if the terms are the same between two posts being compared, sort by date
    if ( $array_a != $array_b ) {
        return strcasecmp( $array_a, $array_b ); // Swop the two variables around to swop sorting order
    } else {
        return $a->post_date < $b->post_date; // Change < to > to swop sorting order around
    }
}, 10, 2 );

// $q->posts is now reordered and sorted by post type and by term, simply run our loop now

あなたのループはこのように見えるはずです。あなたはあなたの正確なニーズに合うようにこれを修正する必要があるでしょう

if ( $q->have_posts() ) {
    // Define variable to hold previous post term name
    $term_string = '';
    while ( $q->have_posts() ) {
    $q->the_post();

       // Set the taxonomy according to post type
      $taxonomy = ( 'reality_shows' == get_post_type() ) ? 'reality_shows_taxonomy' : 'drama_taxonomy';
        // Get the post terms. Use the first term's name
        $terms = get_the_terms( get_the_ID, $taxonomy );
      $term_name = ( $terms && !is_wp_error( $terms ) ) ? $terms[0]->name : 'Not assigned';
        // Display the taxonomy name if previous and current post term name don't match
        if ( $term_string != $term_name )
            echo '<h2>' . $term_name . '</h2>'; // Add styling and tags to suite your needs

        // Update the $term_string variable
        $term_string = $term_name;

        // REST OF YOUR LOOP

    }
 wp_reset_postdata();
}
4
Pieter Goosen