WP: how to query posts by variations? - wordpress

I am trying to do a query my wocommerce products by their variations, so I did:
$args = array(
'meta_key' => 'flower-type', // attribute slug
'meta_value' => 'fresh-roses', // attribute value
'meta_compare' => 'LIKE'
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
wp_reset_postdata();
else :
_e( 'Sorry, no posts matched your criteria.' );
endif;
but unfortunately I always get no results, so what is the issue here?

This type of data is saved in a dynamic created meta key so the attribute name counts when making the query, in your case I assumed the slug for your attribute name is "flower-type", you can check this in your database to confirm.
The meta key that you want to use is compose out of the word attribute and the name of the attribute you created when making the variations fresh-flowers in your case.
Be careful that changing this in the admin will "break" your query.
So the arguments will look like:
$args = array(
'post_type' => 'product',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'attribute_flower-type',
'value' => 'fresh-roses',
'compare' => 'LIKE',
),
),
);
please notice the compare attribute used, it might work with = but first confirm that it works with LIKE and then you can play with it.

Try below argument for passing into WP query:
args = array(
'post_type' => 'product',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'flower-type',
'value' => 'fresh-roses',
'compare' => '=',
),
),
);

Related

Loop products excluding on sale shows only 4 items

I'm retrieving the latest products excluding on sale products based on a code example that i found (the original retrieved on sale products only). This is what i did:
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 8,
'orderby' =>'id',
'order' => 'DESC',
'meta_query' => array(
'relation' => 'OR',
array( // Simple products type
'key' => '_sale_price',
'value' => 0,
'compare' => '=',
'type' => 'numeric'
),
array( // Variable products type
'key' => '_min_variation_sale_price',
'value' => 0,
'compare' => '=',
'type' => 'numeric'
)
)
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; ?>
<?php wp_reset_query(); ?>
Actually it's retrieving only 4 products (i need 8) and these are not the latests, but it's excluding on sale products correctly.
Any idea? thank you.
(edited) This will handle simple products. I'm tried to find how to handle variations but couldn't find any meta key that is set when you create a sale price. Anyway, the "compare" shouldn't be "OR" but should be "AND", since you wish to find the products that does not have any of these meta values.
$args = array(
'post_type' => 'product',
'posts_per_page' => 8,
'orderby' =>'id',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => '_sale_price',
'compare' => 'NOT EXISTS',
),
)
);

Wordpress two loop exclude post

I am using two loop query:
<?php
// show all coupons marked Top Coupon
query_posts(array(
'post_type' => APP_POST_TYPE,
'post_status' => 'publish',
'meta_key' => 'clpr_topcoupon',
'meta_value'=> 1,
APP_TAX_STORE => $term->slug,
'ignore_sticky_posts' => 1,
'posts_per_page' => 1
));
?>
<?php get_template_part( 'loop3', 'coupon' ); ?>
<?php
query_posts( array(
'post_type' => APP_POST_TYPE,
'post_status' => 'publish',
APP_TAX_STORE => $term->slug,
'ignore_sticky_posts' => 1,
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'clpr_excoupon',
'compare' => 'NOT EXISTS'
),
array(
'key' => 'clpr_excoupon',
'compare' => '!=',
'value' => '1'
),
),
) );
?>
<?php get_template_part( 'loop1', 'coupon' ); ?>
Now I don't want to show the first post from the first loop in the second loop. I tried get_the_ID(); however if this one is not having the 'meta_key' => 'clpr_topcoupon' one post is missing. How do I get the get_the_ID(); from first post but only if it has the 'meta_key' => 'clpr_topcoupon'?
Wordpress docs suggest that you should avoid using query_posts whenever possible stating:
Note: This function will completely override the main query and isn’t intended for use by plugins or themes. Its overly-simplistic approach to modifying the main query can be problematic and should be avoided wherever possible.
Instead we can use WP_Query . We'll use the first loop to store the post id and check it during the second loop. Maybe something like this:
<?php
//set parameters for First query
$args = array('post_type' => APP_POST_TYPE,
'post_status' => 'publish',
'meta_key' => 'clpr_topcoupon',
'meta_value'=> 1,
APP_TAX_STORE => $term->slug,
'ignore_sticky_posts' => 1,
'posts_per_page' => 1 );
$first_query = new WP_Query($args); // create query
$post_id = 0;
//initialize loop for custom query like this
if ($first_query->have_posts() ) {
while ($first_query->have_posts() ) {
$first_query->the_post();
$post_id = $post->ID; //store post ID outside of loop
get_template_part( 'loop3', 'coupon' );
}
}
wp_reset_postdata();
//setup second query
$args = array( //excludes post from query by ID See Bill erikson for complete list of WP_Query() arguments
'post__not_in' => array($post_id),
'post_type' => APP_POST_TYPE,
'post_status' => 'publish',
APP_TAX_STORE => $term->slug,
'ignore_sticky_posts' => 1,
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'clpr_excoupon',
'compare' => 'NOT EXISTS'
),
array(
'key' => 'clpr_excoupon',
'compare' => '!=',
'value' => '1'
)
)
);
$second_query = new WP_Query($args);
if ($second_query->have_posts() ) {
while ($second_query->have_posts() {
$second_query->the_post();
get_template_part( 'loop1', 'coupon' );
}
}
wp_reset_postdata();
Hopefully, this code is able to assist you. As you can see, WP_Query accepts an argument 'post__not_in' that takes an array of page id's and excludes them from the query. We retrieved the id from the first query and referenced it in the argument of the second query. I also included wp_reset_postdata which is worth taking a look at if you're running multiple queries.
Good luck with your project!

query posts by ACF field not working

There are plenty of topics related to mine, but I still haven't found a solution. I'm trying to query posts by ACF field (radio button) and it seems that the meta_query gets completely ignored. It returns all the posts, instead of only those matching the criteria. I have tried using the field key instead of field name, other comparisons, etc. nothing seems to work. Hope you have an idea of what may be wrong! Here's my code:
<?php
$post_args = array(
'post_type' => 'products',
'posts_per_page' => - 1,
'status' => 'publish',
'meta_query' => array(
'relation' => 'AND',
array(
'meta_key' => 'product_taste',
'meta_value' => array( 'cold' ),
'compare' => 'IN',
),
array(
'meta_key' => 'product_served',
'meta_value' => array( 'grated' ),
'compare' => 'IN'
)
),
);
$query = new WP_Query( $post_args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) : ?>
<?php
$query->the_post();
?>
<h5>
<?php the_title(); ?>
</h5>
<?php endwhile ?>
<?php wp_reset_postdata();
}
?>
Use 'key' and 'value' in the 'meta_query' array
You don't need to use meta_key and meta_value in a meta_query... you only use those directly in the $args array. If you are adding a meta_query array, you just use key and value, e.g.
$post_args = array(
[...]
'meta_query' => array(
array(
'key' => 'product_taste',
'value' => 'cold',
'compare' => 'LIKE',
),
[...]
2. Querying serialised data with an array of values
There can also be issues using 'compare' => 'IN' with an array of values, when you are trying to query ACF data, because the ACF data can be serialised in the database (e.g. if data is in a repeater).
As you will only ever search for a single value, you can use LIKE instead of IN.
Putting these together
$post_args = array(
'post_type' => 'products',
'posts_per_page' => - 1,
'status' => 'publish',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'product_taste',
'value' => 'cold',
'compare' => 'LIKE',
),
array(
'key' => 'product_served',
'value' => 'grated',
'compare' => 'LIKE'
)
),
);
$query = new WP_Query( $post_args );
If the data is serialized and you have values that could return multiple matches (e.g. LIKE 'cold' would match words like "cold", "colder","coldest"), then try adding a semicolon (;) at the end of the value, e.g.
[...]
array(
'key' => 'product_taste',
'value' => 'cold;', // add ; to the end of the value
'compare' => 'LIKE',
),
array(
'key' => 'product_served',
'value' => 'grated;', // add ; to the end of the value
'compare' => 'LIKE'
)
[...]
This will work when the values are serialised in the database, because each item will be separated by a semicolon.

Wordpress output links to previous and next posts from custom query

I'm using the advanced custom fields plugin for wordpress to create a group of custom post types that have a date set within them.
I'm trying to show the previous post, and the next post, based on the date stored in the custom field. The links need to link to posts that have a date set in the future (so don't show links to posts with dates that have gone by)/
I can get a list of all the posts that are in the future, and out put these using the following code;
<?php
$rightnow = current_time('Ymd');
$args = array(
'post_type' => 'Courses',
'posts_per_page' => '25',
'meta_query' => array(
array(
'key' => 'date_of_the_course_single_day',
'compare' => '>=',
'value' => $rightnow,
)
),
'meta_key' => 'date_of_the_course_single_day',
'orderby' => 'meta_value',
'order' => 'ASC',
'post_status' => 'publish'
);
$posts = get_posts($args);
foreach ( $posts as $post ) {
?>
Output details of post here....
<?php
}
?>
What I thought I could do, is the get the current post's position in the array, to then get details of the posts one before and one after... but I haven't got a clue how to do this.
I've experimented with the wordpress next_post_link and previous_post_link functions, but these seem to work based on when the post was added to wordpress, rather than based on my custom date field.
Am I going about this the complete wrong way? Any tips or pointers would be much appreciated!
Use WP_Query plus paginate_links
$rightnow = current_time('Ymd');
// Query Args
$args = array(
'post_type' => 'Courses',
'posts_per_page' => '25',
'meta_query' => array( array(
'key' => 'date_of_the_course_single_day',
'compare' => '>=',
'value' => $rightnow,
) ),
'meta_key' => 'date_of_the_course_single_day',
'orderby' => 'meta_value',
'order' => 'ASC',
'post_status' => 'publish'
);
$query = new WP_QUery( $arg );
$posts = $query->get_posts();
// Paginate Args
$page_args = array(
'base' => 'your_custom_page_url'.'%_%', // Make sure you got this current depending on your setup
'format' => '/%#%', // requires pretty permalinks
'total' => $query->max_num_pages,
'current' => 0,
'prev_text' => __('«'),
'next_text' => __('»'),
);
foreach ( $posts as $post ) {
// Output
}
echo paginate_links( $page_args );
You have to verify that the base and format of paginate args are correct of it won't properly worked.

WordPress meta_query for Custom Post Type with orderby

I'm trying to sort out a WordPress query for a Custom Post Type, but I can't make it work.
The post type is events. An Advanced Custom Fields field called sticky (yes/no) is used for sorting (stickies on top), and another ACF field called glamrock (yes/no) is used to exclude certain posts.
The result is, glamrock gets excluded, but stickies are not sorted.
If I delete the meta_query, sorting works fine, but glamrock posts are included.
$bpb_args = array(
'numberposts' => -1,
'post_type' => 'events',
'posts_per_page' => 100,
'paged' => get_query_var( 'paged', true ),
'meta-key' => 'sticky',
'meta_query' => array(
array(
'key' => 'glamrock',
'value' => 'no',
'compare' => 'IN',
)
),
'orderby' => 'meta_value',
'order' => 'ASC',
);
$bpb_query = new WP_Query( $bpb_args );
if( $bpb_query->have_posts() ):
while( $bpb_query->have_posts() ) : $bpb_query->the_post();
//show post
endwhile;
endif;
Update:
Unfortunately, meta_value instead of meta_value_num didn't change anything. It still seems to be sorting by date/time.
The Advanced Custom Field type is Radio Buttons.
In addition to the arguments, I also included the loop.
You need to specify only meta_value since your meta-key is non numeric
'orderby' => 'meta_value'
#Mihai had it right: meta_value_num was the main issue. I changed it to meta_value.
Here's the query/loop that worked:
$args = array(
'post_type' => 'events',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_key' => 'sticky',
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'lizenz_erteilt',
'value' => 'no',
'compare' => 'LIKE',
),
)
);
$query = new WP_Query( $args );
// Loop
if( $query->have_posts() ) :
while( $query->have_posts() ) : $query->the_post();
//show post
endwhile;
endif;

Resources