Skip to content

Instantly share code, notes, and snippets.

@elliotcondon
Last active January 26, 2023 20:09
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save elliotcondon/c94abec50dc26ac065c6 to your computer and use it in GitHub Desktop.
Save elliotcondon/c94abec50dc26ac065c6 to your computer and use it in GitHub Desktop.
WooCommerce 'Create variations from all attributes' randomisation fix
<?php
/*
* array_cartesian
*
* This function will fix a frustrating issue in the WooCommerce plugin
* When adding a product using variations, you will most likely use the 'Create variations from all attributes' function
* The issue with this function is that it will create the variations in a random order
* This is frustrating for your clients to edit
*
* The solution is to add the following code to your functions.php file which will modify a function used
* by WooCommerce which does the same functionality, but will keep the expected variation order.
* Origional issue posted here: http://ideas.woothemes.com/forums/133476-woocommerce/suggestions/2650776-be-able-to-sort-variations-of-variable-products-in
*
* @type function
* @date 25/10/2015
* @since n/a
*
* @param $input (array)
* @return $input (array)
*/
if ( ! function_exists( 'array_cartesian' ) ) {
function array_cartesian( $input ) {
// vars
$i = 0;
$max = 1;
$keys = array_keys($input);
$item = array();
$limits = array();
$variations = array();
// populate item
foreach( $keys as $k ) {
// reset array keys
$input[ $k ] = array_values($input[ $k ]);
// set item value
$item[ $k ] = $input[ $k ][0];
// set limit default
$limits[ $k ] = count($input[$k]);
// increase max
$max = $max * count($input[$k]);
}
// loop
while( $i < $max ) {
// vars
$i++;
$index = $i-1;
$variation = $item;
// calculate
foreach( array_reverse($limits) as $k => $limit ) {
// bail early if 0
if( $index == 0 ) break;
// vars
$floor = floor( $index / $limit );
// update index
$index = $index - ($floor * $limit);
// set $variation
$variation[ $k ] = $input[ $k ][ $index ];
// update index for new looping
$index = $floor;
}
// append
$variations[] = $variation;
}
// return
return $variations;
}
}
?>
@jkohlbach
Copy link

Great solution, I raised a core ticket in WooCommerce for this to be integrated.. fingers crossed!

woocommerce/woocommerce#9515

@elliotcondon
Copy link
Author

Update - changed logic to a much simpler and easy to understand solution!

@cartrust
Copy link

Hi there I am trying to get all makes and models of cars to sort automatically by alphabetically. Will this work for that issue. Currently I have to drag and drop after they are created. Where do I add the above code?

@MasterK999
Copy link

This works great except for sorting sizes with numbers above 10. I have a product with many sizes such as 1' x 3', 2' x 3', 3' x'5 ,8' x 10', 11' x 14'.

This bit of code puts 11' x 14' right after 1' x 3'. It is like it only sort by the first digit. How can I change it to put 11 at the end where it should go?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment