Skip to content

Commit dad1949

Browse files
Merge branch '2.4-develop' into patch-21
2 parents 5b265e9 + 001e518 commit dad1949

File tree

66 files changed

+2066
-647
lines changed

Some content is hidden

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

66 files changed

+2066
-647
lines changed

app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
use Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks;
2121
use Magento\Catalog\Model\Product\Link\Resolver as LinkResolver;
2222
use Magento\Catalog\Model\Product\LinkTypeProvider;
23+
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions;
2324
use Magento\Framework\App\ObjectManager;
2425
use Magento\Framework\App\RequestInterface;
26+
use Magento\Framework\Exception\NoSuchEntityException;
2527
use Magento\Framework\Locale\FormatInterface;
2628
use Magento\Framework\Stdlib\DateTime\Filter\Date;
2729
use Magento\Store\Model\StoreManagerInterface;
@@ -278,6 +280,7 @@ public function initialize(Product $product)
278280
* @param Product $product
279281
* @return Product
280282
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
283+
* @throws NoSuchEntityException
281284
* @since 101.0.0
282285
*/
283286
protected function setProductLinks(Product $product)
@@ -301,20 +304,18 @@ protected function setProductLinks(Product $product)
301304
}
302305

303306
foreach ($linkTypes as $linkType => $readonly) {
304-
if (isset($links[$linkType]) && !$readonly) {
305-
foreach ((array) $links[$linkType] as $linkData) {
306-
if (empty($linkData['id'])) {
307-
continue;
308-
}
309-
310-
$linkProduct = $this->productRepository->getById($linkData['id']);
311-
$link = $this->productLinkFactory->create();
312-
$link->setSku($product->getSku())
313-
->setLinkedProductSku($linkProduct->getSku())
314-
->setLinkType($linkType)
315-
->setPosition(isset($linkData['position']) ? (int) $linkData['position'] : 0);
316-
$productLinks[] = $link;
317-
}
307+
$isReadOnlyLinks = $readonly && in_array($linkType, ['upsell', 'related']);
308+
if ($isReadOnlyLinks) {
309+
$productLinks = null;
310+
break;
311+
} else {
312+
$productLinks = $this->setProductLinksForNotReadOnlyItems(
313+
$productLinks,
314+
$product,
315+
$links,
316+
$linkType,
317+
$readonly
318+
);
318319
}
319320
}
320321

@@ -401,6 +402,9 @@ private function overwriteValue($optionId, $option, $overwriteOptions)
401402
$option['is_delete_store_title'] = 1;
402403
}
403404
}
405+
if (CustomOptions::FIELD_TITLE_NAME === $fieldName) {
406+
$option[CustomOptions::FIELD_IS_USE_DEFAULT] = $overwrite;
407+
}
404408
}
405409
}
406410

@@ -523,4 +527,39 @@ private function setCategoryLinks(Product $product): void
523527
$extensionAttributes->setCategoryLinks(!empty($newCategoryLinks) ? $newCategoryLinks : null);
524528
$product->setExtensionAttributes($extensionAttributes);
525529
}
530+
531+
/**
532+
* Set product links when readonly is false
533+
*
534+
* @param array $productLinks
535+
* @param Product $product
536+
* @param array $links
537+
* @param string $linkType
538+
* @param mixed $readonly
539+
* @return array
540+
* @throws NoSuchEntityException
541+
*/
542+
private function setProductLinksForNotReadOnlyItems(
543+
array $productLinks,
544+
Product $product,
545+
array $links,
546+
string $linkType,
547+
mixed $readonly
548+
): array {
549+
if (isset($links[$linkType]) && !$readonly) {
550+
foreach ((array)$links[$linkType] as $linkData) {
551+
if (empty($linkData['id'])) {
552+
continue;
553+
}
554+
$linkProduct = $this->productRepository->getById($linkData['id']);
555+
$link = $this->productLinkFactory->create();
556+
$link->setSku($product->getSku())
557+
->setLinkedProductSku($linkProduct->getSku())
558+
->setLinkType($linkType)
559+
->setPosition(isset($linkData['position']) ? (int)$linkData['position'] : 0);
560+
$productLinks[] = $link;
561+
}
562+
}
563+
return $productLinks;
564+
}
526565
}

app/code/Magento/Catalog/Model/ResourceModel/Product/Option.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
/**
1515
* Catalog product custom option resource model
1616
*
17-
* @author Magento Core Team <[email protected]>
1817
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1918
*/
2019
class Option extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
@@ -25,15 +24,11 @@ class Option extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
2524
protected $metadataPool;
2625

2726
/**
28-
* Store manager
29-
*
3027
* @var \Magento\Store\Model\StoreManagerInterface
3128
*/
3229
protected $_storeManager;
3330

3431
/**
35-
* Currency factory
36-
*
3732
* @var \Magento\Directory\Model\CurrencyFactory
3833
*/
3934
protected $_currencyFactory;
@@ -259,12 +254,13 @@ protected function _saveValueTitles(AbstractModel $object)
259254
}
260255
} else {
261256
// we should insert record into not default store only of if it does not exist in default store
262-
if (($storeId == Store::DEFAULT_STORE_ID && !$existInDefaultStore) ||
257+
if (((int)$storeId === Store::DEFAULT_STORE_ID && !$existInDefaultStore) ||
263258
(
264-
$storeId != Store::DEFAULT_STORE_ID &&
265-
!$existInCurrentStore &&
266-
!$isDeleteStoreTitle
267-
)
259+
(int)$storeId !== Store::DEFAULT_STORE_ID &&
260+
!$isDeleteStoreTitle &&
261+
($object->getDefaultTitle() !== null && $object->getTitle() !== $object->getDefaultTitle())
262+
) ||
263+
($object->getIsUseDefault() !== null && !(int)$object->getIsUseDefault())
268264
) {
269265
$data = $this->_prepareDataForTable(
270266
new \Magento\Framework\DataObject(

app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,11 @@
2727
class Value extends AbstractDb
2828
{
2929
/**
30-
* Store manager
31-
*
3230
* @var StoreManagerInterface
3331
*/
3432
protected $_storeManager;
3533

3634
/**
37-
* Currency factory
38-
*
3935
* @var CurrencyFactory
4036
*/
4137
protected $_currencyFactory;
@@ -288,8 +284,12 @@ protected function _saveValueTitles(AbstractModel $object)
288284
Store::DEFAULT_STORE_ID
289285
);
290286
// we should insert record into not default store only of if it does not exist in default store
291-
if (($storeId == Store::DEFAULT_STORE_ID && !$existInDefaultStore)
292-
|| ($storeId != Store::DEFAULT_STORE_ID && !$existInCurrentStore)
287+
if (((int)$storeId === Store::DEFAULT_STORE_ID && !$existInDefaultStore) ||
288+
(
289+
(int)$storeId !== Store::DEFAULT_STORE_ID &&
290+
($object->getDefaultTitle() !== null && $object->getTitle() !== $object->getDefaultTitle())
291+
) ||
292+
($object->getIsUseDefault() !== null && !(int)$object->getIsUseDefault())
293293
) {
294294
$bind = [
295295
'option_type_id' => (int)$object->getId(),
@@ -456,6 +456,7 @@ public function duplicate(OptionValue $object, $oldOptionId, $newOptionId)
456456
*
457457
* @return FormatInterface
458458
* @deprecated 101.0.8
459+
* @see Avoid direct use of ObjectManager
459460
*/
460461
private function getLocaleFormatter()
461462
{

app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,7 @@ protected function setUp(): void
161161
->getMock();
162162
$this->productLinksMock = $this->createMock(ProductLinks::class);
163163
$this->linkTypeProviderMock = $this->createMock(LinkTypeProvider::class);
164-
$this->productLinksMock->expects($this->any())
165-
->method('initializeLinks')
166-
->willReturn($this->productMock);
164+
167165
$this->attributeFilterMock = $this->createMock(AttributeFilter::class);
168166
$this->localeFormatMock = $this->createMock(Format::class);
169167

@@ -221,6 +219,7 @@ protected function setUp(): void
221219
* @param array|null $tierPrice
222220
* @dataProvider initializeDataProvider
223221
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
222+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
224223
*/
225224
public function testInitialize(
226225
$isSingleStore,
@@ -229,8 +228,17 @@ public function testInitialize(
229228
$links,
230229
$linkTypes,
231230
$expectedLinks,
232-
$tierPrice = null
231+
$tierPrice = null,
232+
$isReadOnlyRelatedItems = null,
233+
$isReadOnlyUpSellItems = null,
234+
$ignoreLinksFlag = false
233235
) {
236+
$this->productMock->setData('related_readonly', $isReadOnlyRelatedItems);
237+
$this->productMock->setData('upsell_readonly', $isReadOnlyUpSellItems);
238+
$this->productLinksMock->expects($this->any())
239+
->method('initializeLinks')
240+
->willReturn($this->productMock);
241+
234242
$this->linkTypeProviderMock->expects($this->once())
235243
->method('getItems')
236244
->willReturn($this->assembleLinkTypes($linkTypes));
@@ -346,6 +354,11 @@ function () {
346354

347355
$productLinks = $this->productMock->getProductLinks();
348356
$this->assertCount(count($expectedLinks), $productLinks);
357+
if ($ignoreLinksFlag) {
358+
$this->assertTrue($this->productMock->getDataByKey('ignore_links_flag'));
359+
} else {
360+
$this->assertFalse($this->productMock->getDataByKey('ignore_links_flag'));
361+
}
349362
$resultLinks = [];
350363

351364
$this->assertEquals($tierPrice ?: [], $this->productMock->getData('tier_price'));
@@ -559,6 +572,34 @@ public static function initializeDataProvider()
559572
['type' => 'related', 'linked_product_sku' => 'Test'],
560573
],
561574
],
575+
576+
// readonly links
577+
[
578+
'single_store' => false,
579+
'website_ids' => ['1' => 1, '2' => 2],
580+
'expected_website_ids' => ['1' => 1, '2' => 2],
581+
'links' => [
582+
'related' => [
583+
0 => [
584+
'id' => 1,
585+
'thumbnail' => 'http://magento.dev/media/no-image.jpg',
586+
'name' => 'Test',
587+
'status' => 'Enabled',
588+
'attribute_set' => 'Default',
589+
'sku' => 'Test',
590+
'price' => 1.00,
591+
'position' => 1,
592+
'record_id' => 1,
593+
],
594+
],
595+
],
596+
'linkTypes' => ['related', 'upsell', 'crosssell'],
597+
'expected_links' => [],
598+
'tierPrice' => [],
599+
true,
600+
true,
601+
true
602+
],
562603
];
563604
}
564605

@@ -660,6 +701,7 @@ public static function mergeProductOptionsDataProvider()
660701
'default_key2' => 'val22',
661702
],
662703
],
704+
'is_use_default' => 1,
663705
],
664706
],
665707
],
@@ -702,6 +744,7 @@ public static function mergeProductOptionsDataProvider()
702744
'default_key1' => 'val11',
703745
'default_title' => 'val22',
704746
'is_delete_store_title' => 1,
747+
'is_use_default' => 1,
705748
],
706749
],
707750
],

app/code/Magento/Checkout/Model/AddressComparator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function isEqual(?AddressInterface $address1, ?AddressInterface $address2
4343
(int)$address2->getCustomerAddressId());
4444
} else {
4545
$addressKeys = array_intersect_key($address1->getData(), $address2->getData());
46-
$removeKeys = ['address_type', 'region_code', 'save_in_address_book'];
46+
$removeKeys = ['address_type', 'region_code', 'save_in_address_book', 'customer_address_id'];
4747
$addressKeys = array_diff_key($addressKeys, array_flip($removeKeys));
4848

4949
$address1Data = array_intersect_key($address1->getData(), $addressKeys);

0 commit comments

Comments
 (0)