diff --git a/app/bootstrap.php b/app/bootstrap.php
index ba62b296bd49c..70b632537a75b 100644
--- a/app/bootstrap.php
+++ b/app/bootstrap.php
@@ -54,8 +54,16 @@
&& isset($_SERVER['HTTP_ACCEPT'])
&& strpos($_SERVER['HTTP_ACCEPT'], 'text/html') !== false
) {
- \Magento\Framework\Profiler::applyConfig(
- (isset($_SERVER['MAGE_PROFILER']) && strlen($_SERVER['MAGE_PROFILER'])) ? $_SERVER['MAGE_PROFILER'] : trim(file_get_contents(BP . '/var/profiler.flag')),
+ $profilerConfig = isset($_SERVER['MAGE_PROFILER']) && strlen($_SERVER['MAGE_PROFILER'])
+ ? $_SERVER['MAGE_PROFILER']
+ : trim(file_get_contents(BP . '/var/profiler.flag'));
+
+ if ($profilerConfig) {
+ $profilerConfig = json_decode($profilerConfig, true) ?: $profilerConfig;
+ }
+
+ Magento\Framework\Profiler::applyConfig(
+ $profilerConfig,
BP,
!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'
);
diff --git a/app/code/Magento/AdminNotification/Observer/PredispatchAdminActionControllerObserver.php b/app/code/Magento/AdminNotification/Observer/PredispatchAdminActionControllerObserver.php
index 3275de2a82fb7..24ef712c0f61f 100644
--- a/app/code/Magento/AdminNotification/Observer/PredispatchAdminActionControllerObserver.php
+++ b/app/code/Magento/AdminNotification/Observer/PredispatchAdminActionControllerObserver.php
@@ -37,7 +37,7 @@ public function __construct(
}
/**
- * Predispath admin action controller
+ * Predispatch admin action controller
*
* @param \Magento\Framework\Event\Observer $observer
* @return void
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/AbstractAction.php
index b6206f96b91e0..6101e5cd362e4 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/AbstractAction.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/AbstractAction.php
@@ -3,6 +3,8 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Catalog\Model\Indexer\Product\Eav;
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\AbstractEav;
@@ -12,6 +14,11 @@
*/
abstract class AbstractAction
{
+ /**
+ * Config path for enable EAV indexer
+ */
+ const ENABLE_EAV_INDEXER = 'catalog/search/enable_eav_indexer';
+
/**
* EAV Indexers by type
*
@@ -29,17 +36,27 @@ abstract class AbstractAction
*/
protected $_eavDecimalFactory;
+ /**
+ * @var \Magento\Framework\App\Config\ScopeConfigInterface
+ */
+ private $scopeConfig;
+
/**
* AbstractAction constructor.
* @param \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\DecimalFactory $eavDecimalFactory
* @param \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\SourceFactory $eavSourceFactory
+ * @param \Magento\Framework\App\Config\ScopeConfigInterface|null $scopeConfig
*/
public function __construct(
\Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\DecimalFactory $eavDecimalFactory,
- \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\SourceFactory $eavSourceFactory
+ \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\SourceFactory $eavSourceFactory,
+ \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig = null
) {
$this->_eavDecimalFactory = $eavDecimalFactory;
$this->_eavSourceFactory = $eavSourceFactory;
+ $this->scopeConfig = $scopeConfig ?: \Magento\Framework\App\ObjectManager::getInstance()->get(
+ \Magento\Framework\App\Config\ScopeConfigInterface::class
+ );
}
/**
@@ -92,6 +109,9 @@ public function getIndexer($type)
*/
public function reindex($ids = null)
{
+ if (!$this->isEavIndexerEnabled()) {
+ return;
+ }
foreach ($this->getIndexers() as $indexer) {
if ($ids === null) {
$indexer->reindexAll();
@@ -149,4 +169,19 @@ protected function processRelations(AbstractEav $indexer, array $ids, bool $only
return array_unique(array_merge($ids, $childIds, $parentIds));
}
+
+ /**
+ * Get EAV indexer status
+ *
+ * @return bool
+ */
+ private function isEavIndexerEnabled(): bool
+ {
+ $eavIndexerStatus = $this->scopeConfig->getValue(
+ self::ENABLE_EAV_INDEXER,
+ \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+ );
+
+ return (bool)$eavIndexerStatus;
+ }
}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Full.php
index bc747e62f641e..802176092d147 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Full.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Full.php
@@ -3,12 +3,15 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Catalog\Model\Indexer\Product\Eav\Action;
use Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher;
/**
* Class Full reindex action
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Full extends \Magento\Catalog\Model\Indexer\Product\Eav\AbstractAction
{
@@ -32,6 +35,11 @@ class Full extends \Magento\Catalog\Model\Indexer\Product\Eav\AbstractAction
*/
private $activeTableSwitcher;
+ /**
+ * @var \Magento\Framework\App\Config\ScopeConfigInterface
+ */
+ private $scopeConfig;
+
/**
* @param \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\DecimalFactory $eavDecimalFactory
* @param \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\SourceFactory $eavSourceFactory
@@ -39,6 +47,7 @@ class Full extends \Magento\Catalog\Model\Indexer\Product\Eav\AbstractAction
* @param \Magento\Framework\Indexer\BatchProviderInterface|null $batchProvider
* @param \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\BatchSizeCalculator $batchSizeCalculator
* @param ActiveTableSwitcher|null $activeTableSwitcher
+ * @param \Magento\Framework\App\Config\ScopeConfigInterface|null $scopeConfig
*/
public function __construct(
\Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\DecimalFactory $eavDecimalFactory,
@@ -46,9 +55,13 @@ public function __construct(
\Magento\Framework\EntityManager\MetadataPool $metadataPool = null,
\Magento\Framework\Indexer\BatchProviderInterface $batchProvider = null,
\Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\BatchSizeCalculator $batchSizeCalculator = null,
- ActiveTableSwitcher $activeTableSwitcher = null
+ ActiveTableSwitcher $activeTableSwitcher = null,
+ \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig = null
) {
- parent::__construct($eavDecimalFactory, $eavSourceFactory);
+ $this->scopeConfig = $scopeConfig ?: \Magento\Framework\App\ObjectManager::getInstance()->get(
+ \Magento\Framework\App\Config\ScopeConfigInterface::class
+ );
+ parent::__construct($eavDecimalFactory, $eavSourceFactory, $scopeConfig);
$this->metadataPool = $metadataPool ?: \Magento\Framework\App\ObjectManager::getInstance()->get(
\Magento\Framework\EntityManager\MetadataPool::class
);
@@ -73,6 +86,9 @@ public function __construct(
*/
public function execute($ids = null)
{
+ if (!$this->isEavIndexerEnabled()) {
+ return;
+ }
try {
foreach ($this->getIndexers() as $indexerName => $indexer) {
$connection = $indexer->getConnection();
@@ -129,4 +145,19 @@ protected function syncData($indexer, $destinationTable, $ids = null)
throw $e;
}
}
+
+ /**
+ * Get EAV indexer status
+ *
+ * @return bool
+ */
+ private function isEavIndexerEnabled(): bool
+ {
+ $eavIndexerStatus = $this->scopeConfig->getValue(
+ self::ENABLE_EAV_INDEXER,
+ \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+ );
+
+ return (bool)$eavIndexerStatus;
+ }
}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Eav/AbstractActionTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Eav/AbstractActionTest.php
index 9d58822fb6073..6ad14af44304e 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Eav/AbstractActionTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Eav/AbstractActionTest.php
@@ -22,6 +22,14 @@ class AbstractActionTest extends \PHPUnit\Framework\TestCase
*/
protected $_eavSourceFactoryMock;
+ /**
+ * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $scopeConfig;
+
+ /**
+ * @return void
+ */
protected function setUp()
{
$this->_eavDecimalFactoryMock = $this->createPartialMock(
@@ -32,12 +40,22 @@ protected function setUp()
\Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\SourceFactory::class,
['create']
);
+ $this->scopeConfig = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class)
+ ->disableOriginalConstructor()
+ ->getMockForAbstractClass();
$this->_model = $this->getMockForAbstractClass(
\Magento\Catalog\Model\Indexer\Product\Eav\AbstractAction::class,
- [$this->_eavDecimalFactoryMock, $this->_eavSourceFactoryMock, []]
+ [
+ $this->_eavDecimalFactoryMock,
+ $this->_eavSourceFactoryMock,
+ $this->scopeConfig
+ ]
);
}
+ /**
+ * @return void
+ */
public function testGetIndexers()
{
$expectedIndexers = [
@@ -73,6 +91,10 @@ public function testGetIndexerWithUnknownTypeThrowsException()
$this->_model->getIndexer('unknown_type');
}
+ /**
+ * @return void
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
public function testGetIndexer()
{
$this->_eavSourceFactoryMock->expects($this->once())
@@ -86,6 +108,10 @@ public function testGetIndexer()
$this->assertEquals('source_return_value', $this->_model->getIndexer('source'));
}
+ /**
+ * @return void
+ * @throws \Exception
+ */
public function testReindexWithoutArgumentsExecutesReindexAll()
{
$eavSource = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\Source::class)
@@ -110,6 +136,10 @@ public function testReindexWithoutArgumentsExecutesReindexAll()
->method('create')
->will($this->returnValue($eavDecimal));
+ $this->scopeConfig->expects($this->once())
+ ->method('getValue')
+ ->willReturn(1);
+
$this->_model->reindex();
}
@@ -174,9 +204,25 @@ public function testReindexWithNotNullArgumentExecutesReindexEntities(
->method('create')
->will($this->returnValue($eavDecimal));
+ $this->scopeConfig->expects($this->once())
+ ->method('getValue')
+ ->willReturn(1);
+
$this->_model->reindex($ids);
}
+ /**
+ * @return void
+ * @throws \Exception
+ */
+ public function testReindexWithDisabledEavIndexer()
+ {
+ $this->scopeConfig->expects($this->once())->method('getValue')->willReturn(0);
+ $this->_eavSourceFactoryMock->expects($this->never())->method('create');
+ $this->_eavDecimalFactoryMock->expects($this->never())->method('create');
+ $this->_model->reindex();
+ }
+
/**
* @return array
*/
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Eav/Action/FullTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Eav/Action/FullTest.php
index c254557904da1..90c3f999a6a8b 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Eav/Action/FullTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Eav/Action/FullTest.php
@@ -5,53 +5,87 @@
*/
namespace Magento\Catalog\Test\Unit\Model\Indexer\Product\Eav\Action;
+use Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\DecimalFactory;
+use Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\SourceFactory;
+use Magento\Framework\EntityManager\MetadataPool;
+use Magento\Framework\Indexer\BatchProviderInterface;
+use Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\BatchSizeCalculator;
+
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class FullTest extends \PHPUnit\Framework\TestCase
{
- public function testExecuteWithAdapterErrorThrowsException()
- {
- $eavDecimalFactory = $this->createPartialMock(
- \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\DecimalFactory::class,
- ['create']
- );
- $eavSourceFactory = $this->createPartialMock(
- \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\SourceFactory::class,
- ['create']
- );
+ /**
+ * @var \Magento\Catalog\Model\Indexer\Product\Eav\Action\Full|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $model;
- $exceptionMessage = 'exception message';
- $exception = new \Exception($exceptionMessage);
+ /**
+ * @var DecimalFactory|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $eavDecimalFactory;
- $eavDecimalFactory->expects($this->once())
- ->method('create')
- ->will($this->throwException($exception));
+ /**
+ * @var SourceFactory|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $eavSourceFactory;
- $metadataMock = $this->createMock(\Magento\Framework\EntityManager\MetadataPool::class);
- $batchProviderMock = $this->createMock(\Magento\Framework\Indexer\BatchProviderInterface::class);
+ /**
+ * @var MetadataPool|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $metadataPool;
- $batchManagementMock = $this->createMock(
- \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\BatchSizeCalculator::class
- );
+ /**
+ * @var BatchProviderInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $batchProvider;
- $tableSwitcherMock = $this->getMockBuilder(
- \Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher::class
- )->disableOriginalConstructor()->getMock();
-
- $model = new \Magento\Catalog\Model\Indexer\Product\Eav\Action\Full(
- $eavDecimalFactory,
- $eavSourceFactory,
- $metadataMock,
- $batchProviderMock,
- $batchManagementMock,
- $tableSwitcherMock
- );
+ /**
+ * @var BatchSizeCalculator|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $batchSizeCalculator;
+
+ /**
+ * @var ActiveTableSwitcher|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $activeTableSwitcher;
+
+ /**
+ * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $scopeConfig;
- $this->expectException(\Magento\Framework\Exception\LocalizedException::class);
- $this->expectExceptionMessage($exceptionMessage);
+ /**
+ * @return void
+ */
+ protected function setUp()
+ {
+ $this->eavDecimalFactory = $this->createPartialMock(DecimalFactory::class, ['create']);
+ $this->eavSourceFactory = $this->createPartialMock(SourceFactory::class, ['create']);
+ $this->metadataPool = $this->createMock(MetadataPool::class);
+ $this->batchProvider = $this->getMockForAbstractClass(BatchProviderInterface::class);
+ $this->batchSizeCalculator = $this->createMock(BatchSizeCalculator::class);
+ $this->activeTableSwitcher = $this->createMock(ActiveTableSwitcher::class);
+ $this->scopeConfig = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class)
+ ->disableOriginalConstructor()
+ ->getMockForAbstractClass();
- $model->execute();
+ $objectManager = new ObjectManager($this);
+ $this->model = $objectManager->getObject(
+ \Magento\Catalog\Model\Indexer\Product\Eav\Action\Full::class,
+ [
+ 'eavDecimalFactory' => $this->eavDecimalFactory,
+ 'eavSourceFactory' => $this->eavSourceFactory,
+ 'metadataPool' => $this->metadataPool,
+ 'batchProvider' => $this->batchProvider,
+ 'batchSizeCalculator' => $this->batchSizeCalculator,
+ 'activeTableSwitcher' => $this->activeTableSwitcher,
+ 'scopeConfig' => $this->scopeConfig
+ ]
+ );
}
/**
@@ -59,14 +93,7 @@ public function testExecuteWithAdapterErrorThrowsException()
*/
public function testExecute()
{
- $eavDecimalFactory = $this->createPartialMock(
- \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\DecimalFactory::class,
- ['create']
- );
- $eavSourceFactory = $this->createPartialMock(
- \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\SourceFactory::class,
- ['create']
- );
+ $this->scopeConfig->expects($this->once())->method('getValue')->willReturn(1);
$ids = [1, 2, 3];
$connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class)
@@ -90,42 +117,29 @@ public function testExecute()
$eavSource->expects($this->atLeastOnce())->method('getConnection')->willReturn($connectionMock);
$eavDecimal->expects($this->atLeastOnce())->method('getConnection')->willReturn($connectionMock);
- $eavDecimal->expects($this->once())
- ->method('reindexEntities')
- ->with($ids);
+ $eavDecimal->expects($this->once())->method('reindexEntities')->with($ids);
- $eavSource->expects($this->once())
- ->method('reindexEntities')
- ->with($ids);
+ $eavSource->expects($this->once())->method('reindexEntities')->with($ids);
- $eavDecimalFactory->expects($this->once())
- ->method('create')
- ->will($this->returnValue($eavSource));
+ $this->eavDecimalFactory->expects($this->once())->method('create')->will($this->returnValue($eavSource));
- $eavSourceFactory->expects($this->once())
- ->method('create')
- ->will($this->returnValue($eavDecimal));
+ $this->eavSourceFactory->expects($this->once())->method('create')->will($this->returnValue($eavDecimal));
- $metadataMock = $this->createMock(\Magento\Framework\EntityManager\MetadataPool::class);
$entityMetadataMock = $this->getMockBuilder(\Magento\Framework\EntityManager\EntityMetadataInterface::class)
->getMockForAbstractClass();
- $metadataMock->expects($this->atLeastOnce())
+ $this->metadataPool->expects($this->atLeastOnce())
->method('getMetadata')
->with(\Magento\Catalog\Api\Data\ProductInterface::class)
->willReturn($entityMetadataMock);
- $batchProviderMock = $this->createMock(\Magento\Framework\Indexer\BatchProviderInterface::class);
- $batchProviderMock->expects($this->atLeastOnce())
+ $this->batchProvider->expects($this->atLeastOnce())
->method('getBatches')
->willReturn([['from' => 10, 'to' => 100]]);
- $batchProviderMock->expects($this->atLeastOnce())
+ $this->batchProvider->expects($this->atLeastOnce())
->method('getBatchIds')
->willReturn($ids);
- $batchManagementMock = $this->createMock(
- \Magento\Catalog\Model\ResourceModel\Product\Indexer\Eav\BatchSizeCalculator::class
- );
$selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
->disableOriginalConstructor()
->getMock();
@@ -134,19 +148,17 @@ public function testExecute()
$selectMock->expects($this->atLeastOnce())->method('distinct')->willReturnSelf();
$selectMock->expects($this->atLeastOnce())->method('from')->willReturnSelf();
- $tableSwitcherMock = $this->getMockBuilder(
- \Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher::class
- )->disableOriginalConstructor()->getMock();
-
- $model = new \Magento\Catalog\Model\Indexer\Product\Eav\Action\Full(
- $eavDecimalFactory,
- $eavSourceFactory,
- $metadataMock,
- $batchProviderMock,
- $batchManagementMock,
- $tableSwitcherMock
- );
+ $this->model->execute();
+ }
- $model->execute();
+ /**
+ * @return void
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ public function testExecuteWithDisabledEavIndexer()
+ {
+ $this->scopeConfig->expects($this->once())->method('getValue')->willReturn(0);
+ $this->metadataPool->expects($this->never())->method('getMetadata');
+ $this->model->execute();
}
}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Conditions.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Conditions.php
index 0b4748c933a3c..9d1a23611dc27 100644
--- a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Conditions.php
+++ b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Conditions.php
@@ -66,7 +66,7 @@ public function getTabTitle()
}
/**
- * Returns status flag about this tab can be showen or not
+ * Returns status flag about this tab can be shown or not
*
* @return bool
* @codeCoverageIgnore
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Widget/Chooser/Sku.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Widget/Chooser/Sku.php
index 306d3b9a347b4..87cb18253a107 100644
--- a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Widget/Chooser/Sku.php
+++ b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Widget/Chooser/Sku.php
@@ -139,7 +139,7 @@ protected function _getCpCollectionInstance()
}
/**
- * Define Cooser Grid Columns and filters
+ * Define Chooser Grid Columns and filters
*
* @return $this
*/
diff --git a/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php b/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php
new file mode 100644
index 0000000000000..c624f9d1c2e52
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Plugin/EnableEavIndexer.php
@@ -0,0 +1,33 @@
+getData(self::SEARCH_ENGINE_VALUE_PATH);
+ if ($searchEngine === 'mysql') {
+ $data = $subject->getData();
+ $data['groups']['search']['fields']['enable_eav_indexer']['value'] = 1;
+
+ $subject->setData($data);
+ }
+ }
+}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Plugin/EnableEavIndexerTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Plugin/EnableEavIndexerTest.php
new file mode 100644
index 0000000000000..0eac2e3309aec
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Plugin/EnableEavIndexerTest.php
@@ -0,0 +1,68 @@
+config = $this->getMockBuilder(\Magento\Config\Model\Config::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getData', 'setData'])
+ ->getMock();
+
+ $objectManagerHelper = new ObjectManagerHelper($this);
+ $this->model = $objectManagerHelper->getObject(
+ \Magento\CatalogSearch\Plugin\EnableEavIndexer::class
+ );
+ }
+
+ /**
+ * Test with other search engine (not MySQL) selected in config
+ *
+ * @return void
+ */
+ public function testBeforeSave()
+ {
+ $this->config->expects($this->once())->method('getData')->willReturn('elasticsearch');
+ $this->config->expects($this->never())->method('setData')->willReturnSelf();
+
+ $this->model->beforeSave($this->config);
+ }
+
+ /**
+ * Test with MySQL search engine selected in config
+ *
+ * @return void
+ */
+ public function testBeforeSaveMysqlSearchEngine()
+ {
+ $this->config->expects($this->at(0))->method('getData')->willReturn('mysql');
+ $this->config->expects($this->at(1))->method('getData')->willReturn([]);
+ $this->config->expects($this->once())->method('setData')->willReturnSelf();
+
+ $this->model->beforeSave($this->config);
+ }
+}
diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json
index 298511ef428a9..1000e349b6f9a 100644
--- a/app/code/Magento/CatalogSearch/composer.json
+++ b/app/code/Magento/CatalogSearch/composer.json
@@ -9,7 +9,7 @@
"magento/framework": "*",
"magento/module-backend": "*",
"magento/module-catalog": "*",
- "magento/module-indexer": "100.2.*",
+ "magento/module-indexer": "*",
"magento/module-catalog-inventory": "*",
"magento/module-customer": "*",
"magento/module-directory": "*",
@@ -19,6 +19,9 @@
"magento/module-theme": "*",
"magento/module-ui": "*"
},
+ "suggest": {
+ "magento/module-config": "*"
+ },
"type": "magento2-module",
"license": [
"OSL-3.0",
diff --git a/app/code/Magento/CatalogSearch/etc/adminhtml/system.xml b/app/code/Magento/CatalogSearch/etc/adminhtml/system.xml
index 18d2cdf542799..39235511eaeec 100644
--- a/app/code/Magento/CatalogSearch/etc/adminhtml/system.xml
+++ b/app/code/Magento/CatalogSearch/etc/adminhtml/system.xml
@@ -36,6 +36,14 @@
validate-digits
+
+
+ Enable/Disable Product EAV indexer to improve indexation speed. Make sure that indexer is not used by 3rd party extensions.
+
+ mysql
+
+ Magento\Config\Model\Config\Source\Yesno
+
diff --git a/app/code/Magento/CatalogSearch/etc/config.xml b/app/code/Magento/CatalogSearch/etc/config.xml
index d2b50fe9f5336..66b79226c9f34 100644
--- a/app/code/Magento/CatalogSearch/etc/config.xml
+++ b/app/code/Magento/CatalogSearch/etc/config.xml
@@ -17,6 +17,7 @@
128
100
8
+ 1
diff --git a/app/code/Magento/CatalogSearch/etc/di.xml b/app/code/Magento/CatalogSearch/etc/di.xml
index acec17f48211e..cc07384d4c525 100644
--- a/app/code/Magento/CatalogSearch/etc/di.xml
+++ b/app/code/Magento/CatalogSearch/etc/di.xml
@@ -337,4 +337,7 @@
+
+
+
diff --git a/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php b/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php
index f22879df0ae0c..29adc1816d337 100644
--- a/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php
+++ b/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php
@@ -101,6 +101,9 @@ public function loadAttributeOptions()
/**
* {@inheritdoc}
+ *
+ * @param array &$attributes
+ * @return void
*/
protected function _addSpecialAttributes(array &$attributes)
{
@@ -163,8 +166,6 @@ protected function addGlobalAttribute(
\Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute,
\Magento\Catalog\Model\ResourceModel\Product\Collection $collection
) {
- $storeId = $this->storeManager->getStore()->getId();
-
switch ($attribute->getBackendType()) {
case 'decimal':
case 'datetime':
@@ -173,10 +174,15 @@ protected function addGlobalAttribute(
$collection->addAttributeToSelect($attribute->getAttributeCode(), 'inner');
break;
default:
- $alias = 'at_' . md5($this->getId()) . $attribute->getAttributeCode();
+ $alias = 'at_' . sha1($this->getId()) . $attribute->getAttributeCode();
+
+ $connection = $this->_productResource->getConnection();
+ $storeId = $connection->getIfNullSql($alias . '.store_id', $this->storeManager->getStore()->getId());
+ $linkField = $attribute->getEntity()->getLinkField();
+
$collection->getSelect()->join(
- [$alias => $collection->getTable('catalog_product_index_eav')],
- "($alias.entity_id = e.entity_id) AND ($alias.store_id = $storeId)" .
+ [$alias => $collection->getTable('catalog_product_entity_varchar')],
+ "($alias.$linkField = e.$linkField) AND ($alias.store_id = $storeId)" .
" AND ($alias.attribute_id = {$attribute->getId()})",
[]
);
@@ -225,6 +231,8 @@ protected function addNotGlobalAttribute(
/**
* {@inheritdoc}
+ *
+ * @return string
*/
public function getMappedSqlField()
{
@@ -244,6 +252,9 @@ public function getMappedSqlField()
/**
* {@inheritdoc}
+ *
+ * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection
+ * @return $this
*/
public function collectValidatedAttributes($productCollection)
{
diff --git a/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/ProductTest.php b/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/ProductTest.php
index 09270b6b41fc7..219cae6829299 100644
--- a/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/ProductTest.php
+++ b/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/ProductTest.php
@@ -17,11 +17,21 @@ class ProductTest extends \PHPUnit\Framework\TestCase
*/
private $model;
+ /**
+ * @var \Magento\Catalog\Model\ResourceModel\Product|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $productResource;
+
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $attributeMock;
+ /**
+ * @inheritdoc
+ *
+ * @return void
+ */
protected function setUp()
{
$objectManagerHelper = new ObjectManager($this);
@@ -33,9 +43,9 @@ protected function setUp()
$storeManager = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
$storeMock = $this->createMock(\Magento\Store\Api\Data\StoreInterface::class);
$storeManager->expects($this->any())->method('getStore')->willReturn($storeMock);
- $productResource = $this->createMock(\Magento\Catalog\Model\ResourceModel\Product::class);
- $productResource->expects($this->once())->method('loadAllAttributes')->willReturnSelf();
- $productResource->expects($this->once())->method('getAttributesByCode')->willReturn([]);
+ $this->productResource = $this->createMock(\Magento\Catalog\Model\ResourceModel\Product::class);
+ $this->productResource->expects($this->once())->method('loadAllAttributes')->willReturnSelf();
+ $this->productResource->expects($this->once())->method('getAttributesByCode')->willReturn([]);
$productCategoryList = $this->getMockBuilder(\Magento\Catalog\Model\ProductCategoryList::class)
->disableOriginalConstructor()
->getMock();
@@ -45,7 +55,7 @@ protected function setUp()
[
'config' => $eavConfig,
'storeManager' => $storeManager,
- 'productResource' => $productResource,
+ 'productResource' => $this->productResource,
'productCategoryList' => $productCategoryList,
'data' => [
'rule' => $ruleMock,
@@ -55,6 +65,11 @@ protected function setUp()
);
}
+ /**
+ * Test addToCollection method.
+ *
+ * @return void
+ */
public function testAddToCollection()
{
$collectionMock = $this->createMock(\Magento\Catalog\Model\ResourceModel\Product\Collection::class);
@@ -67,9 +82,22 @@ public function testAddToCollection()
$this->attributeMock->expects($this->once())->method('isScopeGlobal')->willReturn(true);
$this->attributeMock->expects($this->once())->method('isScopeGlobal')->willReturn(true);
$this->attributeMock->expects($this->once())->method('getBackendType')->willReturn('multiselect');
+
+ $entityMock = $this->createMock(\Magento\Eav\Model\Entity\AbstractEntity::class);
+ $entityMock->expects($this->once())->method('getLinkField')->willReturn('entitiy_id');
+ $this->attributeMock->expects($this->once())->method('getEntity')->willReturn($entityMock);
+ $connection = $this->createMock(\Magento\Framework\DB\Adapter\AdapterInterface::class);
+
+ $this->productResource->expects($this->atLeastOnce())->method('getConnection')->willReturn($connection);
+
$this->model->addToCollection($collectionMock);
}
+ /**
+ * Test getMappedSqlField method.
+ *
+ * @return void
+ */
public function testGetMappedSqlFieldSku()
{
$this->model->setAttribute('sku');
diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml
index e70bccbfdfe2b..4c9ef93c2c4d3 100644
--- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml
@@ -93,13 +93,13 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -108,7 +108,7 @@
-
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml
index 866f5f5070940..a12852ea1ef25 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml
@@ -36,8 +36,8 @@
-
-
+
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml
index e7091dbfae215..602e04b138ea3 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml
@@ -17,6 +17,7 @@
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Product/View/Type/ConfigurableTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Product/View/Type/ConfigurableTest.php
index b45306d670bff..25d8412c91056 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Product/View/Type/ConfigurableTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Product/View/Type/ConfigurableTest.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\ConfigurableProduct\Test\Unit\Block\Product\View\Type;
use Magento\Customer\Model\Session;
@@ -83,6 +84,9 @@ class ConfigurableTest extends \PHPUnit\Framework\TestCase
*/
private $variationPricesMock;
+ /**
+ * {@inheritDoc}
+ */
protected function setUp()
{
$this->mockContextObject();
@@ -174,7 +178,7 @@ protected function setUp()
*
* @return array
*/
- public function cacheKeyProvider() : array
+ public function cacheKeyProvider(): array
{
return [
'without_currency_and_customer_group' => [
@@ -313,11 +317,7 @@ public function testGetJsonConfig()
$this->localeFormat->expects($this->atLeastOnce())->method('getPriceFormat')->willReturn([]);
$this->localeFormat->expects($this->any())
->method('getNumber')
- ->willReturnMap([
- [$amount, $amount],
- [$priceQty, $priceQty],
- [$percentage, $percentage],
- ]);
+ ->willReturnArgument(0);
$this->variationPricesMock->expects($this->once())
->method('getFormattedPrices')
@@ -349,13 +349,13 @@ public function testGetJsonConfig()
/**
* Retrieve array with expected parameters for method getJsonConfig()
*
- * @param $productId
- * @param $amount
- * @param $priceQty
- * @param $percentage
+ * @param int $productId
+ * @param double $amount
+ * @param int $priceQty
+ * @param int $percentage
* @return array
*/
- private function getExpectedArray($productId, $amount, $priceQty, $percentage)
+ private function getExpectedArray($productId, $amount, $priceQty, $percentage): array
{
$expectedArray = [
'attributes' => [],
diff --git a/app/code/Magento/Customer/Controller/Address/FormPost.php b/app/code/Magento/Customer/Controller/Address/FormPost.php
index 21334f51b1752..60e1f6eb172f5 100644
--- a/app/code/Magento/Customer/Controller/Address/FormPost.php
+++ b/app/code/Magento/Customer/Controller/Address/FormPost.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Customer\Controller\Address;
use Magento\Customer\Api\AddressRepositoryInterface;
@@ -197,17 +198,17 @@ public function execute()
try {
$address = $this->_extractAddress();
$this->_addressRepository->save($address);
- $this->messageManager->addSuccess(__('You saved the address.'));
+ $this->messageManager->addSuccessMessage(__('You saved the address.'));
$url = $this->_buildUrl('*/*/index', ['_secure' => true]);
return $this->resultRedirectFactory->create()->setUrl($this->_redirect->success($url));
} catch (InputException $e) {
- $this->messageManager->addError($e->getMessage());
+ $this->messageManager->addErrorMessage($e->getMessage());
foreach ($e->getErrors() as $error) {
- $this->messageManager->addError($error->getMessage());
+ $this->messageManager->addErrorMessage($error->getMessage());
}
} catch (\Exception $e) {
$redirectUrl = $this->_buildUrl('*/*/index');
- $this->messageManager->addException($e, __('We can\'t save the address.'));
+ $this->messageManager->addExceptionMessage($e, __('We can\'t save the address.'));
}
$url = $redirectUrl;
diff --git a/app/code/Magento/Customer/Model/Metadata/Form/Text.php b/app/code/Magento/Customer/Model/Metadata/Form/Text.php
index 9ef6df0a6d36e..c8b9a1e46a127 100644
--- a/app/code/Magento/Customer/Model/Metadata/Form/Text.php
+++ b/app/code/Magento/Customer/Model/Metadata/Form/Text.php
@@ -5,8 +5,10 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Customer\Model\Metadata\Form;
+use Magento\Customer\Api\Data\AttributeMetadataInterface;
use Magento\Framework\Api\ArrayObjectSearch;
class Text extends AbstractData
@@ -19,7 +21,7 @@ class Text extends AbstractData
/**
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
* @param \Psr\Log\LoggerInterface $logger
- * @param \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute
+ * @param AttributeMetadataInterface $attribute
* @param \Magento\Framework\Locale\ResolverInterface $localeResolver
* @param string $value
* @param string $entityTypeCode
@@ -29,7 +31,7 @@ class Text extends AbstractData
public function __construct(
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
\Psr\Log\LoggerInterface $logger,
- \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute,
+ AttributeMetadataInterface $attribute,
\Magento\Framework\Locale\ResolverInterface $localeResolver,
$value,
$entityTypeCode,
@@ -41,7 +43,7 @@ public function __construct(
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function extractValue(\Magento\Framework\App\RequestInterface $request)
{
@@ -49,7 +51,7 @@ public function extractValue(\Magento\Framework\App\RequestInterface $request)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
@@ -72,26 +74,7 @@ public function validateValue($value)
return true;
}
- // validate length
- $length = $this->_string->strlen(trim($value));
-
- $validateRules = $attribute->getValidationRules();
-
- $minTextLength = ArrayObjectSearch::getArrayElementByName(
- $validateRules,
- 'min_text_length'
- );
- if ($minTextLength !== null && $length < $minTextLength) {
- $errors[] = __('"%1" length must be equal or greater than %2 characters.', $label, $minTextLength);
- }
-
- $maxTextLength = ArrayObjectSearch::getArrayElementByName(
- $validateRules,
- 'max_text_length'
- );
- if ($maxTextLength !== null && $length > $maxTextLength) {
- $errors[] = __('"%1" length must be equal or less than %2 characters.', $label, $maxTextLength);
- }
+ $errors = $this->validateLength($value, $attribute, $errors);
$result = $this->_validateInputRule($value);
if ($result !== true) {
@@ -105,7 +88,7 @@ public function validateValue($value)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function compactValue($value)
{
@@ -113,7 +96,7 @@ public function compactValue($value)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function restoreValue($value)
{
@@ -121,10 +104,48 @@ public function restoreValue($value)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function outputValue($format = \Magento\Customer\Model\Metadata\ElementFactory::OUTPUT_FORMAT_TEXT)
{
return $this->_applyOutputFilter($this->_value);
}
+
+ /**
+ * Length validation
+ *
+ * @param mixed $value
+ * @param AttributeMetadataInterface $attribute
+ * @param array $errors
+ * @return array
+ */
+ private function validateLength($value, AttributeMetadataInterface $attribute, array $errors): array
+ {
+ // validate length
+ $label = __($attribute->getStoreLabel());
+
+ $length = $this->_string->strlen(trim($value));
+
+ $validateRules = $attribute->getValidationRules();
+
+ if (!empty(ArrayObjectSearch::getArrayElementByName($validateRules, 'input_validation'))) {
+ $minTextLength = ArrayObjectSearch::getArrayElementByName(
+ $validateRules,
+ 'min_text_length'
+ );
+ if ($minTextLength !== null && $length < $minTextLength) {
+ $errors[] = __('"%1" length must be equal or greater than %2 characters.', $label, $minTextLength);
+ }
+
+ $maxTextLength = ArrayObjectSearch::getArrayElementByName(
+ $validateRules,
+ 'max_text_length'
+ );
+ if ($maxTextLength !== null && $length > $maxTextLength) {
+ $errors[] = __('"%1" length must be equal or less than %2 characters.', $label, $maxTextLength);
+ }
+ }
+
+ return $errors;
+ }
}
diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Address/FormPostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Address/FormPostTest.php
index 4ad1b5cbc96bd..c2a795fc95016 100644
--- a/app/code/Magento/Customer/Test/Unit/Controller/Address/FormPostTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Controller/Address/FormPostTest.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Customer\Test\Unit\Controller\Address;
use Magento\Customer\Api\AddressRepositoryInterface;
@@ -162,6 +163,9 @@ class FormPostTest extends \PHPUnit\Framework\TestCase
*/
private $customerAddressMapper;
+ /**
+ * {@inheritDoc}
+ */
protected function setUp()
{
$this->prepareContext();
@@ -230,7 +234,10 @@ protected function setUp()
);
}
- protected function prepareContext()
+ /**
+ * Prepares context
+ */
+ protected function prepareContext(): void
{
$this->context = $this->getMockBuilder(\Magento\Framework\App\Action\Context::class)
->disableOriginalConstructor()
@@ -284,7 +291,10 @@ protected function prepareContext()
->willReturn($this->messageManager);
}
- protected function prepareAddress()
+ /**
+ * Prepare address
+ */
+ protected function prepareAddress(): void
{
$this->addressRepository = $this->getMockBuilder(\Magento\Customer\Api\AddressRepositoryInterface::class)
->getMockForAbstractClass();
@@ -303,7 +313,10 @@ protected function prepareAddress()
->willReturn($this->addressData);
}
- protected function prepareRegion()
+ /**
+ * Prepare region
+ */
+ protected function prepareRegion(): void
{
$this->region = $this->getMockBuilder(\Magento\Directory\Model\Region::class)
->disableOriginalConstructor()
@@ -335,7 +348,10 @@ protected function prepareRegion()
->willReturn($this->regionData);
}
- protected function prepareForm()
+ /**
+ * Prepare form
+ */
+ protected function prepareForm(): void
{
$this->form = $this->getMockBuilder(\Magento\Customer\Model\Metadata\Form::class)
->disableOriginalConstructor()
@@ -346,7 +362,10 @@ protected function prepareForm()
->getMock();
}
- public function testExecuteNoFormKey()
+ /**
+ * Test form without formKey
+ */
+ public function testExecuteNoFormKey(): void
{
$this->formKeyValidator->expects($this->once())
->method('validate')
@@ -361,7 +380,10 @@ public function testExecuteNoFormKey()
$this->assertEquals($this->resultRedirect, $this->model->execute());
}
- public function testExecuteNoPostData()
+ /**
+ * Test executing without post data
+ */
+ public function testExecuteNoPostData(): void
{
$postValue = 'post_value';
$url = 'url';
@@ -409,10 +431,11 @@ public function testExecuteNoPostData()
}
/**
+ * Tests executing
+ *
* @param int $addressId
* @param int $countryId
* @param int $customerId
- * @param bool $isRegionRequired
* @param int $regionId
* @param string $region
* @param string $regionCode
@@ -433,7 +456,7 @@ public function testExecute(
$newRegionId,
$newRegion,
$newRegionCode
- ) {
+ ): void {
$existingAddressData = [
'country_id' => $countryId,
'region_id' => $regionId,
@@ -517,7 +540,8 @@ public function testExecute(
->willReturnMap([
[
$this->regionData,
- $regionData, \Magento\Customer\Api\Data\RegionInterface::class,
+ $regionData,
+ \Magento\Customer\Api\Data\RegionInterface::class,
$this->dataObjectHelper,
],
[
@@ -549,7 +573,7 @@ public function testExecute(
->willReturnSelf();
$this->messageManager->expects($this->once())
- ->method('addSuccess')
+ ->method('addSuccessMessage')
->with(__('You saved the address.'))
->willReturnSelf();
@@ -581,7 +605,7 @@ public function testExecute(
/**
* @return array
*/
- public function dataProviderTestExecute()
+ public function dataProviderTestExecute(): array
{
return [
[1, 1, 1, null, '', null, '', null, ''],
@@ -612,7 +636,10 @@ public function dataProviderTestExecute()
];
}
- public function testExecuteInputException()
+ /**
+ * Tests input exception
+ */
+ public function testExecuteInputException(): void
{
$addressId = 1;
$postValue = 'post_value';
@@ -640,7 +667,7 @@ public function testExecuteInputException()
->willThrowException(new InputException(__('InputException')));
$this->messageManager->expects($this->once())
- ->method('addError')
+ ->method('addErrorMessage')
->with('InputException')
->willReturnSelf();
@@ -674,7 +701,10 @@ public function testExecuteInputException()
$this->assertEquals($this->resultRedirect, $this->model->execute());
}
- public function testExecuteException()
+ /**
+ * Tests exception
+ */
+ public function testExecuteException(): void
{
$addressId = 1;
$postValue = 'post_value';
@@ -703,7 +733,7 @@ public function testExecuteException()
->willThrowException($exception);
$this->messageManager->expects($this->once())
- ->method('addException')
+ ->method('addExceptionMessage')
->with($exception, __('We can\'t save the address.'))
->willReturnSelf();
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/TextTest.php b/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/TextTest.php
index b95987cba1dcf..7987bdc79ed98 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/TextTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/TextTest.php
@@ -5,8 +5,10 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Customer\Test\Unit\Model\Metadata\Form;
+use Magento\Customer\Api\Data\ValidationRuleInterface;
use Magento\Customer\Model\Metadata\Form\Text;
class TextTest extends AbstractFormTestCase
@@ -14,6 +16,9 @@ class TextTest extends AbstractFormTestCase
/** @var \Magento\Framework\Stdlib\StringUtils */
protected $stringHelper;
+ /**
+ * {@inheritDoc}
+ */
protected function setUp()
{
parent::setUp();
@@ -111,7 +116,7 @@ public function validateValueRequiredDataProvider()
*/
public function testValidateValueLength($value, $expected)
{
- $minTextLengthRule = $this->getMockBuilder(\Magento\Customer\Api\Data\ValidationRuleInterface::class)
+ $minTextLengthRule = $this->getMockBuilder(ValidationRuleInterface::class)
->disableOriginalConstructor()
->setMethods(['getName', 'getValue'])
->getMockForAbstractClass();
@@ -122,7 +127,7 @@ public function testValidateValueLength($value, $expected)
->method('getValue')
->will($this->returnValue(4));
- $maxTextLengthRule = $this->getMockBuilder(\Magento\Customer\Api\Data\ValidationRuleInterface::class)
+ $maxTextLengthRule = $this->getMockBuilder(ValidationRuleInterface::class)
->disableOriginalConstructor()
->setMethods(['getName', 'getValue'])
->getMockForAbstractClass();
@@ -133,7 +138,19 @@ public function testValidateValueLength($value, $expected)
->method('getValue')
->will($this->returnValue(8));
+ $inputValidationRule = $this->getMockBuilder(ValidationRuleInterface::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getName', 'getValue'])
+ ->getMockForAbstractClass();
+ $inputValidationRule->expects($this->any())
+ ->method('getName')
+ ->will($this->returnValue('input_validation'));
+ $inputValidationRule->expects($this->any())
+ ->method('getValue')
+ ->will($this->returnValue('other'));
+
$validationRules = [
+ 'input_validation' => $inputValidationRule,
'min_text_length' => $minTextLengthRule,
'max_text_length' => $maxTextLengthRule,
];
diff --git a/app/code/Magento/Directory/Model/Currency/Import/CurrencyConverterApi.php b/app/code/Magento/Directory/Model/Currency/Import/CurrencyConverterApi.php
new file mode 100644
index 0000000000000..f52886a14264d
--- /dev/null
+++ b/app/code/Magento/Directory/Model/Currency/Import/CurrencyConverterApi.php
@@ -0,0 +1,146 @@
+scopeConfig = $scopeConfig;
+ $this->httpClientFactory = $httpClientFactory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function fetchRates()
+ {
+ $data = [];
+ $currencies = $this->_getCurrencyCodes();
+ $defaultCurrencies = $this->_getDefaultCurrencyCodes();
+
+ foreach ($defaultCurrencies as $currencyFrom) {
+ if (!isset($data[$currencyFrom])) {
+ $data[$currencyFrom] = [];
+ }
+ $data = $this->convertBatch($data, $currencyFrom, $currencies);
+ ksort($data[$currencyFrom]);
+ }
+ return $data;
+ }
+
+ /**
+ * Return currencies convert rates in batch mode
+ *
+ * @param array $data
+ * @param string $currencyFrom
+ * @param array $currenciesTo
+ * @return array
+ */
+ private function convertBatch($data, $currencyFrom, $currenciesTo)
+ {
+ foreach ($currenciesTo as $to) {
+ set_time_limit(0);
+ try {
+ $url = str_replace('{{CURRENCY_FROM}}', $currencyFrom, self::CURRENCY_CONVERTER_URL);
+ $url = str_replace('{{CURRENCY_TO}}', $to, $url);
+ $response = $this->getServiceResponse($url);
+ if ($currencyFrom == $to) {
+ $data[$currencyFrom][$to] = $this->_numberFormat(1);
+ } else {
+ if (empty($response)) {
+ $this->_messages[] = __('We can\'t retrieve a rate from %1 for %2.', $url, $to);
+ $data[$currencyFrom][$to] = null;
+ } else {
+ $data[$currencyFrom][$to] = $this->_numberFormat(
+ (double)$response[$currencyFrom . '_' . $to]
+ );
+ }
+ }
+ } finally {
+ ini_restore('max_execution_time');
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * Get Fixer.io service response
+ *
+ * @param string $url
+ * @param int $retry
+ * @return array
+ */
+ private function getServiceResponse($url, $retry = 0)
+ {
+ /** @var \Magento\Framework\HTTP\ZendClient $httpClient */
+ $httpClient = $this->httpClientFactory->create();
+ $response = [];
+
+ try {
+ $jsonResponse = $httpClient->setUri(
+ $url
+ )->setConfig(
+ [
+ 'timeout' => $this->scopeConfig->getValue(
+ 'currency/currencyconverterapi/timeout',
+ \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+ ),
+ ]
+ )->request(
+ 'GET'
+ )->getBody();
+
+ $response = json_decode($jsonResponse, true);
+ } catch (\Exception $e) {
+ if ($retry == 0) {
+ $response = $this->getServiceResponse($url, 1);
+ }
+ }
+ return $response;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function _convert($currencyFrom, $currencyTo)
+ {
+ return 1;
+ }
+}
diff --git a/app/code/Magento/Directory/etc/adminhtml/system.xml b/app/code/Magento/Directory/etc/adminhtml/system.xml
index 15a82e006bffe..cae3b1c41db36 100644
--- a/app/code/Magento/Directory/etc/adminhtml/system.xml
+++ b/app/code/Magento/Directory/etc/adminhtml/system.xml
@@ -52,6 +52,12 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Directory/etc/config.xml b/app/code/Magento/Directory/etc/config.xml
index fa4e9d64d10d8..de3ff626bc12c 100644
--- a/app/code/Magento/Directory/etc/config.xml
+++ b/app/code/Magento/Directory/etc/config.xml
@@ -27,6 +27,9 @@
100
+
+ 100
+
0
diff --git a/app/code/Magento/Directory/etc/di.xml b/app/code/Magento/Directory/etc/di.xml
index 02e16af29ea14..4d0e51ab9f45a 100644
--- a/app/code/Magento/Directory/etc/di.xml
+++ b/app/code/Magento/Directory/etc/di.xml
@@ -22,6 +22,10 @@
- Fixer.io
- Magento\Directory\Model\Currency\Import\FixerIo
+ -
+
- Currency Converter API
+ - Magento\Directory\Model\Currency\Import\CurrencyConverterApi
+
diff --git a/app/code/Magento/Eav/Model/Attribute/Data/Text.php b/app/code/Magento/Eav/Model/Attribute/Data/Text.php
index 242f4e98108c9..f81fb2affd3b3 100644
--- a/app/code/Magento/Eav/Model/Attribute/Data/Text.php
+++ b/app/code/Magento/Eav/Model/Attribute/Data/Text.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Eav\Model\Attribute\Data;
use Magento\Framework\App\RequestInterface;
@@ -76,19 +77,9 @@ public function validateValue($value)
return true;
}
- // validate length
- $length = $this->_string->strlen(trim($value));
-
- $validateRules = $attribute->getValidateRules();
- if (!empty($validateRules['min_text_length']) && $length < $validateRules['min_text_length']) {
- $label = __($attribute->getStoreLabel());
- $v = $validateRules['min_text_length'];
- $errors[] = __('"%1" length must be equal or greater than %2 characters.', $label, $v);
- }
- if (!empty($validateRules['max_text_length']) && $length > $validateRules['max_text_length']) {
- $label = __($attribute->getStoreLabel());
- $v = $validateRules['max_text_length'];
- $errors[] = __('"%1" length must be equal or less than %2 characters.', $label, $v);
+ $result = $this->validateLength($attribute, $value);
+ if (count($result) !== 0) {
+ $errors = array_merge($errors, $result);
}
$result = $this->_validateInputRule($value);
@@ -142,4 +133,33 @@ public function outputValue($format = \Magento\Eav\Model\AttributeDataFactory::O
return $value;
}
+
+ /**
+ * Validates value length by attribute rules
+ *
+ * @param \Magento\Eav\Model\Attribute $attribute
+ * @param string $value
+ * @return array errors
+ */
+ private function validateLength(\Magento\Eav\Model\Attribute $attribute, $value): array
+ {
+ $errors = [];
+ $length = $this->_string->strlen(trim($value));
+ $validateRules = $attribute->getValidateRules();
+
+ if (!empty($validateRules['input_validation'])) {
+ if (!empty($validateRules['min_text_length']) && $length < $validateRules['min_text_length']) {
+ $label = __($attribute->getStoreLabel());
+ $v = $validateRules['min_text_length'];
+ $errors[] = __('"%1" length must be equal or greater than %2 characters.', $label, $v);
+ }
+ if (!empty($validateRules['max_text_length']) && $length > $validateRules['max_text_length']) {
+ $label = __($attribute->getStoreLabel());
+ $v = $validateRules['max_text_length'];
+ $errors[] = __('"%1" length must be equal or less than %2 characters.', $label, $v);
+ }
+ }
+
+ return $errors;
+ }
}
diff --git a/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/MultilineTest.php b/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/MultilineTest.php
index f628d52f6647f..bde4a3adb9de5 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/MultilineTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/MultilineTest.php
@@ -3,8 +3,12 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Eav\Test\Unit\Model\Attribute\Data;
+use Magento\Framework\Locale\ResolverInterface;
+use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
+
class MultilineTest extends \PHPUnit\Framework\TestCase
{
/**
@@ -13,15 +17,21 @@ class MultilineTest extends \PHPUnit\Framework\TestCase
protected $model;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Stdlib\StringUtils
*/
protected $stringMock;
+ /**
+ * {@inheritDoc}
+ */
protected function setUp()
{
- $timezoneMock = $this->createMock(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class);
+ /** @var TimezoneInterface $timezoneMock */
+ $timezoneMock = $this->createMock(TimezoneInterface::class);
+ /** @var \Psr\Log\LoggerInterface $loggerMock */
$loggerMock = $this->createMock(\Psr\Log\LoggerInterface::class);
- $localeResolverMock = $this->createMock(\Magento\Framework\Locale\ResolverInterface::class);
+ /** @var ResolverInterface $localeResolverMock */
+ $localeResolverMock = $this->createMock(ResolverInterface::class);
$this->stringMock = $this->createMock(\Magento\Framework\Stdlib\StringUtils::class);
$this->model = new \Magento\Eav\Model\Attribute\Data\Multiline(
@@ -33,7 +43,7 @@ protected function setUp()
}
/**
- * @covers \Magento\Eav\Model\Attribute\Data\Multiline::extractValue
+ * @covers \Magento\Eav\Model\Attribute\Data\Multiline::extractValue
*
* @param mixed $param
* @param mixed $expectedResult
@@ -41,11 +51,15 @@ protected function setUp()
*/
public function testExtractValue($param, $expectedResult)
{
+ /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\App\RequestInterface $requestMock */
$requestMock = $this->createMock(\Magento\Framework\App\RequestInterface::class);
+ /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Eav\Model\Attribute $attributeMock */
$attributeMock = $this->createMock(\Magento\Eav\Model\Attribute::class);
$requestMock->expects($this->once())->method('getParam')->will($this->returnValue($param));
- $attributeMock->expects($this->once())->method('getAttributeCode')->will($this->returnValue('attributeCode'));
+ $attributeMock->expects($this->once())
+ ->method('getAttributeCode')
+ ->will($this->returnValue('attributeCode'));
$this->model->setAttribute($attributeMock);
$this->assertEquals($expectedResult, $this->model->extractValue($requestMock));
@@ -69,7 +83,7 @@ public function extractValueDataProvider()
}
/**
- * @covers \Magento\Eav\Model\Attribute\Data\Multiline::outputValue
+ * @covers \Magento\Eav\Model\Attribute\Data\Multiline::outputValue
*
* @param string $format
* @param mixed $expectedResult
@@ -77,9 +91,13 @@ public function extractValueDataProvider()
*/
public function testOutputValue($format, $expectedResult)
{
+ /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Model\AbstractModel $entityMock */
$entityMock = $this->createMock(\Magento\Framework\Model\AbstractModel::class);
- $entityMock->expects($this->once())->method('getData')->will($this->returnValue("value1\nvalue2"));
+ $entityMock->expects($this->once())
+ ->method('getData')
+ ->will($this->returnValue("value1\nvalue2"));
+ /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Eav\Model\Attribute $attributeMock */
$attributeMock = $this->createMock(\Magento\Eav\Model\Attribute::class);
$this->model->setEntity($entityMock);
@@ -113,8 +131,8 @@ public function outputValueDataProvider()
}
/**
- * @covers \Magento\Eav\Model\Attribute\Data\Multiline::validateValue
- * @covers \Magento\Eav\Model\Attribute\Data\Text::validateValue
+ * @covers \Magento\Eav\Model\Attribute\Data\Multiline::validateValue
+ * @covers \Magento\Eav\Model\Attribute\Data\Text::validateValue
*
* @param mixed $value
* @param bool $isAttributeRequired
@@ -124,14 +142,23 @@ public function outputValueDataProvider()
*/
public function testValidateValue($value, $isAttributeRequired, $rules, $expectedResult)
{
+ /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Model\AbstractModel $entityMock */
$entityMock = $this->createMock(\Magento\Framework\Model\AbstractModel::class);
- $entityMock->expects($this->any())->method('getDataUsingMethod')->will($this->returnValue("value1\nvalue2"));
+ $entityMock->expects($this->any())
+ ->method('getDataUsingMethod')
+ ->will($this->returnValue("value1\nvalue2"));
+ /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Eav\Model\Attribute $attributeMock */
$attributeMock = $this->createMock(\Magento\Eav\Model\Attribute::class);
$attributeMock->expects($this->any())->method('getMultilineCount')->will($this->returnValue(2));
$attributeMock->expects($this->any())->method('getValidateRules')->will($this->returnValue($rules));
- $attributeMock->expects($this->any())->method('getStoreLabel')->will($this->returnValue('Label'));
- $attributeMock->expects($this->any())->method('getIsRequired')->will($this->returnValue($isAttributeRequired));
+ $attributeMock->expects($this->any())
+ ->method('getStoreLabel')
+ ->will($this->returnValue('Label'));
+
+ $attributeMock->expects($this->any())
+ ->method('getIsRequired')
+ ->will($this->returnValue($isAttributeRequired));
$this->stringMock->expects($this->any())->method('strlen')->will($this->returnValue(5));
@@ -159,7 +186,7 @@ public function validateValueDataProvider()
'expectedResult' => true,
],
[
- 'value' => ['value1', 'value2'],
+ 'value' => ['value1', 'value2'],
'isAttributeRequired' => false,
'rules' => [],
'expectedResult' => true,
@@ -167,13 +194,13 @@ public function validateValueDataProvider()
[
'value' => 'value',
'isAttributeRequired' => false,
- 'rules' => ['max_text_length' => 3],
+ 'rules' => ['input_validation' => 'other', 'max_text_length' => 3],
'expectedResult' => ['"Label" length must be equal or less than 3 characters.'],
],
[
'value' => 'value',
'isAttributeRequired' => false,
- 'rules' => ['min_text_length' => 10],
+ 'rules' => ['input_validation' => 'other', 'min_text_length' => 10],
'expectedResult' => ['"Label" length must be equal or greater than 10 characters.'],
],
[
diff --git a/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/TextTest.php b/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/TextTest.php
index 36eac0bfab27b..bbbe712b2bb42 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/TextTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/TextTest.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Eav\Test\Unit\Model\Attribute\Data;
class TextTest extends \PHPUnit\Framework\TestCase
@@ -12,6 +13,9 @@ class TextTest extends \PHPUnit\Framework\TestCase
*/
protected $_model;
+ /**
+ * {@inheritDoc}
+ */
protected function setUp()
{
$locale = $this->createMock(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class);
@@ -19,14 +23,77 @@ protected function setUp()
$logger = $this->createMock(\Psr\Log\LoggerInterface::class);
$helper = $this->createMock(\Magento\Framework\Stdlib\StringUtils::class);
- $attributeData = [
+ $this->_model = new \Magento\Eav\Model\Attribute\Data\Text($locale, $logger, $localeResolver, $helper);
+ $this->_model->setAttribute(
+ $this->createAttribute(
+ [
+ 'store_label' => 'Test',
+ 'attribute_code' => 'test',
+ 'is_required' => 1,
+ 'validate_rules' => ['min_text_length' => 0, 'max_text_length' => 0, 'input_validation' => 0],
+ ]
+ )
+ );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function tearDown()
+ {
+ $this->_model = null;
+ }
+
+ /**
+ * Test for string validation
+ */
+ public function testValidateValueString(): void
+ {
+ $inputValue = '0';
+ $expectedResult = true;
+ $this->assertEquals($expectedResult, $this->_model->validateValue($inputValue));
+ }
+
+ /**
+ * Test for integer validation
+ */
+ public function testValidateValueInteger(): void
+ {
+ $inputValue = 0;
+ $expectedResult = ['"Test" is a required value.'];
+ $result = $this->_model->validateValue($inputValue);
+ $this->assertEquals($expectedResult, [(string)$result[0]]);
+ }
+
+ /**
+ * Test without length validation
+ */
+ public function testWithoutLengthValidation(): void
+ {
+ $expectedResult = true;
+ $defaultAttributeData = [
'store_label' => 'Test',
'attribute_code' => 'test',
'is_required' => 1,
'validate_rules' => ['min_text_length' => 0, 'max_text_length' => 0, 'input_validation' => 0],
];
- $attributeClass = \Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class;
+ $defaultAttributeData['validate_rules']['min_text_length'] = 2;
+ $this->_model->setAttribute($this->createAttribute($defaultAttributeData));
+ $this->assertEquals($expectedResult, $this->_model->validateValue('t'));
+
+ $defaultAttributeData['validate_rules']['max_text_length'] = 3;
+ $this->_model->setAttribute($this->createAttribute($defaultAttributeData));
+ $this->assertEquals($expectedResult, $this->_model->validateValue('test'));
+ }
+
+ /**
+ * @param array $attributeData
+ * @return \Magento\Eav\Model\Attribute
+ */
+ protected function createAttribute($attributeData): \Magento\Eav\Model\Entity\Attribute\AbstractAttribute
+ {
+ $attributeClass = \Magento\Eav\Model\Attribute::class;
$objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$eavTypeFactory = $this->createMock(\Magento\Eav\Model\Entity\TypeFactory::class);
$arguments = $objectManagerHelper->getConstructArguments(
@@ -41,27 +108,6 @@ protected function setUp()
->setMethods(['_init'])
->setConstructorArgs($arguments)
->getMock();
- $this->_model = new \Magento\Eav\Model\Attribute\Data\Text($locale, $logger, $localeResolver, $helper);
- $this->_model->setAttribute($attribute);
- }
-
- protected function tearDown()
- {
- $this->_model = null;
- }
-
- public function testValidateValueString()
- {
- $inputValue = '0';
- $expectedResult = true;
- $this->assertEquals($expectedResult, $this->_model->validateValue($inputValue));
- }
-
- public function testValidateValueInteger()
- {
- $inputValue = 0;
- $expectedResult = ['"Test" is a required value.'];
- $result = $this->_model->validateValue($inputValue);
- $this->assertEquals($expectedResult, [(string)$result[0]]);
+ return $attribute;
}
}
diff --git a/app/code/Magento/Persistent/Test/Mftf/Test/GuestCheckoutWithEnabledPersistentTest.xml b/app/code/Magento/Persistent/Test/Mftf/Test/GuestCheckoutWithEnabledPersistentTest.xml
index 49d07992694d4..03509268751ed 100644
--- a/app/code/Magento/Persistent/Test/Mftf/Test/GuestCheckoutWithEnabledPersistentTest.xml
+++ b/app/code/Magento/Persistent/Test/Mftf/Test/GuestCheckoutWithEnabledPersistentTest.xml
@@ -72,12 +72,12 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/app/code/Magento/ProductVideo/Block/Product/View/Gallery.php b/app/code/Magento/ProductVideo/Block/Product/View/Gallery.php
index 2277aa980f66c..45c4925640a0c 100644
--- a/app/code/Magento/ProductVideo/Block/Product/View/Gallery.php
+++ b/app/code/Magento/ProductVideo/Block/Product/View/Gallery.php
@@ -9,9 +9,8 @@
*
* @author Magento Core Team
*/
-namespace Magento\ProductVideo\Block\Product\View;
-use Magento\Catalog\Model\Product\Image\UrlBuilder;
+namespace Magento\ProductVideo\Block\Product\View;
/**
* @api
@@ -93,6 +92,6 @@ public function getVideoSettingsJson()
*/
public function getOptionsMediaGalleryDataJson()
{
- return $this->jsonEncoder->encode([]);
+ return $this->jsonEncoder->encode([]);
}
}
diff --git a/app/code/Magento/ProductVideo/Model/Plugin/Catalog/Product/Gallery/CreateHandler.php b/app/code/Magento/ProductVideo/Model/Plugin/Catalog/Product/Gallery/CreateHandler.php
index ab3c8f3c5269a..ce1493b349a85 100644
--- a/app/code/Magento/ProductVideo/Model/Plugin/Catalog/Product/Gallery/CreateHandler.php
+++ b/app/code/Magento/ProductVideo/Model/Plugin/Catalog/Product/Gallery/CreateHandler.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\ProductVideo\Model\Plugin\Catalog\Product\Gallery;
use Magento\ProductVideo\Model\Product\Attribute\Media\ExternalVideoEntryConverter;
@@ -29,6 +30,7 @@ public function beforeExecute(
\Magento\Catalog\Model\Product $product,
array $arguments = []
) {
+ /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */
$attribute = $mediaGalleryCreateHandler->getAttribute();
$mediaCollection = $this->getMediaEntriesDataCollection($product, $attribute);
if (!empty($mediaCollection)) {
@@ -36,7 +38,7 @@ public function beforeExecute(
$mediaCollection = $this->addAdditionalStoreData($mediaCollection, $storeDataCollection);
$product->setData(
$attribute->getAttributeCode(),
- $mediaCollection + $product->getData($attribute->getAttributeCode())
+ $mediaCollection
);
}
}
@@ -56,6 +58,9 @@ public function afterExecute(
);
if (!empty($mediaCollection)) {
+ $newVideoCollection = $this->collectNewVideos($mediaCollection);
+ $this->saveVideoData($newVideoCollection, 0);
+
$videoDataCollection = $this->collectVideoData($mediaCollection);
$this->saveVideoData($videoDataCollection, $product->getStoreId());
$this->saveAdditionalStoreData($videoDataCollection);
@@ -167,10 +172,7 @@ protected function collectVideoData(array $mediaCollection)
{
$videoDataCollection = [];
foreach ($mediaCollection as $item) {
- if (!empty($item['media_type'])
- && empty($item['removed'])
- && $item['media_type'] == ExternalVideoEntryConverter::MEDIA_TYPE_CODE
- ) {
+ if ($this->isVideoItem($item)) {
$videoData = $this->extractVideoDataFromRowData($item);
$videoDataCollection[] = $videoData;
}
@@ -199,11 +201,7 @@ protected function collectVideoEntriesIdsToAdditionalLoad(array $mediaCollection
{
$ids = [];
foreach ($mediaCollection as $item) {
- if (!empty($item['media_type'])
- && empty($item['removed'])
- && $item['media_type'] == ExternalVideoEntryConverter::MEDIA_TYPE_CODE
- && isset($item['save_data_from'])
- ) {
+ if ($this->isVideoItem($item) && isset($item['save_data_from'])) {
$ids[] = $item['save_data_from'];
}
}
@@ -215,18 +213,19 @@ protected function collectVideoEntriesIdsToAdditionalLoad(array $mediaCollection
* @param array $data
* @return array
*/
- protected function addAdditionalStoreData(array $mediaCollection, array $data)
+ protected function addAdditionalStoreData(array $mediaCollection, array $data): array
{
- foreach ($mediaCollection as &$mediaItem) {
+ $return = [];
+ foreach ($mediaCollection as $key => $mediaItem) {
if (!empty($mediaItem['save_data_from'])) {
$additionalData = $this->createAdditionalStoreDataCollection($data, $mediaItem['save_data_from']);
if (!empty($additionalData)) {
$mediaItem[self::ADDITIONAL_STORE_DATA_KEY] = $additionalData;
}
}
+ $return[$key] = $mediaItem;
}
-
- return ['images' => $mediaCollection];
+ return ['images' => $return];
}
/**
@@ -234,7 +233,7 @@ protected function addAdditionalStoreData(array $mediaCollection, array $data)
* @param int $valueId
* @return array
*/
- protected function createAdditionalStoreDataCollection(array $storeData, $valueId)
+ protected function createAdditionalStoreDataCollection(array $storeData, $valueId): array
{
$result = [];
foreach ($storeData as $item) {
@@ -246,4 +245,41 @@ protected function createAdditionalStoreDataCollection(array $storeData, $valueI
return $result;
}
+
+ /**
+ * @param array $mediaCollection
+ * @return array
+ */
+ private function collectNewVideos(array $mediaCollection): array
+ {
+ $return = [];
+ foreach ($mediaCollection as $item) {
+ if ($this->isVideoItem($item) && $this->isNewVideo($item)) {
+ $return[] = $this->extractVideoDataFromRowData($item);
+ }
+ }
+ return $return;
+ }
+
+ /**
+ * @param array $item
+ * @return bool
+ */
+ private function isVideoItem(array $item): bool
+ {
+ return !empty($item['media_type'])
+ && empty($item['removed'])
+ && $item['media_type'] == ExternalVideoEntryConverter::MEDIA_TYPE_CODE;
+ }
+
+ /**
+ * @param array $item
+ * @return bool
+ */
+ private function isNewVideo(array $item): bool
+ {
+ return !isset($item['video_url_default'], $item['video_title_default'])
+ || empty($item['video_url_default'])
+ || empty($item['video_title_default']);
+ }
}
diff --git a/app/code/Magento/ProductVideo/Model/Plugin/Catalog/Product/Gallery/ReadHandler.php b/app/code/Magento/ProductVideo/Model/Plugin/Catalog/Product/Gallery/ReadHandler.php
index 6c534580c39d9..31d63efcf8cb0 100644
--- a/app/code/Magento/ProductVideo/Model/Plugin/Catalog/Product/Gallery/ReadHandler.php
+++ b/app/code/Magento/ProductVideo/Model/Plugin/Catalog/Product/Gallery/ReadHandler.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\ProductVideo\Model\Plugin\Catalog\Product\Gallery;
use Magento\ProductVideo\Model\Product\Attribute\Media\ExternalVideoEntryConverter;
@@ -55,8 +56,8 @@ protected function collectVideoEntriesIds(array $mediaCollection)
{
$ids = [];
foreach ($mediaCollection as $item) {
- if ($item['media_type'] == ExternalVideoEntryConverter::MEDIA_TYPE_CODE
- && !array_key_exists('video_url', $item)
+ if ($item['media_type'] === ExternalVideoEntryConverter::MEDIA_TYPE_CODE
+ && !isset($item['video_url'])
) {
$ids[] = $item['value_id'];
}
@@ -72,7 +73,7 @@ protected function collectVideoEntriesIds(array $mediaCollection)
protected function loadVideoDataById(array $ids, $storeId = null)
{
$mainTableAlias = $this->resourceModel->getMainTableAlias();
- $joinConditions = $mainTableAlias.'.value_id = store_value.value_id';
+ $joinConditions = $mainTableAlias . '.value_id = store_value.value_id';
if (null !== $storeId) {
$joinConditions = implode(
' AND ',
@@ -138,10 +139,10 @@ protected function addVideoDataToMediaEntries(array $mediaCollection, array $dat
protected function substituteNullsWithDefaultValues(array $rowData)
{
foreach ($this->getVideoProperties(false) as $key) {
- if (empty($rowData[$key]) && !empty($rowData[$key.'_default'])) {
- $rowData[$key] = $rowData[$key.'_default'];
+ if (empty($rowData[$key]) && !empty($rowData[$key . '_default'])) {
+ $rowData[$key] = $rowData[$key . '_default'];
}
- unset($rowData[$key.'_default']);
+ unset($rowData[$key . '_default']);
}
return $rowData;
@@ -154,8 +155,7 @@ protected function substituteNullsWithDefaultValues(array $rowData)
protected function getVideoProperties($withDbMapping = true)
{
$properties = $this->videoPropertiesDbMapping;
- unset($properties['value_id']);
- unset($properties['store_id']);
+ unset($properties['value_id'], $properties['store_id']);
return $withDbMapping ? $properties : array_keys($properties);
}
diff --git a/app/code/Magento/ProductVideo/Test/Unit/Model/Plugin/Catalog/Product/Gallery/CreateHandlerTest.php b/app/code/Magento/ProductVideo/Test/Unit/Model/Plugin/Catalog/Product/Gallery/CreateHandlerTest.php
index 5770ea8b5689d..57ad71997dad7 100644
--- a/app/code/Magento/ProductVideo/Test/Unit/Model/Plugin/Catalog/Product/Gallery/CreateHandlerTest.php
+++ b/app/code/Magento/ProductVideo/Test/Unit/Model/Plugin/Catalog/Product/Gallery/CreateHandlerTest.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\ProductVideo\Test\Unit\Model\Plugin\Catalog\Product\Gallery;
/**
@@ -37,6 +38,9 @@ class CreateHandlerTest extends \PHPUnit\Framework\TestCase
*/
protected $mediaGalleryCreateHandler;
+ /**
+ * {@inheritDoc}
+ */
protected function setUp()
{
$this->product = $this->createMock(\Magento\Catalog\Model\Product::class);
@@ -62,72 +66,18 @@ protected function setUp()
);
}
- public function testAfterExecute()
+ /**
+ * @dataProvider provideImageForAfterExecute
+ * @param array $image
+ * @param array $expectedSave
+ * @param int $rowSaved
+ */
+ public function testAfterExecute($image, $expectedSave, $rowSaved): void
{
- $mediaData = [
- 'images' => [
- '72mljfhmasfilp9cuq' => [
- 'position' => '3',
- 'media_type' => 'external-video',
- 'file' => '/i/n/index111111.jpg',
- 'value_id' => '4',
- 'label' => '',
- 'disabled' => '0',
- 'removed' => '',
- 'video_provider' => 'youtube',
- 'video_url' => 'https://www.youtube.com/watch?v=ab123456',
- 'video_title' => 'Some second title',
- 'video_description' => 'Description second',
- 'video_metadata' => 'meta two',
- 'role' => '',
- ],
- 'w596fi79hv1p6wj21u' => [
- 'position' => '4',
- 'media_type' => 'image',
- 'video_provider' => '',
- 'file' => '/h/d/hd_image.jpg',
- 'value_id' => '7',
- 'label' => '',
- 'disabled' => '0',
- 'removed' => '',
- 'video_url' => '',
- 'video_title' => '',
- 'video_description' => '',
- 'video_metadata' => '',
- 'role' => '',
- ],
- 'tcodwd7e0dirifr64j' => [
- 'position' => '4',
- 'media_type' => 'external-video',
- 'file' => '/s/a/sample_3.jpg',
- 'value_id' => '5',
- 'label' => '',
- 'disabled' => '0',
- 'removed' => '',
- 'video_provider' => 'youtube',
- 'video_url' => 'https://www.youtube.com/watch?v=ab123456',
- 'video_title' => 'Some second title',
- 'video_description' => 'Description second',
- 'video_metadata' => 'meta two',
- 'role' => '',
- 'additional_store_data' => [
- 0 => [
- 'store_id' => '0',
- 'video_provider' => null,
- 'video_url' => 'https://www.youtube.com/watch?v=ab123456',
- 'video_title' => 'New Title',
- 'video_description' => 'New Description',
- 'video_metadata' => 'New metadata',
- ],
- ]
- ],
- ],
- ];
-
$this->product->expects($this->once())
->method('getData')
->with('media_gallery')
- ->willReturn($mediaData);
+ ->willReturn(['images' => $image]);
$this->product->expects($this->once())
->method('getStoreId')
->willReturn(0);
@@ -136,13 +86,150 @@ public function testAfterExecute()
->method('getAttribute')
->willReturn($this->attribute);
- $this->subject->afterExecute(
- $this->mediaGalleryCreateHandler,
- $this->product
- );
+ $this->resourceModel->expects($this->exactly($rowSaved))
+ ->method('saveDataRow')
+ ->with('catalog_product_entity_media_gallery_value_video', $expectedSave)
+ ->willReturn(1);
+
+ $this->subject->afterExecute($this->mediaGalleryCreateHandler, $this->product);
+ }
+
+ /**
+ * DataProvider for testAfterExecute
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ * @return array
+ */
+ public function provideImageForAfterExecute(): array
+ {
+ return [
+ 'new_video' => [
+ [
+ '72mljfhmasfilp9cuq' => [
+ 'position' => '3',
+ 'media_type' => 'external-video',
+ 'file' => '/i/n/index111111.jpg',
+ 'value_id' => '4',
+ 'label' => '',
+ 'disabled' => '0',
+ 'removed' => '',
+ 'video_provider' => 'youtube',
+ 'video_url' => 'https://www.youtube.com/watch?v=ab123456',
+ 'video_title' => 'Some second title',
+ 'video_description' => 'Description second',
+ 'video_metadata' => 'meta two',
+ 'role' => '',
+ ],
+ ],
+ [
+ 'value_id' => '4',
+ 'store_id' => 0,
+ 'provider' => 'youtube',
+ 'url' => 'https://www.youtube.com/watch?v=ab123456',
+ 'title' => 'Some second title',
+ 'description' => 'Description second',
+ 'metadata' => 'meta two',
+ ],
+ 2
+ ],
+ 'image' => [
+ [
+ 'w596fi79hv1p6wj21u' => [
+ 'position' => '4',
+ 'media_type' => 'image',
+ 'video_provider' => '',
+ 'file' => '/h/d/hd_image.jpg',
+ 'value_id' => '7',
+ 'label' => '',
+ 'disabled' => '0',
+ 'removed' => '',
+ 'video_url' => '',
+ 'video_title' => '',
+ 'video_description' => '',
+ 'video_metadata' => '',
+ 'role' => '',
+ ],
+ ],
+ [],
+ 0
+ ],
+ 'new_video_with_additional_data' => [
+ [
+ 'tcodwd7e0dirifr64j' => [
+ 'position' => '4',
+ 'media_type' => 'external-video',
+ 'file' => '/s/a/sample_3.jpg',
+ 'value_id' => '5',
+ 'label' => '',
+ 'disabled' => '0',
+ 'removed' => '',
+ 'video_provider' => 'youtube',
+ 'video_url' => 'https://www.youtube.com/watch?v=ab123456',
+ 'video_title' => 'Some second title',
+ 'video_description' => 'Description second',
+ 'video_metadata' => 'meta two',
+ 'role' => '',
+ 'additional_store_data' => [
+ 0 => [
+ 'store_id' => 0,
+ 'video_provider' => 'youtube',
+ 'video_url' => 'https://www.youtube.com/watch?v=ab123456',
+ 'video_title' => 'Some second title',
+ 'video_description' => 'Description second',
+ 'video_metadata' => 'meta two',
+ ],
+ ]
+ ],
+ ],
+ [
+ 'value_id' => '5',
+ 'store_id' => 0,
+ 'provider' => 'youtube',
+ 'url' => 'https://www.youtube.com/watch?v=ab123456',
+ 'title' => 'Some second title',
+ 'description' => 'Description second',
+ 'metadata' => 'meta two',
+ ],
+ 3
+ ],
+ 'not_new_video' => [
+ [
+ '72mljfhmasfilp9cuq' => [
+ 'position' => '3',
+ 'media_type' => 'external-video',
+ 'file' => '/i/n/index111111.jpg',
+ 'value_id' => '4',
+ 'label' => '',
+ 'disabled' => '0',
+ 'removed' => '',
+ 'video_provider' => 'youtube',
+ 'video_url' => 'https://www.youtube.com/watch?v=ab123456',
+ 'video_url_default' => 'https://www.youtube.com/watch?v=ab123456',
+ 'video_title' => 'Some second title',
+ 'video_title_default' => 'Some second title',
+ 'video_description' => 'Description second',
+ 'video_metadata' => 'meta two',
+ 'role' => '',
+ ],
+ ],
+ [
+ 'value_id' => '4',
+ 'store_id' => 0,
+ 'provider' => 'youtube',
+ 'url' => 'https://www.youtube.com/watch?v=ab123456',
+ 'title' => 'Some second title',
+ 'description' => 'Description second',
+ 'metadata' => 'meta two',
+ ],
+ 1
+ ],
+ ];
}
- public function testAfterExecuteEmpty()
+ /**
+ * Tests empty media gallery
+ */
+ public function testAfterExecuteEmpty(): void
{
$this->product->expects($this->once())
->method('getData')
@@ -162,7 +249,7 @@ public function testAfterExecuteEmpty()
/**
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
- public function testBeforeExecute()
+ public function testBeforeExecute(): void
{
$mediaData = [
'images' => [
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Config/Form/Field/YtdStart.php b/app/code/Magento/Reports/Block/Adminhtml/Config/Form/Field/YtdStart.php
index 5a27b4dc7666f..4ac12501aa90f 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Config/Form/Field/YtdStart.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Config/Form/Field/YtdStart.php
@@ -23,9 +23,8 @@ protected function _getElementHtml(AbstractElement $element)
{
$_months = [];
for ($i = 1; $i <= 12; $i++) {
- $_months[$i] = $this->_localeDate->date(mktime(null, null, null, $i))->format('m');
+ $_months[$i] = $this->_localeDate->date(mktime(null, null, null, $i, 1))->format('m');
}
-
$_days = [];
for ($i = 1; $i <= 31; $i++) {
$_days[$i] = $i < 10 ? '0' . $i : $i;
diff --git a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
index e3bec2d9959b1..a1987f67e47f2 100644
--- a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
+++ b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
@@ -355,10 +355,10 @@ public function getValueParsed()
{
if (!$this->hasValueParsed()) {
$value = $this->getData('value');
- if (is_array($value) && isset($value[0]) && is_string($value[0])) {
- $value = $value[0];
+ if (is_array($value) && count($value) === 1) {
+ $value = reset($value);
}
- if ($this->isArrayOperatorType() && $value) {
+ if (!is_array($value) && $this->isArrayOperatorType() && $value) {
$value = preg_split('#\s*[,;]\s*#', $value, null, PREG_SPLIT_NO_EMPTY);
}
$this->setValueParsed($value);
@@ -380,7 +380,7 @@ public function isArrayOperatorType()
}
/**
- * @return array
+ * @return mixed
*/
public function getValue()
{
diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php
index e1c9bf99f2675..2894de0f19b87 100644
--- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php
+++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php
@@ -163,8 +163,22 @@ protected function _getMappedSqlCondition(
$this->_conditionOperatorMap[$conditionOperator]
);
+ $bindValue = $condition->getBindArgumentValue();
+ $expression = $value . $this->_connection->quoteInto($sql, $bindValue);
+
+ // values for multiselect attributes can be saved in comma-separated format
+ // below is a solution for matching such conditions with selected values
+ if (is_array($bindValue) && \in_array($conditionOperator, ['()', '{}'], true)) {
+ foreach ($bindValue as $item) {
+ $expression .= $this->_connection->quoteInto(
+ " OR (FIND_IN_SET (?, {$this->_connection->quoteIdentifier($argument)}) > 0)",
+ $item
+ );
+ }
+ }
+
return $this->_expressionFactory->create(
- ['expression' => $value . $this->_connection->quoteInto($sql, $condition->getBindArgumentValue())]
+ ['expression' => $expression]
);
}
@@ -174,6 +188,7 @@ protected function _getMappedSqlCondition(
* @param bool $isDefaultStoreUsed
* @return string
* @SuppressWarnings(PHPMD.NPathComplexity)
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _getMappedSqlCombination(
Combine $combine,
diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php
index 499e35db9dfd6..d2e7cabe473f4 100644
--- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php
+++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\SalesRule\Model\Rule\Condition;
/**
@@ -51,10 +52,17 @@ public function validate(\Magento\Framework\Model\AbstractModel $model)
$attrCode = $this->getAttribute();
- if ('category_ids' == $attrCode) {
+ if ($attrCode === 'category_ids') {
return $this->validateAttribute($this->_getAvailableInCategories($product->getId()));
}
+ if ($attrCode === 'quote_item_price') {
+ $numericOperations = $this->getDefaultOperatorInputByType()['numeric'];
+ if (in_array($this->getOperator(), $numericOperations)) {
+ $this->setData('value', $this->getFormattedPrice($this->getValue()));
+ }
+ }
+
return parent::validate($product);
}
@@ -79,4 +87,23 @@ public function getValueElementChooserUrl()
}
return $url !== false ? $this->_backendData->getUrl($url) : '';
}
+
+ /**
+ * @param string $value
+ * @return float|null
+ */
+ private function getFormattedPrice($value)
+ {
+ $value = preg_replace('/[^0-9^\^.,-]/m', '', $value);
+
+ /**
+ * If the comma is the third symbol in the number, we consider it to be a decimal separator
+ */
+ $separatorComa = strpos($value, ',');
+ $separatorDot = strpos($value, '.');
+ if ($separatorComa !== false && $separatorDot === false && preg_match('/,\d{3}$/m', $value) === 1) {
+ $value .= '.00';
+ }
+ return $this->_localeFormat->getNumber($value);
+ }
}
diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php
index 0bce282747b16..51c7b9ede5aa2 100644
--- a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php
+++ b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php
@@ -3,11 +3,15 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\SalesRule\Test\Unit\Model\Rule\Condition;
+use Magento\Directory\Model\CurrencyFactory;
+use Magento\Framework\App\ScopeResolverInterface;
use \Magento\Framework\DB\Adapter\AdapterInterface;
use \Magento\Framework\DB\Select;
-use \Magento\Framework\Model\AbstractModel;
+use Magento\Framework\Locale\Format;
+use Magento\Framework\Locale\ResolverInterface;
use Magento\Quote\Model\Quote\Item\AbstractItem;
use \Magento\Rule\Model\Condition\Context;
use \Magento\Backend\Helper\Data;
@@ -50,8 +54,8 @@ class ProductTest extends \PHPUnit\Framework\TestCase
/** @var Collection|\PHPUnit_Framework_MockObject_MockObject */
protected $collectionMock;
- /** @var FormatInterface|\PHPUnit_Framework_MockObject_MockObject */
- protected $formatMock;
+ /** @var FormatInterface */
+ protected $format;
/** @var AttributeLoaderInterface|\PHPUnit_Framework_MockObject_MockObject */
protected $attributeLoaderInterfaceMock;
@@ -130,8 +134,12 @@ protected function setUp()
$this->collectionMock = $this->getMockBuilder(Collection::class)
->disableOriginalConstructor()
->getMock();
- $this->formatMock = $this->getMockBuilder(FormatInterface::class)
- ->getMockForAbstractClass();
+ $this->format = new Format(
+ $this->getMockBuilder(ScopeResolverInterface::class)->disableOriginalConstructor()->getMock(),
+ $this->getMockBuilder(ResolverInterface::class)->disableOriginalConstructor()->getMock(),
+ $this->getMockBuilder(CurrencyFactory::class)->disableOriginalConstructor()->getMock()
+ );
+
$this->model = new SalesRuleProduct(
$this->contextMock,
$this->backendHelperMock,
@@ -140,7 +148,7 @@ protected function setUp()
$this->productRepositoryMock,
$this->productMock,
$this->collectionMock,
- $this->formatMock
+ $this->format
);
}
@@ -199,7 +207,10 @@ public function testGetValueElementChooserUrl($attribute, $url, $jsObject = '')
$this->assertEquals($url, $this->model->getValueElementChooserUrl());
}
- public function testValidateCategoriesIgnoresVisibility()
+ /**
+ * test ValidateCategoriesIgnoresVisibility
+ */
+ public function testValidateCategoriesIgnoresVisibility(): void
{
/* @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */
$product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
@@ -231,4 +242,81 @@ public function testValidateCategoriesIgnoresVisibility()
$this->model->validate($item);
}
+
+ /**
+ * @param boolean $isValid
+ * @param string $conditionValue
+ * @param string $operator
+ * @param double $productPrice
+ * @dataProvider localisationProvider
+ */
+ public function testQuoteLocaleFormatPrice($isValid, $conditionValue, $operator = '>=', $productPrice = 2000.00)
+ {
+ $attr = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getAttribute'])
+ ->getMockForAbstractClass();
+
+ $attr->expects($this->any())
+ ->method('getAttribute')
+ ->willReturn('');
+
+ /* @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */
+ $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['setQuoteItemPrice', 'getResource', 'hasData', 'getData',])
+ ->getMock();
+
+ $product->expects($this->any())
+ ->method('setQuoteItemPrice')
+ ->willReturnSelf();
+
+ $product->expects($this->any())
+ ->method('getResource')
+ ->willReturn($attr);
+
+ $product->expects($this->any())
+ ->method('hasData')
+ ->willReturn(true);
+
+ $product->expects($this->any())
+ ->method('getData')
+ ->with('quote_item_price')
+ ->willReturn($productPrice);
+
+ /* @var AbstractItem|\PHPUnit_Framework_MockObject_MockObject $item */
+ $item = $this->getMockBuilder(AbstractItem::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getPrice', 'getProduct',])
+ ->getMockForAbstractClass();
+
+ $item->expects($this->any())
+ ->method('getPrice')
+ ->willReturn($productPrice);
+
+ $item->expects($this->any())
+ ->method('getProduct')
+ ->willReturn($product);
+
+ $this->model->setAttribute('quote_item_price')
+ ->setOperator($operator);
+
+ $this->assertEquals($isValid, $this->model->setValue($conditionValue)->validate($item));
+ }
+
+ /**
+ * DataProvider for testQuoteLocaleFormatPrice
+ *
+ * @return array
+ */
+ public function localisationProvider(): array
+ {
+ return [
+ 'number' => [true, 500.01],
+ 'locale' => [true, '1,500.03'],
+ 'operation' => [true, '1,500.03', '!='],
+ 'stringOperation' => [false, '1,500.03', '{}'],
+ 'smallPrice' => [false, '1,500.03', '>=', 1000],
+ ];
+ }
}
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Delete.php b/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Delete.php
index bb476423692d1..9d8b612cefadf 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Delete.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Delete.php
@@ -60,16 +60,18 @@ public function execute()
/** @var \Magento\Search\Model\SynonymGroup $synGroupModel */
$synGroupModel = $this->synGroupRepository->get($id);
$this->synGroupRepository->delete($synGroupModel);
- $this->messageManager->addSuccess(__('The synonym group has been deleted.'));
+ $this->messageManager->addSuccessMessage(__('The synonym group has been deleted.'));
} catch (\Magento\Framework\Exception\LocalizedException $e) {
- $this->messageManager->addError($e->getMessage());
+ $this->messageManager->addErrorMessage($e->getMessage());
$this->logger->error($e);
} catch (\Exception $e) {
- $this->messageManager->addError(__('An error was encountered while performing delete operation.'));
+ $this->messageManager->addErrorMessage(
+ __('An error was encountered while performing delete operation.')
+ );
$this->logger->error($e);
}
} else {
- $this->messageManager->addError(__('We can\'t find a synonym group to delete.'));
+ $this->messageManager->addErrorMessage(__('We can\'t find a synonym group to delete.'));
}
return $resultRedirect->setPath('*/*/');
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Edit.php b/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Edit.php
index 8eefc956e8aa5..adc4ecc52030a 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Edit.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Edit.php
@@ -65,7 +65,7 @@ public function execute()
// 2. Initial checking
if ($groupId && (!$synGroup->getGroupId())) {
- $this->messageManager->addError(__('This synonyms group no longer exists.'));
+ $this->messageManager->addErrorMessage(__('This synonyms group no longer exists.'));
/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultRedirectFactory->create();
return $resultRedirect->setPath('*/*/');
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Synonyms/MassDelete.php b/app/code/Magento/Search/Controller/Adminhtml/Synonyms/MassDelete.php
index 4add418d95325..f2770f77cc533 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Synonyms/MassDelete.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Synonyms/MassDelete.php
@@ -72,17 +72,17 @@ public function execute()
$this->synGroupRepository->delete($synonymGroup);
$deletedItems++;
} catch (\Exception $e) {
- $this->messageManager->addError($e->getMessage());
+ $this->messageManager->addErrorMessage($e->getMessage());
}
}
if ($deletedItems != 0) {
if ($collectionSize != $deletedItems) {
- $this->messageManager->addError(
+ $this->messageManager->addErrorMessage(
__('Failed to delete %1 synonym group(s).', $collectionSize - $deletedItems)
);
}
- $this->messageManager->addSuccess(
+ $this->messageManager->addSuccessMessage(
__('A total of %1 synonym group(s) have been deleted.', $deletedItems)
);
}
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Save.php b/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Save.php
index ffa97ceb3e0e1..0ed73fd0cee32 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Save.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Synonyms/Save.php
@@ -59,7 +59,7 @@ public function execute()
$synGroup = $this->synGroupRepository->get($synGroupId);
if (!$synGroup->getGroupId() && $synGroupId) {
- $this->messageManager->addError(__('This synonym group no longer exists.'));
+ $this->messageManager->addErrorMessage(__('This synonym group no longer exists.'));
return $resultRedirect->setPath('*/*/');
}
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/Delete.php b/app/code/Magento/Search/Controller/Adminhtml/Term/Delete.php
index 3a1b80df2ea7e..c7adf32da0fb0 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/Delete.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/Delete.php
@@ -23,16 +23,16 @@ public function execute()
$model = $this->_objectManager->create(\Magento\Search\Model\Query::class);
$model->setId($id);
$model->delete();
- $this->messageManager->addSuccess(__('You deleted the search.'));
+ $this->messageManager->addSuccessMessage(__('You deleted the search.'));
$resultRedirect->setPath('search/*/');
return $resultRedirect;
} catch (\Exception $e) {
- $this->messageManager->addError($e->getMessage());
+ $this->messageManager->addErrorMessage($e->getMessage());
$resultRedirect->setPath('search/*/edit', ['id' => $this->getRequest()->getParam('id')]);
return $resultRedirect;
}
}
- $this->messageManager->addError(__('We can\'t find a search term to delete.'));
+ $this->messageManager->addErrorMessage(__('We can\'t find a search term to delete.'));
$resultRedirect->setPath('search/*/');
return $resultRedirect;
}
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/Edit.php b/app/code/Magento/Search/Controller/Adminhtml/Term/Edit.php
index 85e14ae9fe0b0..3ee0ea240377f 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/Edit.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/Edit.php
@@ -43,7 +43,7 @@ public function execute()
if ($id) {
$model->load($id);
if (!$model->getId()) {
- $this->messageManager->addError(__('This search no longer exists.'));
+ $this->messageManager->addErrorMessage(__('This search no longer exists.'));
/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$resultRedirect->setPath('search/*');
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/MassDelete.php b/app/code/Magento/Search/Controller/Adminhtml/Term/MassDelete.php
index b38d883b8faae..f6874078f2f64 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/MassDelete.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/MassDelete.php
@@ -17,16 +17,16 @@ public function execute()
{
$searchIds = $this->getRequest()->getParam('search');
if (!is_array($searchIds)) {
- $this->messageManager->addError(__('Please select searches.'));
+ $this->messageManager->addErrorMessage(__('Please select searches.'));
} else {
try {
foreach ($searchIds as $searchId) {
$model = $this->_objectManager->create(\Magento\Search\Model\Query::class)->load($searchId);
$model->delete();
}
- $this->messageManager->addSuccess(__('Total of %1 record(s) were deleted.', count($searchIds)));
+ $this->messageManager->addSuccessMessage(__('Total of %1 record(s) were deleted.', count($searchIds)));
} catch (\Exception $e) {
- $this->messageManager->addError($e->getMessage());
+ $this->messageManager->addErrorMessage($e->getMessage());
}
}
/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php b/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php
index 42e9373a20fe2..cd9b1347ed1ed 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php
@@ -45,12 +45,15 @@ public function execute()
$model->addData($data);
$model->setIsProcessed(0);
$model->save();
- $this->messageManager->addSuccess(__('You saved the search term.'));
+ $this->messageManager->addSuccessMessage(__('You saved the search term.'));
} catch (LocalizedException $e) {
- $this->messageManager->addError($e->getMessage());
+ $this->messageManager->addErrorMessage($e->getMessage());
return $this->proceedToEdit($data);
} catch (\Exception $e) {
- $this->messageManager->addException($e, __('Something went wrong while saving the search query.'));
+ $this->messageManager->addExceptionMessage(
+ $e,
+ __('Something went wrong while saving the search query.')
+ );
return $this->proceedToEdit($data);
}
}
diff --git a/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Synonyms/DeleteTest.php b/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Synonyms/DeleteTest.php
index a7f71941dc6b2..38c78b986faf4 100644
--- a/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Synonyms/DeleteTest.php
+++ b/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Synonyms/DeleteTest.php
@@ -107,10 +107,10 @@ public function testDeleteAction()
$this->repository->expects($this->once())->method('get')->with(10)->willReturn($this->synonymGroupMock);
$this->messageManagerMock->expects($this->once())
- ->method('addSuccess')
+ ->method('addSuccessMessage')
->with(__('The synonym group has been deleted.'));
- $this->messageManagerMock->expects($this->never())->method('addError');
+ $this->messageManagerMock->expects($this->never())->method('addErrorMessage');
$this->resultRedirectMock->expects($this->once())->method('setPath')->with('*/*/')->willReturnSelf();
@@ -124,10 +124,10 @@ public function testDeleteActionNoId()
->willReturn(null);
$this->messageManagerMock->expects($this->once())
- ->method('addError')
+ ->method('addErrorMessage')
->with(__('We can\'t find a synonym group to delete.'));
$this->messageManagerMock->expects($this->never())
- ->method('addSuccess');
+ ->method('addSuccessMessage');
$this->resultRedirectMock->expects($this->once())
->method('setPath')
diff --git a/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Term/MassDeleteTest.php b/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Term/MassDeleteTest.php
index efda8f52fcfe9..60cc958a6187c 100644
--- a/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Term/MassDeleteTest.php
+++ b/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Term/MassDeleteTest.php
@@ -54,7 +54,7 @@ protected function setUp()
->getMockForAbstractClass();
$this->messageManager = $this->getMockBuilder(\Magento\Framework\Message\ManagerInterface::class)
->disableOriginalConstructor()
- ->setMethods(['addSuccess', 'addError'])
+ ->setMethods(['addSuccessMessage', 'addErrorMessage'])
->getMockForAbstractClass();
$this->pageFactory = $this->getMockBuilder(\Magento\Framework\View\Result\PageFactory::class)
->setMethods([])
@@ -107,7 +107,7 @@ public function testExecute()
$this->createQuery(0, 1);
$this->createQuery(1, 2);
$this->messageManager->expects($this->once())
- ->method('addSuccess')
+ ->method('addSuccessMessage')
->will($this->returnSelf());
$this->resultRedirectMock->expects($this->once())
->method('setPath')
diff --git a/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Term/SaveTest.php b/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Term/SaveTest.php
index 09ae2c38fe525..28f4b65cd412f 100644
--- a/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Term/SaveTest.php
+++ b/app/code/Magento/Search/Test/Unit/Controller/Adminhtml/Term/SaveTest.php
@@ -75,7 +75,7 @@ protected function setUp()
$this->messageManager = $this->getMockBuilder(\Magento\Framework\Message\ManagerInterface::class)
->disableOriginalConstructor()
- ->setMethods(['addSuccess', 'addError', 'addException'])
+ ->setMethods(['addSuccessMessage', 'addErrorMessage', 'addExceptionMessage'])
->getMockForAbstractClass();
$this->context->expects($this->any())
->method('getMessageManager')
@@ -143,7 +143,7 @@ public function testExecuteLoadQueryQueryId()
$this->query->expects($this->once())->method('getId')->willReturn(false);
$this->query->expects($this->once())->method('load')->with($queryId);
- $this->messageManager->expects($this->once())->method('addSuccess');
+ $this->messageManager->expects($this->once())->method('addSuccessMessage');
$this->redirect->expects($this->once())->method('setPath')->willReturnSelf();
$this->assertSame($this->redirect, $this->controller->execute());
@@ -161,7 +161,7 @@ public function testExecuteLoadQueryQueryIdQueryText()
$this->query->expects($this->once())->method('loadByQueryText')->with($queryText);
$this->query->expects($this->any())->method('getId')->willReturn($queryId);
- $this->messageManager->expects($this->once())->method('addSuccess');
+ $this->messageManager->expects($this->once())->method('addSuccessMessage');
$this->redirect->expects($this->once())->method('setPath')->willReturnSelf();
$this->assertSame($this->redirect, $this->controller->execute());
@@ -180,7 +180,7 @@ public function testExecuteLoadQueryQueryIdQueryText2()
$this->query->expects($this->any())->method('getId')->willReturn(false);
$this->query->expects($this->once())->method('load')->with($queryId);
- $this->messageManager->expects($this->once())->method('addSuccess');
+ $this->messageManager->expects($this->once())->method('addSuccessMessage');
$this->redirect->expects($this->once())->method('setPath')->willReturnSelf();
$this->assertSame($this->redirect, $this->controller->execute());
@@ -199,7 +199,7 @@ public function testExecuteLoadQueryQueryIdQueryTextException()
$this->query->expects($this->once())->method('loadByQueryText')->with($queryText);
$this->query->expects($this->any())->method('getId')->willReturn($anotherQueryId);
- $this->messageManager->expects($this->once())->method('addError');
+ $this->messageManager->expects($this->once())->method('addErrorMessage');
$this->session->expects($this->once())->method('setPageData');
$this->redirect->expects($this->once())->method('setPath')->willReturnSelf();
$this->assertSame($this->redirect, $this->controller->execute());
@@ -216,7 +216,7 @@ public function testExecuteException()
$this->query->expects($this->once())->method('setStoreId');
$this->query->expects($this->once())->method('loadByQueryText')->willThrowException(new \Exception());
- $this->messageManager->expects($this->once())->method('addException');
+ $this->messageManager->expects($this->once())->method('addExceptionMessage');
$this->session->expects($this->once())->method('setPageData');
$this->redirect->expects($this->once())->method('setPath')->willReturnSelf();
$this->assertSame($this->redirect, $this->controller->execute());
diff --git a/app/code/Magento/Security/Controller/Adminhtml/Session/LogoutAll.php b/app/code/Magento/Security/Controller/Adminhtml/Session/LogoutAll.php
index c533e740b2251..35d8f22d84d51 100644
--- a/app/code/Magento/Security/Controller/Adminhtml/Session/LogoutAll.php
+++ b/app/code/Magento/Security/Controller/Adminhtml/Session/LogoutAll.php
@@ -38,11 +38,11 @@ public function execute()
{
try {
$this->sessionsManager->logoutOtherUserSessions();
- $this->messageManager->addSuccess(__('All other open sessions for this account were terminated.'));
+ $this->messageManager->addSuccessMessage(__('All other open sessions for this account were terminated.'));
} catch (\Magento\Framework\Exception\LocalizedException $e) {
- $this->messageManager->addError($e->getMessage());
+ $this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
- $this->messageManager->addException($e, __("We couldn't logout because of an error."));
+ $this->messageManager->addExceptionMessage($e, __("We couldn't logout because of an error."));
}
$this->_redirect('*/*/activity');
}
diff --git a/app/code/Magento/Security/Model/Plugin/AuthSession.php b/app/code/Magento/Security/Model/Plugin/AuthSession.php
index abec4dc7c29ef..01203caaa31cd 100644
--- a/app/code/Magento/Security/Model/Plugin/AuthSession.php
+++ b/app/code/Magento/Security/Model/Plugin/AuthSession.php
@@ -82,7 +82,7 @@ private function addUserLogoutNotification()
$this->sessionsManager->getCurrentSession()->getStatus()
);
} elseif ($message = $this->sessionsManager->getLogoutReasonMessage()) {
- $this->messageManager->addError($message);
+ $this->messageManager->addErrorMessage($message);
}
return $this;
diff --git a/app/code/Magento/Security/Model/Plugin/LoginController.php b/app/code/Magento/Security/Model/Plugin/LoginController.php
index ab9c6e2857bce..ba1a18c4f0c06 100644
--- a/app/code/Magento/Security/Model/Plugin/LoginController.php
+++ b/app/code/Magento/Security/Model/Plugin/LoginController.php
@@ -53,7 +53,7 @@ public function beforeExecute(Login $login)
{
$logoutReasonCode = $this->securityCookie->getLogoutReasonCookie();
if ($this->isLoginForm($login) && $logoutReasonCode >= 0) {
- $this->messageManager->addError(
+ $this->messageManager->addErrorMessage(
$this->sessionsManager->getLogoutReasonMessageByStatus($logoutReasonCode)
);
$this->securityCookie->deleteLogoutReasonCookie();
diff --git a/app/code/Magento/Security/Test/Unit/Controller/Adminhtml/Session/LogoutAllTest.php b/app/code/Magento/Security/Test/Unit/Controller/Adminhtml/Session/LogoutAllTest.php
index 8c2119bde667e..02335ef55aa93 100644
--- a/app/code/Magento/Security/Test/Unit/Controller/Adminhtml/Session/LogoutAllTest.php
+++ b/app/code/Magento/Security/Test/Unit/Controller/Adminhtml/Session/LogoutAllTest.php
@@ -74,7 +74,7 @@ public function setUp()
$this->messageManager = $this->getMockBuilder(\Magento\Framework\Message\ManagerInterface::class)
->disableOriginalConstructor()
- ->setMethods(['addSuccess', 'addError', 'addException'])
+ ->setMethods(['addSuccessMessage', 'addErrorMessage', 'addExceptionMessage'])
->getMockForAbstractClass();
$this->contextMock->expects($this->any())
->method('getMessageManager')
@@ -132,12 +132,12 @@ public function testExecute()
$this->sessionsManager->expects($this->once())
->method('logoutOtherUserSessions');
$this->messageManager->expects($this->once())
- ->method('addSuccess')
+ ->method('addSuccessMessage')
->with($successMessage);
$this->messageManager->expects($this->never())
- ->method('addError');
+ ->method('addErrorMessage');
$this->messageManager->expects($this->never())
- ->method('addException');
+ ->method('addExceptionMessage');
$this->responseMock->expects($this->once())
->method('setRedirect');
$this->actionFlagMock->expects($this->once())
@@ -158,7 +158,7 @@ public function testExecuteLocalizedException()
->method('logoutOtherUserSessions')
->willThrowException(new LocalizedException($phrase));
$this->messageManager->expects($this->once())
- ->method('addError')
+ ->method('addErrorMessage')
->with($phrase);
$this->controller->execute();
}
@@ -173,7 +173,7 @@ public function testExecuteException()
->method('logoutOtherUserSessions')
->willThrowException(new \Exception());
$this->messageManager->expects($this->once())
- ->method('addException')
+ ->method('addExceptionMessage')
->with(new \Exception(), $phrase);
$this->controller->execute();
}
diff --git a/app/code/Magento/Security/Test/Unit/Model/Plugin/AuthSessionTest.php b/app/code/Magento/Security/Test/Unit/Model/Plugin/AuthSessionTest.php
index 5cb06d6143023..0f7f590b71de4 100644
--- a/app/code/Magento/Security/Test/Unit/Model/Plugin/AuthSessionTest.php
+++ b/app/code/Magento/Security/Test/Unit/Model/Plugin/AuthSessionTest.php
@@ -112,7 +112,7 @@ public function testAroundProlongSessionIsNotActiveAndIsNotAjaxRequest()
->willReturn($errorMessage);
$this->messageManagerMock->expects($this->once())
- ->method('addError')
+ ->method('addErrorMessage')
->with($errorMessage);
$this->model->aroundProlong($this->authSessionMock, $proceed);
diff --git a/app/code/Magento/Security/Test/Unit/Model/Plugin/LoginControllerTest.php b/app/code/Magento/Security/Test/Unit/Model/Plugin/LoginControllerTest.php
index 2bb2bc3cafac7..aa066e23f67cb 100644
--- a/app/code/Magento/Security/Test/Unit/Model/Plugin/LoginControllerTest.php
+++ b/app/code/Magento/Security/Test/Unit/Model/Plugin/LoginControllerTest.php
@@ -103,7 +103,7 @@ public function testBeforeExecute()
->willReturn($errorMessage);
$this->messageManagerMock->expects($this->once())
- ->method('addError')
+ ->method('addErrorMessage')
->with($errorMessage);
$this->securityCookieMock->expects($this->once())
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Delete.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Delete.php
index 422fed9d9a688..29d50ea8408fd 100644
--- a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Delete.php
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Delete.php
@@ -65,20 +65,20 @@ public function execute()
}
$sitemap->delete();
// display success message
- $this->messageManager->addSuccess(__('You deleted the sitemap.'));
+ $this->messageManager->addSuccessMessage(__('You deleted the sitemap.'));
// go to grid
$this->_redirect('adminhtml/*/');
return;
} catch (\Exception $e) {
// display error message
- $this->messageManager->addError($e->getMessage());
+ $this->messageManager->addErrorMessage($e->getMessage());
// go back to edit form
$this->_redirect('adminhtml/*/edit', ['sitemap_id' => $id]);
return;
}
}
// display error message
- $this->messageManager->addError(__('We can\'t find a sitemap to delete.'));
+ $this->messageManager->addErrorMessage(__('We can\'t find a sitemap to delete.'));
// go to grid
$this->_redirect('adminhtml/*/');
}
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Edit.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Edit.php
index 04ab4f8725e0e..111353550b9cd 100644
--- a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Edit.php
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Edit.php
@@ -41,7 +41,7 @@ public function execute()
if ($id) {
$model->load($id);
if (!$model->getId()) {
- $this->messageManager->addError(__('This sitemap no longer exists.'));
+ $this->messageManager->addErrorMessage(__('This sitemap no longer exists.'));
$this->_redirect('adminhtml/*/');
return;
}
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Generate.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Generate.php
index d19b248c8008f..9592ab6f57c55 100644
--- a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Generate.php
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Generate.php
@@ -52,18 +52,18 @@ public function execute()
);
$sitemap->generateXml();
- $this->messageManager->addSuccess(
+ $this->messageManager->addSuccessMessage(
__('The sitemap "%1" has been generated.', $sitemap->getSitemapFilename())
);
} catch (\Magento\Framework\Exception\LocalizedException $e) {
- $this->messageManager->addError($e->getMessage());
+ $this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
- $this->messageManager->addException($e, __('We can\'t generate the sitemap right now.'));
+ $this->messageManager->addExceptionMessage($e, __('We can\'t generate the sitemap right now.'));
} finally {
$this->appEmulation->stopEnvironmentEmulation();
}
} else {
- $this->messageManager->addError(__('We can\'t find a sitemap to generate.'));
+ $this->messageManager->addErrorMessage(__('We can\'t find a sitemap to generate.'));
}
// go to grid
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php
index 5c38cc68e6ef7..1e0d1cb248f00 100644
--- a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php
@@ -30,7 +30,7 @@ protected function validatePath(array $data)
$validator->setPaths($helper->getValidPaths());
if (!$validator->isValid($path)) {
foreach ($validator->getMessages() as $message) {
- $this->messageManager->addError($message);
+ $this->messageManager->addErrorMessage($message);
}
// save data in session
$this->_objectManager->get(\Magento\Backend\Model\Session::class)->setFormData($data);
@@ -83,13 +83,13 @@ protected function saveData($data)
// save the data
$model->save();
// display success message
- $this->messageManager->addSuccess(__('You saved the sitemap.'));
+ $this->messageManager->addSuccessMessage(__('You saved the sitemap.'));
// clear previously saved data from session
$this->_objectManager->get(\Magento\Backend\Model\Session::class)->setFormData(false);
return $model->getId();
} catch (\Exception $e) {
// display error message
- $this->messageManager->addError($e->getMessage());
+ $this->messageManager->addErrorMessage($e->getMessage());
// save data in session
$this->_objectManager->get(\Magento\Backend\Model\Session::class)->setFormData($data);
}
diff --git a/app/code/Magento/Sitemap/Test/Unit/Controller/Adminhtml/Sitemap/SaveTest.php b/app/code/Magento/Sitemap/Test/Unit/Controller/Adminhtml/Sitemap/SaveTest.php
index 36e3aa0312627..f77954101df7c 100644
--- a/app/code/Magento/Sitemap/Test/Unit/Controller/Adminhtml/Sitemap/SaveTest.php
+++ b/app/code/Magento/Sitemap/Test/Unit/Controller/Adminhtml/Sitemap/SaveTest.php
@@ -154,7 +154,7 @@ public function testTryToSaveInvalidDataShouldFailWithErrors()
->willReturnMap([[$helperClass, $helper], [$sessionClass, $session]]);
$this->messageManagerMock->expects($this->at(0))
- ->method('addError')
+ ->method('addErrorMessage')
->withConsecutive(
[$messages[0]],
[$messages[1]]
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest.xml
index f051d4f8c3b82..3e85ecc783253 100644
--- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest.xml
@@ -313,7 +313,7 @@
-
+
@@ -329,7 +329,7 @@
-
+
diff --git a/app/code/Magento/Ui/DataProvider/EavValidationRules.php b/app/code/Magento/Ui/DataProvider/EavValidationRules.php
index 12e345e1fa12c..6e2bb3866e947 100644
--- a/app/code/Magento/Ui/DataProvider/EavValidationRules.php
+++ b/app/code/Magento/Ui/DataProvider/EavValidationRules.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Ui\DataProvider;
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
@@ -31,25 +32,51 @@ class EavValidationRules
*/
public function build(AbstractAttribute $attribute, array $data)
{
- $validation = [];
+ $validations = [];
if (isset($data['required']) && $data['required'] == 1) {
- $validation = array_merge($validation, ['required-entry' => true]);
+ $validations = array_merge($validations, ['required-entry' => true]);
}
if ($attribute->getFrontendInput() === 'price') {
- $validation = array_merge($validation, ['validate-zero-or-greater' => true]);
+ $validations = array_merge($validations, ['validate-zero-or-greater' => true]);
}
if ($attribute->getValidateRules()) {
- $validation = array_merge($validation, $attribute->getValidateRules());
+ $validations = array_merge($validations, $this->clipLengthRules($attribute->getValidateRules()));
}
+ return $this->aggregateRules($validations);
+ }
+
+ /**
+ * @param array $validations
+ * @return array
+ */
+ private function aggregateRules(array $validations): array
+ {
$rules = [];
- foreach ($validation as $type => $ruleName) {
- $rule = [$type => $ruleName];
+ foreach ($validations as $type => $ruleValue) {
+ $rule = [$type => $ruleValue];
if ($type === 'input_validation') {
- $rule = isset($this->validationRules[$ruleName]) ? $this->validationRules[$ruleName] : [];
+ $rule = $this->validationRules[$ruleValue] ?? [];
+ }
+ if (count($rule) !== 0) {
+ $key = key($rule);
+ $rules[$key] = $rule[$key];
}
- $rules = array_merge($rules, $rule);
}
+ return $rules;
+ }
+ /**
+ * @param array $rules
+ * @return array
+ */
+ private function clipLengthRules(array $rules): array
+ {
+ if (empty($rules['input_validation'])) {
+ unset(
+ $rules['min_text_length'],
+ $rules['max_text_length']
+ );
+ }
return $rules;
}
}
diff --git a/app/code/Magento/Ui/Test/Unit/DataProvider/EavValidationRulesTest.php b/app/code/Magento/Ui/Test/Unit/DataProvider/EavValidationRulesTest.php
index debcde4765fc7..cdb62ce1db68d 100644
--- a/app/code/Magento/Ui/Test/Unit/DataProvider/EavValidationRulesTest.php
+++ b/app/code/Magento/Ui/Test/Unit/DataProvider/EavValidationRulesTest.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Ui\Test\Unit\DataProvider;
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
@@ -29,6 +30,9 @@ class EavValidationRulesTest extends \PHPUnit\Framework\TestCase
*/
protected $attributeMock;
+ /**
+ * {@inheritDoc}
+ */
protected function setUp()
{
$this->objectManager = new ObjectManager($this);
@@ -42,11 +46,13 @@ protected function setUp()
}
/**
+ * @param string $attributeInputType
+ * @param mixed $validateRules
* @param array $data
* @param array $expected
* @dataProvider buildDataProvider
*/
- public function testBuild($attributeInputType, $validateRules, $data, $expected)
+ public function testBuild($attributeInputType, $validateRules, $data, $expected): void
{
$this->attributeMock->expects($this->once())->method('getFrontendInput')->willReturn($attributeInputType);
$this->attributeMock->expects($this->any())->method('getValidateRules')->willReturn($validateRules);
@@ -70,11 +76,25 @@ public function buildDataProvider()
['', ['input_validation' => 'email'], [], ['validate-email' => true]],
['', ['input_validation' => 'date'], [], ['validate-date' => true]],
['', ['input_validation' => 'other'], [], []],
- ['', ['max_text_length' => '254'], ['required' => 1], ['max_text_length' => 254, 'required-entry' => true]],
- ['', ['max_text_length' => '254', 'min_text_length' => 1], [],
- ['max_text_length' => 254, 'min_text_length' => 1]],
- ['', ['max_text_length' => '254', 'input_validation' => 'date'], [],
- ['max_text_length' => 254, 'validate-date' => true]],
+ ['', ['max_text_length' => '254'], ['required' => 1], ['required-entry' => true]],
+ [
+ '',
+ ['input_validation' => 'other', 'max_text_length' => '254'],
+ ['required' => 1],
+ ['max_text_length' => 254, 'required-entry' => true]
+ ],
+ [
+ '',
+ ['input_validation' => 'other', 'max_text_length' => '254', 'min_text_length' => 1],
+ [],
+ ['max_text_length' => 254, 'min_text_length' => 1]
+ ],
+ [
+ '',
+ ['max_text_length' => '254', 'input_validation' => 'date'],
+ [],
+ ['max_text_length' => 254, 'validate-date' => true]
+ ],
];
}
}
diff --git a/app/code/Magento/Ui/etc/adminhtml/system.xml b/app/code/Magento/Ui/etc/adminhtml/system.xml
index 74e2e076b93c8..ab4272f8d2a34 100644
--- a/app/code/Magento/Ui/etc/adminhtml/system.xml
+++ b/app/code/Magento/Ui/etc/adminhtml/system.xml
@@ -9,12 +9,12 @@
-
+
Magento\Config\Model\Config\Source\Yesno
If enabled, can be used by functional tests for extended reporting
-
+
Use this key to retrieve collected js errors
diff --git a/app/code/Magento/Ui/i18n/en_US.csv b/app/code/Magento/Ui/i18n/en_US.csv
index ed4386f6000c3..106526f66e708 100644
--- a/app/code/Magento/Ui/i18n/en_US.csv
+++ b/app/code/Magento/Ui/i18n/en_US.csv
@@ -125,30 +125,18 @@ Ok,Ok
"Label Actions Two","Label Actions Two"
"Some Dynamic Actions","Some Dynamic Actions"
"Log JS Errors to Session Storage","Log JS Errors to Session Storage"
+"If enabled, can be used by functional tests for extended reporting","If enabled, can be used by functional tests for extended reporting"
"Log JS Errors to Session Storage Key","Log JS Errors to Session Storage Key"
+"Use this key to retrieve collected js errors","Use this key to retrieve collected js errors"
settings/label,settings/label
settings/confirm/title,settings/confirm/title
-"settings/confirm/message
- ","settings/confirm/message
- "
-"
- settings/callback/provider
- ","
- settings/callback/provider
- "
-"settings/callback/target
- ","settings/callback/target
- "
-"settings/newViewLabel
- ","settings/newViewLabel
- "
+"settings/confirm/message","settings/confirm/message"
+"settings/callback/provider","settings/callback/provider"
+"settings/callback/target","settings/callback/target"
+"settings/newViewLabel","settings/newViewLabel"
settings/title,settings/title
settings/description,settings/description
-"
- settings/addButtonLabel
- ","
- settings/addButtonLabel
- "
+"settings/addButtonLabel","settings/addButtonLabel"
"
formElements/*[name(.)=../../@formElement]/settings/description
","
diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml b/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml
index 94272f723ec77..ccd702c23ea65 100644
--- a/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml
+++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition.map.xml
@@ -16,15 +16,11 @@
- settings/url
-
- settings/confirm/title
- - settings/confirm/message
-
+ - settings/confirm/message
-
-
-
- settings/callback/provider
-
- - settings/callback/target
-
+ - settings/callback/provider
+ - settings/callback/target
@@ -59,8 +55,7 @@
-
- settings/childDefaults
- settings/viewTmpl
- - settings/newViewLabel
-
+ - settings/newViewLabel
@@ -265,9 +260,7 @@
- settings/columnsHeaderClasses
- settings/recordTemplate
- settings/collapsibleHeader
- -
- settings/addButtonLabel
-
+ - settings/addButtonLabel
- settings/addButton
- settings/deleteProperty
- settings/identificationProperty
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
index b729dd3127d90..6d33386fa1f1c 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
@@ -22,7 +22,7 @@ define([
opened: false,
level: 0,
visible: true,
- initializeFieldsetDataByDefault: false, /* Data in some fieldsets should be initialized before open */
+ initializeFieldsetDataByDefault: false, /* Data in some fieldsets should be initialized before open */
disabled: false,
listens: {
'opened': 'onVisibilityChange'
@@ -77,9 +77,9 @@ define([
elem.initContainer(this);
elem.on({
- 'update': this.onChildrenUpdate,
- 'loading': this.onContentLoading,
- 'error': this.onChildrenError
+ 'update': this.onChildrenUpdate,
+ 'loading': this.onContentLoading,
+ 'error': this.onChildrenError
});
if (this.disabled) {
@@ -155,11 +155,42 @@ define([
* @param {String} message - error message.
*/
onChildrenError: function (message) {
- var hasErrors = this.elems.some('error');
+ var hasErrors = false;
+
+ if (!message) {
+ hasErrors = this._isChildrenHasErrors(hasErrors, this);
+ }
this.error(hasErrors || message);
},
+ /**
+ * Returns errors of children if exist
+ *
+ * @param {Boolean} hasErrors
+ * @param {*} container
+ * @return {Boolean}
+ * @private
+ */
+ _isChildrenHasErrors: function (hasErrors, container) {
+ var self = this;
+
+ if (hasErrors === false && container.hasOwnProperty('elems')) {
+ hasErrors = container.elems.some('error');
+
+ if (hasErrors === false && container.hasOwnProperty('_elems')) {
+ container._elems.forEach(function (child) {
+
+ if (hasErrors === false) {
+ hasErrors = self._isChildrenHasErrors(hasErrors, child);
+ }
+ });
+ }
+ }
+
+ return hasErrors;
+ },
+
/**
* Callback that sets loading property to true.
*/
diff --git a/app/code/Magento/WebapiSecurity/etc/adminhtml/system.xml b/app/code/Magento/WebapiSecurity/etc/adminhtml/system.xml
index 425a2047cfd51..c38ea402718e3 100644
--- a/app/code/Magento/WebapiSecurity/etc/adminhtml/system.xml
+++ b/app/code/Magento/WebapiSecurity/etc/adminhtml/system.xml
@@ -5,10 +5,10 @@
-->
-
+
-
+
Magento\Config\Model\Config\Source\Yesno
This feature applies only to CMS, Catalog and Store APIs. Please consult your developers for details on potential security risks.
diff --git a/app/code/Magento/WebapiSecurity/i18n/en_US.csv b/app/code/Magento/WebapiSecurity/i18n/en_US.csv
index 94a4e8706bcd8..5e5e821e63e7f 100644
--- a/app/code/Magento/WebapiSecurity/i18n/en_US.csv
+++ b/app/code/Magento/WebapiSecurity/i18n/en_US.csv
@@ -1,2 +1,3 @@
"Web API Security","Web API Security"
"Allow Anonymous Guest Access","Allow Anonymous Guest Access"
+"This feature applies only to CMS, Catalog and Store APIs. Please consult your developers for details on potential security risks.","This feature applies only to CMS, Catalog and Store APIs. Please consult your developers for details on potential security risks."
diff --git a/app/code/Magento/Wishlist/etc/adminhtml/system.xml b/app/code/Magento/Wishlist/etc/adminhtml/system.xml
index 86c24bab11ffb..50ea4b01fe12b 100644
--- a/app/code/Magento/Wishlist/etc/adminhtml/system.xml
+++ b/app/code/Magento/Wishlist/etc/adminhtml/system.xml
@@ -22,12 +22,12 @@
Email template chosen based on theme fallback when "Default" option is selected.
Magento\Config\Model\Config\Source\Email\Template
-
+
10 by default. Max - 10000
validate-digits validate-digits-range digits-range-1-10000
-
+
255 by default
validate-digits validate-digits-range digits-range-1-10000
diff --git a/app/code/Magento/Wishlist/i18n/en_US.csv b/app/code/Magento/Wishlist/i18n/en_US.csv
index 75d5a2e840102..a1d33cbd574f0 100644
--- a/app/code/Magento/Wishlist/i18n/en_US.csv
+++ b/app/code/Magento/Wishlist/i18n/en_US.csv
@@ -99,7 +99,9 @@ Back,Back
"Email Template","Email Template"
"Email template chosen based on theme fallback when ""Default"" option is selected.","Email template chosen based on theme fallback when ""Default"" option is selected."
"Max Emails Allowed to be Sent","Max Emails Allowed to be Sent"
+"10 by default. Max - 10000","10 by default. Max - 10000"
"Email Text Length Limit","Email Text Length Limit"
+"255 by default","255 by default"
"General Options","General Options"
Enabled,Enabled
"My Wish List Link","My Wish List Link"
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml
index 9e20bbdaac1d9..5c05d4a840009 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml
@@ -49,6 +49,10 @@
+
+ stable:no
+ MAGETWO-94169: [MTF] - OnePageCheckoutUsingNonDefaultAddress_0 fails on 2.3-develop
+
severity:S1
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php
index 4c30adb6894e2..32a622d4aa654 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php
@@ -18,6 +18,9 @@ class AddressTest extends \Magento\TestFramework\TestCase\AbstractController
/** @var FormKey */
private $formKey;
+ /**
+ * {@inheritDoc}
+ */
protected function setUp()
{
parent::setUp();
@@ -150,8 +153,8 @@ public function testFailedFormPostAction()
$this->equalTo(
[
'One or more input exceptions have occurred.',
- '"street" is required. Enter and try again.',
- '"city" is required. Enter and try again.',
+ '"street" is required. Enter and try again.',
+ '"city" is required. Enter and try again.',
]
),
\Magento\Framework\Message\MessageInterface::TYPE_ERROR
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
index b942365d64a75..6448816c9345c 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
@@ -44,6 +44,9 @@ class IndexTest extends \Magento\TestFramework\TestCase\AbstractBackendControlle
/** @var \Magento\TestFramework\ObjectManager */
protected $objectManager;
+ /**
+ * {@inheritDoc}
+ */
protected function setUp()
{
parent::setUp();
@@ -67,6 +70,9 @@ protected function setUp()
);
}
+ /**
+ * {@inheritDoc}
+ */
protected function tearDown()
{
/**
@@ -522,7 +528,10 @@ public function testEditAction()
$this->assertContains('test firstname test lastname
', $body);
}
- public function testNewAction()
+ /**
+ * Tests new action
+ */
+ public function testNewAction(): void
{
$this->dispatch('backend/customer/index/edit');
$body = $this->getResponse()->getBody();
@@ -717,12 +726,9 @@ public function testValidateCustomerWithAddressFailure()
$this->assertContains('{"error":true,"messages":', $body);
$this->assertContains('\"First Name\" is a required value', $body);
- $this->assertContains('\"First Name\" length must be equal or greater than 1 characters', $body);
$this->assertContains('\"Last Name\" is a required value.', $body);
- $this->assertContains('\"Last Name\" length must be equal or greater than 1 characters.', $body);
$this->assertContains('\"Country\" is a required value.', $body);
$this->assertContains('\"Phone Number\" is a required value.', $body);
- $this->assertContains('\"Phone Number\" length must be equal or greater than 1 characters.', $body);
}
/**
diff --git a/lib/internal/Magento/Framework/Locale/Format.php b/lib/internal/Magento/Framework/Locale/Format.php
index 89f6957011876..ca50cdb2440f4 100644
--- a/lib/internal/Magento/Framework/Locale/Format.php
+++ b/lib/internal/Magento/Framework/Locale/Format.php
@@ -65,7 +65,7 @@ public function getNumber($value)
}
//trim spaces and apostrophes
- $value = str_replace(['\'', ' '], '', $value);
+ $value = preg_replace('/[^0-9^\^.,-]/m', '', $value);
$separatorComa = strpos($value, ',');
$separatorDot = strpos($value, '.');
diff --git a/lib/internal/Magento/Framework/Locale/Test/Unit/FormatTest.php b/lib/internal/Magento/Framework/Locale/Test/Unit/FormatTest.php
index 41583fd1383a5..1141f451c13a5 100644
--- a/lib/internal/Magento/Framework/Locale/Test/Unit/FormatTest.php
+++ b/lib/internal/Magento/Framework/Locale/Test/Unit/FormatTest.php
@@ -33,6 +33,9 @@ class FormatTest extends \PHPUnit\Framework\TestCase
*/
protected $currency;
+ /**
+ * {@inheritDoc}
+ */
protected function setUp()
{
$this->currency = $this->getMockBuilder(\Magento\Directory\Model\Currency::class)
@@ -41,9 +44,7 @@ protected function setUp()
$this->scope = $this->getMockBuilder(\Magento\Framework\App\ScopeInterface::class)
->setMethods(['getCurrentCurrency'])
->getMockForAbstractClass();
- $this->scope->expects($this->once())
- ->method('getCurrentCurrency')
- ->willReturn($this->currency);
+
$this->scopeResolver = $this->getMockBuilder(\Magento\Framework\App\ScopeResolverInterface::class)
->setMethods(['getScope'])
->getMockForAbstractClass();
@@ -52,7 +53,10 @@ protected function setUp()
->willReturn($this->scope);
$this->localeResolver = $this->getMockBuilder(\Magento\Framework\Locale\ResolverInterface::class)
->getMock();
+
+ /** @var \Magento\Directory\Model\CurrencyFactory|\PHPUnit_Framework_MockObject_MockObject $currencyFactory */
$currencyFactory = $this->getMockBuilder(\Magento\Directory\Model\CurrencyFactory::class)
+ ->disableOriginalConstructor()
->getMock();
$this->formatModel = new \Magento\Framework\Locale\Format(
@@ -63,21 +67,26 @@ protected function setUp()
}
/**
- * @param $localeCode
- * @param $expectedResult
+ * @param string $localeCode
+ * @param array $expectedResult
* @dataProvider getPriceFormatDataProvider
*/
- public function testGetPriceFormat($localeCode, $expectedResult)
+ public function testGetPriceFormat($localeCode, array $expectedResult): void
{
+ $this->scope->expects($this->once())
+ ->method('getCurrentCurrency')
+ ->willReturn($this->currency);
+
$result = $this->formatModel->getPriceFormat($localeCode);
$intersection = array_intersect_assoc($result, $expectedResult);
$this->assertCount(count($expectedResult), $intersection);
}
/**
+ *
* @return array
*/
- public function getPriceFormatDataProvider()
+ public function getPriceFormatDataProvider(): array
{
return [
['en_US', ['decimalSymbol' => '.', 'groupSymbol' => ',']],
@@ -86,4 +95,35 @@ public function getPriceFormatDataProvider()
['uk_UA', ['decimalSymbol' => ',', 'groupSymbol' => ' ']]
];
}
+
+ /**
+ *
+ * @param mixed $value
+ * @param float $expected
+ * @dataProvider provideNumbers
+ */
+ public function testGetNumber($value, $expected): void
+ {
+ $this->assertEquals($expected, $this->formatModel->getNumber($value));
+ }
+
+ /**
+ *
+ * @return array
+ */
+ public function provideNumbers(): array
+ {
+ return [
+ [' 2345.4356,1234', 23454356.1234],
+ ['+23,3452.123', 233452.123],
+ ['12343', 12343],
+ ['-9456km', -9456],
+ ['0', 0],
+ ['2 054,10', 2054.1],
+ ['2046,45', 2046.45],
+ ['2 054.52', 2054.52],
+ ['2,46 GB', 2.46],
+ ['2,054.00', 2054],
+ ];
+ }
}