Search code examples
woocommerceshortcode

Woocommerce shortcode to display products with stock equal or above the value stated (Updated again)


I'm trying to create a custom shortcode that will allow me to display products with stock levels equal to, or higher than a set numerical value.

So ideally I could place a shortcode along the lines of: [product_category category="secret-wars" stock="3"]

Which would display products in the secret wars category with 3 or more in stock.

Update #1:

So I found some code by LoicTheAztec which I'm hoping I can alter to my requirements here Display WooCommerce products with a shortcode using a custom meta_query

I've tried making some changes but can't get the code to work, here's the code I currently have:

    if( ! function_exists('minimum_stock') ) {

    // Add Shortcode
    function minimum_stock( $atts ) {
        global $woocommerce_loop;

        // Attributes 
        $atts = shortcode_atts(
            array(
                'columns'   => '5',
                'limit'     => '40',
                'stock'     => '3',
            ),
            $atts, 'minimum_stock'
        );


        $woocommerce_loop['columns'] = $atts['columns'];

        // The WP_Query
        $products = new WP_Query( array (
            'post_type'         => 'product',
            'post_status'       => 'publish',
            'posts_per_page'    => $atts['limit'],
            'meta_query'        => array(
                'stock'  => array(
                    'key'       =>'_stock',
                    'type'    => 'numeric',
                    'value'   => ''
                    'compare'   => '>=',
                ),
            )
        ));

        ob_start();

        if ( $products->have_posts() ) { ?>

            <?php woocommerce_product_loop_start(); ?>

                <?php while ( $products->have_posts() ) : $products->the_post(); ?>

                    <?php wc_get_template_part( 'content', 'product' ); ?>

                <?php endwhile; // end of the loop. ?>

            <?php woocommerce_product_loop_end(); ?>

            <?php
        } else {
            do_action( "woocommerce_shortcode_products_loop_no_results", $atts );
            echo "<p>There are no results.</p>"
        }

        woocommerce_reset_loop();
        wp_reset_postdata();

        return '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
    }

    add_shortcode( 'stock', 'minimum_stock' );
}

I've also tried coming at it a slightly different way:

// Add Minimum Stock Shortcode
function minimum_stock_func ( $atts , $args ) {
    $a = shortcode_atts( array(
                'stock' => $args = array(
                        'meta_key'      => '_stock',
                        'type'          => 'numeric',
                        'meta_value'    => '',
                        'compare'       => '>='
                ), $atts ) );

    return "stock = {$a['stock']}";
}
add_shortcode( 'stock', 'minimum_stock_func' );

If anyone has any idea what I'm doing wrong your help would be very much appreciated!

Update #2: Okay, so I think I'm getting there... I've managed to get minimum stock of 3 to show using this code:

// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );

function minimum_stock_shortcode( $atts ) {
global $product, $woocommerce, $woocommerce_loop;

// Attributes 
        $atts = shortcode_atts(
            array(
            'limit'         => '40',
            'columns'       => '5',
            'orderby'       => 'title',
            'order'         => 'asc',
            'category'      => '',
            'cat_operator'  => 'IN',
            ),
            $atts, 'minimum_stock'
        );

        $woocommerce_loop['columns'] = $atts['columns'];

        $args = array(
            'post_type'             => 'product',
            'post_status'           => 'publish',
            'posts_per_page'        => $atts['limit'],
            'orderby'               => $atts['orderby'],
            'order'                 => $atts['order'],
            'meta_query'            => array(
                array(
                    'key'           => '_stock',
                    'value'         => 3,
                    'compare'       => '>='
                )
            ),
            'tax_query' => array( array(
                        'taxonomy'  => 'product_cat',
                        'field'     => 'slug',
                        'terms'     => $atts['category'],
                )
            )
        );

$loop = new WP_Query($args);

ob_start();

woocommerce_product_loop_start();

while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile; 

woocommerce_product_loop_end();

woocommerce_reset_loop();
wp_reset_postdata();

return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
}

This will display products within a category that has minimum stock amount of 3, with this shortcode:

[minimum_stock category="comic-book-publishers"]

Does anyone know how I can get it to work if the shortcode were like so:

[products minimum_stock="2" category="comic-book-publishers"]

I'd like to be able to use the Woocommerce [products] shortcode as with it I'll also get pagination and the store 'orderby' dropdown menu will appear above the products. I'd also like to be able to specify the minimum_stock amount with [minimum_stock="2"] rather than it be set in the shortcode stock.

Any help would be very much appreciated.

Kind regards, JP


Solution

  • Okay so I've gotten most of this done.

    The shortcode in it's current form allows me to display products with a set minimum stock amount in a specific category like so [minimum_stock stock="4" category="comic-book-publishers"]

    Here's the code:

    // Minimum Stock Shortcode
    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>';
    }
    

    Now I need to work out how to apply pagination to the shortcode and include the Woocommerce order by dropdown... time to start a new question! :)

    If anyone knows how I can do this please let me know, the new question regarding this can be found here: How to add woocommerce-pagination and woocommerce-ordering dropdown to custom shortcode