Combining Multiple if into one? - php

I have two wordpress queries and am curious if there is a way to combine them into one?
I have tried else if, but to no avail.
<?php
$posts = get_field('appeal_forms', 'options');
if( $posts ): ?>
<ul>
<?php foreach( $posts as $post): // variable must be called $post (IMPORTANT) ?>
<?php setup_postdata($post); ?>
<li>
<?php the_title(); ?>
</li>
<?php endforeach; ?>
</ul>
<?php wp_reset_postdata(); // IMPORTANT - reset the $post object so the rest of the page works correctly ?>
<?php endif; ?>
And here the second:
<?php
$posts = get_field('misc', 'options');
if( $posts ): ?>
<ul>
<?php foreach( $posts as $post): // variable must be called $post (IMPORTANT) ?>
<?php setup_postdata($post); ?>
<li>
<?php the_title(); ?>
</li>
<?php endforeach; ?>
</ul>
<?php wp_reset_postdata(); // IMPORTANT - reset the $post object so the rest of the page works correctly ?>
<?php endif; ?>

You need to combine both arrays of posts into a single array then loop through it as you were doing.
In the example below I'm getting both arrays, checking they are valid using is_array and then merging them into one using array_merge.
<?php
// Get both post arrays.
$appeal_forms = get_field('appeal_forms', 'options');
$misc = get_field('misc', 'options');
// Check both are arrays.
if ( is_array( $appeal_forms ) && is_array( $misc ) ) {
// Combine the posts into a single array.
$posts = array_merge( $appeal_forms, $misc ); ?>
<ul>
<?php foreach ( $posts as $post ) {
setup_postdata( $post ); ?>
<li>
<?php the_title(); ?>
</li>
<?php } ?>
</ul>
<?php wp_reset_postdata(); ?>
<?php } ?>
If both arrays won't always have posts then the code needs to be adapted. The check I perform means that if appeal_forms or misc is empty then nothing is displayed.
If that's the case the solution I'd propose would be:
$posts = array();
// Check each array individually and add their contents to the post array.
if ( is_array( $appeal_forms ) ) {
$posts = array_merge( $posts, $appeal_forms );
}
if ( is_array( $misc ) ) {
$posts = array_merge( $posts, $misc );
}
if ( $posts ) {…

Related

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.
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(); ?>
You Could do like this in simple and short way:
$args = array(
'post_type' => 'gig'
);
$gigs = get_posts($args);
$songsarr = array();
foreach($gigs as $gig) {
$posts = get_field('songs', $gig->ID);
array_push($songsarr,$posts[0]);
}
//echo "<pre>;
//print_r($songsarr);
$countsongs = array_count_values($songsarr);
echo 'No. of Duplicate Items: '.count($countsongs).'<br><br>';
// print_r($countsongs);
foreach($countsongs as $songID => $songname){
echo get_the_title( $songID );
echo $songname;
}
I have Tried by making Two Custom Post Type(gig, songs) and I got count numbers of song this way that you can show in home page and also you can give condition in last foreach loop if song more than one etc..
Hope this will help you!
Hope help:
<?php
$args = array(
'post_type' => 'song'
);
?>
<?php $loop = new WP_Query($args); ?>
<?php if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post(); ?>
<?php
$song_count = count(get_field('songs', get_the_ID())); <-- add
echo $song_count . " ";
the_title();
?><br />
<?php endwhile; ?>
<?php else: ?>
<!-- No gigs available -->
<?php endif; ?>
<?php wp_reset_postdata(); ?>
My understanding of your question is you are seeking to generate a top 10 list of songs that have the most associated gigs. The best way to approach this would be to generate a set that would map a unique identifier and a count value of how many times that songs has been seen.
Here is an example:
<?php
// Get all the posts
$gigs = get_posts([
'post_type' => 'gigs',
'numberposts' => -1
]);
// We will use this array to key a running tally of
$set = [];
// If the key doesn't exist yet on the array, then we will initialize it, otherwise, increment the count
function add_set_element(&$set, $key) {
if (!isset($set[$key])) {
$set[$key] = 1;
} else {
$set[$key]++;
}
}
function iterate_songs($songs, &$set){
/** #var WP_Post $song */
foreach($songs as $song) {
$key = $song->post_title;// This can be what ever unique identifier you want to get from $song object, such as ID or title
add_set_element($set, $key);
}
}
foreach($gigs as $gig) {
setup_postdata($gig);
$songs = get_the_field('songs');
iterate_songs($songs, $set);
}
Afterwards you can sort and manipulate the $set variable however you feel to get the data you want from it.
Let me know if I misinterpreted your questions, and I can provide another answer.

Get the current post category name inside while loop

I created a custom post type "stm_media_gallery"
And three category inside this custom post type.
I want to display category name associated with each post.
<?php $gallery_query = new WP_Query( array('post_type' =>
'stm_media_gallery', 'posts_per_page' => -1) );
if( $gallery_query->have_posts() ) :
while( $gallery_query->have_posts() ) : $gallery_query->the_post(); ?>
--Display post name and its category name
<?php endif; ?>
<?php endwhile; ?>
You just need to put following code inside loop :
<div>
<?php
foreach((get_the_category()) as $category){
echo $category->name."<br>";
echo category_description($category);
}
?>
</div>
Update in existing code
<?php $gallery_query = new WP_Query(
array('post_type' => 'stm_media_gallery',
'posts_per_page' => -1) );
if( $gallery_query->have_posts() ) :
while( $gallery_query->have_posts() ) : $gallery_query->the_post();
$gallery_category = get_the_category( get_the_ID() );
the_title( '<h3>', '</h3>' );
echo "<br>";
<?php foreach ( $gallery_category as $key => $value) { echo $value->category_nicename; } ?>
<?php endif; ?>
<?php endwhile; ?>
You can use the pre-made WordPress function the_category( $separator, $parents, $post_id ) to print the post categories as links.
Further information on the WordPress Codex: Function Reference: the_category
Edit: Print only the names:
$categories = get_the_category();
if ( ! empty( $categories ) ) {
echo esc_html( $categories->name );
}
Put this inside While Loop
global $post;
$postcat = get_the_category( $post->ID );

ACF - get checkbox values inside flexible content field

Have been going around and around with this and can't make it work - probably something very simple but I've got no hair left - can anyone help me?
<?php
if( have_rows('page_content') ):
while ( have_rows('page_content') ) : the_row();
if( get_row_layout() == 'specs' ):
// check if the nested repeater field has rows of data
if( get_sub_field('objectives') ):
echo '<ul>';
$field = get_field_object('objectives');
$value = $field['value'];
$choices = $field['choices'];
// loop through the rows of data
foreach( $value as $v):
echo '<li>'.$choices.'</li>';
endforeach;
echo '</ul>';
endif;
endif;
endwhile;
endif;
?>
Thanks in advance.
Can you try with the Key of ACF field like this,
$field_key = "field_5039a99716d1d";
$field = get_field_object($field_key);
https://www.advancedcustomfields.com/resources/get_field_object/
Working now ... thanks to the great support team at ACF. I was missing the [$v] after .$choices. Working code below:
<?php
if( have_rows('page_content') ):
while ( have_rows('page_content') ) : the_row();
if( get_row_layout() == 'specs' ):
// check if the nested repeater field has rows of data
if( get_sub_field('objectives') ):
echo '<ul>';
$field = get_field_object('objectives');
$value = $field['value'];
$choices = $field['choices'];
// loop through the rows of data
foreach( $value as $v):
echo '<li>'.$choices.'</li>';
endforeach;
echo '</ul>';
endif;
endif;
endwhile;
endif;
?>

Changing Repeater class based on count in Advanced Custom Fields

I need to be able to have different classes for repeater items based on the count. In other words, the first repeater item needs class="single-item active" and all other repeaters need class="single-item not-visible move-right".
This is what I have so far:
<?php $count = 0; ?>
<?php if (have_rows('features')): while (have_rows('features')) : the_row(); ?>
<?php if(!$count): ?>
<li class="cd-single-item cd-active"></li>
<?php else: ?>
<li class="cd-single-item cd-not-visible cd-move-right"></li>
<?php $count++; endif; endwhile; endif; ?>
Simply set a boolean to false after the first check:
$repeater = get_field('my_repeater_field');
$first = true;
foreach ($repeater as $sub) {
$class = $first ? 'single-item active' : 'single-item not-visible move-right';
// do whatever with $sub and $class here...
$first = false;
}
Your code is almost correct, but you're only increasing $count if (!$count) is false and this never happens because you're only increasing $count if… and so on.
Just put your $count++ after the first endif. I rewrote it like this:
<?php
$count = 0;
if ( have_rows('features') ):
while ( have_rows('features') ) : the_row();
if ( ! $count ): ?>
<li class="cd-single-item cd-active"></li>
<?php else: ?>
<li class="cd-single-item cd-not-visible cd-move-right"></li>
<?php
endif;
$count++;
endwhile;
endif;
?>
Hope this helps!

Wordpress Advanced Custom Fields display field not working in loop

I am using Advanced Custom Fields with Wordpress.
I have a custom post type called VIDEOS which has two fields - video_link and video_artist.
I can call and output the video_link field, but I cannot seem to display the 'video_artist' field using the code below...
<?php
$posts = get_posts(array(
'post_type' => 'videos',
'posts_per_page' => -1
)
));
if( $posts ): ?>
<?php foreach( $posts as $post ):
setup_postdata( $post )
?>
<?php echo wp_oembed_get( get_field( 'video_link' ) ); ?>
<?php the_title(); ?>
<?php the_field('video_artist'); ?>
</div>
<?php endforeach; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
In fact, this line...
<?php the_field('video_artist'); ?>
...breaks the site and displays nothing at all after it appears. No html of any kind.
It's more or less the same code as your, just tested, and it works fine
As #admcfadn said, your are note in a wordpress loop, so you need to add the post id as a parameter of the_field
$posts = get_posts(array(
'post_type' => 'videos',
'posts_per_page' => -1
));
if( $posts ):
foreach( $posts as $post ):
setup_postdata( $post );
the_title();
the_field('video_link', $post->ID);
the_field('video_artist', $post->ID);
endforeach;
wp_reset_postdata();
endif;
If you like to use the loop without arg in the_field that will look like that:
$options = array(
'post_type' => 'videos',
'posts_per_page' => -1
);
$query = new WP_Query( $options );
if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post();
the_title();
the_field('video_link');
the_field('video_artist');
endwhile; endif;
ps: you don't need to use <?php ?> on each line
$post->the_field('video_artist');
you're using get_posts, not wp_query, so you might need to refer to the variables via $post.
&/or troubleshoot it with the following:
the_field('video_artist', $post->ID);
might get if for you.
Or...
$baz = get_field( 'video_artist' ); echo $baz;
Also, looks like you're missing a semi-colon after setup_postdata( $post ) and have an extra closing parentheses after get_posts

Categories