diff --git a/app/code/Magento/Backend/Model/Auth/Session.php b/app/code/Magento/Backend/Model/Auth/Session.php
index e65caf13f2ea3..ec813472695d7 100644
--- a/app/code/Magento/Backend/Model/Auth/Session.php
+++ b/app/code/Magento/Backend/Model/Auth/Session.php
@@ -114,6 +114,16 @@ public function __construct(
);
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->_isFirstAfterLogin = null;
+ $this->acl = null;
+ }
+
/**
* Refresh ACL resources stored in session
*
diff --git a/app/code/Magento/Backend/Model/Session/Quote.php b/app/code/Magento/Backend/Model/Session/Quote.php
index ed0312874565c..b3067d3c98851 100644
--- a/app/code/Magento/Backend/Model/Session/Quote.php
+++ b/app/code/Magento/Backend/Model/Session/Quote.php
@@ -139,6 +139,17 @@ public function __construct(
}
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->_quote = null;
+ $this->_store = null;
+ $this->_order = null;
+ }
+
/**
* Retrieve quote model object
*
@@ -154,7 +165,7 @@ public function getQuote()
$this->_quote->setCustomerGroupId($customerGroupId);
$this->_quote->setIsActive(false);
$this->_quote->setStoreId($this->getStoreId());
-
+
$this->quoteRepository->save($this->_quote);
$this->setQuoteId($this->_quote->getId());
$this->_quote = $this->quoteRepository->get($this->getQuoteId(), [$this->getStoreId()]);
diff --git a/app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml b/app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml
index 41c8812e7b1e0..268ff07850f43 100644
--- a/app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml
+++ b/app/code/Magento/Backend/Test/Mftf/Section/LocaleOptionsSection.xml
@@ -18,5 +18,8 @@
+
+
+
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Download.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Download.php
index 864e5f4b37721..252ca89ae411b 100644
--- a/app/code/Magento/Backup/Controller/Adminhtml/Index/Download.php
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Download.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Backup\Controller\Adminhtml\Index;
+use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
-class Download extends \Magento\Backup\Controller\Adminhtml\Index
+class Download extends \Magento\Backup\Controller\Adminhtml\Index implements HttpGetActionInterface
{
/**
* @var \Magento\Framework\Controller\Result\RawFactory
@@ -66,17 +67,12 @@ public function execute()
$fileName = $this->_objectManager->get(\Magento\Backup\Helper\Data::class)->generateBackupDownloadName($backup);
- $this->_fileFactory->create(
+ return $this->_fileFactory->create(
$fileName,
- null,
+ ['type' => 'filename', 'value' => $backup->getPath() . DIRECTORY_SEPARATOR . $backup->getFileName()],
DirectoryList::VAR_DIR,
'application/octet-stream',
$backup->getSize()
);
-
- /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
- $resultRaw = $this->resultRawFactory->create();
- $resultRaw->setContents($backup->output());
- return $resultRaw;
}
}
diff --git a/app/code/Magento/Backup/Test/Unit/Controller/Adminhtml/Index/DownloadTest.php b/app/code/Magento/Backup/Test/Unit/Controller/Adminhtml/Index/DownloadTest.php
index 4ae20c711327f..b9c6b67cf1bc7 100644
--- a/app/code/Magento/Backup/Test/Unit/Controller/Adminhtml/Index/DownloadTest.php
+++ b/app/code/Magento/Backup/Test/Unit/Controller/Adminhtml/Index/DownloadTest.php
@@ -115,7 +115,7 @@ protected function setUp(): void
->getMock();
$this->backupModelMock = $this->getMockBuilder(Backup::class)
->disableOriginalConstructor()
- ->setMethods(['getTime', 'exists', 'getSize', 'output'])
+ ->setMethods(['getTime', 'exists', 'getSize', 'output', 'getPath', 'getFileName'])
->getMock();
$this->dataHelperMock = $this->getMockBuilder(Data::class)
->disableOriginalConstructor()
@@ -169,8 +169,13 @@ public function testExecuteBackupFound()
$type = 'db';
$filename = 'filename';
$size = 10;
- $output = 'test';
-
+ $path = 'testpath';
+ $this->backupModelMock->expects($this->atLeastOnce())
+ ->method('getPath')
+ ->willReturn($path);
+ $this->backupModelMock->expects($this->atLeastOnce())
+ ->method('getFileName')
+ ->willReturn($filename);
$this->backupModelMock->expects($this->atLeastOnce())
->method('getTime')
->willReturn($time);
@@ -180,9 +185,6 @@ public function testExecuteBackupFound()
$this->backupModelMock->expects($this->atLeastOnce())
->method('getSize')
->willReturn($size);
- $this->backupModelMock->expects($this->atLeastOnce())
- ->method('output')
- ->willReturn($output);
$this->requestMock->expects($this->any())
->method('getParam')
->willReturnMap(
@@ -206,20 +208,14 @@ public function testExecuteBackupFound()
$this->fileFactoryMock->expects($this->once())
->method('create')->with(
$filename,
- null,
+ ['type' => 'filename', 'value' => $path . '/' . $filename],
DirectoryList::VAR_DIR,
'application/octet-stream',
$size
)
->willReturn($this->responseMock);
- $this->resultRawMock->expects($this->once())
- ->method('setContents')
- ->with($output);
- $this->resultRawFactoryMock->expects($this->once())
- ->method('create')
- ->willReturn($this->resultRawMock);
- $this->assertSame($this->resultRawMock, $this->downloadController->execute());
+ $this->assertSame($this->responseMock, $this->downloadController->execute());
}
/**
diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php b/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php
index 303c33b571d35..04f4305bdf77d 100644
--- a/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php
+++ b/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php
@@ -128,7 +128,6 @@ public function __construct(
$metadataPool,
$tableMaintainer
);
-
$this->stockItem = $stockItem
?? ObjectManager::getInstance()->get(\Magento\CatalogInventory\Model\ResourceModel\Stock\Item::class);
}
@@ -145,6 +144,17 @@ protected function _construct()
$this->_selectionTable = $this->getTable('catalog_product_bundle_selection');
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->itemPrototype = null;
+ $this->catalogRuleProcessor = null;
+ $this->websiteScopePriceJoined = false;
+ }
+
/**
* Set store id for each collection item when collection was loaded.
* phpcs:disable Generic.CodeAnalysis.UselessOverridingMethod
@@ -355,8 +365,6 @@ public function addPriceFilter($product, $searchMin, $useRegularPrice = false)
* Get Catalog Rule Processor.
*
* @return \Magento\CatalogRule\Model\ResourceModel\Product\CollectionProcessor
- *
- * @deprecated 100.2.0
*/
private function getCatalogRuleProcessor()
{
diff --git a/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml b/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml
index 912e637dc534e..4ab4ec7f055f9 100644
--- a/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml
+++ b/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml
@@ -21,6 +21,7 @@
+
20
@@ -62,6 +63,7 @@
+
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php
index 0b1ef98c386c4..ea14dbc1ce627 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php
@@ -4,18 +4,21 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Catalog\Controller\Adminhtml\Product;
-use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
-use Magento\Backend\App\Action;
use Magento\Catalog\Controller\Adminhtml\Product;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Framework\App\ObjectManager;
+use Magento\Framework\RegexValidator;
class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product implements HttpGetActionInterface
{
/**
* @var Initialization\StockDataFilter
* @deprecated 101.0.0
+ * @see Initialization\StockDataFilter
*/
protected $stockFilter;
@@ -30,23 +33,32 @@ class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product implements
protected $resultForwardFactory;
/**
- * @param Action\Context $context
+ * @var RegexValidator
+ */
+ private RegexValidator $regexValidator;
+
+ /**
+ * @param Context $context
* @param Builder $productBuilder
* @param Initialization\StockDataFilter $stockFilter
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
* @param \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory
+ * @param RegexValidator|null $regexValidator
*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
Product\Builder $productBuilder,
Initialization\StockDataFilter $stockFilter,
\Magento\Framework\View\Result\PageFactory $resultPageFactory,
- \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory
+ \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory,
+ RegexValidator $regexValidator = null
) {
$this->stockFilter = $stockFilter;
parent::__construct($context, $productBuilder);
$this->resultPageFactory = $resultPageFactory;
$this->resultForwardFactory = $resultForwardFactory;
+ $this->regexValidator = $regexValidator
+ ?: ObjectManager::getInstance()->get(RegexValidator::class);
}
/**
@@ -56,6 +68,11 @@ public function __construct(
*/
public function execute()
{
+ $typeId = $this->getRequest()->getParam('type');
+ if (!$this->regexValidator->validateParamRegex($typeId)) {
+ return $this->resultForwardFactory->create()->forward('noroute');
+ }
+
if (!$this->getRequest()->getParam('set')) {
return $this->resultForwardFactory->create()->forward('noroute');
}
diff --git a/app/code/Magento/Catalog/Model/Layer/Resolver.php b/app/code/Magento/Catalog/Model/Layer/Resolver.php
index a4224aeafe7e0..b6ca16f1ac029 100644
--- a/app/code/Magento/Catalog/Model/Layer/Resolver.php
+++ b/app/code/Magento/Catalog/Model/Layer/Resolver.php
@@ -9,15 +9,17 @@
namespace Magento\Catalog\Model\Layer;
+use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
+
/**
* Layer Resolver
*
* @api
*/
-class Resolver
+class Resolver implements ResetAfterRequestInterface
{
- const CATALOG_LAYER_CATEGORY = 'category';
- const CATALOG_LAYER_SEARCH = 'search';
+ public const CATALOG_LAYER_CATEGORY = 'category';
+ public const CATALOG_LAYER_SEARCH = 'search';
/**
* Catalog view layer models list
@@ -79,4 +81,12 @@ public function get()
}
return $this->layer;
}
+
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ $this->layer = null;
+ }
}
diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php
index 4034c75f7373c..85a69a9e69be0 100644
--- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php
+++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php
@@ -6,6 +6,7 @@
namespace Magento\Catalog\Model\Product\Gallery;
+use Magento\AwsS3\Driver\AwsS3;
use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface;
use Magento\Catalog\Api\Data\ProductInterfaceFactory;
use Magento\Catalog\Api\ProductRepositoryInterface;
@@ -287,10 +288,18 @@ private function getImageContent($product, $entry): ImageContentInterface
$mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$path = $mediaDirectory->getAbsolutePath($product->getMediaConfig()->getMediaPath($entry->getFile()));
$fileName = $this->file->getPathInfo($path)['basename'];
- $imageFileContent = $mediaDirectory->getDriver()->fileGetContents($path);
+ $fileDriver = $mediaDirectory->getDriver();
+ $imageFileContent = $fileDriver->fileGetContents($path);
+
+ if ($fileDriver instanceof AwsS3) {
+ $remoteMediaMimeType = $fileDriver->getMetadata($path);
+ $mediaMimeType = $remoteMediaMimeType['mimetype'];
+ } else {
+ $mediaMimeType = $this->mime->getMimeType($path);
+ }
return $this->imageContentInterface->create()
->setName($fileName)
->setBase64EncodedData(base64_encode($imageFileContent))
- ->setType($this->mime->getMimeType($path));
+ ->setType($mediaMimeType);
}
}
diff --git a/app/code/Magento/Catalog/Model/Product/Media/Config.php b/app/code/Magento/Catalog/Model/Product/Media/Config.php
index 25c05dad46817..99c2513f5187a 100644
--- a/app/code/Magento/Catalog/Model/Product/Media/Config.php
+++ b/app/code/Magento/Catalog/Model/Product/Media/Config.php
@@ -30,7 +30,7 @@ class Config implements ConfigInterface, ResetAfterRequestInterface
private $attributeHelper;
/**
- * @var string[]
+ * @var string[]|null
*/
private $mediaAttributeCodes;
@@ -206,6 +206,6 @@ private function getAttributeHelper()
*/
public function _resetState(): void
{
- $this->mediaAttributeCodes = [];
+ $this->mediaAttributeCodes = null;
}
}
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php
index 56fb7290b81a6..9df0a3a9b3831 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php
@@ -137,6 +137,18 @@ protected function _construct()
$this->_init(Category::class, \Magento\Catalog\Model\ResourceModel\Category::class);
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->_productTable = null;
+ $this->_productStoreId = null;
+ $this->_productWebsiteTable = null;
+ $this->_loadWithProductCount = false;
+ }
+
/**
* Add Id filter
*
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php b/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php
index a121648b7acba..89dacf5361a69 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php
@@ -76,6 +76,15 @@ public function __construct(
);
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->_storeId = null;
+ }
+
/**
* Retrieve Entity Primary Key
*
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php
index 79636c55c0f56..6756aac0786a9 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php
@@ -102,6 +102,11 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac
*/
protected $_productLimitationFilters;
+ /**
+ * @var ProductLimitationFactory
+ */
+ private $productLimitationFactory;
+
/**
* Category product count select
*
@@ -354,10 +359,10 @@ public function __construct(
$this->_resourceHelper = $resourceHelper;
$this->dateTime = $dateTime;
$this->_groupManagement = $groupManagement;
- $productLimitationFactory = $productLimitationFactory ?: ObjectManager::getInstance()->get(
+ $this->productLimitationFactory = $productLimitationFactory ?: ObjectManager::getInstance()->get(
\Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory::class
);
- $this->_productLimitationFilters = $productLimitationFactory->create();
+ $this->_productLimitationFilters = $this->productLimitationFactory->create();
$this->metadataPool = $metadataPool ?: ObjectManager::getInstance()->get(MetadataPool::class);
parent::__construct(
$entityFactory,
@@ -387,6 +392,36 @@ public function __construct(
->get(Gallery::class);
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->_flatEnabled = [];
+ $this->_addUrlRewrite = false;
+ $this->_urlRewriteCategory = '';
+ $this->_addFinalPrice = false;
+ $this->_allIdsCache = null;
+ $this->_addTaxPercents = false;
+ $this->_productLimitationFilters = $this->productLimitationFactory->create();
+ $this->_productCountSelect = null;
+ $this->_isWebsiteFilter = false;
+ $this->_priceDataFieldFilters = [];
+ $this->_priceExpression = null;
+ $this->_additionalPriceExpression = null;
+ $this->_maxPrice = null;
+ $this->_minPrice = null;
+ $this->_priceStandardDeviation = null;
+ $this->_pricesCount = null;
+ $this->_catalogPreparePriceSelect = null;
+ $this->needToAddWebsiteNamesToResult = null;
+ $this->linkField = null;
+ $this->backend = null;
+ $this->emptyItem = null;
+ $this->_construct();
+ }
+
/**
* Get cloned Select after dispatching 'catalog_prepare_price_select' event
*
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php
index 76f566a364769..7100f20ecd96f 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php
@@ -46,15 +46,11 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
protected $_comparableAttributes;
/**
- * Catalog product compare
- *
* @var \Magento\Catalog\Helper\Product\Compare
*/
protected $_catalogProductCompare = null;
/**
- * Catalog product compare item
- *
* @var \Magento\Catalog\Model\ResourceModel\Product\Compare\Item
*/
protected $_catalogProductCompareItem;
@@ -150,6 +146,18 @@ protected function _construct()
$this->_initTables();
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->_customerId = 0;
+ $this->_visitorId = 0;
+ $this->listId = 0;
+ $this->_comparableAttributes = null;
+ }
+
/**
* Set customer filter to collection
*
@@ -287,7 +295,6 @@ public function getProductsByListId(int $listId): array
return $this->getConnection()->fetchCol($select);
}
-
/**
* Set list_id for customer compare item
*
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Link/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Link/Product/Collection.php
index bca919e700364..cac549e0a17c9 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Link/Product/Collection.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Link/Product/Collection.php
@@ -183,6 +183,21 @@ public function __construct(
}
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->_product = null;
+ $this->_linkModel = null;
+ $this->_linkTypeId = null;
+ $this->_isStrongMode = null;
+ $this->_hasLinkFilter = false;
+ $this->productIds = null;
+ $this->linkField = null;
+ }
+
/**
* Declare link model and initialize type attributes join
*
diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminDeleteCreatedColorSpecificAttributeActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminDeleteCreatedColorSpecificAttributeActionGroup.xml
new file mode 100644
index 0000000000000..2907f88446ec2
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminDeleteCreatedColorSpecificAttributeActionGroup.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ Delete the created new colors in color attribute
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeGridSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeGridSection.xml
index 455cde4c1d70c..8e2877b47b64a 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeGridSection.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductAttributeGridSection.xml
@@ -24,6 +24,7 @@
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection/AdminProductFormSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection/AdminProductFormSection.xml
index 0a3c67bc00d5b..f0a1b0f2e9452 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection/AdminProductFormSection.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection/AdminProductFormSection.xml
@@ -83,5 +83,9 @@
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection/StorefrontCategorySidebarSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection/StorefrontCategorySidebarSection.xml
index 26a5452ee018c..6edef36fd98f4 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection/StorefrontCategorySidebarSection.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection/StorefrontCategorySidebarSection.xml
@@ -27,5 +27,9 @@
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductInfoMainSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductInfoMainSection.xml
index 5ec949332a36b..370487075c3c0 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductInfoMainSection.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductInfoMainSection.xml
@@ -30,6 +30,7 @@
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AddNewProductAttributeInProductPageTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AddNewProductAttributeInProductPageTest.xml
index 38fc09c9cafb7..1aaa26d893fcb 100755
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AddNewProductAttributeInProductPageTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AddNewProductAttributeInProductPageTest.xml
@@ -22,6 +22,7 @@
+
@@ -99,11 +100,11 @@
-
+
+
-
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml
index 3b0fad592fed8..7a10c0e949e31 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml
@@ -18,13 +18,16 @@
+
+
+
+
-
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontVerifyCategoryPageNotCachedTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontVerifyCategoryPageNotCachedTest.xml
new file mode 100644
index 0000000000000..6c79b40b3ff94
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontVerifyCategoryPageNotCachedTest.xml
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 100
+
+
+
+ 200
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php
old mode 100644
new mode 100755
index 974c85b2b5c98..cad43f39f0261
--- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php
@@ -16,6 +16,9 @@
use Magento\Catalog\Controller\Adminhtml\Product\NewAction;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Test\Unit\Controller\Adminhtml\ProductTest;
+use Magento\Framework\RegexValidator;
+use Magento\Framework\Validator\Regex;
+use Magento\Framework\Validator\RegexFactory;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Framework\View\Result\PageFactory;
use PHPUnit\Framework\MockObject\MockObject;
@@ -42,6 +45,26 @@ class NewActionTest extends ProductTest
*/
protected $initializationHelper;
+ /**
+ * @var RegexValidator|MockObject
+ */
+ private $regexValidator;
+
+ /**
+ * @var RegexFactory
+ */
+ private $regexValidatorFactoryMock;
+
+ /**
+ * @var Regex|MockObject
+ */
+ private $regexValidatorMock;
+
+ /**
+ * @var ForwardFactory&MockObject|MockObject
+ */
+ private $resultForwardFactory;
+
protected function setUp(): void
{
$this->productBuilder = $this->createPartialMock(
@@ -63,37 +86,78 @@ protected function setUp(): void
->disableOriginalConstructor()
->setMethods(['create'])
->getMock();
- $resultPageFactory->expects($this->atLeastOnce())
- ->method('create')
- ->willReturn($this->resultPage);
$this->resultForward = $this->getMockBuilder(Forward::class)
->disableOriginalConstructor()
->getMock();
- $resultForwardFactory = $this->getMockBuilder(ForwardFactory::class)
+ $this->resultForwardFactory = $this->getMockBuilder(ForwardFactory::class)
+ ->disableOriginalConstructor()
+ ->onlyMethods(['create'])
+ ->getMock();
+
+ $this->regexValidatorFactoryMock = $this->getMockBuilder(RegexFactory::class)
->disableOriginalConstructor()
->setMethods(['create'])
->getMock();
- $resultForwardFactory->expects($this->any())
- ->method('create')
- ->willReturn($this->resultForward);
+ $this->regexValidatorMock = $this->createMock(Regex::class);
+ $this->regexValidatorFactoryMock->method('create')
+ ->willReturn($this->regexValidatorMock);
+ $this->regexValidator = new regexValidator($this->regexValidatorFactoryMock);
$this->action = (new ObjectManager($this))->getObject(
NewAction::class,
[
'context' => $this->initContext(),
'productBuilder' => $this->productBuilder,
'resultPageFactory' => $resultPageFactory,
- 'resultForwardFactory' => $resultForwardFactory,
+ 'resultForwardFactory' => $this->resultForwardFactory,
+ 'regexValidator' => $this->regexValidator,
]
);
}
- public function testExecute()
+ /**
+ * Test execute method input validation.
+ *
+ * @param string $value
+ * @param bool $exceptionThrown
+ * @dataProvider validationCases
+ */
+ public function testExecute(string $value, bool $exceptionThrown): void
+ {
+ if ($exceptionThrown) {
+ $this->action->getRequest()->expects($this->any())
+ ->method('getParam')
+ ->willReturn($value);
+ $this->resultForwardFactory->expects($this->any())
+ ->method('create')
+ ->willReturn($this->resultForward);
+ $this->resultForward->expects($this->once())
+ ->method('forward')
+ ->with('noroute')
+ ->willReturn(true);
+ $this->assertTrue($this->action->execute());
+ } else {
+ $this->action->getRequest()->expects($this->any())->method('getParam')->willReturn($value);
+ $this->regexValidatorMock->expects($this->any())
+ ->method('isValid')
+ ->with($value)
+ ->willReturn(true);
+
+ $this->assertEquals(true, $this->regexValidator->validateParamRegex($value));
+ }
+ }
+
+ /**
+ * Validation cases.
+ *
+ * @return array
+ */
+ public function validationCases(): array
{
- $this->action->getRequest()->expects($this->any())->method('getParam')->willReturn(true);
- $this->action->getRequest()->expects($this->any())->method('getFullActionName')
- ->willReturn('catalog_product_new');
- $this->action->execute();
+ return [
+ 'execute-with-exception' => ['simple\' and true()]|*[self%3a%3ahandle%20or%20self%3a%3alayout',true],
+ 'execute-without-exception' => ['catalog_product_new',false]
+ ];
}
}
diff --git a/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php b/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
index 2b98e35b52de1..eadf47601585d 100644
--- a/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php
@@ -15,8 +15,11 @@
use Magento\Catalog\Pricing\Render\FinalPriceBox;
use Magento\Framework\App\Cache\StateInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\App\DeploymentConfig;
use Magento\Framework\App\State;
+use Magento\Framework\Config\ConfigOptionsListConstants;
use Magento\Framework\Event\Test\Unit\ManagerStub;
+use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\Pricing\Amount\AmountInterface;
use Magento\Framework\Pricing\Price\PriceInterface;
use Magento\Framework\Pricing\PriceInfoInterface;
@@ -96,11 +99,27 @@ class FinalPriceBoxTest extends TestCase
*/
private $minimalPriceCalculator;
+ /**
+ * @var DeploymentConfig|MockObject
+ */
+ private $deploymentConfig;
+
+ /**
+ * @var ObjectManagerInterface|MockObject
+ */
+ private $objectManagerMock;
+
/**
* @inheritDoc
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
protected function setUp(): void
{
+ $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class)
+ ->disableOriginalConstructor()
+ ->onlyMethods(['get'])
+ ->getMockForAbstractClass();
+ \Magento\Framework\App\ObjectManager::setInstance($this->objectManagerMock);
$this->product = $this->getMockBuilder(Product::class)
->addMethods(['getCanShowPrice'])
->onlyMethods(['getPriceInfo', 'isSalable', 'getId'])
@@ -183,6 +202,11 @@ protected function setUp(): void
->disableOriginalConstructor()
->getMockForAbstractClass();
+ $this->deploymentConfig = $this->createPartialMock(
+ DeploymentConfig::class,
+ ['get']
+ );
+
$this->minimalPriceCalculator = $this->getMockForAbstractClass(MinimalPriceCalculatorInterface::class);
$this->object = $objectManager->getObject(
FinalPriceBox::class,
@@ -455,6 +479,15 @@ public function testHidePrice(): void
*/
public function testGetCacheKey(): void
{
+ $this->objectManagerMock->expects($this->any())
+ ->method('get')
+ ->with(DeploymentConfig::class)
+ ->willReturn($this->deploymentConfig);
+
+ $this->deploymentConfig->expects($this->any())
+ ->method('get')
+ ->with(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY)
+ ->willReturn('448198e08af35844a42d3c93c1ef4e03');
$result = $this->object->getCacheKey();
$this->assertStringEndsWith('list-category-page', $result);
}
diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json
index 4421b2991266b..73f8d988bf270 100644
--- a/app/code/Magento/Catalog/composer.json
+++ b/app/code/Magento/Catalog/composer.json
@@ -31,7 +31,8 @@
"magento/module-ui": "*",
"magento/module-url-rewrite": "*",
"magento/module-widget": "*",
- "magento/module-wishlist": "*"
+ "magento/module-wishlist": "*",
+ "magento/module-aws-s3": "*"
},
"suggest": {
"magento/module-cookie": "*",
diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv
index defbf31a6b8f8..81e059adb3bb0 100644
--- a/app/code/Magento/Catalog/i18n/en_US.csv
+++ b/app/code/Magento/Catalog/i18n/en_US.csv
@@ -819,4 +819,5 @@ Details,Details
"Failed to retrieve product links for ""%1""","Failed to retrieve product links for ""%1"""
"The linked product SKU is invalid. Verify the data and try again.","The linked product SKU is invalid. Verify the data and try again."
"The linked products data is invalid. Verify the data and try again.","The linked products data is invalid. Verify the data and try again."
+"The url has invalid characters. Please correct and try again.","The url has invalid characters. Please correct and try again."
diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js b/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js
index d292bd126593c..b4d4ed12d20ba 100644
--- a/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js
+++ b/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js
@@ -5,10 +5,9 @@
define([
'jquery',
- 'mageUtils',
'jquery/ui',
'jquery/jstree/jquery.jstree'
-], function ($, utils) {
+], function ($) {
'use strict';
$.widget('mage.categoryTree', {
@@ -87,7 +86,7 @@ define([
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
result = {
id: node.id,
- text: utils.unescape(node.name) + ' (' + node.product_count + ')',
+ text: node.name + ' (' + node.product_count + ')',
li_attr: {
class: node.cls + (!!node.disabled ? ' disabled' : '') //eslint-disable-line no-extra-boolean-cast
},
diff --git a/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php b/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php
index c9591d1cbcf6b..63a998022df80 100644
--- a/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php
+++ b/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php
@@ -10,6 +10,7 @@
use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\InlineFragmentNode;
use GraphQL\Language\AST\NodeKind;
+use GraphQL\Language\AST\NodeList;
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
@@ -69,37 +70,49 @@ public function getQueryFields(FieldNode $fieldNode, ResolveInfo $resolveInfo):
{
if (null === $this->getFieldNodeSelections($fieldNode)) {
$query = $fieldNode->selectionSet->selections;
- $selectedFields = [];
- $fragmentFields = [];
/** @var FieldNode $field */
- foreach ($query as $field) {
- if ($field->kind === NodeKind::INLINE_FRAGMENT) {
- $fragmentFields[] = $this->addInlineFragmentFields($resolveInfo, $field);
- } elseif ($field->kind === NodeKind::FRAGMENT_SPREAD &&
- ($spreadFragmentNode = $resolveInfo->fragments[$field->name->value])) {
-
- foreach ($spreadFragmentNode->selectionSet->selections as $spreadNode) {
- if (isset($spreadNode->selectionSet->selections)
- && $spreadNode->kind === NodeKind::INLINE_FRAGMENT) {
- $fragmentFields[] = $this->addInlineFragmentFields($resolveInfo, $spreadNode);
- } elseif (isset($spreadNode->selectionSet->selections)
- && $spreadNode->kind !== NodeKind::INLINE_FRAGMENT) {
- $fragmentFields[] = $this->getQueryFields($spreadNode, $resolveInfo);
- } else {
+ $result = $this->getQueryData($query, $resolveInfo);
+ if ($result['fragmentFields']) {
+ $result['selectedFields'] = array_merge([], $result['selectedFields'], ...$result['fragmentFields']);
+ }
+ $this->setSelectionsForFieldNode($fieldNode, array_unique($result['selectedFields']));
+ }
+ return $this->getFieldNodeSelections($fieldNode);
+ }
+
+ /**
+ * Get an array of queried data.
+ *
+ * @param NodeList $query
+ * @param ResolveInfo $resolveInfo
+ * @return array
+ */
+ public function getQueryData(NodeList $query, ResolveInfo $resolveInfo): array
+ {
+ $selectedFields = $fragmentFields = $data = [];
+ foreach ($query as $field) {
+ if ($field->kind === NodeKind::INLINE_FRAGMENT) {
+ $fragmentFields[] = $this->addInlineFragmentFields($resolveInfo, $field);
+ } elseif ($field->kind === NodeKind::FRAGMENT_SPREAD &&
+ ($spreadFragmentNode = $resolveInfo->fragments[$field->name->value])) {
+ foreach ($spreadFragmentNode->selectionSet->selections as $spreadNode) {
+ if (isset($spreadNode->selectionSet->selections)) {
+ if ($spreadNode->kind === NodeKind::FIELD && isset($spreadNode->name)) {
$selectedFields[] = $spreadNode->name->value;
}
+ $fragmentFields[] = $this->getQueryFields($spreadNode, $resolveInfo);
+ } else {
+ $selectedFields[] = $spreadNode->name->value;
}
- } else {
- $selectedFields[] = $field->name->value;
}
+ } else {
+ $selectedFields[] = $field->name->value;
}
- if ($fragmentFields) {
- $selectedFields = array_merge([], $selectedFields, ...$fragmentFields);
- }
- $this->setSelectionsForFieldNode($fieldNode, array_unique($selectedFields));
}
+ $data['selectedFields'] = $selectedFields;
+ $data['fragmentFields'] = $fragmentFields;
- return $this->getFieldNodeSelections($fieldNode);
+ return $data;
}
/**
@@ -117,15 +130,22 @@ private function addInlineFragmentFields(
): array {
$query = $inlineFragmentField->selectionSet->selections;
/** @var FieldNode $field */
+ $fragmentFields = [];
foreach ($query as $field) {
if ($field->kind === NodeKind::INLINE_FRAGMENT) {
$this->addInlineFragmentFields($resolveInfo, $field, $inlineFragmentFields);
} elseif (isset($field->selectionSet->selections)) {
- continue;
+ if ($field->kind === NodeKind::FIELD && isset($field->name)) {
+ $inlineFragmentFields[] = $field->name->value;
+ }
+ $fragmentFields[] = $this->getQueryFields($field, $resolveInfo);
} else {
$inlineFragmentFields[] = $field->name->value;
}
}
+ if ($fragmentFields) {
+ $inlineFragmentFields = array_merge([], $inlineFragmentFields, ...$fragmentFields);
+ }
return array_unique($inlineFragmentFields);
}
diff --git a/app/code/Magento/CatalogGraphQl/Model/Config/SortAttributeReader.php b/app/code/Magento/CatalogGraphQl/Model/Config/SortAttributeReader.php
index 215b28be0579c..2f16e9ccb318f 100644
--- a/app/code/Magento/CatalogGraphQl/Model/Config/SortAttributeReader.php
+++ b/app/code/Magento/CatalogGraphQl/Model/Config/SortAttributeReader.php
@@ -6,9 +6,11 @@
namespace Magento\CatalogGraphQl\Model\Config;
+use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection as AttributesCollection;
+use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory as AttributesCollectionFactory;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\Config\ReaderInterface;
use Magento\Framework\GraphQl\Schema\Type\Entity\MapperInterface;
-use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection as AttributesCollection;
/**
* Adds custom/eav attribute to catalog products sorting in the GraphQL config.
@@ -31,20 +33,24 @@ class SortAttributeReader implements ReaderInterface
private $mapper;
/**
- * @var AttributesCollection
+ * @var AttributesCollectionFactory
*/
- private $attributesCollection;
+ private $attributesCollectionFactory;
/**
* @param MapperInterface $mapper
- * @param AttributesCollection $attributesCollection
+ * @param AttributesCollection $attributesCollection @deprecated @see $attributesCollectionFactory
+ * @param AttributesCollectionFactory|null $attributesCollectionFactory
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function __construct(
MapperInterface $mapper,
- AttributesCollection $attributesCollection
+ AttributesCollection $attributesCollection,
+ ?AttributesCollectionFactory $attributesCollectionFactory = null
) {
$this->mapper = $mapper;
- $this->attributesCollection = $attributesCollection;
+ $this->attributesCollectionFactory = $attributesCollectionFactory
+ ?? ObjectManager::getInstance()->get(AttributesCollectionFactory::class);
}
/**
@@ -58,7 +64,8 @@ public function read($scope = null) : array
{
$map = $this->mapper->getMappedTypes(self::ENTITY_TYPE);
$config =[];
- $attributes = $this->attributesCollection->addSearchableAttributeFilter()->addFilter('used_for_sort_by', 1);
+ $attributes = $this->attributesCollectionFactory->create()
+ ->addSearchableAttributeFilter()->addFilter('used_for_sort_by', 1);
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */
foreach ($attributes as $attribute) {
$attributeCode = $attribute->getAttributeCode();
@@ -73,7 +80,6 @@ public function read($scope = null) : array
];
}
}
-
return $config;
}
}
diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductFieldsSelector.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductFieldsSelector.php
index 3139c35774008..ab9fed035cc35 100644
--- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductFieldsSelector.php
+++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/ProductFieldsSelector.php
@@ -7,7 +7,7 @@
namespace Magento\CatalogGraphQl\Model\Resolver\Product;
-use GraphQL\Language\AST\NodeKind;
+use Magento\CatalogGraphQl\Model\AttributesJoiner;
use Magento\Framework\GraphQl\Query\FieldTranslator;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
@@ -19,14 +19,23 @@ class ProductFieldsSelector
/**
* @var FieldTranslator
*/
- private $fieldTranslator;
+ private FieldTranslator $fieldTranslator;
+
+ /**
+ * @var AttributesJoiner
+ */
+ private AttributesJoiner $attributesJoiner;
/**
* @param FieldTranslator $fieldTranslator
+ * @param AttributesJoiner $attributesJoiner
*/
- public function __construct(FieldTranslator $fieldTranslator)
- {
+ public function __construct(
+ FieldTranslator $fieldTranslator,
+ AttributesJoiner $attributesJoiner
+ ) {
$this->fieldTranslator = $fieldTranslator;
+ $this->attributesJoiner = $attributesJoiner;
}
/**
@@ -36,27 +45,17 @@ public function __construct(FieldTranslator $fieldTranslator)
* @param string $productNodeName
* @return string[]
*/
- public function getProductFieldsFromInfo(ResolveInfo $info, string $productNodeName = 'product') : array
+ public function getProductFieldsFromInfo(ResolveInfo $info, string $productNodeName = 'product'): array
{
$fieldNames = [];
foreach ($info->fieldNodes as $node) {
if ($node->name->value !== $productNodeName) {
continue;
}
- foreach ($node->selectionSet->selections as $selectionNode) {
- if ($selectionNode->kind === NodeKind::INLINE_FRAGMENT) {
- foreach ($selectionNode->selectionSet->selections as $inlineSelection) {
- if ($inlineSelection->kind === NodeKind::INLINE_FRAGMENT) {
- continue;
- }
- $fieldNames[] = $this->fieldTranslator->translate($inlineSelection->name->value);
- }
- continue;
- }
- $fieldNames[] = $this->fieldTranslator->translate($selectionNode->name->value);
- }
+ $queryFields = $this->attributesJoiner->getQueryFields($node, $info);
+ $fieldNames[] = $queryFields;
}
- return $fieldNames;
+ return array_merge(...$fieldNames);
}
}
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index 9d050ce6170bf..a0ee8d77d69f3 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -51,6 +51,7 @@
*/
class Product extends AbstractEntity
{
+ private const COL_NAME_FORMAT = '/[\x00-\x1F\x7F]/';
private const DEFAULT_GLOBAL_MULTIPLE_VALUE_SEPARATOR = ',';
public const CONFIG_KEY_PRODUCT_TYPES = 'global/importexport/import_product_types';
@@ -1633,6 +1634,10 @@ protected function _saveProducts()
// the bunch of products will pass for the event with url_key column.
$bunch[$rowNum][self::URL_KEY] = $rowData[self::URL_KEY] = $urlKey;
}
+ if (!empty($rowData[self::COL_NAME])) {
+ // remove null byte character
+ $rowData[self::COL_NAME] = preg_replace(self::COL_NAME_FORMAT, '', $rowData[self::COL_NAME]);
+ }
$rowSku = $rowData[self::COL_SKU];
if (null === $rowSku) {
$this->getErrorAggregator()->addRowToSkip($rowNum);
diff --git a/app/code/Magento/CatalogInventory/Helper/Minsaleqty.php b/app/code/Magento/CatalogInventory/Helper/Minsaleqty.php
index 96bf5bd965355..1ee8e1a97e89f 100644
--- a/app/code/Magento/CatalogInventory/Helper/Minsaleqty.php
+++ b/app/code/Magento/CatalogInventory/Helper/Minsaleqty.php
@@ -8,13 +8,14 @@
use Magento\Customer\Api\GroupManagementInterface;
use Magento\Framework\App\ObjectManager;
+use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Store\Model\Store;
/**
* MinSaleQty value manipulation helper
*/
-class Minsaleqty
+class Minsaleqty implements ResetAfterRequestInterface
{
/**
* Core store config
@@ -61,6 +62,14 @@ public function __construct(
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class);
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ $this->minSaleQtyCache = [];
+ }
+
/**
* Retrieve fixed qty value
*
diff --git a/app/code/Magento/CatalogInventory/Model/Configuration.php b/app/code/Magento/CatalogInventory/Model/Configuration.php
index 8b0849c8874bc..9df634c225d71 100644
--- a/app/code/Magento/CatalogInventory/Model/Configuration.php
+++ b/app/code/Magento/CatalogInventory/Model/Configuration.php
@@ -9,98 +9,96 @@
use Magento\CatalogInventory\Helper\Minsaleqty as MinsaleqtyHelper;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Catalog\Model\ProductTypes\ConfigInterface;
+use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;
-/**
- * Class Configuration
- */
-class Configuration implements StockConfigurationInterface
+class Configuration implements StockConfigurationInterface, ResetAfterRequestInterface
{
/**
* Default website id
*/
- const DEFAULT_WEBSITE_ID = 1;
+ public const DEFAULT_WEBSITE_ID = 1;
/**
* Inventory options config path
*/
- const XML_PATH_GLOBAL = 'cataloginventory/options/';
+ public const XML_PATH_GLOBAL = 'cataloginventory/options/';
/**
* Subtract config path
*/
- const XML_PATH_CAN_SUBTRACT = 'cataloginventory/options/can_subtract';
+ public const XML_PATH_CAN_SUBTRACT = 'cataloginventory/options/can_subtract';
/**
* Back in stock config path
*/
- const XML_PATH_CAN_BACK_IN_STOCK = 'cataloginventory/options/can_back_in_stock';
+ public const XML_PATH_CAN_BACK_IN_STOCK = 'cataloginventory/options/can_back_in_stock';
/**
* Item options config path
*/
- const XML_PATH_ITEM = 'cataloginventory/item_options/';
+ public const XML_PATH_ITEM = 'cataloginventory/item_options/';
/**
* Max qty config path
*/
- const XML_PATH_MIN_QTY = 'cataloginventory/item_options/min_qty';
+ public const XML_PATH_MIN_QTY = 'cataloginventory/item_options/min_qty';
/**
* Min sale qty config path
*/
- const XML_PATH_MIN_SALE_QTY = 'cataloginventory/item_options/min_sale_qty';
+ public const XML_PATH_MIN_SALE_QTY = 'cataloginventory/item_options/min_sale_qty';
/**
* Max sale qty config path
*/
- const XML_PATH_MAX_SALE_QTY = 'cataloginventory/item_options/max_sale_qty';
+ public const XML_PATH_MAX_SALE_QTY = 'cataloginventory/item_options/max_sale_qty';
/**
* Back orders config path
*/
- const XML_PATH_BACKORDERS = 'cataloginventory/item_options/backorders';
+ public const XML_PATH_BACKORDERS = 'cataloginventory/item_options/backorders';
/**
* Notify stock config path
*/
- const XML_PATH_NOTIFY_STOCK_QTY = 'cataloginventory/item_options/notify_stock_qty';
+ public const XML_PATH_NOTIFY_STOCK_QTY = 'cataloginventory/item_options/notify_stock_qty';
/**
* Manage stock config path
*/
- const XML_PATH_MANAGE_STOCK = 'cataloginventory/item_options/manage_stock';
+ public const XML_PATH_MANAGE_STOCK = 'cataloginventory/item_options/manage_stock';
/**
* Enable qty increments config path
*/
- const XML_PATH_ENABLE_QTY_INCREMENTS = 'cataloginventory/item_options/enable_qty_increments';
+ public const XML_PATH_ENABLE_QTY_INCREMENTS = 'cataloginventory/item_options/enable_qty_increments';
/**
* Qty increments config path
*/
- const XML_PATH_QTY_INCREMENTS = 'cataloginventory/item_options/qty_increments';
+ public const XML_PATH_QTY_INCREMENTS = 'cataloginventory/item_options/qty_increments';
/**
* Show out of stock config path
*/
- const XML_PATH_SHOW_OUT_OF_STOCK = 'cataloginventory/options/show_out_of_stock';
+ public const XML_PATH_SHOW_OUT_OF_STOCK = 'cataloginventory/options/show_out_of_stock';
/**
* Auto return config path
*/
- const XML_PATH_ITEM_AUTO_RETURN = 'cataloginventory/item_options/auto_return';
+ public const XML_PATH_ITEM_AUTO_RETURN = 'cataloginventory/item_options/auto_return';
/**
* Path to configuration option 'Display product stock status'
*/
- const XML_PATH_DISPLAY_PRODUCT_STOCK_STATUS = 'cataloginventory/options/display_product_stock_status';
+ public const XML_PATH_DISPLAY_PRODUCT_STOCK_STATUS = 'cataloginventory/options/display_product_stock_status';
/**
* Threshold qty config path
*/
- const XML_PATH_STOCK_THRESHOLD_QTY = 'cataloginventory/options/stock_threshold_qty';
+ public const XML_PATH_STOCK_THRESHOLD_QTY = 'cataloginventory/options/stock_threshold_qty';
/**
* @var ConfigInterface
@@ -122,7 +120,7 @@ class Configuration implements StockConfigurationInterface
/**
* All product types registry in scope of quantity availability
*
- * @var array
+ * @var array|null
*/
protected $isQtyTypeIds;
@@ -151,6 +149,14 @@ public function __construct(
$this->storeManager = $storeManager;
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ $this->isQtyTypeIds = null;
+ }
+
/**
* @inheritdoc
*/
diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml
index 6f388c3e6c6d1..9a198dd571def 100644
--- a/app/code/Magento/CatalogInventory/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml
+++ b/app/code/Magento/CatalogInventory/Test/Mftf/Section/AdminProductFormAdvancedInventorySection.xml
@@ -36,5 +36,7 @@
+
+
diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php
index 9b66606d37a9e..d29928306f24b 100644
--- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php
+++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php
@@ -219,10 +219,23 @@ public function __construct(
->get(DefaultFilterStrategyApplyChecker::class);
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->queryText = null;
+ $this->search = null;
+ $this->searchCriteriaBuilder = null;
+ $this->searchResult = null;
+ $this->filterBuilder = null;
+ $this->searchOrders = null;
+ }
+
/**
* Get search.
*
- * @deprecated 100.1.0
* @return \Magento\Search\Api\SearchInterface
*/
private function getSearch()
@@ -237,6 +250,7 @@ private function getSearch()
* Test search.
*
* @deprecated 100.1.0
+ * @see __construct
* @param \Magento\Search\Api\SearchInterface $object
* @return void
* @since 100.1.0
@@ -249,7 +263,6 @@ public function setSearch(\Magento\Search\Api\SearchInterface $object)
/**
* Set search criteria builder.
*
- * @deprecated 100.1.0
* @return \Magento\Framework\Api\Search\SearchCriteriaBuilder
*/
private function getSearchCriteriaBuilder()
@@ -265,6 +278,7 @@ private function getSearchCriteriaBuilder()
* Set search criteria builder.
*
* @deprecated 100.1.0
+ * @see __construct
* @param \Magento\Framework\Api\Search\SearchCriteriaBuilder $object
* @return void
* @since 100.1.0
@@ -277,7 +291,6 @@ public function setSearchCriteriaBuilder(\Magento\Framework\Api\Search\SearchCri
/**
* Get filter builder.
*
- * @deprecated 100.1.0
* @return \Magento\Framework\Api\FilterBuilder
*/
private function getFilterBuilder()
@@ -292,6 +305,7 @@ private function getFilterBuilder()
* Set filter builder.
*
* @deprecated 100.1.0
+ * @see __construct
* @param \Magento\Framework\Api\FilterBuilder $object
* @return void
* @since 100.1.0
diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php
index 7e9be408a3850..10e72e0155ff3 100644
--- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php
+++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php
@@ -23,22 +23,16 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
private $indexUsageEnforcements;
/**
- * Attribute collection
- *
* @var array
*/
protected $_attributesCollection;
/**
- * Search query
- *
* @var string
*/
protected $_searchQuery;
/**
- * Attribute collection factory
- *
* @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory
*/
protected $_attributeCollectionFactory;
@@ -119,6 +113,16 @@ public function __construct(
$this->indexUsageEnforcements = $indexUsageEnforcements;
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->_attributesCollection = null;
+ $this->_searchQuery = null;
+ }
+
/**
* Add search query filter
*
@@ -240,6 +244,8 @@ private function isIndexExists(string $table, string $index) : bool
* @param mixed $query
* @param bool $searchOnlyInCurrentStore Search only in current store or in all stores
* @return string
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
protected function _getSearchEntityIdsSql($query, $searchOnlyInCurrentStore = true)
{
diff --git a/app/code/Magento/Checkout/Model/Session.php b/app/code/Magento/Checkout/Model/Session.php
index 0addbf069cba3..3a2beb3b4371c 100644
--- a/app/code/Magento/Checkout/Model/Session.php
+++ b/app/code/Magento/Checkout/Model/Session.php
@@ -24,7 +24,7 @@
*/
class Session extends \Magento\Framework\Session\SessionManager
{
- const CHECKOUT_STATE_BEGIN = 'begin';
+ public const CHECKOUT_STATE_BEGIN = 'begin';
/**
* Quote instance
@@ -99,12 +99,12 @@ class Session extends \Magento\Framework\Session\SessionManager
protected $customerRepository;
/**
- * @param QuoteIdMaskFactory
+ * @var QuoteIdMaskFactory
*/
protected $quoteIdMaskFactory;
/**
- * @param bool
+ * @var bool
*/
protected $isQuoteMasked;
@@ -186,6 +186,19 @@ public function __construct(
->get(LoggerInterface::class);
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->_quote = null;
+ $this->_customer = null;
+ $this->_loadInactive = false;
+ $this->isLoading = false;
+ $this->_order = null;
+ }
+
/**
* Set customer data.
*
diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
index f397a8ddc9cf1..f08c48c55efa1 100644
--- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
+++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
namespace Magento\Checkout\Model;
@@ -39,60 +40,62 @@ class ShippingInformationManagement implements ShippingInformationManagementInte
/**
* @var PaymentMethodManagementInterface
*/
- protected $paymentMethodManagement;
+ protected PaymentMethodManagementInterface $paymentMethodManagement;
/**
* @var PaymentDetailsFactory
*/
- protected $paymentDetailsFactory;
+ protected PaymentDetailsFactory $paymentDetailsFactory;
/**
* @var CartTotalRepositoryInterface
*/
- protected $cartTotalsRepository;
+ protected CartTotalRepositoryInterface $cartTotalsRepository;
/**
* @var CartRepositoryInterface
*/
- protected $quoteRepository;
-
+ protected CartRepositoryInterface $quoteRepository;
/**
* @var Logger
*/
- protected $logger;
+ protected Logger $logger;
/**
* @var QuoteAddressValidator
*/
- protected $addressValidator;
+ protected QuoteAddressValidator $addressValidator;
/**
* @var AddressRepositoryInterface
* @deprecated 100.2.0
+ * @see AddressRepositoryInterface
*/
- protected $addressRepository;
+ protected AddressRepositoryInterface $addressRepository;
/**
* @var ScopeConfigInterface
* @deprecated 100.2.0
+ * @see ScopeConfigInterface
*/
- protected $scopeConfig;
+ protected ScopeConfigInterface $scopeConfig;
/**
* @var TotalsCollector
* @deprecated 100.2.0
+ * @see TotalsCollector
*/
- protected $totalsCollector;
+ protected TotalsCollector $totalsCollector;
/**
* @var CartExtensionFactory
*/
- private $cartExtensionFactory;
+ private CartExtensionFactory $cartExtensionFactory;
/**
* @var ShippingAssignmentFactory
*/
- protected $shippingAssignmentFactory;
+ protected ShippingAssignmentFactory $shippingAssignmentFactory;
/**
* @var ShippingFactory
@@ -262,8 +265,11 @@ protected function validateQuote(Quote $quote): void
* @param string $method
* @return CartInterface
*/
- private function prepareShippingAssignment(CartInterface $quote, AddressInterface $address, $method): CartInterface
- {
+ private function prepareShippingAssignment(
+ CartInterface $quote,
+ AddressInterface $address,
+ string $method
+ ): CartInterface {
$cartExtension = $quote->getExtensionAttributes();
if ($cartExtension === null) {
$cartExtension = $this->cartExtensionFactory->create();
diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutSuccessMainSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutSuccessMainSection.xml
index abdb4ddac7343..e5e912af73343 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutSuccessMainSection.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutSuccessMainSection.xml
@@ -21,5 +21,6 @@
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml
index a5734b35afc0a..f9ddee8284d8b 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml
@@ -21,11 +21,11 @@
+
560
-
@@ -41,6 +41,7 @@
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml
index 1bd9b0c9229bc..8ccb7af5a334a 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml
@@ -21,6 +21,7 @@
+
560
@@ -41,6 +42,7 @@
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml
index 1a85bb0bee1ee..a176a7ccd27f3 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml
@@ -18,6 +18,7 @@
+
@@ -101,10 +102,14 @@
+
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml
index bc4f18a3ac9fc..d59af6328f736 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml
@@ -20,6 +20,7 @@
+
@@ -40,9 +41,9 @@
-
+
diff --git a/app/code/Magento/Checkout/etc/adminhtml/system.xml b/app/code/Magento/Checkout/etc/adminhtml/system.xml
index b56566a043c3e..5bb0f37f3bc25 100644
--- a/app/code/Magento/Checkout/etc/adminhtml/system.xml
+++ b/app/code/Magento/Checkout/etc/adminhtml/system.xml
@@ -13,6 +13,11 @@
Magento_Checkout::checkout
+
+
+ Magento\Config\Model\Config\Source\Yesno
+ Enabling this setting will allow unauthenticated users to query if an e-mail address is already associated with a customer account. This can be used to enhance the checkout workflow for guests that do not realize they already have an account but comes at the cost of exposing information to unauthenticated users.
+
Magento\Config\Model\Config\Source\Yesno
@@ -23,7 +28,7 @@
- \Magento\Checkout\Model\Adminhtml\BillingAddressDisplayOptions
+ Magento\Checkout\Model\Adminhtml\BillingAddressDisplayOptions
diff --git a/app/code/Magento/Checkout/etc/config.xml b/app/code/Magento/Checkout/etc/config.xml
index eac0bd849da35..c85d68b35f714 100644
--- a/app/code/Magento/Checkout/etc/config.xml
+++ b/app/code/Magento/Checkout/etc/config.xml
@@ -9,6 +9,7 @@
+ 0
1
1
0
diff --git a/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php b/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php
index f22367393030a..7d30908a2d9d6 100644
--- a/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php
+++ b/app/code/Magento/Cms/Model/ResourceModel/Block/Collection.php
@@ -19,15 +19,11 @@ class Collection extends AbstractCollection
protected $_idFieldName = 'block_id';
/**
- * Event prefix
- *
* @var string
*/
protected $_eventPrefix = 'cms_block_collection';
/**
- * Event object
- *
* @var string
*/
protected $_eventObject = 'block_collection';
diff --git a/app/code/Magento/Cms/Model/ResourceModel/Page/Collection.php b/app/code/Magento/Cms/Model/ResourceModel/Page/Collection.php
index 96886a995b1c9..6aafb010fb625 100644
--- a/app/code/Magento/Cms/Model/ResourceModel/Page/Collection.php
+++ b/app/code/Magento/Cms/Model/ResourceModel/Page/Collection.php
@@ -26,15 +26,11 @@ class Collection extends AbstractCollection
protected $_previewFlag;
/**
- * Event prefix
- *
* @var string
*/
protected $_eventPrefix = 'cms_page_collection';
/**
- * Event object
- *
* @var string
*/
protected $_eventObject = 'page_collection';
diff --git a/app/code/Magento/Cms/Test/Mftf/Section/StorefrontCMSPageSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/StorefrontCMSPageSection.xml
index bb276b2adb0de..de70c5706360a 100644
--- a/app/code/Magento/Cms/Test/Mftf/Section/StorefrontCMSPageSection.xml
+++ b/app/code/Magento/Cms/Test/Mftf/Section/StorefrontCMSPageSection.xml
@@ -16,5 +16,6 @@
+
diff --git a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection/WidgetSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection/WidgetSection.xml
index 5be91f61e1e1e..c9ef757ca7477 100644
--- a/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection/WidgetSection.xml
+++ b/app/code/Magento/Cms/Test/Mftf/Section/TinyMCESection/WidgetSection.xml
@@ -48,5 +48,8 @@
+
+
+
diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminCmsPageGridUrlFilterApplierTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminCmsPageGridUrlFilterApplierTest.xml
index 949ddc8c05deb..ca07a5cdd0bb5 100644
--- a/app/code/Magento/Cms/Test/Mftf/Test/AdminCmsPageGridUrlFilterApplierTest.xml
+++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminCmsPageGridUrlFilterApplierTest.xml
@@ -33,6 +33,7 @@
+
diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminConfigureStoreInformationTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminConfigureStoreInformationTest.xml
new file mode 100644
index 0000000000000..b06bb0341d517
--- /dev/null
+++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminConfigureStoreInformationTest.xml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Config/Model/Config/Reader/Source/Deployed/SettingChecker.php b/app/code/Magento/Config/Model/Config/Reader/Source/Deployed/SettingChecker.php
index 48c53f8201bb2..0d56aca14fb0a 100644
--- a/app/code/Magento/Config/Model/Config/Reader/Source/Deployed/SettingChecker.php
+++ b/app/code/Magento/Config/Model/Config/Reader/Source/Deployed/SettingChecker.php
@@ -102,12 +102,8 @@ public function getPlaceholderValue($path, $scope, $scopeCode = null)
public function getEnvValue($placeholder)
{
// phpcs:disable Magento2.Security.Superglobal
- $environment = [];
- foreach ($_ENV as $key => $value) {
- $environment[strtolower($key)] = $value;
- }
- if ($this->placeholder->isApplicable($placeholder) && isset($environment[strtolower($placeholder)])) {
- return $environment[strtolower($placeholder)];
+ if ($this->placeholder->isApplicable($placeholder) && isset($_ENV[$placeholder])) {
+ return $_ENV[$placeholder];
}
// phpcs:enable
diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/AdminChangeTimeZoneForDifferentWebsiteActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/AdminChangeTimeZoneForDifferentWebsiteActionGroup.xml
new file mode 100644
index 0000000000000..7b33c5229a869
--- /dev/null
+++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/AdminChangeTimeZoneForDifferentWebsiteActionGroup.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+ set the time zone for different website
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/EuropeanCountriesSystemCheckBoxActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/EuropeanCountriesSystemCheckBoxActionGroup.xml
new file mode 100644
index 0000000000000..055715d71f93c
--- /dev/null
+++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/EuropeanCountriesSystemCheckBoxActionGroup.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ check system value european country option value
+
+
+
+
+
+
diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ResetBackTaxClassForGiftOptionsAndShoppingCartDisplaySettingsActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ResetBackTaxClassForGiftOptionsAndShoppingCartDisplaySettingsActionGroup.xml
new file mode 100644
index 0000000000000..99bf20b3e671c
--- /dev/null
+++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ResetBackTaxClassForGiftOptionsAndShoppingCartDisplaySettingsActionGroup.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+ Goes to the 'Configuration' page for 'Tax'. Resets 'Tax Class for Shipping' to 'Taxable Goods'. Updates the Shopping cart display settongs. Clicks on the Save button.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/SetTaxClassForGiftOptionsAndShoppingCartDisplaySettingsActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/SetTaxClassForGiftOptionsAndShoppingCartDisplaySettingsActionGroup.xml
new file mode 100644
index 0000000000000..3a825ebfb511f
--- /dev/null
+++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/SetTaxClassForGiftOptionsAndShoppingCartDisplaySettingsActionGroup.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+ Goes to the 'Configuration' page for 'Tax'. Sets 'Tax Class for Shipping' to 'Taxable Goods'. Updates the Shopping cart display settongs. Clicks on the Save button.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Config/Test/Mftf/Data/CountryOptionConfigData.xml b/app/code/Magento/Config/Test/Mftf/Data/CountryOptionConfigData.xml
index 378aa0bfc510c..59c70ff68f419 100644
--- a/app/code/Magento/Config/Test/Mftf/Data/CountryOptionConfigData.xml
+++ b/app/code/Magento/Config/Test/Mftf/Data/CountryOptionConfigData.xml
@@ -30,4 +30,8 @@
websites
base
+
+ general/country/eu_countries
+ GB,DE,FR
+
diff --git a/app/code/Magento/Config/Test/Mftf/Section/SalesConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/SalesConfigSection.xml
index 878a0c24f7331..f971b4dd03cec 100644
--- a/app/code/Magento/Config/Test/Mftf/Section/SalesConfigSection.xml
+++ b/app/code/Magento/Config/Test/Mftf/Section/SalesConfigSection.xml
@@ -13,5 +13,10 @@
+
+
+
+
+
diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/Reader/Source/Deployed/SettingCheckerTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/Reader/Source/Deployed/SettingCheckerTest.php
index 157d740d524c1..a0158a6b473df 100644
--- a/app/code/Magento/Config/Test/Unit/Model/Config/Reader/Source/Deployed/SettingCheckerTest.php
+++ b/app/code/Magento/Config/Test/Unit/Model/Config/Reader/Source/Deployed/SettingCheckerTest.php
@@ -69,16 +69,6 @@ protected function setUp(): void
$this->checker = new SettingChecker($this->configMock, $placeholderFactoryMock, $this->scopeCodeResolverMock);
}
- public function testGetEnvValue(): void
- {
- $_ENV = array_merge($this->env, ['SOME_PLACEHOLDER' => 0, 'another_placeholder' => 1, 'some_placeholder' => 1]);
- $this->placeholderMock->expects($this->any())
- ->method('isApplicable')
- ->willReturn(true);
- $this->assertSame($this->checker->getEnvValue('SOME_PLACEHOLDER'), 1);
- $this->assertSame($this->checker->getEnvValue('another_placeholder'), 1);
- }
-
/**
* @param string $path
* @param string $scope
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php b/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php
index 88b5c3e48ea19..50421c6967b36 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/VariationHandler.php
@@ -200,7 +200,10 @@ protected function fillSimpleProductData(
continue;
}
- $product->setData($attribute->getAttributeCode(), $parentProduct->getData($attribute->getAttributeCode()));
+ $product->setData(
+ $attribute->getAttributeCode(),
+ $parentProduct->getData($attribute->getAttributeCode()) ?? $attribute->getDefaultValue()
+ );
}
$keysFilter = ['item_id', 'product_id', 'stock_id', 'type_id', 'website_id'];
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection/AdminProductFormConfigurationsSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection/AdminProductFormConfigurationsSection.xml
index 22cb822dbe762..1ceb33a231c99 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection/AdminProductFormConfigurationsSection.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection/AdminProductFormConfigurationsSection.xml
@@ -53,5 +53,12 @@
+
+
+
+
+
+
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCheckResultsOfColorAndOtherFiltersTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCheckResultsOfColorAndOtherFiltersTest.xml
index 852cc97b0f040..bc56c333ac4fb 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCheckResultsOfColorAndOtherFiltersTest.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCheckResultsOfColorAndOtherFiltersTest.xml
@@ -201,5 +201,6 @@
+
diff --git a/app/code/Magento/Customer/Api/AccountManagementInterface.php b/app/code/Magento/Customer/Api/AccountManagementInterface.php
index 9c607be9f217c..165233cc6a880 100644
--- a/app/code/Magento/Customer/Api/AccountManagementInterface.php
+++ b/app/code/Magento/Customer/Api/AccountManagementInterface.php
@@ -8,6 +8,7 @@
namespace Magento\Customer\Api;
use Magento\Framework\Exception\InputException;
+use Magento\Framework\Exception\LocalizedException;
/**
* Interface for managing customers accounts.
@@ -194,7 +195,7 @@ public function resendConfirmation($email, $websiteId, $redirectUrl = '');
* Check if given email is associated with a customer account in given website.
*
* @param string $customerEmail
- * @param int $websiteId If not set, will use the current websiteId
+ * @param int|null $websiteId If not set, will use the current websiteId
* @return bool
* @throws \Magento\Framework\Exception\LocalizedException
*/
diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php
index 3719cb61cede7..29f1ebc0e531b 100644
--- a/app/code/Magento/Customer/Model/AccountManagement.php
+++ b/app/code/Magento/Customer/Model/AccountManagement.php
@@ -20,6 +20,7 @@
use Magento\Customer\Model\Customer as CustomerModel;
use Magento\Customer\Model\Customer\CredentialsValidator;
use Magento\Customer\Model\ForgotPasswordToken\GetCustomerByToken;
+use Magento\Customer\Model\Logger as CustomerLogger;
use Magento\Customer\Model\Metadata\Validator;
use Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory;
use Magento\Directory\Model\AllowedCountries;
@@ -57,7 +58,6 @@
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;
use Psr\Log\LoggerInterface as PsrLogger;
-use Magento\Customer\Model\Logger as CustomerLogger;
/**
* Handle various customer account actions
@@ -69,6 +69,11 @@
*/
class AccountManagement implements AccountManagementInterface
{
+ /**
+ * System Configuration Path for Enable/Disable Login at Guest Checkout
+ */
+ public const GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG = 'checkout/options/enable_guest_checkout_login';
+
/**
* Configuration paths for create account email template
*
@@ -719,7 +724,7 @@ private function handleUnknownTemplate($template)
throw new InputException(
__(
'Invalid value of "%value" provided for the %fieldName field. '
- . 'Possible values: %template1 or %template2.',
+ . 'Possible values: %template1 or %template2.',
[
'value' => $template,
'fieldName' => 'template',
@@ -1120,7 +1125,7 @@ public function validate(CustomerInterface $customer)
$result = $this->eavValidator->isValid($customerModel);
if ($result === false && is_array($this->eavValidator->getMessages())) {
return $validationResults->setIsValid(false)->setMessages(
- // phpcs:ignore Magento2.Functions.DiscouragedFunction
+ // phpcs:ignore Magento2.Functions.DiscouragedFunction
call_user_func_array(
'array_merge',
array_values($this->eavValidator->getMessages())
@@ -1132,9 +1137,24 @@ public function validate(CustomerInterface $customer)
/**
* @inheritdoc
+ *
+ * @param string $customerEmail
+ * @param int|null $websiteId
+ * @return bool
+ * @throws LocalizedException
*/
public function isEmailAvailable($customerEmail, $websiteId = null)
{
+ $guestLoginConfig = $this->scopeConfig->getValue(
+ self::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG,
+ ScopeInterface::SCOPE_WEBSITE,
+ $websiteId
+ );
+
+ if (!$guestLoginConfig) {
+ return true;
+ }
+
try {
if ($websiteId === null) {
$websiteId = $this->storeManager->getStore()->getWebsiteId();
diff --git a/app/code/Magento/Customer/Model/App/FrontController/DeleteCookieWhenCustomerNotExistPlugin.php b/app/code/Magento/Customer/Model/App/FrontController/DeleteCookieWhenCustomerNotExistPlugin.php
deleted file mode 100644
index 53e170f6026f8..0000000000000
--- a/app/code/Magento/Customer/Model/App/FrontController/DeleteCookieWhenCustomerNotExistPlugin.php
+++ /dev/null
@@ -1,55 +0,0 @@
-responseHttp = $responseHttp;
- $this->session = $session;
- }
-
- /**
- * Delete the cookie when the customer is not exist before dispatch the front controller.
- *
- * @return void
- */
- public function beforeDispatch(): void
- {
- if (!$this->session->getCustomerId()) {
- $this->responseHttp->sendVary();
- }
- }
-}
diff --git a/app/code/Magento/Customer/Model/ResourceModel/Address/Grid/Collection.php b/app/code/Magento/Customer/Model/ResourceModel/Address/Grid/Collection.php
index c7b44288bc85f..ffb5f41a40687 100644
--- a/app/code/Magento/Customer/Model/ResourceModel/Address/Grid/Collection.php
+++ b/app/code/Magento/Customer/Model/ResourceModel/Address/Grid/Collection.php
@@ -94,6 +94,15 @@ public function __construct(
);
}
+ /**
+ * @inheritDoc
+ */
+ public function _resetState(): void
+ {
+ parent::_resetState();
+ $this->_idFieldName = 'entity_id';
+ }
+
/**
* @inheritdoc
*/
diff --git a/app/code/Magento/Customer/Model/Session.php b/app/code/Magento/Customer/Model/Session.php
index f5a7cc0d124b3..ec47afe8e065a 100644
--- a/app/code/Magento/Customer/Model/Session.php
+++ b/app/code/Magento/Customer/Model/Session.php
@@ -399,7 +399,11 @@ public function getCustomerGroupId()
public function _resetState(): void
{
$this->_customer = null;
- parent::_resetState(); // TODO: Change the autogenerated stub
+ $this->_customerModel = null;
+ $this->setCustomerId(null);
+ $this->setCustomerGroupId($this->groupManagement->getNotLoggedInGroup()->getId());
+ $this->_isCustomerIdChecked = null;
+ parent::_resetState();
}
/**
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/EnterAddressDetailsActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/EnterAddressDetailsActionGroup.xml
new file mode 100644
index 0000000000000..074b93d860f19
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/EnterAddressDetailsActionGroup.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ Removed specific page. Fills in the required details
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/FillNewCustomerAddressFieldsActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/FillNewCustomerAddressFieldsActionGroup.xml
new file mode 100644
index 0000000000000..d31bacf807ec3
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/FillNewCustomerAddressFieldsActionGroup.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ Select country before select state
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontDeleteStoredPaymentMethodActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontDeleteStoredPaymentMethodActionGroup.xml
new file mode 100644
index 0000000000000..567122c45317e
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontDeleteStoredPaymentMethodActionGroup.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ Goes to the Stored Payment Method and delete the 2nd card
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontFillCustomerCreateAnAccountActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontFillCustomerCreateAnAccountActionGroup.xml
new file mode 100644
index 0000000000000..f08a2422e0230
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StorefrontFillCustomerCreateAnAccountActionGroup.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ Fills in the provided Customer details on the Storefront Customer creation page.
+
+
+
+
+
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerSignInFormSection/StorefrontCustomerSignInPopupFormSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerSignInFormSection/StorefrontCustomerSignInPopupFormSection.xml
index f6587a757ff3e..b1eeeec6de62e 100644
--- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerSignInFormSection/StorefrontCustomerSignInPopupFormSection.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerSignInFormSection/StorefrontCustomerSignInPopupFormSection.xml
@@ -13,6 +13,6 @@
-
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerStoredPaymentMethodsSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerStoredPaymentMethodsSection.xml
index d6b586e42f28c..ba8159948701d 100644
--- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerStoredPaymentMethodsSection.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerStoredPaymentMethodsSection.xml
@@ -11,5 +11,9 @@
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml
index 6e7fe4e259d7a..cee34fb258aa3 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml
@@ -23,6 +23,7 @@
+
@@ -32,6 +33,7 @@
+
diff --git a/app/code/Magento/Customer/Test/Unit/Model/App/FrontController/DeleteCookieWhenCustomerNotExistPluginTest.php b/app/code/Magento/Customer/Test/Unit/Model/App/FrontController/DeleteCookieWhenCustomerNotExistPluginTest.php
deleted file mode 100644
index fd06dbf6b8004..0000000000000
--- a/app/code/Magento/Customer/Test/Unit/Model/App/FrontController/DeleteCookieWhenCustomerNotExistPluginTest.php
+++ /dev/null
@@ -1,56 +0,0 @@
-customerSessionMock = $this->createMock(Session::class);
- $this->responseHttpMock = $this->createMock(ResponseHttp::class);
- $this->plugin = new DeleteCookieWhenCustomerNotExistPlugin(
- $this->responseHttpMock,
- $this->customerSessionMock
- );
- }
-
- public function testBeforeDispatch()
- {
- $this->customerSessionMock->expects($this->once())
- ->method('getCustomerId')
- ->willReturn(0);
- $this->plugin->beforeDispatch();
- }
-}
diff --git a/app/code/Magento/Customer/ViewModel/Customer/Data.php b/app/code/Magento/Customer/ViewModel/Customer/Data.php
deleted file mode 100644
index 8c285b368c961..0000000000000
--- a/app/code/Magento/Customer/ViewModel/Customer/Data.php
+++ /dev/null
@@ -1,63 +0,0 @@
-httpContext = $httpContext;
- $this->jsonEncoder = $jsonEncoder;
- }
-
- /**
- * Check is user login
- *
- * @return bool
- */
- public function isLoggedIn()
- {
- return $this->httpContext->getValue(Context::CONTEXT_AUTH);
- }
-
- /**
- * Encode the mixed $valueToEncode into the JSON format
- *
- * @param mixed $valueToEncode
- * @return string
- */
- public function jsonEncode($valueToEncode)
- {
- return $this->jsonEncoder->serialize($valueToEncode);
- }
-}
diff --git a/app/code/Magento/Customer/etc/frontend/di.xml b/app/code/Magento/Customer/etc/frontend/di.xml
index e29f7cc1cf1ea..827a153e94674 100644
--- a/app/code/Magento/Customer/etc/frontend/di.xml
+++ b/app/code/Magento/Customer/etc/frontend/di.xml
@@ -130,7 +130,4 @@
-
-
-
diff --git a/app/code/Magento/Customer/view/frontend/layout/default.xml b/app/code/Magento/Customer/view/frontend/layout/default.xml
index eba504a12a1e5..b431373ca4125 100644
--- a/app/code/Magento/Customer/view/frontend/layout/default.xml
+++ b/app/code/Magento/Customer/view/frontend/layout/default.xml
@@ -48,11 +48,7 @@
-
- Magento\Customer\ViewModel\Customer\Data
-
-
+ template="Magento_Customer::js/customer-data.phtml"/>
diff --git a/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml b/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml
index 7031778a8d473..de5d0004a288b 100644
--- a/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml
+++ b/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml
@@ -3,16 +3,14 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-use Magento\Customer\ViewModel\Customer\Data;
-use Magento\Framework\App\ObjectManager;
/** @var \Magento\Customer\Block\CustomerData $block */
+/** @var \Magento\Framework\Json\Helper\Data $jsonHelper */
+$expirableSectionNames = $block->getExpirableSectionNames();
// phpcs:disable Magento2.Templates.ThisInTemplate.FoundHelper
-/** @var Data $viewModel */
-$viewModel = $block->getViewModel() ?? ObjectManager::getInstance()->get(Data::class);
-$customerDataUrl = $block->getCustomerDataUrl('customer/account/updateSession');
-$expirableSectionNames = $block->getExpirableSectionNames();
+// phpcs:disable Magento2.Templates.ThisInTemplate.FoundThis
+$jsonHelper = $this->helper(\Magento\Framework\Json\Helper\Data::class);
?>