Skip to content

Commit 4ec5d38

Browse files
Merge branch '2.4-develop' into cia-2.4.8-develop-2.4-develop-sync-02212025
2 parents aa1c12c + 9c05217 commit 4ec5d38

File tree

128 files changed

+4375
-3661
lines changed

Some content is hidden

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

128 files changed

+4375
-3661
lines changed

app/code/Magento/AdvancedSearch/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ The Magento_AdvancedSearch module introduces advanced search functionality and p
77
Before disabling or uninstalling this module, note that the following modules depends on this module:
88

99
- Magento_Elasticsearch
10-
- Magento_Elasticsearch7
10+
- Magento_Elasticsearch8
1111

1212
For information about module installation in Magento 2, see [Enable or disable modules](https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/tutorials/manage-modules.html).
1313

app/code/Magento/Backend/Test/Mftf/Section/AdminMessagesSection.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88

@@ -25,5 +25,7 @@
2525
<element name="noticeMessage" type="text" selector=".message-notice"/>
2626
<element name="assertCacheManagementConfigurationStatus" type="button" selector="//td[@data-column='tags' and contains(text(),'CONFIG')]/following-sibling::td//span[@class='grid-severity-notice']//span"/>
2727
<element name="assertCacheManagementLayoutsStatus" type="button" selector="//td[@data-column='tags' and contains(text(),'LAYOUT_GENERAL_CACHE_TAG')]/following-sibling::td//span[@class='grid-severity-notice']//span"/>
28+
<element name="assertCacheManagementStatusEnabled" type="button" selector="//td[@data-column='tags' and contains(text(),'{{cache}}')]/following-sibling::td//span[@class='grid-severity-notice']//span" parameterized="true"/>
29+
<element name="assertCacheManagementStatusInvalidated" type="button" selector="//td[@data-column='tags' and contains(text(),'{{cacheType}}')]/following-sibling::td//span[@class='grid-severity-minor']//span" parameterized="true"/>
2830
</section>
2931
</sections>
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
6+
*/
7+
-->
8+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
10+
<test name="AdminValidateEAVTypesAndAttributesConfigurationTest">
11+
<annotations>
12+
<features value="Cache"/>
13+
<stories value="Cache Management"/>
14+
<title value="Validate EAVTypes And Attributes Cache Type"/>
15+
<description value="Validate EAVTypes And Attributes Cache Type After Cache Management"/>
16+
<severity value="MAJOR"/>
17+
<testCaseId value="AC-3833"/>
18+
</annotations>
19+
<before>
20+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
21+
<actionGroup ref="AdminGoToCacheManagementPageActionGroup" stepKey="goToCacheManagementPage"/>
22+
<!--Verify Cache Type EAV Types And Attributes Is ENABLED -->
23+
<waitForText selector="{{AdminMessagesSection.assertCacheManagementStatusEnabled('EAV')}}" userInput="ENABLED" stepKey="verifyCacheTypeEAVTypesAndAttributesIsENABLED"/>
24+
</before>
25+
<after>
26+
<!--Delete created entity -->
27+
<deleteData createDataKey="createSimpleProduct" stepKey="deleteFirstProduct"/>
28+
<actionGroup ref="NavigateToEditProductAttributeActionGroup" stepKey="goToEditPage">
29+
<argument name="ProductAttribute" value="{{multiselectProductAttribute.attribute_code}}"/>
30+
</actionGroup>
31+
<actionGroup ref="DeleteProductAttributeByAttributeCodeActionGroup" stepKey="deleteProductAttribute"/>
32+
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex">
33+
<argument name="indices" value=""/>
34+
</actionGroup>
35+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
36+
</after>
37+
<!-- Create Simple Product -->
38+
<createData entity="SimpleProduct" stepKey="createSimpleProduct"/>
39+
<!--Navigate to Stores > Attributes > Product.-->
40+
<actionGroup ref="AdminOpenProductAttributePageActionGroup" stepKey="goToProductAttributes"/>
41+
<!--Create new Product Attribute as TextField, with code and default value.-->
42+
<actionGroup ref="CreateProductAttributeActionGroup" stepKey="createAttribute">
43+
<argument name="attribute" value="multiselectProductAttribute"/>
44+
</actionGroup>
45+
<!--Navigate to Product Attribute, add Product Options and Save - 1-->
46+
<actionGroup ref="NavigateToEditProductAttributeActionGroup" stepKey="goToEditPage1">
47+
<argument name="ProductAttribute" value="{{multiselectProductAttribute.attribute_code}}"/>
48+
</actionGroup>
49+
<actionGroup ref="CreateAttributeDropdownNthOptionActionGroup" stepKey="createOption1">
50+
<argument name="adminName" value="{{multiselectProductAttribute.option1_admin}}"/>
51+
<argument name="frontName" value="{{multiselectProductAttribute.option1_frontend}}"/>
52+
<argument name="row" value="1"/>
53+
</actionGroup>
54+
<actionGroup ref="AdminSetProductAttributeUseInLayeredNavigationOptionActionGroup" stepKey="setDropdownUseInLayeredNavigationNoResults">
55+
<argument name="useInLayeredNavigationValue" value="Filterable (with results)"/>
56+
</actionGroup>
57+
<selectOption selector="{{AdvancedAttributePropertiesSection.UseInSearch}}" userInput="Yes" stepKey="selectIsSearchAble"/>
58+
<selectOption selector="{{AttributePropertiesSection.useInSearchResultsLayeredNavigation}}" userInput="Yes" stepKey="selectUseInLayeredNavigationOption"/>
59+
<click stepKey="saveAttribute" selector="{{AttributePropertiesSection.Save}}"/>
60+
<!-- Open created product for edit -->
61+
<actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="goToProductEditPage">
62+
<argument name="productId" value="$createSimpleProduct.id$"/>
63+
</actionGroup>
64+
<waitForPageLoad stepKey="waitForProductPageLoad"/>
65+
<click selector="{{AdminProductFormSection.addAttributeBtn}}" stepKey="clickAddAttributeBtn"/>
66+
<waitForPageLoad stepKey="waitForAttributeAdded"/>
67+
<!-- Filter By Attribute Label on Add Attribute Page -->
68+
<click selector="{{AdminProductFiltersSection.filter}}" stepKey="clickOnFilter"/>
69+
<fillField selector="{{AdminProductAddAttributeModalSection.attributeCodeFilter}}" userInput="{{multiselectProductAttribute.attribute_code}}" stepKey="fillAttrCodeField" />
70+
<click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="clickSearchBtn" />
71+
<click stepKey="clickonFirstRow" selector="{{AdminProductAddAttributeModalSection.firstRowCheckBox}}"/>
72+
<click stepKey="clickOnAddSelected" selector="{{AdminProductAttributeGridSection.addSelected}}"/>
73+
<waitForPageLoad stepKey="waitForAttributeAdded2"/>
74+
<!-- Expand 'Attributes' tab -->
75+
<actionGroup ref="AdminExpandProductAttributesTabActionGroup" stepKey="expandAttributesTab"/>
76+
<!-- Check created attribute presents in the 'Attributes' tab -->
77+
<waitForElementVisible selector="{{AdminProductAttributesSection.attributeDropdownByCode(multiselectProductAttribute.attribute_code)}}" stepKey="assertAttributeIsPresentInTab"/>
78+
<!-- Select attribute options -->
79+
<selectOption selector="{{AdminProductAttributesSection.attributeDropdownByCode(multiselectProductAttribute.attribute_code)}}" userInput="{{multiselectProductAttribute.option1_admin}}" stepKey="selectProduct1AttributeOption"/>
80+
<!-- Save product -->
81+
<actionGroup ref="SaveProductFormActionGroup" stepKey="saveProductForm"/>
82+
<!--Verify Cache Type Page Cache Is INVALIDATED -->
83+
<actionGroup ref="AdminGoToCacheManagementPageActionGroup" stepKey="goToCacheManagementPageAgain"/>
84+
<waitForText selector="{{AdminMessagesSection.assertCacheManagementStatusInvalidated('FPC')}}" userInput="INVALIDATED" stepKey="verifyCacheTypePageCacheIsInvalidated"/>
85+
<!--Flush Cache -->
86+
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex">
87+
<argument name="indices" value=""/>
88+
</actionGroup>
89+
<actionGroup ref="CliCacheCleanActionGroup" stepKey="flushCache">
90+
<argument name="tags" value="full_page"/>
91+
</actionGroup>
92+
<!--Verify Cache Type Page Cache s Is Enabled -->
93+
<actionGroup ref="AdminGoToCacheManagementPageActionGroup" stepKey="goToCacheManagementPageAgain1"/>
94+
<waitForText selector="{{AdminMessagesSection.assertCacheManagementStatusEnabled('FPC')}}" userInput="ENABLED" stepKey="verifyCacheTypePageCacheIsENABLED"/>
95+
<!-- Go to Storefront and search for product-->
96+
<actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToFrontPage"/>
97+
<actionGroup ref="StorefrontCheckQuickSearchStringActionGroup" stepKey="searchStorefront">
98+
<argument name="phrase" value="$createSimpleProduct.name$"/>
99+
</actionGroup>
100+
<!-- Assert custom Attribute in Layered Navigation-->
101+
<waitForElementVisible selector="{{StorefrontCategorySidebarSection.filterOptionsTitle(multiselectProductAttribute.attribute_code)}}" stepKey="waitForAttributeVisible"/>
102+
<conditionalClick selector="{{StorefrontCategorySidebarSection.filterOptionsTitle(multiselectProductAttribute.attribute_code)}}" dependentSelector="{{StorefrontCategorySidebarSection.activeFilterOptions}}" visible="false" stepKey="clickToExpandAttribute"/>
103+
<waitForElementVisible selector="{{StorefrontCategorySidebarSection.activeFilterOptions}}" stepKey="waitForAttributeOptionsVisible"/>
104+
</test>
105+
</tests>

app/code/Magento/Captcha/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"magento/module-store": "*",
1515
"magento/module-authorization": "*",
1616
"laminas/laminas-captcha": "^2.18",
17-
"magento/laminas-db": "^1.0.0"
17+
"magento/magento-zf-db": "^3.21"
1818
},
1919
"type": "magento2-module",
2020
"license": [

app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
namespace Magento\Catalog\Model\Product\Option\Type\File;
99

10-
use Laminas\Filter\File\Rename;
11-
use Laminas\File\Transfer\Exception\PhpEnvironmentException;
1210
use Magento\Catalog\Model\Product;
1311
use Magento\Catalog\Model\Product\Exception as ProductException;
1412
use Magento\Framework\App\Filesystem\DirectoryList;
@@ -126,7 +124,6 @@ public function setProduct(Product $product)
126124
* @throws \Exception
127125
* @throws \Magento\Framework\Exception\InputException
128126
* @throws \Magento\Framework\Validator\Exception
129-
* @throws PhpEnvironmentException
130127
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
131128
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
132129
*/
@@ -184,8 +181,6 @@ public function validate($processingParams, $option)
184181
$filePath = $dispersion . '/' . $fileName;
185182
$fileFullPath = $this->mediaDirectory->getAbsolutePath($this->quotePath . $filePath);
186183

187-
$upload->addFilter(new Rename(['target' => $fileFullPath, 'overwrite' => true]));
188-
189184
if ($this->product !== null) {
190185
$this->product->getTypeInstance()->addFileQueue(
191186
[
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Catalog\Plugin\Model;
10+
11+
use Magento\Catalog\Api\Data\CategoryInterface;
12+
use Magento\Catalog\Model\CategoryRepository;
13+
14+
/**
15+
* Plugin for category repository
16+
*/
17+
class CategoryRepositoryPlugin
18+
{
19+
private const ATTRIBUTES_TO_PROCESS = [
20+
'url_key',
21+
'url_path'
22+
];
23+
24+
/**
25+
* Formats category url key and path using the default formatter.
26+
*
27+
* @param CategoryRepository $subject
28+
* @param CategoryInterface $category
29+
* @return array
30+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
31+
*/
32+
public function beforeSave(CategoryRepository $subject, CategoryInterface $category): array
33+
{
34+
foreach (self::ATTRIBUTES_TO_PROCESS as $attributeKey) {
35+
$attribute = $category->getCustomAttribute($attributeKey);
36+
if ($attribute !== null) {
37+
$value = $category->getData($attributeKey);
38+
$formattedValue = $category->formatUrlKey($value);
39+
$attribute->setValue($formattedValue);
40+
}
41+
}
42+
return [$category];
43+
}
44+
}

app/code/Magento/Catalog/Test/Mftf/Test/AdminApplyTierPriceToProductTest/StoreFrontDeleteProductImagesAssignedDifferentRolesTest.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2025 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88

@@ -77,7 +77,7 @@
7777
<!-- Go to the product page on StoreFront and see the Base image -->
7878
<amOnPage url="{{StorefrontProductPage.url($simpleProductOne.custom_attributes[url_key]$)}}" stepKey="goToProductPage"/>
7979
<waitForPageLoad stepKey="waitForPageLoad"/>
80-
<seeElement selector="{{StorefrontProductMediaSection.imageFile('/adobe-base')}}" stepKey="seeBaseImageOnProductPage"/>
80+
<seeElement selector="{{StorefrontProductMediaSection.imageFile(TestImageAdobe.filename)}}" stepKey="seeBaseImageOnProductPage"/>
8181
<!-- Go to the category page and see the Small image -->
8282
<amOnPage url="{{StorefrontCategoryPage.url($testCategory.custom_attributes[url_key]$)}}" stepKey="goToCategoryPage"/>
8383
<waitForPageLoad stepKey="waitForPageLoadingToFinish"/>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Test\Unit\Plugin\Model;
9+
10+
use Magento\Catalog\Plugin\Model\CategoryRepositoryPlugin;
11+
use Magento\Catalog\Model\CategoryRepository;
12+
use PHPUnit\Framework\TestCase;
13+
use PHPUnit\Framework\MockObject\MockObject;
14+
use Magento\Framework\Api\AttributeInterface;
15+
use Magento\Catalog\Model\Category;
16+
17+
class CategoryRepositoryPluginTest extends TestCase
18+
{
19+
/**
20+
* @var CategoryRepositoryPlugin
21+
*/
22+
private $categoryRepositoryPluginMock;
23+
24+
/**
25+
* @var CategoryRepository|MockObject
26+
*/
27+
private $categoryRepositoryMock;
28+
29+
/**
30+
* @var Category|MockObject
31+
*/
32+
private $categoryMock;
33+
34+
protected function setUp(): void
35+
{
36+
$this->categoryRepositoryMock = $this->createMock(CategoryRepository::class);
37+
$this->categoryMock = $this->createMock(Category::class);
38+
$this->categoryRepositoryPluginMock = new CategoryRepositoryPlugin();
39+
}
40+
41+
/**
42+
* Test beforeSave method
43+
*/
44+
public function testBeforeSave()
45+
{
46+
$attributeMock = $this->createMock(AttributeInterface::class);
47+
$urlKey = 'new test Cat (1)!';
48+
$formattedUrlKey = 'new-test-cat-1';
49+
$this->categoryMock->method('getCustomAttribute')
50+
->willReturnMap([
51+
['url_key', $attributeMock],
52+
['url_path', $attributeMock],
53+
]);
54+
55+
$this->categoryMock->method('getData')
56+
->willReturn($urlKey);
57+
58+
$this->categoryMock->method('formatUrlKey')
59+
->willReturn($formattedUrlKey);
60+
61+
$result = $this->categoryRepositoryPluginMock->beforeSave($this->categoryRepositoryMock, $this->categoryMock);
62+
$this->assertSame([$this->categoryMock], $result);
63+
}
64+
}

app/code/Magento/Catalog/etc/webapi_rest/di.xml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2014 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88

@@ -44,4 +44,7 @@
4444
<plugin name="reindex_after_save_product_links" type="Magento\Catalog\Plugin\Api\ProductLinkRepositoryInterface\ReindexAfterSaveProductLinksPlugin"/>
4545
<plugin name="reindex_after_delete_by_id_product_links" type="Magento\Catalog\Plugin\Api\ProductLinkRepositoryInterface\ReindexAfterDeleteByIdProductLinksPlugin"/>
4646
</type>
47+
<type name="Magento\Catalog\Model\CategoryRepository">
48+
<plugin name="format_category_url_key_rest_api" type="Magento\Catalog\Plugin\Model\CategoryRepositoryPlugin" />
49+
</type>
4750
</config>
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88

@@ -11,7 +11,7 @@
1111
<entity name="SimpleTerm" type="searchTerm">
1212
<data key="search_query" unique="suffix">Query text</data>
1313
<data key="store_id">Default Store View</data>
14-
<data key="redirect" unique="suffix">http://example.com/</data>
14+
<data key="redirect" unique="suffix">https://example.com/</data>
1515
<data key="display_in_terms">No</data>
1616
</entity>
17-
</entities>
17+
</entities>

0 commit comments

Comments
 (0)