diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml
index 063d66edb9e70..74e1c5f874954 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml
@@ -7,95 +7,111 @@
// @codingStandardsIgnoreFile
/** @var $block \Magento\Bundle\Block\Sales\Order\Items\Renderer */
+$parentItem = $block->getItem();
+$items = array_merge([$parentItem], $parentItem->getChildrenItems());
+$index = 0;
+$prevOptionId = '';
?>
-getItem() ?>
-getChildrenItems()); ?>
-
-
+
-
-
- getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
-
+ getItemOptions()
+ || $parentItem->getDescription()
+ || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem)
+ && $parentItem->getGiftMessageId()): ?>
+
-
+
- getParentItem()): ?>
- getSelectionAttributes($_item) ?>
-
+ getParentItem()): ?>
+ getSelectionAttributes($item) ?>
+
- = /* @escapeNotVerified */ $attributes['option_label'] ?> |
+ = $block->escapeHtml($attributes['option_label']); ?> |
-
+
-getParentItem()): ?> data-th="= /* @escapeNotVerified */ $attributes['option_label'] ?>">
- getParentItem()): ?>
-
- = $block->escapeHtml($_item->getName()) ?>
+ |
getParentItem()): ?>
+ data-th="= $block->escapeHtml($attributes['option_label']); ?>"
+ >
+ getParentItem()): ?>
+
+ = $block->escapeHtml($item->getName()); ?>
|
- = $block->getValueHtml($_item) ?> |
+
+ = $block->getValueHtml($item); ?>
+ |
- = /* @escapeNotVerified */ $block->prepareSku($_item->getSku()) ?> |
-
- getParentItem()): ?>
- = $block->getItemPriceHtml() ?>
+ |
+ = /* @noEscape */ $block->prepareSku($item->getSku()); ?>
+ |
+
+ getParentItem()): ?>
+ = /* @noEscape */ $block->getItemPriceHtml(); ?>
|
-
+ |
getParentItem() && $block->isChildCalculated()) ||
- (!$_item->getParentItem() && !$block->isChildCalculated()) || ($_item->getQtyShipped() > 0 && $_item->getParentItem() && $block->isShipmentSeparately())):?>
+ ($item->getParentItem() && $block->isChildCalculated()) ||
+ (!$item->getParentItem() && !$block->isChildCalculated()) ||
+ ($item->getQtyShipped() > 0 && $item->getParentItem() && $block->isShipmentSeparately())): ?>
- getParentItem() && $block->isChildCalculated()) ||
- (!$_item->getParentItem() && !$block->isChildCalculated())): ?>
- getQtyOrdered() > 0): ?>
+ getParentItem() && $block->isChildCalculated()) ||
+ (!$item->getParentItem() && !$block->isChildCalculated())): ?>
+ getQtyOrdered() > 0): ?>
-
- = /* @escapeNotVerified */ __('Ordered') ?>
- = /* @escapeNotVerified */ $_item->getQtyOrdered()*1 ?>
+ = $block->escapeHtml(__('Ordered')); ?>
+ = /* @noEscape */ $item->getQtyOrdered() * 1; ?>
- getQtyShipped() > 0 && !$block->isShipmentSeparately()): ?>
+ getQtyShipped() > 0 && !$block->isShipmentSeparately()): ?>
-
- = /* @escapeNotVerified */ __('Shipped') ?>
- = /* @escapeNotVerified */ $_item->getQtyShipped()*1 ?>
+ = $block->escapeHtml(__('Shipped')); ?>
+ = /* @noEscape */ $item->getQtyShipped() * 1; ?>
- getQtyCanceled() > 0): ?>
+ getQtyCanceled() > 0): ?>
-
- = /* @escapeNotVerified */ __('Canceled') ?>
- = /* @escapeNotVerified */ $_item->getQtyCanceled()*1 ?>
+ = $block->escapeHtml(__('Canceled')); ?>
+ = /* @noEscape */ $item->getQtyCanceled() * 1; ?>
- getQtyRefunded() > 0): ?>
+ getQtyRefunded() > 0): ?>
-
- = /* @escapeNotVerified */ __('Refunded') ?>
- = /* @escapeNotVerified */ $_item->getQtyRefunded()*1 ?>
+ = $block->escapeHtml(__('Refunded')); ?>
+ = /* @noEscape */ $item->getQtyRefunded() * 1; ?>
- getQtyShipped() > 0 && $_item->getParentItem() && $block->isShipmentSeparately()): ?>
+ getQtyShipped() > 0 && $item->getParentItem() && $block->isShipmentSeparately()): ?>
-
- = /* @escapeNotVerified */ __('Shipped') ?>
- = /* @escapeNotVerified */ $_item->getQtyShipped()*1 ?>
+ = $block->escapeHtml(__('Shipped')); ?>
+ = /* @noEscape */ $item->getQtyShipped() * 1; ?>
-
+ = /* @noEscape */ $parentItem->getQtyOrdered() * 1; ?>
getParentItem() && $block->isChildCalculated()) ||
- (!$_item->getParentItem() && !$block->isChildCalculated()) || ($_item->getQtyShipped() > 0 && $_item->getParentItem() && $block->isShipmentSeparately())):?>
+ ($item->getParentItem() && $block->isChildCalculated()) ||
+ (!$item->getParentItem() && !$block->isChildCalculated()) ||
+ ($item->getQtyShipped() > 0 && $item->getParentItem() && $block->isShipmentSeparately())):?>
|
- getParentItem()): ?>
- = $block->getItemRowTotalHtml() ?>
+ getParentItem()): ?>
+ = /* @noEscape */ $block->getItemRowTotalHtml(); ?>
@@ -103,33 +119,38 @@
|
-getItemOptions()) || $block->escapeHtml($_item->getDescription()))): ?>
+getItemOptions()) || $block->escapeHtml($item->getDescription()))): ?>
- getItemOptions()): ?>
+ getItemOptions()): ?>
-
- - = $block->escapeHtml($_option['label']) ?>
+
+ - = $block->escapeHtml($option['label']) ?>
getPrintStatus()): ?>
- getFormatedOptionValue($_option) ?>
- - class="tooltip wrapper">
- = /* @escapeNotVerified */ $_formatedOptionValue['value'] ?>
-
+ getFormatedOptionValue($option) ?>
+
-
+ class="tooltip wrapper"
+ >
+ = /* @noEscape */ $formattedOptionValue['value'] ?>
+
- - = $block->escapeHtml($_option['label']) ?>
- - = /* @escapeNotVerified */ $_formatedOptionValue['full_view'] ?>
+ - = $block->escapeHtml($option['label']); ?>
+ - = /* @noEscape */ $formattedOptionValue['full_view']; ?>
- - = $block->escapeHtml((isset($_option['print_value']) ? $_option['print_value'] : $_option['value'])) ?>
+ - = $block->escapeHtml((isset($option['print_value']) ?
+ $option['print_value'] :
+ $option['value'])); ?>
+
- = $block->escapeHtml($_item->getDescription()) ?>
+ = $block->escapeHtml($item->getDescription()); ?>
|
diff --git a/app/code/Magento/Catalog/view/base/web/js/price-box.js b/app/code/Magento/Catalog/view/base/web/js/price-box.js
index de68d769885fd..783d39cddbc76 100644
--- a/app/code/Magento/Catalog/view/base/web/js/price-box.js
+++ b/app/code/Magento/Catalog/view/base/web/js/price-box.js
@@ -78,11 +78,7 @@ define([
pricesCode = [],
priceValue, origin, finalPrice;
- if (typeof newPrices !== 'undefined' && newPrices.hasOwnProperty('prices')) {
- this.cache.additionalPriceObject = {};
- } else {
- this.cache.additionalPriceObject = this.cache.additionalPriceObject || {};
- }
+ this.cache.additionalPriceObject = this.cache.additionalPriceObject || {};
if (newPrices) {
$.extend(this.cache.additionalPriceObject, newPrices);
diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php
index 7aac6e98fc044..7b239d84bf962 100644
--- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php
+++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Attribute.php
@@ -91,12 +91,10 @@ protected function _getItemsData()
return $this->itemDataBuilder->build();
}
- $productSize = $productCollection->getSize();
-
$options = $attribute->getFrontend()
->getSelectOptions();
foreach ($options as $option) {
- $this->buildOptionData($option, $isAttributeFilterable, $optionsFacetedData, $productSize);
+ $this->buildOptionData($option, $isAttributeFilterable, $optionsFacetedData);
}
return $this->itemDataBuilder->build();
@@ -108,17 +106,16 @@ protected function _getItemsData()
* @param array $option
* @param boolean $isAttributeFilterable
* @param array $optionsFacetedData
- * @param int $productSize
* @return void
*/
- private function buildOptionData($option, $isAttributeFilterable, $optionsFacetedData, $productSize)
+ private function buildOptionData($option, $isAttributeFilterable, $optionsFacetedData)
{
$value = $this->getOptionValue($option);
if ($value === false) {
return;
}
$count = $this->getOptionCount($value, $optionsFacetedData);
- if ($isAttributeFilterable && (!$this->isOptionReducesResults($count, $productSize) || $count === 0)) {
+ if ($isAttributeFilterable && $count === 0) {
return;
}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/AttributeTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/AttributeTest.php
index abc0fdd1069fe..69e2c33d02d1a 100644
--- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/AttributeTest.php
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/AttributeTest.php
@@ -321,10 +321,6 @@ public function testGetItemsWithoutApply()
->method('build')
->will($this->returnValue($builtData));
- $this->fulltextCollection->expects($this->once())
- ->method('getSize')
- ->will($this->returnValue(50));
-
$expectedFilterItems = [
$this->createFilterItem(0, $builtData[0]['label'], $builtData[0]['value'], $builtData[0]['count']),
$this->createFilterItem(1, $builtData[1]['label'], $builtData[1]['value'], $builtData[1]['count']),
@@ -383,9 +379,6 @@ public function testGetItemsOnlyWithResults()
$this->fulltextCollection->expects($this->once())
->method('getFacetedData')
->willReturn($facetedData);
- $this->fulltextCollection->expects($this->once())
- ->method('getSize')
- ->will($this->returnValue(50));
$this->itemDataBuilder->expects($this->once())
->method('addItemData')
diff --git a/app/code/Magento/Config/Console/Command/ConfigSet/DefaultProcessor.php b/app/code/Magento/Config/Console/Command/ConfigSet/DefaultProcessor.php
index d7d513bfad423..86ae1f96749df 100644
--- a/app/code/Magento/Config/Console/Command/ConfigSet/DefaultProcessor.php
+++ b/app/code/Magento/Config/Console/Command/ConfigSet/DefaultProcessor.php
@@ -7,17 +7,19 @@
use Magento\Config\App\Config\Type\System;
use Magento\Config\Console\Command\ConfigSetCommand;
+use Magento\Config\Model\Config\Factory as ConfigFactory;
use Magento\Framework\App\Config\ConfigPathResolver;
use Magento\Framework\App\DeploymentConfig;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Config\Model\PreparedValueFactory;
-use Magento\Framework\App\Config\Value;
/**
* Processes default flow of config:set command.
+ *
* This processor saves the value of configuration into database.
*
- * {@inheritdoc}
+ * @inheritdoc
* @api
* @since 100.2.0
*/
@@ -44,26 +46,36 @@ class DefaultProcessor implements ConfigSetProcessorInterface
*/
private $preparedValueFactory;
+ /**
+ * @var ConfigFactory
+ */
+ private $configFactory;
+
/**
* @param PreparedValueFactory $preparedValueFactory The factory for prepared value
* @param DeploymentConfig $deploymentConfig The deployment configuration reader
* @param ConfigPathResolver $configPathResolver The resolver for configuration paths according to source type
+ * @param ConfigFactory|null $configFactory
*/
public function __construct(
PreparedValueFactory $preparedValueFactory,
DeploymentConfig $deploymentConfig,
- ConfigPathResolver $configPathResolver
+ ConfigPathResolver $configPathResolver,
+ ConfigFactory $configFactory = null
) {
$this->preparedValueFactory = $preparedValueFactory;
$this->deploymentConfig = $deploymentConfig;
$this->configPathResolver = $configPathResolver;
+
+ $this->configFactory = $configFactory ?? ObjectManager::getInstance()->get(ConfigFactory::class);
}
/**
* Processes database flow of config:set command.
+ *
* Requires installed application.
*
- * {@inheritdoc}
+ * @inheritdoc
* @since 100.2.0
*/
public function process($path, $value, $scope, $scopeCode)
@@ -78,12 +90,12 @@ public function process($path, $value, $scope, $scopeCode)
}
try {
- /** @var Value $backendModel */
- $backendModel = $this->preparedValueFactory->create($path, $value, $scope, $scopeCode);
- if ($backendModel instanceof Value) {
- $resourceModel = $backendModel->getResource();
- $resourceModel->save($backendModel);
- }
+ $config = $this->configFactory->create([
+ 'scope' => $scope,
+ 'scope_code' => $scopeCode,
+ ]);
+ $config->setDataByPath($path, $value);
+ $config->save();
} catch (\Exception $exception) {
throw new CouldNotSaveException(__('%1', $exception->getMessage()), $exception);
}
diff --git a/app/code/Magento/Config/Model/Config.php b/app/code/Magento/Config/Model/Config.php
index 0472c5daa276f..b1074e92cc949 100644
--- a/app/code/Magento/Config/Model/Config.php
+++ b/app/code/Magento/Config/Model/Config.php
@@ -9,15 +9,32 @@
use Magento\Config\Model\Config\Structure\Element\Group;
use Magento\Config\Model\Config\Structure\Element\Field;
use Magento\Framework\App\ObjectManager;
+use Magento\Framework\App\ScopeInterface;
+use Magento\Framework\App\ScopeResolverPool;
+use Magento\Store\Model\ScopeInterface as StoreScopeInterface;
+use Magento\Store\Model\ScopeTypeNormalizer;
/**
* Backend config model
+ *
* Used to save configuration
*
* @author Magento Core Team
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @api
* @since 100.0.2
+ * @method string getSection()
+ * @method void setSection(string $section)
+ * @method string getWebsite()
+ * @method void setWebsite(string $website)
+ * @method string getStore()
+ * @method void setStore(string $store)
+ * @method string getScope()
+ * @method void setScope(string $scope)
+ * @method int getScopeId()
+ * @method void setScopeId(int $scopeId)
+ * @method string getScopeCode()
+ * @method void setScopeCode(string $scopeCode)
*/
class Config extends \Magento\Framework\DataObject
{
@@ -87,6 +104,16 @@ class Config extends \Magento\Framework\DataObject
*/
private $settingChecker;
+ /**
+ * @var ScopeResolverPool
+ */
+ private $scopeResolverPool;
+
+ /**
+ * @var ScopeTypeNormalizer
+ */
+ private $scopeTypeNormalizer;
+
/**
* @param \Magento\Framework\App\Config\ReinitableConfigInterface $config
* @param \Magento\Framework\Event\ManagerInterface $eventManager
@@ -97,6 +124,9 @@ class Config extends \Magento\Framework\DataObject
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param Config\Reader\Source\Deployed\SettingChecker|null $settingChecker
* @param array $data
+ * @param ScopeResolverPool|null $scopeResolverPool
+ * @param ScopeTypeNormalizer|null $scopeTypeNormalizer
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
\Magento\Framework\App\Config\ReinitableConfigInterface $config,
@@ -107,7 +137,9 @@ public function __construct(
\Magento\Framework\App\Config\ValueFactory $configValueFactory,
\Magento\Store\Model\StoreManagerInterface $storeManager,
SettingChecker $settingChecker = null,
- array $data = []
+ array $data = [],
+ ScopeResolverPool $scopeResolverPool = null,
+ ScopeTypeNormalizer $scopeTypeNormalizer = null
) {
parent::__construct($data);
$this->_eventManager = $eventManager;
@@ -117,11 +149,17 @@ public function __construct(
$this->_configLoader = $configLoader;
$this->_configValueFactory = $configValueFactory;
$this->_storeManager = $storeManager;
- $this->settingChecker = $settingChecker ?: ObjectManager::getInstance()->get(SettingChecker::class);
+ $this->settingChecker = $settingChecker
+ ?? ObjectManager::getInstance()->get(SettingChecker::class);
+ $this->scopeResolverPool = $scopeResolverPool
+ ?? ObjectManager::getInstance()->get(ScopeResolverPool::class);
+ $this->scopeTypeNormalizer = $scopeTypeNormalizer
+ ?? ObjectManager::getInstance()->get(ScopeTypeNormalizer::class);
}
/**
* Save config section
+ *
* Require set: section, website, store and groups
*
* @throws \Exception
@@ -504,8 +542,8 @@ public function setDataByPath($path, $value)
}
/**
- * Get scope name and scopeId
- * @todo refactor to scope resolver
+ * Set scope data
+ *
* @return void
*/
private function initScope()
@@ -513,31 +551,66 @@ private function initScope()
if ($this->getSection() === null) {
$this->setSection('');
}
+
+ $scope = $this->retrieveScope();
+ $this->setScope($this->scopeTypeNormalizer->normalize($scope->getScopeType()));
+ $this->setScopeCode($scope->getCode());
+ $this->setScopeId($scope->getId());
+
if ($this->getWebsite() === null) {
- $this->setWebsite('');
+ $this->setWebsite(StoreScopeInterface::SCOPE_WEBSITES === $this->getScope() ? $scope->getId() : '');
}
if ($this->getStore() === null) {
- $this->setStore('');
+ $this->setStore(StoreScopeInterface::SCOPE_STORES === $this->getScope() ? $scope->getId() : '');
}
+ }
- if ($this->getStore()) {
- $scope = 'stores';
- $store = $this->_storeManager->getStore($this->getStore());
- $scopeId = (int)$store->getId();
- $scopeCode = $store->getCode();
- } elseif ($this->getWebsite()) {
- $scope = 'websites';
- $website = $this->_storeManager->getWebsite($this->getWebsite());
- $scopeId = (int)$website->getId();
- $scopeCode = $website->getCode();
+ /**
+ * Retrieve scope from initial data
+ *
+ * @return ScopeInterface
+ */
+ private function retrieveScope(): ScopeInterface
+ {
+ $scopeType = $this->getScope();
+ if (!$scopeType) {
+ switch (true) {
+ case $this->getStore():
+ $scopeType = StoreScopeInterface::SCOPE_STORES;
+ $scopeIdentifier = $this->getStore();
+ break;
+ case $this->getWebsite():
+ $scopeType = StoreScopeInterface::SCOPE_WEBSITES;
+ $scopeIdentifier = $this->getWebsite();
+ break;
+ default:
+ $scopeType = ScopeInterface::SCOPE_DEFAULT;
+ $scopeIdentifier = null;
+ break;
+ }
} else {
- $scope = 'default';
- $scopeId = 0;
- $scopeCode = '';
+ switch (true) {
+ case $this->getScopeId() !== null:
+ $scopeIdentifier = $this->getScopeId();
+ break;
+ case $this->getScopeCode() !== null:
+ $scopeIdentifier = $this->getScopeCode();
+ break;
+ case $this->getStore() !== null:
+ $scopeIdentifier = $this->getStore();
+ break;
+ case $this->getWebsite() !== null:
+ $scopeIdentifier = $this->getWebsite();
+ break;
+ default:
+ $scopeIdentifier = null;
+ break;
+ }
}
- $this->setScope($scope);
- $this->setScopeId($scopeId);
- $this->setScopeCode($scopeCode);
+ $scope = $this->scopeResolverPool->get($scopeType)
+ ->getScope($scopeIdentifier);
+
+ return $scope;
}
/**
diff --git a/app/code/Magento/Config/Model/Config/Backend/Currency/AbstractCurrency.php b/app/code/Magento/Config/Model/Config/Backend/Currency/AbstractCurrency.php
index 4ae66bfd9692b..25303093ace5d 100644
--- a/app/code/Magento/Config/Model/Config/Backend/Currency/AbstractCurrency.php
+++ b/app/code/Magento/Config/Model/Config/Backend/Currency/AbstractCurrency.php
@@ -14,6 +14,8 @@
namespace Magento\Config\Model\Config\Backend\Currency;
/**
+ * Base currency class
+ *
* @api
* @since 100.0.2
*/
@@ -26,18 +28,19 @@ abstract class AbstractCurrency extends \Magento\Framework\App\Config\Value
*/
protected function _getAllowedCurrencies()
{
- if (!$this->isFormData() || $this->getData('groups/options/fields/allow/inherit')) {
- return explode(
+ $allowValue = $this->getData('groups/options/fields/allow/value');
+ $allowedCurrencies = $allowValue === null || $this->getData('groups/options/fields/allow/inherit')
+ ? explode(
',',
(string)$this->_config->getValue(
\Magento\Directory\Model\Currency::XML_PATH_CURRENCY_ALLOW,
$this->getScope(),
$this->getScopeId()
)
- );
- }
+ )
+ : (array) $allowValue;
- return (array)$this->getData('groups/options/fields/allow/value');
+ return $allowedCurrencies;
}
/**
diff --git a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/DefaultProcessorTest.php b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/DefaultProcessorTest.php
index 984e0fe842687..3fb7d9ad21cd4 100644
--- a/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/DefaultProcessorTest.php
+++ b/app/code/Magento/Config/Test/Unit/Console/Command/ConfigSet/DefaultProcessorTest.php
@@ -7,13 +7,14 @@
use Magento\Config\App\Config\Type\System;
use Magento\Config\Console\Command\ConfigSet\DefaultProcessor;
+use Magento\Config\Model\Config;
+use Magento\Config\Model\Config\Factory as ConfigFactory;
use Magento\Framework\App\Config\ConfigPathResolver;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\DeploymentConfig;
use Magento\Store\Model\ScopeInterface;
use Magento\Config\Model\PreparedValueFactory;
use Magento\Framework\App\Config\Value;
-use Magento\Framework\App\Config\ValueInterface;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
use PHPUnit_Framework_MockObject_MockObject as Mock;
@@ -55,17 +56,18 @@ class DefaultProcessorTest extends \PHPUnit\Framework\TestCase
*/
private $resourceModelMock;
+ /**
+ * @var ConfigFactory|Mock
+ */
+ private $configFactory;
+
/**
* @inheritdoc
*/
protected function setUp()
{
- $this->deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->configPathResolverMock = $this->getMockBuilder(ConfigPathResolver::class)
- ->disableOriginalConstructor()
- ->getMock();
+ $this->deploymentConfigMock = $this->createMock(DeploymentConfig::class);
+ $this->configPathResolverMock = $this->createMock(ConfigPathResolver::class);
$this->resourceModelMock = $this->getMockBuilder(AbstractDb::class)
->disableOriginalConstructor()
->setMethods(['save'])
@@ -74,14 +76,14 @@ protected function setUp()
->disableOriginalConstructor()
->setMethods(['getResource'])
->getMock();
- $this->preparedValueFactoryMock = $this->getMockBuilder(PreparedValueFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
+ $this->preparedValueFactoryMock = $this->createMock(PreparedValueFactory::class);
+ $this->configFactory = $this->createMock(ConfigFactory::class);
$this->model = new DefaultProcessor(
$this->preparedValueFactoryMock,
$this->deploymentConfigMock,
- $this->configPathResolverMock
+ $this->configPathResolverMock,
+ $this->configFactory
);
}
@@ -98,15 +100,14 @@ public function testProcess($path, $value, $scope, $scopeCode)
{
$this->configMockForProcessTest($path, $scope, $scopeCode);
- $this->preparedValueFactoryMock->expects($this->once())
- ->method('create')
- ->willReturn($this->valueMock);
- $this->valueMock->expects($this->once())
- ->method('getResource')
- ->willReturn($this->resourceModelMock);
- $this->resourceModelMock->expects($this->once())
+ $config = $this->createMock(Config::class);
+ $this->configFactory->method('create')
+ ->with(['scope' => $scope, 'scope_code' => $scopeCode])
+ ->willReturn($config);
+ $config->method('setDataByPath')
+ ->with($path, $value);
+ $config->expects($this->once())
->method('save')
- ->with($this->valueMock)
->willReturnSelf();
$this->model->process($path, $value, $scope, $scopeCode);
@@ -124,28 +125,6 @@ public function processDataProvider()
];
}
- public function testProcessWithWrongValueInstance()
- {
- $path = 'test/test/test';
- $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT;
- $scopeCode = null;
- $value = 'value';
- $valueInterfaceMock = $this->getMockBuilder(ValueInterface::class)
- ->getMockForAbstractClass();
-
- $this->configMockForProcessTest($path, $scope, $scopeCode);
-
- $this->preparedValueFactoryMock->expects($this->once())
- ->method('create')
- ->willReturn($valueInterfaceMock);
- $this->valueMock->expects($this->never())
- ->method('getResource');
- $this->resourceModelMock->expects($this->never())
- ->method('save');
-
- $this->model->process($path, $value, $scope, $scopeCode);
- }
-
/**
* @param string $path
* @param string $scope
@@ -185,6 +164,9 @@ public function testProcessLockedValue()
->method('resolve')
->willReturn('system/default/test/test/test');
+ $this->configFactory->expects($this->never())
+ ->method('create');
+
$this->model->process($path, $value, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null);
}
}
diff --git a/app/code/Magento/Config/Test/Unit/Model/ConfigTest.php b/app/code/Magento/Config/Test/Unit/Model/ConfigTest.php
index fcc1ff8b9c70c..bb772f51c0dac 100644
--- a/app/code/Magento/Config/Test/Unit/Model/ConfigTest.php
+++ b/app/code/Magento/Config/Test/Unit/Model/ConfigTest.php
@@ -5,138 +5,183 @@
*/
namespace Magento\Config\Test\Unit\Model;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+use Magento\Config\Model\Config;
+use Magento\Framework\App\Config\ReinitableConfigInterface;
+use Magento\Framework\Event\ManagerInterface;
+use Magento\Config\Model\Config\Structure\Reader;
+use Magento\Framework\DB\TransactionFactory;
+use Magento\Config\Model\Config\Loader;
+use Magento\Framework\App\Config\ValueFactory;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\Config\Model\Config\Structure;
+use Magento\Config\Model\Config\Reader\Source\Deployed\SettingChecker;
+use Magento\Framework\App\ScopeResolverPool;
+use Magento\Framework\App\ScopeResolverInterface;
+use Magento\Framework\App\ScopeInterface;
+use Magento\Store\Model\ScopeTypeNormalizer;
+use Magento\Framework\DB\Transaction;
+use Magento\Framework\App\Config\Value;
+use Magento\Store\Model\Website;
+use Magento\Config\Model\Config\Structure\Element\Group;
+use Magento\Config\Model\Config\Structure\Element\Field;
+
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ConfigTest extends \PHPUnit\Framework\TestCase
{
/**
- * @var \Magento\Config\Model\Config
+ * @var Config
+ */
+ private $model;
+
+ /**
+ * @var ManagerInterface|MockObject
+ */
+ private $eventManagerMock;
+
+ /**
+ * @var Reader|MockObject
+ */
+ private $structureReaderMock;
+
+ /**
+ * @var TransactionFactory|MockObject
*/
- protected $_model;
+ private $transFactoryMock;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var ReinitableConfigInterface|MockObject
*/
- protected $_eventManagerMock;
+ private $appConfigMock;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var Loader|MockObject
*/
- protected $_structureReaderMock;
+ private $configLoaderMock;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var ValueFactory|MockObject
*/
- protected $_transFactoryMock;
+ private $dataFactoryMock;
/**
- * @var \Magento\Framework\App\Config\ReinitableConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+ * @var StoreManagerInterface|MockObject
*/
- protected $_appConfigMock;
+ private $storeManager;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var Structure|MockObject
*/
- protected $_applicationMock;
+ private $configStructure;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var SettingChecker|MockObject
*/
- protected $_configLoaderMock;
+ private $settingsChecker;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var ScopeResolverPool|MockObject
*/
- protected $_dataFactoryMock;
+ private $scopeResolverPool;
/**
- * @var \Magento\Store\Model\StoreManagerInterface
+ * @var ScopeResolverInterface|MockObject
*/
- protected $_storeManager;
+ private $scopeResolver;
/**
- * @var \Magento\Config\Model\Config\Structure
+ * @var ScopeInterface|MockObject
*/
- protected $_configStructure;
+ private $scope;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var ScopeTypeNormalizer|MockObject
*/
- private $_settingsChecker;
+ private $scopeTypeNormalizer;
protected function setUp()
{
- $this->_eventManagerMock = $this->createMock(\Magento\Framework\Event\ManagerInterface::class);
- $this->_structureReaderMock = $this->createPartialMock(
- \Magento\Config\Model\Config\Structure\Reader::class,
+ $this->eventManagerMock = $this->createMock(ManagerInterface::class);
+ $this->structureReaderMock = $this->createPartialMock(
+ Reader::class,
['getConfiguration']
);
- $this->_configStructure = $this->createMock(\Magento\Config\Model\Config\Structure::class);
+ $this->configStructure = $this->createMock(Structure::class);
- $this->_structureReaderMock->expects(
- $this->any()
- )->method(
- 'getConfiguration'
- )->will(
- $this->returnValue($this->_configStructure)
- );
+ $this->structureReaderMock->method('getConfiguration')
+ ->willReturn($this->configStructure);
- $this->_transFactoryMock = $this->createPartialMock(
- \Magento\Framework\DB\TransactionFactory::class,
+ $this->transFactoryMock = $this->createPartialMock(
+ TransactionFactory::class,
['create', 'addObject']
);
- $this->_appConfigMock = $this->createMock(\Magento\Framework\App\Config\ReinitableConfigInterface::class);
- $this->_configLoaderMock = $this->createPartialMock(
- \Magento\Config\Model\Config\Loader::class,
+ $this->appConfigMock = $this->createMock(ReinitableConfigInterface::class);
+ $this->configLoaderMock = $this->createPartialMock(
+ Loader::class,
['getConfigByPath']
);
- $this->_dataFactoryMock = $this->createMock(\Magento\Framework\App\Config\ValueFactory::class);
-
- $this->_storeManager = $this->getMockForAbstractClass(\Magento\Store\Model\StoreManagerInterface::class);
-
- $this->_settingsChecker = $this
- ->createMock(\Magento\Config\Model\Config\Reader\Source\Deployed\SettingChecker::class);
-
- $this->_model = new \Magento\Config\Model\Config(
- $this->_appConfigMock,
- $this->_eventManagerMock,
- $this->_configStructure,
- $this->_transFactoryMock,
- $this->_configLoaderMock,
- $this->_dataFactoryMock,
- $this->_storeManager,
- $this->_settingsChecker
+ $this->dataFactoryMock = $this->createMock(ValueFactory::class);
+
+ $this->storeManager = $this->createMock(StoreManagerInterface::class);
+
+ $this->settingsChecker = $this->createMock(SettingChecker::class);
+
+ $this->scopeResolverPool = $this->createMock(ScopeResolverPool::class);
+ $this->scopeResolver = $this->createMock(ScopeResolverInterface::class);
+ $this->scopeResolverPool->method('get')
+ ->willReturn($this->scopeResolver);
+ $this->scope = $this->createMock(ScopeInterface::class);
+ $this->scopeResolver->method('getScope')
+ ->willReturn($this->scope);
+
+ $this->scopeTypeNormalizer = $this->createMock(ScopeTypeNormalizer::class);
+
+ $this->model = new Config(
+ $this->appConfigMock,
+ $this->eventManagerMock,
+ $this->configStructure,
+ $this->transFactoryMock,
+ $this->configLoaderMock,
+ $this->dataFactoryMock,
+ $this->storeManager,
+ $this->settingsChecker,
+ [],
+ $this->scopeResolverPool,
+ $this->scopeTypeNormalizer
);
}
public function testSaveDoesNotDoAnythingIfGroupsAreNotPassed()
{
- $this->_configLoaderMock->expects($this->never())->method('getConfigByPath');
- $this->_model->save();
+ $this->configLoaderMock->expects($this->never())->method('getConfigByPath');
+ $this->model->save();
}
public function testSaveEmptiesNonSetArguments()
{
- $this->_structureReaderMock->expects($this->never())->method('getConfiguration');
- $this->assertNull($this->_model->getSection());
- $this->assertNull($this->_model->getWebsite());
- $this->assertNull($this->_model->getStore());
- $this->_model->save();
- $this->assertSame('', $this->_model->getSection());
- $this->assertSame('', $this->_model->getWebsite());
- $this->assertSame('', $this->_model->getStore());
+ $this->structureReaderMock->expects($this->never())->method('getConfiguration');
+ $this->assertNull($this->model->getSection());
+ $this->assertNull($this->model->getWebsite());
+ $this->assertNull($this->model->getStore());
+ $this->model->save();
+ $this->assertSame('', $this->model->getSection());
+ $this->assertSame('', $this->model->getWebsite());
+ $this->assertSame('', $this->model->getStore());
}
public function testSaveToCheckAdminSystemConfigChangedSectionEvent()
{
- $transactionMock = $this->createMock(\Magento\Framework\DB\Transaction::class);
+ $transactionMock = $this->createMock(Transaction::class);
- $this->_transFactoryMock->expects($this->any())->method('create')->will($this->returnValue($transactionMock));
+ $this->transFactoryMock->method('create')
+ ->willReturn($transactionMock);
- $this->_configLoaderMock->expects($this->any())->method('getConfigByPath')->will($this->returnValue([]));
+ $this->configLoaderMock->method('getConfigByPath')
+ ->willReturn([]);
- $this->_eventManagerMock->expects(
+ $this->eventManagerMock->expects(
$this->at(0)
)->method(
'dispatch'
@@ -145,7 +190,7 @@ public function testSaveToCheckAdminSystemConfigChangedSectionEvent()
$this->arrayHasKey('website')
);
- $this->_eventManagerMock->expects(
+ $this->eventManagerMock->expects(
$this->at(0)
)->method(
'dispatch'
@@ -154,123 +199,147 @@ public function testSaveToCheckAdminSystemConfigChangedSectionEvent()
$this->arrayHasKey('store')
);
- $this->_model->setGroups(['1' => ['data']]);
- $this->_model->save();
+ $this->model->setGroups(['1' => ['data']]);
+ $this->model->save();
}
public function testDoNotSaveReadOnlyFields()
{
- $transactionMock = $this->createMock(\Magento\Framework\DB\Transaction::class);
- $this->_transFactoryMock->expects($this->any())->method('create')->will($this->returnValue($transactionMock));
+ $transactionMock = $this->createMock(Transaction::class);
+ $this->transFactoryMock->method('create')
+ ->willReturn($transactionMock);
- $this->_settingsChecker->expects($this->any())->method('isReadOnly')->will($this->returnValue(true));
- $this->_configLoaderMock->expects($this->any())->method('getConfigByPath')->will($this->returnValue([]));
+ $this->settingsChecker->method('isReadOnly')
+ ->willReturn(true);
+ $this->configLoaderMock->method('getConfigByPath')
+ ->willReturn([]);
- $this->_model->setGroups(['1' => ['fields' => ['key' => ['data']]]]);
- $this->_model->setSection('section');
+ $this->model->setGroups(['1' => ['fields' => ['key' => ['data']]]]);
+ $this->model->setSection('section');
- $group = $this->createMock(\Magento\Config\Model\Config\Structure\Element\Group::class);
- $group->method('getPath')->willReturn('section/1');
+ $group = $this->createMock(Group::class);
+ $group->method('getPath')
+ ->willReturn('section/1');
- $field = $this->createMock(\Magento\Config\Model\Config\Structure\Element\Field::class);
- $field->method('getGroupPath')->willReturn('section/1');
- $field->method('getId')->willReturn('key');
+ $field = $this->createMock(Field::class);
+ $field->method('getGroupPath')
+ ->willReturn('section/1');
+ $field->method('getId')
+ ->willReturn('key');
- $this->_configStructure->expects($this->at(0))
+ $this->configStructure->expects($this->at(0))
->method('getElement')
->with('section/1')
- ->will($this->returnValue($group));
- $this->_configStructure->expects($this->at(1))
+ ->willReturn($group);
+ $this->configStructure->expects($this->at(1))
->method('getElement')
->with('section/1')
- ->will($this->returnValue($group));
- $this->_configStructure->expects($this->at(2))
+ ->willReturn($group);
+ $this->configStructure->expects($this->at(2))
->method('getElement')
->with('section/1/key')
- ->will($this->returnValue($field));
+ ->willReturn($field);
$backendModel = $this->createPartialMock(
- \Magento\Framework\App\Config\Value::class,
+ Value::class,
['addData']
);
- $this->_dataFactoryMock->expects($this->any())->method('create')->will($this->returnValue($backendModel));
+ $this->dataFactoryMock->method('create')
+ ->willReturn($backendModel);
- $this->_transFactoryMock->expects($this->never())->method('addObject');
- $backendModel->expects($this->never())->method('addData');
+ $this->transFactoryMock->expects($this->never())
+ ->method('addObject');
+ $backendModel->expects($this->never())
+ ->method('addData');
- $this->_model->save();
+ $this->model->save();
}
public function testSaveToCheckScopeDataSet()
{
- $transactionMock = $this->createMock(\Magento\Framework\DB\Transaction::class);
- $this->_transFactoryMock->expects($this->any())->method('create')->will($this->returnValue($transactionMock));
+ $transactionMock = $this->createMock(Transaction::class);
+ $this->transFactoryMock->method('create')
+ ->willReturn($transactionMock);
- $this->_configLoaderMock->expects($this->any())->method('getConfigByPath')->will($this->returnValue([]));
+ $this->configLoaderMock->method('getConfigByPath')
+ ->willReturn([]);
- $this->_eventManagerMock->expects($this->at(0))
+ $this->eventManagerMock->expects($this->at(0))
->method('dispatch')
->with(
$this->equalTo('admin_system_config_changed_section_section'),
$this->arrayHasKey('website')
);
- $this->_eventManagerMock->expects($this->at(0))
+ $this->eventManagerMock->expects($this->at(0))
->method('dispatch')
->with(
$this->equalTo('admin_system_config_changed_section_section'),
$this->arrayHasKey('store')
);
- $group = $this->createMock(\Magento\Config\Model\Config\Structure\Element\Group::class);
+ $group = $this->createMock(Group::class);
$group->method('getPath')->willReturn('section/1');
- $field = $this->createMock(\Magento\Config\Model\Config\Structure\Element\Field::class);
+ $field = $this->createMock(Field::class);
$field->method('getGroupPath')->willReturn('section/1');
$field->method('getId')->willReturn('key');
- $this->_configStructure->expects($this->at(0))
+ $this->configStructure->expects($this->at(0))
->method('getElement')
->with('section/1')
- ->will($this->returnValue($group));
- $this->_configStructure->expects($this->at(1))
+ ->willReturn($group);
+ $this->configStructure->expects($this->at(1))
->method('getElement')
->with('section/1')
- ->will($this->returnValue($group));
- $this->_configStructure->expects($this->at(2))
+ ->willReturn($group);
+ $this->configStructure->expects($this->at(2))
->method('getElement')
->with('section/1/key')
- ->will($this->returnValue($field));
- $this->_configStructure->expects($this->at(3))
+ ->willReturn($field);
+ $this->configStructure->expects($this->at(3))
->method('getElement')
->with('section/1')
- ->will($this->returnValue($group));
- $this->_configStructure->expects($this->at(4))
+ ->willReturn($group);
+ $this->configStructure->expects($this->at(4))
->method('getElement')
->with('section/1/key')
- ->will($this->returnValue($field));
-
- $website = $this->createMock(\Magento\Store\Model\Website::class);
- $website->expects($this->any())->method('getCode')->will($this->returnValue('website_code'));
- $this->_storeManager->expects($this->any())->method('getWebsite')->will($this->returnValue($website));
- $this->_storeManager->expects($this->any())->method('getWebsites')->will($this->returnValue([$website]));
- $this->_storeManager->expects($this->any())->method('isSingleStoreMode')->will($this->returnValue(true));
-
- $this->_model->setWebsite('website');
- $this->_model->setSection('section');
- $this->_model->setGroups(['1' => ['fields' => ['key' => ['data']]]]);
+ ->willReturn($field);
+
+ $this->scopeResolver->method('getScope')
+ ->with('1')
+ ->willReturn($this->scope);
+ $this->scope->expects($this->atLeastOnce())
+ ->method('getScopeType')
+ ->willReturn('website');
+ $this->scope->expects($this->atLeastOnce())
+ ->method('getId')
+ ->willReturn(1);
+ $this->scope->expects($this->atLeastOnce())
+ ->method('getCode')
+ ->willReturn('website_code');
+ $this->scopeTypeNormalizer->expects($this->atLeastOnce())
+ ->method('normalize')
+ ->with('website')
+ ->willReturn('websites');
+ $website = $this->createMock(Website::class);
+ $this->storeManager->method('getWebsites')->willReturn([$website]);
+ $this->storeManager->method('isSingleStoreMode')->willReturn(true);
+
+ $this->model->setWebsite('1');
+ $this->model->setSection('section');
+ $this->model->setGroups(['1' => ['fields' => ['key' => ['data']]]]);
$backendModel = $this->createPartialMock(
- \Magento\Framework\App\Config\Value::class,
+ Value::class,
['setPath', 'addData', '__sleep', '__wakeup']
);
- $backendModel->expects($this->once())
- ->method('addData')
+ $backendModel->method('addData')
->with([
'field' => 'key',
'groups' => [1 => ['fields' => ['key' => ['data']]]],
'group_id' => null,
'scope' => 'websites',
- 'scope_id' => 0,
+ 'scope_id' => 1,
'scope_code' => 'website_code',
'field_config' => null,
'fieldset_data' => ['key' => null],
@@ -278,18 +347,19 @@ public function testSaveToCheckScopeDataSet()
$backendModel->expects($this->once())
->method('setPath')
->with('section/1/key')
- ->will($this->returnValue($backendModel));
+ ->willReturn($backendModel);
- $this->_dataFactoryMock->expects($this->any())->method('create')->will($this->returnValue($backendModel));
+ $this->dataFactoryMock->method('create')
+ ->willReturn($backendModel);
- $this->_model->save();
+ $this->model->save();
}
public function testSetDataByPath()
{
$value = 'value';
$path = '//';
- $this->_model->setDataByPath($path, $value);
+ $this->model->setDataByPath($path, $value);
$expected = [
'section' => '',
'groups' => [
@@ -300,7 +370,7 @@ public function testSetDataByPath()
],
],
];
- $this->assertSame($expected, $this->_model->getData());
+ $this->assertSame($expected, $this->model->getData());
}
/**
@@ -309,7 +379,7 @@ public function testSetDataByPath()
*/
public function testSetDataByPathEmpty()
{
- $this->_model->setDataByPath('', 'value');
+ $this->model->setDataByPath('', 'value');
}
/**
@@ -324,7 +394,7 @@ public function testSetDataByPathWrongDepth($path, $expectedException)
$this->expectException('\UnexpectedValueException');
$this->expectExceptionMessage($expectedException);
$value = 'value';
- $this->_model->setDataByPath($path, $value);
+ $this->model->setDataByPath($path, $value);
}
/**
diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
index 6357bbd6c7c0c..1df84d27a5c30 100644
--- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
+++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
@@ -376,7 +376,8 @@ define([
basePrice = parseFloat(this.options.spConfig.prices.basePrice.amount),
optionFinalPrice,
optionPriceDiff,
- optionPrices = this.options.spConfig.optionPrices;
+ optionPrices = this.options.spConfig.optionPrices,
+ allowedProductMinPrice;
this._clearSelect(element);
element.options[0] = new Option('', '');
@@ -407,8 +408,8 @@ define([
if (typeof allowedProducts[0] !== 'undefined' &&
typeof optionPrices[allowedProducts[0]] !== 'undefined') {
-
- optionFinalPrice = parseFloat(optionPrices[allowedProducts[0]].finalPrice.amount);
+ allowedProductMinPrice = this._getAllowedProductWithMinPrice(allowedProducts);
+ optionFinalPrice = parseFloat(optionPrices[allowedProductMinPrice].finalPrice.amount);
optionPriceDiff = optionFinalPrice - basePrice;
if (optionPriceDiff !== 0) {
@@ -489,36 +490,27 @@ define([
_getPrices: function () {
var prices = {},
elements = _.toArray(this.options.settings),
- hasProductPrice = false,
- optionPriceDiff = 0,
- allowedProduct, optionPrices, basePrice, optionFinalPrice;
+ allowedProduct;
_.each(elements, function (element) {
var selected = element.options[element.selectedIndex],
config = selected && selected.config,
priceValue = {};
- if (config && config.allowedProducts.length === 1 && !hasProductPrice) {
- prices = {};
+ if (config && config.allowedProducts.length === 1) {
priceValue = this._calculatePrice(config);
- hasProductPrice = true;
} else if (element.value) {
allowedProduct = this._getAllowedProductWithMinPrice(config.allowedProducts);
- optionPrices = this.options.spConfig.optionPrices;
- basePrice = parseFloat(this.options.spConfig.prices.basePrice.amount);
-
- if (!_.isEmpty(allowedProduct)) {
- optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount);
- optionPriceDiff = optionFinalPrice - basePrice;
- }
-
- if (optionPriceDiff !== 0) {
- prices = {};
- priceValue = this._calculatePriceDifference(allowedProduct);
- }
+ priceValue = this._calculatePrice({
+ 'allowedProducts': [
+ allowedProduct
+ ]
+ });
}
- prices[element.attributeId] = priceValue;
+ if (!_.isEmpty(priceValue)) {
+ prices.prices = priceValue;
+ }
}, this);
return prices;
@@ -539,40 +531,15 @@ define([
_.each(allowedProducts, function (allowedProduct) {
optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount);
- if (_.isEmpty(product)) {
+ if (_.isEmpty(product) || optionFinalPrice < optionMinPrice) {
optionMinPrice = optionFinalPrice;
product = allowedProduct;
}
-
- if (optionFinalPrice < optionMinPrice) {
- product = allowedProduct;
- }
}, this);
return product;
},
- /**
- * Calculate price difference for allowed product
- *
- * @param {*} allowedProduct - Product
- * @returns {*}
- * @private
- */
- _calculatePriceDifference: function (allowedProduct) {
- var displayPrices = $(this.options.priceHolderSelector).priceBox('option').prices,
- newPrices = this.options.spConfig.optionPrices[allowedProduct];
-
- _.each(displayPrices, function (price, code) {
-
- if (newPrices[code]) {
- displayPrices[code].amount = newPrices[code].amount - displayPrices[code].amount;
- }
- });
-
- return displayPrices;
- },
-
/**
* Returns prices for configured products
*
diff --git a/app/code/Magento/Paypal/Model/Config/Structure/Element/FieldPlugin.php b/app/code/Magento/Paypal/Model/Config/Structure/Element/FieldPlugin.php
index c2056aea08c00..5d5db0128b1eb 100644
--- a/app/code/Magento/Paypal/Model/Config/Structure/Element/FieldPlugin.php
+++ b/app/code/Magento/Paypal/Model/Config/Structure/Element/FieldPlugin.php
@@ -5,7 +5,6 @@
*/
namespace Magento\Paypal\Model\Config\Structure\Element;
-use Magento\Framework\App\RequestInterface;
use Magento\Config\Model\Config\Structure\Element\Field as FieldConfigStructure;
use Magento\Paypal\Model\Config\StructurePlugin as ConfigStructurePlugin;
@@ -14,19 +13,6 @@
*/
class FieldPlugin
{
- /**
- * @var RequestInterface
- */
- private $request;
-
- /**
- * @param RequestInterface $request
- */
- public function __construct(RequestInterface $request)
- {
- $this->request = $request;
- }
-
/**
* Get original configPath (not changed by PayPal configuration inheritance)
*
@@ -36,7 +22,7 @@ public function __construct(RequestInterface $request)
*/
public function afterGetConfigPath(FieldConfigStructure $subject, $result)
{
- if (!$result && $this->request->getParam('section') == 'payment') {
+ if (!$result && strpos($subject->getPath(), 'payment_') === 0) {
$result = preg_replace(
'@^(' . implode('|', ConfigStructurePlugin::getPaypalConfigCountries(true)) . ')/@',
'payment/',
diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php b/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php
index 8615b91383aaa..72c13c80b31e4 100644
--- a/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php
+++ b/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php
@@ -7,7 +7,6 @@
use Magento\Paypal\Model\Config\Structure\Element\FieldPlugin as FieldConfigStructurePlugin;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
-use Magento\Framework\App\RequestInterface;
use Magento\Config\Model\Config\Structure\Element\Field as FieldConfigStructureMock;
class FieldPluginTest extends \PHPUnit\Framework\TestCase
@@ -22,11 +21,6 @@ class FieldPluginTest extends \PHPUnit\Framework\TestCase
*/
private $objectManagerHelper;
- /**
- * @var RequestInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- private $requestMock;
-
/**
* @var FieldConfigStructureMock|\PHPUnit_Framework_MockObject_MockObject
*/
@@ -34,16 +28,13 @@ class FieldPluginTest extends \PHPUnit\Framework\TestCase
protected function setUp()
{
- $this->requestMock = $this->getMockBuilder(RequestInterface::class)
- ->getMockForAbstractClass();
$this->subjectMock = $this->getMockBuilder(FieldConfigStructureMock::class)
->disableOriginalConstructor()
->getMock();
$this->objectManagerHelper = new ObjectManagerHelper($this);
$this->plugin = $this->objectManagerHelper->getObject(
- FieldConfigStructurePlugin::class,
- ['request' => $this->requestMock]
+ FieldConfigStructurePlugin::class
);
}
@@ -56,10 +47,8 @@ public function testAroundGetConfigPathHasResult()
public function testAroundGetConfigPathNonPaymentSection()
{
- $this->requestMock->expects(static::once())
- ->method('getParam')
- ->with('section')
- ->willReturn('non-payment');
+ $this->subjectMock->method('getPath')
+ ->willReturn('non-payment/group/field');
$this->assertNull($this->plugin->afterGetConfigPath($this->subjectMock, null));
}
@@ -72,12 +61,7 @@ public function testAroundGetConfigPathNonPaymentSection()
*/
public function testAroundGetConfigPath($subjectPath, $expectedConfigPath)
{
- $this->requestMock->expects(static::once())
- ->method('getParam')
- ->with('section')
- ->willReturn('payment');
- $this->subjectMock->expects(static::once())
- ->method('getPath')
+ $this->subjectMock->method('getPath')
->willReturn($subjectPath);
$this->assertEquals($expectedConfigPath, $this->plugin->afterGetConfigPath($this->subjectMock, null));
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php
index 0f92fa2320e89..b61a5cf83734b 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Account.php
@@ -11,6 +11,7 @@
use Magento\Framework\Api\ExtensibleDataObjectConverter;
use Magento\Framework\Data\Form\Element\AbstractElement;
use Magento\Framework\Pricing\PriceCurrencyInterface;
+use Magento\Store\Model\ScopeInterface;
/**
* Create order account form
@@ -134,15 +135,8 @@ protected function _prepareForm()
$this->_addAttributesToForm($attributes, $fieldset);
$this->_form->addFieldNameSuffix('order[account]');
-
- $formValues = $this->getFormValues();
- foreach ($attributes as $code => $attribute) {
- $defaultValue = $attribute->getDefaultValue();
- if (isset($defaultValue) && !isset($formValues[$code])) {
- $formValues[$code] = $defaultValue;
- }
- }
- $this->_form->setValues($formValues);
+ $storeId = (int)$this->_sessionQuote->getStoreId();
+ $this->_form->setValues($this->extractValuesFromAttributes($attributes, $storeId));
return $this;
}
@@ -189,4 +183,42 @@ public function getFormValues()
return $data;
}
+
+ /**
+ * Extract the form values from attributes.
+ *
+ * @param array $attributes
+ * @param int $storeId
+ * @return array
+ */
+ private function extractValuesFromAttributes(array $attributes, int $storeId): array
+ {
+ $formValues = $this->getFormValues();
+ foreach ($attributes as $code => $attribute) {
+ $defaultValue = $attribute->getDefaultValue();
+ if (isset($defaultValue) && !isset($formValues[$code])) {
+ $formValues[$code] = $defaultValue;
+ }
+ if ($code === 'group_id' && empty($defaultValue)) {
+ $formValues[$code] = $this->getDefaultCustomerGroup($storeId);
+ }
+ }
+
+ return $formValues;
+ }
+
+ /**
+ * Gets default customer group.
+ *
+ * @param int $storeId
+ * @return string|null
+ */
+ private function getDefaultCustomerGroup(int $storeId)
+ {
+ return $this->_scopeConfig->getValue(
+ 'customer/create_account/default_group',
+ ScopeInterface::SCOPE_STORE,
+ $storeId
+ );
+ }
}
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Sidebar/Cart.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Sidebar/Cart.php
index 34d7a3f8ee25e..8179c0e8d282a 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Sidebar/Cart.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Sidebar/Cart.php
@@ -3,8 +3,13 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Sales\Block\Adminhtml\Order\Create\Sidebar;
+use Magento\Catalog\Model\Product;
+use Magento\Catalog\Pricing\Price\FinalPrice;
+
/**
* Adminhtml sales order create sidebar cart block
*
@@ -58,6 +63,17 @@ public function getItemCollection()
return $collection;
}
+ /**
+ * @inheritdoc
+ */
+ public function getItemPrice(Product $product)
+ {
+ $customPrice = $this->getCartItemCustomPrice($product);
+ $price = $customPrice ?? $product->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getValue();
+
+ return $this->convertPrice($price);
+ }
+
/**
* Retrieve display item qty availability
*
@@ -111,4 +127,23 @@ protected function _prepareLayout()
return parent::_prepareLayout();
}
+
+ /**
+ * Returns cart item custom price.
+ *
+ * @param Product $product
+ * @return float|null
+ */
+ private function getCartItemCustomPrice(Product $product)
+ {
+ $items = $this->getItemCollection();
+ foreach ($items as $item) {
+ $productItemId = $this->getProduct($item)->getId();
+ if ($productItemId === $product->getId() && $item->getCustomPrice()) {
+ return (float)$item->getCustomPrice();
+ }
+ }
+
+ return null;
+ }
}
diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml
index 3d740bfee2093..83f891d06647d 100644
--- a/app/code/Magento/Store/etc/di.xml
+++ b/app/code/Magento/Store/etc/di.xml
@@ -232,6 +232,7 @@
+ - Magento\Framework\App\ScopeResolver
- Magento\Store\Model\Resolver\Store
- Magento\Store\Model\Resolver\Store
- Magento\Store\Model\Resolver\Group
diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
index 4b8a96f57e53e..1145d3acc11ed 100644
--- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
+++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
@@ -1030,14 +1030,10 @@ define([
_.each(allowedProducts, function (allowedProduct) {
optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount);
- if (_.isEmpty(product)) {
+ if (_.isEmpty(product) || optionFinalPrice < optionMinPrice) {
optionMinPrice = optionFinalPrice;
product = allowedProduct;
}
-
- if (optionFinalPrice < optionMinPrice) {
- product = allowedProduct;
- }
}, this);
return product;
diff --git a/app/etc/di.xml b/app/etc/di.xml
index ad77ae3adc566..05fd34a178ded 100755
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -1356,4 +1356,11 @@
Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT
+
+
+
+ - Magento\Framework\App\ScopeResolver
+
+
+
diff --git a/dev/tests/integration/testsuite/Magento/Config/Console/Command/ConfigSetCommandTest.php b/dev/tests/integration/testsuite/Magento/Config/Console/Command/ConfigSetCommandTest.php
index 3f333a36c9c93..a1998c6c89536 100644
--- a/dev/tests/integration/testsuite/Magento/Config/Console/Command/ConfigSetCommandTest.php
+++ b/dev/tests/integration/testsuite/Magento/Config/Console/Command/ConfigSetCommandTest.php
@@ -27,7 +27,7 @@
/**
* Tests the different flows of config:set command.
*
- * {@inheritdoc}
+ * @inheritdoc
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @magentoDbIsolation enabled
*/
@@ -291,8 +291,7 @@ public function runExtendedDataProvider()
* @param string $scope
* @param $scopeCode string|null
* @dataProvider configSetValidationErrorDataProvider
- *
- * @magentoDbIsolation enabled
+ * @magentoDbIsolation disabled
*/
public function testConfigSetValidationError(
$path,
@@ -306,6 +305,7 @@ public function testConfigSetValidationError(
/**
* Data provider for testConfigSetValidationError
+ *
* @return array
*/
public function configSetValidationErrorDataProvider()
@@ -398,7 +398,6 @@ public function testConfigSetCurrency()
* Saving values with successful validation
*
* @dataProvider configSetValidDataProvider
- *
* @magentoDbIsolation enabled
*/
public function testConfigSetValid()
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AccountTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AccountTest.php
index 999522a49e006..ce3f3a3e1fc8e 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AccountTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AccountTest.php
@@ -11,26 +11,37 @@
namespace Magento\Sales\Block\Adminhtml\Order\Create\Form;
use Magento\Backend\Model\Session\Quote as SessionQuote;
+use Magento\Customer\Api\Data\AttributeMetadataInterface;
use Magento\Customer\Api\Data\AttributeMetadataInterfaceFactory;
+use Magento\Customer\Model\Data\Option;
use Magento\Customer\Model\Metadata\Form;
use Magento\Customer\Model\Metadata\FormFactory;
use Magento\Framework\View\LayoutInterface;
use Magento\Quote\Model\Quote;
use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\ObjectManager;
+use PHPUnit\Framework\MockObject\MockObject;
/**
* @magentoAppArea adminhtml
*/
class AccountTest extends \PHPUnit\Framework\TestCase
{
- /** @var Account */
+ /**
+ * @var Account
+ */
private $accountBlock;
/**
- * @var Bootstrap
+ * @var ObjectManager
*/
private $objectManager;
+ /**
+ * @var SessionQuote|MockObject
+ */
+ private $session;
+
/**
* @magentoDataFixture Magento/Sales/_files/quote.php
*/
@@ -38,19 +49,23 @@ protected function setUp()
{
$this->objectManager = Bootstrap::getObjectManager();
$quote = $this->objectManager->create(Quote::class)->load(1);
- $sessionQuoteMock = $this->getMockBuilder(
- SessionQuote::class
- )->disableOriginalConstructor()->setMethods(
- ['getCustomerId', 'getStore', 'getStoreId', 'getQuote']
- )->getMock();
- $sessionQuoteMock->expects($this->any())->method('getCustomerId')->will($this->returnValue(1));
- $sessionQuoteMock->expects($this->any())->method('getQuote')->will($this->returnValue($quote));
+
+ $this->session = $this->getMockBuilder(SessionQuote::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getCustomerId', 'getStore', 'getStoreId', 'getQuote', 'getQuoteId'])
+ ->getMock();
+ $this->session->method('getCustomerId')
+ ->willReturn(1);
+ $this->session->method('getQuote')
+ ->willReturn($quote);
+ $this->session->method('getQuoteId')
+ ->willReturn($quote->getId());
/** @var LayoutInterface $layout */
$layout = $this->objectManager->get(LayoutInterface::class);
$this->accountBlock = $layout->createBlock(
Account::class,
'address_block' . rand(),
- ['sessionQuote' => $sessionQuoteMock]
+ ['sessionQuote' => $this->session]
);
parent::setUp();
}
@@ -62,13 +77,13 @@ public function testGetForm()
{
$expectedFields = ['group_id', 'email'];
$form = $this->accountBlock->getForm();
- $this->assertEquals(1, $form->getElements()->count(), "Form has invalid number of fieldsets");
+ self::assertEquals(1, $form->getElements()->count(), "Form has invalid number of fieldsets");
$fieldset = $form->getElements()[0];
- $this->assertEquals(count($expectedFields), $fieldset->getElements()->count());
+ self::assertEquals(count($expectedFields), $fieldset->getElements()->count());
foreach ($fieldset->getElements() as $element) {
- $this->assertTrue(
+ self::assertTrue(
in_array($element->getId(), $expectedFields),
sprintf('Unexpected field "%s" in form.', $element->getId())
);
@@ -79,6 +94,7 @@ public function testGetForm()
* Tests a case when user defined custom attribute has default value.
*
* @magentoDataFixture Magento/Customer/_files/customer.php
+ * @magentoConfigFixture current_store customer/create_account/default_group 3
*/
public function testGetFormWithUserDefinedAttribute()
{
@@ -91,18 +107,27 @@ public function testGetFormWithUserDefinedAttribute()
$form = $accountBlock->getForm();
$form->setUseContainer(true);
+ $content = $form->toHtml();
- $this->assertContains(
+ self::assertContains(
'',
- $form->toHtml(),
- 'Default value for user defined custom attribute should be selected'
+ $content,
+ 'Default value for user defined custom attribute should be selected.'
+ );
+
+ self::assertContains(
+ '',
+ $content,
+ 'The Customer Group specified for the chosen store should be selected.'
);
}
/**
- * @return \PHPUnit_Framework_MockObject_MockObject
+ * Creates a mock for Form object.
+ *
+ * @return MockObject
*/
- private function getFormFactoryMock(): \PHPUnit_Framework_MockObject_MockObject
+ private function getFormFactoryMock()
{
/** @var AttributeMetadataInterfaceFactory $attributeMetadataFactory */
$attributeMetadataFactory = $this->objectManager->create(AttributeMetadataInterfaceFactory::class);
@@ -113,11 +138,12 @@ private function getFormFactoryMock(): \PHPUnit_Framework_MockObject_MockObject
->setDefaultValue('1')
->setFrontendLabel('Yes/No');
+ /** @var Form|MockObject $form */
$form = $this->getMockBuilder(Form::class)
->disableOriginalConstructor()
->getMock();
$form->method('getUserAttributes')->willReturn([$booleanAttribute]);
- $form->method('getSystemAttributes')->willReturn([]);
+ $form->method('getSystemAttributes')->willReturn([$this->createCustomerGroupAttribute()]);
$formFactory = $this->getMockBuilder(FormFactory::class)
->disableOriginalConstructor()
@@ -126,4 +152,33 @@ private function getFormFactoryMock(): \PHPUnit_Framework_MockObject_MockObject
return $formFactory;
}
+
+ /**
+ * Creates a customer group attribute object.
+ *
+ * @return AttributeMetadataInterface
+ */
+ private function createCustomerGroupAttribute(): AttributeMetadataInterface
+ {
+ /** @var Option $option1 */
+ $option1 = $this->objectManager->create(Option::class);
+ $option1->setValue(3);
+ $option1->setLabel('Customer Group 1');
+
+ /** @var Option $option2 */
+ $option2 = $this->objectManager->create(Option::class);
+ $option2->setValue(4);
+ $option2->setLabel('Customer Group 2');
+
+ /** @var AttributeMetadataInterfaceFactory $attributeMetadataFactory */
+ $attributeMetadataFactory = $this->objectManager->create(AttributeMetadataInterfaceFactory::class);
+ $attribute = $attributeMetadataFactory->create()
+ ->setAttributeCode('group_id')
+ ->setBackendType('static')
+ ->setFrontendInput('select')
+ ->setOptions([$option1, $option2])
+ ->setIsRequired(true);
+
+ return $attribute;
+ }
}
diff --git a/lib/internal/Magento/Framework/App/ScopeDefault.php b/lib/internal/Magento/Framework/App/ScopeDefault.php
index 2ea62387145bf..e62d19f9ffbb4 100644
--- a/lib/internal/Magento/Framework/App/ScopeDefault.php
+++ b/lib/internal/Magento/Framework/App/ScopeDefault.php
@@ -17,7 +17,7 @@ class ScopeDefault implements ScopeInterface
*/
public function getCode()
{
- return 'default';
+ return '';
}
/**
@@ -27,7 +27,7 @@ public function getCode()
*/
public function getId()
{
- return 1;
+ return 0;
}
/**