Skip to content

Commit 550c2a3

Browse files
Merge branch '2.4-develop' into ACQE-functional-deployment-version15
2 parents 9870f81 + bd4aabb commit 550c2a3

File tree

92 files changed

+4381
-273
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+4381
-273
lines changed

app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleProductToCartFromWishListPageTest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
<deleteData createDataKey="createSimpleProduct2" stepKey="deleteSimpleProduct2"/>
7070
<!-- Log out -->
7171
<comment userInput="Log out" stepKey="commentLogOut"/>
72+
<deleteData createDataKey="createCategory" stepKey="deletecreateCategory"/>
7273
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
7374
</after>
7475
<!-- Login to the Storefront as created customer -->

app/code/Magento/Bundle/Test/Mftf/Test/AdminAssociateBundleProductToWebsitesTest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
<actionGroup ref="NavigateToAndResetProductGridToDefaultViewActionGroup" stepKey="resetProductGridFilter"/>
8888

8989
<!-- Admin logout -->
90+
<deleteData createDataKey="createCategory" stepKey="deletecreateCategory"/>
9091
<actionGroup ref="AdminLogoutActionGroup" stepKey="adminLogout"/>
9192
</after>
9293

app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductShownInCategoryListAndGridTest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
</before>
3333
<after>
3434
<!--Logging out-->
35+
<actionGroup ref="AdminDeleteCategoryByNameActionGroup" stepKey="deleteCategory">
36+
<argument name="categoryName" value="{{SimpleSubCategory.name}}"/>
37+
</actionGroup>
3538
<actionGroup ref="AdminLogoutActionGroup" stepKey="amOnLogoutPage"/>
3639
<deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/>
3740
<deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/>

app/code/Magento/Bundle/Test/Mftf/Test/StorefrontCheckPriceForDynamicBundleProductWithMixedDiscountsTest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@
173173
<deleteData createDataKey="sixthProduct" stepKey="deleteSixthProduct"/>
174174
<deleteData createDataKey="createBundleProduct" stepKey="deleteBundleProduct"/>
175175
<actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteCatalogPriceRules"/>
176+
<deleteData createDataKey="category1" stepKey="deletecategory1"/>
177+
<deleteData createDataKey="category2" stepKey="deletecategory2"/>
178+
<deleteData createDataKey="category3" stepKey="deletecategory3"/>
176179
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
177180
</after>
178181
<!-- Go to storefront category page -->

app/code/Magento/Bundle/Test/Mftf/Test/StorefrontCheckPriceForFixedBundleProductWithCatalogRuleTest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
<deleteData createDataKey="createFixedBundleProduct" stepKey="deleteBundleProduct"/>
148148
<actionGroup ref="AdminCatalogPriceRuleDeleteAllActionGroup" stepKey="deleteCatalogPriceRules"/>
149149
<!-- logout admin -->
150+
<deleteData createDataKey="category1" stepKey="deletecategory1"/>
150151
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
151152
</after>
152153
<!-- check product prices on category and product page -->

app/code/Magento/BundleImportExport/Test/Mftf/Test/UpdateBundleProductViaImportTest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
<argument name="sku" value="Simple"/>
3131
</actionGroup>
3232
<actionGroup ref="ResetAdminDataGridToDefaultViewActionGroup" stepKey="clearFilters"/>
33+
<actionGroup ref="AdminDeleteCategoryByNameActionGroup" stepKey="deleteCategory">
34+
<argument name="categoryName" value="New"/>
35+
</actionGroup>
3336
<actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/>
3437
</after>
3538

app/code/Magento/Catalog/Model/CustomOptions/CustomOptionProcessor.php

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,23 @@
33
* Copyright 2015 Adobe
44
* All Rights Reserved.
55
*/
6+
67
namespace Magento\Catalog\Model\CustomOptions;
78

9+
use Magento\Catalog\Api\Data\CustomOptionInterface;
10+
use Magento\Catalog\Api\Data\ProductCustomOptionInterface;
11+
use Magento\Catalog\Api\ProductRepositoryInterface;
12+
use Magento\Catalog\Model\Product\Option\Type\File\ImageContentProcessor;
813
use Magento\Framework\DataObject;
14+
use Magento\Framework\Exception\NoSuchEntityException;
915
use Magento\Quote\Api\Data\CartItemInterface;
1016
use Magento\Quote\Model\Quote\Item\CartItemProcessorInterface;
1117
use Magento\Quote\Api\Data\ProductOptionExtensionFactory;
1218
use Magento\Quote\Model\Quote\ProductOptionFactory;
1319

20+
/**
21+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
22+
*/
1423
class CustomOptionProcessor implements CartItemProcessorInterface
1524
{
1625
/**
@@ -45,41 +54,63 @@ class CustomOptionProcessor implements CartItemProcessorInterface
4554
*/
4655
private $serializer;
4756

57+
/**
58+
* @var ProductRepositoryInterface
59+
*/
60+
private $productRepository;
61+
62+
/**
63+
* @var ImageContentProcessor
64+
*/
65+
private $imageContentProcessor;
66+
4867
/**
4968
* @param DataObject\Factory $objectFactory
5069
* @param ProductOptionFactory $productOptionFactory
5170
* @param ProductOptionExtensionFactory $extensionFactory
5271
* @param CustomOptionFactory $customOptionFactory
5372
* @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
73+
* @param ProductRepositoryInterface|null $productRepository
74+
* @param ImageContentProcessor|null $imageContentProcessor
5475
*/
5576
public function __construct(
5677
\Magento\Framework\DataObject\Factory $objectFactory,
5778
\Magento\Quote\Model\Quote\ProductOptionFactory $productOptionFactory,
5879
\Magento\Quote\Api\Data\ProductOptionExtensionFactory $extensionFactory,
5980
\Magento\Catalog\Model\CustomOptions\CustomOptionFactory $customOptionFactory,
60-
?\Magento\Framework\Serialize\Serializer\Json $serializer = null
81+
?\Magento\Framework\Serialize\Serializer\Json $serializer = null,
82+
?ProductRepositoryInterface $productRepository = null,
83+
?ImageContentProcessor $imageContentProcessor = null
6184
) {
6285
$this->objectFactory = $objectFactory;
6386
$this->productOptionFactory = $productOptionFactory;
6487
$this->extensionFactory = $extensionFactory;
6588
$this->customOptionFactory = $customOptionFactory;
6689
$this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
6790
->get(\Magento\Framework\Serialize\Serializer\Json::class);
91+
$this->productRepository = $productRepository
92+
?: \Magento\Framework\App\ObjectManager::getInstance()
93+
->get(ProductRepositoryInterface::class);
94+
$this->imageContentProcessor = $imageContentProcessor
95+
?: \Magento\Framework\App\ObjectManager::getInstance()
96+
->get(ImageContentProcessor::class);
6897
}
6998

7099
/**
71100
* @inheritDoc
72101
*/
73102
public function convertToBuyRequest(CartItemInterface $cartItem)
74103
{
75-
if ($cartItem->getProductOption()
76-
&& $cartItem->getProductOption()->getExtensionAttributes()
77-
&& $cartItem->getProductOption()->getExtensionAttributes()->getCustomOptions()) {
104+
if ($cartItem->getProductOption()?->getExtensionAttributes()?->getCustomOptions()) {
78105
$customOptions = $cartItem->getProductOption()->getExtensionAttributes()->getCustomOptions();
79-
if (!empty($customOptions) && is_array($customOptions)) {
106+
if (!empty($customOptions)) {
80107
$requestData = [];
108+
$productOptions = $this->getProductCustomOptions($cartItem);
81109
foreach ($customOptions as $option) {
82-
$requestData['options'][$option->getOptionId()] = $option->getOptionValue();
110+
$requestData['options'][$option->getOptionId()] = $this->getCustomOptionValue(
111+
$option,
112+
$productOptions[$option->getOptionId()] ?? null
113+
);
83114
}
84115
return $this->objectFactory->create($requestData);
85116
}
@@ -99,7 +130,6 @@ public function processOptions(CartItemInterface $cartItem)
99130
? $cartItem->getProductOption()
100131
: $this->productOptionFactory->create();
101132

102-
/** @var \Magento\Quote\Api\Data\ProductOptionExtensionInterface $extensibleAttribute */
103133
$extensibleAttribute = $productOption->getExtensionAttributes()
104134
? $productOption->getExtensionAttributes()
105135
: $this->extensionFactory->create();
@@ -136,7 +166,7 @@ protected function getOptions(CartItemInterface $cartItem)
136166
protected function updateOptionsValues(array &$options)
137167
{
138168
foreach ($options as $optionId => &$optionValue) {
139-
/** @var \Magento\Catalog\Model\CustomOptions\CustomOption $option */
169+
/** @var CustomOption $option */
140170
$option = $this->customOptionFactory->create();
141171
$option->setOptionId($optionId);
142172
if (is_array($optionValue)) {
@@ -204,4 +234,55 @@ private function getUrlBuilder()
204234
}
205235
return $this->urlBuilder;
206236
}
237+
238+
/**
239+
* Get Product Options
240+
*
241+
* @param CartItemInterface $cartItem
242+
* @return ProductCustomOptionInterface[]
243+
*/
244+
private function getProductCustomOptions(CartItemInterface $cartItem): array
245+
{
246+
try {
247+
$product = $this->productRepository->get($cartItem->getSku());
248+
} catch (NoSuchEntityException) {
249+
$product = null;
250+
}
251+
252+
$options = [];
253+
foreach ($product?->getHasOptions() ? $product->getOptions() : [] as $option) {
254+
$options[$option->getOptionId()] = $option;
255+
}
256+
return $options;
257+
}
258+
259+
/**
260+
* Get custom option value depending on the type of custom option
261+
*
262+
* @param CustomOptionInterface $customOption
263+
* @param ProductCustomOptionInterface|null $productCustomOption
264+
* @return string|array|null
265+
*/
266+
private function getCustomOptionValue(
267+
CustomOptionInterface $customOption,
268+
?ProductCustomOptionInterface $productCustomOption = null
269+
): mixed {
270+
if ($customOption->getExtensionAttributes()?->getFileInfo()) {
271+
if ($productCustomOption
272+
&& $productCustomOption->getType() === ProductCustomOptionInterface::OPTION_TYPE_FILE
273+
) {
274+
return $this->imageContentProcessor->process(
275+
$customOption->getExtensionAttributes()->getFileInfo(),
276+
$productCustomOption
277+
);
278+
} elseif ($customOption instanceof CustomOption) {
279+
// Check if the custom option is an instance of CustomOption for backward compatibility
280+
// Bypass CustomOption::getOptionValue as the current implementation would process the file
281+
// even if it is not a file option.
282+
return $customOption->getData(CustomOptionInterface::OPTION_VALUE);
283+
}
284+
}
285+
286+
return $customOption->getOptionValue();
287+
}
207288
}

app/code/Magento/Catalog/Model/Indexer/Category/Product/Action/Full.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,13 @@ public function execute(): Full
187187
protected function reindex(): void
188188
{
189189
$userFunctions = [];
190-
191190
foreach ($this->storeManager->getStores() as $store) {
192191
if ($this->getPathFromCategoryId($store->getRootCategoryId())) {
193192
$userFunctions[$store->getId()] = function () use ($store) {
194193
$this->reindexStore($store);
195194
};
196195
}
197196
}
198-
199197
$this->processManager->execute($userFunctions);
200198
}
201199

@@ -206,6 +204,9 @@ protected function reindex(): void
206204
*/
207205
private function reindexStore($store): void
208206
{
207+
// Ensure the same adapter instance that created the TEMP table is used for all operations
208+
// phpcs:ignore
209+
$this->connection = $this->tableMaintainer->getSameAdapterConnection();
209210
$this->reindexRootCategory($store);
210211
$this->reindexAnchorCategories($store);
211212
$this->reindexNonAnchorCategories($store);

app/code/Magento/Catalog/Model/Indexer/Category/Product/TableMaintainer.php

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,15 @@ class TableMaintainer
3535

3636
/**
3737
* Catalog tmp category index table name
38+
*
39+
* @var string
3840
*/
3941
private $tmpTableSuffix = '_tmp';
4042

4143
/**
4244
* Catalog tmp category index table name
45+
*
46+
* @var string
4347
*/
4448
private $additionalTableSuffix = '_replica';
4549

@@ -73,6 +77,16 @@ private function getConnection()
7377
return $this->connection;
7478
}
7579

80+
/**
81+
* Expose connection so callers can use the same adapter instance that created temporary tables.
82+
*
83+
* @return AdapterInterface
84+
*/
85+
public function getSameAdapterConnection(): AdapterInterface
86+
{
87+
return $this->getConnection();
88+
}
89+
7690
/**
7791
* Return validated table name
7892
*
@@ -120,7 +134,7 @@ private function dropTable($tableName)
120134
/**
121135
* Return main index table name
122136
*
123-
* @param $storeId
137+
* @param int $storeId
124138
*
125139
* @return string
126140
*/
@@ -134,7 +148,7 @@ public function getMainTable(int $storeId)
134148
/**
135149
* Create main and replica index tables for store
136150
*
137-
* @param $storeId
151+
* @param int $storeId
138152
*
139153
* @return void
140154
*
@@ -161,7 +175,7 @@ public function createTablesForStore(int $storeId)
161175
/**
162176
* Drop main and replica index tables for store
163177
*
164-
* @param $storeId
178+
* @param int $storeId
165179
*
166180
* @return void
167181
*/
@@ -177,7 +191,7 @@ public function dropTablesForStore(int $storeId)
177191
/**
178192
* Return replica index table name
179193
*
180-
* @param $storeId
194+
* @param int $storeId
181195
*
182196
* @return string
183197
*/
@@ -189,7 +203,7 @@ public function getMainReplicaTable(int $storeId)
189203
/**
190204
* Create temporary index table for store
191205
*
192-
* @param $storeId
206+
* @param int $storeId
193207
*
194208
* @return void
195209
*/
@@ -206,7 +220,7 @@ public function createMainTmpTable(int $storeId)
206220
/**
207221
* Return temporary index table name
208222
*
209-
* @param $storeId
223+
* @param int $storeId
210224
*
211225
* @return string
212226
*
@@ -215,7 +229,7 @@ public function createMainTmpTable(int $storeId)
215229
public function getMainTmpTable(int $storeId)
216230
{
217231
if (!isset($this->mainTmpTable[$storeId])) {
218-
throw new \Magento\Framework\Exception\NoSuchEntityException('Temporary table does not exist');
232+
throw new \Magento\Framework\Exception\NoSuchEntityException(__('Temporary table does not exist'));
219233
}
220234
return $this->mainTmpTable[$storeId];
221235
}

0 commit comments

Comments
 (0)