Query WooCommerce Products based on Attribute - wordpress

This one's driving me nuts.. I'm trying to query and output WooCommerce products based on a specific attribute. For example, I set up an Attribute called on, with possible values of yes or no.
I query using the following:
$args = array(
'post_type' => 'product',
'meta_key' => 'pa_on',
'meta_value' => 'yes',
'posts_per_page' => -1
);
query_posts($args);
The meta_key is crucial perhaps; if I call it on I get nothing. If I call it pa_on (because that's how I understand WooCommerce custom attributes to be constructed) I get nothing.
However, if I try a different query and use _featured, which is a standard WooCommerce custom meta thingy, it returns the relevant featured posts. Help, anyone?

I know this is an old one, but just in case someone stumbles upon it like I did today -- Woocommerce (I'm using v2.6.2) appears to store these custom attributes as taxonomies.
I suspect the correct args for the original question would look like this:
$args = array(
'post_type' => 'product',
'tax_query' => array(
array(
'taxonomy' => 'pa_on',
'field' => 'name',
'terms' => 'yes'
)
)
);
Using the appropriate values for my installation, it solved my problem.

For new woocommerce use:
$attribute = 'on';
$value = 'yes';
$args = array(
'post_type' => 'product',
'tax_query' => array(
array(
'taxonomy' => 'pa_' . $attribute,
'terms' => $value,
'field' => 'slug',
'operator' => 'IN'
)
)
);

If product attribute is saved as specific product attribute (i.e. not global), then you can't query it as taxonomy, instead you can use this snippet (copied from http://snippet.fm/snippets/query-woocommerce-products-product-specific-custom-attribute/):
// Set custom attribute name and value to search for
$attribute_name = 'color';
$attribute_value = 'green';
$serialized_value = serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value ); // extended version: $serialized_value = serialize( $attribute_name ) . 'a:6:{' . serialize( 'name' ) . serialize( $attribute_name ) . serialize( 'value' ) . serialize( $attribute_value ) . serialize( 'position' );
$args = array(
'post_type' => 'product',
'post_status' => 'any',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => '_product_attributes',
'value' => $serialized_value,
'compare' => 'LIKE',
),
),
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) {
$loop->the_post();
// do stuff here... e.g. get_the_ID()
}
wp_reset_postdata();

Guess what you need is a query with meta_query value set:
$args = array(
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'pa_on',
'value' => 'yes',
'compare' => '='
)
)
);
$query = new WP_Query( $args );
You can learn more about those here:
http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters

Related

custom wp_query where meta_key is variable or not needed

To make a custom post type filterable and sortable, i created a custom query that works based on variables in url, accessed by $_GET.
One specific situation breaks it. This is an (un)specified metakey. In the case of sort, the metakey is needed when sorting on a custom field. In the other cases, the metakey can be ignored. However, when i set the variable on empty, the query doesnt produce any posts. How to deal with an empty meta_key?
So far i tried to set the variable as empty ($variable ='');
I set the variable as null; I have used unset.
if (isset($_GET["key"]) || isset($_GET["orderby"])){
if (isset($_GET["key"])) {$key = $_GET["key"];}
else {$key = '';}
if (isset($_GET["value"])) {$value = $_GET["value"]; echo $value;}
else {$value = '';}
if (isset($_GET["orderby"])) {$orderby = $_GET["orderby"];}
if ($orderby='meta_value'){$meta_key='averagerating';}
else {$orderby='';$meta_key='';}
if (isset($_GET["order"])) {$order = $_GET["order"];}
else {$order='';}
$cat = get_queried_object();
if (!empty($cat) && !is_post_type_archive('bedrijf')){
$category = $cat->name;
}
if (is_post_type_archive('bedrijf')){
$category = '';
$terms = get_terms( 'bedrijfs-category' );
// convert array of term objects to array of term IDs
$category = wp_list_pluck( $terms, 'name' );
}
global $post;
$the_query ='';
$args = array(
'post_type' => 'bedrijf',
'posts_per_page' => 10,
'meta_key' => ''.$meta_key.'',
'orderby' => ''.$orderby.'',
'order' => ''.$order.'',
'tax_query' => array(
array(
'taxonomy' => 'bedrijfs-category',
'field' => 'name',
'terms' => $category
)
),
'meta_query' => array(
array(
'key'=> ''.$key.'',
'value' => ''.$value.'',
'compare' => 'LIKE'
)
)
);
$the_query = new WP_Query($args); }
WHat i would like is a solution for inserting an empty variable in the meta_key => ''.$meta_key.'' so the loop skips the meta_key part.
define meta_query or tax_query out of $args
and (example):
if($_GET['some_name'] !== ''){
$meta_query = array(
array(
'taxonomy' => 'bedrijfs-category',
'field' => 'name',
'terms' => $category
)
);
//define args with some_one para exists
$args = array(
'post_type' => 'bedrijf',
'posts_per_page' => 10,
'meta_key' => ''.$meta_key.'',
'orderby' => ''.$orderby.'',
'order' => ''.$order.'',
'meta_query' => $meta_query
);
}else{
//define args with some_one para not exists
$args = array(
'post_type' => 'bedrijf',
'posts_per_page' => 10,
'meta_key' => ''.$meta_key.'',
'orderby' => ''.$orderby.'',
'order' => ''.$order.''
);
}
tax_query is like this

WordPress include custom field in search

I have a custom post type of post_type_1 in WordPress, I also have a custom field in that post type of custom_field_data
I am doing a search for apples by querying posts using wp_query like this...
$search_term = 'apples';
$args = array(
'post_type' => array('post_type_1'),
'post_status' => array('publish'),
'posts_per_page' => -1,
's' => sanitize_text_field( $search_term)
);
$results= new WP_Query( $args );
This works correctly and returns all posts with apples in the title, but I would also like to extend the search to the custom field custom_field_data so the query will return all posts with apples in either title or custom field.
What is my best approach? I have tried using a meta_query but haven't been successful. Does anybody have an example?
Use below code will work for custom field search.
$custom_field = $_GET['custom_field '] != '' ? $_GET['custom_field '] : '';
$search_term = 'apples';
$args = array(
'post_type' => array('post_type_1'),
'post_status' => array('publish'),
'posts_per_page' => -1,
's' => sanitize_text_field( $search_term),
'meta_query' => array(
array(
'key' => 'custom_field_key',
'value' => $custom_field ,
'compare' => 'LIKE',
),
)
);
$results= new WP_Query( $args );
Tested and works well.

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!

Filter with Advanced Custom Field in WordPress

I am trying to set filters based on Advanced Custom Fields in my WordPress site. Basically my advanced custom field named as 'ispremium' has two values as 'yes' and 'no' and in dropdown filter I have set two options as 'Premium Only' And 'All Programs'.
I need to do when 'Premium Only' dropdown option is selected it will list all the post having value 'ispremium'='yes' and when all program is selected it will list both 'ispremium=yes' and 'ispremium='no'. I have following code but it is listing post with 'ispremium=yes' always. What's wrong in my code?
<select name="order" onchange="this.form.submit();">
<?php
$order_options = array(
'yes' => 'Premium Only',
'no' => 'All Programs',
);
$result = query_posts( array(
'post_type' => 'post',
'meta_query' => array(
array(
'key' => 'ispremium',
'value' => 'yes',
),
) ) );
$result = query_posts( array(
'post_type' => 'post',
'meta_query' => array(
array(
'key' => 'ispremium',
'value' => 'yes','no'
),
) ) );
foreach( $order_options as $result => $label ) {
echo "<option ".selected( $_GET['value'], $value )." value='$value'>$label</option>";
}
?>
</select>
First, try to use WP_Query instead of query_posts(). You also have some syntax errors like 'value' => 'yes','no'.
For premium only:
$args = array(
'post_type' => 'post',
'meta_query' => array(
array(
'key' => 'ispremium',
'value' => 'yes',
'compare' => '='
)
)
);
$the_query = new WP_Query( $args );
All Programs
$args = array(
'post_type' => 'post',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'ispremium',
'value' => 'yes',
'compare' => '='
),
array(
'key' => 'ispremium',
'value' => 'no',
'compare' => '='
)
)
);
$the_query = new WP_Query( $args );
Check ACF documentation for further info. Also, I suggest you to do this with Ajax, since if you put this code within your select element, the available options are going to be the from the last query made, and won't be dynamic on field change.
But I don't totally get what you're trying to do though; you'll probably want to show the available programs in another drop down, or you could simply redirect to another archive page which lists the programs accordingly to the selected option.

WordPress custom loop filter by meta_key and value with serialize data

I am trying to run custom loop for Custom Post Type with filtering by some meta_key and value
Now simple meta value works fine but here I have a challenge with the below kind of serialized data (nested).
I am using wpalchemy for meta box. meta_key for the post type is _event_meta and value is as below
a:9:{s:19:"ac_event_operations";a:1:{i:0;s:8:"Training";}s:18:"ac_event_positions";a:1:{i:0;s:10:"Supervisor";}s:18:"ac_event_employees";a:1:{i:0;s:2:"15";}s:13:"ac_event_date";s:10:"2017-06-15";s:19:"ac_event_start_time";s:5:"06:30";s:17:"ac_event_end_time";s:5:"07:00";s:14:"ac_event_place";s:6:"Office";s:18:"ac_event_organizer";s:4:"Jack";s:16:"ac_event_contact";s:4:"Rose";}
I am trying to filter All Events based on ac_event_operations, ac_event_positions, ac_event_employees
So for me, the challenge is to get events filtering with the value from above meta_keys. Here is the query I used but of course, it is not giving any result.
global $event_mb;
$meta = get_post_meta( get_the_ID(), $event_mb->get_the_id(), TRUE );
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$args = [
'post_type' => 'event',
'posts_per_page' => get_option( 'posts_per_page' ),
'paged' => $paged,
'meta_query' => [
'meta_key' => '_event_meta',
'value' => '%ac_event_employees%',
'compare' => 'LIKE'
],
];
$temp = $wp_query;
$wp_query = NULL;
$wp_query = new WP_Query( $args );
Use like below,
$args = array(
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'country',
'value' => 'Israel',
'compare' => '='
),
array(
'key' => 'age',
'value' => array( 20, 30 ),
'type' => 'numeric',
'compare' => 'BETWEEN'
)
)
);
$user_query = new WP_User_Query( $args );
For more Ref : https://codex.wordpress.org/Class_Reference/WP_User_Query

Resources