function fn_add_product_to_cart($product_data, &$cart, &$auth, $update = false) { $ids = array(); if (!empty($product_data) && is_array($product_data)) { if (!defined('GET_OPTIONS')) { list($product_data, $cart) = fn_add_product_options_files($product_data, $cart, $auth, $update); } fn_set_hook('pre_add_to_cart', $product_data, $cart, $auth, $update); foreach ($product_data as $key => $data) { if (empty($key)) { continue; } if (empty($data['amount'])) { continue; } $data['stored_price'] = !empty($data['stored_price']) && defined('ORDER_MANAGEMENT') ? $data['stored_price'] : 'N'; if (empty($data['extra'])) { $data['extra'] = array(); } $product_id = !empty($data['product_id']) ? intval($data['product_id']) : intval($key); if (!fn_check_add_product_to_cart($cart, $data, $product_id)) { continue; } // Check if product options exist if (!isset($data['product_options'])) { $data['product_options'] = fn_get_default_product_options($product_id); } // Generate cart id $data['extra']['product_options'] = $data['product_options']; $_id = fn_generate_cart_id($product_id, $data['extra'], false); if (isset($ids[$_id]) && $key == $_id) { continue; } if (isset($data['extra']['exclude_from_calculate'])) { if (!empty($cart['products'][$key]) && !empty($cart['products'][$key]['extra']['aoc'])) { $cart['saved_product_options'][$cart['products'][$key]['extra']['saved_options_key']] = $data['product_options']; } if (isset($cart['deleted_exclude_products'][$data['extra']['exclude_from_calculate']][$_id])) { continue; } } $amount = fn_normalize_amount(@$data['amount']); if (!isset($data['extra']['exclude_from_calculate'])) { if ($data['stored_price'] != 'Y') { $allow_add = true; // Check if the product price with options modifiers equals to zero $price = fn_get_product_price($product_id, $amount, $auth); $zero_price_action = db_get_field("SELECT zero_price_action FROM ?:products WHERE product_id = ?i", $product_id); if (!floatval($price) && $zero_price_action == 'A') { if (isset($cart['products'][$key]['custom_user_price'])) { $price = $cart['products'][$key]['custom_user_price']; } else { $custom_user_price = empty($data['price']) ? 0 : $data['price']; } } $price = fn_apply_options_modifiers($data['product_options'], $price, 'P', array(), array('product_data' => $data)); if (!floatval($price)) { $data['price'] = isset($data['price']) ? fn_parse_price($data['price']) : 0; if (($zero_price_action == 'R' || $zero_price_action == 'A' && floatval($data['price']) < 0) && AREA == 'C') { if ($zero_price_action == 'A') { fn_set_notification('E', __('error'), __('incorrect_price_warning')); } $allow_add = false; } $price = empty($data['price']) ? 0 : $data['price']; } /** * Recalculates price and checks if product can be added with the current price * * @param array $data Adding product data * @param float $price Calculated product price * @param boolean $allow_add Flag that determines if product can be added to cart */ fn_set_hook('add_product_to_cart_check_price', $data, $price, $allow_add); if (!$allow_add) { continue; } } else { $price = empty($data['price']) ? 0 : $data['price']; } } else { $price = 0; } $_data = db_get_row('SELECT is_edp, options_type, tracking, unlimited_download FROM ?:products WHERE product_id = ?i', $product_id); if (isset($_data['is_edp'])) { $data['is_edp'] = $_data['is_edp']; } elseif (!isset($data['is_edp'])) { $data['is_edp'] = 0; } if (isset($_data['options_type'])) { $data['options_type'] = $_data['options_type']; } if (isset($_data['tracking'])) { $data['tracking'] = $_data['tracking']; } if (isset($_data['unlimited_download'])) { $data['extra']['unlimited_download'] = $_data['unlimited_download']; } // Check the sequential options if (!empty($data['tracking']) && $data['tracking'] == ProductTracking::TRACK_WITH_OPTIONS && $data['options_type'] == 'S') { $inventory_options = db_get_fields("SELECT a.option_id FROM ?:product_options as a LEFT JOIN ?:product_global_option_links as c ON c.option_id = a.option_id WHERE (a.product_id = ?i OR c.product_id = ?i) AND a.status = 'A' AND a.inventory = 'Y'", $product_id, $product_id); $sequential_completed = true; if (!empty($inventory_options)) { foreach ($inventory_options as $option_id) { if (!isset($data['product_options'][$option_id]) || empty($data['product_options'][$option_id])) { $sequential_completed = false; break; } } } if (!$sequential_completed) { fn_set_notification('E', __('error'), __('select_all_product_options')); // Even if customer tried to add the product from the catalog page, we will redirect he/she to the detailed product page to give an ability to complete a purchase $redirect_url = fn_url('products.view?product_id=' . $product_id . '&combination=' . fn_get_options_combination($data['product_options'])); $_REQUEST['redirect_url'] = $redirect_url; //FIXME: Very very very BAD style to use the global variables in the functions!!! return false; } } if (!isset($cart['products'][$_id])) { // If product doesn't exists in the cart $amount = empty($data['original_amount']) ? fn_check_amount_in_stock($product_id, $amount, $data['product_options'], $_id, $data['is_edp'], 0, $cart, $update == true ? $key : 0) : $data['original_amount']; if ($amount === false) { continue; } $cart['products'][$_id]['product_id'] = $product_id; $cart['products'][$_id]['product_code'] = fn_get_product_code($product_id, $data['product_options']); $cart['products'][$_id]['product'] = fn_get_product_name($product_id); $cart['products'][$_id]['amount'] = $amount; $cart['products'][$_id]['product_options'] = $data['product_options']; $cart['products'][$_id]['price'] = $price; if (!empty($zero_price_action) && $zero_price_action == 'A') { if (isset($custom_user_price)) { $cart['products'][$_id]['custom_user_price'] = $custom_user_price; } elseif (isset($cart['products'][$key]['custom_user_price'])) { $cart['products'][$_id]['custom_user_price'] = $cart['products'][$key]['custom_user_price']; } } $cart['products'][$_id]['stored_price'] = $data['stored_price']; // add image for minicart $cart['products'][$_id]['main_pair'] = fn_get_cart_product_icon($product_id, $data); fn_define_original_amount($product_id, $_id, $cart['products'][$_id], $data); if ($update == true && $key != $_id) { fn_delete_cart_product($cart, $key, false); } } else { // If product is already exist in the cart $_initial_amount = empty($cart['products'][$_id]['original_amount']) ? $cart['products'][$_id]['amount'] : $cart['products'][$_id]['original_amount']; // If ID changed (options were changed), summ the total amount of old and new products if ($update == true && $key != $_id) { $amount += $_initial_amount; fn_delete_cart_product($cart, $key, false); } $cart['products'][$_id]['amount'] = fn_check_amount_in_stock($product_id, ($update == true ? 0 : $_initial_amount) + $amount, $data['product_options'], $_id, !empty($data['is_edp']) && $data['is_edp'] == 'Y' ? 'Y' : 'N', 0, $cart, $update == true ? $key : 0); } $cart['products'][$_id]['extra'] = empty($data['extra']) ? array() : $data['extra']; $cart['products'][$_id]['stored_discount'] = @$data['stored_discount']; if (defined('ORDER_MANAGEMENT')) { $cart['products'][$_id]['discount'] = @$data['discount']; } // Increase product popularity if (empty($_SESSION['products_popularity']['added'][$product_id])) { $_data = array('product_id' => $product_id, 'added' => 1, 'total' => POPULARITY_ADD_TO_CART); db_query("INSERT INTO ?:product_popularity ?e ON DUPLICATE KEY UPDATE added = added + 1, total = total + ?i", $_data, POPULARITY_ADD_TO_CART); $_SESSION['products_popularity']['added'][$product_id] = true; } $company_id = db_get_field("SELECT company_id FROM ?:products WHERE product_id = ?i", $product_id); $cart['products'][$_id]['company_id'] = $company_id; if (!empty($data['saved_object_id'])) { $cart['products'][$_id]['object_id'] = $data['saved_object_id']; } fn_set_hook('add_to_cart', $cart, $product_id, $_id); $ids[$_id] = $product_id; } /** * Change product data after adding product to cart * * @param array $product_data Product data * @param array $cart Cart data * @param array $auth Auth data * @param bool $update Flag the determains if cart data are updated */ fn_set_hook('post_add_to_cart', $product_data, $cart, $auth, $update, $ids); $cart['recalculate'] = true; if (!empty($cart['chosen_shipping'])) { $cart['calculate_shipping'] = true; unset($cart['product_groups']); } return $ids; } else { return false; } }
} } fn_update_exceptions($_REQUEST['product_id']); $suffix = ".exceptions?product_id={$_REQUEST['product_id']}"; } if ($mode == 'm_delete_exceptions') { db_query("DELETE FROM ?:product_options_exceptions WHERE exception_id IN (?n)", $_REQUEST['exception_ids']); $suffix = ".exceptions?product_id={$_REQUEST['product_id']}"; } } if ($mode == 'add_combinations') { if (is_array($_REQUEST['add_inventory'])) { foreach ($_REQUEST['add_inventory'] as $k => $v) { $combination_hash = fn_generate_cart_id($_REQUEST['product_id'], array('product_options' => $_REQUEST['add_options_combination'][$k])); $combination = fn_get_options_combination($_REQUEST['add_options_combination'][$k]); $product_code = fn_get_product_code($_REQUEST['product_id'], $_REQUEST['add_options_combination'][$k]); $_data = array('product_id' => $_REQUEST['product_id'], 'combination_hash' => $combination_hash, 'combination' => $combination, 'product_code' => !empty($product_code) ? $product_code : ''); $_data = fn_array_merge($v, $_data); db_query("REPLACE INTO ?:product_options_inventory ?e", $_data); } } $suffix = ".inventory?product_id={$_REQUEST['product_id']}"; } if ($mode == 'update_combinations') { // Updating images fn_attach_image_pairs('combinations', 'product_option', 0, CART_LANGUAGE, array()); $inventory = db_get_hash_array("SELECT * FROM ?:product_options_inventory WHERE product_id = ?i", 'combination_hash', $_REQUEST['product_id']); foreach ($inventory as $i) { $inventory_ids[] = $i['combination_hash']; } fn_attach_aditional_image_pairs('product_option_add_additional', 'product_option', 0, CART_LANGUAGE, $inventory_ids);
/** * Updates/Creates options combination * * @param array $combination_data Combination data * @param string $combination_hash Combination hash * @return string Combination hash */ function fn_update_option_combination($combination_data, $combination_hash = 0) { /** * Change parameters for updating options combination * * @param array $combination_data Combination data * @param string $combination_hash Combination hash */ fn_set_hook('update_option_combination_pre', $combination_data, $combination_hash); $inventory_amount = db_get_field('SELECT amount FROM ?:product_options_inventory WHERE combination_hash = ?s', $combination_hash); if (empty($combination_hash)) { $combination_hash = fn_generate_cart_id($combination_data['product_id'], array('product_options' => $combination_data['combination'])); $combination = fn_get_options_combination($combination_data['combination']); $product_code = fn_get_product_code($combination_data['product_id'], $combination_data['combination']); $_data = array('product_id' => $combination_data['product_id'], 'combination_hash' => $combination_hash, 'combination' => $combination, 'product_code' => !empty($product_code) ? $product_code : '', 'amount' => !empty($combination_data['amount']) ? $combination_data['amount'] : 0, 'position' => !empty($combination_data['position']) ? $combination_data['position'] : 0); db_query("REPLACE INTO ?:product_options_inventory ?e", $_data); } else { // Forbid to update options in the existing combination. Only qty/code/pos. unset($combination_data['combination']); db_query("UPDATE ?:product_options_inventory SET ?u WHERE combination_hash = ?s", $combination_data, $combination_hash); } if (isset($combination_data['amount']) && $combination_data['amount'] > 0 && $inventory_amount <= 0) { fn_send_product_notifications($combination_data['product_id']); } // Updating images fn_attach_image_pairs('combinations', 'product_option'); /** * Makes extra actions after updating options combination * * @param array $combination_data Combination data * @param string $combination_hash Combination hash * @param int $inventory_amount Previous (before update) inventory amount of the combination */ fn_set_hook('update_option_combination_pre', $combination_data, $combination_hash, $inventory_amount); return $combination_hash; }