1
votes

I have a list of products which should show variations in it's own row. The code for that works fine so far.

But I couldn't figure out how I could show the SKU of a variation.

Here's my current code:

$args = [
    'status'    => array('publish', 'draft'),
    'orderby'   => 'name',
    'order'     => 'ASC',
    'limit'     => -1,
];
$vendor_products = wc_get_products($args);

$list_array = array();

foreach ($vendor_products as $key => $product) {

    if ($product->get_type() == "variable") {

        foreach ($product->get_variation_attributes() as $variations) {
            foreach ($variations as $variation) {

                $list_array[] = array(
                    'SKU'      => $product->get_sku(),
                    'Name'     => $product->get_title() . " - " . $variation,
                );

            }
        }

    } else {

        $list_array[] = array(
            'SKU'      => $product->get_sku(),
            'Name'     => $product->get_title(),
        );


    }
}

return $list_array;

I tried to display the product attributes and I also tried to get the ID of the variation. Nothing works for me?!

Is there no simple way to get the variation SKU?

1
wc_get_products() is only for "product" type but not for product_variation typeLoicTheAztec
Ah ok, is there any other way to get to the SKU within my foreach loop?Cray
so you want to get all variation skus from the variable products, as your are querying all "product" postype?LoicTheAztec
Yes, kind of. I need the SKU of the variation instead the one from the parent product. I have already the addition of the variation in the title but couldn't get any other stuff like ID or SKUCray

1 Answers

2
votes

You should better use WC_Product_Variable get_children() method like:

$args = [
    'status'    => array('publish', 'draft'),
    'orderby'   => 'name',
    'order'     => 'ASC',
    'limit'     => -1,
];
$vendor_products = wc_get_products($args);

$list_array = array();

foreach ($vendor_products as $key => $product) {

    if ( $product->is_type( "variable" ) ) {

        foreach ( $product->get_children( false ) as $child_id ) {
            // get an instance of the WC_Variation_product Object
            $variation = wc_get_product( $child_id ); 

            if ( ! $variation || ! $variation->exists() ) {
                continue;
            }

            $list_array[] = array(
                'SKU'      => $variation->get_sku(),
                'Name'     => $product->get_name() . " - " . $child_id,
            );
        }

    } else {

        $list_array[] = array(
            'SKU'      => $product->get_sku(),
            'Name'     => $product->get_name(),
        );

    }

}

return $list_array;

Or even some other available methods like get_available_variations() (which use get_children() method when looking at its source code). It should better work...


Targeting product variations of a variable product with different other post statuses than "publish".

In this case you should replace get_children() method with a custom WP_Query that will handle other post statuses like below:

$statuses = array('publish', 'draft');

// Args on the main query for WC_Product_Query
$args = [
    'status'    => $statuses,
    'orderby'   => 'name',
    'order'     => 'ASC',
    'limit'     => -1,
];

$vendor_products = wc_get_products($args);

$list_array = array();

foreach ($vendor_products as $key => $product) {

    if ($product->get_type() == "variable") {

        // Args on product variations query for a variable product using a WP_Query
        $args2 = array( 
            'post_parent' => $product->get_id(), 
            'post_type'   => 'product_variation', 
            'orderby'     => array( 'menu_order' => 'ASC', 'ID' => 'ASC' ), 
            'fields'      => 'ids', 
            'post_status' => $statuses, 
            'numberposts' => -1, 
        ); 

        foreach ( get_posts( $args2 ) as $child_id ) {
            // get an instance of the WC_Variation_product Object
            $variation = wc_get_product( $child_id ); 

            if ( ! $variation || ! $variation->exists() ) {
                continue;
            }

            $list_array[] = array(
                'SKU'      => $variation->get_sku(),
                'Name'     => $product->get_name() . " - " . $child_id,
            );
        }

    } else {

        $list_array[] = array(
            'SKU'      => $product->get_sku(),
            'Name'     => $product->get_name(),
        );

    }

}

return $list_array;

This time you will get all the product variations of your variable products.

For reference: Product -> Get Children doesn't return all variations #13469