/**
 * wpsc_edit_product_variations function.
 * this is the function to make child products using variations
 *
 * @access public
 * @param mixed $product_id
 * @param mixed $post_data
 * @return void
 */
function wpsc_edit_product_variations($product_id, $post_data)
{
    global $user_ID;
    $parent = get_post_field('post_parent', $product_id);
    if (!empty($parent)) {
        return;
    }
    $variations = array();
    $product_children = array();
    if (!isset($post_data['edit_var_val'])) {
        $post_data['edit_var_val'] = '';
    }
    $variations = (array) $post_data['edit_var_val'];
    // Generate the arrays for variation sets, values and combinations
    $wpsc_combinator = new wpsc_variation_combinator($variations);
    // Retrieve the array containing the variation set IDs
    $variation_sets = $wpsc_combinator->return_variation_sets();
    // Retrieve the array containing the combinations of each variation set to be associated with this product.
    $variation_values = $wpsc_combinator->return_variation_values();
    // Retrieve the array containing the combinations of each variation set to be associated with this product.
    $combinations = $wpsc_combinator->return_combinations();
    $product_terms = wp_get_object_terms($product_id, 'wpsc-variation');
    $variation_sets_and_values = array_merge($variation_sets, $variation_values);
    $variation_sets_and_values = apply_filters('wpsc_edit_product_variation_sets_and_values', $variation_sets_and_values, $product_id);
    wp_set_object_terms($product_id, $variation_sets_and_values, 'wpsc-variation');
    $child_product_template = array('post_author' => $user_ID, 'post_content' => $post_data['description'], 'post_excerpt' => $post_data['additional_description'], 'post_title' => $post_data['name'], 'post_status' => 'inherit', 'post_type' => "wpsc-product", 'post_name' => sanitize_title($post_data['name']), 'post_parent' => $product_id);
    $child_product_meta = get_post_custom($product_id);
    // here we loop through the combinations, get the term data and generate custom product names
    foreach ($combinations as $combination) {
        $term_names = array();
        $term_ids = array();
        $term_slugs = array();
        $product_values = $child_product_template;
        $combination_terms = get_terms('wpsc-variation', array('hide_empty' => 0, 'include' => implode(",", $combination), 'orderby' => 'parent'));
        foreach ($combination_terms as $term) {
            $term_ids[] = $term->term_id;
            $term_slugs[] = $term->slug;
            $term_names[] = $term->name;
        }
        $product_values['post_title'] .= " (" . implode(", ", $term_names) . ")";
        $product_values['post_name'] = sanitize_title($product_values['post_title']);
        $selected_post = get_posts(array('name' => $product_values['post_name'], 'post_parent' => $product_id, 'post_type' => "wpsc-product", 'post_status' => 'all', 'suppress_filters' => true));
        $selected_post = array_shift($selected_post);
        $child_product_id = wpsc_get_child_object_in_terms($product_id, $term_ids, 'wpsc-variation');
        $already_a_variation = true;
        if ($child_product_id == false) {
            $already_a_variation = false;
            if ($selected_post != null) {
                $child_product_id = $selected_post->ID;
            } else {
                $child_product_id = wp_insert_post($product_values);
            }
        } else {
            // sometimes there have been problems saving the variations, this gets the correct product ID
            if ($selected_post != null && $selected_post->ID != $child_product_id) {
                $child_product_id = $selected_post->ID;
            }
        }
        $product_children[] = $child_product_id;
        if ($child_product_id > 0) {
            wp_set_object_terms($child_product_id, $term_slugs, 'wpsc-variation');
        }
        //JS - 7.9 - Adding loop to include meta data in child product.
        if (!$already_a_variation) {
            $this_child_product_meta = apply_filters('insert_child_product_meta', $child_product_meta, $product_id, $combination_terms);
            foreach ($this_child_product_meta as $meta_key => $meta_value) {
                if ($meta_key == "_wpsc_product_metadata") {
                    update_post_meta($child_product_id, $meta_key, unserialize($meta_value[0]));
                } else {
                    update_post_meta($child_product_id, $meta_key, $meta_value[0]);
                }
            }
            if (is_array($term_ids) && ($price = wpsc_determine_variation_price($child_product_id, $term_ids))) {
                update_product_meta($child_product_id, 'price', $price);
            }
        }
    }
    //For reasons unknown, this code did not previously deal with variation deletions.
    //Basically, we'll just check if any existing term associations are missing from the posted variables, delete if they are.
    //Get posted terms (multi-dimensional array, first level = parent var, second level = child var)
    $posted_term = $variations;
    //Get currently associated terms
    $currently_associated_var = $product_terms;
    foreach ($currently_associated_var as $current) {
        $currently_associated_vars[] = $current->term_id;
    }
    foreach ($posted_term as $term => $val) {
        $posted_terms[] = $term;
        if (is_array($val)) {
            foreach ($val as $term2 => $val2) {
                $posted_terms[] = $term2;
            }
        }
    }
    if (!empty($currently_associated_vars)) {
        $term_ids_to_delete = array();
        $term_ids_to_delete = array_diff($currently_associated_vars, $posted_terms);
    }
    if (isset($_REQUEST["post_ID"])) {
        $post_id = $_REQUEST["post_ID"];
    } elseif (isset($_REQUEST["product_id"])) {
        $post_id = $_REQUEST["product_id"];
    }
    if (!empty($term_ids_to_delete) && (isset($_REQUEST["product_id"]) || isset($post_id))) {
        $post_ids_to_delete = array();
        // Whatever remains, find child products of current product with that term, in the variation taxonomy, and delete
        $post_ids_to_delete = wpsc_get_child_object_in_terms_var($_REQUEST["product_id"], $term_ids_to_delete, 'wpsc-variation');
        if (is_array($post_ids_to_delete) && !empty($post_ids_to_delete)) {
            foreach ($post_ids_to_delete as $object_ids) {
                foreach ($object_ids as $object_id) {
                    wp_delete_post($object_id);
                }
            }
        }
    }
    $current_children = query_posts(array('post_parent' => $post_id, 'post_type' => "wpsc-product", 'post_status' => 'all'));
    foreach ((array) $current_children as $child_prod) {
        $childs[] = $child_prod->ID;
    }
    if (!empty($childs)) {
        $old_ids_to_delete = array_diff($childs, $product_children);
        $old_ids_to_delete = apply_filters('wpsc_edit_product_variations_deletion', $old_ids_to_delete);
        if (is_array($old_ids_to_delete) && !empty($old_ids_to_delete)) {
            foreach ($old_ids_to_delete as $object_ids) {
                wp_delete_post($object_ids);
            }
        }
    }
}
 /**
  * wpsc_edit_product_variations function.
  * this is the function to make child products using variations 
  *
  * @access public
  * @param mixed $product_id
  * @param mixed $post_data
  * @return void
  */
 function data_feed_variants_manage($product_id, $post_data)
 {
     global $wpdb, $user_ID;
     $variations = array();
     if (!isset($post_data['edit_var_val'])) {
         $post_data['edit_var_val'] = '';
     }
     $variations = (array) $post_data['edit_var_val'];
     // bail if the array is empty
     if (count($variations) < 1) {
         return false;
     }
     // Generate the arrays for variation sets, values and combinations
     $wpsc_combinator = new wpsc_variation_combinator($variations);
     // Retrieve the array containing the variation set IDs
     $variation_sets = $wpsc_combinator->return_variation_sets();
     // Retrieve the array containing the combinations of each variation set to be associated with this product.
     $variation_values = $wpsc_combinator->return_variation_values();
     // Retrieve the array containing the combinations of each variation set to be associated with this product.
     $combinations = $wpsc_combinator->return_combinations();
     $variation_sets_and_values = array_merge($variation_sets, $variation_values);
     wp_set_object_terms($product_id, $variation_sets_and_values, 'wpsc-variation', true);
     $child_product_template = array('post_author' => $user_ID, 'post_content' => isset($post_data['description']) ? $post_data['description'] : '', 'post_excerpt' => isset($post_data['additional_description']) ? $post_data['additional_description'] : '', 'post_title' => isset($post_data['name']) ? $post_data['name'] : '', 'post_status' => 'inherit', 'post_type' => 'wpsc-product', 'post_name' => isset($post_data['name']) ? sanitize_title($post_data['name']) : '', 'post_parent' => $product_id);
     $child_product_meta = get_post_custom($product_id);
     if ($this->isGood($post_data['meta'])) {
         if ($this->isGood($post_data['meta']['_wpsc_price']) && $child_product_meta['_wpsc_price'] != $post_data['meta']['_wpsc_price']) {
             $child_product_meta['_wpsc_price'] = array($post_data['meta']['_wpsc_price']);
         }
         if ($this->isGood($post_data['meta']['_wpsc_stock']) && $this->isGood($child_product_meta['_wpsc_stock']) && $child_product_meta['_wpsc_stock'] != $post_data['meta']['_wpsc_stock']) {
             $child_product_meta['_wpsc_stock'] = array($post_data['meta']['_wpsc_stock']);
         }
         if ($this->isGood($post_data['meta']['_wpsc_product_metadata']['weight'])) {
             $tempMeta = unserialize($child_product_meta['_wpsc_product_metadata'][0]);
             $tempMeta['weight'] = $post_data['meta']['_wpsc_product_metadata']['weight'];
             $child_product_meta['_wpsc_product_metadata'] = array(serialize($tempMeta));
         }
     }
     // here we loop through the combinations, get the term data and generate custom product names
     $child_ids = array();
     foreach ($combinations as $combination) {
         $term_names = array();
         $term_ids = array();
         $term_slugs = array();
         $product_values = $child_product_template;
         $combination_terms = get_terms('wpsc-variation', array('hide_empty' => 0, 'include' => implode(",", $combination), 'orderby' => 'parent'));
         foreach ($combination_terms as $term) {
             $term_ids[] = $term->term_id;
             $term_slugs[] = $term->slug;
             $term_names[] = $term->name;
         }
         $product_values['post_title'] .= " (" . implode(", ", $term_names) . ")";
         $product_values['post_name'] = sanitize_title($product_values['post_title']);
         /*
          * wp_set_object_terms($product_id, $variation_sets_and_values, 'wpsc-variation');
          * Once we create a new variant, store it's variantion sets and values to a global
          * array that keeps track by style, at the end of the total update, send the list to
          * wp_set_object_terms, this should will other variantions.
          */
         if (!isset($this->itemsAdded[$product_id])) {
             $this->itemsAdded[$product_id] = array();
         }
         $this->itemsAdded[$product_id] = array_merge($this->itemsAdded[$product_id], array_merge($variation_sets, $variation_values));
         //This clears all previous variants
         wp_set_object_terms($product_id, $this->itemsAdded[$product_id], 'wpsc-variation', true);
         $selected_post = get_posts(array('name' => $product_values['post_name'], 'post_parent' => $product_id, 'post_type' => "wpsc-product", 'post_status' => 'all', 'suppress_filters' => true));
         $selected_post = array_shift($selected_post);
         $child_product_id = wpsc_get_child_object_in_terms($product_id, $term_ids, 'wpsc-variation');
         $already_a_variation = true;
         if ($child_product_id == false) {
             $already_a_variation = false;
             if ($selected_post != null) {
                 $child_product_id = $selected_post->ID;
             } else {
                 $child_product_id = wp_update_post($product_values);
             }
         } else {
             // sometimes there have been problems saving the variations, this gets the correct product ID
             if ($selected_post != null && $selected_post->ID != $child_product_id) {
                 $child_product_id = $selected_post->ID;
             }
         }
         if ($child_product_id > 0) {
             array_push($child_ids, $child_product_id);
             wp_set_object_terms($child_product_id, $term_slugs, 'wpsc-variation');
         }
         //JS - 7.9 - Adding loop to include meta data in child product.
         foreach ($child_product_meta as $meta_key => $meta_value) {
             if ($meta_key == "_wpsc_product_metadata") {
                 update_post_meta($child_product_id, $meta_key, unserialize($meta_value[0]));
             } else {
                 update_post_meta($child_product_id, $meta_key, $meta_value[0]);
             }
         }
         //Adding this to check for a price on variations.  Applying the highest price, seems to make the most sense.
         if (is_array($term_ids)) {
             $price = array();
             foreach ($term_ids as $term_id_price) {
                 $price[] = term_id_price($term_id_price, $child_product_meta["_wpsc_price"][0]);
                 //$price[] = $term_id_price;
             }
             rsort($price);
             $price = $price[0];
             if ($price > 0) {
                 update_post_meta($child_product_id, "_wpsc_price", $price);
             }
         }
     }
     return $child_ids;
 }