Skip to content

Commit b759b3f

Browse files
[Magento Community Engineering] Community Contributions - 2.4-develop
- merged latest code from mainline branch
2 parents b4b0a6e + 21aa619 commit b759b3f

File tree

60 files changed

+1408
-230
lines changed

Some content is hidden

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

60 files changed

+1408
-230
lines changed

app/code/Magento/CatalogInventory/Model/StockManagement.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public function registerProductsSale($items, $websiteId = null)
119119
) {
120120
$this->getResource()->commit();
121121
throw new \Magento\Framework\Exception\LocalizedException(
122-
__('Not all of your products are available in the requested quantity.')
122+
__('Some of the products are out of stock.')
123123
);
124124
}
125125
if ($this->canSubtractQty($stockItem)) {
@@ -137,7 +137,7 @@ public function registerProductsSale($items, $websiteId = null)
137137
}
138138
$this->qtyCounter->correctItemsQty($registeredItems, $websiteId, '-');
139139
$this->getResource()->commit();
140-
140+
141141
return $fullSaveItems;
142142
}
143143

app/code/Magento/CatalogInventory/Model/StockStateProvider.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,9 @@ public function checkQty(StockItemInterface $stockItem, $qty)
249249
if (!$stockItem->getManageStock()) {
250250
return true;
251251
}
252+
if (!$stockItem->getIsInStock()) {
253+
return false;
254+
}
252255
if ($stockItem->getQty() - $stockItem->getMinQty() - $qty < 0) {
253256
switch ($stockItem->getBackorders()) {
254257
case \Magento\CatalogInventory\Model\Stock::BACKORDERS_YES_NONOTIFY:

app/code/Magento/CatalogInventory/Test/Unit/Model/Spi/StockStateProviderTest.php

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,21 @@ public function testCheckQty(StockItemInterface $stockItem, $expectedResult)
200200
);
201201
}
202202

203+
/**
204+
* Check quantity with out-of-stock status but positive or 0 quantity.
205+
*
206+
* @param StockItemInterface $stockItem
207+
* @param mixed $expectedResult
208+
* @dataProvider checkQtyWithStockStatusDataProvider
209+
*/
210+
public function testCheckQtyWithPositiveQtyAndOutOfStockstatus(StockItemInterface $stockItem, $expectedResult)
211+
{
212+
$this->assertEquals(
213+
$expectedResult,
214+
$this->stockStateProvider->checkQty($stockItem, $this->qty)
215+
);
216+
}
217+
203218
/**
204219
* @param StockItemInterface $stockItem
205220
* @param mixed $expectedResult
@@ -281,6 +296,14 @@ public function checkQtyDataProvider()
281296
return $this->prepareDataForMethod('checkQty');
282297
}
283298

299+
/**
300+
* @return array
301+
*/
302+
public function checkQtyWithStockStatusDataProvider()
303+
{
304+
return $this->prepareDataForMethod('checkQty', $this->getVariationsForQtyAndStock());
305+
}
306+
284307
/**
285308
* @return array
286309
*/
@@ -315,12 +338,16 @@ public function checkQuoteItemQtyDataProvider()
315338

316339
/**
317340
* @param $methodName
341+
* @param array|null $options
318342
* @return array
319343
*/
320-
protected function prepareDataForMethod($methodName)
344+
protected function prepareDataForMethod($methodName, array $options = null)
321345
{
322346
$variations = [];
323-
foreach ($this->getVariations() as $variation) {
347+
if ($options === null) {
348+
$options = $this->getVariations();
349+
}
350+
foreach ($options as $variation) {
324351
$stockItem = $this->getMockBuilder(StockItemInterface::class)
325352
->disableOriginalConstructor()
326353
->setMethods($this->stockItemMethods)
@@ -360,7 +387,7 @@ protected function prepareDataForMethod($methodName)
360387
/**
361388
* @return array
362389
*/
363-
protected function getVariations()
390+
private function getVariations()
364391
{
365392
$stockQty = 100;
366393
return [
@@ -448,6 +475,58 @@ protected function getVariations()
448475
];
449476
}
450477

478+
/**
479+
* @return array
480+
*/
481+
private function getVariationsForQtyAndStock()
482+
{
483+
$stockQty = 100;
484+
return [
485+
[
486+
'values' => [
487+
'getIsInStock' => false,
488+
'getQty' => $stockQty,
489+
'getMinQty' => 60,
490+
'getMinSaleQty' => 1,
491+
'getMaxSaleQty' => 99,
492+
'getNotifyStockQty' => 101,
493+
'getManageStock' => true,
494+
'getBackorders' => 0,
495+
'getQtyIncrements' => 1,
496+
'_stock_qty_' => null,
497+
'_suppress_check_qty_increments_' => false,
498+
'_is_saleable_' => true,
499+
'_ordered_items_' => 0,
500+
'_product_' => 'Test product Name',
501+
],
502+
'results' => [
503+
'checkQty' => false
504+
]
505+
],
506+
[
507+
'values' => [
508+
'getIsInStock' => false,
509+
'getQty' => 0,
510+
'getMinQty' => 60,
511+
'getMinSaleQty' => 1,
512+
'getMaxSaleQty' => 99,
513+
'getNotifyStockQty' => 101,
514+
'getManageStock' => true,
515+
'getBackorders' => 0,
516+
'getQtyIncrements' => 1,
517+
'_stock_qty_' => null,
518+
'_suppress_check_qty_increments_' => false,
519+
'_is_saleable_' => true,
520+
'_ordered_items_' => 0,
521+
'_product_' => 'Test product Name',
522+
],
523+
'results' => [
524+
'checkQty' => false
525+
]
526+
]
527+
];
528+
}
529+
451530
/**
452531
* @param bool $isChildItem
453532
* @param string $expectedMsg

app/code/Magento/CatalogInventory/Test/Unit/Model/StockManagementTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ public function testRegisterProductsSale(
204204
public function testRegisterProductsSaleException(array $items, array $lockedItems)
205205
{
206206
$this->expectException('Magento\Framework\Exception\LocalizedException');
207-
$this->expectExceptionMessage('Not all of your products are available in the requested quantity.');
207+
$this->expectExceptionMessage('Some of the products are out of stock.');
208208
$this->stockResourceMock
209209
->expects($this->once())
210210
->method('beginTransaction');

app/code/Magento/Customer/Api/SessionCleanerInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
interface SessionCleanerInterface
1414
{
1515
/**
16-
* Destroy all active customer sessions related to given customer except current session.
16+
* Destroy all active customer sessions related to given customer id, including current session.
1717
*
1818
* @param int $customerId
1919
* @return void

app/code/Magento/Customer/Controller/Account/EditPost.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright © Magento, Inc. All rights reserved.
55
* See COPYING.txt for license details.
66
*/
7+
declare(strict_types=1);
78

89
namespace Magento\Customer\Controller\Account;
910

@@ -226,7 +227,7 @@ public function execute()
226227

227228
try {
228229
// whether a customer enabled change email option
229-
$this->processChangeEmailRequest($currentCustomerDataObject);
230+
$isEmailChanged = $this->processChangeEmailRequest($currentCustomerDataObject);
230231

231232
// whether a customer enabled change password option
232233
$isPasswordChanged = $this->changeCustomerPassword($currentCustomerDataObject->getEmail());
@@ -242,8 +243,8 @@ public function execute()
242243
);
243244
$this->dispatchSuccessEvent($customerCandidateDataObject);
244245
$this->messageManager->addSuccessMessage(__('You saved the account information.'));
245-
// logout from current session if password changed.
246-
if ($isPasswordChanged) {
246+
// logout from current session if password or email changed.
247+
if ($isPasswordChanged || $isEmailChanged) {
247248
$this->session->logout();
248249
$this->session->start();
249250
return $resultRedirect->setPath('customer/account/login');
@@ -364,7 +365,7 @@ protected function changeCustomerPassword($email)
364365
* Process change email request
365366
*
366367
* @param CustomerInterface $currentCustomerDataObject
367-
* @return void
368+
* @return bool
368369
* @throws InvalidEmailOrPasswordException
369370
* @throws UserLockedException
370371
*/
@@ -377,13 +378,15 @@ private function processChangeEmailRequest(CustomerInterface $currentCustomerDat
377378
$currentCustomerDataObject->getId(),
378379
$this->getRequest()->getPost('current_password')
379380
);
380-
$this->sessionCleaner->clearFor($currentCustomerDataObject->getId());
381+
$this->sessionCleaner->clearFor((int) $currentCustomerDataObject->getId());
382+
return true;
381383
} catch (InvalidEmailOrPasswordException $e) {
382384
throw new InvalidEmailOrPasswordException(
383385
__("The password doesn't match this account. Verify the password and try again.")
384386
);
385387
}
386388
}
389+
return false;
387390
}
388391

389392
/**

app/code/Magento/Customer/Model/ResourceModel/Customer.php

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Customer\Model\ResourceModel;
89

910
use Magento\Customer\Model\AccountConfirmation;
1011
use Magento\Customer\Model\Customer\NotificationStorage;
1112
use Magento\Framework\App\ObjectManager;
12-
use Magento\Framework\Validator\Exception as ValidatorException;
1313
use Magento\Framework\Exception\AlreadyExistsException;
14+
use Magento\Framework\Validator\Exception as ValidatorException;
1415

1516
/**
1617
* Customer entity resource model
@@ -403,4 +404,45 @@ public function changeResetPasswordLinkToken(\Magento\Customer\Model\Customer $c
403404
}
404405
return $this;
405406
}
407+
408+
/**
409+
* Gets the session cut off timestamp string for provided customer id.
410+
*
411+
* @param int $customerId
412+
* @return int|null
413+
*/
414+
public function findSessionCutOff(int $customerId): ?int
415+
{
416+
$connection = $this->getConnection();
417+
$select = $connection->select()->from(
418+
['customer_table' => $this->getTable('customer_entity')],
419+
['session_cutoff' => 'customer_table.session_cutoff']
420+
)->where(
421+
'entity_id =?',
422+
$customerId
423+
)->limit(
424+
1
425+
);
426+
$lookup = $connection->fetchRow($select);
427+
if (empty($lookup) || $lookup['session_cutoff'] == null) {
428+
return null;
429+
}
430+
return strtotime($lookup['session_cutoff']);
431+
}
432+
433+
/**
434+
* Update session cutoff column value for customer
435+
*
436+
* @param int $customerId
437+
* @param int $timestamp
438+
* @return void
439+
*/
440+
public function updateSessionCutOff(int $customerId, int $timestamp): void
441+
{
442+
$this->getConnection()->update(
443+
$this->getTable('customer_entity'),
444+
['session_cutoff' => $this->dateTime->formatDate($timestamp)],
445+
$this->getConnection()->quoteInto('entity_id = ?', $customerId)
446+
);
447+
}
406448
}

app/code/Magento/Customer/Model/ResourceModel/Visitor.php

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Customer\Model\ResourceModel;
89

@@ -59,7 +60,6 @@ protected function _prepareDataForSave(\Magento\Framework\Model\AbstractModel $v
5960
{
6061
return [
6162
'customer_id' => $visitor->getCustomerId(),
62-
'session_id' => $visitor->getSessionId(),
6363
'last_visit_at' => $visitor->getLastVisitAt()
6464
];
6565
}
@@ -95,4 +95,45 @@ public function clean(\Magento\Customer\Model\Visitor $object)
9595

9696
return $this;
9797
}
98+
99+
/**
100+
* Gets created at value for the visitor id.
101+
*
102+
* @param int $visitorId
103+
* @return int|null
104+
*/
105+
public function fetchCreatedAt(int $visitorId): ?int
106+
{
107+
$connection = $this->getConnection();
108+
$select = $connection->select()->from(
109+
['visitor_table' => $this->getTable('customer_visitor')],
110+
['created_at' => 'visitor_table.created_at']
111+
)->where(
112+
'visitor_table.visitor_id = ?',
113+
(string) $visitorId
114+
)->limit(
115+
1
116+
);
117+
$lookup = $connection->fetchRow($select);
118+
if (empty($lookup) || $lookup['created_at'] == null) {
119+
return null;
120+
}
121+
return strtotime($lookup['created_at']);
122+
}
123+
124+
/**
125+
* Update visitor session created at column value
126+
*
127+
* @param int $visitorId
128+
* @param int $timestamp
129+
* @return void
130+
*/
131+
public function updateCreatedAt(int $visitorId, int $timestamp): void
132+
{
133+
$this->getConnection()->update(
134+
$this->getTable('customer_visitor'),
135+
['created_at' => $this->dateTime->formatDate($timestamp)],
136+
$this->getConnection()->quoteInto('visitor_id = ?', $visitorId)
137+
);
138+
}
98139
}

0 commit comments

Comments
 (0)