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.
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(); ?>