Skip to content

Commit 73a3ce5

Browse files
authored
Merge branch '2.4-develop' into UPS_AC9653_OCT_22_2023
2 parents e043ad4 + 9e2eb99 commit 73a3ce5

File tree

123 files changed

+3907
-1062
lines changed

Some content is hidden

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

123 files changed

+3907
-1062
lines changed

app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Front.php

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Magento\Catalog\Model\Entity\Attribute;
1414
use Magento\Eav\Block\Adminhtml\Attribute\PropertyLocker;
1515
use Magento\Framework\Data\FormFactory;
16+
use Magento\Framework\Exception\LocalizedException;
1617
use Magento\Framework\Registry;
1718

1819
/**
@@ -58,6 +59,7 @@ public function __construct(
5859
* @inheritDoc
5960
* @return $this
6061
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
62+
* @throws LocalizedException
6163
*/
6264
protected function _prepareForm()
6365
{
@@ -176,28 +178,34 @@ protected function _prepareForm()
176178
['form' => $form, 'attribute' => $attributeObject]
177179
);
178180

181+
$dependencies = $this->getLayout()->createBlock(
182+
\Magento\Backend\Block\Widget\Form\Element\Dependence::class
183+
)->addFieldMap(
184+
"is_html_allowed_on_front",
185+
'html_allowed_on_front'
186+
)->addFieldMap(
187+
"frontend_input",
188+
'frontend_input_type'
189+
)->addFieldMap(
190+
"is_searchable",
191+
'searchable'
192+
)->addFieldMap(
193+
"is_visible_in_advanced_search",
194+
'advanced_search'
195+
)->addFieldDependence(
196+
'advanced_search',
197+
'searchable',
198+
'1'
199+
);
200+
$this->_eventManager->dispatch(
201+
'adminhtml_catalog_product_attribute_edit_frontend_prepare_field_dependencies',
202+
['dependencies' => $dependencies]
203+
);
204+
179205
// define field dependencies
180206
$this->setChild(
181207
'form_after',
182-
$this->getLayout()->createBlock(
183-
\Magento\Backend\Block\Widget\Form\Element\Dependence::class
184-
)->addFieldMap(
185-
"is_html_allowed_on_front",
186-
'html_allowed_on_front'
187-
)->addFieldMap(
188-
"frontend_input",
189-
'frontend_input_type'
190-
)->addFieldMap(
191-
"is_searchable",
192-
'searchable'
193-
)->addFieldMap(
194-
"is_visible_in_advanced_search",
195-
'advanced_search'
196-
)->addFieldDependence(
197-
'advanced_search',
198-
'searchable',
199-
'1'
200-
)
208+
$dependencies
201209
);
202210

203211
$this->setForm($form);

app/code/Magento/Catalog/Model/ProductRepository/MediaGalleryProcessor.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public function __construct(
8282
* @throws InputException
8383
* @throws StateException
8484
* @throws LocalizedException
85+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
8586
*/
8687
public function processMediaGallery(ProductInterface $product, array $mediaGalleryEntries) :void
8788
{
@@ -113,6 +114,9 @@ public function processMediaGallery(ProductInterface $product, array $mediaGalle
113114
// phpcs:ignore Magento2.Performance.ForeachArrayMerge
114115
$existingMediaGallery[$key] = array_merge($existingEntry, $updatedEntry);
115116
}
117+
} elseif (!empty($newEntries) && isset($existingEntry['value_id'])) {
118+
//avoid deleting an exiting image while adding a new one
119+
unset($existingMediaGallery[$key]);
116120
} elseif ($this->canRemoveImage($product, $existingEntry)) {
117121
//set the removed flag
118122
$existingEntry['removed'] = true;

app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
* Category resource collection
1717
*
1818
* @api
19-
* @author Magento Core Team <core@magentocommerce.com>
2019
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2120
* @since 100.0.2
2221
*/
@@ -568,8 +567,7 @@ private function getProductsCountFromCategoryTable(Category $item, string $websi
568567
*/
569568
private function getProductsCountQuery(array $categoryIds, $addVisibilityFilter = true): Select
570569
{
571-
$connections = $this->_resource->getConnection();
572-
$categoryTable = $connections->getTableName('catalog_category_product_index');
570+
$categoryTable = $this->_resource->getTableName('catalog_category_product_index');
573571
$select = $this->_conn->select()
574572
->from(
575573
['cat_index' => $categoryTable],

app/code/Magento/Catalog/Test/Mftf/Test/SavingCustomAttributeValuesUsingUITest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
<actionGroup ref="AdminSetProductAttributeUseInLayeredNavigationOptionActionGroup" stepKey="setDropdownUseInLayeredNavigationNoResults">
5656
<argument name="useInLayeredNavigationValue" value="Filterable (with results)"/>
5757
</actionGroup>
58+
<selectOption selector="{{AdvancedAttributePropertiesSection.UseInSearch}}" userInput="Yes" stepKey="selectIsSearchAble"/>
5859
<selectOption selector="{{AttributePropertiesSection.useInSearchResultsLayeredNavigation}}" userInput="Yes" stepKey="selectUseInLayeredNavigationOption"/>
5960
<click stepKey="saveAttribute" selector="{{AttributePropertiesSection.Save}}"/>
6061

app/code/Magento/Catalog/Test/Mftf/Test/StorefrontVerifyCategoryPageNotCachedTest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<!--Login to Admin Panel-->
2323
<actionGroup ref="AdminLoginActionGroup" stepKey="logInAsAdmin"/>
2424
<!-- Create tax rate for CA -->
25-
<createData entity="US_CA_Rate_1" stepKey="createTaxRateCA"/>
25+
<createData entity="TaxRateCalifornia" stepKey="createTaxRateCA"/>
2626
<!-- Create tax rate for TX -->
2727
<createData entity="ThirdTaxRateTexas" stepKey="createTaxRateTX"/>
2828
<!-- Create Tax Rules -->
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Test\Unit\Model\ProductRepository;
9+
10+
use Magento\Catalog\Model\Product;
11+
use Magento\Catalog\Model\Product\Gallery\DeleteValidator;
12+
use Magento\Catalog\Model\Product\Gallery\Processor;
13+
use Magento\Catalog\Model\Product\Media\Config;
14+
use Magento\Catalog\Model\ProductRepository\MediaGalleryProcessor;
15+
use Magento\Framework\Api\Data\ImageContentInterface;
16+
use Magento\Framework\Api\Data\ImageContentInterfaceFactory;
17+
use Magento\Framework\Api\ImageContent;
18+
use Magento\Framework\Api\ImageProcessorInterface;
19+
use PHPUnit\Framework\MockObject\MockObject;
20+
use PHPUnit\Framework\TestCase;
21+
22+
class MediaGalleryProcessorTest extends TestCase
23+
{
24+
/**
25+
* @var MediaGalleryProcessor
26+
*/
27+
private $galleryProcessor;
28+
29+
/**
30+
* @var Processor|MockObject
31+
*/
32+
private $processorMock;
33+
34+
/**
35+
* @var ImageContentInterfaceFactory|MockObject
36+
*/
37+
private $contentFactoryMock;
38+
39+
/**
40+
* @var ImageProcessorInterface|MockObject
41+
*/
42+
private $imageProcessorMock;
43+
44+
/**
45+
* @var DeleteValidator|MockObject
46+
*/
47+
private $deleteValidatorMock;
48+
49+
/**
50+
* @var Product|MockObject
51+
*/
52+
private $productMock;
53+
54+
protected function setUp(): void
55+
{
56+
$this->processorMock = $this->getMockBuilder(Processor::class)
57+
->disableOriginalConstructor()
58+
->getMock();
59+
$this->contentFactoryMock = $this->getMockBuilder(ImageContentInterfaceFactory::class)
60+
->disableOriginalConstructor()
61+
->getMock();
62+
$this->imageProcessorMock = $this->getMockBuilder(ImageProcessorInterface::class)
63+
->disableOriginalConstructor()
64+
->getMock();
65+
$this->deleteValidatorMock = $this->getMockBuilder(DeleteValidator::class)
66+
->disableOriginalConstructor()
67+
->getMock();
68+
$this->productMock = $this->getMockBuilder(Product::class)
69+
->addMethods(['getMediaGallery'])
70+
->onlyMethods(['hasGalleryAttribute', 'getMediaConfig', 'getMediaAttributes'])
71+
->disableOriginalConstructor()
72+
->getMock();
73+
74+
$this->galleryProcessor = new MediaGalleryProcessor(
75+
$this->processorMock,
76+
$this->contentFactoryMock,
77+
$this->imageProcessorMock,
78+
$this->deleteValidatorMock
79+
);
80+
}
81+
82+
/**
83+
* The media gallery array should not have "removed" key while adding the new entry
84+
*
85+
* @return void
86+
*/
87+
public function testProcessMediaGallery(): void
88+
{
89+
$initialExitingEntry = [
90+
'value_id' => 5,
91+
"label" => "new_label_text",
92+
'file' => 'filename1',
93+
'position' => 10,
94+
'disabled' => false,
95+
'types' => ['image', 'small_image']
96+
];
97+
$newEntriesData = [
98+
'images' => [
99+
$initialExitingEntry,
100+
[
101+
'value_id' => null,
102+
'label' => "label_text",
103+
'position' => 10,
104+
'disabled' => false,
105+
'types' => ['image', 'small_image'],
106+
'content' => [
107+
'data' => [
108+
ImageContentInterface::NAME => 'filename',
109+
ImageContentInterface::TYPE => 'image/jpeg',
110+
ImageContentInterface::BASE64_ENCODED_DATA => 'encoded_content'
111+
]
112+
],
113+
'media_type' => 'media_type'
114+
]
115+
]
116+
];
117+
$newExitingEntriesData = [
118+
'images' => [
119+
$initialExitingEntry,
120+
[
121+
'value_id' => 6,
122+
"label" => "label_text2",
123+
'file' => 'filename2',
124+
'position' => 10,
125+
'disabled' => false,
126+
'types' => ['image', 'small_image']
127+
]
128+
]
129+
];
130+
$this->productMock->method('getMediaGallery')
131+
->willReturnOnConsecutiveCalls(
132+
$newExitingEntriesData['images'],
133+
$newExitingEntriesData['images']
134+
);
135+
$this->productMock->expects($this->any())
136+
->method('getMediaAttributes')
137+
->willReturn(["image" => "imageAttribute", "small_image" => "small_image_attribute"]);
138+
$this->productMock->method('hasGalleryAttribute')->willReturn(true);
139+
$mediaTmpPath = '/tmp';
140+
$absolutePath = '/a/b/filename.jpg';
141+
$this->processorMock->expects($this->once())->method('clearMediaAttribute')
142+
->with($this->productMock, ['image', 'small_image']);
143+
$mediaConfigMock = $this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock();
144+
$mediaConfigMock->expects($this->once())->method('getTmpMediaShortUrl')->with($absolutePath)
145+
->willReturn($mediaTmpPath . $absolutePath);
146+
$this->productMock->expects($this->once())->method('getMediaConfig')->willReturn($mediaConfigMock);
147+
//verify new entries
148+
$contentDataObject = $this->getMockBuilder(ImageContent::class)
149+
->disableOriginalConstructor()
150+
->setMethods(null)
151+
->getMock();
152+
$this->contentFactoryMock->expects($this->once())->method('create')->willReturn($contentDataObject);
153+
$this->imageProcessorMock->expects($this->once())->method('processImageContent')->willReturn($absolutePath);
154+
$imageFileUri = $mediaTmpPath . $absolutePath;
155+
$this->processorMock->expects($this->once())->method('addImage')
156+
->willReturnCallback(
157+
function ($product, $imageFileUri) use ($newEntriesData) {
158+
foreach ($product['media_gallery']['images'] as $entry) {
159+
if (isset($entry['value_id'])) {
160+
$this->assertArrayNotHasKey('removed', $entry);
161+
}
162+
}
163+
$this->productMock->setData('media_gallery', $newEntriesData);
164+
return $imageFileUri;
165+
}
166+
);
167+
$this->processorMock->expects($this->once())->method('updateImage')
168+
->with(
169+
$this->productMock,
170+
$imageFileUri,
171+
[
172+
'label' => 'label_text',
173+
'position' => 10,
174+
'disabled' => false,
175+
'media_type' => 'media_type',
176+
]
177+
);
178+
$this->galleryProcessor->processMediaGallery($this->productMock, $newEntriesData['images']);
179+
}
180+
}

app/code/Magento/CatalogInventory/Test/Mftf/Test/StoreFrontAddOutOfStockProductToShoppingCartTest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
<!-- Mouse Hover Product On Category Page-->
6363
<actionGroup ref="StorefrontHoverProductOnCategoryPageActionGroup" stepKey="hoverProduct"/>
6464
<!-- Select Add to cart-->
65+
<waitForElementClickable selector="{{StorefrontCategoryMainSection.addToCartProductBySku($$simpleProductOne.sku$$)}}" stepKey="waitForAddToCartButton"/>
6566
<click selector="{{StorefrontCategoryMainSection.addToCartProductBySku($$simpleProductOne.sku$$)}}" stepKey="toCategory"/>
6667
<waitForElementVisible selector="{{StorefrontProductPageSection.errorMsg}}" stepKey="wait"/>
6768
<!-- Assert the Error Message-->

app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Product/Category/Action/Rows.php

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)