Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
DefaultSelectionPriceListProvider.php
Go to the documentation of this file.
1 <?php
8 
13 
18 {
22  private $selectionFactory;
23 
27  private $priceList;
28 
32  public function __construct(BundleSelectionFactory $bundleSelectionFactory)
33  {
34  $this->selectionFactory = $bundleSelectionFactory;
35  }
36 
40  public function getPriceList(Product $bundleProduct, $searchMin, $useRegularPrice)
41  {
42  $shouldFindMinOption = $this->isShouldFindMinOption($bundleProduct, $searchMin);
43  $canSkipRequiredOptions = $searchMin && !$shouldFindMinOption;
44 
46  $typeInstance = $bundleProduct->getTypeInstance();
47  $this->priceList = [];
48 
49  foreach ($this->getBundleOptions($bundleProduct) as $option) {
51  if ($this->canSkipOption($option, $canSkipRequiredOptions)) {
52  continue;
53  }
54 
55  $selectionsCollection = $typeInstance->getSelectionsCollection(
56  [(int)$option->getOptionId()],
58  );
59  $selectionsCollection->removeAttributeToSelect();
60  $selectionsCollection->addQuantityFilter();
61 
62  if (!$useRegularPrice) {
63  $selectionsCollection->addAttributeToSelect('special_price');
64  $selectionsCollection->addAttributeToSelect('special_from_date');
65  $selectionsCollection->addAttributeToSelect('special_to_date');
66  $selectionsCollection->addAttributeToSelect('tax_class_id');
67  }
68 
69  if (!$searchMin && $option->isMultiSelection()) {
70  $this->addMaximumMultiSelectionPriceList($bundleProduct, $selectionsCollection, $useRegularPrice);
71  } else {
72  $this->addMiniMaxPriceList($bundleProduct, $selectionsCollection, $searchMin, $useRegularPrice);
73  }
74  }
75 
76  if ($shouldFindMinOption) {
77  $this->processMinPriceForNonRequiredOptions();
78  }
79 
80  return $this->priceList;
81  }
82 
90  private function isShouldFindMinOption(Product $bundleProduct, $searchMin)
91  {
92  $shouldFindMinOption = false;
93  if ($searchMin
94  && $bundleProduct->getPriceType() == Price::PRICE_TYPE_DYNAMIC
95  && !$this->hasRequiredOption($bundleProduct)
96  ) {
97  $shouldFindMinOption = true;
98  }
99 
100  return $shouldFindMinOption;
101  }
102 
112  private function addMiniMaxPriceList(Product $bundleProduct, $selectionsCollection, $searchMin, $useRegularPrice)
113  {
114  $selectionsCollection->addPriceFilter($bundleProduct, $searchMin, $useRegularPrice);
115  $selectionsCollection->setPage(0, 1);
116 
117  $selection = $selectionsCollection->getFirstItem();
118 
119  if (!$selection->isEmpty()) {
120  $this->priceList[] = $this->selectionFactory->create(
122  $selection,
123  $selection->getSelectionQty(),
124  [
125  'useRegularPrice' => $useRegularPrice,
126  ]
127  );
128  }
129  }
130 
139  private function addMaximumMultiSelectionPriceList(Product $bundleProduct, $selectionsCollection, $useRegularPrice)
140  {
141  $selectionsCollection->addPriceData();
142 
143  foreach ($selectionsCollection as $selection) {
144  $this->priceList[] = $this->selectionFactory->create(
146  $selection,
147  $selection->getSelectionQty(),
148  [
149  'useRegularPrice' => $useRegularPrice,
150  ]
151  );
152  }
153  }
154 
158  private function processMinPriceForNonRequiredOptions()
159  {
160  $minPrice = null;
161  $priceSelection = null;
162  foreach ($this->priceList as $price) {
163  $minPriceTmp = $price->getAmount()->getValue() * $price->getQuantity();
164  if (!$minPrice || $minPriceTmp < $minPrice) {
165  $minPrice = $minPriceTmp;
166  $priceSelection = $price;
167  }
168  }
169  $this->priceList = $priceSelection ? [$priceSelection] : [];
170  }
171 
179  private function canSkipOption($option, $canSkipRequiredOption)
180  {
181  return $canSkipRequiredOption && !$option->getRequired();
182  }
183 
190  private function hasRequiredOption($bundleProduct)
191  {
192  $collection = clone $this->getBundleOptions($bundleProduct);
193  $collection->clear();
194 
195  return $collection->addFilter(Option::KEY_REQUIRED, 1)->getSize() > 0;
196  }
197 
204  private function getBundleOptions(Product $saleableItem)
205  {
206  return $saleableItem->getTypeInstance()->getOptionsCollection($saleableItem);
207  }
208 }
$price
getPriceList(Product $bundleProduct, $searchMin, $useRegularPrice)
$bundleProduct