Example #1
0
 /**
  * Prepare product and its configuration to be added to some products list.
  * Perform standard preparation process and then prepare of bundle selections options.
  *
  * @param \Magento\Framework\DataObject $buyRequest
  * @param \Magento\Catalog\Model\Product $product
  * @param string $processMode
  * @return \Magento\Framework\Phrase|array|string
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.NPathComplexity)
  * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  */
 protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $product, $processMode)
 {
     $result = parent::_prepareProduct($buyRequest, $product, $processMode);
     try {
         if (is_string($result)) {
             throw new \Magento\Framework\Exception\LocalizedException(__($result));
         }
         $selections = [];
         $isStrictProcessMode = $this->_isStrictProcessMode($processMode);
         $skipSaleableCheck = $this->_catalogProduct->getSkipSaleableCheck();
         $_appendAllSelections = (bool) $product->getSkipCheckRequiredOption() || $skipSaleableCheck;
         $options = $buyRequest->getBundleOption();
         if (is_array($options)) {
             $options = $this->recursiveIntval($options);
             $optionIds = array_keys($options);
             if (empty($optionIds) && $isStrictProcessMode) {
                 throw new \Magento\Framework\Exception\LocalizedException(__('Please specify product option(s).'));
             }
             $product->getTypeInstance()->setStoreFilter($product->getStoreId(), $product);
             $optionsCollection = $this->getOptionsCollection($product);
             $this->checkIsAllRequiredOptions($product, $isStrictProcessMode, $optionsCollection, $options);
             $selectionIds = $this->multiToFlatArray($options);
             // If product has not been configured yet then $selections array should be empty
             if (!empty($selectionIds)) {
                 $selections = $this->getSelectionsByIds($selectionIds, $product);
                 if (count($selections->getItems()) !== count($selectionIds)) {
                     throw new \Magento\Framework\Exception\LocalizedException(__('The options you selected are not available.'));
                 }
                 // Check if added selections are still on sale
                 $this->checkSelectionsIsSale($selections, $skipSaleableCheck, $optionsCollection, $options);
                 $optionsCollection->appendSelections($selections, false, $_appendAllSelections);
                 $selections = $selections->getItems();
             } else {
                 $selections = [];
             }
         } else {
             $product->setOptionsValidationFail(true);
             $product->getTypeInstance()->setStoreFilter($product->getStoreId(), $product);
             $optionCollection = $product->getTypeInstance()->getOptionsCollection($product);
             $optionIds = $product->getTypeInstance()->getOptionsIds($product);
             $selectionCollection = $product->getTypeInstance()->getSelectionsCollection($optionIds, $product);
             $options = $optionCollection->appendSelections($selectionCollection, false, $_appendAllSelections);
             $selections = $this->mergeSelectionsWithOptions($options, $selections);
         }
         if (count($selections) > 0 || !$isStrictProcessMode) {
             $uniqueKey = [$product->getId()];
             $selectionIds = [];
             $qtys = $buyRequest->getBundleOptionQty();
             // Shuffle selection array by option position
             usort($selections, [$this, 'shakeSelections']);
             foreach ($selections as $selection) {
                 $selectionOptionId = $selection->getOptionId();
                 $qty = $this->getQty($selection, $qtys, $selectionOptionId);
                 $selectionId = $selection->getSelectionId();
                 $product->addCustomOption('selection_qty_' . $selectionId, $qty, $selection);
                 $selection->addCustomOption('selection_id', $selectionId);
                 $beforeQty = $this->getBeforeQty($product, $selection);
                 $product->addCustomOption('product_qty_' . $selection->getId(), $qty + $beforeQty, $selection);
                 /*
                  * Create extra attributes that will be converted to product options in order item
                  * for selection (not for all bundle)
                  */
                 $price = $product->getPriceModel()->getSelectionFinalTotalPrice($product, $selection, 0, $qty);
                 $attributes = ['price' => $this->priceCurrency->convert($price), 'qty' => $qty, 'option_label' => $selection->getOption()->getTitle(), 'option_id' => $selection->getOption()->getId()];
                 $_result = $selection->getTypeInstance()->prepareForCart($buyRequest, $selection);
                 $this->checkIsResult($_result);
                 $result[] = $_result[0]->setParentProductId($product->getId())->addCustomOption('bundle_option_ids', serialize(array_map('intval', $optionIds)))->addCustomOption('bundle_selection_attributes', serialize($attributes));
                 if ($isStrictProcessMode) {
                     $_result[0]->setCartQty($qty);
                 }
                 $resultSelectionId = $_result[0]->getSelectionId();
                 $selectionIds[] = $resultSelectionId;
                 $uniqueKey[] = $resultSelectionId;
                 $uniqueKey[] = $qty;
             }
             // "unique" key for bundle selection and add it to selections and bundle for selections
             $uniqueKey = implode('_', $uniqueKey);
             foreach ($result as $item) {
                 $item->addCustomOption('bundle_identity', $uniqueKey);
             }
             $product->addCustomOption('bundle_option_ids', serialize(array_map('intval', $optionIds)));
             $product->addCustomOption('bundle_selection_ids', serialize($selectionIds));
             return $result;
         }
     } catch (\Magento\Framework\Exception\LocalizedException $e) {
         return $e->getMessage();
     }
     return $this->getSpecifyOptionMessage();
 }
Example #2
0
 /**
  * Prepare product and its configuration to be added to some products list.
  * Perform standard preparation process and then add Configurable specific options.
  *
  * @param \Magento\Framework\Object $buyRequest
  * @param \Magento\Catalog\Model\Product $product
  * @param string $processMode
  * @return \Magento\Framework\Phrase|array|string
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.NPathComplexity)
  */
 protected function _prepareProduct(\Magento\Framework\Object $buyRequest, $product, $processMode)
 {
     $attributes = $buyRequest->getSuperAttribute();
     if ($attributes || !$this->_isStrictProcessMode($processMode)) {
         if (!$this->_isStrictProcessMode($processMode)) {
             if (is_array($attributes)) {
                 foreach ($attributes as $key => $val) {
                     if (empty($val)) {
                         unset($attributes[$key]);
                     }
                 }
             } else {
                 $attributes = [];
             }
         }
         $result = parent::_prepareProduct($buyRequest, $product, $processMode);
         if (is_array($result)) {
             /**
              * $attributes = array($attributeId=>$attributeValue)
              */
             $subProduct = true;
             if ($this->_isStrictProcessMode($processMode)) {
                 foreach ($this->getConfigurableAttributes($product) as $attributeItem) {
                     /* @var $attributeItem \Magento\Framework\Object */
                     $attrId = $attributeItem->getData('attribute_id');
                     if (!isset($attributes[$attrId]) || empty($attributes[$attrId])) {
                         $subProduct = null;
                         break;
                     }
                 }
             }
             if ($subProduct) {
                 $subProduct = $this->getProductByAttributes($attributes, $product);
             }
             if ($subProduct) {
                 $product->addCustomOption('attributes', serialize($attributes));
                 $product->addCustomOption('product_qty_' . $subProduct->getId(), 1, $subProduct);
                 $product->addCustomOption('simple_product', $subProduct->getId(), $subProduct);
                 $_result = $subProduct->getTypeInstance()->processConfiguration($buyRequest, $subProduct, $processMode);
                 if (is_string($_result) && !is_array($_result)) {
                     return $_result;
                 }
                 if (!isset($_result[0])) {
                     return __('You can\'t add the item to shopping cart.')->render();
                 }
                 /**
                  * Adding parent product custom options to child product
                  * to be sure that it will be unique as its parent
                  */
                 if ($optionIds = $product->getCustomOption('option_ids')) {
                     $optionIds = explode(',', $optionIds->getValue());
                     foreach ($optionIds as $optionId) {
                         if ($option = $product->getCustomOption('option_' . $optionId)) {
                             $_result[0]->addCustomOption('option_' . $optionId, $option->getValue());
                         }
                     }
                 }
                 $_result[0]->setParentProductId($product->getId())->addCustomOption('parent_product_id', $product->getId());
                 if ($this->_isStrictProcessMode($processMode)) {
                     $_result[0]->setCartQty(1);
                 }
                 $result[] = $_result[0];
                 return $result;
             } else {
                 if (!$this->_isStrictProcessMode($processMode)) {
                     return $result;
                 }
             }
         }
     }
     return $this->getSpecifyOptionMessage()->render();
 }
Example #3
0
 /**
  * Prepare product and its configuration to be added to some products list.
  * Perform standard preparation process and then prepare of bundle selections options.
  *
  * @param \Magento\Framework\Object $buyRequest
  * @param \Magento\Catalog\Model\Product $product
  * @param string $processMode
  * @return array|string
  */
 protected function _prepareProduct(\Magento\Framework\Object $buyRequest, $product, $processMode)
 {
     $result = parent::_prepareProduct($buyRequest, $product, $processMode);
     if (is_string($result)) {
         return $result;
     }
     $selections = array();
     $isStrictProcessMode = $this->_isStrictProcessMode($processMode);
     $skipSaleableCheck = $this->_catalogProduct->getSkipSaleableCheck();
     $_appendAllSelections = (bool) $product->getSkipCheckRequiredOption() || $skipSaleableCheck;
     $options = $buyRequest->getBundleOption();
     if (is_array($options)) {
         $options = array_filter($options, 'intval');
         $qtys = $buyRequest->getBundleOptionQty();
         foreach ($options as $_optionId => $_selections) {
             if (empty($_selections)) {
                 unset($options[$_optionId]);
             }
         }
         $optionIds = array_keys($options);
         if (empty($optionIds) && $isStrictProcessMode) {
             return __('Please specify product option(s).');
         }
         $product->getTypeInstance()->setStoreFilter($product->getStoreId(), $product);
         $optionsCollection = $this->getOptionsCollection($product);
         if (!$product->getSkipCheckRequiredOption() && $isStrictProcessMode) {
             foreach ($optionsCollection->getItems() as $option) {
                 if ($option->getRequired() && !isset($options[$option->getId()])) {
                     return __('Please select all required options.');
                 }
             }
         }
         $selectionIds = array();
         foreach ($options as $selectionId) {
             if (!is_array($selectionId)) {
                 if ($selectionId != '') {
                     $selectionIds[] = (int) $selectionId;
                 }
             } else {
                 foreach ($selectionId as $id) {
                     if ($id != '') {
                         $selectionIds[] = (int) $id;
                     }
                 }
             }
         }
         // If product has not been configured yet then $selections array should be empty
         if (!empty($selectionIds)) {
             $selections = $this->getSelectionsByIds($selectionIds, $product);
             // Check if added selections are still on sale
             foreach ($selections->getItems() as $selection) {
                 if (!$selection->isSalable() && !$skipSaleableCheck) {
                     $_option = $optionsCollection->getItemById($selection->getOptionId());
                     if (is_array($options[$_option->getId()]) && count($options[$_option->getId()]) > 1) {
                         $moreSelections = true;
                     } else {
                         $moreSelections = false;
                     }
                     if ($_option->getRequired() && (!$_option->isMultiSelection() || $_option->isMultiSelection() && !$moreSelections)) {
                         return __('The required options you selected are not available.');
                     }
                 }
             }
             $optionsCollection->appendSelections($selections, false, $_appendAllSelections);
             $selections = $selections->getItems();
         } else {
             $selections = array();
         }
     } else {
         $product->setOptionsValidationFail(true);
         $product->getTypeInstance()->setStoreFilter($product->getStoreId(), $product);
         $optionCollection = $product->getTypeInstance()->getOptionsCollection($product);
         $optionIds = $product->getTypeInstance()->getOptionsIds($product);
         $selectionCollection = $product->getTypeInstance()->getSelectionsCollection($optionIds, $product);
         $options = $optionCollection->appendSelections($selectionCollection, false, $_appendAllSelections);
         foreach ($options as $option) {
             if ($option->getRequired() && count($option->getSelections()) == 1) {
                 $selections = array_merge($selections, $option->getSelections());
             } else {
                 $selections = array();
                 break;
             }
         }
     }
     if (count($selections) > 0 || !$isStrictProcessMode) {
         $uniqueKey = array($product->getId());
         $selectionIds = array();
         // Shuffle selection array by option position
         usort($selections, array($this, 'shakeSelections'));
         foreach ($selections as $selection) {
             if ($selection->getSelectionCanChangeQty() && isset($qtys[$selection->getOptionId()])) {
                 $qty = (double) $qtys[$selection->getOptionId()] > 0 ? $qtys[$selection->getOptionId()] : 1;
             } else {
                 $qty = (double) $selection->getSelectionQty() ? $selection->getSelectionQty() : 1;
             }
             $qty = (double) $qty;
             $product->addCustomOption('selection_qty_' . $selection->getSelectionId(), $qty, $selection);
             $selection->addCustomOption('selection_id', $selection->getSelectionId());
             $beforeQty = 0;
             $customOption = $product->getCustomOption('product_qty_' . $selection->getId());
             if ($customOption && $customOption->getProduct()->getId() == $selection->getId()) {
                 $beforeQty = (double) $customOption->getValue();
             }
             $product->addCustomOption('product_qty_' . $selection->getId(), $qty + $beforeQty, $selection);
             /*
              * Create extra attributes that will be converted to product options in order item
              * for selection (not for all bundle)
              */
             $price = $product->getPriceModel()->getSelectionFinalTotalPrice($product, $selection, 0, $qty);
             $attributes = array('price' => $this->priceCurrency->convert($price), 'qty' => $qty, 'option_label' => $selection->getOption()->getTitle(), 'option_id' => $selection->getOption()->getId());
             $_result = $selection->getTypeInstance()->prepareForCart($buyRequest, $selection);
             if (is_string($_result) && !is_array($_result)) {
                 return $_result;
             }
             if (!isset($_result[0])) {
                 return __('We cannot add this item to your shopping cart.');
             }
             $result[] = $_result[0]->setParentProductId($product->getId())->addCustomOption('bundle_option_ids', serialize(array_map('intval', $optionIds)))->addCustomOption('bundle_selection_attributes', serialize($attributes));
             if ($isStrictProcessMode) {
                 $_result[0]->setCartQty($qty);
             }
             $selectionIds[] = $_result[0]->getSelectionId();
             $uniqueKey[] = $_result[0]->getSelectionId();
             $uniqueKey[] = $qty;
         }
         // "unique" key for bundle selection and add it to selections and bundle for selections
         $uniqueKey = implode('_', $uniqueKey);
         foreach ($result as $item) {
             $item->addCustomOption('bundle_identity', $uniqueKey);
         }
         $product->addCustomOption('bundle_option_ids', serialize(array_map('intval', $optionIds)));
         $product->addCustomOption('bundle_selection_ids', serialize($selectionIds));
         return $result;
     }
     return $this->getSpecifyOptionMessage();
 }