Your code is working fine. I tested on local WordPress and worked as expected.
columns
attribute is the visual presentation so it will not affect how many categories are displayed. number
attribute is the number of categories retrieved. I changed it to 4 and it worked perfectly.
Either way you can optimize your code like this:
function rand_product_categories( $atts ) {
global $woocommerce_loop;
// Get shortcode attributes and set default values
$atts = shortcode_atts( array(
'number' => 10,
'orderby' => 'name',
'order' => 'ASC',
'columns' => '4',
'hide_empty' => 1,
'parent' => 0,
'ids' => ''
), $atts );
if ( isset( $atts['ids'] ) ) {
$ids = explode( ',', $atts['ids'] );
$ids = array_map( 'trim', $ids );
} else {
$ids = array();
}
$hide_empty = ( $atts['hide_empty'] == true || $atts['hide_empty'] == 1 ) ? 1 : 0;
// get terms and workaround WP bug with parents/pad counts
$args = array(
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'hide_empty' => $hide_empty,
'include' => $ids,
'pad_counts' => true,
'child_of' => $atts['parent']
);
$rand_product_categories = get_terms( 'product_cat', $args );
shuffle( $rand_product_categories );
// add $atts['number'] here
$rand_product_categories = array_slice( $rand_product_categories, 0, $atts['number'] );
// child_of default value is 0, no need to check for parent
/*if ( '' !== $atts['parent'] ) {
$rand_product_categories = wp_list_filter( $rand_product_categories, array( 'parent' => $atts['parent'] ) );
}*/
/*
// No need to check for hide empty, its already part of the query
if ( $hide_empty ) {
foreach ( $rand_product_categories as $key => $category ) {
if ( $category->count == 0 ) {
unset( $rand_product_categories[ $key ] );
}
}
}
*/
/* if ( $atts['number'] ) {
$rand_product_categories = array_slice( $rand_product_categories, 0, $atts['number'] );
}*/
$columns = absint( $atts['columns'] );
$woocommerce_loop['columns'] = $columns;
ob_start();
// Reset loop/columns globals when starting a new loop
$woocommerce_loop['loop'] = $woocommerce_loop['column'] = '';
// Shuffle already done
// if ( shuffle($rand_product_categories) ) {
woocommerce_product_loop_start();
foreach ( $rand_product_categories as $category ) {
wc_get_template( 'content-product_cat.php', array(
'category' => $category
) );
}
woocommerce_product_loop_end();
// }
woocommerce_reset_loop();
return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
}
add_shortcode( 'rand_prod_cat', 'rand_product_categories' );