diff --git a/app/code/Magento/Bundle/Model/Product/SelectionProductsDisabledRequired.php b/app/code/Magento/Bundle/Model/Product/SelectionProductsDisabledRequired.php
deleted file mode 100644
index 424330a1671e..000000000000
--- a/app/code/Magento/Bundle/Model/Product/SelectionProductsDisabledRequired.php
+++ /dev/null
@@ -1,173 +0,0 @@
-bundleSelection = $bundleSelection;
- $this->storeManager = $storeManager;
- $this->catalogProductStatus = $catalogProductStatus;
- $this->productCollectionFactory = $productCollectionFactory;
- $this->metadataPool = $metadataPool;
- }
-
- /**
- * Return ids of options and child products when all products in required option are disabled in bundle product
- *
- * @param int $bundleId
- * @param int|null $websiteId
- * @return array
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- public function getChildProductIds(int $bundleId, ?int $websiteId = null): array
- {
- if (!$websiteId) {
- $websiteId = (int)$this->storeManager->getStore()->getWebsiteId();
- }
- $cacheKey = $this->getCacheKey($bundleId, $websiteId);
- if (isset($this->productsDisabledRequired[$cacheKey])) {
- return $this->productsDisabledRequired[$cacheKey];
- }
- $selectionProductIds = $this->bundleSelection->getChildrenIds($bundleId);
- /** for cases when no required products found */
- if (count($selectionProductIds) === 1 && isset($selectionProductIds[0])) {
- $this->productsDisabledRequired[$cacheKey] = [];
- return $this->productsDisabledRequired[$cacheKey];
- }
- $products = $this->getProducts($selectionProductIds, $websiteId);
- if (!$products) {
- $this->productsDisabledRequired[$cacheKey] = [];
- return $this->productsDisabledRequired[$cacheKey];
- }
- foreach ($selectionProductIds as $optionId => $optionProductIds) {
- foreach ($optionProductIds as $productId) {
- if (isset($products[$productId])) {
- /** @var Product $product */
- $product = $products[$productId];
- if (in_array($product->getStatus(), $this->catalogProductStatus->getVisibleStatusIds())) {
- unset($selectionProductIds[$optionId]);
- }
- }
- }
- }
- $this->productsDisabledRequired[$cacheKey] = $selectionProductIds;
- return $this->productsDisabledRequired[$cacheKey];
- }
-
- /**
- * Get products objects
- *
- * @param array $selectionProductIds
- * @param int $websiteId
- * @return ProductInterface[]
- */
- private function getProducts(array $selectionProductIds, int $websiteId): array
- {
- $productIds = [];
- $defaultStore = $this->storeManager->getWebsite($websiteId)->getDefaultStore();
- $defaultStoreId = $defaultStore ? $defaultStore->getId() : null;
- foreach ($selectionProductIds as $optionProductIds) {
- $productIds[] = $optionProductIds;
- }
- $productIds = array_merge([], ...$productIds);
- $productCollection = $this->productCollectionFactory->create();
- $productCollection->joinAttribute(
- ProductInterface::STATUS,
- Product::ENTITY . '/' . ProductInterface::STATUS,
- $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(),
- null,
- 'inner',
- $defaultStoreId
- );
- $productCollection->addIdFilter($productIds);
- $productCollection->addStoreFilter($defaultStoreId);
- $productCollection->setFlag($this->hasStockStatusFilter, true);
- return $productCollection->getItems();
- }
-
- /**
- * Get cache key
- *
- * @param int $bundleId
- * @param int $websiteId
- * @return string
- */
- private function getCacheKey(int $bundleId, int $websiteId): string
- {
- return $bundleId . '-' . $websiteId;
- }
-
- /**
- * @inheritDoc
- */
- public function _resetState(): void
- {
- $this->productsDisabledRequired = [];
- }
-}
diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price/DisabledProductOptionPriceModifier.php b/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price/DisabledProductOptionPriceModifier.php
deleted file mode 100644
index 1730c3b62d3b..000000000000
--- a/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price/DisabledProductOptionPriceModifier.php
+++ /dev/null
@@ -1,157 +0,0 @@
-resourceConnection = $resourceConnection;
- $this->config = $config;
- $this->metadataPool = $metadataPool;
- $this->bundleSelection = $bundleSelection;
- $this->selectionProductsDisabledRequired = $selectionProductsDisabledRequired;
- }
-
- /**
- * Remove bundle product from price index when all products in required option are disabled
- *
- * @param IndexTableStructure $priceTable
- * @param array $entityIds
- * @return void
- * @throws \Magento\Framework\Exception\LocalizedException
- */
- public function modifyPrice(IndexTableStructure $priceTable, array $entityIds = []) : void
- {
- foreach ($this->getBundleIds($entityIds) as $entityId) {
- $entityId = (int) $entityId;
- foreach ($this->getWebsiteIdsOfProduct($entityId) as $websiteId) {
- $websiteId = (int) $websiteId;
- $productIdsDisabledRequired = $this->selectionProductsDisabledRequired
- ->getChildProductIds($entityId, $websiteId);
- if ($productIdsDisabledRequired) {
- $connection = $this->resourceConnection->getConnection('indexer');
- $select = $connection->select();
- $select->from(['price_index' => $priceTable->getTableName()], []);
- $priceEntityField = $priceTable->getEntityField();
- $select->where('price_index.website_id = ?', $websiteId);
- $select->where("price_index.{$priceEntityField} = ?", $entityId);
- $query = $select->deleteFromSelect('price_index');
- $connection->query($query);
- }
- }
- }
- }
-
- /**
- * Get all website ids of product
- *
- * @param int $entityId
- * @return array
- */
- private function getWebsiteIdsOfProduct(int $entityId): array
- {
- if (isset($this->websiteIdsOfProduct[$entityId])) {
- return $this->websiteIdsOfProduct[$entityId];
- }
- $connection = $this->resourceConnection->getConnection('indexer');
- $select = $connection->select();
- $select->from(
- ['product_in_websites' => $this->resourceConnection->getTableName('catalog_product_website')],
- ['website_id']
- )->where('product_in_websites.product_id = ?', $entityId);
- $this->websiteIdsOfProduct[$entityId] = $connection->fetchCol($select);
-
- return $this->websiteIdsOfProduct[$entityId];
- }
-
- /**
- * Get Bundle Ids
- *
- * @param array $entityIds
- * @return \Traversable
- */
- private function getBundleIds(array $entityIds): \Traversable
- {
- $connection = $this->resourceConnection->getConnection('indexer');
- $select = $connection->select();
- $select->from(
- ['cpe' => $this->resourceConnection->getTableName('catalog_product_entity')],
- ['entity_id']
- )->where('cpe.entity_id in ( ? )', !empty($entityIds) ? $entityIds : [0], \Zend_Db::INT_TYPE)
- ->where('type_id = ?', Type::TYPE_BUNDLE);
-
- $statement = $select->query();
- while ($id = $statement->fetchColumn()) {
- yield $id;
- }
- }
-
- /**
- * @inheritDoc
- */
- public function _resetState(): void
- {
- $this->websiteIdsOfProduct = [];
- }
-}
diff --git a/app/code/Magento/Bundle/Plugin/Catalog/Helper/Product.php b/app/code/Magento/Bundle/Plugin/Catalog/Helper/Product.php
deleted file mode 100644
index 0b090b2cbad7..000000000000
--- a/app/code/Magento/Bundle/Plugin/Catalog/Helper/Product.php
+++ /dev/null
@@ -1,82 +0,0 @@
-selectionProductsDisabledRequired = $selectionProductsDisabledRequired;
- $this->scopeConfig = $scopeConfig;
- $this->productRepository = $productRepository;
- }
-
- /**
- * Do not show bundle product when all products in required option are disabled
- *
- * @param Subject $subject
- * @param bool $result
- * @param ProductModel|int $product
- * @return bool
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
- */
- public function afterCanShow(Subject $subject, $result, $product)
- {
- if (is_int($product)) {
- $product = $this->productRepository->getById($product);
- }
- $productId = (int)$product->getEntityId();
- if ($result == false || $product->getTypeId() !== Type::TYPE_BUNDLE) {
- return $result;
- }
- $isShowOutOfStock = $this->scopeConfig->getValue(
- Configuration::XML_PATH_SHOW_OUT_OF_STOCK,
- ScopeInterface::SCOPE_STORE
- );
- if ($isShowOutOfStock) {
- return $result;
- }
- $productIdsDisabledRequired = $this->selectionProductsDisabledRequired->getChildProductIds($productId);
- return $productIdsDisabledRequired ? false : $result;
- }
-}
diff --git a/app/code/Magento/Bundle/etc/di.xml b/app/code/Magento/Bundle/etc/di.xml
index 7601224056be..3ddefc1a0559 100644
--- a/app/code/Magento/Bundle/etc/di.xml
+++ b/app/code/Magento/Bundle/etc/di.xml
@@ -277,13 +277,6 @@
-
-
-
- - Magento\Bundle\Model\ResourceModel\Indexer\Price\DisabledProductOptionPriceModifier
-
-
-
diff --git a/app/code/Magento/Bundle/etc/frontend/di.xml b/app/code/Magento/Bundle/etc/frontend/di.xml
index 411cf91cbc8b..54f5ff0a1f48 100644
--- a/app/code/Magento/Bundle/etc/frontend/di.xml
+++ b/app/code/Magento/Bundle/etc/frontend/di.xml
@@ -22,7 +22,4 @@
-
-
-
diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/DisabledProductOptionPostProcessor.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/DisabledProductOptionPostProcessor.php
deleted file mode 100644
index 8887fa14fd8c..000000000000
--- a/app/code/Magento/BundleGraphQl/Model/Resolver/Products/DataProvider/Product/DisabledProductOptionPostProcessor.php
+++ /dev/null
@@ -1,70 +0,0 @@
-selectionProductsDisabledRequired = $selectionProductsDisabledRequired;
- }
-
- /**
- * Remove bundle product from collection when all products in required option are disabled
- *
- * @param Collection $collection
- * @param array $attributeNames
- * @param ContextInterface|null $context
- * @return Collection
- * @throws \Magento\Framework\Exception\LocalizedException
- * @throws \Magento\Framework\Exception\NoSuchEntityException
- */
- public function process(
- Collection $collection,
- array $attributeNames,
- ?ContextInterface $context = null
- ): Collection {
- if (!$collection->isLoaded()) {
- $collection->load();
- }
- /** @var Product $product */
- foreach ($collection as $key => $product) {
- if ($product->getTypeId() !== Product\Type::TYPE_BUNDLE || $context === null) {
- continue;
- }
- $productId = (int)$product->getEntityId();
- $websiteId = (int)$context->getExtensionAttributes()->getStore()->getWebsiteId();
- $productIdsDisabledRequired = $this->selectionProductsDisabledRequired->getChildProductIds(
- $productId,
- $websiteId
- );
- if ($productIdsDisabledRequired) {
- $collection->removeItemByKey($key);
- }
- }
- return $collection;
- }
-}
diff --git a/app/code/Magento/BundleGraphQl/composer.json b/app/code/Magento/BundleGraphQl/composer.json
index e8cc6723f1f8..2f7605cc1098 100644
--- a/app/code/Magento/BundleGraphQl/composer.json
+++ b/app/code/Magento/BundleGraphQl/composer.json
@@ -6,7 +6,6 @@
"php": "~8.1.0||~8.2.0||~8.3.0",
"magento/module-catalog": "*",
"magento/module-bundle": "*",
- "magento/module-graph-ql": "*",
"magento/module-catalog-graph-ql": "*",
"magento/module-quote": "*",
"magento/module-quote-graph-ql": "*",
diff --git a/app/code/Magento/BundleGraphQl/etc/di.xml b/app/code/Magento/BundleGraphQl/etc/di.xml
index 879359839a64..15acad7c6bf0 100644
--- a/app/code/Magento/BundleGraphQl/etc/di.xml
+++ b/app/code/Magento/BundleGraphQl/etc/di.xml
@@ -23,11 +23,4 @@
-
-
-
- - Magento\BundleGraphQl\Model\Resolver\Products\DataProvider\Product\DisabledProductOptionPostProcessor
-
-
-
diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml
index 36decbcff089..b564ffa3e652 100644
--- a/app/code/Magento/Catalog/etc/db_schema.xml
+++ b/app/code/Magento/Catalog/etc/db_schema.xml
@@ -1645,6 +1645,11 @@
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/etc/db_schema_whitelist.json b/app/code/Magento/Catalog/etc/db_schema_whitelist.json
index fd332606bb22..4b6a247f5ff4 100644
--- a/app/code/Magento/Catalog/etc/db_schema_whitelist.json
+++ b/app/code/Magento/Catalog/etc/db_schema_whitelist.json
@@ -992,7 +992,8 @@
"index": {
"CATALOG_PRODUCT_INDEX_PRICE_TMP_CUSTOMER_GROUP_ID": true,
"CATALOG_PRODUCT_INDEX_PRICE_TMP_WEBSITE_ID": true,
- "CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE": true
+ "CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE": true,
+ "CAT_PRD_IDX_PRICE_TMP_ENTT_ID_CSTR_GROUP_ID_WS_ID": true
},
"constraint": {
"PRIMARY": true
diff --git a/app/code/Magento/Cms/Test/Fixture/Block.php b/app/code/Magento/Cms/Test/Fixture/Block.php
new file mode 100644
index 000000000000..2a3c4079504e
--- /dev/null
+++ b/app/code/Magento/Cms/Test/Fixture/Block.php
@@ -0,0 +1,69 @@
+ 'block%uniqid%',
+ BlockInterface::TITLE => 'Block%uniqid%',
+ BlockInterface::CONTENT => 'BlockContent%uniqid%',
+ BlockInterface::CREATION_TIME => null,
+ BlockInterface::UPDATE_TIME => null,
+ 'active' => true
+ ];
+
+ /**
+ * @param ProcessorInterface $dataProcessor
+ * @param ServiceFactory $serviceFactory
+ */
+ public function __construct(
+ private readonly ProcessorInterface $dataProcessor,
+ private readonly ServiceFactory $serviceFactory
+ ) {
+ }
+
+ /**
+ * {@inheritdoc}
+ * @param array $data Parameters. Same format as Block::DEFAULT_DATA.
+ */
+ public function apply(array $data = []): ?DataObject
+ {
+ $data = $this->dataProcessor->process($this, array_merge(self::DEFAULT_DATA, $data));
+ $service = $this->serviceFactory->create(BlockRepositoryInterface::class, 'save');
+
+ return $service->execute(['block' => $data]);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function revert(DataObject $data): void
+ {
+ $service = $this->serviceFactory->create(BlockRepositoryInterface::class, 'deleteById');
+ $service->execute(['blockId' => $data->getId()]);
+ }
+}
diff --git a/app/code/Magento/GraphQlCache/Model/Plugin/View/Layout.php b/app/code/Magento/GraphQlCache/Model/Plugin/View/Layout.php
new file mode 100644
index 000000000000..c2668a5d4d40
--- /dev/null
+++ b/app/code/Magento/GraphQlCache/Model/Plugin/View/Layout.php
@@ -0,0 +1,57 @@
+cacheableQuery->addCacheTags($block->getIdentities());
+ }
+ return $result;
+ }
+}
diff --git a/app/code/Magento/GraphQlCache/etc/graphql/di.xml b/app/code/Magento/GraphQlCache/etc/graphql/di.xml
index 1a85f02b5be9..f1a63cfb7be7 100644
--- a/app/code/Magento/GraphQlCache/etc/graphql/di.xml
+++ b/app/code/Magento/GraphQlCache/etc/graphql/di.xml
@@ -29,4 +29,7 @@
+
+
+
diff --git a/app/code/Magento/OpenSearch/Model/Adapter/DynamicTemplates/PriceMapper.php b/app/code/Magento/OpenSearch/Model/Adapter/DynamicTemplates/PriceMapper.php
index 03ced99cc632..545d8b95c006 100644
--- a/app/code/Magento/OpenSearch/Model/Adapter/DynamicTemplates/PriceMapper.php
+++ b/app/code/Magento/OpenSearch/Model/Adapter/DynamicTemplates/PriceMapper.php
@@ -19,7 +19,8 @@ public function processTemplates(array $templates): array
{
$templates[] = [
'price_mapping' => [
- 'match' => 'price_*',
+ "match_pattern" => "regex",
+ 'match' => 'price_\\d+_\\d+',
'match_mapping_type' => 'string',
'mapping' => [
'type' => 'double',
diff --git a/app/code/Magento/OpenSearch/Test/Unit/Model/OpenSearchTest.php b/app/code/Magento/OpenSearch/Test/Unit/Model/OpenSearchTest.php
index 5fa55dcab9ca..551b4ee98275 100644
--- a/app/code/Magento/OpenSearch/Test/Unit/Model/OpenSearchTest.php
+++ b/app/code/Magento/OpenSearch/Test/Unit/Model/OpenSearchTest.php
@@ -147,7 +147,8 @@ public function testAddFieldsMapping()
'dynamic_templates' => [
[
'price_mapping' => [
- 'match' => 'price_*',
+ "match_pattern" => "regex",
+ 'match' => 'price_\\d+_\\d+',
'match_mapping_type' => 'string',
'mapping' => [
'type' => 'double',
diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php
index 7270734e3ff4..380d2d7ca1c6 100644
--- a/app/code/Magento/Quote/Model/Quote.php
+++ b/app/code/Magento/Quote/Model/Quote.php
@@ -12,6 +12,7 @@
use Magento\Framework\Api\AttributeValueFactory;
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
use Magento\Framework\App\ObjectManager;
+use Magento\Framework\DataObject;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Model\AbstractExtensibleModel;
use Magento\Quote\Api\Data\PaymentInterface;
@@ -1619,7 +1620,7 @@ public function addItem(\Magento\Quote\Model\Quote\Item $item)
* Add product. Returns error message if product type instance can't prepare product.
*
* @param mixed $product
- * @param null|float|\Magento\Framework\DataObject $request
+ * @param null|float|DataObject $request
* @param null|string $processMode
* @return \Magento\Quote\Model\Quote\Item|string
* @throws \Magento\Framework\Exception\LocalizedException
@@ -1637,11 +1638,12 @@ public function addProduct(
if (is_numeric($request)) {
$request = $this->objectFactory->create(['qty' => $request]);
}
- if (!$request instanceof \Magento\Framework\DataObject) {
+ if (!$request instanceof DataObject) {
throw new \Magento\Framework\Exception\LocalizedException(
__('We found an invalid request for adding product to quote.')
);
}
+ $invalidProductAddFlag = $this->checkForInvalidProductAdd($request);
if (!$product->isSalable()) {
throw new \Magento\Framework\Exception\LocalizedException(
@@ -1699,7 +1701,9 @@ public function addProduct(
// collect errors instead of throwing first one
if ($item->getHasError()) {
- $this->deleteItem($item);
+ if (!$invalidProductAddFlag) {
+ $this->deleteItem($item);
+ }
foreach ($item->getMessage(false) as $message) {
if (!in_array($message, $errors)) {
// filter duplicate messages
@@ -1717,6 +1721,20 @@ public function addProduct(
return $parentItem;
}
+ /**
+ * Checks if invalid products should be added to quote
+ *
+ * @param DataObject $request
+ * @return bool
+ */
+ private function checkForInvalidProductAdd(DataObject $request): bool
+ {
+ $forceAdd = $request->getAddToCartInvalidProduct();
+ $request->unsetData('add_to_cart_invalid_product');
+
+ return (bool) $forceAdd;
+ }
+
/**
* Adding catalog product object data to quote
*
@@ -1772,8 +1790,8 @@ protected function _addCatalogProduct(\Magento\Catalog\Model\Product $product, $
* For more options see \Magento\Catalog\Helper\Product->addParamsToBuyRequest()
*
* @param int $itemId
- * @param \Magento\Framework\DataObject $buyRequest
- * @param null|array|\Magento\Framework\DataObject $params
+ * @param DataObject $buyRequest
+ * @param null|array|DataObject $params
* @return \Magento\Quote\Model\Quote\Item
* @throws \Magento\Framework\Exception\LocalizedException
*
@@ -1795,9 +1813,9 @@ public function updateItem($itemId, $buyRequest, $params = null)
$product = clone $this->productRepository->getById($productId, false, $this->getStore()->getId());
if (!$params) {
- $params = new \Magento\Framework\DataObject();
+ $params = new DataObject();
} elseif (is_array($params)) {
- $params = new \Magento\Framework\DataObject($params);
+ $params = new DataObject($params);
}
$params->setCurrentConfig($item->getBuyRequest());
$buyRequest = $this->_catalogProduct->addParamsToBuyRequest($buyRequest, $params);
@@ -2146,7 +2164,7 @@ protected function _clearErrorInfo()
* @param string|null $origin Usually a name of module, that embeds error
* @param int|null $code Error code, unique for origin, that sets it
* @param string|null $message Error message
- * @param \Magento\Framework\DataObject|null $additionalData Any additional data, that caller would like to store
+ * @param DataObject|null $additionalData Any additional data, that caller would like to store
* @return $this
*/
public function addErrorInfo(
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php
index b7571da30b9b..4698ab56dfbf 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php
@@ -30,6 +30,7 @@
use Magento\Framework\DataObject\Copy;
use Magento\Framework\DataObject\Factory;
use Magento\Framework\Event\Manager;
+use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Model\Context;
use Magento\Framework\Phrase;
@@ -1072,17 +1073,28 @@ public function testAddProductItemPreparation(): void
}
/**
+ * @param $request
+ * @param $hasError
* @return void
+ * @throws LocalizedException
+ * @dataProvider dataProviderForTestAddProductItem
*/
- public function testAddProductItemNew(): void
+ public function testAddProductItemNew($request, $hasError): void
{
- $itemMock = $this->createMock(Item::class);
+ $itemMock = $this->getMockBuilder(Item::class)
+ ->disableOriginalConstructor()
+ ->addMethods(['getHasError'])
+ ->onlyMethods(['representProduct', 'setProduct', 'setOptions', 'setQuote', 'getProduct'])
+ ->getMock();
+ $itemMock->expects($this->once())->method('getHasError')->willReturn($hasError);
+ $product = $this->createMock(Product::class);
+ $itemMock->expects($this->any())->method('getProduct')->willReturn($product);
$expectedResult = $itemMock;
$requestMock = $this->createMock(
DataObject::class
);
- $this->objectFactoryMock->expects($this->once())
+ $this->objectFactoryMock->expects($this->any())
->method('create')
->with(['qty' => 1])
->willReturn($requestMock);
@@ -1145,10 +1157,29 @@ public function testAddProductItemNew(): void
->method('getTypeInstance')
->willReturn($typeInstanceMock);
- $result = $this->quote->addProduct($this->productMock, null);
+ $result = $this->quote->addProduct($this->productMock, $request);
$this->assertEquals($expectedResult, $result);
}
+ /**
+ * @return array[]
+ */
+ public function dataProviderForTestAddProductItem(): array
+ {
+ return [
+ 'not_invalid_product_add' => [null, false],
+ 'invalid_product_add' => [
+ new DataObject(
+ [
+ 'add_to_cart_invalid_product' => true,
+ 'qty' => 1
+ ]
+ ),
+ true
+ ]
+ ];
+ }
+
/**
* @return void
*/
diff --git a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php
index 5eb485e26219..e4dc6b00204d 100644
--- a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php
+++ b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php
@@ -94,16 +94,6 @@ public function execute()
// to session for guest customer, as it does \Magento\Checkout\Model\Cart::save which is deprecated.
$this->checkoutSession->setQuoteId($reorderOutput->getCart()->getId());
- $errors = $reorderOutput->getErrors();
- if (!empty($errors)) {
- $useNotice = $this->_objectManager->get(\Magento\Checkout\Model\Session::class)->getUseNotice(true);
- foreach ($errors as $error) {
- $useNotice
- ? $this->messageManager->addNoticeMessage($error->getMessage())
- : $this->messageManager->addErrorMessage($error->getMessage());
- }
- }
-
return $resultRedirect->setPath('checkout/cart');
}
}
diff --git a/app/code/Magento/Sales/Model/Reorder/Reorder.php b/app/code/Magento/Sales/Model/Reorder/Reorder.php
index 9c89b73e8d25..27c2e280848a 100644
--- a/app/code/Magento/Sales/Model/Reorder/Reorder.php
+++ b/app/code/Magento/Sales/Model/Reorder/Reorder.php
@@ -111,6 +111,11 @@ class Reorder
*/
private $storeManager;
+ /**
+ * @var bool
+ */
+ private bool $addToCartInvalidProduct;
+
/**
* @param OrderFactory $orderFactory
* @param CustomerCartResolver $customerCartProvider
@@ -121,6 +126,9 @@ class Reorder
* @param ProductCollectionFactory $productCollectionFactory
* @param OrderInfoBuyRequestGetter $orderInfoBuyRequestGetter
* @param StoreManagerInterface|null $storeManager
+ * @param bool $addToCartInvalidProduct
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
OrderFactory $orderFactory,
@@ -131,7 +139,8 @@ public function __construct(
LoggerInterface $logger,
ProductCollectionFactory $productCollectionFactory,
OrderInfoBuyRequestGetter $orderInfoBuyRequestGetter,
- ?StoreManagerInterface $storeManager = null
+ ?StoreManagerInterface $storeManager = null,
+ bool $addToCartInvalidProduct = false
) {
$this->orderFactory = $orderFactory;
$this->cartRepository = $cartRepository;
@@ -143,6 +152,7 @@ public function __construct(
$this->orderInfoBuyRequestGetter = $orderInfoBuyRequestGetter;
$this->storeManager = $storeManager
?: ObjectManager::getInstance()->get(StoreManagerInterface::class);
+ $this->addToCartInvalidProduct = $addToCartInvalidProduct;
}
/**
@@ -276,6 +286,7 @@ private function addItemToCart(OrderItemInterface $orderItem, Quote $cart, Produ
$addProductResult = null;
try {
+ $infoBuyRequest->setAddToCartInvalidProduct($this->addToCartInvalidProduct);
$addProductResult = $cart->addProduct($product, $infoBuyRequest);
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$this->addError($this->getCartItemErrorMessage($orderItem, $product, $e->getMessage()));
diff --git a/app/code/Magento/Sales/etc/frontend/di.xml b/app/code/Magento/Sales/etc/frontend/di.xml
index b2d4a7d78a6e..695cf037d776 100644
--- a/app/code/Magento/Sales/etc/frontend/di.xml
+++ b/app/code/Magento/Sales/etc/frontend/di.xml
@@ -22,4 +22,9 @@
+
+
+ true
+
+
diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule.php
index 125e2194b45e..4ed17d7ef815 100644
--- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule.php
+++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule.php
@@ -305,18 +305,19 @@ public function getStoreLabel($ruleId, $storeId)
public function getActiveAttributes()
{
$connection = $this->getConnection();
+ $subSelect = $connection->select();
+ $subSelect->reset();
+ $subSelect->from($this->getTable('salesrule_product_attribute'))
+ ->group('attribute_id');
$select = $connection->select()->from(
- ['a' => $this->getTable('salesrule_product_attribute')],
- new \Zend_Db_Expr('DISTINCT ea.attribute_code')
+ ['a' => $subSelect],
+ new \Zend_Db_Expr('ea.attribute_code')
)->joinInner(
['ea' => $this->getTable('eav_attribute')],
'ea.attribute_id = a.attribute_id',
[]
- )->joinInner(
- ['sr' => $this->getTable('salesrule')],
- 'a.' . $this->getLinkField() . ' = sr.' . $this->getLinkField() . ' AND sr.is_active = 1',
- []
);
+
return $connection->fetchAll($select);
}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php
index cff69caa05a6..bec3402fe370 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/BundleProductViewTest.php
@@ -14,13 +14,15 @@
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Store\Test\Fixture\Group as GroupFixture;
+use Magento\Store\Test\Fixture\Store as StoreFixture;
+use Magento\Store\Test\Fixture\Website as WebsiteFixture;
use Magento\TestFramework\Fixture\DataFixture;
+use Magento\TestFramework\Fixture\DbIsolation;
use Magento\TestFramework\ObjectManager;
use Magento\TestFramework\TestCase\GraphQlAbstract;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus;
-use Magento\TestFramework\Fixture\DataFixtureStorage;
-use Magento\TestFramework\Fixture\DataFixtureStorageManager;
/**
* Test querying Bundle products
@@ -278,7 +280,7 @@ private function assertBundleProductOptions($product, $actualResponse)
'quantity' => (int)$bundleProductLink->getQty(),
'position' => $bundleProductLink->getPosition(),
'is_default' => (bool)$bundleProductLink->getIsDefault(),
- 'price_type' => self::KEY_PRICE_TYPE_FIXED,
+ 'price_type' => self::KEY_PRICE_TYPE_FIXED,
'can_change_quantity' => $bundleProductLink->getCanChangeQuantity()
]
);
@@ -443,9 +445,20 @@ public function testNonExistentFieldQtyExceptionOnBundleProduct()
$this->graphQlQuery($query);
}
- /**
- * @magentoApiDataFixture Magento/Bundle/_files/product_1.php
- */
+ #[
+ DbIsolation(false),
+ DataFixture(WebsiteFixture::class, as: 'website2'),
+ DataFixture(GroupFixture::class, ['website_id' => '$website2.id$'], 'group2'),
+ DataFixture(StoreFixture::class, ['store_group_id' => '$group2.id$', 'code' => 'store2'], 'store2'),
+ DataFixture(ProductFixture::class, ['sku' => 'p1', 'website_ids' => [1, '$website2.id$']], 'p1'),
+ DataFixture(ProductFixture::class, ['sku' => 'p2', 'website_ids' => [1, '$website2.id$']], 'p2'),
+ DataFixture(BundleOptionFixture::class, ['product_links' => ['$p1$']], 'opt1'),
+ DataFixture(BundleOptionFixture::class, ['product_links' => ['$p2$']], 'opt2'),
+ DataFixture(
+ BundleProductFixture::class,
+ ['sku' => 'bundle-product', '_options' => ['$opt1$', '$opt2$'], 'website_ids' => [1, '$website2.id$']]
+ ),
+ ]
public function testBundleProductWithDisabledProductOption()
{
/** @var StoreManagerInterface $storeManager */
@@ -453,7 +466,7 @@ public function testBundleProductWithDisabledProductOption()
$storeIdDefault = $storeManager->getDefaultStoreView()->getId();
/** @var ProductRepositoryInterface $productRepository */
$productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
- $simpleProduct = $productRepository->get('simple', false, $storeIdDefault, true);
+ $simpleProduct = $productRepository->get('p1', true, $storeIdDefault, true);
$simpleProduct->setStatus(ProductStatus::STATUS_DISABLED);
$simpleProduct->setStoreIds([$storeIdDefault]);
$productRepository->save($simpleProduct);
@@ -508,8 +521,11 @@ public function testBundleProductWithDisabledProductOption()
}
QUERY;
- $response = $this->graphQlQuery($query);
+ $response = $this->graphQlQuery($query, [], '', ['Store' => 'default']);
$this->assertEmpty($response['products']['items']);
+ $response = $this->graphQlQuery($query, [], '', ['Store' => 'store2']);
+ $this->assertNotEmpty($response['products']['items']);
+ $this->assertEquals($productSku, $response['products']['items'][0]['sku']);
}
#[
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php
index 93e6caebe2ba..46fa6de59467 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/PageCache/CacheTagTest.php
@@ -7,9 +7,19 @@
namespace Magento\GraphQl\PageCache;
+use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product;
+use Magento\Catalog\Test\Fixture\Category as CategoryFixture;
+use Magento\Cms\Model\BlockRepository;
+use Magento\Cms\Test\Fixture\Block as BlockFixture;
use Magento\GraphQlCache\Model\CacheId\CacheIdCalculator;
+use Magento\PageCache\Model\Config;
+use Magento\Store\Model\Store;
+use Magento\TestFramework\Fixture\Config as ConfigFixture;
+use Magento\TestFramework\Fixture\DataFixture;
+use Magento\TestFramework\Fixture\DataFixtureStorageManager;
+use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\ObjectManager;
/**
@@ -133,6 +143,140 @@ public function testCacheInvalidationForCategoriesWithProduct()
);
}
+ #[
+ ConfigFixture(Config::XML_PAGECACHE_TYPE, Config::VARNISH),
+ DataFixture(BlockFixture::class, ['content' => 'Original Block content'], as: 'block'),
+ DataFixture(CategoryFixture::class, as: 'category1'),
+ DataFixture(CategoryFixture::class, ['description' => 'Original Category description'], as: 'category2'),
+ ]
+ public function testCacheInvalidationForCategoriesWithWidget(): void
+ {
+ $fixtures = DataFixtureStorageManager::getStorage();
+ $block = $fixtures->get('block');
+ $category1 = $fixtures->get('category1');
+ $category2 = $fixtures->get('category2');
+ $queryForCategory1 = $this->getCategoriesQuery((int) $category1->getId());
+ $queryForCategory2 = $this->getCategoriesQuery((int) $category2->getId());
+
+ $this->updateCategoryDescription((int) $category1->getId(), $this->getBlockWidget((int) $block->getId()));
+
+ $responseCacheIdForCategory1 = $this->getQueryResponseCacheKey($queryForCategory1);
+ // Verify we get MISS for category1 query in the first request
+ $responseMissForCategory1 = $this->assertCacheMissAndReturnResponse(
+ $queryForCategory1,
+ [CacheIdCalculator::CACHE_ID_HEADER => $responseCacheIdForCategory1]
+ );
+
+ // Verify we get HIT for category 1 query in the second request
+ $responseHitForCategory1 = $this->assertCacheHitAndReturnResponse(
+ $queryForCategory1,
+ [CacheIdCalculator::CACHE_ID_HEADER => $responseCacheIdForCategory1]
+ );
+
+ $this->assertEquals($responseMissForCategory1['body'], $responseHitForCategory1['body']);
+
+ // Verify category1 description contains block content
+ $this->assertCategoryDescription('Original Block content', $responseHitForCategory1);
+
+ $responseCacheIdForCategory2 = $this->getQueryResponseCacheKey($queryForCategory2);
+ // Verify we get MISS for category2 query in the first request
+ $responseMissForCategory2 = $this->assertCacheMissAndReturnResponse(
+ $queryForCategory2,
+ [CacheIdCalculator::CACHE_ID_HEADER => $responseCacheIdForCategory2]
+ );
+
+ // Verify we get HIT for category 2 query in the second request
+ $responseHitForCategory2 = $this->assertCacheHitAndReturnResponse(
+ $queryForCategory2,
+ [CacheIdCalculator::CACHE_ID_HEADER => $responseCacheIdForCategory2]
+ );
+
+ $this->assertEquals($responseMissForCategory2['body'], $responseHitForCategory2['body']);
+
+ // Verify category2 description is the same as created
+ $this->assertCategoryDescription('Original Category description', $responseHitForCategory2);
+
+ // Update block content
+ $newBlockContent = 'New block content!!!';
+ $this->updateBlockContent((int) $block->getId(), $newBlockContent);
+
+ // Verify we get MISS for category1 query after block is updated
+ $this->assertCacheMissAndReturnResponse(
+ $queryForCategory1,
+ [CacheIdCalculator::CACHE_ID_HEADER => $responseCacheIdForCategory1]
+ );
+
+ // Verify we get HIT for category1 query in the second request after block is updated
+ $responseHitForCategory1 = $this->assertCacheHitAndReturnResponse(
+ $queryForCategory1,
+ [CacheIdCalculator::CACHE_ID_HEADER => $responseCacheIdForCategory1]
+ );
+
+ // Verify we get HIT for category2 query after block is updated
+ $responseHitForCategory2 = $this->assertCacheHitAndReturnResponse(
+ $queryForCategory2,
+ [CacheIdCalculator::CACHE_ID_HEADER => $responseCacheIdForCategory2]
+ );
+
+ // Verify the updated block data is returned in category1 query response
+ $this->assertCategoryDescription($newBlockContent, $responseHitForCategory1);
+
+ // Verify category2 description is the same as created
+ $this->assertCategoryDescription('Original Category description', $responseHitForCategory2);
+ }
+
+ private function assertCategoryDescription(string $expected, array $response): void
+ {
+ $responseBody = $response['body'];
+ $this->assertIsArray($responseBody);
+ $this->assertArrayNotHasKey('errors', $responseBody);
+ $this->assertStringContainsString($expected, $responseBody['categories']['items'][0]['description']);
+ }
+
+ private function getQueryResponseCacheKey(string $query): string
+ {
+ $response = $this->graphQlQueryWithResponseHeaders($query);
+ $this->assertArrayHasKey(CacheIdCalculator::CACHE_ID_HEADER, $response['headers']);
+ return $response['headers'][CacheIdCalculator::CACHE_ID_HEADER];
+ }
+
+ private function updateBlockContent(int $id, string $content): void
+ {
+ $blockRepository = Bootstrap::getObjectManager()->get(BlockRepository::class);
+ $block = $blockRepository->getById($id);
+ $block->setContent($content);
+ $blockRepository->save($block);
+ }
+
+ private function updateCategoryDescription(int $id, string $description): void
+ {
+ $categoryRepository = Bootstrap::getObjectManager()->get(CategoryRepositoryInterface::class);
+ $category = $categoryRepository->get($id, Store::DEFAULT_STORE_ID);
+ $category->setCustomAttribute('description', $description);
+ $categoryRepository->save($category);
+ }
+
+ private function getBlockWidget(int $blockId): string
+ {
+ return "{{widget type=\"Magento\\Cms\\Block\\Widget\\Block\" " .
+ "template=\"widget/static_block/default.phtml\" " .
+ "block_id=\"$blockId\" " .
+ "type_name=\"CMS Static Block\"}}";
+ }
+
+ private function getCategoriesQuery(int $categoryId): string
+ {
+ return <<get(ResourceConnection::class)->getConnection();
+ $indexes = $connection->getIndexList($tableName);
+ $this->assertArrayHasKey($indexName, $indexes);
+ $this->assertSame($columns, $indexes[$indexName]['COLUMNS_LIST']);
+ $this->assertSame($indexType, $indexes[$indexName]['INDEX_TYPE']);
+ }
+
+ /**
+ * @return array[]
+ */
+ public function indexDataProvider(): array
+ {
+ return [
+ [
+ 'catalog_product_index_price_tmp',
+ 'CAT_PRD_IDX_PRICE_TMP_ENTT_ID_CSTR_GROUP_ID_WS_ID',
+ ['entity_id', 'customer_group_id', 'website_id']
+ ]
+ ];
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Order/ReorderTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Order/ReorderTest.php
index 6a508e9a95ee..6e2015c5a241 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Order/ReorderTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Order/ReorderTest.php
@@ -108,13 +108,7 @@ public function testReorderProductLowQty(): void
$order = $this->orderFactory->create()->loadByIncrementId('55555555');
$this->customerSession->setCustomerId($order->getCustomerId());
$this->dispatchReorderRequest((int)$order->getId());
- $origMessage = (string)__('The requested qty is not available');
- $message = $this->escaper->escapeHtml(
- __('Could not add the product with SKU "%1" to the shopping cart: %2', 'simple-1', $origMessage)
- );
- $constraint = $this->logicalOr($this->containsEqual($origMessage), $this->containsEqual($message));
- $this->assertThat($this->getMessages(MessageInterface::TYPE_ERROR), $constraint);
- $this->quote = $this->checkoutSession->getQuote();
+ $this->assertRedirect($this->stringContains('checkout/cart'));
}
/**
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Order/ReorderWithDifferentStoreTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Order/ReorderWithDifferentStoreTest.php
index 33d86189aa4f..0e9f60719df9 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Order/ReorderWithDifferentStoreTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Order/ReorderWithDifferentStoreTest.php
@@ -117,7 +117,7 @@ public function testReorderWithDifferentStoreAndGlobalCustomerAccount(): void
$this->dispatch('sales/order/reorder/');
$this->assertRedirect($this->stringContains('checkout/cart'));
$this->quote = $this->checkoutSession->getQuote();
- $quoteItemsCollection = $this->quote->getAllItems();
- $this->assertCount(0, $quoteItemsCollection);
+
+ $this->assertCount(1, $this->quote->getErrors());
}
}
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/RuleTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/RuleTest.php
index 1299c5fca09f..f2ec3bbb5449 100644
--- a/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/RuleTest.php
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/RuleTest.php
@@ -72,8 +72,6 @@ public function testAfterSave()
public function testGetActiveAttributes()
{
$rule = $this->fixtures->get('rule1');
- $items = $this->resource->getActiveAttributes();
- $this->assertEquals([], $items);
$rule->setIsActive(1);
$rule->save();
$items = $this->resource->getActiveAttributes();
diff --git a/lib/internal/Magento/Framework/Mview/Test/Unit/View/ChangelogBatchWalkerTest.php b/lib/internal/Magento/Framework/Mview/Test/Unit/View/ChangelogBatchWalkerTest.php
new file mode 100644
index 000000000000..afbe2cf33e05
--- /dev/null
+++ b/lib/internal/Magento/Framework/Mview/Test/Unit/View/ChangelogBatchWalkerTest.php
@@ -0,0 +1,174 @@
+resourceConnection = $this->getMockBuilder(ResourceConnection::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->generator = $this->getMockBuilder(Generator::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->idsTableBuilder = $this->getMockBuilder(IdsTableBuilderInterface::class)
+ ->getMockForAbstractClass();
+ $this->idsSelectBuilder = $this->getMockBuilder(IdsSelectBuilderInterface::class)
+ ->getMockForAbstractClass();
+ $this->idsContext = $this->getMockBuilder(IdsContext::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->idsContext->expects($this->any())
+ ->method('getSelectBuilder')
+ ->willReturn($this->idsSelectBuilder);
+ $this->idsContext->expects($this->any())
+ ->method('getTableBuilder')
+ ->willReturn($this->idsTableBuilder);
+
+ $this->changeLog = $this->getMockBuilder(ChangelogInterface::class)
+ ->getMockForAbstractClass();
+ $this->connection = $this->getMockBuilder(AdapterInterface::class)
+ ->getMockForAbstractClass();
+ $this->table = $this->getMockBuilder(Table::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->resourceConnection->expects($this->any())
+ ->method('getConnection')
+ ->willReturn($this->connection);
+
+ $this->select = $this->getMockBuilder(Select::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->select->expects($this->any())
+ ->method('from')
+ ->willReturnSelf();
+ $this->select->expects($this->any())
+ ->method('where')
+ ->willReturnSelf();
+ $this->select->expects($this->any())
+ ->method('distinct')
+ ->willReturnSelf();
+ $this->connection->expects($this->any())
+ ->method('select')
+ ->willReturn($this->select);
+
+ $this->model = new ChangelogBatchWalker(
+ $this->resourceConnection,
+ $this->generator,
+ $this->idsContext
+ );
+ }
+
+ public function testNoTemporaryTablesUsed()
+ {
+ $this->connection->expects($this->once())
+ ->method('isTableExists')
+ ->willReturn(true);
+ $this->table->expects($this->any())
+ ->method('getColumns')
+ ->willReturn([]);
+ $this->idsTableBuilder->expects($this->any())
+ ->method('build')
+ ->willReturn($this->table);
+ $this->idsSelectBuilder->expects($this->any())
+ ->method('build')
+ ->willReturn($this->select);
+ $this->generator->expects($this->any())
+ ->method('generate')
+ ->willReturn([]);
+
+ foreach ($this->model->walk($this->changeLog, 1, 2, 1) as $iteration) {
+ $this->assertEmpty($iteration);
+ $this->connection->expects($this->once())
+ ->method('createTable');
+ $this->connection->expects($this->never())
+ ->method('createTemporaryTableTable');
+ }
+ }
+}
diff --git a/lib/internal/Magento/Framework/Mview/View/ChangelogBatchWalker.php b/lib/internal/Magento/Framework/Mview/View/ChangelogBatchWalker.php
index 61956b0cd3ae..474c687a1381 100644
--- a/lib/internal/Magento/Framework/Mview/View/ChangelogBatchWalker.php
+++ b/lib/internal/Magento/Framework/Mview/View/ChangelogBatchWalker.php
@@ -24,30 +24,34 @@
class ChangelogBatchWalker implements ChangelogBatchWalkerInterface
{
/**
- * @var \Magento\Framework\App\ResourceConnection
+ * @var ResourceConnection
*/
private ResourceConnection $resourceConnection;
+
/**
- * @var \Magento\Framework\DB\Query\Generator
+ * @var Generator
*/
private Generator $generator;
+
/**
- * @var \Magento\Framework\Mview\View\ChangelogBatchWalker\IdsTableBuilderInterface
+ * @var IdsTableBuilderInterface
*/
private IdsTableBuilderInterface $idsTableBuilder;
+
/**
- * @var \Magento\Framework\Mview\View\ChangelogBatchWalker\IdsSelectBuilderInterface
+ * @var IdsSelectBuilderInterface
*/
private IdsSelectBuilderInterface $idsSelectBuilder;
+
/**
- * @var \Magento\Framework\Mview\View\ChangelogBatchWalker\IdsFetcherInterface
+ * @var IdsFetcherInterface
*/
private IdsFetcherInterface $idsFetcher;
/**
* @param ResourceConnection $resourceConnection
- * @param \Magento\Framework\DB\Query\Generator $generator
- * @param \Magento\Framework\Mview\View\ChangelogBatchWalker\IdsContext $idsContext
+ * @param Generator $generator
+ * @param IdsContext $idsContext
*/
public function __construct(
ResourceConnection $resourceConnection,
@@ -80,7 +84,7 @@ public function walk(
$idsTable = $this->idsTableBuilder->build($changelog);
try {
- $connection->createTemporaryTable($idsTable);
+ $connection->createTable($idsTable);
$columns = $this->getIdsColumns($idsTable);
@@ -122,7 +126,7 @@ public function walk(
yield $ids;
}
} finally {
- $connection->dropTemporaryTable($idsTable->getName());
+ $connection->dropTable($idsTable->getName());
}
}
diff --git a/lib/internal/Magento/Framework/Mview/View/ChangelogBatchWalker/IdsTableBuilder.php b/lib/internal/Magento/Framework/Mview/View/ChangelogBatchWalker/IdsTableBuilder.php
index 69b1527fe661..fe0753144dca 100644
--- a/lib/internal/Magento/Framework/Mview/View/ChangelogBatchWalker/IdsTableBuilder.php
+++ b/lib/internal/Magento/Framework/Mview/View/ChangelogBatchWalker/IdsTableBuilder.php
@@ -50,7 +50,6 @@ public function build(ChangelogInterface $changelog): Table
['unsigned' => true, 'nullable' => false],
'Entity ID'
);
- $table->setOption('type', 'memory');
$table->addIndex(
self::INDEX_NAME_UNIQUE,
[
diff --git a/lib/internal/Magento/Framework/Test/Unit/Mview/View/ChangelogBatchWalker/IdsTableBuilderTest.php b/lib/internal/Magento/Framework/Test/Unit/Mview/View/ChangelogBatchWalker/IdsTableBuilderTest.php
new file mode 100644
index 000000000000..a46cab3dc2cc
--- /dev/null
+++ b/lib/internal/Magento/Framework/Test/Unit/Mview/View/ChangelogBatchWalker/IdsTableBuilderTest.php
@@ -0,0 +1,87 @@
+changeLog = $this->getMockBuilder(ChangelogInterface::class)
+ ->getMockForAbstractClass();
+ $this->connection = $this->getMockBuilder(AdapterInterface::class)
+ ->getMockForAbstractClass();
+ $this->table = $this->getMockBuilder(Table::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->resourceConnection = $this->getMockBuilder(ResourceConnection::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->resourceConnection->expects($this->any())
+ ->method('getConnection')
+ ->willReturn($this->connection);
+ $this->connection->expects($this->any())
+ ->method('newTable')
+ ->willReturn($this->table);
+
+ $this->model = new IdsTableBuilder($this->resourceConnection);
+ }
+
+ public function testBuildDoNotCreateMemoryTable() : void
+ {
+ $this->table->expects($this->never())
+ ->method('setOption')
+ ->with('type', 'memory');
+
+ $this->model->build($this->changeLog);
+ }
+}