Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Public Member Functions | Data Fields | Protected Member Functions | Protected Attributes
Type Class Reference
Inheritance diagram for Type:
AbstractType

Public Member Functions

 __construct (\Magento\Catalog\Model\Product\Option $catalogProductOption, \Magento\Eav\Model\Config $eavConfig, \Magento\Catalog\Model\Product\Type $catalogProductType, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb, \Magento\Framework\Filesystem $filesystem, \Magento\Framework\Registry $coreRegistry, \Psr\Log\LoggerInterface $logger, ProductRepositoryInterface $productRepository, \Magento\Catalog\Helper\Product $catalogProduct, \Magento\Catalog\Helper\Data $catalogData, \Magento\Bundle\Model\SelectionFactory $bundleModelSelection, \Magento\Bundle\Model\ResourceModel\BundleFactory $bundleFactory, \Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory $bundleCollection, \Magento\Catalog\Model\Config $config, \Magento\Bundle\Model\ResourceModel\Selection $bundleSelection, \Magento\Bundle\Model\OptionFactory $bundleOption, \Magento\Store\Model\StoreManagerInterface $storeManager, PriceCurrencyInterface $priceCurrency, \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry, \Magento\CatalogInventory\Api\StockStateInterface $stockState, Json $serializer=null, MetadataPool $metadataPool=null, SelectionCollectionFilterApplier $selectionCollectionFilterApplier=null)
 
 getRelationInfo ()
 
 getChildrenIds ($parentId, $required=true)
 
 getParentIdsByChild ($childId)
 
 getSku ($product)
 
 getWeight ($product)
 
 isVirtual ($product)
 
 beforeSave ($product)
 
 getOptions ($product)
 
 getOptionsIds ($product)
 
 updateQtyOption ($options, \Magento\Framework\DataObject $option, $value, $product)
 
 prepareQuoteItemQty ($qty, $product)
 
 isSalable ($product)
 
 getSpecifyOptionMessage ()
 
 getOptionsByIds ($optionIds, $product)
 
 getOrderOptions ($product)
 
 shakeSelections ($firstItem, $secondItem)
 
 hasOptions ($product)
 
 getForceChildItemQtyChanges ($product)
 
 getSearchableData ($product)
 
 checkProductBuyState ($product)
 
 getProductsToPurchaseByReqGroups ($product)
 
 processBuyRequest ($product, $buyRequest)
 
 canConfigure ($product)
 
 deleteTypeSpecificData (\Magento\Catalog\Model\Product $product)
 
- Public Member Functions inherited from AbstractType
 deleteTypeSpecificData (\Magento\Catalog\Model\Product $product)
 
 __construct (\Magento\Catalog\Model\Product\Option $catalogProductOption, \Magento\Eav\Model\Config $eavConfig, \Magento\Catalog\Model\Product\Type $catalogProductType, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb, \Magento\Framework\Filesystem $filesystem, \Magento\Framework\Registry $coreRegistry, \Psr\Log\LoggerInterface $logger, ProductRepositoryInterface $productRepository, \Magento\Framework\Serialize\Serializer\Json $serializer=null)
 
 setTypeId ($typeId)
 
 getRelationInfo ()
 
 getChildrenIds ($parentId, $required=true)
 
 getParentIdsByChild ($childId)
 
 getSetAttributes ($product)
 
 attributesCompare ($attributeOne, $attributeTwo)
 
 getEditableAttributes ($product)
 
 getAttributeById ($attributeId, $product)
 
 isVirtual ($product)
 
 isSalable ($product)
 
 processConfiguration (\Magento\Framework\DataObject $buyRequest, $product, $processMode=self::PROCESS_MODE_LITE)
 
 prepareForCartAdvanced (\Magento\Framework\DataObject $buyRequest, $product, $processMode=null)
 
 prepareForCart (\Magento\Framework\DataObject $buyRequest, $product)
 
 addFileQueue ($queueOptions)
 
 getSpecifyOptionMessage ()
 
 checkProductBuyState ($product)
 
 getOrderOptions ($product)
 
 save ($product)
 
 beforeSave ($product)
 
 isComposite ($product)
 
 canConfigure ($product)
 
 canUseQtyDecimals ()
 
 getSku ($product)
 
 getOptionSku ($product, $sku='')
 
 getWeight ($product)
 
 hasOptions ($product)
 
 updateQtyOption ($options, \Magento\Framework\DataObject $option, $value, $product)
 
 hasRequiredOptions ($product)
 
 getStoreFilter ($product)
 
 setStoreFilter ($store, $product)
 
 getForceChildItemQtyChanges ($product)
 
 prepareQuoteItemQty ($qty, $product)
 
 assignProductToOption ($optionProduct, $option, $product)
 
 setConfig ($config)
 
 getSearchableData ($product)
 
 getProductsToPurchaseByReqGroups ($product)
 
 processBuyRequest ($product, $buyRequest)
 
 checkProductConfiguration ($product, $buyRequest)
 
 hasWeight ()
 
 setImageFromChildProduct (\Magento\Catalog\Model\Product $product)
 
 getIdentities (\Magento\Catalog\Model\Product $product)
 
 getAssociatedProducts ($product)
 
 isPossibleBuyFromList ($product)
 

Data Fields

const TYPE_CODE = 'bundle'
 
- Data Fields inherited from AbstractType
const CALCULATE_CHILD = 0
 
const CALCULATE_PARENT = 1
 
const SHIPMENT_SEPARATELY = 1
 
const SHIPMENT_TOGETHER = 0
 
const PROCESS_MODE_FULL = 'full'
 
const PROCESS_MODE_LITE = 'lite'
 
const OPTION_PREFIX = 'option_'
 

Protected Member Functions

 _prepareProduct (\Magento\Framework\DataObject $buyRequest, $product, $processMode)
 
 getQty ($selection, $qtys, $selectionOptionId)
 
 getBeforeQty ($product, $selection)
 
 checkIsAllRequiredOptions ($product, $isStrictProcessMode, $optionsCollection, $options)
 
 checkSelectionsIsSale ($selections, $skipSaleableCheck, $optionsCollection, $options)
 
 checkIsResult ($_result)
 
 mergeSelectionsWithOptions ($options, $selections)
 
- Protected Member Functions inherited from AbstractType
 _isStrictProcessMode ($processMode)
 
 _prepareOptions (\Magento\Framework\DataObject $buyRequest, $product, $processMode)
 
 _removeNotApplicableAttributes ($product)
 

Protected Attributes

 $_isComposite = true
 
 $_keyOptionsCollection = '_cache_instance_options_collection'
 
 $_keySelectionsCollection = '_cache_instance_selections_collection'
 
 $_keyUsedSelections = '_cache_instance_used_selections'
 
 $_keyUsedSelectionsIds = '_cache_instance_used_selections_ids'
 
 $_keyUsedOptions = '_cache_instance_used_options'
 
 $_keyUsedOptionsIds = '_cache_instance_used_options_ids'
 
 $_canConfigure = true
 
 $_catalogData = null
 
 $_catalogProduct = null
 
 $_storeManager
 
 $_bundleOption
 
 $_bundleSelection
 
 $_config
 
 $_bundleCollection
 
 $_bundleFactory
 
 $_bundleModelSelection
 
 $priceCurrency
 
 $_stockRegistry
 
 $_stockState
 
- Protected Attributes inherited from AbstractType
 $_typeId
 
 $_editableAttributes
 
 $_isComposite = false
 
 $_canConfigure = false
 
 $_canUseQtyDecimals = true
 
 $_fileQueue = []
 
 $_filesystem
 
 $_fileStorageDb
 
 $_cacheProductSetAttributes = '_cache_instance_product_set_attributes'
 
 $_coreRegistry
 
 $_eventManager
 
 $_logger
 
 $_catalogProductType
 
 $_eavConfig
 
 $_catalogProductOption
 
 $productRepository
 
 $serializer
 

Detailed Description

Bundle Type Model @SuppressWarnings(PHPMD.TooManyFields) @SuppressWarnings(PHPMD.ExcessiveClassComplexity) @SuppressWarnings(PHPMD.CouplingBetweenObjects) @api

Since
100.0.2

Definition at line 25 of file Type.php.

Constructor & Destructor Documentation

◆ __construct()

__construct ( \Magento\Catalog\Model\Product\Option  $catalogProductOption,
\Magento\Eav\Model\Config  $eavConfig,
\Magento\Catalog\Model\Product\Type  $catalogProductType,
\Magento\Framework\Event\ManagerInterface  $eventManager,
\Magento\MediaStorage\Helper\File\Storage\Database  $fileStorageDb,
\Magento\Framework\Filesystem  $filesystem,
\Magento\Framework\Registry  $coreRegistry,
\Psr\Log\LoggerInterface  $logger,
ProductRepositoryInterface  $productRepository,
\Magento\Catalog\Helper\Product  $catalogProduct,
\Magento\Catalog\Helper\Data  $catalogData,
\Magento\Bundle\Model\SelectionFactory  $bundleModelSelection,
\Magento\Bundle\Model\ResourceModel\BundleFactory  $bundleFactory,
\Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory  $bundleCollection,
\Magento\Catalog\Model\Config  $config,
\Magento\Bundle\Model\ResourceModel\Selection  $bundleSelection,
\Magento\Bundle\Model\OptionFactory  $bundleOption,
\Magento\Store\Model\StoreManagerInterface  $storeManager,
PriceCurrencyInterface  $priceCurrency,
\Magento\CatalogInventory\Api\StockRegistryInterface  $stockRegistry,
\Magento\CatalogInventory\Api\StockStateInterface  $stockState,
Json  $serializer = null,
MetadataPool  $metadataPool = null,
SelectionCollectionFilterApplier  $selectionCollectionFilterApplier = null 
)
Parameters
\Magento\Catalog\Model\Product\Option$catalogProductOption
\Magento\Eav\Model\Config$eavConfig
\Magento\Catalog\Model\Product\Type$catalogProductType
\Magento\Framework\Event\ManagerInterface$eventManager
\Magento\MediaStorage\Helper\File\Storage\Database$fileStorageDb
\Magento\Framework\Filesystem$filesystem
\Magento\Framework\Registry$coreRegistry
\Psr\Log\LoggerInterface$logger
ProductRepositoryInterface$productRepository
\Magento\Catalog\Helper\Product$catalogProduct
\Magento\Catalog\Helper\Data$catalogData
\Magento\Bundle\Model\SelectionFactory$bundleModelSelection
\Magento\Bundle\Model\ResourceModel\BundleFactory$bundleFactory
\Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory$bundleCollection
\Magento\Catalog\Model\Config$config
\Magento\Bundle\Model\ResourceModel\Selection$bundleSelection
\Magento\Bundle\Model\OptionFactory$bundleOption
\Magento\Store\Model\StoreManagerInterface$storeManager
PriceCurrencyInterface$priceCurrency
\Magento\CatalogInventory\Api\StockRegistryInterface$stockRegistry
\Magento\CatalogInventory\Api\StockStateInterface$stockState
\Magento\Framework\Serialize\Serializer\Json$serializer
MetadataPool | null$metadataPool
SelectionCollectionFilterApplier | null$selectionCollectionFilterApplier@SuppressWarnings(PHPMD.ExcessiveParameterList)

Definition at line 191 of file Type.php.

216  {
217  $this->_catalogProduct = $catalogProduct;
218  $this->_catalogData = $catalogData;
219  $this->_storeManager = $storeManager;
220  $this->_bundleOption = $bundleOption;
221  $this->_bundleSelection = $bundleSelection;
222  $this->_config = $config;
223  $this->_bundleCollection = $bundleCollection;
224  $this->_bundleFactory = $bundleFactory;
225  $this->_bundleModelSelection = $bundleModelSelection;
226  $this->priceCurrency = $priceCurrency;
227  $this->_stockRegistry = $stockRegistry;
228  $this->_stockState = $stockState;
229 
230  $this->metadataPool = $metadataPool
231  ?: ObjectManager::getInstance()->get(MetadataPool::class);
232 
233  $this->selectionCollectionFilterApplier = $selectionCollectionFilterApplier
234  ?: ObjectManager::getInstance()->get(SelectionCollectionFilterApplier::class);
235 
236  parent::__construct(
237  $catalogProductOption,
238  $eavConfig,
239  $catalogProductType,
240  $eventManager,
241  $fileStorageDb,
242  $filesystem,
243  $coreRegistry,
244  $logger,
247  );
248  }
$config
Definition: fraud_order.php:17
$storeManager
$logger
$filesystem

Member Function Documentation

◆ _prepareProduct()

_prepareProduct ( \Magento\Framework\DataObject  $buyRequest,
  $product,
  $processMode 
)
protected

Prepare product and its configuration to be added to some products list. Perform standard preparation process and then prepare of bundle selections options.

Parameters
\Magento\Framework\DataObject$buyRequest
\Magento\Catalog\Model\Product$product
string$processMode
Returns
\Magento\Framework\Phrase|array|string @SuppressWarnings(PHPMD.CyclomaticComplexity) @SuppressWarnings(PHPMD.NPathComplexity) @SuppressWarnings(PHPMD.ExcessiveMethodLength)

Definition at line 638 of file Type.php.

639  {
640  $result = parent::_prepareProduct($buyRequest, $product, $processMode);
641 
642  try {
643  if (is_string($result)) {
644  throw new \Magento\Framework\Exception\LocalizedException(__($result));
645  }
646 
647  $selections = [];
648  $isStrictProcessMode = $this->_isStrictProcessMode($processMode);
649 
650  $skipSaleableCheck = $this->_catalogProduct->getSkipSaleableCheck();
651  $_appendAllSelections = (bool)$product->getSkipCheckRequiredOption() || $skipSaleableCheck;
652 
653  $options = $buyRequest->getBundleOption();
654  if (is_array($options)) {
655  $options = $this->recursiveIntval($options);
656  $optionIds = array_keys($options);
657 
658  if (empty($optionIds) && $isStrictProcessMode) {
659  throw new \Magento\Framework\Exception\LocalizedException(__('Please specify product option(s).'));
660  }
661 
662  $product->getTypeInstance()
663  ->setStoreFilter($product->getStoreId(), $product);
664  $optionsCollection = $this->getOptionsCollection($product);
666  $product,
667  $isStrictProcessMode,
668  $optionsCollection,
669  $options
670  );
671 
672  $selectionIds = $this->multiToFlatArray($options);
673  // If product has not been configured yet then $selections array should be empty
674  if (!empty($selectionIds)) {
675  $selections = $this->getSelectionsByIds($selectionIds, $product);
676 
677  if (count($selections->getItems()) !== count($selectionIds)) {
678  throw new \Magento\Framework\Exception\LocalizedException(
679  __('The options you selected are not available.')
680  );
681  }
682 
683  // Check if added selections are still on sale
684  $this->checkSelectionsIsSale(
685  $selections,
686  $skipSaleableCheck,
687  $optionsCollection,
688  $options
689  );
690 
691  $optionsCollection->appendSelections($selections, true, $_appendAllSelections);
692 
693  $selections = $selections->getItems();
694  } else {
695  $selections = [];
696  }
697  } else {
698  $product->setOptionsValidationFail(true);
699  $product->getTypeInstance()
700  ->setStoreFilter($product->getStoreId(), $product);
701 
702  $optionCollection = $product->getTypeInstance()
703  ->getOptionsCollection($product);
704  $optionIds = $product->getTypeInstance()
705  ->getOptionsIds($product);
706  $selectionCollection = $product->getTypeInstance()
707  ->getSelectionsCollection($optionIds, $product);
708  $options = $optionCollection->appendSelections($selectionCollection, true, $_appendAllSelections);
709 
710  $selections = $this->mergeSelectionsWithOptions($options, $selections);
711  }
712  if ((is_array($selections) && count($selections) > 0) || !$isStrictProcessMode) {
713  $uniqueKey = [$product->getId()];
714  $selectionIds = [];
715  $qtys = $buyRequest->getBundleOptionQty();
716 
717  // Shuffle selection array by option position
718  usort($selections, [$this, 'shakeSelections']);
719 
720  foreach ($selections as $selection) {
721  $selectionOptionId = $selection->getOptionId();
722  $qty = $this->getQty($selection, $qtys, $selectionOptionId);
723 
724  $selectionId = $selection->getSelectionId();
725  $product->addCustomOption('selection_qty_' . $selectionId, $qty, $selection);
726  $selection->addCustomOption('selection_id', $selectionId);
727 
728  $beforeQty = $this->getBeforeQty($product, $selection);
729  $product->addCustomOption('product_qty_' . $selection->getId(), $qty + $beforeQty, $selection);
730 
731  /*
732  * Create extra attributes that will be converted to product options in order item
733  * for selection (not for all bundle)
734  */
735  $price = $product->getPriceModel()
736  ->getSelectionFinalTotalPrice($product, $selection, 0, $qty);
737  $attributes = [
738  'price' => $this->priceCurrency->convert($price),
739  'qty' => $qty,
740  'option_label' => $selection->getOption()
741  ->getTitle(),
742  'option_id' => $selection->getOption()
743  ->getId(),
744  ];
745 
746  $_result = $selection->getTypeInstance()
747  ->prepareForCart($buyRequest, $selection);
748  $this->checkIsResult($_result);
749 
750  $result[] = $_result[0]->setParentProductId($product->getId())
751  ->addCustomOption(
752  'bundle_option_ids',
753  $this->serializer->serialize(array_map('intval', $optionIds))
754  )
755  ->addCustomOption(
756  'bundle_selection_attributes',
757  $this->serializer->serialize($attributes)
758  );
759 
760  if ($isStrictProcessMode) {
761  $_result[0]->setCartQty($qty);
762  }
763 
764  $resultSelectionId = $_result[0]->getSelectionId();
765  $selectionIds[] = $resultSelectionId;
766  $uniqueKey[] = $resultSelectionId;
767  $uniqueKey[] = $qty;
768  }
769 
770  // "unique" key for bundle selection and add it to selections and bundle for selections
771  $uniqueKey = implode('_', $uniqueKey);
772  foreach ($result as $item) {
773  $item->addCustomOption('bundle_identity', $uniqueKey);
774  }
775  $product->addCustomOption(
776  'bundle_option_ids',
777  $this->serializer->serialize(
778  array_map('intval', $optionIds)
779  )
780  );
781  $product->addCustomOption('bundle_selection_ids', $this->serializer->serialize($selectionIds));
782 
783  return $result;
784  }
785  } catch (\Magento\Framework\Exception\LocalizedException $e) {
786  return $e->getMessage();
787  }
788 
789  return $this->getSpecifyOptionMessage();
790  }
checkIsAllRequiredOptions($product, $isStrictProcessMode, $optionsCollection, $options)
Definition: Type.php:1259
checkSelectionsIsSale($selections, $skipSaleableCheck, $optionsCollection, $options)
Definition: Type.php:1280
addCustomOption($code, $value, $product=null)
Definition: Product.php:2040
__()
Definition: __.php:13
$price
getBeforeQty($product, $selection)
Definition: Type.php:1239
mergeSelectionsWithOptions($options, $selections)
Definition: Type.php:1325
foreach($product->getExtensionAttributes() ->getBundleProductOptions() as $option) $buyRequest
$attributes
Definition: matrix.phtml:13
$selectionCollection
getQty($selection, $qtys, $selectionOptionId)
Definition: Type.php:1222

◆ beforeSave()

beforeSave (   $product)

Before save type related data

Parameters
\Magento\Catalog\Model\Product$product
Returns
$this|void @SuppressWarnings(PHPMD.CyclomaticComplexity)

unset product custom options for dynamic price

Definition at line 384 of file Type.php.

385  {
386  parent::beforeSave($product);
387 
388  // If bundle product has dynamic weight, than delete weight attribute
389  if (!$product->getData('weight_type') && $product->hasData('weight')) {
390  $product->setData('weight', false);
391  }
392 
393  if ($product->getPriceType() == Price::PRICE_TYPE_DYNAMIC) {
395  if ($product->hasData('product_options')) {
396  $product->unsetData('product_options');
397  }
398  }
399 
400  $product->canAffectOptions(false);
401 
402  if ($product->getCanSaveBundleSelections()) {
403  $product->canAffectOptions(true);
404  $selections = $product->getBundleSelectionsData();
405  if ($selections && !empty($selections)) {
406  $options = $product->getBundleOptionsData();
407  if ($options) {
408  foreach ($options as $option) {
409  if (empty($option['delete']) || 1 != (int)$option['delete']) {
410  $product->setTypeHasOptions(true);
411  if (1 == (int)$option['required']) {
412  $product->setTypeHasRequiredOptions(true);
413  break;
414  }
415  }
416  }
417  }
418  }
419  }
420  }

◆ canConfigure()

canConfigure (   $product)

Check if product can be configured

Parameters
\Magento\Catalog\Model\Product$product
Returns
bool

Definition at line 1176 of file Type.php.

1177  {
1178  return $product instanceof \Magento\Catalog\Model\Product && $product->isAvailable() && parent::canConfigure(
1179  $product
1180  );
1181  }

◆ checkIsAllRequiredOptions()

checkIsAllRequiredOptions (   $product,
  $isStrictProcessMode,
  $optionsCollection,
  $options 
)
protected
Parameters
\Magento\Catalog\Model\Product$product
bool$isStrictProcessMode
\Magento\Bundle\Model\ResourceModel\Option\Collection$optionsCollection
int[]$options
Returns
void
Exceptions

Definition at line 1259 of file Type.php.

1260  {
1261  if (!$product->getSkipCheckRequiredOption() && $isStrictProcessMode) {
1262  foreach ($optionsCollection->getItems() as $option) {
1263  if ($option->getRequired() && !isset($options[$option->getId()])) {
1264  throw new \Magento\Framework\Exception\LocalizedException(
1265  __('Please select all required options.')
1266  );
1267  }
1268  }
1269  }
1270  }
__()
Definition: __.php:13

◆ checkIsResult()

checkIsResult (   $_result)
protected
Parameters
array$_result
Returns
void
Exceptions

Definition at line 1307 of file Type.php.

1308  {
1309  if (is_string($_result)) {
1310  throw new \Magento\Framework\Exception\LocalizedException(__($_result));
1311  }
1312 
1313  if (!isset($_result[0])) {
1314  throw new \Magento\Framework\Exception\LocalizedException(
1315  __('We can\'t add this item to your shopping cart right now.')
1316  );
1317  }
1318  }
__()
Definition: __.php:13

◆ checkProductBuyState()

checkProductBuyState (   $product)

Check if product can be bought

Parameters
\Magento\Catalog\Model\Product$product
Returns
$this
Exceptions

Definition at line 1081 of file Type.php.

1082  {
1083  parent::checkProductBuyState($product);
1084  $productOptionIds = $this->getOptionsIds($product);
1085  $productSelections = $this->getSelectionsCollection($productOptionIds, $product);
1086  $selectionIds = $product->getCustomOption('bundle_selection_ids');
1087  $selectionIds = $this->serializer->unserialize($selectionIds->getValue());
1088  $buyRequest = $product->getCustomOption('info_buyRequest');
1089  $buyRequest = new \Magento\Framework\DataObject($this->serializer->unserialize($buyRequest->getValue()));
1090  $bundleOption = $buyRequest->getBundleOption();
1091 
1092  if (empty($bundleOption)) {
1093  throw new \Magento\Framework\Exception\LocalizedException($this->getSpecifyOptionMessage());
1094  }
1095 
1096  $skipSaleableCheck = $this->_catalogProduct->getSkipSaleableCheck();
1097  foreach ($selectionIds as $selectionId) {
1098  /* @var $selection \Magento\Bundle\Model\Selection */
1099  $selection = $productSelections->getItemById($selectionId);
1100  if (!$selection || !$selection->isSalable() && !$skipSaleableCheck) {
1101  throw new \Magento\Framework\Exception\LocalizedException(
1102  __('The required options you selected are not available.')
1103  );
1104  }
1105  }
1106 
1107  $product->getTypeInstance()
1108  ->setStoreFilter($product->getStoreId(), $product);
1109  $optionsCollection = $this->getOptionsCollection($product);
1110  foreach ($optionsCollection->getItems() as $option) {
1111  if ($option->getRequired() && empty($bundleOption[$option->getId()])) {
1112  throw new \Magento\Framework\Exception\LocalizedException(__('Please select all required options.'));
1113  }
1114  }
1115 
1116  return $this;
1117  }
__()
Definition: __.php:13
foreach($product->getExtensionAttributes() ->getBundleProductOptions() as $option) $buyRequest

◆ checkSelectionsIsSale()

checkSelectionsIsSale (   $selections,
  $skipSaleableCheck,
  $optionsCollection,
  $options 
)
protected
Parameters
\Magento\Bundle\Model\ResourceModel\Selection\Collection$selections
bool$skipSaleableCheck
\Magento\Bundle\Model\ResourceModel\Option\Collection$optionsCollection
int[]$options
Returns
void
Exceptions

Definition at line 1280 of file Type.php.

1281  {
1282  foreach ($selections->getItems() as $selection) {
1283  if (!$selection->isSalable() && !$skipSaleableCheck) {
1284  $_option = $optionsCollection->getItemById($selection->getOptionId());
1285  $optionId = $_option->getId();
1286  if (is_array($options[$optionId]) && count($options[$optionId]) > 1) {
1287  $moreSelections = true;
1288  } else {
1289  $moreSelections = false;
1290  }
1291  $isMultiSelection = $_option->isMultiSelection();
1292  if ($_option->getRequired() && (!$isMultiSelection || !$moreSelections)
1293  ) {
1294  throw new \Magento\Framework\Exception\LocalizedException(
1295  __('The required options you selected are not available.')
1296  );
1297  }
1298  }
1299  }
1300  }
$_option
Definition: checkbox.phtml:11
__()
Definition: __.php:13

◆ deleteTypeSpecificData()

deleteTypeSpecificData ( \Magento\Catalog\Model\Product  $product)

Delete data specific for Bundle product type

Parameters
\Magento\Catalog\Model\Product$product
Returns
void @SuppressWarnings(PHPMD.UnusedFormalParameter)

Definition at line 1190 of file Type.php.

1191  {
1192  }

◆ getBeforeQty()

getBeforeQty (   $product,
  $selection 
)
protected
Parameters
\Magento\Catalog\Model\Product$product
\Magento\Framework\DataObject$selection
Returns
float|int

Definition at line 1239 of file Type.php.

1240  {
1241  $beforeQty = 0;
1242  $customOption = $product->getCustomOption('product_qty_' . $selection->getId());
1243  if ($customOption && $customOption->getProduct()->getId() == $selection->getId()) {
1244  $beforeQty = (float)$customOption->getValue();
1245  return $beforeQty;
1246  }
1247 
1248  return $beforeQty;
1249  }
$customOption
Definition: products.php:73

◆ getChildrenIds()

getChildrenIds (   $parentId,
  $required = true 
)

Retrieve Required children ids Return grouped array, ex array( group => array(ids) )

Parameters
int$parentId
bool$required
Returns
array

Definition at line 275 of file Type.php.

276  {
277  return $this->_bundleSelection->getChildrenIds($parentId, $required);
278  }
$required
Definition: wrapper.phtml:8

◆ getForceChildItemQtyChanges()

getForceChildItemQtyChanges (   $product)

Allow for updates of children qty's

Parameters
\Magento\Catalog\Model\Product$product
Returns
boolean true @SuppressWarnings(PHPMD.BooleanGetMethodName) @SuppressWarnings(PHPMD.UnusedFormalParameter)

Definition at line 1046 of file Type.php.

1047  {
1048  return true;
1049  }

◆ getOptions()

getOptions (   $product)

Retrieve bundle options items

Parameters
\Magento\Catalog\Model\Product$product
Returns
\Magento\Framework\DataObject[]

Definition at line 428 of file Type.php.

429  {
430  return $this->getOptionsCollection($product)
431  ->getItems();
432  }

◆ getOptionsByIds()

getOptionsByIds (   $optionIds,
  $product 
)

Retrieve bundle options collection based on ids

Parameters
array$optionIds
\Magento\Catalog\Model\Product$product
Returns
\Magento\Bundle\Model\ResourceModel\Option\Collection

Definition at line 895 of file Type.php.

896  {
897  sort($optionIds);
898 
899  $usedOptions = $product->getData($this->_keyUsedOptions);
900  $usedOptionsIds = $product->getData($this->_keyUsedOptionsIds);
901 
902  if (!$usedOptions
903  || $this->serializer->serialize($usedOptionsIds) != $this->serializer->serialize($optionIds)
904  ) {
905  $usedOptions = $this->_bundleOption
906  ->create()
907  ->getResourceCollection()
908  ->setProductIdFilter($product->getId())
909  ->setPositionOrder()
910  ->joinValues(
911  $this->_storeManager->getStore()
912  ->getId()
913  )
914  ->setIdFilter($optionIds);
915  $product->setData($this->_keyUsedOptions, $usedOptions);
916  $product->setData($this->_keyUsedOptionsIds, $optionIds);
917  }
918 
919  return $usedOptions;
920  }

◆ getOptionsIds()

getOptionsIds (   $product)

Retrieve bundle options ids

Parameters
\Magento\Catalog\Model\Product$product
Returns
array

Definition at line 440 of file Type.php.

441  {
442  return $this->getOptionsCollection($product)
443  ->getAllIds();
444  }

◆ getOrderOptions()

getOrderOptions (   $product)

Prepare additional options/information for order item which will be created from this product

Parameters
\Magento\Catalog\Model\Product$product
Returns
array

Product Prices calculations save

Definition at line 929 of file Type.php.

930  {
931  $optionArr = parent::getOrderOptions($product);
932  $bundleOptions = [];
933 
934  if ($product->hasCustomOptions()) {
935  $customOption = $product->getCustomOption('bundle_option_ids');
936  $optionIds = $this->serializer->unserialize($customOption->getValue());
938  $customOption = $product->getCustomOption('bundle_selection_ids');
939  $selectionIds = $this->serializer->unserialize($customOption->getValue());
940  $selections = $this->getSelectionsByIds($selectionIds, $product);
941  foreach ($selections->getItems() as $selection) {
942  if ($selection->isSalable()) {
943  $selectionQty = $product->getCustomOption('selection_qty_' . $selection->getSelectionId());
944  if ($selectionQty) {
945  $price = $product->getPriceModel()
946  ->getSelectionFinalTotalPrice(
947  $product,
948  $selection,
949  0,
950  $selectionQty->getValue()
951  );
952 
953  $option = $options->getItemById($selection->getOptionId());
954  if (!isset($bundleOptions[$option->getId()])) {
955  $bundleOptions[$option->getId()] = [
956  'option_id' => $option->getId(),
957  'label' => $option->getTitle(),
958  'value' => [],
959  ];
960  }
961 
962  $bundleOptions[$option->getId()]['value'][] = [
963  'title' => $selection->getName(),
964  'qty' => $selectionQty->getValue(),
965  'price' => $this->priceCurrency->convert($price),
966  ];
967  }
968  }
969  }
970  }
971 
972  $optionArr['bundle_options'] = $bundleOptions;
973 
977  if ($product->getPriceType()) {
978  $optionArr['product_calculations'] = self::CALCULATE_PARENT;
979  } else {
980  $optionArr['product_calculations'] = self::CALCULATE_CHILD;
981  }
982 
983  $optionArr['shipment_type'] = $product->getShipmentType();
984 
985  return $optionArr;
986  }
$customOption
Definition: products.php:73
$price
getOptionsByIds($optionIds, $product)
Definition: Type.php:895

◆ getParentIdsByChild()

getParentIdsByChild (   $childId)

Retrieve parent ids array by required child

Parameters
int | array$childId
Returns
array

Definition at line 286 of file Type.php.

287  {
288  return $this->_bundleSelection->getParentIdsByChild($childId);
289  }

◆ getProductsToPurchaseByReqGroups()

getProductsToPurchaseByReqGroups (   $product)

Retrieve products divided into groups required to purchase At least one product in each group has to be purchased

Parameters
\Magento\Catalog\Model\Product$product
Returns
array

Definition at line 1126 of file Type.php.

1127  {
1128  $groups = [];
1129  $allProducts = [];
1130  $hasRequiredOptions = false;
1131  foreach ($this->getOptions($product) as $option) {
1132  $groupProducts = [];
1133  foreach ($this->getSelectionsCollection([$option->getId()], $product) as $childProduct) {
1134  $groupProducts[] = $childProduct;
1135  $allProducts[] = $childProduct;
1136  }
1137  if ($option->getRequired()) {
1138  $groups[] = $groupProducts;
1139  $hasRequiredOptions = true;
1140  }
1141  }
1142  if (!$hasRequiredOptions) {
1143  $groups = [$allProducts];
1144  }
1145 
1146  return $groups;
1147  }

◆ getQty()

getQty (   $selection,
  $qtys,
  $selectionOptionId 
)
protected
Parameters
\Magento\Framework\DataObject$selection
int[]$qtys
int$selectionOptionId
Returns
float

Definition at line 1222 of file Type.php.

1223  {
1224  if ($selection->getSelectionCanChangeQty() && isset($qtys[$selectionOptionId])) {
1225  $qty = (float)$qtys[$selectionOptionId] > 0 ? $qtys[$selectionOptionId] : 1;
1226  } else {
1227  $qty = (float)$selection->getSelectionQty() ? $selection->getSelectionQty() : 1;
1228  }
1229  $qty = (float)$qty;
1230 
1231  return $qty;
1232  }

◆ getRelationInfo()

getRelationInfo ( )

Return relation info about used products

Returns
\Magento\Framework\DataObject Object with information data

Definition at line 255 of file Type.php.

256  {
257  $info = new \Magento\Framework\DataObject();
258  $info->setTable('catalog_product_bundle_selection')
259  ->setParentFieldName('parent_product_id')
260  ->setChildFieldName('product_id');
261 
262  return $info;
263  }
foreach( $_productCollection as $_product)() ?>" class $info
Definition: listing.phtml:52

◆ getSearchableData()

getSearchableData (   $product)

Retrieve additional searchable data from type instance Using based on product id and store_id data

Parameters
\Magento\Catalog\Model\Product$product
Returns
array

Definition at line 1058 of file Type.php.

1059  {
1060  $searchData = parent::getSearchableData($product);
1061 
1062  $optionSearchData = $this->_bundleOption->create()
1063  ->getSearchableData(
1064  $product->getId(),
1065  $product->getStoreId()
1066  );
1067  if ($optionSearchData) {
1068  $searchData = array_merge($searchData, $optionSearchData);
1069  }
1070 
1071  return $searchData;
1072  }

◆ getSku()

getSku (   $product)

Return product sku based on sku_type attribute

Parameters
\Magento\Catalog\Model\Product$product
Returns
string

Definition at line 297 of file Type.php.

298  {
299  $sku = parent::getSku($product);
300 
301  if ($product->getData('sku_type')) {
302  return $sku;
303  } else {
304  $skuParts = [$sku];
305 
306  if ($product->hasCustomOptions()) {
307  $customOption = $product->getCustomOption('bundle_selection_ids');
308  $selectionIds = $this->serializer->unserialize($customOption->getValue());
309  if (!empty($selectionIds)) {
310  $selections = $this->getSelectionsByIds($selectionIds, $product);
311  foreach ($selections->getItems() as $selection) {
312  $skuParts[] = $selection->getSku();
313  }
314  }
315  }
316 
317  return implode('-', $skuParts);
318  }
319  }
$customOption
Definition: products.php:73

◆ getSpecifyOptionMessage()

getSpecifyOptionMessage ( )

Retrieve message for specify option(s)

Returns
\Magento\Framework\Phrase

Definition at line 834 of file Type.php.

835  {
836  return __('Please specify product option(s).');
837  }
__()
Definition: __.php:13

◆ getWeight()

getWeight (   $product)

Return product weight based on weight_type attribute

Parameters
\Magento\Catalog\Model\Product$product
Returns
float

Definition at line 327 of file Type.php.

328  {
329  if ($product->getData('weight_type')) {
330  return $product->getData('weight');
331  } else {
332  $weight = 0;
333 
334  if ($product->hasCustomOptions()) {
335  $customOption = $product->getCustomOption('bundle_selection_ids');
336  $selectionIds = $this->serializer->unserialize($customOption->getValue());
337  $selections = $this->getSelectionsByIds($selectionIds, $product);
338  foreach ($selections->getItems() as $selection) {
339  $qtyOption = $product->getCustomOption('selection_qty_' . $selection->getSelectionId());
340  if ($qtyOption) {
341  $weight += $selection->getWeight() * $qtyOption->getValue();
342  } else {
343  $weight += $selection->getWeight();
344  }
345  }
346  }
347 
348  return $weight;
349  }
350  }
$customOption
Definition: products.php:73

◆ hasOptions()

hasOptions (   $product)

Return true if product has options

Parameters
\Magento\Catalog\Model\Product$product
Returns
bool

Definition at line 1024 of file Type.php.

1025  {
1026  $this->setStoreFilter($product->getStoreId(), $product);
1027  $optionIds = $this->getOptionsCollection($product)
1028  ->getAllIds();
1029  $collection = $this->getSelectionsCollection($optionIds, $product);
1030 
1031  if ($collection->getSize() > 0 || $product->getOptions()) {
1032  return true;
1033  }
1034 
1035  return false;
1036  }

◆ isSalable()

isSalable (   $product)

Checking if we can sale this bundle

Parameters
\Magento\Catalog\Model\Product$product
Returns
bool @SuppressWarnings(PHPMD.CyclomaticComplexity) @SuppressWarnings(PHPMD.NPathComplexity)

Definition at line 573 of file Type.php.

574  {
575  if (!parent::isSalable($product)) {
576  return false;
577  }
578 
579  if ($product->hasData('all_items_salable')) {
580  return $product->getData('all_items_salable');
581  }
582 
583  $metadata = $this->metadataPool->getMetadata(
584  \Magento\Catalog\Api\Data\ProductInterface::class
585  );
586 
587  $isSalable = false;
588  foreach ($this->getOptionsCollection($product) as $option) {
589  $hasSalable = false;
590 
591  $selectionsCollection = $this->_bundleCollection->create();
592  $selectionsCollection->addAttributeToSelect('status');
593  $selectionsCollection->addQuantityFilter();
594  $selectionsCollection->setFlag('product_children', true);
595  $selectionsCollection->addFilterByRequiredOptions();
596  $selectionsCollection->setOptionIdsFilter([$option->getId()]);
597 
598  $this->selectionCollectionFilterApplier->apply(
599  $selectionsCollection,
600  'parent_product_id',
601  $product->getData($metadata->getLinkField())
602  );
603 
604  foreach ($selectionsCollection as $selection) {
605  if ($selection->isSalable()) {
606  $hasSalable = true;
607  break;
608  }
609  }
610 
611  if ($hasSalable) {
612  $isSalable = true;
613  }
614 
615  if (!$hasSalable && $option->getRequired()) {
616  $isSalable = false;
617  break;
618  }
619  }
620 
621  $product->setData('all_items_salable', $isSalable);
622 
623  return $isSalable;
624  }

◆ isVirtual()

isVirtual (   $product)

Check is virtual product

Parameters
\Magento\Catalog\Model\Product$product
Returns
bool

Definition at line 358 of file Type.php.

359  {
360  if ($product->hasCustomOptions()) {
361  $customOption = $product->getCustomOption('bundle_selection_ids');
362  $selectionIds = $this->serializer->unserialize($customOption->getValue());
363  $selections = $this->getSelectionsByIds($selectionIds, $product);
364  $virtualCount = 0;
365  foreach ($selections->getItems() as $selection) {
366  if ($selection->isVirtual()) {
367  $virtualCount++;
368  }
369  }
370 
371  return $virtualCount === count($selections);
372  }
373 
374  return false;
375  }
$customOption
Definition: products.php:73

◆ mergeSelectionsWithOptions()

mergeSelectionsWithOptions (   $options,
  $selections 
)
protected
Parameters

Definition at line 1325 of file Type.php.

1326  {
1327  foreach ($options as $option) {
1328  $optionSelections = $option->getSelections();
1329  if ($option->getRequired() && is_array($optionSelections) && count($optionSelections) == 1) {
1330  $selections = array_merge($selections, $optionSelections);
1331  } else {
1332  $selections = [];
1333  break;
1334  }
1335  }
1336 
1337  return $selections;
1338  }

◆ prepareQuoteItemQty()

prepareQuoteItemQty (   $qty,
  $product 
)

Prepare Quote Item Quantity

Parameters
mixed$qty
\Magento\Catalog\Model\Product$product
Returns
int @SuppressWarnings(PHPMD.UnusedFormalParameter)

Definition at line 560 of file Type.php.

561  {
562  return (int) $qty;
563  }

◆ processBuyRequest()

processBuyRequest (   $product,
  $buyRequest 
)

Prepare selected options for bundle product

Parameters
\Magento\Catalog\Model\Product$product
\Magento\Framework\DataObject$buyRequest
Returns
array @SuppressWarnings(PHPMD.UnusedFormalParameter)

Definition at line 1157 of file Type.php.

1158  {
1159  $option = $buyRequest->getBundleOption();
1160  $optionQty = $buyRequest->getBundleOptionQty();
1161 
1162  $option = is_array($option) ? array_filter($option, 'intval') : [];
1163  $optionQty = is_array($optionQty) ? array_filter($optionQty, 'intval') : [];
1164 
1165  $options = ['bundle_option' => $option, 'bundle_option_qty' => $optionQty];
1166 
1167  return $options;
1168  }
foreach($product->getExtensionAttributes() ->getBundleProductOptions() as $option) $buyRequest

◆ shakeSelections()

shakeSelections (   $firstItem,
  $secondItem 
)

Sort selections method for usort function Sort selections by option position, selection position and selection id

Parameters
\Magento\Catalog\Model\Product$firstItem
\Magento\Catalog\Model\Product$secondItem
Returns
int

Definition at line 996 of file Type.php.

997  {
998  $aPosition = [
999  $firstItem->getOption()
1000  ->getPosition(),
1001  $firstItem->getOptionId(),
1002  $firstItem->getPosition(),
1003  $firstItem->getSelectionId(),
1004  ];
1005  $bPosition = [
1006  $secondItem->getOption()
1007  ->getPosition(),
1008  $secondItem->getOptionId(),
1009  $secondItem->getPosition(),
1010  $secondItem->getSelectionId(),
1011  ];
1012  if ($aPosition == $bPosition) {
1013  return 0;
1014  }
1015  return $aPosition < $bPosition ? -1 : 1;
1016  }

◆ updateQtyOption()

updateQtyOption (   $options,
\Magento\Framework\DataObject  $option,
  $value,
  $product 
)

Method is needed for specific actions to change given quote options values according current product type logic Example: the catalog inventory validation of decimal qty can change qty to int, so need to change quote item qty option value too.

Parameters
array$options
\Magento\Framework\DataObject$option
mixed$value
\Magento\Catalog\Model\Product$product
Returns
$this

Definition at line 527 of file Type.php.

528  {
529  $optionProduct = $option->getProduct($product);
530  $optionUpdateFlag = $option->getHasQtyOptionUpdate();
531  $optionCollection = $this->getOptionsCollection($product);
532 
533  $selections = $this->getSelectionsCollection($optionCollection->getAllIds(), $product);
534 
535  foreach ($selections as $selection) {
536  if ($selection->getProductId() == $optionProduct->getId()) {
537  foreach ($options as $quoteItemOption) {
538  if ($quoteItemOption->getCode() == 'selection_qty_' . $selection->getSelectionId()) {
539  if ($optionUpdateFlag) {
540  $quoteItemOption->setValue(intval($quoteItemOption->getValue()));
541  } else {
542  $quoteItemOption->setValue($value);
543  }
544  }
545  }
546  }
547  }
548 
549  return $this;
550  }
$value
Definition: gender.phtml:16

Field Documentation

◆ $_bundleCollection

$_bundleCollection
protected

Definition at line 126 of file Type.php.

◆ $_bundleFactory

$_bundleFactory
protected

Definition at line 131 of file Type.php.

◆ $_bundleModelSelection

$_bundleModelSelection
protected

Definition at line 136 of file Type.php.

◆ $_bundleOption

$_bundleOption
protected

Definition at line 111 of file Type.php.

◆ $_bundleSelection

$_bundleSelection
protected

Definition at line 116 of file Type.php.

◆ $_canConfigure

$_canConfigure = true
protected

Definition at line 87 of file Type.php.

◆ $_catalogData

$_catalogData = null
protected

Definition at line 94 of file Type.php.

◆ $_catalogProduct

$_catalogProduct = null
protected

Definition at line 101 of file Type.php.

◆ $_config

$_config
protected

Definition at line 121 of file Type.php.

◆ $_isComposite

$_isComposite = true
protected

Definition at line 37 of file Type.php.

◆ $_keyOptionsCollection

$_keyOptionsCollection = '_cache_instance_options_collection'
protected

Definition at line 44 of file Type.php.

◆ $_keySelectionsCollection

$_keySelectionsCollection = '_cache_instance_selections_collection'
protected

Definition at line 52 of file Type.php.

◆ $_keyUsedOptions

$_keyUsedOptions = '_cache_instance_used_options'
protected

Definition at line 73 of file Type.php.

◆ $_keyUsedOptionsIds

$_keyUsedOptionsIds = '_cache_instance_used_options_ids'
protected

Definition at line 80 of file Type.php.

◆ $_keyUsedSelections

$_keyUsedSelections = '_cache_instance_used_selections'
protected

Definition at line 59 of file Type.php.

◆ $_keyUsedSelectionsIds

$_keyUsedSelectionsIds = '_cache_instance_used_selections_ids'
protected

Definition at line 66 of file Type.php.

◆ $_stockRegistry

$_stockRegistry
protected

Definition at line 146 of file Type.php.

◆ $_stockState

$_stockState
protected

Definition at line 151 of file Type.php.

◆ $_storeManager

$_storeManager
protected

Definition at line 106 of file Type.php.

◆ $priceCurrency

$priceCurrency
protected

Definition at line 141 of file Type.php.

◆ TYPE_CODE

const TYPE_CODE = 'bundle'

Product type

Definition at line 30 of file Type.php.


The documentation for this class was generated from the following file: