Skip to content

Commit 35d1377

Browse files
🔃 [EngCom] Public Pull Requests - 2.2-develop
Accepted Public Pull Requests: - #12566: Move isAllowed method from AccessChangeQuoteControl to separate service (by @JeroenVanLeusden) - #14829: Add statement to 'beforeSave' method to allow app:config:import (by @bmxmale) - #14699: [2.2] Optimize ID to SKU lookup of tier prices (by @toddbc)
2 parents 00b6f61 + a05392d commit 35d1377

File tree

7 files changed

+138
-49
lines changed

7 files changed

+138
-49
lines changed

app/code/Magento/Braintree/Model/Adminhtml/System/Config/CountryCreditCard.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ public function __construct(
6666
public function beforeSave()
6767
{
6868
$value = $this->getValue();
69+
if (!is_array($value)) {
70+
try {
71+
$value = $this->serializer->unserialize($value);
72+
} catch (\InvalidArgumentException $e) {
73+
$value = [];
74+
}
75+
}
6976
$result = [];
7077
foreach ($value as $data) {
7178
if (empty($data['country_id']) || empty($data['cc_types'])) {

app/code/Magento/Catalog/Model/Product/Price/TierPriceStorage.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,10 @@ private function getExistingPrices(array $skus, $groupBySku = false)
172172
$rawPrices = $this->tierPricePersistence->get($ids);
173173
$prices = [];
174174

175+
$linkField = $this->tierPricePersistence->getEntityLinkField();
176+
$skuByIdLookup = $this->buildSkuByIdLookup($skus);
175177
foreach ($rawPrices as $rawPrice) {
176-
$sku = $this->retrieveSkuById($rawPrice[$this->tierPricePersistence->getEntityLinkField()], $skus);
178+
$sku = $skuByIdLookup[$rawPrice[$linkField]];
177179
$price = $this->tierPriceFactory->create($rawPrice, $sku);
178180
if ($groupBySku) {
179181
$prices[$sku][] = $price;
@@ -300,21 +302,21 @@ private function isCorrectPriceValue(array $existingPrice, array $price)
300302
}
301303

302304
/**
303-
* Retrieve SKU by product ID.
305+
* Generate lookup to retrieve SKU by product ID.
304306
*
305-
* @param int $id
306307
* @param array $skus
307-
* @return string|null
308+
* @return array
308309
*/
309-
private function retrieveSkuById($id, $skus)
310+
private function buildSkuByIdLookup($skus)
310311
{
312+
$lookup = [];
311313
foreach ($this->productIdLocator->retrieveProductIdsBySkus($skus) as $sku => $ids) {
312-
if (isset($ids[$id])) {
313-
return $sku;
314+
foreach (array_keys($ids) as $id) {
315+
$lookup[$id] = $sku;
314316
}
315317
}
316318

317-
return null;
319+
return $lookup;
318320
}
319321

320322
/**
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Quote\Api;
8+
9+
use Magento\Quote\Api\Data\CartInterface;
10+
11+
/**
12+
* Service checks if the user has ability to change the quote.
13+
*/
14+
interface ChangeQuoteControlInterface
15+
{
16+
/**
17+
* Checks if user is allowed to change the quote.
18+
*
19+
* @param CartInterface $quote
20+
* @return bool
21+
*/
22+
public function isAllowed(CartInterface $quote): bool;
23+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Quote\Model;
8+
9+
use Magento\Authorization\Model\UserContextInterface;
10+
use Magento\Quote\Api\ChangeQuoteControlInterface;
11+
use Magento\Quote\Api\Data\CartInterface;
12+
13+
/**
14+
* {@inheritdoc}
15+
*/
16+
class ChangeQuoteControl implements ChangeQuoteControlInterface
17+
{
18+
/**
19+
* @var UserContextInterface $userContext
20+
*/
21+
private $userContext;
22+
23+
/**
24+
* @param UserContextInterface $userContext
25+
*/
26+
public function __construct(UserContextInterface $userContext)
27+
{
28+
$this->userContext = $userContext;
29+
}
30+
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
public function isAllowed(CartInterface $quote): bool
35+
{
36+
switch ($this->userContext->getUserType()) {
37+
case UserContextInterface::USER_TYPE_CUSTOMER:
38+
$isAllowed = ($quote->getCustomerId() == $this->userContext->getUserId());
39+
break;
40+
case UserContextInterface::USER_TYPE_GUEST:
41+
$isAllowed = ($quote->getCustomerId() === null);
42+
break;
43+
case UserContextInterface::USER_TYPE_ADMIN:
44+
case UserContextInterface::USER_TYPE_INTEGRATION:
45+
$isAllowed = true;
46+
break;
47+
default:
48+
$isAllowed = false;
49+
}
50+
51+
return $isAllowed;
52+
}
53+
}

app/code/Magento/Quote/Model/QuoteRepository/Plugin/AccessChangeQuoteControl.php

Lines changed: 10 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\Quote\Model\QuoteRepository\Plugin;
78

8-
use Magento\Authorization\Model\UserContextInterface;
9-
use Magento\Quote\Model\Quote;
9+
use Magento\Quote\Api\ChangeQuoteControlInterface;
1010
use Magento\Framework\Exception\StateException;
1111
use Magento\Quote\Api\CartRepositoryInterface;
1212
use Magento\Quote\Api\Data\CartInterface;
@@ -17,59 +17,32 @@
1717
class AccessChangeQuoteControl
1818
{
1919
/**
20-
* @var UserContextInterface
20+
* @var ChangeQuoteControlInterface $changeQuoteControl
2121
*/
22-
private $userContext;
22+
private $changeQuoteControl;
2323

2424
/**
25-
* @param UserContextInterface $userContext
25+
* @param ChangeQuoteControlInterface $changeQuoteControl
2626
*/
27-
public function __construct(
28-
UserContextInterface $userContext
29-
) {
30-
$this->userContext = $userContext;
27+
public function __construct(ChangeQuoteControlInterface $changeQuoteControl)
28+
{
29+
$this->changeQuoteControl = $changeQuoteControl;
3130
}
3231

3332
/**
3433
* Checks if change quote's customer id is allowed for current user.
3534
*
3635
* @param CartRepositoryInterface $subject
37-
* @param Quote $quote
36+
* @param CartInterface $quote
3837
* @throws StateException if Guest has customer_id or Customer's customer_id not much with user_id
3938
* or unknown user's type
4039
* @return void
4140
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
4241
*/
4342
public function beforeSave(CartRepositoryInterface $subject, CartInterface $quote)
4443
{
45-
if (!$this->isAllowed($quote)) {
44+
if (! $this->changeQuoteControl->isAllowed($quote)) {
4645
throw new StateException(__("Invalid state change requested"));
4746
}
4847
}
49-
50-
/**
51-
* Checks if user is allowed to change the quote.
52-
*
53-
* @param Quote $quote
54-
* @return bool
55-
*/
56-
private function isAllowed(Quote $quote)
57-
{
58-
switch ($this->userContext->getUserType()) {
59-
case UserContextInterface::USER_TYPE_CUSTOMER:
60-
$isAllowed = ($quote->getCustomerId() == $this->userContext->getUserId());
61-
break;
62-
case UserContextInterface::USER_TYPE_GUEST:
63-
$isAllowed = ($quote->getCustomerId() === null);
64-
break;
65-
case UserContextInterface::USER_TYPE_ADMIN:
66-
case UserContextInterface::USER_TYPE_INTEGRATION:
67-
$isAllowed = true;
68-
break;
69-
default:
70-
$isAllowed = false;
71-
}
72-
73-
return $isAllowed;
74-
}
7548
}

app/code/Magento/Quote/Test/Unit/Model/QuoteRepository/Plugin/AccessChangeQuoteControlTest.php

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\Quote\Test\Unit\Model\QuoteRepository\Plugin;
78

89
use Magento\Authorization\Model\UserContextInterface;
10+
use Magento\Quote\Model\ChangeQuoteControl;
911
use Magento\Quote\Model\QuoteRepository\Plugin\AccessChangeQuoteControl;
1012
use Magento\Quote\Model\Quote;
1113
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
@@ -34,6 +36,11 @@ class AccessChangeQuoteControlTest extends \PHPUnit\Framework\TestCase
3436
*/
3537
private $quoteRepositoryMock;
3638

39+
/**
40+
* @var ChangeQuoteControl|MockObject
41+
*/
42+
private $changeQuoteControlMock;
43+
3744
protected function setUp()
3845
{
3946
$this->userContextMock = $this->getMockBuilder(UserContextInterface::class)
@@ -50,15 +57,19 @@ protected function setUp()
5057
->disableOriginalConstructor()
5158
->getMock();
5259

60+
$this->changeQuoteControlMock = $this->getMockBuilder(ChangeQuoteControl::class)
61+
->disableOriginalConstructor()
62+
->getMock();
63+
5364
$objectManagerHelper = new ObjectManager($this);
5465
$this->accessChangeQuoteControl = $objectManagerHelper->getObject(
5566
AccessChangeQuoteControl::class,
56-
['userContext' => $this->userContextMock]
67+
['changeQuoteControl' => $this->changeQuoteControlMock]
5768
);
5869
}
5970

6071
/**
61-
* User with role Customer and customer_id much with context user_id.
72+
* User with role Customer and customer_id matches context user_id.
6273
*/
6374
public function testBeforeSaveForCustomer()
6475
{
@@ -68,6 +79,9 @@ public function testBeforeSaveForCustomer()
6879
$this->userContextMock->method('getUserType')
6980
->willReturn(UserContextInterface::USER_TYPE_CUSTOMER);
7081

82+
$this->changeQuoteControlMock->method('isAllowed')
83+
->willReturn(true);
84+
7185
$result = $this->accessChangeQuoteControl->beforeSave($this->quoteRepositoryMock, $this->quoteMock);
7286

7387
$this->assertNull($result);
@@ -81,11 +95,15 @@ public function testBeforeSaveForCustomer()
8195
*/
8296
public function testBeforeSaveException()
8397
{
84-
$this->userContextMock->method('getUserType')
85-
->willReturn(UserContextInterface::USER_TYPE_CUSTOMER);
8698
$this->quoteMock->method('getCustomerId')
8799
->willReturn(2);
88100

101+
$this->userContextMock->method('getUserType')
102+
->willReturn(UserContextInterface::USER_TYPE_CUSTOMER);
103+
104+
$this->changeQuoteControlMock->method('isAllowed')
105+
->willReturn(false);
106+
89107
$this->accessChangeQuoteControl->beforeSave($this->quoteRepositoryMock, $this->quoteMock);
90108
}
91109

@@ -100,6 +118,9 @@ public function testBeforeSaveForAdmin()
100118
$this->userContextMock->method('getUserType')
101119
->willReturn(UserContextInterface::USER_TYPE_ADMIN);
102120

121+
$this->changeQuoteControlMock->method('isAllowed')
122+
->willReturn(true);
123+
103124
$result = $this->accessChangeQuoteControl->beforeSave($this->quoteRepositoryMock, $this->quoteMock);
104125

105126
$this->assertNull($result);
@@ -116,6 +137,9 @@ public function testBeforeSaveForGuest()
116137
$this->userContextMock->method('getUserType')
117138
->willReturn(UserContextInterface::USER_TYPE_GUEST);
118139

140+
$this->changeQuoteControlMock->method('isAllowed')
141+
->willReturn(true);
142+
119143
$result = $this->accessChangeQuoteControl->beforeSave($this->quoteRepositoryMock, $this->quoteMock);
120144

121145
$this->assertNull($result);
@@ -135,6 +159,9 @@ public function testBeforeSaveForGuestException()
135159
$this->userContextMock->method('getUserType')
136160
->willReturn(UserContextInterface::USER_TYPE_GUEST);
137161

162+
$this->changeQuoteControlMock->method('isAllowed')
163+
->willReturn(false);
164+
138165
$this->accessChangeQuoteControl->beforeSave($this->quoteRepositoryMock, $this->quoteMock);
139166
}
140167

@@ -152,6 +179,9 @@ public function testBeforeSaveForUnknownUserTypeException()
152179
$this->userContextMock->method('getUserType')
153180
->willReturn(10);
154181

182+
$this->changeQuoteControlMock->method('isAllowed')
183+
->willReturn(false);
184+
155185
$this->accessChangeQuoteControl->beforeSave($this->quoteRepositoryMock, $this->quoteMock);
156186
}
157187
}

app/code/Magento/Quote/etc/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<preference for="Magento\Quote\Api\CouponManagementInterface" type="Magento\Quote\Model\CouponManagement" />
2323
<preference for="Magento\Quote\Api\CartManagementInterface" type="Magento\Quote\Model\QuoteManagement" />
2424
<preference for="Magento\Quote\Api\CartTotalRepositoryInterface" type="Magento\Quote\Model\Cart\CartTotalRepository" />
25+
<preference for="Magento\Quote\Api\ChangeQuoteControlInterface" type="Magento\Quote\Model\ChangeQuoteControl" />
2526
<preference for="Magento\Quote\Api\CartTotalManagementInterface" type="Magento\Quote\Model\Cart\CartTotalManagement" />
2627
<preference for="Magento\Quote\Api\Data\TotalsInterface" type="Magento\Quote\Model\Cart\Totals" />
2728
<preference for="Magento\Quote\Api\Data\TotalSegmentInterface" type="Magento\Quote\Model\Cart\TotalSegment" />

0 commit comments

Comments
 (0)