public function syncGlobalCartProductsWithOrder($encoder, $order, &$updates = null) { global $cart; // helper arrays, in all keys are [productId][productAttributeId] (if no productAttributeId, then it's 0) $cartProductQuantities = array(); // value is quantity $orderProductQuantities = array(); // value is quantity // go over the cart products and prepare them for sync $_cartProducts = $this->getCartProductsFromCartId($cart->id); foreach ($_cartProducts as $row) { if ($row['id_product_attribute']) { $cartProductQuantities[$row['id_product']][$row['id_product_attribute']] = (int) $row['quantity']; } else { $cartProductQuantities[$row['id_product']][0] = (int) $row['quantity']; } } // go over the order products and prepare them for sync $orderItems = CartAPI_Helpers::getDictionaryKeyAsArray($order, 'OrderItem'); foreach ($orderItems as $orderItem) { if (!isset($orderItem['ItemId'])) { continue; } $productAttribute = $this->getProductAttributeIdFromOrderItem($orderItem); if ($productAttribute !== false) { $orderProductQuantities[$orderItem['ItemId']][$productAttribute] = (int) $orderItem['Quantity']; } else { $orderProductQuantities[$orderItem['ItemId']][0] = (int) $orderItem['Quantity']; } } // start syncing $errors = array(); $updateFailed = false; // this accomodates the initial checkDiscountValidity() in the beginning of CartController preProcess() // consider putting it back, removed because seems redundant /// $this->validateGlobalCartDiscounts($errors, false); // first, make sure everything in the order is in the cart too foreach ($orderProductQuantities as $productId => $productAttributeIds) { foreach ($productAttributeIds as $productAttributeId => $orderQuantity) { $cartQuantity = 0; if (isset($cartProductQuantities[$productId][$productAttributeId])) { $cartQuantity = (int) $cartProductQuantities[$productId][$productAttributeId]; } // do the quantity update if (!$this->updateGlobalCartProductQuantity($orderQuantity - $cartQuantity, $productId, $productAttributeId, $errors)) { $updateFailed = true; } unset($cartProductQuantities[$productId][$productAttributeId]); // to make sure we don't sync it again } } // second, if we have anything left in the cart list, it should be removed since it's not in the order anymore foreach ($cartProductQuantities as $productId => $productAttributeIds) { foreach ($productAttributeIds as $productAttributeId => $cartQuantity) { // remove the product from the cart if (!$this->updateGlobalCartProductQuantity(-1 * $cartQuantity, $productId, $productAttributeId, $errors)) { $updateFailed = true; } } } // done syncing // handle the errors if found if ($updateFailed || count($errors) > 0) { // if we can't update the order, die if ($updates === null) { CartAPI_Helpers::dieOnErrors($encoder, 'InvalidOrder', $errors); } // if here, then update the order (add an order update) $this->addOrderItemsOrderUpdateFromGlobalCart($encoder, $updates, $errors); } }