Skip to content

Commit 718fb5f

Browse files
Merge branch '2.4-develop' into 2.4-develop-prs
2 parents 5ae7d39 + f1adf23 commit 718fb5f

File tree

16 files changed

+499
-125
lines changed

16 files changed

+499
-125
lines changed

app/code/Magento/Catalog/Block/Product/Compare/ListCompare.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ class ListCompare extends \Magento\Catalog\Block\Product\AbstractProduct
4040
protected $_useLinkForAsLowAs = false;
4141

4242
/**
43-
* Customer id
44-
*
4543
* @var null|int
4644
*/
4745
protected $_customerId = null;
@@ -52,22 +50,16 @@ class ListCompare extends \Magento\Catalog\Block\Product\AbstractProduct
5250
protected $httpContext;
5351

5452
/**
55-
* Customer visitor
56-
*
5753
* @var \Magento\Customer\Model\Visitor
5854
*/
5955
protected $_customerVisitor;
6056

6157
/**
62-
* Catalog product visibility
63-
*
6458
* @var \Magento\Catalog\Model\Product\Visibility
6559
*/
6660
protected $_catalogProductVisibility;
6761

6862
/**
69-
* Item collection factory
70-
*
7163
* @var \Magento\Catalog\Model\ResourceModel\Product\Compare\Item\CollectionFactory
7264
*/
7365
protected $_itemCollectionFactory;
@@ -205,6 +197,9 @@ public function getProductAttributeValue($product, $attribute)
205197
} else {
206198
$value = $product->getData($attribute->getAttributeCode());
207199
}
200+
if (is_array($value)) {
201+
return __('N/A');
202+
}
208203
return (string)$value == '' ? __('No') : $value;
209204
}
210205

app/code/Magento/Catalog/Test/Unit/Block/Product/Compare/ListCompareTest.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
use Magento\Catalog\Block\Product\Compare\ListCompare;
1111
use Magento\Catalog\Block\Product\Context;
1212
use Magento\Catalog\Model\Product;
13+
use Magento\Eav\Model\Entity\Attribute\AttributeInterface;
14+
use Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend;
1315
use Magento\Framework\Pricing\Render;
1416
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1517
use Magento\Framework\View\Layout;
@@ -50,6 +52,48 @@ protected function tearDown(): void
5052
$this->block = null;
5153
}
5254

55+
/**
56+
* @dataProvider attributeDataProvider
57+
* @param array $attributeData
58+
* @param string $expectedResult
59+
*/
60+
public function testProductAttributeValue($attributeData, $expectedResult)
61+
{
62+
$attribute = $this->getMockBuilder(AttributeInterface::class)
63+
->addMethods(['getAttributeCode', 'getSourceModel', 'getFrontendInput', 'getFrontend'])
64+
->getMockForAbstractClass();
65+
$frontEndModel = $this->createPartialMock(AbstractFrontend::class, ['getValue']);
66+
$productMock = $this->createPartialMock(Product::class, ['getId', 'getData', 'hasData']);
67+
$productMock->expects($this->any())
68+
->method('hasData')
69+
->with($attributeData['attribute_code'])
70+
->willReturn(true);
71+
$productMock->expects($this->any())
72+
->method('getData')
73+
->with($attributeData['attribute_code'])
74+
->willReturn($attributeData['attribute_value']);
75+
$attribute->expects($this->any())
76+
->method('getAttributeCode')
77+
->willReturn($attributeData['attribute_code']);
78+
$attribute->expects($this->any())
79+
->method('getSourceModel')
80+
->willReturn($attributeData['source_model']);
81+
$attribute->expects($this->any())
82+
->method('getFrontendInput')
83+
->willReturn($attributeData['frontend_input']);
84+
$frontEndModel->expects($this->any())
85+
->method('getValue')
86+
->with($productMock)
87+
->willReturn($attributeData['attribute_value']);
88+
$attribute->expects($this->any())
89+
->method('getFrontend')
90+
->willReturn($frontEndModel);
91+
$this->assertEquals(
92+
$expectedResult,
93+
$this->block->getProductAttributeValue($productMock, $attribute)
94+
);
95+
}
96+
5397
public function testGetProductPrice()
5498
{
5599
//Data
@@ -84,4 +128,31 @@ public function testGetProductPrice()
84128

85129
$this->assertEquals($expectedResult, $this->block->getProductPrice($product, '-compare-list-top'));
86130
}
131+
132+
/**
133+
* @return array
134+
*/
135+
public function attributeDataProvider(): array
136+
{
137+
return [
138+
[
139+
'attributeData' => [
140+
'attribute_code' => 'tier_price',
141+
'source_model' => null,
142+
'frontend_input' => 'text',
143+
'attribute_value' => []
144+
],
145+
'expectedResult' => __('N/A')
146+
],
147+
[
148+
'attributeData' => [
149+
'attribute_code' => 'special_price',
150+
'source_model' => null,
151+
'frontend_input' => 'decimal',
152+
'attribute_value' => 50.00
153+
],
154+
'expectedResult' => '50.00'
155+
]
156+
];
157+
}
87158
}

app/code/Magento/Indexer/Console/Command/IndexerShowDimensionsModeCommand.php

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
*/
2020
class IndexerShowDimensionsModeCommand extends AbstractIndexerCommand
2121
{
22-
const INPUT_KEY_INDEXER = 'indexer';
23-
const DIMENSION_MODE_NONE = 'none';
24-
const XML_PATH_DIMENSIONS_MODE_MASK = 'indexer/%s/dimensions_mode';
22+
private const INPUT_KEY_INDEXER = 'indexer';
23+
private const DIMENSION_MODE_NONE = 'none';
24+
private const XML_PATH_DIMENSIONS_MODE_MASK = 'indexer/%s/dimensions_mode';
2525
/**
2626
* @var string
2727
*/
@@ -36,24 +36,31 @@ class IndexerShowDimensionsModeCommand extends AbstractIndexerCommand
3636
* @var string[]
3737
*/
3838
private $indexers;
39+
/**
40+
* @var string[]
41+
*/
42+
private $optionalIndexers;
3943

4044
/**
4145
* @param ObjectManagerFactory $objectManagerFactory
4246
* @param ScopeConfigInterface $configReader
4347
* @param array $indexers
48+
* @param array $optionalIndexers
4449
*/
4550
public function __construct(
4651
ObjectManagerFactory $objectManagerFactory,
4752
ScopeConfigInterface $configReader,
48-
array $indexers
53+
array $indexers,
54+
array $optionalIndexers = []
4955
) {
5056
$this->configReader = $configReader;
5157
$this->indexers = $indexers;
58+
$this->optionalIndexers = $optionalIndexers;
5259
parent::__construct($objectManagerFactory);
5360
}
5461

5562
/**
56-
* {@inheritdoc}
63+
* @inheritdoc
5764
*/
5865
protected function configure()
5966
{
@@ -64,7 +71,7 @@ protected function configure()
6471
}
6572

6673
/**
67-
* {@inheritdoc}
74+
* @inheritdoc
6875
* @param InputInterface $input
6976
* @param OutputInterface $output
7077
* @return int
@@ -92,10 +99,12 @@ protected function execute(InputInterface $input, OutputInterface $output)
9299
$output->writeln(sprintf('%-50s ', $indexer->getTitle() . ':') . $mode);
93100
}
94101
} catch (\Exception $e) {
95-
$output->writeln('"' . $indexer->getTitle() . '" indexer process unknown error:' . PHP_EOL);
96-
$output->writeln($e->getMessage() . PHP_EOL);
97-
// we must have an exit code higher than zero to indicate something was wrong
98-
$returnValue = Cli::RETURN_FAILURE;
102+
if (!in_array($indexerId, $this->optionalIndexers)) { /** @phpstan-ignore-line */
103+
$output->writeln('"' . $indexer->getTitle() . '" indexer process unknown error:' . PHP_EOL);
104+
$output->writeln($e->getMessage() . PHP_EOL);
105+
// we must have an exit code higher than zero to indicate something was wrong
106+
$returnValue = Cli::RETURN_FAILURE;
107+
}
99108
}
100109

101110
return $returnValue;
@@ -112,7 +121,7 @@ private function getInputList(): array
112121
$arguments[] = new InputArgument(
113122
self::INPUT_KEY_INDEXER,
114123
InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
115-
$optionDescription . ' (' . implode($this->indexers) . ')'
124+
$optionDescription . ' (' . implode(',', $this->indexers) . ')'
116125
);
117126

118127
return $arguments;

app/code/Magento/Indexer/Test/Unit/Console/Command/IndexerShowDimensionsModeCommandTest.php

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,26 @@ class IndexerShowDimensionsModeCommandTest extends AbstractIndexerCommandCommonS
4141
*/
4242
private $indexerMock;
4343

44+
/**
45+
* @var string[]
46+
*/
47+
private $optionalIndexers;
48+
49+
/**
50+
* @var ObjectManagerHelper
51+
*/
52+
private $objectManagerHelper;
53+
4454
/**
4555
* @inheritdoc
4656
*/
4757
protected function setUp(): void
4858
{
4959
parent::setUp();
50-
$objectManagerHelper = new ObjectManagerHelper($this);
60+
$this->objectManagerHelper = new ObjectManagerHelper($this);
5161
$this->configReaderMock = $this->getMockForAbstractClass(ScopeConfigInterface::class);
5262
$this->indexers = ['indexer_1' => 'indexer_1', 'indexer_2' => 'indexer_2'];
53-
$this->command = $objectManagerHelper->getObject(
63+
$this->command = $this->objectManagerHelper->getObject(
5464
IndexerShowDimensionsModeCommand::class,
5565
[
5666
'objectManagerFactory' => $this->objectManagerFactory,
@@ -98,6 +108,29 @@ public function testExecuteWithAttributes($command, $consoleOutput)
98108
);
99109
}
100110

111+
public function testExecuteWithOptionalIndexers()
112+
{
113+
$this->optionalIndexers = ['indexer_3'];
114+
$this->indexers = ['indexer_3'=> 'indexer_3'];
115+
$this->command = $this->objectManagerHelper->getObject(
116+
IndexerShowDimensionsModeCommand::class,
117+
[
118+
'objectManagerFactory' => $this->objectManagerFactory,
119+
'configReader' => $this->configReaderMock,
120+
'indexers' => $this->indexers,
121+
'optionalIndexers' => $this->optionalIndexers
122+
]
123+
);
124+
$command = ['indexer' => ['indexer_3']];
125+
$this->configureAdminArea();
126+
/** @var CommandTester $commandTester */
127+
$commandTester = new CommandTester($this->command);
128+
$this->indexerMock->method('load')->willThrowException(new \InvalidArgumentException());
129+
$commandTester->execute($command);
130+
$actualValue = $commandTester->getDisplay();
131+
$this->assertEquals('', $actualValue);
132+
}
133+
101134
/**
102135
* @return array
103136
*/

app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php

Lines changed: 7 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -8,55 +8,27 @@
88
namespace Magento\Multishipping\Model\Cart\Controller;
99

1010
use Magento\Checkout\Controller\Cart;
11-
use Magento\Checkout\Model\Session;
12-
use Magento\Customer\Api\AddressRepositoryInterface;
1311
use Magento\Framework\App\RequestInterface;
1412
use Magento\Framework\Exception\LocalizedException;
15-
use Magento\Multishipping\Model\DisableMultishipping;
16-
use Magento\Quote\Api\CartRepositoryInterface;
17-
use Magento\Quote\Model\Quote;
13+
use Magento\Multishipping\Model\Cart\MultishippingClearItemAddress;
1814

1915
/**
2016
* Cleans shipping addresses and item assignments after MultiShipping flow
2117
*/
2218
class CartPlugin
2319
{
2420
/**
25-
* @var CartRepositoryInterface
21+
* @var MultishippingClearItemAddress
2622
*/
27-
private $cartRepository;
23+
private $multishippingClearItemAddress;
2824

2925
/**
30-
* @var Session
31-
*/
32-
private $checkoutSession;
33-
34-
/**
35-
* @var AddressRepositoryInterface
36-
*/
37-
private $addressRepository;
38-
39-
/**
40-
* @var DisableMultishipping
41-
*/
42-
private $disableMultishipping;
43-
44-
/**
45-
* @param CartRepositoryInterface $cartRepository
46-
* @param Session $checkoutSession
47-
* @param AddressRepositoryInterface $addressRepository
48-
* @param DisableMultishipping $disableMultishipping
26+
* @param MultishippingClearItemAddress $multishippingClearItemAddress
4927
*/
5028
public function __construct(
51-
CartRepositoryInterface $cartRepository,
52-
Session $checkoutSession,
53-
AddressRepositoryInterface $addressRepository,
54-
DisableMultishipping $disableMultishipping
29+
MultishippingClearItemAddress $multishippingClearItemAddress
5530
) {
56-
$this->cartRepository = $cartRepository;
57-
$this->checkoutSession = $checkoutSession;
58-
$this->addressRepository = $addressRepository;
59-
$this->disableMultishipping = $disableMultishipping;
31+
$this->multishippingClearItemAddress = $multishippingClearItemAddress;
6032
}
6133

6234
/**
@@ -70,62 +42,6 @@ public function __construct(
7042
*/
7143
public function beforeDispatch(Cart $subject, RequestInterface $request)
7244
{
73-
/** @var Quote $quote */
74-
$quote = $this->checkoutSession->getQuote();
75-
$isMultipleShippingAddressesPresent = $quote->isMultipleShippingAddresses();
76-
if ($isMultipleShippingAddressesPresent || $this->isDisableMultishippingRequired($request, $quote)) {
77-
$this->disableMultishipping->execute($quote);
78-
foreach ($quote->getAllShippingAddresses() as $address) {
79-
$quote->removeAddress($address->getId());
80-
}
81-
82-
$shippingAddress = $quote->getShippingAddress();
83-
$defaultShipping = $quote->getCustomer()->getDefaultShipping();
84-
if ($defaultShipping) {
85-
$defaultCustomerAddress = $this->addressRepository->getById($defaultShipping);
86-
$shippingAddress->importCustomerAddressData($defaultCustomerAddress);
87-
}
88-
if ($isMultipleShippingAddressesPresent) {
89-
$this->checkoutSession->setMultiShippingAddressesFlag(true);
90-
}
91-
$this->cartRepository->save($quote);
92-
} elseif ($this->disableMultishipping->execute($quote) && $this->isVirtualItemInQuote($quote)) {
93-
$quote->setTotalsCollectedFlag(false);
94-
$this->cartRepository->save($quote);
95-
}
96-
}
97-
98-
/**
99-
* Checks whether quote has virtual items
100-
*
101-
* @param Quote $quote
102-
* @return bool
103-
*/
104-
private function isVirtualItemInQuote(Quote $quote): bool
105-
{
106-
$items = $quote->getItems();
107-
if (!empty($items)) {
108-
foreach ($items as $item) {
109-
if ($item->getIsVirtual()) {
110-
return true;
111-
}
112-
}
113-
}
114-
115-
return false;
116-
}
117-
118-
/**
119-
* Check if we have to disable multishipping mode depends on the request action name
120-
*
121-
* We should not disable multishipping mode if we are adding a new product item to the existing quote
122-
*
123-
* @param RequestInterface $request
124-
* @param Quote $quote
125-
* @return bool
126-
*/
127-
private function isDisableMultishippingRequired(RequestInterface $request, Quote $quote): bool
128-
{
129-
return $request->getActionName() !== "add" && $quote->getIsMultiShipping();
45+
$this->multishippingClearItemAddress->clearAddressItem($subject, $request);
13046
}
13147
}

0 commit comments

Comments
 (0)