Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 11922a1

Browse files
Merge forwardport of magento/magento2#11809 to 2.3-develop branch
Applied pull request patch https://github.com/magento/magento2/pull/11809.patch (created by @nmalevanec) based on commit(s): 1. 38735ac 2. b63ceb9 3. 3e0c785 Fixed GitHub Issues in 2.3-develop branch: - magento/magento2#8003: Using System Value for Base Currency Results in Config Error (reported by @tsmith1985)
2 parents 8b40859 + 6b9c188 commit 11922a1

File tree

5 files changed

+443
-6
lines changed

5 files changed

+443
-6
lines changed

app/code/Magento/Directory/Model/Currency.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Magento\Directory\Model;
88

9+
use Magento\Framework\App\ObjectManager;
910
use Magento\Framework\Exception\InputException;
1011
use Magento\Directory\Model\Currency\Filter;
1112

@@ -65,6 +66,11 @@ class Currency extends \Magento\Framework\Model\AbstractModel
6566
*/
6667
protected $_localeCurrency;
6768

69+
/**
70+
* @var CurrencyConfig
71+
*/
72+
private $currencyConfig;
73+
6874
/**
6975
* @param \Magento\Framework\Model\Context $context
7076
* @param \Magento\Framework\Registry $registry
@@ -76,6 +82,7 @@ class Currency extends \Magento\Framework\Model\AbstractModel
7682
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
7783
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
7884
* @param array $data
85+
* @param CurrencyConfig $currencyConfig
7986
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
8087
*/
8188
public function __construct(
@@ -88,7 +95,8 @@ public function __construct(
8895
\Magento\Framework\Locale\CurrencyInterface $localeCurrency,
8996
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
9097
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
91-
array $data = []
98+
array $data = [],
99+
CurrencyConfig $currencyConfig = null
92100
) {
93101
parent::__construct(
94102
$context,
@@ -102,6 +110,7 @@ public function __construct(
102110
$this->_directoryHelper = $directoryHelper;
103111
$this->_currencyFilterFactory = $currencyFilterFactory;
104112
$this->_localeCurrency = $localeCurrency;
113+
$this->currencyConfig = $currencyConfig ?: ObjectManager::getInstance()->get(CurrencyConfig::class);
105114
}
106115

107116
/**
@@ -347,7 +356,7 @@ public function getOutputFormat()
347356
*/
348357
public function getConfigAllowCurrencies()
349358
{
350-
$allowedCurrencies = $this->_getResource()->getConfigCurrencies($this, self::XML_PATH_CURRENCY_ALLOW);
359+
$allowedCurrencies = $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_ALLOW);
351360
$appBaseCurrencyCode = $this->_directoryHelper->getBaseCurrencyCode();
352361
if (!in_array($appBaseCurrencyCode, $allowedCurrencies)) {
353362
$allowedCurrencies[] = $appBaseCurrencyCode;
@@ -369,17 +378,15 @@ public function getConfigAllowCurrencies()
369378
*/
370379
public function getConfigDefaultCurrencies()
371380
{
372-
$defaultCurrencies = $this->_getResource()->getConfigCurrencies($this, self::XML_PATH_CURRENCY_DEFAULT);
373-
return $defaultCurrencies;
381+
return $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_DEFAULT);
374382
}
375383

376384
/**
377385
* @return array
378386
*/
379387
public function getConfigBaseCurrencies()
380388
{
381-
$defaultCurrencies = $this->_getResource()->getConfigCurrencies($this, self::XML_PATH_CURRENCY_BASE);
382-
return $defaultCurrencies;
389+
return $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_BASE);
383390
}
384391

385392
/**
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Directory\Model;
8+
9+
use Magento\Framework\App\Area;
10+
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
use Magento\Framework\App\State;
12+
use Magento\Store\Model\ScopeInterface;
13+
use Magento\Store\Model\StoreManagerInterface;
14+
15+
/**
16+
* Provide config values for allowed, base and default currencies.
17+
*/
18+
class CurrencyConfig
19+
{
20+
/**
21+
* @var State
22+
*/
23+
private $appState;
24+
25+
/**
26+
* @var ScopeConfigInterface
27+
*/
28+
private $config;
29+
30+
/**
31+
* @var StoreManagerInterface
32+
*/
33+
private $storeManager;
34+
35+
/**
36+
* CurrencyConfig constructor.
37+
*
38+
* @param State $appState
39+
* @param ScopeConfigInterface $config
40+
* @param StoreManagerInterface $storeManager
41+
*/
42+
public function __construct(
43+
State $appState,
44+
ScopeConfigInterface $config,
45+
StoreManagerInterface $storeManager
46+
) {
47+
$this->appState = $appState;
48+
$this->config = $config;
49+
$this->storeManager = $storeManager;
50+
}
51+
52+
/**
53+
* Retrieve config currency data by config path.
54+
*
55+
* @param string $path
56+
* @return array
57+
*/
58+
public function getConfigCurrencies(string $path)
59+
{
60+
$result = $this->appState->getAreaCode() === Area::AREA_ADMINHTML
61+
? $this->getConfigForAllStores($path)
62+
: $this->getConfigForCurrentStore($path);
63+
sort($result);
64+
65+
return array_unique($result);
66+
}
67+
68+
/**
69+
* Get allowed, base and default currency codes for all stores.
70+
*
71+
* @param string $path
72+
* @return array
73+
*/
74+
private function getConfigForAllStores(string $path)
75+
{
76+
$storesResult = [[]];
77+
foreach ($this->storeManager->getStores() as $store) {
78+
$storesResult[] = explode(
79+
',',
80+
$this->config->getValue($path, ScopeInterface::SCOPE_STORE, $store->getCode())
81+
);
82+
}
83+
84+
return array_merge(...$storesResult);
85+
}
86+
87+
/**
88+
* Get allowed, base and default currency codes for current store.
89+
*
90+
* @param string $path
91+
* @return mixed
92+
*/
93+
private function getConfigForCurrentStore(string $path)
94+
{
95+
$store = $this->storeManager->getStore();
96+
97+
return explode(',', $this->config->getValue($path, ScopeInterface::SCOPE_STORE, $store->getCode()));
98+
}
99+
}

app/code/Magento/Directory/Model/ResourceModel/Currency.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ public function saveRates($rates)
165165
* @param string $path
166166
* @return array
167167
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
168+
* @deprecated because doesn't take into consideration scopes and system config values.
169+
* @see \Magento\Directory\Model\CurrencyConfig::getConfigCurrencies()
168170
*/
169171
public function getConfigCurrencies($model, $path)
170172
{
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Directory\Test\Unit\Model;
8+
9+
use Magento\Config\App\Config\Type\System;
10+
use Magento\Directory\Model\CurrencyConfig;
11+
use Magento\Framework\App\Area;
12+
use Magento\Framework\App\Config\ScopeConfigInterface;
13+
use Magento\Framework\App\State;
14+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
15+
use Magento\Store\Api\Data\StoreInterface;
16+
use Magento\Store\Model\StoreManagerInterface;
17+
use PHPUnit\Framework\TestCase;
18+
19+
/**
20+
* Provide tests for CurrencyConfig model.
21+
*/
22+
class CurrencyConfigTest extends TestCase
23+
{
24+
/**
25+
* @var CurrencyConfig
26+
*/
27+
private $testSubject;
28+
29+
/**
30+
* @var System|\PHPUnit_Framework_MockObject_MockObject
31+
*/
32+
private $config;
33+
34+
/**
35+
* @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
36+
*/
37+
private $storeManager;
38+
39+
/**
40+
* @var State|\PHPUnit_Framework_MockObject_MockObject
41+
*/
42+
private $appState;
43+
44+
/**
45+
* @inheritdoc
46+
*/
47+
protected function setUp()
48+
{
49+
$this->config = $this->getMockBuilder(ScopeConfigInterface::class)
50+
->disableOriginalConstructor()
51+
->getMock();
52+
$this->storeManager = $this->getMockBuilder(StoreManagerInterface::class)
53+
->setMethods(['getStores', 'getWebsites'])
54+
->disableOriginalConstructor()
55+
->getMockForAbstractClass();
56+
$this->appState = $this->getMockBuilder(State::class)
57+
->disableOriginalConstructor()
58+
->getMock();
59+
$objectManager = new ObjectManager($this);
60+
$this->testSubject = $objectManager->getObject(
61+
CurrencyConfig::class,
62+
[
63+
'storeManager' => $this->storeManager,
64+
'appState' => $this->appState,
65+
'config' => $this->config,
66+
]
67+
);
68+
}
69+
70+
/**
71+
* Test get currency config for admin and storefront areas.
72+
*
73+
* @dataProvider getConfigCurrenciesDataProvider
74+
* @return void
75+
*/
76+
public function testGetConfigCurrencies(string $areCode)
77+
{
78+
$path = 'test/path';
79+
$expected = ['ARS', 'AUD', 'BZD'];
80+
81+
$this->appState->expects(self::once())
82+
->method('getAreaCode')
83+
->willReturn($areCode);
84+
85+
/** @var StoreInterface|\PHPUnit_Framework_MockObject_MockObject $store */
86+
$store = $this->getMockBuilder(StoreInterface::class)
87+
->setMethods(['getCode'])
88+
->disableOriginalConstructor()
89+
->getMockForAbstractClass();
90+
$store->expects(self::once())
91+
->method('getCode')
92+
->willReturn('testCode');
93+
94+
if ($areCode === Area::AREA_ADMINHTML) {
95+
$this->storeManager->expects(self::once())
96+
->method('getStores')
97+
->willReturn([$store]);
98+
} else {
99+
$this->storeManager->expects(self::once())
100+
->method('getStore')
101+
->willReturn($store);
102+
}
103+
104+
$this->config->expects(self::once())
105+
->method('getValue')
106+
->with(
107+
self::identicalTo($path)
108+
)->willReturn('ARS,AUD,BZD');
109+
110+
$result = $this->testSubject->getConfigCurrencies($path);
111+
112+
self::assertEquals($expected, $result);
113+
}
114+
115+
/**
116+
* Provide test data for getConfigCurrencies test.
117+
*
118+
* @return array
119+
*/
120+
public function getConfigCurrenciesDataProvider()
121+
{
122+
return [
123+
['areaCode' => Area::AREA_ADMINHTML],
124+
['areaCode' => Area::AREA_FRONTEND],
125+
];
126+
}
127+
}

0 commit comments

Comments
 (0)