Wordpress: Iterative Parent Page if Custom Field Contains Page ID - wordpress

I am trying to display a list based on the page. The list is built based on data in an ACF custom field, which is in a serialized array.
The list is for employees in a department. I am setting the parent page in Wordpress but want the employees to be listed on all child page. Employees may also need to be listed in multiple departments, so the ACF field is stored as a serialized array.
I have been able to get this to work if the current page is in the array, but am having problems when the data is for a parent, grandparent, etc. page. How can I iterate through this to find the first parent page that matches the criteria?
Relevant code (additional content is displayed, some included in case it is helpful in your answer):
$postid = get_the_ID();
$staffList = get_posts(array(
'post_type' => 'staff',
'meta_key' => 'position_order',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'ministries', // name of custom field
'value' => $postid,
'compare' => 'LIKE',
),
array(
'key' => 'administration', // name of custom field
'value' => $postid,
'compare' => 'LIKE',
)
)
));
if(( $staffList ) != '') {
foreach ( $staffList as $staff ) : setup_postdata( $people );
$pid = $staff->ID;
$featured_img_url = get_the_post_thumbnail_url($pid, 'full');
$highres = get_field('high_res', $pid);
$normal = get_field('normal', $pid);
$biofile = get_field('bio_file', $pid);
$scontent = $staff->post_content;
$contact = apply_filters('the_content',$scontent);
?>
<div class="profile">
<div class="text-center">
<img src="<?php echo $featured_img_url; ?>" width="130"
alt="<?php echo $staff->post_title; ?>">
</div>
<div class="profile__name"><?php echo $staff->post_title; ?></div>
<?php echo $contact; ?>
<?php if ( $biofile != "" ) { ?>
<span class="icon-file"></span> <?php echo $people->post_title; ?> Bio
<?php } ?>
</div>
<?php
endforeach;
wp_reset_postdata();
?>
<?php } endif; ?>
I'm thinking the query needs to be placed in a function, but having a problem getting it to run correctly and then iterate through parent posts until it finds a results. The concept is:
if no employees for current $pageid, then get $parent_pageid and run query. if no employees found, find grandparent_pageid and run query, etc., until either employees are found or there are no more parent pages.
I've found this: Recursive function to get the parent caegory description that seems like a good way to iterate, just having a problem modifying for my needs.
Thanks for your help!

This function will loop through parent posts until it returns results:
function get_staff_posts($post) {
$staffList = new WP_Query( array(
'post_type' => 'staff',
'meta_key' => 'position_order',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'ministries', // name of custom field
'value' => $post->ID,
'compare' => 'LIKE',
),
array(
'key' => 'administration', // name of custom field
'value' => $post->ID,
'compare' => 'LIKE',
),
),
));
$parent = $post->post_parent;
if( !$staffList->have_posts() && $parent != 0 )
get_staff_posts($parent);
return $staffList;
}
The function will return the query, so you could use it in your theme like this:
$staffList = get_staff_posts($post);
if( $staffList->have_posts() ):
while( $staffList->have_posts() ): $staffList->the_post();
// output
endwhile; wp_reset_postdata();
endif;

Related

WP_Query - posts_per_page parameter not working?

So the setup is working fine, however I tried to limit the number of titles shown but nothing is working. What am I missing? So it should be limited to 10 or 5 titles.
I tried everything I could think of but for some reason it is not taking the limit in account.
<?php
$meta_query = array();
$args_booking = array(
'post_type' => 'booking',
'post_status' => array('publish', 'pending', 'canceled'),
'nopaging' => 'false',
'posts_per_page' => 1,
'orderby' => array(
'menu_order' => 'ASC',
'date' => 'DESC',
),
);
$meta_query[] = array(
'key' => GOLO_METABOX_PREFIX. 'booking_item_author',
'value' => $user_id,
'type' => 'NUMERIC',
'compare' => '=',
);
$args_booking['meta_query'] = array(
'relation' => 'AND',
$meta_query
);
//$data_booking = new WP_Query($args_booking);
//$total_post = $data_booking->found_posts;
if( count($results) > 0 ){//if( $total_post > 0 ){
?>
<ul class="listing-detail custom-scrollbar">
<?php foreach ($results as $r):?>
<?php
$lang = $r->lang!='nl'?'/' . $r->lang : '';
$param = http_build_query(json_decode(stripslashes($r->filter_data), true));//json_decode($val, true, JSON_UNESCAPED_SLASHES);
$url = site_url("/") . 'search-results/?' . $param . "&sid=" . $r->ID;
?>
<li><?php echo get_city($r->city_id)->name;?></li>
<?php endforeach;?>
</ul>
<?php
}else{
?>
<span class="no-item"><?php esc_html_e('No recent plan', 'golo-framework'); ?></span>
<?php
}
?>
There are a couple of filters that run before WP_Query actually executes the desired SQL command, which means you posts_per_page setting can actually get overridden before your results are returned.
Unfortunately this can be done in both the theme you may be using, and in any plugins that maybe active. What I would do in this situation, is first check any of my other code to see if I am modifying the pre_get_posts or the post_limits filter.
I'd then check the theme settings to see if it has a setting for this, and last resort would be to disable plugins one by one to see if any of those are filtering the query.
Lastly don't discount cache being an issue. Some hosts can force caching of pages, even when you are logged in to WordPress.
I corrected this like this.
So you can take a pattern.
Let me know if it does not work or does
I used posts_per_page to set the number of posts per page (number of titles per page) Or you can use numberposts.
numberposts is used to search and display only 20 posts and posts_per_page is used to display 20 posts per page.
$args_booking = array(
'post_type' => 'booking',
'post_status' => array('publish', 'pending', 'canceled'),
'nopaging' => 'false',
'posts_per_page' => 20, // for set limit.
'orderby' => array(
'menu_order' => 'ASC',
'date' => 'DESC',
),
'meta_query' => array(
array(
'key' => GOLO_METABOX_PREFIX . 'booking_item_author',
'value' => $user_id,
'type' => 'NUMERIC',
'compare' => '=',
)
)
);
$query = new WP_Query($args_booking);
$results = $query->get_posts();
if (count($results) > 0) {//if( $total_post > 0 ){
?>
<ul class="listing-detail custom-scrollbar">
<?php foreach ($results as $r): ?>
<?php
$lang = $r->lang != 'nl' ? '/' . $r->lang : '';
$param = http_build_query(json_decode(stripslashes($r->filter_data), true));//json_decode($val, true, JSON_UNESCAPED_SLASHES);
$url = site_url("/") . 'search-results/?' . $param . "&sid=" . $r->ID;
?>
<li>
<a href="<?php echo $url; ?>" class="place-view"
data-id="<?php echo $r->ID; ?>">
<?php echo get_city($r->city_id)->name; ?>
</a>
</li>
<?php endforeach; ?>
</ul>
<?php
} else {
?>
<span class="no-item"><?php esc_html_e('No recent plan', 'golo-framework'); ?></span>
<?php
}

How to get the same post to not show twice when being pulled with a counter

So I have this as the post counter
<?php
if ( $postcounter%6== 0 )
include( locate_template( '/my-include.php', false, false ) );
?>
<?php
endwhile;
wp_reset_postdata();
endif;
//resets the hotel counter to zero so it can show another featured article after the next 6 hotels.
$postcounter = 0;
?>
I am pulling the posts with an include that has this for the loop
<?php
$offset = rand(1, 100);
$args = array(
'orderby' => 'rand',
'post_type' => 'blog',
'posts_per_page'=>1,
'meta_query' => array(
array(
'key' => 'status',
'value' => 'featured'
)
),
'tax_query' => array(
array(
'taxonomy' => 'content',
'field' => 'slug',
'terms' => 'my-category'
)
)
);
$pull_articles = new WP_Query( $args );
?>
This does currently work but it seems to show the same post a lot. Is there a way to make sure it never shows the same post? Like a prevention on duplicate posts even though I am using a counter and its posting per every 6th post?
It might be a little hacky, but you could save the ids for the posts you've returned in an array and pass those to wp's post__not_in argument.

Why isn't this Wordpress query sorting properly

I have a custom post_type called special_listing which contains a custom field called listing_index. A special_listing with a listing_index of 20, should appear before one with an index of 15, then 10, and so on. However this doesn't appear to be working and listings appear in whatever order they choose.
I'm not a PHP or Wordpress guy, I mainly deal with ASP.Net and C# so this is a bit confusing for me. Is there some simple mistake I'm making?
Function:
// Get the first $count listings with the highest indices for a given $region_slug:
function get_listings($region_slug, $count) {
$args = array(
'post_type' => 'special_listing',
'meta_key' => 'listing_region_slug',
'meta_value' => $region_slug
);
$posts = get_posts($args);
sort_array_on_field($posts, 'listing_index', 'DESC');
truncate_array($posts, $count);
return $posts;
}
View:
<?php
$listings = get_listings(get_microsite_slug() . '-microsite-home-featured', 4);
$i = 0;
if (sizeof($listings) > 0) : while ($i < sizeof($listings)) : $listing = $listings[$i]; // Loop and set current listing
?>
<section>
<a href="<?php echo $listing->destination; ?>">
<h3><?php echo $listing->post_title; ?></h3>
<p><?php echo $listing->post_content; ?></p>
</a>
</section>
<?php $i++; ?>
<?php endwhile; ?>
<?php endif; ?>
My attempt:
I don't know how to return the listing_index value
function get_sorted_listings($region_slug, $count){
$args = array(
'post_type' => 'kodakalaris_listing',
'meta_query' => array(
'relation' => 'AND',
array (
'key' => 'listing_region_slug',
'value' => $region_slug
),
array (
'key' => 'listing_index',
'value' => ''
),
orderby: 'listing_index',
order: 'DESC'
)
);
$posts = get_posts($args);
truncate_array($posts, $count);
return $posts;
}
Update
Trying a new way and it now pulls the content in by the published date. Still not ordering by listing_index, but at least it's not completely random either. I began looking to meta_query. Won't this only return a result with a single value? I've also tried out this other SO answer, but I find it's implementation confusing.
<?php
$args = array(
'post_type' => 'kodakalaris_listing',
'meta_key' => 'listing_region_slug',
'meta_value' => get_microsite_slug() . '-microsite-home-featured',
'posts_per_page' => 4,
'order' => 'DESC',
'orderby' => 'listing_index'
);
$listings = new WP_Query($args);
if ($listings->have_posts()) : while ($listings->have_posts()) : $listings->the_post();
?>
...
...
<?php
endwhile;
endif;
?>
You don't need to sort after you query. WP_Query has orderby parameters:
function get_listings($region_slug, $count) {
$args = array(
'post_type' => 'special_listing',
'meta_key' => 'listing_region_slug',
'meta_value' => $region_slug,
'orderby' => 'meta_value_num'
);
$posts = new WP_Query($args);
return $posts;
}
You'll then want to use The Loop rather than a foreach loop, in your view.
So I was able to figure this out after reading this article, but basically assigning a name to each meta_query array allows you to call which one should take priority when using orderby.
$args = array(
'post_type' => 'special_listing',
'posts_per_page' => 4,
'orderby' => 'index_clause',
'meta_query' => array (
'site_clause' => array (
'key' => 'listing_region_slug',
'value' => get_microsite_slug() . '-microsite-home-featured'
),
'index_clause' => array (
'key' => 'listing_index',
)
)
);
Change the function to :
<?php
// Get the first $count listings with the highest indices for a given $region_slug:
function get_listings($region_slug, $count) {
$args = array(
'post_type' => 'special_listing',
'orderby' => 'listing_index',
'order' => 'DESC',
'meta_key' => 'listing_region_slug',
'meta_value' => $region_slug
);
$posts = get_posts($args);
return $posts;
}

How to query on custom fields in Wordpress?

I'm trying to query posts based on a custom field, and then display them in a loop. I've checked and double checked my code against the codex and other sources, but the query still does not appear to be working. What am I doing wrong?
Stripped down to the essentials, my code looks like this:
<?php
$args = array(
'meta_key' => 'my_custom_field'
);
$my_query = new WP_Query( $args );
?>
<?php if ( $my_query->have_posts() ) { ?>
<p>Success, we have posts!!!</p>
<?php } else { ?>
<p>Uh Oh, No posts!!!</p>
<?php } ?>
The conditional statement is dropping through and returning "Uh Oh, no posts".
I've checked the postmeta table, and there are definitely posts that contain the meta_key _my_custom_field. I have tried the query both with and without leading underscore.
What am I doing wrong?
I use this for search a date between two custom dates field in my custom post type "porfolio", i think that you are in a similar situation:
$args = array(
'post_type' => 'portfolio',
'posts_per_page' => '10',
'meta_query' => array(
array('key' => 'portfolio_start_date', 'value' => data_to_db2($ricerca_data), 'compare' => '<=', 'type' => 'NUMERIC'),
array('key' => 'portfolio_end_date', 'value' => data_to_db2($ricerca_data), 'compare' => '>=', 'type' => 'NUMERIC')
)
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
$post_count = wp_count_posts();
while ( $the_query->have_posts() ) {
// DO WHAT YOU WANT
}
}
My advice is to use meta_query in $args array

Wordpress Query based on Checkbox Value

I'm trying to query my custom post type of "projects" and return all posts that have the "custom_featured" checkbox checked on. This is my current query, however it's not returning anything although I have several posts with that checkbox checked.
$args = array(
'post_type' => 'projects',
'meta_query' => array(
array(
'key' => 'custom_featured',
'value' => 'true',
'compare' => '='
)
)
);
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
while ($my_query->have_posts()) : $my_query->the_post(); ?>
<a href="<?php the_permalink();?>">
<h1><?php the_title(); ?> </h1>
</a>
<?php endwhile;
}
wp_reset_query();
I figured this out. The 'value' should be "on" and not "true"
Use the following code, if you are saving text values in the database from checkbox
'meta_query' => array(
array(
'key' => 'custom_field_key',
'value' =>'custom_field_value',
'compare' => 'LIKE'
)

Resources