/**
 * 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);
            }
        }
    }
}
/**
 * @todo - Should probably refactor this at some point - very procedural,
 *         WAY too many foreach loops for my liking :)  But it does the trick
 *
 * @param <type> $term_id
 */
function save_term_prices($term_id)
{
    // First - Saves options from input
    if (isset($_POST['variation_price']) || isset($_POST["apply_to_current"])) {
        $term_prices = get_option('term_prices');
        $term_prices[$term_id]["price"] = sanitize_text_field($_POST["variation_price"]);
        $term_prices[$term_id]["checked"] = isset($_POST["apply_to_current"]) ? "checked" : "unchecked";
        update_option('term_prices', $term_prices);
    }
    // Second - If box was checked, let's then check whether or not it was flat, differential, or percentile, then let's apply the pricing to every product appropriately
    if (isset($_POST["apply_to_current"])) {
        //Now, find all products with this term_id, update their pricing structure (terms returned include only parents at this point, we'll grab relevent children soon)
        $products_to_mod = get_objects_in_term($term_id, "wpsc-variation");
        $product_parents = array();
        foreach ((array) $products_to_mod as $get_parent) {
            $post = get_post($get_parent);
            if (!$post->post_parent) {
                $product_parents[] = $post->ID;
            }
        }
        //Now that we have all parent IDs with this term, we can get the children (only the ones that are also in $products_to_mod, we don't want to apply pricing to ALL kids)
        foreach ($product_parents as $parent) {
            $args = array('post_parent' => $parent, 'post_type' => 'wpsc-product');
            $children = get_children($args, ARRAY_A);
            foreach ($children as $childrens) {
                $parent = $childrens["post_parent"];
                $children_ids[$parent][] = $childrens["ID"];
                $children_ids[$parent] = array_intersect($children_ids[$parent], $products_to_mod);
            }
        }
        //Got the right kids, let's grab their parent pricing and modify their pricing based on var_price_type
        foreach ((array) $children_ids as $parents => $kids) {
            $kids = array_values($kids);
            foreach ($kids as $kiddos) {
                $price = wpsc_determine_variation_price($kiddos);
                update_product_meta($kiddos, 'price', $price);
            }
        }
    }
}