Skip to content

Commit 0ed0838

Browse files
authored
ENGCOM-4712: Fix for Issue #7227: "x_forwarded_for" value is always empty in Order object #21787
2 parents 2da1c1f + 11cedb4 commit 0ed0838

File tree

2 files changed

+91
-18
lines changed

2 files changed

+91
-18
lines changed

app/code/Magento/Quote/Model/QuoteManagement.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,16 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
146146
*/
147147
private $addressesToSync = [];
148148

149+
/**
150+
* @var \Magento\Framework\App\RequestInterface
151+
*/
152+
private $request;
153+
154+
/**
155+
* @var \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress
156+
*/
157+
private $remoteAddress;
158+
149159
/**
150160
* @param EventManager $eventManager
151161
* @param QuoteValidator $quoteValidator
@@ -169,6 +179,8 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
169179
* @param QuoteFactory $quoteFactory
170180
* @param \Magento\Quote\Model\QuoteIdMaskFactory|null $quoteIdMaskFactory
171181
* @param \Magento\Customer\Api\AddressRepositoryInterface|null $addressRepository
182+
* @param \Magento\Framework\App\RequestInterface|null $request
183+
* @param \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress
172184
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
173185
*/
174186
public function __construct(
@@ -193,7 +205,9 @@ public function __construct(
193205
\Magento\Customer\Api\AccountManagementInterface $accountManagement,
194206
\Magento\Quote\Model\QuoteFactory $quoteFactory,
195207
\Magento\Quote\Model\QuoteIdMaskFactory $quoteIdMaskFactory = null,
196-
\Magento\Customer\Api\AddressRepositoryInterface $addressRepository = null
208+
\Magento\Customer\Api\AddressRepositoryInterface $addressRepository = null,
209+
\Magento\Framework\App\RequestInterface $request = null,
210+
\Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress = null
197211
) {
198212
$this->eventManager = $eventManager;
199213
$this->quoteValidator = $quoteValidator;
@@ -219,6 +233,10 @@ public function __construct(
219233
->get(\Magento\Quote\Model\QuoteIdMaskFactory::class);
220234
$this->addressRepository = $addressRepository ?: ObjectManager::getInstance()
221235
->get(\Magento\Customer\Api\AddressRepositoryInterface::class);
236+
$this->request = $request ?: ObjectManager::getInstance()
237+
->get(\Magento\Framework\App\RequestInterface::class);
238+
$this->remoteAddress = $remoteAddress ?: ObjectManager::getInstance()
239+
->get(\Magento\Framework\HTTP\PhpEnvironment\RemoteAddress::class);
222240
}
223241

224242
/**
@@ -281,6 +299,7 @@ public function assignCustomer($cartId, $customerId, $storeId)
281299
throw new StateException(
282300
__("The customer can't be assigned to the cart because the customer already has an active cart.")
283301
);
302+
// phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
284303
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
285304
}
286305

@@ -368,6 +387,14 @@ public function placeOrder($cartId, PaymentInterface $paymentMethod = null)
368387
$quote->setCustomerGroupId(\Magento\Customer\Api\Data\GroupInterface::NOT_LOGGED_IN_ID);
369388
}
370389

390+
$remoteAddress = $this->remoteAddress->getRemoteAddress();
391+
if ($remoteAddress !== false) {
392+
$quote->setRemoteIp($remoteAddress);
393+
$quote->setXForwardedFor(
394+
$this->request->getServer('HTTP_X_FORWARDED_FOR')
395+
);
396+
}
397+
371398
$this->eventManager->dispatch('checkout_submit_before', ['quote' => $quote]);
372399

373400
$order = $this->submit($quote);
@@ -627,12 +654,14 @@ private function rollbackAddresses(
627654
'exception' => $e,
628655
]
629656
);
657+
// phpcs:ignore Magento2.Exceptions.ThrowCatch
630658
} catch (\Exception $consecutiveException) {
631659
$message = sprintf(
632660
"An exception occurred on 'sales_model_service_quote_submit_failure' event: %s",
633661
$consecutiveException->getMessage()
634662
);
635663

664+
// phpcs:ignore Magento2.Exceptions.DirectThrow
636665
throw new \Exception($message, 0, $e);
637666
}
638667
}

app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66

77
namespace Magento\Quote\Test\Unit\Model;
88

9+
use Magento\Framework\App\RequestInterface;
910
use Magento\Framework\Exception\NoSuchEntityException;
1011

12+
use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
1113
use Magento\Quote\Model\CustomerManagement;
14+
use Magento\Quote\Model\QuoteIdMaskFactory;
1215
use Magento\Sales\Api\Data\OrderAddressInterface;
1316

1417
/**
@@ -137,6 +140,21 @@ class QuoteManagementTest extends \PHPUnit\Framework\TestCase
137140
*/
138141
private $quoteFactoryMock;
139142

143+
/**
144+
* @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
145+
*/
146+
private $requestMock;
147+
148+
/**
149+
* @var \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress|\PHPUnit_Framework_MockObject_MockObject
150+
*/
151+
private $remoteAddressMock;
152+
153+
/**
154+
* @var \Magento\Quote\Model\QuoteIdMaskFactory|\PHPUnit_Framework_MockObject_MockObject
155+
*/
156+
private $quoteIdMaskFactoryMock;
157+
140158
/**
141159
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
142160
*/
@@ -178,18 +196,20 @@ protected function setUp()
178196
);
179197

180198
$this->quoteMock = $this->createPartialMock(\Magento\Quote\Model\Quote::class, [
181-
'getId',
182-
'getCheckoutMethod',
183-
'setCheckoutMethod',
184-
'setCustomerId',
185-
'setCustomerEmail',
186-
'getBillingAddress',
187-
'setCustomerIsGuest',
188-
'setCustomerGroupId',
189-
'assignCustomer',
190-
'getPayment',
191-
'collectTotals'
192-
]);
199+
'assignCustomer',
200+
'collectTotals',
201+
'getBillingAddress',
202+
'getCheckoutMethod',
203+
'getPayment',
204+
'setCheckoutMethod',
205+
'setCustomerEmail',
206+
'setCustomerGroupId',
207+
'setCustomerId',
208+
'setCustomerIsGuest',
209+
'setRemoteIp',
210+
'setXForwardedFor',
211+
'getId',
212+
]);
193213

194214
$this->quoteAddressFactory = $this->createPartialMock(
195215
\Magento\Quote\Model\Quote\AddressFactory::class,
@@ -237,8 +257,11 @@ protected function setUp()
237257

238258
// Set the new dependency
239259
$this->quoteIdMock = $this->createMock(\Magento\Quote\Model\QuoteIdMask::class);
240-
$quoteIdFactoryMock = $this->createPartialMock(\Magento\Quote\Model\QuoteIdMaskFactory::class, ['create']);
241-
$this->setPropertyValue($this->model, 'quoteIdMaskFactory', $quoteIdFactoryMock);
260+
$this->quoteIdMaskFactoryMock = $this->createPartialMock(QuoteIdMaskFactory::class, ['create']);
261+
$this->setPropertyValue($this->model, 'quoteIdMaskFactory', $this->quoteIdMaskFactoryMock);
262+
263+
$this->requestMock = $this->createPartialMockForAbstractClass(RequestInterface::class, ['getServer']);
264+
$this->remoteAddressMock = $this->createMock(RemoteAddress::class);
242265
}
243266

244267
public function testCreateEmptyCartAnonymous()
@@ -676,7 +699,11 @@ public function testPlaceOrderIfCustomerIsGuest()
676699
'checkoutSession' => $this->checkoutSessionMock,
677700
'customerSession' => $this->customerSessionMock,
678701
'accountManagement' => $this->accountManagementMock,
679-
'quoteFactory' => $this->quoteFactoryMock
702+
'quoteFactory' => $this->quoteFactoryMock,
703+
'quoteIdMaskFactory' => $this->quoteIdMaskFactoryMock,
704+
'addressRepository' => $this->addressRepositoryMock,
705+
'request' => $this->requestMock,
706+
'remoteAddress' => $this->remoteAddressMock,
680707
]
681708
)
682709
->getMock();
@@ -709,13 +736,15 @@ public function testPlaceOrder()
709736
$orderId = 332;
710737
$orderIncrementId = 100003332;
711738
$orderStatus = 'status1';
739+
$remoteAddress = '192.168.1.10';
740+
$forwardedForIp = '192.168.1.11';
712741

713742
/** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Quote\Model\QuoteManagement $service */
714743
$service = $this->getMockBuilder(\Magento\Quote\Model\QuoteManagement::class)
715744
->setMethods(['submit'])
716745
->setConstructorArgs(
717746
[
718-
'eventManager' => $this->eventManager,
747+
'eventManager' => $this->eventManager,
719748
'quoteValidator' => $this->quoteValidator,
720749
'orderFactory' => $this->orderFactory,
721750
'orderManagement' => $this->orderManagement,
@@ -734,7 +763,11 @@ public function testPlaceOrder()
734763
'checkoutSession' => $this->checkoutSessionMock,
735764
'customerSession' => $this->customerSessionMock,
736765
'accountManagement' => $this->accountManagementMock,
737-
'quoteFactory' => $this->quoteFactoryMock
766+
'quoteFactory' => $this->quoteFactoryMock,
767+
'quoteIdMaskFactory' => $this->quoteIdMaskFactoryMock,
768+
'addressRepository' => $this->addressRepositoryMock,
769+
'request' => $this->requestMock,
770+
'remoteAddress' => $this->remoteAddressMock,
738771
]
739772
)
740773
->getMock();
@@ -762,6 +795,17 @@ public function testPlaceOrder()
762795
->method('setCustomerIsGuest')
763796
->with(true);
764797

798+
$this->remoteAddressMock
799+
->method('getRemoteAddress')
800+
->willReturn($remoteAddress);
801+
802+
$this->requestMock
803+
->method('getServer')
804+
->willReturn($forwardedForIp);
805+
806+
$this->quoteMock->expects($this->once())->method('setRemoteIp')->with($remoteAddress);
807+
$this->quoteMock->expects($this->once())->method('setXForwardedFor')->with($forwardedForIp);
808+
765809
$service->expects($this->once())->method('submit')->willReturn($orderMock);
766810

767811
$this->quoteMock->expects($this->atLeastOnce())->method('getId')->willReturn($cartId);

0 commit comments

Comments
 (0)