Search code examples
phpwordpressrelationshipadvanced-custom-fieldscustom-post-type

Count the number of relation posts in ACF


I'm working on a website for a band where you can add gigs and add the songs played on that specific gig.

So I've created two custom post types: - gig - song

I got a custom field "Songs" of type "Relationship". This field is shown on the Custom Post Type. This way I can add songs to a specific gig. This works perfectly.

But I want to show some statistics on the homepage of that website: I want to count how many times a specific song is played and show the top 10. So I guess that I have to loop over the gig custom post type and count the relation with 'songs'.

I thought this would do the trick:

<?php 
    $args = array(
        'post_type' => 'gig'
    ); 
?>

<?php $loop = new WP_Query($args); ?>

<?php if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post(); ?>

    <?php 
    print_r(get_field('songs'))
    //$song_count = count(get_field('songs')); 
    //echo $song_count . " ";

    the_title(); 

    ?><br />

<?php endwhile; ?>

<?php else: ?>
    <!-- No gigs available -->
<?php endif; ?>
<?php wp_reset_postdata(); ?>

You can find the result of the print_r over here: http://snippi.com/s/njzg3uu

For example: the song "A memory" is on 2 gigs. That why you can find it twice in the array. The song "Wasted" can be found only once, because it's on 1 gig.


Solution

  • You can use this code to create an array of all the songs:

    <?php 
        $args = array(
            'post_type' => 'gig'
        ); 
    
        $countArray = []; //create an array where you can put all the song id's and the number of times played
    ?>
    
    <?php $loop = new WP_Query($args); ?>
    
    <?php if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post(); ?>
    
        <?php
            $posts = get_field('songs');
    
            if( $posts ): 
                    foreach( $posts as $post):
                        setup_postdata($post); 
    
                        //if the song id already exists -> count + 1
                        if (array_key_exists($post->ID, $countArray)){
                            $countArray[$post->ID]++;
                        }
                        else { // otherwise the song is played 1 time
                            $countArray[$post->ID] = 1;    
                        } 
                    endforeach;
    
                wp_reset_postdata();
            endif;
        ?>
    
    <?php endwhile; ?>
    

    The code above will create an array of post ID's of songs and the number of times it is used in the post_type "gig".

    Now you can use the array $countArray and do whatever you want with it. In your example you want to sort it, so you have to do arsort($countArray); This way the array is sorted by it's value (the number of times played) from high to low.

    Then you have to loop through the array: foreach ($countArray as $key => $value) { ?>

    <?php echo get_post_permalink($key); //=the permalink of the song ?>
    <?php echo get_the_title($key); //= the title of the song ?>
    <?php echo $value; //number of times play in a gig ?>
    
    <?php  
    }
    

    So the full code is:

    <?php 
        $args = array(
            'post_type' => 'gig'
        ); 
    
        $countArray = [];
    ?>
    
    <?php $loop = new WP_Query($args); ?>
    
    <?php if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post(); ?>
    
        <?php
            $posts = get_field('songs');
    
            if( $posts ): 
                    foreach( $posts as $post):
                        setup_postdata($post); 
    
                        if (array_key_exists($post->ID, $countArray)){
                            $countArray[$post->ID]++;
                        }
                        else {
                            $countArray[$post->ID] = 1;    
                        } 
                    endforeach;
    
                wp_reset_postdata();
            endif;
        ?>
    
    <?php endwhile; ?>
    
    <?php
        arsort($countArray);
    
        foreach ($countArray as $key => $value) {
        ?>
    
            <?php echo get_post_permalink($key); //=the permalink of the song ?>
            <?php echo get_the_title($key); //= the title of the song ?>
            <?php echo $value; //number of times play in a gig ?>
    
        <?php  
        }
    ?>
    
    <?php else: ?>
        <!-- No gigs available -->
    <?php endif; ?>
    <?php wp_reset_postdata(); ?>