Added wc_array_cartesian function to generate variations in a logical order.

Fixes #9515 @claudiosmweb
This commit is contained in:
Mike Jolley 2015-11-04 12:14:48 +00:00
parent e1c2054b5c
commit 7eb45ba16f
3 changed files with 68 additions and 63 deletions

View File

@ -946,71 +946,9 @@ class WC_AJAX {
'post_type' => 'product_variation'
);
// Now find all combinations and create posts
if ( ! function_exists( 'array_cartesian' ) ) {
/**
* @param array $input
* @return array
*/
function array_cartesian( $input ) {
$result = array();
while ( list( $key, $values ) = each( $input ) ) {
// If a sub-array is empty, it doesn't affect the cartesian product
if ( empty( $values ) ) {
continue;
}
// Special case: seeding the product array with the values from the first sub-array
if ( empty( $result ) ) {
foreach ( $values as $value ) {
$result[] = array( $key => $value );
}
}
else {
// Second and subsequent input sub-arrays work like this:
// 1. In each existing array inside $product, add an item with
// key == $key and value == first item in input sub-array
// 2. Then, for each remaining item in current input sub-array,
// add a copy of each existing array inside $product with
// key == $key and value == first item in current input sub-array
// Store all items to be added to $product here; adding them on the spot
// inside the foreach will result in an infinite loop
$append = array();
foreach ( $result as &$product ) {
// Do step 1 above. array_shift is not the most efficient, but it
// allows us to iterate over the rest of the items with a simple
// foreach, making the code short and familiar.
$product[ $key ] = array_shift( $values );
// $product is by reference (that's why the key we added above
// will appear in the end result), so make a copy of it here
$copy = $product;
// Do step 2 above.
foreach ( $values as $item ) {
$copy[ $key ] = $item;
$append[] = $copy;
}
// Undo the side effecst of array_shift
array_unshift( $values, $product[ $key ] );
}
// Out of the foreach, we can add to $results now
$result = array_merge( $result, $append );
}
}
return $result;
}
}
$variation_ids = array();
$added = 0;
$possible_variations = array_cartesian( $variations );
$possible_variations = wc_array_cartesian( $variations );
foreach ( $possible_variations as $variation ) {

View File

@ -844,3 +844,69 @@ function wc_rand_hash() {
function wc_api_hash( $data ) {
return hash_hmac( 'sha256', $data, 'wc-api' );
}
/**
* Find all possible combinations of values from the input array and return in a logical order.
* @since 2.5.0
* @param array $input
* @return array
*/
function wc_array_cartesian( $input ) {
$input = array_filter( $input );
$results = array();
$indexes = array();
$index = 0;
// Generate indexes from keys and values so we have a logical sort order
foreach ( $input as $key => $values ) {
foreach ( $values as $value ) {
$indexes[ $key ][ $value ] = $index ++;
}
}
// Loop over the 2D array of indexes and generate all combinations
foreach ( $indexes as $key => $values ) {
// When result is empty, fill with the values of the first looped array
if ( empty( $results ) ) {
foreach ( $values as $value ) {
$results[] = array( $key => $value );
}
// Second and subsequent input sub-array merging.
} else {
foreach ( $results as $result_key => $result ) {
foreach ( $values as $value ) {
// If the key is not set, we can set it
if ( ! isset( $results[ $result_key ][ $key ] ) ) {
$results[ $result_key ][ $key ] = $value;
// If the key is set, we can add a new combination to the results array
} else {
$new_combination = $results[ $result_key ];
$new_combination[ $key ] = $value;
$results[] = $new_combination;
}
}
}
}
}
// Sort the indexes
arsort( $results );
// Convert indexes back to values
foreach ( $results as $result_key => $result ) {
$converted_values = array();
// Sort the values
arsort( $results[ $result_key ] );
// Convert the values
foreach ( $results[ $result_key ] as $key => $value ) {
$converted_values[ $key ] = array_search( $value, $indexes[ $key ] );
}
$results[ $result_key ] = $converted_values;
}
return $results;
}

View File

@ -169,6 +169,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
* Fix - Check for existence of global attribute when you get_attributes() for a product.
* Fix - Show order by template on product search.
* Fix - Search variation skus in backend search.
* Tweak - Added wc_array_cartesian function to generate variations in a logical order.
* Tweak - Revised email settings screens to show emails in a table and avoid a long sub-nav.
* Tweak - Default customer role capabilities.
* Tweak - Expire mini-cart cache after 24 hours.