Skip to content

Commit 6ab9b17

Browse files
authored
Merge branch '2.4-develop' into Hammer_247_beta1_scope_09032023
2 parents f5251ef + 3b6828d commit 6ab9b17

File tree

33 files changed

+1024
-319
lines changed

33 files changed

+1024
-319
lines changed

app/code/Magento/Catalog/Test/Mftf/Data/ImageData.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@
4343
<data key="filename">jpg</data>
4444
<data key="file_extension">jpg</data>
4545
</entity>
46+
<entity name="GifImageWithUnusedTransparencyIndex" type="image">
47+
<data key="title" unique="suffix">GifImageWithUnusedTransparencyIndex</data>
48+
<data key="file">transparency_index.gif</data>
49+
<data key="filename">transparency_index</data>
50+
<data key="file_extension">gif</data>
51+
</entity>
4652
<entity name="LargeImage" type="image">
4753
<data key="title" unique="suffix">largeimage</data>
4854
<data key="file">large.jpg</data>

app/code/Magento/Catalog/Test/Mftf/Section/StoreFrontRecentProductSection.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@
1111

1212
<section name="StoreFrontRecentlyViewedProductSection">
1313
<element name="ProductName" type="text" selector="//div[@class='products-grid']/ol/li[position()={{position}}]/div/div[@class='product-item-details']/strong/a" parameterized="true"/>
14+
<element name="ProductPrice" type="text" selector=".price-including-tax .price"/>
1415
</section>
15-
</sections>
16+
</sections>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
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="AdminSimpleProductGifWithUnusedTransparencyImageTest">
11+
<annotations>
12+
<features value="Catalog"/>
13+
<stories value="Using a GIF image with transparency color declared but not used as a product main image should not prevent the product grid from being rendered properly"/>
14+
<title value="Using a GIF image with transparency color declared but not used as a product image"/>
15+
<description value="Using a GIF image with transparency color declared but not used as a product main image should not prevent the product grid from being rendered properly"/>
16+
<severity value="CRITICAL"/>
17+
<useCaseId value="ACP2E-1632"/>
18+
<testCaseId value="AC-8028"/>
19+
<group value="Catalog"/>
20+
</annotations>
21+
22+
<before>
23+
<createData entity="_defaultCategory" stepKey="category"/>
24+
<createData entity="_defaultProduct" stepKey="firstProduct">
25+
<requiredEntity createDataKey="category"/>
26+
</createData>
27+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
28+
</before>
29+
30+
<after>
31+
<deleteData createDataKey="category" stepKey="deletePreReqCategory"/>
32+
<deleteData createDataKey="firstProduct" stepKey="deleteFirstProduct"/>
33+
<actionGroup ref="AdminLogoutActionGroup" stepKey="adminLogout"/>
34+
</after>
35+
36+
<!-- Navigate to the product grid and edit the product -->
37+
<actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="goToProductIndex"/>
38+
<actionGroup ref="FilterProductGridBySkuActionGroup" stepKey="filterProductGridBySku">
39+
<argument name="product" value="$$firstProduct$$"/>
40+
</actionGroup>
41+
<actionGroup ref="OpenProductForEditByClickingRowXColumnYInProductGridActionGroup" stepKey="openProducForEditByClickingRow1Column2InProductGrid"/>
42+
43+
<!-- Set the test GIF image as a main product image and save the product -->
44+
<actionGroup ref="AddProductImageActionGroup" stepKey="addImageForProduct">
45+
<argument name="image" value="GifImageWithUnusedTransparencyIndex"/>
46+
</actionGroup>
47+
<actionGroup ref="AdminProductFormSaveActionGroup" stepKey="saveProduct"/>
48+
49+
<!-- Go back to the product grid and make sure the product is present and visible on the grid -->
50+
<actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="returnToProductIndex"/>
51+
<actionGroup ref="AssertProductOnAdminGridActionGroup" stepKey="assertFirstOnAdminGrid">
52+
<argument name="product" value="_defaultProduct"/>
53+
</actionGroup>
54+
55+
<actionGroup ref="ClearFiltersAdminProductGridActionGroup" stepKey="resetProductGridBeforeLeaving"/>
56+
</test>
57+
</tests>

app/code/Magento/Catalog/Ui/DataProvider/Product/Listing/Collector/Price.php

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
use Magento\Catalog\Api\Data\ProductRender\PriceInfoInterfaceFactory;
1212
use Magento\Catalog\Api\Data\ProductRenderInterface;
1313
use Magento\Catalog\Model\ProductRender\FormattedPriceInfoBuilder;
14+
use Magento\Catalog\Pricing\Price\FinalPrice;
15+
use Magento\Catalog\Pricing\Price\RegularPrice;
1416
use Magento\Catalog\Ui\DataProvider\Product\ProductRenderCollectorInterface;
1517
use Magento\Framework\Pricing\PriceCurrencyInterface;
18+
use Magento\GroupedProduct\Model\Product\Type\Grouped;
1619

1720
/**
1821
* Collect information about base prices of products
@@ -22,18 +25,6 @@
2225
*/
2326
class Price implements ProductRenderCollectorInterface
2427
{
25-
/** FInal Price key */
26-
const KEY_FINAL_PRICE = "final_price";
27-
28-
/** Minimal Price key */
29-
const KEY_MINIMAL_PRICE = "minimal_price";
30-
31-
/** Regular Price key */
32-
const KEY_REGULAR_PRICE = "regular_price";
33-
34-
/** Max Price key */
35-
const KEY_MAX_PRICE = "max_price";
36-
3728
/**
3829
* @var PriceCurrencyInterface
3930
*/
@@ -84,40 +75,49 @@ public function collect(ProductInterface $product, ProductRenderInterface $produ
8475
$priceInfo = $this->priceInfoFactory->create();
8576
}
8677

87-
$priceInfo->setFinalPrice(
88-
$product
89-
->getPriceInfo()
90-
->getPrice('final_price')
91-
->getAmount()
92-
->getValue()
93-
);
94-
$priceInfo->setMinimalPrice(
95-
$product
78+
if ($product->getTypeId() === Grouped::TYPE_CODE) {
79+
$product = $product
9680
->getPriceInfo()
97-
->getPrice('final_price')
98-
->getMinimalPrice()
99-
->getValue()
100-
);
101-
$priceInfo->setRegularPrice(
102-
$product
103-
->getPriceInfo()
104-
->getPrice('regular_price')
105-
->getAmount()
106-
->getValue()
107-
);
108-
$priceInfo->setMaxPrice(
109-
$product
110-
->getPriceInfo()
111-
->getPrice('final_price')
112-
->getMaximalPrice()
113-
->getValue()
114-
);
81+
->getPrice(FinalPrice::PRICE_CODE)
82+
->getMinProduct();
83+
}
11584

116-
$this->formattedPriceInfoBuilder->build(
117-
$priceInfo,
118-
$productRender->getStoreId(),
119-
$productRender->getCurrencyCode()
120-
);
85+
if ($product !== null) {
86+
$priceInfo->setFinalPrice(
87+
$product
88+
->getPriceInfo()
89+
->getPrice(FinalPrice::PRICE_CODE)
90+
->getAmount()
91+
->getValue()
92+
);
93+
$priceInfo->setMinimalPrice(
94+
$product
95+
->getPriceInfo()
96+
->getPrice(FinalPrice::PRICE_CODE)
97+
->getMinimalPrice()
98+
->getValue()
99+
);
100+
$priceInfo->setRegularPrice(
101+
$product
102+
->getPriceInfo()
103+
->getPrice(RegularPrice::PRICE_CODE)
104+
->getAmount()
105+
->getValue()
106+
);
107+
$priceInfo->setMaxPrice(
108+
$product
109+
->getPriceInfo()
110+
->getPrice(FinalPrice::PRICE_CODE)
111+
->getMaximalPrice()
112+
->getValue()
113+
);
114+
115+
$this->formattedPriceInfoBuilder->build(
116+
$priceInfo,
117+
$productRender->getStoreId(),
118+
$productRender->getCurrencyCode()
119+
);
120+
}
121121

122122
$productRender->setPriceInfo($priceInfo);
123123
}

app/code/Magento/Catalog/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"magento/module-ui": "*",
3232
"magento/module-url-rewrite": "*",
3333
"magento/module-widget": "*",
34-
"magento/module-wishlist": "*"
34+
"magento/module-wishlist": "*",
35+
"magento/module-grouped-product": "*"
3536
},
3637
"suggest": {
3738
"magento/module-cookie": "*",

app/code/Magento/Catalog/view/frontend/templates/product/view/opengraph/general.phtml

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,47 @@
44
* See COPYING.txt for license details.
55
*/
66

7-
/** @var $block \Magento\Catalog\Block\Product\View */
7+
use Magento\Catalog\Block\Product\View;
8+
use Magento\Catalog\Model\Product;
9+
use Magento\Catalog\Pricing\Price\FinalPrice;
10+
use Magento\Framework\Escaper;
11+
use Magento\GroupedProduct\Model\Product\Type\Grouped;
12+
13+
/**
14+
* @var View $block
15+
* @var Escaper $escaper
16+
*/
817
?>
918

1019
<meta property="og:type" content="product" />
1120
<meta property="og:title"
12-
content="<?= $block->escapeHtmlAttr($block->stripTags($block->getProduct()->getName())) ?>" />
21+
content="<?= $escaper->escapeHtmlAttr($block->stripTags($block->getProduct()->getName())) ?>" />
1322
<meta property="og:image"
14-
content="<?= $block->escapeUrl($block->getImage($block->getProduct(), 'product_base_image')->getImageUrl()) ?>" />
23+
content="<?= $escaper->escapeUrl($block->getImage($block->getProduct(), 'product_base_image')->getImageUrl()) ?>"
24+
/>
1525
<meta property="og:description"
16-
content="<?= $block->escapeHtmlAttr($block->stripTags($block->getProduct()->getShortDescription())) ?>" />
26+
content="<?= $escaper->escapeHtmlAttr($block->stripTags($block->getProduct()->getShortDescription())) ?>" />
1727
<meta property="og:url" content="<?= $block->escapeUrl($block->getProduct()->getProductUrl()) ?>" />
18-
<?php if ($priceAmount = $block->getProduct()
19-
->getPriceInfo()
20-
->getPrice(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)
21-
->getAmount()):?>
22-
<meta property="product:price:amount" content="<?= $block->escapeHtmlAttr($priceAmount) ?>"/>
23-
<?= $block->getChildHtml('meta.currency') ?>
28+
<?php
29+
if ($block->getProduct()->getTypeId() === Grouped::TYPE_CODE):
30+
/** @var Product $minProduct */
31+
$minProduct = $block->getProduct()
32+
->getPriceInfo()
33+
->getPrice(FinalPrice::PRICE_CODE)
34+
->getMinProduct();
35+
36+
$priceAmount = ($minProduct !== null) ? $minProduct->getPriceInfo()
37+
->getPrice(FinalPrice::PRICE_CODE)
38+
->getAmount() : $minProduct;
39+
else:
40+
$priceAmount = $block->getProduct()
41+
->getPriceInfo()
42+
->getPrice(FinalPrice::PRICE_CODE)
43+
->getAmount();
44+
endif;
45+
?>
46+
47+
<?php if ($priceAmount !== null): ?>
48+
<meta property="product:price:amount" content="<?= $block->escapeHtmlAttr($priceAmount) ?>"/>
49+
<?= $block->getChildHtml('meta.currency') ?>
2450
<?php endif;?>

app/code/Magento/CatalogGraphQl/Model/Resolver/Categories.php

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
class Categories implements ResolverInterface
2828
{
2929
/**
30-
* @var Collection
30+
* @var CollectionFactory
3131
*/
32-
private $collection;
32+
private $collectionFactory;
3333

3434
/**
3535
* Accumulated category ids
@@ -68,6 +68,11 @@ class Categories implements ResolverInterface
6868
*/
6969
private $storeManager;
7070

71+
/**
72+
* @var array
73+
*/
74+
private $collections = [];
75+
7176
/**
7277
* @param CollectionFactory $collectionFactory
7378
* @param AttributesJoiner $attributesJoiner
@@ -86,7 +91,7 @@ public function __construct(
8691
ProductCategories $productCategories,
8792
StoreManagerInterface $storeManager
8893
) {
89-
$this->collection = $collectionFactory->create();
94+
$this->collectionFactory = $collectionFactory;
9095
$this->attributesJoiner = $attributesJoiner;
9196
$this->customAttributesFlattener = $customAttributesFlattener;
9297
$this->valueFactory = $valueFactory;
@@ -120,12 +125,9 @@ function () use ($that, $categoryIds, $info) {
120125
return [];
121126
}
122127

123-
if (!$this->collection->isLoaded()) {
124-
$that->attributesJoiner->join($info->fieldNodes[0], $this->collection, $info);
125-
$this->collection->addIdFilter($this->categoryIds);
126-
}
128+
$collection = $this->getCollection($that, $info);
127129
/** @var CategoryInterface | \Magento\Catalog\Model\Category $item */
128-
foreach ($this->collection as $item) {
130+
foreach ($collection as $item) {
129131
if (in_array($item->getId(), $categoryIds)) {
130132
// Try to extract all requested fields from the loaded collection data
131133
$categories[$item->getId()] = $this->categoryHydrator->hydrateCategory($item, true);
@@ -146,4 +148,25 @@ function () use ($that, $categoryIds, $info) {
146148
}
147149
);
148150
}
151+
152+
/**
153+
* Returns category collection.
154+
*
155+
* @param Categories $that
156+
* @param ResolveInfo $info
157+
* @return Collection
158+
*/
159+
private function getCollection(Categories $that, ResolveInfo $info): Collection
160+
{
161+
$requestedFields = $that->attributesJoiner->getQueryFields($info->fieldNodes[0], $info);
162+
sort($requestedFields);
163+
$requestedFieldsHash = sha1(implode(',', $requestedFields));
164+
if (!isset($this->collections[$requestedFieldsHash])) {
165+
$this->collections[$requestedFieldsHash] = $this->collectionFactory->create();
166+
$that->attributesJoiner->join($info->fieldNodes[0], $this->collections[$requestedFieldsHash], $info);
167+
$this->collections[$requestedFieldsHash]->addIdFilter($this->categoryIds);
168+
}
169+
170+
return $this->collections[$requestedFieldsHash];
171+
}
149172
}

app/code/Magento/Cms/Block/Adminhtml/Block/Widget/Chooser.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public function getRowClickCallback()
100100
$js = '
101101
function (grid, event) {
102102
var trElement = Event.findElement(event, "tr");
103-
var blockId = trElement.down("td").innerHTML.replace(/^\s+|\s+$/g,"");
103+
var blockId = trElement.down("td").next().next().innerHTML.replace(/^\s+|\s+$/g,"");
104104
var blockTitle = trElement.down("td").next().innerHTML;
105105
' .
106106
$chooserJsObject .
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
10+
<actionGroup name="AdminAssertCMSPageContentParamValueActionGroup">
11+
<annotations>
12+
<description>Assert content param with value on CMS page.</description>
13+
</annotations>
14+
<arguments>
15+
<argument name="param" type="string"/>
16+
<argument name="value" type="string"/>
17+
</arguments>
18+
19+
<grabValueFrom selector="{{CmsNewPagePageActionsSection.content}}" stepKey="grabContent"/>
20+
<assertStringContainsString stepKey="assertClass">
21+
<actualResult type="string">{$grabContent}</actualResult>
22+
<expectedResult type="string">{{param}}=&quot;{{value}}&quot;</expectedResult>
23+
</assertStringContainsString>
24+
</actionGroup>
25+
</actionGroups>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
10+
<actionGroup name="AdminClickSelectBlockActionGroup">
11+
<annotations>
12+
<description>Click on Select Block button.</description>
13+
</annotations>
14+
15+
<waitForElementVisible selector="{{WidgetSection.BtnChooser}}" stepKey="waitForSelectBlockButtonVisible"/>
16+
<click selector="{{WidgetSection.BtnChooser}}" stepKey="clickSelectBlockBtn"/>
17+
<waitForLoadingMaskToDisappear stepKey="waitForLoading"/>
18+
</actionGroup>
19+
</actionGroups>

0 commit comments

Comments
 (0)