Skip to content

Commit 7e9bfb1

Browse files
authored
Merge branch '2.4-develop' into patch-14
2 parents 50a4cf6 + 7b8064f commit 7e9bfb1

File tree

344 files changed

+17487
-4885
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

344 files changed

+17487
-4885
lines changed

.github/app-projects-boards-automation.config.yaml

Lines changed: 402 additions & 0 deletions
Large diffs are not rendered by default.

app/code/Magento/Backend/App/Area/FrontNameResolver.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ public function getFrontName($checkHost = false)
117117
/**
118118
* Return whether the host from request is the backend host
119119
*
120+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
121+
* @SuppressWarnings(PHPMD.NPathComplexity)
122+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
120123
* @return bool
121124
*/
122125
public function isHostBackend()
@@ -128,10 +131,11 @@ public function isHostBackend()
128131
if ($this->scopeConfig->getValue(self::XML_PATH_USE_CUSTOM_ADMIN_URL, ScopeInterface::SCOPE_STORE)) {
129132
$backendUrl = $this->scopeConfig->getValue(self::XML_PATH_CUSTOM_ADMIN_URL, ScopeInterface::SCOPE_STORE);
130133
} else {
131-
$backendUrl = $this->config->getValue(Store::XML_PATH_UNSECURE_BASE_URL);
134+
$xmlPath = $this->request->isSecure() ? Store::XML_PATH_SECURE_BASE_URL : Store::XML_PATH_UNSECURE_BASE_URL;
135+
$backendUrl = $this->config->getValue($xmlPath);
132136
if ($backendUrl === null) {
133137
$backendUrl = $this->scopeConfig->getValue(
134-
Store::XML_PATH_UNSECURE_BASE_URL,
138+
$xmlPath,
135139
ScopeInterface::SCOPE_STORE
136140
);
137141
}

app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2014 Adobe
4+
* All Rights Reserved.
55
*/
66

77
namespace Magento\Backend\Block\Widget\Grid\Column\Renderer;
88

9+
use Magento\Framework\Exception\NoSuchEntityException;
10+
911
/**
1012
* Backend grid item renderer currency
1113
*
@@ -82,7 +84,6 @@ public function render(\Magento\Framework\DataObject $row)
8284
{
8385
if ($data = (string)$this->_getValue($row)) {
8486
$currency_code = $this->_getCurrencyCode($row);
85-
$data = (float)$data * $this->_getRate($row);
8687
$sign = (bool)(int)$this->getColumn()->getShowNumberSign() && $data > 0 ? '+' : '';
8788
$data = sprintf("%f", $data);
8889
$data = $this->_localeCurrency->getCurrency($currency_code)->toCurrency($data);
@@ -103,11 +104,28 @@ protected function _getCurrencyCode($row)
103104
return $code;
104105
}
105106
$currency = $this->getColumn()->getCurrency();
106-
107107
if ($currency !== null && $code = $row->getData($currency)) {
108108
return $code;
109109
}
110-
110+
$storeId = $row->getData('store_id');
111+
if ($storeId) {
112+
try {
113+
$store = $this->_storeManager->getStore($storeId);
114+
// Check if the currency is set at the store level
115+
$currencyCode = $store->getCurrentCurrencyCode();
116+
if ($currencyCode) {
117+
return $currencyCode;
118+
}
119+
$website = $store->getWebsite();
120+
// Check if the currency is set at the website level
121+
$currencyCode = $website->getBaseCurrencyCode();
122+
if ($currencyCode) {
123+
return $currencyCode;
124+
}
125+
} catch (NoSuchEntityException $e) {
126+
$this->_logger->warning('Failed to get website currency: ' . $e->getMessage());
127+
}
128+
}
111129
return $this->_currencyLocator->getDefaultCurrency($this->_request);
112130
}
113131

@@ -128,6 +146,17 @@ protected function _getRate($row)
128146
return (float) $rate;
129147
}
130148

149+
$storeId = $row->getData('store_id');
150+
if ($storeId) {
151+
try {
152+
$store = $this->_storeManager->getStore($storeId);
153+
return $store->getBaseCurrency()->getRate($store->getCurrentCurrencyCode());
154+
} catch (NoSuchEntityException $e) {
155+
$this->_logger->warning('Failed to get website currency: ' . $e->getMessage());
156+
}
157+
158+
}
159+
131160
return $this->_defaultBaseCurrency->getRate($this->_getCurrencyCode($row));
132161
}
133162

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
/**
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Backend\Cron;
9+
10+
use Magento\Framework\Lock\Backend\FileLock;
11+
use Magento\Framework\Lock\LockBackendFactory;
12+
use Psr\Log\LoggerInterface;
13+
14+
class CleanLocks
15+
{
16+
/**
17+
* @param LockBackendFactory $lockFactory
18+
* @param LoggerInterface $logger
19+
*/
20+
public function __construct(
21+
private readonly LockBackendFactory $lockFactory,
22+
private readonly LoggerInterface $logger,
23+
) {
24+
}
25+
26+
/**
27+
* Cron job to cleanup old locks
28+
*/
29+
public function execute(): void
30+
{
31+
$locker = $this->lockFactory->create();
32+
33+
if ($locker instanceof FileLock) {
34+
$numberOfLockFilesDeleted = $locker->cleanupOldLocks();
35+
36+
$this->logger->info(sprintf('Deleted %d old lock files', $numberOfLockFilesDeleted));
37+
}
38+
}
39+
}

app/code/Magento/Backend/Test/Unit/App/Area/FrontNameResolverTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ public function testIsHostBackend(
129129
->willReturnMap(
130130
[
131131
[Store::XML_PATH_UNSECURE_BASE_URL, ScopeInterface::SCOPE_STORE, null, $url],
132+
[Store::XML_PATH_SECURE_BASE_URL, ScopeInterface::SCOPE_STORE, null, $url],
132133
[
133134
FrontNameResolver::XML_PATH_USE_CUSTOM_ADMIN_URL,
134135
ScopeInterface::SCOPE_STORE,
@@ -160,7 +161,6 @@ public function testIsHostBackend(
160161
->setHost(parse_url($url, PHP_URL_HOST))
161162
->setPort(parse_url($url, PHP_URL_PORT))
162163
);
163-
164164
$this->assertEquals($expectedValue, $this->model->isHostBackend());
165165
}
166166

Lines changed: 95 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2014 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

88
namespace Magento\Backend\Test\Unit\Block\Widget\Grid\Column\Renderer;
99

10-
use Magento\Backend\Block\Widget\Grid\Column;
11-
use Magento\Backend\Block\Widget\Grid\Column\Renderer\Currency;
1210
use Magento\Directory\Model\Currency\DefaultLocator;
13-
use Magento\Directory\Model\CurrencyFactory;
1411
use Magento\Framework\App\RequestInterface;
15-
use Magento\Framework\Currency\Data\Currency as CurrencyData;
12+
use Magento\Directory\Model\CurrencyFactory;
13+
use Magento\Backend\Block\Widget\Grid\Column;
1614
use Magento\Framework\DataObject;
17-
use Magento\Framework\Locale\CurrencyInterface;
1815
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
16+
use Magento\Backend\Block\Widget\Grid\Column\Renderer\Currency;
17+
use Magento\Framework\Locale\Currency as LocaleCurrency;
18+
use Magento\Directory\Model\Currency as CurrencyData;
19+
use Magento\Store\Model\Store;
1920
use Magento\Store\Model\StoreManagerInterface;
2021
use PHPUnit\Framework\MockObject\MockObject;
2122
use PHPUnit\Framework\TestCase;
@@ -28,114 +29,128 @@ class CurrencyTest extends TestCase
2829
/**
2930
* @var Currency
3031
*/
31-
protected $_blockCurrency;
32+
private $currencyRenderer;
3233

3334
/**
34-
* @var MockObject
35+
* @var ObjectManager
3536
*/
36-
protected $_localeMock;
37+
private $objectManager;
3738

3839
/**
39-
* @var MockObject
40+
* @var Store|MockObject
4041
*/
41-
protected $_curLocatorMock;
42+
private $storeManagerMock;
4243

4344
/**
44-
* @var MockObject
45+
* @var DefaultLocator|MockObject
4546
*/
46-
protected $_columnMock;
47+
private $currencyLocatorMock;
4748

4849
/**
49-
* @var MockObject
50+
* @var CurrencyFactory|MockObject
5051
*/
51-
protected $_storeManagerMock;
52+
private $currencyFactoryMock;
5253

5354
/**
54-
* @var MockObject
55+
* @var LocaleCurrency|MockObject
5556
*/
56-
protected $_requestMock;
57+
private $localeCurrencyMock;
5758

5859
/**
59-
* @var MockObject
60+
* @var RequestInterface|MockObject
6061
*/
61-
protected $_currencyMock;
62+
private $requestMock;
6263

6364
/**
64-
* @var DataObject
65+
* @var Column|MockObject
6566
*/
66-
protected $_row;
67+
private $columnMock;
6768

6869
protected function setUp(): void
6970
{
70-
$this->_storeManagerMock = $this->getMockForAbstractClass(StoreManagerInterface::class);
71-
$this->_localeMock = $this->getMockForAbstractClass(CurrencyInterface::class);
72-
$this->_requestMock = $this->getMockForAbstractClass(RequestInterface::class);
73-
74-
$this->_curLocatorMock = $this->createMock(DefaultLocator::class);
75-
$this->_columnMock = $this->getMockBuilder(Column::class)
76-
->addMethods(['getIndex', 'getCurrency', 'getRateField'])
71+
$this->objectManager = new ObjectManager($this);
72+
$this->storeManagerMock = $this->createMock(StoreManagerInterface::class);
73+
$this->currencyLocatorMock = $this->createMock(DefaultLocator::class);
74+
$this->currencyFactoryMock = $this->createMock(CurrencyFactory::class);
75+
$this->requestMock = $this->createMock(RequestInterface::class);
76+
$defaultCurrencyCode = 'USD';
77+
$currencyMock = $this->createMock(CurrencyData::class);
78+
$this->currencyFactoryMock->method('create')
79+
->willReturn($currencyMock);
80+
$currencyMock->method('load')
81+
->with($defaultCurrencyCode)
82+
->willReturnSelf();
83+
$this->currencyLocatorMock->method('getDefaultCurrency')
84+
->with($this->requestMock)
85+
->willReturn($defaultCurrencyCode);
86+
$this->columnMock = $this->getMockBuilder(Column::class)
87+
->addMethods(['getIndex', 'getShowNumberSign', 'getDefault'])
7788
->disableOriginalConstructor()
7889
->getMock();
79-
$this->_columnMock->expects($this->any())->method('getIndex')->willReturn('columnIndex');
80-
81-
$this->_currencyMock = $this->createMock(\Magento\Directory\Model\Currency::class);
82-
$this->_currencyMock->expects($this->any())->method('load')->willReturnSelf();
83-
$currencyFactoryMock = $this->createPartialMock(CurrencyFactory::class, ['create']);
84-
$currencyFactoryMock->expects($this->any())->method('create')->willReturn($this->_currencyMock);
85-
86-
$this->_row = new DataObject(['columnIndex' => '10']);
87-
88-
$helper = new ObjectManager($this);
89-
$this->_blockCurrency = $helper->getObject(
90+
$this->columnMock->method('getIndex')->willReturn('value');
91+
$this->columnMock->method('getShowNumberSign')->willReturn(false);
92+
$this->columnMock->method('getDefault')->willReturn('');
93+
$this->localeCurrencyMock = $this->getMockBuilder(LocaleCurrency::class)
94+
->onlyMethods(['getCurrency'])
95+
->addMethods(['toCurrency'])
96+
->disableOriginalConstructor()
97+
->getMock();
98+
$this->currencyRenderer = $this->objectManager->getObject(
9099
Currency::class,
91100
[
92-
'storeManager' => $this->_storeManagerMock,
93-
'localeCurrency' => $this->_localeMock,
94-
'currencyLocator' => $this->_curLocatorMock,
95-
'request' => $this->_requestMock,
96-
'currencyFactory' => $currencyFactoryMock
101+
'storeManager' => $this->storeManagerMock,
102+
'localeCurrency' => $this->localeCurrencyMock,
103+
'currencyLocator' => $this->currencyLocatorMock,
104+
'request' => $this->requestMock,
105+
'currencyFactory' => $this->currencyFactoryMock
97106
]
98107
);
99-
100-
$this->_blockCurrency->setColumn($this->_columnMock);
101108
}
102109

103-
protected function tearDown(): void
110+
public function testRenderWithDefaultCurrency()
104111
{
105-
unset($this->_localeMock);
106-
unset($this->_curLocatorMock);
107-
unset($this->_columnMock);
108-
unset($this->_row);
109-
unset($this->_storeManagerMock);
110-
unset($this->_requestMock);
111-
unset($this->_blockCurrency);
112+
$defaultCurrencyCode = 'USD';
113+
$amount = 123.45;
114+
$formattedAmount = '$123.45';
115+
$row = new DataObject(['value' => $amount]);
116+
$this->currencyRenderer->setColumn($this->columnMock);
117+
$this->localeCurrencyMock->method('getCurrency')
118+
->with($defaultCurrencyCode)
119+
->willReturn($this->localeCurrencyMock);
120+
$this->localeCurrencyMock->method('toCurrency')
121+
->with(sprintf("%f", $amount))
122+
->willReturn($formattedAmount);
123+
$result = $this->currencyRenderer->render($row);
124+
$this->assertEquals($formattedAmount, $result);
112125
}
113126

114-
/**
115-
* @covers \Magento\Backend\Block\Widget\Grid\Column\Renderer\Currency::render
116-
*/
117-
public function testRenderWithDefaultCurrency()
127+
public function testRenderWithNonDefaultCurrency()
118128
{
119-
$this->_currencyMock->expects($this->once())
120-
->method('getRate')
121-
->with('defaultCurrency')
122-
->willReturn(1.5);
123-
$this->_curLocatorMock->expects($this->any())
124-
->method('getDefaultCurrency')
125-
->with($this->_requestMock)
126-
->willReturn('defaultCurrency');
127-
$currLocaleMock = $this->createMock(CurrencyData::class);
128-
$currLocaleMock->expects($this->once())
129-
->method('toCurrency')
130-
->with(15.0000)
131-
->willReturn('15USD');
132-
$this->_localeMock->expects($this->once())
133-
->method('getCurrency')
134-
->with('defaultCurrency')
135-
->willReturn($currLocaleMock);
136-
$this->_columnMock->method('getCurrency')->willReturn('USD');
137-
$this->_columnMock->method('getRateField')->willReturn('test_rate_field');
138-
139-
$this->assertEquals('15USD', $this->_blockCurrency->render($this->_row));
129+
$nonDefaultCurrencyCode = 'EUR';
130+
$amount = 123.45;
131+
$formattedAmount = '€123.45';
132+
$storeId = 2;
133+
$row = new DataObject([
134+
'value' => $amount,
135+
'store_id' => $storeId
136+
]);
137+
$this->currencyRenderer->setColumn($this->columnMock);
138+
$storeMock = $this->getMockBuilder(Store::class)
139+
->onlyMethods(['getCurrentCurrencyCode'])
140+
->disableOriginalConstructor()
141+
->getMock();
142+
$this->storeManagerMock->method('getStore')
143+
->with($storeId)
144+
->willReturn($storeMock);
145+
$storeMock->method('getCurrentCurrencyCode')
146+
->willReturn($nonDefaultCurrencyCode);
147+
$this->localeCurrencyMock->method('getCurrency')
148+
->with($nonDefaultCurrencyCode)
149+
->willReturn($this->localeCurrencyMock);
150+
$this->localeCurrencyMock->method('toCurrency')
151+
->with(sprintf("%f", $amount))
152+
->willReturn($formattedAmount);
153+
$result = $this->currencyRenderer->render($row);
154+
$this->assertEquals($formattedAmount, $result);
140155
}
141156
}

0 commit comments

Comments
 (0)