Skip to content

Commit 98b3ee6

Browse files
authored
Merge branch '2.4-develop' into jquery-upgrade
2 parents 00396c5 + 76ff97e commit 98b3ee6

File tree

9 files changed

+407
-44
lines changed

9 files changed

+407
-44
lines changed

app/code/Magento/Bundle/Model/Product/Type.php

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,11 @@ protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $p
665665
$skipSaleableCheck = $this->_catalogProduct->getSkipSaleableCheck();
666666
$_appendAllSelections = (bool)$product->getSkipCheckRequiredOption() || $skipSaleableCheck;
667667

668-
$options = $buyRequest->getBundleOption();
668+
if ($buyRequest->getBundleOptionsData()) {
669+
$options = $this->getPreparedOptions($buyRequest->getBundleOptionsData());
670+
} else {
671+
$options = $buyRequest->getBundleOption();
672+
}
669673
if (is_array($options)) {
670674
$options = $this->recursiveIntval($options);
671675
$optionIds = array_keys($options);
@@ -732,7 +736,11 @@ protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $p
732736
if ((is_array($selections) && count($selections) > 0) || !$isStrictProcessMode) {
733737
$uniqueKey = [$product->getId()];
734738
$selectionIds = [];
735-
$qtys = $buyRequest->getBundleOptionQty();
739+
if ($buyRequest->getBundleOptionsData()) {
740+
$qtys = $buyRequest->getBundleOptionsData();
741+
} else {
742+
$qtys = $buyRequest->getBundleOptionQty();
743+
}
736744

737745
// Shuffle selection array by option position
738746
usort($selections, [$this, 'shakeSelections']);
@@ -1231,7 +1239,12 @@ public function getIdentities(\Magento\Catalog\Model\Product $product)
12311239
protected function getQty($selection, $qtys, $selectionOptionId)
12321240
{
12331241
if ($selection->getSelectionCanChangeQty() && isset($qtys[$selectionOptionId])) {
1234-
$qty = (float)$qtys[$selectionOptionId] > 0 ? $qtys[$selectionOptionId] : 1;
1242+
if (is_array($qtys[$selectionOptionId]) && isset($qtys[$selectionOptionId][$selection->getSelectionId()])) {
1243+
$selectionQty = $qtys[$selectionOptionId][$selection->getSelectionId()];
1244+
$qty = (float)$selectionQty > 0 ? $selectionQty : 1;
1245+
} else {
1246+
$qty = (float)$qtys[$selectionOptionId] > 0 ? $qtys[$selectionOptionId] : 1;
1247+
}
12351248
} else {
12361249
$qty = (float)$selection->getSelectionQty() ? $selection->getSelectionQty() : 1;
12371250
}
@@ -1404,4 +1417,21 @@ protected function mergeSelectionsWithOptions($options, $selections)
14041417

14051418
return array_merge([], ...$selections);
14061419
}
1420+
1421+
/**
1422+
* Get prepared options with selection ids
1423+
*
1424+
* @param array $options
1425+
* @return array
1426+
*/
1427+
private function getPreparedOptions(array $options): array
1428+
{
1429+
foreach ($options as $optionId => $option) {
1430+
foreach ($option as $selectionId => $optionQty) {
1431+
$options[$optionId][$selectionId] = $selectionId;
1432+
}
1433+
}
1434+
1435+
return $options;
1436+
}
14071437
}

app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,16 @@ public function testPrepareForCartAdvancedWithoutOptions()
232232
/** @var MockObject|DataObject $buyRequest */
233233
$buyRequest = $this->getMockBuilder(DataObject::class)
234234
->setMethods(
235-
['__wakeup', 'getOptions', 'getSuperProductConfig', 'unsetData', 'getData', 'getQty', 'getBundleOption']
235+
[
236+
'__wakeup',
237+
'getOptions',
238+
'getSuperProductConfig',
239+
'unsetData',
240+
'getData',
241+
'getQty',
242+
'getBundleOption',
243+
'getBundleOptionsData',
244+
]
236245
)
237246
->disableOriginalConstructor()
238247
->getMock();
@@ -342,7 +351,8 @@ public function testPrepareForCartAdvancedWithShoppingCart()
342351
'getData',
343352
'getQty',
344353
'getBundleOption',
345-
'getBundleOptionQty'
354+
'getBundleOptionQty',
355+
'getBundleOptionsData',
346356
]
347357
)
348358
->disableOriginalConstructor()
@@ -586,7 +596,8 @@ public function testPrepareForCartAdvancedEmptyShoppingCart()
586596
'getData',
587597
'getQty',
588598
'getBundleOption',
589-
'getBundleOptionQty'
599+
'getBundleOptionQty',
600+
'getBundleOptionsData',
590601
]
591602
)
592603
->disableOriginalConstructor()
@@ -811,7 +822,8 @@ public function testPrepareForCartAdvancedStringInResult()
811822
'getData',
812823
'getQty',
813824
'getBundleOption',
814-
'getBundleOptionQty'
825+
'getBundleOptionQty',
826+
'getBundleOptionsData',
815827
]
816828
)
817829
->disableOriginalConstructor()
@@ -1030,7 +1042,8 @@ public function testPrepareForCartAdvancedWithoutSelections()
10301042
'getData',
10311043
'getQty',
10321044
'getBundleOption',
1033-
'getBundleOptionQty'
1045+
'getBundleOptionQty',
1046+
'getBundleOptionsData',
10341047
]
10351048
)
10361049
->disableOriginalConstructor()
@@ -1131,7 +1144,16 @@ public function testPrepareForCartAdvancedSelectionsSelectionIdsExists()
11311144
/** @var MockObject|DataObject $buyRequest */
11321145
$buyRequest = $this->getMockBuilder(DataObject::class)
11331146
->setMethods(
1134-
['__wakeup', 'getOptions', 'getSuperProductConfig', 'unsetData', 'getData', 'getQty', 'getBundleOption']
1147+
[
1148+
'__wakeup',
1149+
'getOptions',
1150+
'getSuperProductConfig',
1151+
'unsetData',
1152+
'getData',
1153+
'getQty',
1154+
'getBundleOption',
1155+
'getBundleOptionsData',
1156+
]
11351157
)
11361158
->disableOriginalConstructor()
11371159
->getMock();
@@ -1258,7 +1280,16 @@ public function testPrepareForCartAdvancedSelectRequiredOptions()
12581280
/** @var MockObject|DataObject $buyRequest */
12591281
$buyRequest = $this->getMockBuilder(DataObject::class)
12601282
->setMethods(
1261-
['__wakeup', 'getOptions', 'getSuperProductConfig', 'unsetData', 'getData', 'getQty', 'getBundleOption']
1283+
[
1284+
'__wakeup',
1285+
'getOptions',
1286+
'getSuperProductConfig',
1287+
'unsetData',
1288+
'getData',
1289+
'getQty',
1290+
'getBundleOption',
1291+
'getBundleOptionsData',
1292+
]
12621293
)
12631294
->disableOriginalConstructor()
12641295
->getMock();
@@ -1422,7 +1453,16 @@ public function testPrepareForCartAdvancedAllRequiredOption()
14221453
/** @var MockObject|DataObject $buyRequest */
14231454
$buyRequest = $this->getMockBuilder(DataObject::class)
14241455
->setMethods(
1425-
['__wakeup', 'getOptions', 'getSuperProductConfig', 'unsetData', 'getData', 'getQty', 'getBundleOption']
1456+
[
1457+
'__wakeup',
1458+
'getOptions',
1459+
'getSuperProductConfig',
1460+
'unsetData',
1461+
'getData',
1462+
'getQty',
1463+
'getBundleOption',
1464+
'getBundleOptionsData',
1465+
]
14261466
)
14271467
->disableOriginalConstructor()
14281468
->getMock();
@@ -1523,7 +1563,16 @@ public function testPrepareForCartAdvancedSpecifyProductOptions()
15231563
/** @var MockObject|DataObject $buyRequest */
15241564
$buyRequest = $this->getMockBuilder(DataObject::class)
15251565
->setMethods(
1526-
['__wakeup', 'getOptions', 'getSuperProductConfig', 'unsetData', 'getData', 'getQty', 'getBundleOption']
1566+
[
1567+
'__wakeup',
1568+
'getOptions',
1569+
'getSuperProductConfig',
1570+
'unsetData',
1571+
'getData',
1572+
'getQty',
1573+
'getBundleOption',
1574+
'getBundleOptionsData',
1575+
]
15271576
)
15281577
->disableOriginalConstructor()
15291578
->getMock();

app/code/Magento/Catalog/Controller/Product/View.php

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,22 @@
55
*/
66
namespace Magento\Catalog\Controller\Product;
77

8+
use Magento\Catalog\Api\ProductRepositoryInterface;
9+
use Magento\Catalog\Model\Design;
810
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
911
use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
1012
use Magento\Framework\App\Action\Context;
1113
use Magento\Framework\App\ObjectManager;
14+
use Magento\Framework\Controller\Result\Forward;
15+
use Magento\Framework\Controller\Result\ForwardFactory;
16+
use Magento\Framework\Controller\Result\Redirect;
17+
use Magento\Framework\DataObject;
18+
use Magento\Framework\Exception\NoSuchEntityException;
19+
use Magento\Framework\Json\Helper\Data;
1220
use Magento\Framework\View\Result\PageFactory;
1321
use Magento\Catalog\Controller\Product as ProductAction;
22+
use Magento\Store\Model\StoreManagerInterface;
23+
use Psr\Log\LoggerInterface;
1424

1525
/**
1626
* View a product on storefront. Needs to be accessible by POST because of the store switching
@@ -25,57 +35,84 @@ class View extends ProductAction implements HttpGetActionInterface, HttpPostActi
2535
protected $viewHelper;
2636

2737
/**
28-
* @var \Magento\Framework\Controller\Result\ForwardFactory
38+
* @var ForwardFactory
2939
*/
3040
protected $resultForwardFactory;
3141

3242
/**
33-
* @var \Magento\Framework\View\Result\PageFactory
43+
* @var PageFactory
3444
*/
3545
protected $resultPageFactory;
3646

3747
/**
38-
* @var \Psr\Log\LoggerInterface
48+
* @var LoggerInterface
3949
*/
4050
private $logger;
4151

4252
/**
43-
* @var \Magento\Framework\Json\Helper\Data
53+
* @var Data
4454
*/
4555
private $jsonHelper;
4656

57+
/**
58+
* @var Design
59+
*/
60+
private $catalogDesign;
61+
62+
/**
63+
* @var ProductRepositoryInterface
64+
*/
65+
private $productRepository;
66+
67+
/**
68+
* @var StoreManagerInterface
69+
*/
70+
private $storeManager;
71+
4772
/**
4873
* Constructor
4974
*
5075
* @param Context $context
5176
* @param \Magento\Catalog\Helper\Product\View $viewHelper
52-
* @param \Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory
77+
* @param ForwardFactory $resultForwardFactory
5378
* @param PageFactory $resultPageFactory
54-
* @param \Psr\Log\LoggerInterface $logger
55-
* @param \Magento\Framework\Json\Helper\Data $jsonHelper
79+
* @param LoggerInterface|null $logger
80+
* @param Data|null $jsonHelper
81+
* @param Design|null $catalogDesign
82+
* @param ProductRepositoryInterface|null $productRepository
83+
* @param StoreManagerInterface|null $storeManager
5684
*/
5785
public function __construct(
5886
Context $context,
5987
\Magento\Catalog\Helper\Product\View $viewHelper,
60-
\Magento\Framework\Controller\Result\ForwardFactory $resultForwardFactory,
88+
ForwardFactory $resultForwardFactory,
6189
PageFactory $resultPageFactory,
62-
\Psr\Log\LoggerInterface $logger = null,
63-
\Magento\Framework\Json\Helper\Data $jsonHelper = null
90+
?LoggerInterface $logger = null,
91+
?Data $jsonHelper = null,
92+
?Design $catalogDesign = null,
93+
?ProductRepositoryInterface $productRepository = null,
94+
?StoreManagerInterface $storeManager = null
6495
) {
6596
parent::__construct($context);
6697
$this->viewHelper = $viewHelper;
6798
$this->resultForwardFactory = $resultForwardFactory;
6899
$this->resultPageFactory = $resultPageFactory;
69100
$this->logger = $logger ?: ObjectManager::getInstance()
70-
->get(\Psr\Log\LoggerInterface::class);
101+
->get(LoggerInterface::class);
71102
$this->jsonHelper = $jsonHelper ?: ObjectManager::getInstance()
72-
->get(\Magento\Framework\Json\Helper\Data::class);
103+
->get(Data::class);
104+
$this->catalogDesign = $catalogDesign ?: ObjectManager::getInstance()
105+
->get(Design::class);
106+
$this->productRepository = $productRepository ?: ObjectManager::getInstance()
107+
->get(ProductRepositoryInterface::class);
108+
$this->storeManager = $storeManager ?: ObjectManager::getInstance()
109+
->get(StoreManagerInterface::class);
73110
}
74111

75112
/**
76113
* Redirect if product failed to load
77114
*
78-
* @return \Magento\Framework\Controller\Result\Redirect|\Magento\Framework\Controller\Result\Forward
115+
* @return Redirect|Forward
79116
*/
80117
protected function noProductRedirect()
81118
{
@@ -93,7 +130,7 @@ protected function noProductRedirect()
93130
/**
94131
* Product view action
95132
*
96-
* @return \Magento\Framework\Controller\Result\Forward|\Magento\Framework\Controller\Result\Redirect
133+
* @return Forward|Redirect
97134
*/
98135
public function execute()
99136
{
@@ -130,16 +167,17 @@ public function execute()
130167
}
131168

132169
// Prepare helper and params
133-
$params = new \Magento\Framework\DataObject();
170+
$params = new DataObject();
134171
$params->setCategoryId($categoryId);
135172
$params->setSpecifyOptions($specifyOptions);
136173

137174
// Render page
138175
try {
176+
$this->applyCustomDesign($productId);
139177
$page = $this->resultPageFactory->create();
140178
$this->viewHelper->prepareAndRender($page, $productId, $this, $params);
141179
return $page;
142-
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
180+
} catch (NoSuchEntityException $e) {
143181
return $this->noProductRedirect();
144182
} catch (\Exception $e) {
145183
$this->logger->critical($e);
@@ -148,4 +186,19 @@ public function execute()
148186
return $resultForward;
149187
}
150188
}
189+
190+
/**
191+
* Apply custom design from product design settings
192+
*
193+
* @param int $productId
194+
* @throws NoSuchEntityException
195+
*/
196+
private function applyCustomDesign(int $productId): void
197+
{
198+
$product = $this->productRepository->getById($productId, false, $this->storeManager->getStore()->getId());
199+
$settings = $this->catalogDesign->getDesignSettings($product);
200+
if ($settings->getCustomDesign()) {
201+
$this->catalogDesign->applyCustomDesign($settings->getCustomDesign());
202+
}
203+
}
151204
}

0 commit comments

Comments
 (0)