WooCommerce custom ShortCodes - php

I am trying to create a custom shortcode for WooCommerce, I want to display featured products from a specific catagory at the end of a post.
There is a standard shortcode:
[featured_products per_page="12" columns="4" orderby="date" order="desc"]
I want to add catagory to this, so the new shortcode will be:
[featured_category_products category="13" per_page="4" columns="4" orderby="date" order="desc"]
To get it work it's officiously necessary to create a function for it, so I found the class-wc-shortcodes.php file with all the default shortcodes.
I add a new function based on the default featured product:
public function featured_category_products( $atts ) {
global $woocommerce_loop;
extract(shortcode_atts(array(
'category' => '',
'per_page' => '4',
'columns' => '4',
'orderby' => 'date',
'order' => 'desc'
), $atts));
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $per_page,
'orderby' => $orderby,
'order' => $order,
'meta_query' => array(
array(
'key' => '_visibility',
'value' => array('catalog', 'visible'),
'compare' => 'IN'
),
array(
'key' => '_featured',
'value' => 'yes'
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'terms' => array( esc_attr($category) ),
'field' => 'slug',
'operator' => 'IN'
)
)
);
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $columns;
if ( $products->have_posts() ) : ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php woocommerce_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
wp_reset_postdata();
return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
I added the category variable extraction (and checked if it worked) and added tax-query part (found it from another function that show product based on categories). So I thought this should work, but off course not. I don't get any results nor a error.
Anybody an idea how the get this to work?

If you're only looking for one product category, use 'terms' => $category. Or you can do an explode() to split a comma separated string into an array.
See Wp Query : Taxonomy Parameters.
Other notes:
Don't touch the plugin files, your changes will be lost in the next update.
Create your own plugin.
Copy the function you created to it.
Register the shortcode to make it available (using your custom function as callback):
add_shortcode( 'featured_category_product', 'featured_category_product_function' );

Related

Get WooCommerce Subscription product type and specific category in a WP_Query

I'm using the WooCommerce Subscriptions plug-in for several products in the catalog that are available as both individual or subscription products and am writing a custom template page to query products that are available as subscriptions. My query is below, everything looks right to my eyes, but for some reason it's not working. Can anyone see what's wrong here?
*Note, if I remove the 'tax_query', all the coffee products are returned as expected, but when I try to restrict by the tax_query no products are returned (and yes, I have subscription products in the coffee category).
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'product_cat' => 'coffee',
'tax_query' => array( // builds the taxonomy query
array(
'taxonomy' => 'product_type',
'field' => 'name',
'terms' => 'subscription',
),
),
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
You need to make a "tax_query" for the product category too, to avoid this problem as the way you are doing it, is deprecated since WordPress version 3.1 in favor of "tax_query". So in your code:
$loop = new WP_Query( array(
'post_type' => 'product',
'posts_per_page' => -1,
'post_status' => 'publish',
'tax_query' => array( // builds the taxonomy query
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'coffee',
),
array(
'taxonomy' => 'product_type',
'field' => 'name',
'terms' => 'subscription',
)
)
) );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
It should work.

Loop through the meta value of WooCommerce products using a WP Query

I am working in WooCommerce API and I would like to make a new endpoint which lists me specific products. We have made previously new fields with a plugin and I would like to check them. If the property is ticked in the settings, then show it, else do not.
The new property of the products (checkbox in advanced settings):
woocommerce_wp_checkbox(
array(
'id' => '_checkbox_badge_hot',
'desc' => __('set the checkbox', 'woocommerce'),
'label' => __('Hot', 'woocommerce'),
'desc_tip' => 'true',
'value' => get_post_meta( $post->ID, '_checkbox_badge_hot', true )
)
);
The Code which should list me the products (now if I try to request to the endpoint it just keeps loading):
function get_hot_products(){
$args_for_hot_product = array(
'post_type' => 'product',
'posts_per_page' => -1
);
$loop = new WP_Query( $args_for_hot_product );
$hotproducts = [];
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
while ( $loop->have_posts() ): $loop->the_post(){
$hot = $loop->get_meta('_checkbox_badge_hot');
if( $hot === "yes" ){
array_push($hotproducts, $hot);
}
}
//wp_reset_postdata();
return $hotproducts;
}
add_action( 'rest_api_init', function () {
register_rest_route( '/wc/v3', '/featuredproducts', array(
'methods' => 'GET',
'callback' => 'get_hot_products',
) );
} );
Thanks for your help guys!
To get and display all products that have a specific custom field value, using a WP_Query, you will simply use a eta query as follow:
function display_hot_products(){
$loop = new WP_Query( array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array( array(
'key' => '_checkbox_badge_hot',
'value' => 'yes',
'compare' => '=',
)),
));
if ( $loop->have_posts() ) :
while ( $loop->have_posts() ) : $loop->the_post();
the_title(); // Display product title
endwhile;
wp_reset_postdata();
endif;
}
Don't forget that when using a WP_Query you get WC_Post objects and not WC_Product Objects.

woocommerce shortcode with stock quantity

I would like a shortcode like the following example that shows the stock of the products:
[products limit="8" columns="4" category="pantalones" cat_operator="IN"]
I would need something like this:
[products limit="8" columns="4" category="pantalones" cat_operator="IN" showstock="yes"]
I found this code a few days ago, I found it here on stackoverflow, but now I don't remember the link, sorry.:
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );
function minimum_stock_shortcode( $atts ) {
global $woocommerce_loop;
// Attributes
$atts = shortcode_atts(
array(
'limit' => '40',
'columns' => '5',
'orderby' => 'title',
'order' => 'asc',
'category' => '',
'cat_operator' => 'IN',
'stock' => '',
),
$atts, 'minimum_stock'
);
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['limit'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'meta_query' => array(
array(
'key' => '_stock',
'value' => $atts['stock'],
'compare' => '>='
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
)
)
);
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $atts['columns'];
if ( $products->have_posts() ) : ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php woocommerce_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
wp_reset_postdata();
return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
This code works perfect, but not show stock in homepage
I think the solution is not to modify the shortcode, but to modify the template that it uses to visualize data, but I don't know how to do it, if someone knows where it is or how it's done, I deeply appreciate it
Very thanks for your time.
I found, solution, thanks, very thanks
add_action( 'woocommerce_after_shop_loop_item', 'bbloomer_show_stock_shop', 10 );
function bbloomer_show_stock_shop() {
global $product;
echo wc_get_stock_html( $product );
}

Filter products by custom product attribute et post meta data in a WP_Query

I have already filtered by category, but don't know how to filter products by custom attributes or meta values
code:
$key="naam"; //custom attribute name
$value="test";// custom value
$query_custom = array('key' => $key, 'value' => $value);
$meta_query[] = $query_custom ;
$args=array('meta_query'=>$meta_query, 'product_cat' => 'activiteiten','posts_per_page' => 10,'post_type' => 'product');
$loop = new WP_Query( $args );
`
Here is a working example of a query involving:
product category filtering
post meta value filtering (meta query)
product attribute value filtering (tax query)
The code:
$products = new WP_Query( array(
'posts_per_page' => 10,
'post_type' => 'product',
'post_status' => 'publish',
// 1. Product category filter
'product_cat' => 'clothing',
// 2. The Post meta query part (filtering by post meta value)
'meta_query' => array( array(
'key' => '_price',
'value' => 5,
'type' => 'numeric',
'compare' => '>',
), ),
// 3. The taxonomy meta query part (filtering by term values)
'tax_query' => array( array(
'taxonomy' => 'pa_color', // Product attribute taxonomy: always start with 'pa_'
'field' => 'slug', // Can be 'term_id', 'slug' or 'name'
'terms' => array('blue'),
), ),
) );
// Testing output
if( $products->have_posts() ) :
echo '<ul>'
while ( $products->have_posts() ) : $products->the_post();
echo '<li class="post-id-' . get_the_id() . '">' . get_the_title() . '</li>';
endwhile;
wp_reset_postdata();
echo '</ul>'
endif;
Tested and working:
Official reference documentation for Wordpress WP_Query:
WP_Query and Custom fields parameters
WP_Query and Taxonomy parameters
You can achieve using following code.
$args = array(
'meta_query'=> array(
array(
'key' => 'vote', // here use your field name
'compare' => '=', // comparison sign
'value' => 5, // value using that you can search
)
),
'product_cat' => 'activiteiten',
'posts_per_page' => 10,
'post_type' => 'product'
) );
query_posts( $args ); // get all the posts data using above filter.
query_posts is used to find out the posts with list of arguments meta_query is used in your case to find the matched custom field data.

Show pagination and exclude category

So, I am trying to show items from a specific category in the woocommerce:
Here is what I have so far:
<?php
$args = array( 'post_type' => 'product', 'posts_per_page' => 10, 'product_cat' => '', 'orderby' => 'date', 'order' => 'DESC' );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post(); global $product;
?>
<div class="content"> Content </div>
<?php endwhile; ?>
<?php wp_reset_query(); ?>
When the product_cat is empty, it shows all the items. I want to include "exclude category".
For example, I want to show all but items in a "no_good" category.
Could someone help me out with it?
Also, how can I add a pagination to this?
Thanks!
Is product_cat your custom taxonomy? If it is then you need to modify your $args with tax query:
$args = array(
'post_type' => 'product',
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
'tax' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'name',
'terms' => array('no_good'),
'operator' => 'NOT IN',
),
),
);
...
This assumes that "no_good" is a product_cat name. Adjust field if it isn't.
Regarding the pagination part, do check the codex article regarding pagination.

Categories