I’m trying to filter posts on a page via URL parameter by an ACF checkbox field. I have successfully done this using a select field with the following code:
function my_pre_get_posts( $query ) {
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'product' ) {
if( isset($_GET['wine_style']) ) {
$query->set('meta_key', 'wine_style');
$query->set('meta_value', $_GET['wine_style']);
}
} // if post_type == product
return $query;
}
add_action('pre_get_posts', 'my_pre_get_posts'); //Allow for query string in URL for product style ACF field (red, sparkling, etc.)
The above code works and it is filtering my custom post type of “product” with the ACF select field of “wine_style”. In this field there are various values of “red”, white”, “sparkling” etc so when you go to the URL of “/shop?wine_style=white” it only shows white.
I am trying to do the exact same thing by setting the meta values but for a different field with a checkbox.
I’ve got a CPT of Inventory and I’m trying to show a dropdown of all OEMs. I’ve got the form and pre_get_posts function so that when a user selects an OEM, the page refreshes and shows only the inventory with that OEM.
THE PROBLEM: Once you select an OEM and the page refreshes, and only that OEM shows as an option! No matter what I try (I won’t post them all here because I have tried like 10 different loops) to build the select options, I can’t get it to show ALL OEMs, all the time.
I’ve read through several dozen articles (literally) and cannot seem to find a solution that works.
Here is what I have right now:
In my functions.php
function my_pre_get_posts( $query ) {
// do not modify queries in the admin
if( is_admin() ) {
return $query;
}
// only modify queries for 'inventory' post type
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'inventory' ) {
// allow the url to alter the query
if( isset($_GET['item_oem']) ) {
$query->set('meta_key', 'item_oem');
$query->set('meta_value', $_GET['item_oem']);
$query->set( 'meta_compare', '=' );
}
}
// return
return $query;
}
add_action('pre_get_posts', 'my_pre_get_posts');
and my loop
<?php // using get right now to see the query string and confirm functionality ?>
<form method="get" action="" onchange="submit();">
<?php
$posts = get_posts( array(
'post_type' => 'inventory',
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
));
if ( $posts ): ?>
<select name="item_oem" id="select-oem">
<?php foreach( $posts as $post ): ?>
<option value="<?php the_field('item_oem'); ?>"> <?php the_field('item_oem'); ?> </option>
<?php endforeach; ?>
</select>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
</form>
How can I retrieve ALL values of the item_oem custom field, regardless of what post is being displayed? I’ve tried resetting the query, the post data, etc without luck.
We are working on a project with a cpt and a date field for events.
My clients wants to order the events by date in the admin columns.
add_action( 'pre_get_posts', 'posttype_default_order' );
function posttype_default_order( $query ) {
if( ! is_admin() || ! $query->is_main_query() ) {
return;
}
if ( 'when' === $query->get( 'orderby') ) {
$query->set( 'orderby', 'meta_value_num' );
$query->set( 'meta_key', 'when' );
}
}
But this does not work. Because we want to order this way:
I’m not able to get this sorting correct.
Hi there – I am using ACF form to display user profile details. I have a gallery field, which I have managed to restrict media upload library to the user. All is fine with the uploads however, when the caption or alt tags are changed the edits are not saved. Any idea what I can do to allow this? The code used is below.
And a minor issue the X dashicon is not showing up on the Image to indicate remove. Is there a way to enable this?
Many thanks
Charlie
/**
* Only Show own images in add gallery
*/
//https://support.advancedcustomfields.com/forums/topic/gallery-field-hide-media-library/
function restrict_media_library_to_current_user( $wp_query_obj ) {
if ( ! current_user_can( 'level_5' ) ) {
global $current_user, $pagenow;
if ( ! is_a( $current_user, 'WP_User' ) || 'admin-ajax.php' != $pagenow || $_REQUEST['action'] != 'query-attachments' ) {
return;
}
$wp_query_obj->set( 'author', $current_user->ID );
return;
}
}
add_action( 'pre_get_posts', 'restrict_media_library_to_current_user' );
Hi forum,
i ran into an error i can’t figure out.
i have a ACF Options page for my Theme Logo field (returns Array)
it works on every page template except of my archive-cpt.php
i try to sort my cpt by acf field and have this in my functions file
function sort_by_date_termin( $query ) {
if ( is_post_type_archive( 'termin') ) {
$query->set('meta_key', 'datum');
$query->set('orderby', 'meta_value_num');
$query->set('meta_type', 'DATE');
$query->set('order', 'ASC');
return;
}
}
add_filter( 'pre_get_posts', 'sort_by_date_termin', 1);
when i remove this filter the archive-cpt.php gives no errors and the theme logo is normally displayed in the header
when the filter is active i get this error:
<b>Warning</b>: Illegal string offset ‘url’ in <b>/www/htdocs/domain.com/wp-content/themes/mythemename/header.php</b> on line <b>24</b>
Warning</b>: Illegal string offset ‘alt’ in <b>/www/htdocs/domain.com/wp-content/themes/mythemename/header.php</b> on line <b>24</b>
so there must be some conflict with the filter pre_get_posts
this is line 24 in my header.php
$mainlogo = get_field('header_logo' , 'option'); ?>
<img src="<?php echo $mainlogo['url']; ?>" alt="<?php echo $mainlogo['alt']; ?>">
I have a CPT that I am trying to set up an author archive for. On the regular ol’ archive for that post, I am able to get the field and use its contents on the archive page. On the author archive, whether I am using:
get_field('my_field_name')
or
get_field('my_field_name', $post->ID)
The return is not the field’s contents but rather:
string(4) "6124"
In order to get the CPT on the archive I am using the following filter in my funtions.php:
function wpbrigade_author_custom_post_types( $query ) {
if( is_author() && empty( $query->query_vars['suppress_filters'] ) ) {
$query->set( 'post_type', array(
'post', 'know',
));
return $query;
}
}
add_filter( 'pre_get_posts', 'wpbrigade_author_custom_post_types' );
?>
My hunch is that the way I am modifying the $query is the root of the issue here, but honestly, I have no idea. Does anyone see what I’m doing wrong here? Thanks in advance for the help!
Hello and thanks for a great plugin. I probably should not post here since I have no knowledge of PHP, but I hope it’s not too much of a bother.
I’ve created a custom post type called Event and then a custom field with date picker. With the help of a code example in the documentaion on here I was able to sort the events by their date from the date picker field. I added the code to functions.php
function my_pre_get_posts( $query ) {
// do not modify queries in the admin
if( is_admin() ) {
return $query;
}
// only modify queries for 'event' post type
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'event' ) {
$query->set('orderby', 'meta_value');
$query->set('meta_key', 'start_date');
$query->set('order', 'ASC');
}
// return
return $query;
}
add_action('pre_get_posts', 'my_pre_get_posts');
I wonder if it would be possible to have a similar function for hiding past posts/events and only show current day and forward? When looking around I did find code that seemed to do this, but I was not able to change it so it would work or make it into a function.
Thank you in advance.
I’m trying to sort the archive page of a custom post type sfwd_courses using pre_get_post
Here’s stripped down version of my archive page:
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<h3 class="h2 entry-title" style="font-size: 1em;">
<a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a>
</h3>
<?php if ( have_rows( 'presenter' ) ) : ?>
<ul>
<?php while ( have_rows( 'presenter' ) ) : the_row(); ?>
<?php $presenter_info = get_sub_field( 'presenter_info' ); ?>
<?php if ( $presenter_info ) : ?>
<?php $post = $presenter_info; ?>
<?php setup_postdata( $post ); ?>
<li><a>"><?php the_title(); ?></a></li>
<?php wp_reset_postdata(); ?>
<?php endif; ?>
<?php endwhile; ?>
</ul>
<?php else : ?>
<?php // no rows found ?><p>There is no presenter.</p>
<?php endif; ?>
<p>Expires: <?php the_field( 'expiry_date' ); ?></p>
<p>CE Points: <?php the_field( 'ce_points' ); ?> </p>
<?php endwhile; ?>
<?php endif; ?>
If I use this in functions.php, the sorting works but the presenter_info sub-field (which can contain multiple presenter names — its a post object field) does not display:
add_action( 'pre_get_posts', 'my_change_sort_order');
function my_change_sort_order($query){
if(is_post_type_archive( $sfwd_courses )):
$query->set('orderby', 'meta_value');
$query->set('meta_key', 'expiry_date');
$query->set('order', 'DESC');
endif;
};
What am I missing?
I’m currently building a pre_get_posts function that will do the following:
Filter out from the filters that I have set up but also I need some date filtering logic, for example if I have a project that is
from the 1st to the 15th as an example:
If
1. **Filter = from 2nd to 15th = Project shows up**
2. **Filter = from 1st to 12th = Project shows up**
3. **Filter = from 3rd to 10th = Project shows up**
4. **Filter = from 1st to the 15th = Project shows up**
Basically if the start date is between the project date or if the end date is between the project dates
This is the query that i have written so far:
` $meta_query = array(
‘relation’ => ‘AND’,
array(
array(
‘key’ => ‘place’,
‘value’ => $place,
‘compare’ => ‘LIKE’,
),
array(
‘key’ => ‘industry’,
‘value’ => $industry,
‘compare’ => ‘LIKE’,
),
array(
‘key’ => ‘type’,
‘value’ => $type,
‘compare’ => ‘LIKE’,
),
),
array(
‘relation’ => ‘OR’,
array(
‘key’ => ‘date_start’,
‘type’ => ‘DATE’,
‘value’ => $date_start_formatted,
‘compare’ => ‘=’,
),
array(
‘key’ => ‘date_end’,
‘type’ => ‘DATE’,
‘value’ => $date_end_formatted,
‘compare’ => ‘=’,
),
),
array(
‘relation’ => ‘OR’,
array(
‘key’ => ‘date_start’,
‘type’ => ‘DATE’,
‘value’ => array($date_start_formatted, $date_end_formatted),
‘compare’ => ‘BETWEEN’,
),
array(
‘key’ => ‘date_end’,
‘type’ => ‘DATE’,
‘value’ => array($date_end_formatted, $date_start_formatted),
‘compare’ => ‘BETWEEN’,
),
),`
but the logic seems to fail if i select the option 3 from the examples, the project does not show up.
Would greatly appreciate some help or directions
Good day, i have a custom post type which I would want to show on a default category taxonomy page, so I add it to the query like so
function add_custom_post_type_to_query( $query ) {
if ( is_admin() || !$query->is_main_query() )
return $query;
if ( is_category() || is_tag() ) {
$query->set( 'post_type', array('custom_post_type') );
}
return $query;
}
add_action( 'pre_get_posts', 'add_custom_post_type_to_query' );
and after that all of my “the_field()” on said category page doesn’t show up their values. How can i add a CPT to a query and make ACF keep working?
Below code creates a filter option (from a select field) for the admin columns for custom post type ‘measurement’.
function yl_filter_measurement_status() {
$scr = get_current_screen();
if ( $scr->base !== 'edit' && $scr->post_type !== 'measurement') return;
$selected = filter_input(INPUT_GET, 'measurement_status', FILTER_SANITIZE_STRING );
$status_options = get_field_object('measurement_status');
$choices = $status_options['choices'];
echo '<select name="measurement_status">';
echo '<option value="all" '. (( $selected == 'all' ) ? 'selected="selected"' : "") . '>' . __( 'Filter by status', 'gasmetingonline' ) . '</option>';
foreach( $choices as $key => $value ) {
echo '<option value="' . $key . '" '. (( $selected == $key ) ? 'selected="selected"' : "") . '>' . $value . '</option>';
}
echo '</select>';
}
add_action('restrict_manage_posts', 'yl_filter_measurement_status');
function yl_filter_measurement_status_action($query) {
if ( is_admin() && $query->is_main_query() ) {
$scr = get_current_screen();
if ( $scr->base !== 'edit' && $scr->post_type !== 'measurement' ) return;
if (isset($_GET['measurement_status']) && $_GET['measurement_status'] != 'all') {
$query->set('meta_query', array( array(
'key' => 'measurement_status',
'value' => sanitize_text_field($_GET['measurement_status'])
) ) );
}
}
}
add_action('pre_get_posts','yl_filter_measurement_status_action');
Everything works great.
In this same group I have an POST OBJECT field to select the EXECUTIVE from an other custom post type (executive). When I use this above code to create a filter for executive, the filter stays empty.
This probably got to do with the values being in another group.
How can I retrieve the EXECUTIVE values to fill the filter?
Hi,
Im trying to retrieve a option field from within the pre_get_posts filter, it doesnt work and gives me a error 500 each time, I tried retrieving the option field from regular template files ie. single.php and it returns the value there.
Sample code looks like:
add_action('pre_get_posts', function($query) {
if(is_single()){
$option_a = get_field('my_option_field', 'option'); //post object , array of post ids
$query->set('post__in', $option_a);
}
}
Thanks in advance!
I have two custom post types: Stores and Products. When adding a new Stores post, there is an ACF Relationship field to select the Products that would be available at that single store.
Is it possible on the archive page for Stores, to filter by a custom field that is inside the Product post type? For example, a custom field on the Product post type is ‘Status’ which is a radio selection of available, unavailable and archived. Currently, I can only filter the Stores by the custom fields directly associated with the Stores post type.
I’m looking for something like: domain.com/stores/?status=available or domain.com/stores/?status=archived.
Tutorial I’m referencing: https://www.advancedcustomfields.com/resources/creating-wp-archive-custom-field-filter/
archive-stores.php
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
$products = get_field('products'); // acf relationship
?>
<div class="store">
<h4><?php echo get_the_title(); ?></h4>
<?php if( $products ): ?>
<?php foreach( $products as $product ):
$status = get_field('status', $product->ID);
$type = get_field('type_tax', $product->ID);
?>
[url=]<?php echo get_the_title( $product->ID ); ?>
<div>Status: <?php echo $status; ?></div>
<div>Type: <?php echo $type; ?></div>
<br>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php endwhile; ?>
<?php endif; ?>
functions.php
<?php
$GLOBALS['my_query_filters'] = array(
'field_5f786da6ec5a6' => 'status',
);
add_action('pre_get_posts', 'my_pre_get_posts', 10, 1);
function my_pre_get_posts( $query ) {
if( is_admin() ) return;
if( !$query->is_main_query() ) return;
$meta_query = $query->get('meta_query');
foreach( $GLOBALS['my_query_filters'] as $key => $name ) {
if( empty($_GET[ $name ]) ) {
continue;
}
$value = explode(',', $_GET[ $name ]);
$meta_query = array(
array(
'key' => $name,
'value' => $value,
'compare' => 'IN',
)
);
}
$query->set('meta_query', $meta_query);
return;
}
?>
—- Versions —-
ACF v5.8.9
WP v5.4.2
Hi everyone!
Hope you can help me with this issue:
I have two CTP in my site:
1. deck
2. tournament
Then, in CPT Deck I have a custom field of type object in which you can select one of the CPT Tournament.
CPT Tournament have a custom field of type date.
My problem is that I would like to order the CTP Deck Archive by the date of the Tournament it is linked to.
I would like to achieve this through filtering the pre_get_posts hook.
Is this possible?
Thanks!!!
Hi everyone!
I really like the plugin, it is great.
I have been pairing it with a custom post type displaying concert dates, I can get all my posts to work fine and I can use WP_Query and $args to filter/order them simply. I use a datepicker ACF field ‘date_selector’, and “orderby” to order them by date.
Things got more complicated then…
I am trying to create a basic select menu with 2 options that would help sorting/reordering the posts based on their date. Just changing the “orderby” value for now would be enough to understand the way it works.
From the ACF documentation, I understand that you can use if( isset($_GET['your-option']) )
to get the URL parameter and then use that to make some changes in your arrays?
Sorry if I am lost. Here is my code for the cpt:
<?php
$today = date('Y-m-d H:i:s');
$args = array(
'post_type' => 'agenda',
'posts_per_page' => 8,
'meta_key' => 'date_selector',
'orderby' => 'meta_value',
'order' => 'DESC',
'suppress_filters' => true,
'lang' => '',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'date_selector',
'value' => $today,
'type' => 'DATE',
'compare' => '<',
)
)
)
?>
<div class="filtering-box fl-2 on_w g_sm_mt">
<p>Sort by:</p>
<form action="<?php the_permalink(); ?>" method="get">
<select name="filter" id="date-filter">
<option value="date-recent">Now</option>
<option value="to-come">To come</option>
</select>
<button type="submit" value="">Sort</button>
</form>
</div>
<wrapper class="events-container g_sm_mt">
<?php
function my_pre_get_posts( $query ) {
// do not modify queries in the admin
if( is_admin() ) {
return $query;
}
// only modify queries for 'event' post type
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'agenda' ) {
// allow the url to alter the query
if( isset($_GET['date-recent']) ) {
$args = array(
'post_type' => 'agenda',
'posts_per_page' => 1,
'meta_query' => array(
'key' => 'date_selector',
'value' => $today,
'type' => 'DATE',
'compare' => '>',
)
);
}
// return
return $query;
}
}
add_action('pre_get_posts', 'my_pre_get_posts');
?>
<?php //Query posts
$agenda_dates = new WP_Query( $args ); ?>
<?php if ($agenda_dates->have_posts()): ?>
<?php while ($agenda_dates->have_posts()): $agenda_dates->the_post();?>
//my posts here...
<?php endwhile;?>
<?php endif;?>
<?php wp_reset_postdata();?>
I got this far, it keeps working but the filter option does not change anything to the posts when I select the value “date-recent”. Sorry for this poor attempt, I am not good at php and do not understand how to implement the sorting option.
I am not even sure about the syntax and where I should write the URL parameter condition if( isset($_GET['...']))
.
Can anyone of you help me with this?
Thank you,
Have a nice day!
Hey,
So I’m very new to this but have spent the last few days trying to work it out.
I have a custom post order for my posts which is the same throughout all category pages which I’d like to keep when people hit those pages. What I’m looking to do is sort the posts by a custom field (price) using a link or button clicked by the client…
ie – sort by price (low to high)
– sort by price (high to low)
I have used this…
function my_pre_get_posts( $query ) {
if( is_admin() ) {
return $query;
}
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'post' ) {
$query->set('orderby', 'meta_value_num');
$query->set('meta_key', 'price');
$query->set('order', 'ASC');
}
// return
return $query;
}
add_action('pre_get_posts', 'my_pre_get_posts');
in my functions page which makes all category pages sorted by the custom field (price) on initial load but I can’t figure out how to keep my initial post order and activate the function when someone clicks a button or visits a specific link.
Ideally when the front end user clicks something the page reloads with all posts in that category re-ordered by my custom field.
Any ideas?
Thanks!!
Hi, I have been using CPT ui to create custom post type. I want to create a page for categories assgined to custom post type. I added catgory.php page and used below function to retrieve posts in custom post type.
add_filter('pre_get_posts', 'query_post_type');
function query_post_type($query)
{
if (is_category()) {
$post_type = get_query_var('post_type');
if ($post_type)
$post_type = $post_type;
else
$post_type = array('nav_menu_item', 'post', 'set_date', 'year_round'); // don't forget nav_menu_item to allow menus to work!
$query->set('post_type', $post_type);
return $query;
}
}
However, I have added an custom ACF field for taxanomy (category) where I can add image to it. When I run the get_field(‘hero_image’) in category.php page, im unable to get the image url. Why is that?
I am working on Learndash Based Website which is having Membership and we have given parents a way to show only specific category of quiz. And our code work fine when page loads happens normally.
But, When user use Ajax button to load next page content then get_field is not working inside of our code and hence we are not able to get the values stored in option. We are not getting any errors. Our Code is not moving ahead after get_field and hence we are not even seeing any error_log which we are using to debug.
Here is our code:
if (!class_exists('NtmlConfigurePopupQuizEnable')) {
class NtmlConfigurePopupQuizEnable
{
public function __construct()
{
add_action('pre_get_posts', array($this, 'ntml_configure_popup_quiz_enabled'));
}
public function ntml_configure_popup_quiz_enabled($query)
{
$user = MeprUtils::get_currentuserinfo();
if ( (!is_admin() && ( ( !$query->is_main_query() && isset($query->query['post_type']) && ($query->query['post_type'] == 'sfwd-quiz'))) ) || ( isset($_GET['ld-lesson-page']) || isset($_POST['ld-lesson-page']) && ( !$query->is_main_query() && isset($query->query['post_type']) && ($query->query['post_type'] == 'sfwd-quiz')) ) ) {
$user = MeprUtils::get_currentuserinfo();
if ($user != false && isset($user->ID)) {
$status_of_all_products = array();
$all_active_products = $user->active_product_subscriptions('ids', true, true);
foreach ($all_active_products as $product) {
$quiz_status_product = get_post_meta($product, 'quiz_enabled', true);
$status_of_all_products[] = $quiz_status_product;
}
$sub_account_status = get_user_meta($user->ID, 'mpca_corporate_account_id', true);
if( ( isset($_GET['ld-lesson-page']) || isset($_POST['ld-lesson-page']) ) ){
//error_log('mpca_corporate_account_id');
//error_log($sub_account_status);
//error_log(print_r($status_of_all_products,1));
}
if (isset($sub_account_status) && !empty($sub_account_status) && !empty($status_of_all_products) && in_array(1, $status_of_all_products)) {
if( ( isset($_GET['ld-lesson-page']) || isset($_POST['ld-lesson-page']) ) ){
//error_log('status of products is true');
}
$category_IDs_to_show = array();
if( ( isset($_GET['ld-lesson-page']) || isset($_POST['ld-lesson-page']) ) ){
//error_log('enabled quiz cate');
}
//get all the acf fields
$ld_course_mapping_with_categories = get_field('ld_course_mapping_with_categories', 'option');
if( ( isset($_GET['ld-lesson-page']) || isset($_POST['ld-lesson-page']) ) ){
error_log('after get field');
}
//user fields
$ld_enabled_quiz_categories = get_user_meta($user->ID, 'ld_enabled_quiz_categories', true);
$ld_enabled_sec_quiz_categories = get_user_meta($user->ID, 'ld_enabled_sec_quiz_categories', true);
if( ( isset($_GET['ld-lesson-page']) || isset($_POST['ld-lesson-page']) ) ){
error_log('enabled quiz cate');
error_log(print_r($ld_enabled_quiz_categories));
}
if (!empty($ld_enabled_quiz_categories)) {
//for all grader
$all_grade_user_current_group = get_user_meta($user->ID, 'user_current_class', true);
if (isset($all_grade_user_current_group) && !empty($all_grade_user_current_group)) {
$all_courses_ids = array();
$getCurrentBookAssociatedTerms = array();
$course_associated_with_group = NtmlUtils::getGroupCourses($all_grade_user_current_group);
foreach ($course_associated_with_group as $course) {
if (is_object($course)) {
$all_courses_ids[] = $course->ID;
}
}
if (count($all_courses_ids) == 1) {
$getCurrentBookAssociatedTerms = NtmlUtils::get_category_for_passed_course_id($all_courses_ids[0], $ld_course_mapping_with_categories);
} else {
foreach ($all_courses_ids as $courses_id) {
$getCurrentBookAssociatedTerms = array_merge($getCurrentBookAssociatedTerms, NtmlUtils::get_category_for_passed_course_id($courses_id, $ld_course_mapping_with_categories));
}
}
foreach ($getCurrentBookAssociatedTerms as $quiz_cat) {
$term = get_term_by('id', absint($quiz_cat), 'ld_quiz_category');
if (strpos($term->slug, $ld_enabled_quiz_categories)) {
$category_IDs_to_show[] = $term->term_id;
}
}
if (isset($ld_enabled_sec_quiz_categories) && !empty($ld_enabled_sec_quiz_categories)) {
$category_IDs_to_show = array_merge($category_IDs_to_show, $ld_enabled_sec_quiz_categories);
}
$query->set('tax_query',
array(
array(
'taxonomy' => 'ld_quiz_category',
'field' => 'term_id',
'terms' => $category_IDs_to_show,
'operator' => 'IN'
)
)
);
return $query;
} else {
//for single grader
GFCommon::log_debug(' debug inside else ');
$member_of_groups = groups_get_user_groups($user->ID);
$course_associated_with_single_grader = array();
$all_courses_ids_single_grade = array();
$getCurrentBookAssociatedTerms = array();
if ($member_of_groups['total'] == 0) {
return $query;
}
$first_group_member_enrolled = $member_of_groups['groups'];
foreach ($first_group_member_enrolled as $group) {
$course_associated_with_single_grader = array_merge($course_associated_with_single_grader, NtmlUtils::getGroupCourses($group));
}
foreach ($course_associated_with_single_grader as $course) {
if (is_object($course)) {
$all_courses_ids_single_grade[] = $course->ID;
}
}
if (count($all_courses_ids_single_grade) == 1) {
$getCurrentBookAssociatedTerms = NtmlUtils::get_category_for_passed_course_id($all_courses_ids_single_grade[0], $ld_course_mapping_with_categories);
} else {
foreach ($all_courses_ids_single_grade as $courses_id) {
$getCurrentBookAssociatedTerms = array_merge($getCurrentBookAssociatedTerms, NtmlUtils::get_category_for_passed_course_id($courses_id, $ld_course_mapping_with_categories));
}
}
//get all primary
foreach ($getCurrentBookAssociatedTerms as $quiz_cat) {
$term = get_term_by('id', absint($quiz_cat), 'ld_quiz_category');
if (strpos($term->slug, $ld_enabled_quiz_categories)) {
$category_IDs_to_show[] = $term->term_id;
}
}
//merge primary with secondary
if (isset($ld_enabled_sec_quiz_categories) && !empty($ld_enabled_sec_quiz_categories)) {
$category_IDs_to_show = array_merge($category_IDs_to_show, $ld_enabled_sec_quiz_categories);
}
//id before
$query->set('tax_query',
array(
array(
'taxonomy' => 'ld_quiz_category',
'field' => 'term_id',
'terms' => $category_IDs_to_show,
'operator' => 'IN'
)
)
);
}
}
}
}
}
return $query;
}
}
new NtmlConfigurePopupQuizEnable();
}
Hello,
I’m stuck on the following: I’d like to create a filter with the checkbox which I’m using as “category”. I named it ‘trainingscategory’. With this I’d like to filter the posts from my CPT ‘training’. I don’t suppose I’m the first one trying this but I have a hard time finding answers or perhaps I just don’t understand them. I’ve read the query and filter by custom field posts a dozen times but I can’string them together.
In my functions.php I’ve set:
<?php
function my_pre_get_posts( $query ) {
// do not modify queries in the admin
if( is_admin() ) {
return $query;
}
// only modify queries for 'training' post type
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'training' ) {
// allow the url to alter the query
if( isset($_GET['trainingscategory']) ) {
$query->set('meta_key', 'trainingscategory');
$query->set('meta_value', $_GET['trainingscategory']);
}
}
// return
return $query;
}
add_action('pre_get_posts', 'my_pre_get_posts');
For now on my page I’m only showing a table with the posts in CPT ‘training’ without the filtering.
For my sidebar I’d like to show the values set in ‘trainingscategory’.
<?php
// Load field settings and values.
$field = get_field_object('trainingscategory');
$cats = $field['value'];
// Display labels.
if( $cats ): ?>
<ul>
<?php foreach( $cats as $cat ): ?>
<li><?php echo $field['choices'][ $cat ]; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
This doesn’t show anything since this only shows what is set on the current page if I understood correctly. However I couldn’t figure out how to show all values in a list.
For the filtering I think I’d need to set the above values in a add_query in the URL?
But then how do I make the table show only the posts with that value?
I think it should be something like below but I can’t figur out how to make this work as filter result. (I’m using a ul here instead of my table to save space)
// Query
$the_query = new WP_Query(array(
'post_type' => 'training',
'posts_per_page' => -1,
'meta_key' => 'trainingscategory',
'orderby' => 'meta_value',
'order' => 'DESC'
));
?>
<?php if( $the_query->have_posts() ): ?>
<ul>
<?php while( $the_query->have_posts() ) : $the_query->the_post();?>
<li>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</li>
<?php endwhile; ?>
</ul>
<?php endif; ?>
<?php wp_reset_query(); // Restore global post data stomped by the_post(). ?>
I have a feeling I’ve read the answer a dozen times in the posts but I simply can’t figure it out. If someone could help me in the right direction I’d appreciate that alot.
Kind regards,
Hello,
For a page on which I’m displaying a table with courses I’d like a sidebar which should be used as a filter for the table.
I’m using the checkbox ‘trainingscategory’. I’d like to show all available values in the sidebar with a link. Once link is clicked it will show all posts in teh table containing that have that value.
I’m sure I’m not the first one to do this, however I can’t find or don’t understand the way to approach this.
My guess is that the best way would be to use a query. So I went to make a my_pre_get_posts in functions for my post type ‘training’.
<?php
function my_pre_get_posts( $query ) {
// do not modify queries in the admin
if( is_admin() ) {
return $query;
}
// only modify queries for 'training' post type
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'training' ) {
// allow the url to alter the query
if( isset($_GET['trainingscategory']) ) {
$query->set('meta_key', 'trainingscategory');
$query->set('meta_value', $_GET['trainingscategory']);
}
}
// return
return $query;
}
add_action('pre_get_posts', 'my_pre_get_posts');
That’s about as far as I came. I have trouble understanding how to properly use the query and to load the values.
To load the ‘trainingscategory’ in the sidebar I used the following:
<?php
// Load field settings and values.
$field = get_field_object('trainingscategory');
$cats = $field['value'];
// Display labels.
if( $cats ): ?>
<ul>
<?php foreach( $cats as $cat ): ?>
<li><?php echo $field['choices'][ $cat ]; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
It doesn’t show the values since none are set for the page I suppose but I can’t figure out how to show them and use them to set a query for the table.
Lastly I’d like to show the posts which have the selected cats. But I’m unsure how to make the query to show these results. I’ve read the documentation and forums about order by custom fields, query posts and url parameters a dozen times but I can’t string it together for some reason. I’m sure it’s obvious and I’ve been oblivious but the pieces just won’t fall for me. If someone could guide me in the right direction I would appreciate that alot.
Kind regards,
Hi guys! Faced a problem, I can’t solve it the second day. Help me please.
I made a filter, it worked. But it took a changes and it’s not working now.
I have post type projects. There are several custom fields. Type, area, color. When there was one color, there were no problems. But now 1-3 colors can be assigned to one project.
Here is my code
add_action('pre_get_posts', 'my_pre_get_posts');
function my_pre_get_posts( $query) {
if( is_admin() ) {
return;
}
if ( ! $query->is_main_query() ) {
return $query;
}
$meta_query = $query->get('meta_query');
$colors = explode(',', $_GET['color']);
$types = explode(',', $_GET['type']);
foreach ($colors as $color){
$meta_query[] = array(
'relation' => 'AND',
array(
'key' => 'project_type',
'value' => $types,
'compare' => 'IN',
),
array(
'key' => 'project_area',
'value' => $_GET['area_min'],
'type' => 'DECIMAL',
'compare' => '>',
),
array(
'key' => 'project_area',
'value' => $_GET['area_max'],
'type' => 'DECIMAL',
'compare' => '<',
),
array(
'key' => 'project_color', // array
'value' => $color, //array too (if 'value' => '"'.$color.'"' I get the same problem
'compare' => 'LIKE',
),
);
}
}
$query->set('meta_query', $meta_query);
return;
}
If one color is selected, it works fine. If I choose two or more colors, then no project is suitable for the request.
Only those projects are assigned to which all the colors that the user has selected are assigned. But it is necessary that all projects that contain at least one of these colors be found.
How can I make queries so that each foreach result is related to subsequent ones through ‘relation’ => ‘OR’. And at the same time in the request where I check the type, area and color relation remained AND.
How can I do that? Or is this approach wrong, and need to be done differently? I will be very grateful for your help!
my_query_filters not showing filter results in the archive.php with repeater sub_fields. I am getting the value but when trying to filter the post it does not show any result. rest normal fields showing result fine. here is the code i am using in my functions.php:
// array of filters (field key => field name)
$GLOBALS[‘my_query_filters’] = array(
‘field_5ebae4d1733b7’ => ‘starting_price’,
‘field_5eb8f98a60609’ => ‘coupon_start_date’, //Repeater sub_field
‘field_5eb8fdc433e09’ => ‘coupon_end_date’, //Repeater sub_field
‘field_5eb8fa4deffb6’ => ‘private_coupon’, //Repeater sub_field
‘field_5eb8fd31628b2’ => ‘refundable’,
‘field_5eb6b8a81305c’ => ‘star_rating’
);
// action
add_action(‘pre_get_posts’, ‘my_pre_get_posts’, 10, 1);
function my_pre_get_posts( $query ) {
// bail early if is in admin
if( is_admin() ) return;
// bail early if not main query
// – allows custom code / plugins to continue working
if( !$query->is_main_query() ) return;
// get meta query
$meta_query = $query->get(‘meta_query’);
// loop over filters
foreach( $GLOBALS[‘my_query_filters’] as $key => $name ) {
// continue if not found in url
if( empty($_GET[ $name ]) ) {
continue;
}
// get the value for this filter
// eg: http://www.website.com/events?city=melbourne,sydney
$value = explode(‘,’, $_GET[ $name ]);
// append meta query
$meta_query[] = array(
‘key’ => $name,
‘value’ => $value,
‘compare’ => ‘LIKE’,
);
}
// update meta query
$query->set(‘meta_query’, $meta_query);
}
Hello!
I have 2 custom post types – projects and designers. project item has custom fields (text, taxonomies and Post Object). Text field contain area of flat/apartment, taxonomies: first, it’s type of project and, second one is status of project (prototype, finished, etc.). Post Oblect field – relationship Project and Designer (select a designer for project).
I’m making a filter for Projects Archive page. Like this – https://www.advancedcustomfields.com/resources/creating-wp-archive-custom-field-filter/
It’s working good for simple text custom field (for area), but not working for taxonomies and post object fields. How should I make this?
my urls for filtering on the archive page:
http://mydomain.com/projects/?area=25
http://mydomain.com/projects/?designer=new_studio
http://mydomain.com/projects/?type=bath
My functions.php
add_action('pre_get_posts', 'my_pre_get_posts');
function my_pre_get_posts( $query) {
if( is_admin() ) {
return;
}
$meta_query = $query->get('meta_query');
if (isset($_GET['area']) ) {
$meta_query[] = array(
'key' => 'project_area', // custom text field - working good
'value' => $_GET['area'],
'type' => 'NUMERIC',
'compare' => '=',
);
}
if (isset($_GET['designer']) ) {
$meta_query[] = array(
'key' => 'project_designer_obj', //custom field (Post obj) - not working. How should I use ['post_name'] of this Object for comparing with name of designer below?
'value' => $_GET['designer'],
'compare' => '=',
);
}
if (isset($_GET['type']) ) {
$meta_query[] = array(
'key' => 'project_type', //custom field (taxonomy) - not working. How should I use relationship taxs?
'value' => $_GET['type'],
'compare' => '=',
);
}
$query->set('meta_query', $meta_query);
return;
}
If I try this:
if( !empty($_GET['designer']) ){
$designer = the_field('project_designer_obj');
$designer_name = $designer->post_name; // Trying to get property of non-object
$meta_query[] = array(
'key' => 'project_designer_obj',
'value' => $designer_name,
'compare' => '=',
);
}
I see “Notice: Trying to get property of non-object …”
Please, help me figure it out.
I have been trying everything I can think of but there’s something about trying to include custom fields in a meta_query I am just not getting.
Any help appreciated!
add_filter('pre_get_posts', __NAMESPACE__ . '\\search_custom_fields');
// add_action('pre_get_posts', __NAMESPACE__ . '\\search_custom_fields');
function search_custom_fields($query)
{
if ($query->is_search && $query->is_main_query()) {
echo "search_custom_fields: " . $query->is_main_query() . " " . $query->is_search . "\n";
echo "query->post_type: " . get_query_var('post_type') . "\n";
echo "Setting meta_query in search_custom_fields. " . "\n\n\n";
// i want the search to include custom fields as well as continue to include the title and post content. So i want to return ANY matches from any of the fields
$search_word = get_query_var('s'); // 'test' for post title and content.
$query->set('post_type', 'location'); // search is only for post type 'locations'
$query->set('orderby', 'date');
$query->set('order', 'DSC');
// this taxonomy test works and returns results with title LIKE 'test' with this term
$tax = array(
array(
'taxonomy' => 'location_facilities',
'field' => 'slug',
'terms' => 'inside-m25',
));
$query->set('tax_query', $tax);
// acf field is called 'loc_refid'
// this stops all results
$meta_query1 =
[
[
'key' => 'loc_refid',
'value' => "%" . $search_word . "%",
'compare' => 'LIKE',
],
];
// returns general matches but nothing for the loc_refid field
$meta_query2 = [
'key' => 'loc_refid',
'value' => "%" . $search_word . "%",
'compare' => 'LIKE',
];
// // this stops all results
$meta_query3 = [
'relation' => 'OR',
[
'key' => 'loc_refid',
'value' => $search_word,
'compare' => 'LIKE',
],
];
$meta_query4 = array(
'relation' => 'OR',
array(
'key' => 'loc_refid',
'value' => $search_word,
'compare' => 'LIKE',
),
array(
'key' => 'location_postcode_preview',
'value' => $search_word,
'compare' =>'LIKE'
),
);
$query->set('meta_query', $meta_query4);
print_r($query);
}
return $query;
// if useing add_action no need to return
}
print_r($query);
WP_Query Object
(
[query] => Array
(
[s] => test
)
[query_vars] => Array
(
...
[tax_query] => Array
(
[0] => Array
(
[taxonomy] => location_facilities
[field] => slug
[terms] => inside-m25
)
)
[meta_query] => Array
(
[relation] => OR
[0] => Array
(
[key] => loc_refid
[value] => test
[compare] => LIKE
)
[1] => Array
(
[key] => location_postcode_preview
[value] => test
[compare] => LIKE
)
)
)
[tax_query] => WP_Tax_Query Object
(
[queries] => Array
(
)
[relation] => AND
[table_aliases:protected] => Array
(
)
[queried_terms] => Array
(
)
[primary_table] =>
[primary_id_column] =>
)
[meta_query] =>
[date_query] =>
[post_count] => 0
...
Hi there,
I want to exclude my search results by post ids.
Therefor I created an relation field as option.
But the get_field is probably also using pre_get_posts and gets into an infinite loop.
This is my code.
function wpb_search_filter( $query ) {
if(!is_admin() && is_search()){
$excluded_post_ids = get_field('exclude_from_search','option');
if(!empty($excluded_post_ids)){
if ( $query->is_search && !is_admin() ){
$query->set( 'post__not_in', $excluded_post_ids );
}
}
}
return $query;
}
add_filter( 'pre_get_posts', 'wpb_search_filter' );
How do I set the proper IF statement?
Thanks in advance!