/**
 * Update a visitor's cart
 *
 * @access public
 * @since 3.8.9
 * @param  mixed $id visitor ID. Default to the current user ID.
 * @return  WP_Error | wpsc_cart
 */
function wpsc_update_visitor_cart($visitor_id, $wpsc_cart)
{
    if (!_wpsc_visitor_database_ready()) {
        return $wpsc_cart;
    }
    if (!empty($wpsc_cart->_signature)) {
        if (_wpsc_calculate_cart_signature($wpsc_cart) == $wpsc_cart->_signature) {
            return $wpsc_cart;
        }
    }
    foreach ($wpsc_cart as $key => $value) {
        $cart_property_meta_key = _wpsc_get_visitor_meta_key('cart.' . $key);
        // we don't store empty cart properties, this keeps meta table and caches neater
        if (!empty($value)) {
            switch ($key) {
                case '_signature':
                    // don't save the signature
                // don't save the signature
                case 'current_cart_item':
                    // don't save array cursor
                // don't save array cursor
                case 'current_shipping_method':
                    // don't save array cursor
                // don't save array cursor
                case 'current_shipping_quote':
                    // don't save array cursor
                    continue;
                case 'shipping_methods':
                case 'shipping_quotes':
                case 'cart_items':
                case 'cart_item':
                    $value = _wpsc_encode_meta_value($value);
                    break;
                default:
                    break;
            }
            wpsc_update_visitor_meta($visitor_id, $cart_property_meta_key, $value);
        } else {
            wpsc_delete_visitor_meta($visitor_id, $cart_property_meta_key);
        }
    }
    $wpsc_cart->_signature = _wpsc_calculate_cart_signature($wpsc_cart);
    return apply_filters('wpsc_update_visitor_cart', $wpsc_cart, $visitor_id);
}
/**
 * Merge cart from anonymous user with cart from logged in user
 *
 * @since 3.8.13
 * @access private
 */
function _wpsc_merge_cart()
{
    $id_from_wp_user = get_user_meta(get_current_user_id(), _wpsc_get_visitor_meta_key('visitor_id'), true);
    if (empty($id_from_wp_user)) {
        return;
    }
    do_action('_wpsc_merge_cart', $id_from_wp_user);
    $id_from_customer_meta = wpsc_get_customer_meta('merge_cart_vistor_id');
    wpsc_delete_customer_meta('merge_cart_vistor_id');
    $old_cart = wpsc_get_customer_cart($id_from_customer_meta);
    $items = $old_cart->get_items();
    $new_cart = wpsc_get_customer_cart($id_from_wp_user);
    // first of all empty the old cart so that the claimed stock and related
    // hooks are released
    $old_cart->empty_cart();
    // add each item to the new cart
    foreach ($items as $item) {
        $new_cart->set_item($item->product_id, array('quantity' => $item->quantity, 'variation_values' => $item->variation_values, 'custom_message' => $item->custom_message, 'provided_price' => $item->provided_price, 'time_requested' => $item->time_requested, 'custom_file' => $item->custom_file, 'is_customisable' => $item->is_customisable, 'meta' => $item->meta, 'item_meta' => $item->get_meta()));
    }
    wpsc_update_customer_cart($new_cart);
    // The old profile is no longer needed
    _wpsc_abandon_temporary_customer_profile($id_from_customer_meta);
}
/**
 * Check the visitor meta key to see if it has been aliased to another visitor meta key
 *
 * @since 3.8.14
 *
 * @param string $visitor_meta_key
 * @return string valid unchanged key if original is valid, or replacement visitor meta key
 */
function _wpsc_validate_visitor_meta_key($visitor_meta_key)
{
    // WPEC internal visitor meta keys are not allowed to be aliased, internal visitor meta keys
    if (!(strpos($visitor_meta_key, _wpsc_get_visitor_meta_key('')) === 0)) {
        $build_in_checkout_names = wpsc_checkout_unique_names();
        // the built in checkout names cannot be aliased to something else
        if (!in_array($visitor_meta_key, $build_in_checkout_names)) {
            /**
             * Filter wpsc_visitor_meta_key_replacements
             *
             * Get an array of key/value pairs that are used to alias visitor meta keys. The
             * key is the old name, the value is the new name
             *
             * @since 3.8.14
             *
             * @param array of key value pairs
             *
             */
            $aliased_meta_keys = apply_filters('wpsc_visitor_meta_key_replacements', array());
            if (isset($aliased_meta_keys[$visitor_meta_key])) {
                $visitor_meta_key = $aliased_meta_keys[$visitor_meta_key];
            }
        }
    }
    return $visitor_meta_key;
}