Skip to content

Commit f104c89

Browse files
authored
Merge pull request #6740 from magento-tsg/2.4-develop-pr137
[Arrows] Fixes for 2.4 (pr137) (2.4-develop)
2 parents 613577d + 7ed47a8 commit f104c89

23 files changed

+983
-82
lines changed

app/code/Magento/Bundle/Model/Product/LinksList.php

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,22 @@
44
* Copyright © Magento, Inc. All rights reserved.
55
* See COPYING.txt for license details.
66
*/
7+
declare(strict_types=1);
8+
79
namespace Magento\Bundle\Model\Product;
810

11+
use Magento\Bundle\Api\Data\LinkInterface;
12+
use Magento\Bundle\Api\Data\LinkInterfaceFactory;
13+
use Magento\Catalog\Api\Data\ProductInterface;
14+
use Magento\Framework\Api\DataObjectHelper;
15+
16+
/**
17+
* Retrieve bundle product links service.
18+
*/
919
class LinksList
1020
{
1121
/**
12-
* @var \Magento\Bundle\Api\Data\LinkInterfaceFactory
22+
* @var LinkInterfaceFactory
1323
*/
1424
protected $linkFactory;
1525

@@ -19,52 +29,52 @@ class LinksList
1929
protected $type;
2030

2131
/**
22-
* @var \Magento\Framework\Api\DataObjectHelper
32+
* @var DataObjectHelper
2333
*/
2434
protected $dataObjectHelper;
2535

2636
/**
27-
* @param \Magento\Bundle\Api\Data\LinkInterfaceFactory $linkFactory
37+
* @param LinkInterfaceFactory $linkFactory
2838
* @param Type $type
29-
* @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
39+
* @param DataObjectHelper $dataObjectHelper
3040
*/
3141
public function __construct(
32-
\Magento\Bundle\Api\Data\LinkInterfaceFactory $linkFactory,
33-
\Magento\Bundle\Model\Product\Type $type,
34-
\Magento\Framework\Api\DataObjectHelper $dataObjectHelper
42+
LinkInterfaceFactory $linkFactory,
43+
Type $type,
44+
DataObjectHelper $dataObjectHelper
3545
) {
3646
$this->linkFactory = $linkFactory;
3747
$this->type = $type;
3848
$this->dataObjectHelper = $dataObjectHelper;
3949
}
4050

4151
/**
42-
* Bundle Product Items Data
52+
* Get Bundle Product Items Data.
4353
*
44-
* @param \Magento\Catalog\Api\Data\ProductInterface $product
54+
* @param ProductInterface $product
4555
* @param int $optionId
46-
* @return \Magento\Bundle\Api\Data\LinkInterface[]
56+
* @return LinkInterface[]
4757
*/
48-
public function getItems(\Magento\Catalog\Api\Data\ProductInterface $product, $optionId)
58+
public function getItems(ProductInterface $product, $optionId)
4959
{
5060
$selectionCollection = $this->type->getSelectionsCollection([$optionId], $product);
5161

5262
$productLinks = [];
5363
/** @var \Magento\Catalog\Model\Product $selection */
5464
foreach ($selectionCollection as $selection) {
55-
$bundledProductPrice = $selection->getSelectionPriceValue();
56-
if ($bundledProductPrice <= 0) {
57-
$bundledProductPrice = $selection->getPrice();
58-
}
59-
$selectionPriceType = $product->getPriceType() ? $selection->getSelectionPriceType() : null;
60-
$selectionPrice = $bundledProductPrice ? $bundledProductPrice : null;
65+
$priceType = $product->getPriceType();
66+
$selectionPriceType = $priceType ? $selection->getSelectionPriceType() : null;
67+
$selectionPriceValue = $selection->getSelectionPriceValue() < 0
68+
? $selection->getPrice()
69+
: $selection->getSelectionPriceValue();
70+
$selectionPrice = $priceType ? $selectionPriceValue : $selection->getPrice();
6171

62-
/** @var \Magento\Bundle\Api\Data\LinkInterface $productLink */
72+
/** @var LinkInterface $productLink */
6373
$productLink = $this->linkFactory->create();
6474
$this->dataObjectHelper->populateWithArray(
6575
$productLink,
6676
$selection->getData(),
67-
\Magento\Bundle\Api\Data\LinkInterface::class
77+
LinkInterface::class
6878
);
6979
$productLink->setIsDefault($selection->getIsDefault())
7080
->setId($selection->getSelectionId())

app/code/Magento/Bundle/Test/Unit/Model/Product/LinksListTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public function testLinksList()
9595
$this->selectionMock->expects($this->once())
9696
->method('getSelectionPriceType')
9797
->willReturn('selection_price_type');
98-
$this->selectionMock->expects($this->once())->method('getSelectionPriceValue')->willReturn(12);
98+
$this->selectionMock->expects($this->exactly(2))->method('getSelectionPriceValue')->willReturn(12);
9999
$this->selectionMock->expects($this->once())->method('getData')->willReturn(['some data']);
100100
$this->selectionMock->expects($this->once())->method('getSelectionId')->willReturn($selectionId);
101101
$this->selectionMock->expects($this->once())->method('getIsDefault')->willReturn(true);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,8 @@ private function joinPositionField(
914914
foreach ($searchCriteria->getFilterGroups() as $filterGroup) {
915915
foreach ($filterGroup->getFilters() as $filter) {
916916
if ($filter->getField() === 'category_id') {
917-
$categoryIds[] = explode(',', $filter->getValue());
917+
$filterValue = $filter->getValue();
918+
$categoryIds[] = is_array($filterValue) ? $filterValue : explode(',', $filterValue);
918919
}
919920
}
920921
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminChangeSeoUrlKeyToDefaultValueWithoutRedirectActionGroup">
12+
<annotations>
13+
<description>Requires navigation to category creation/edit page. Selects 'Use Default Value' checkbox for the 'URL Key' with 'Create Permanent Redirect for old URL' unchecked.</description>
14+
</annotations>
15+
16+
<conditionalClick selector="{{AdminCategorySEOSection.SectionHeader}}" dependentSelector="{{AdminCategorySEOSection.UrlKeyInput}}" visible="false" stepKey="clickOnSEOTab"/>
17+
<waitForElementVisible selector="{{AdminCategorySEOSection.UrlKeyInput}}" stepKey="waitForSEOTabOpened"/>
18+
<clearField selector="{{AdminCategorySEOSection.UrlKeyInput}}" stepKey="clearUrlKeyField"/>
19+
<uncheckOption selector="{{AdminCategorySEOSection.UrlKeyRedirectCheckbox}}" stepKey="uncheckRedirectCheckbox"/>
20+
<checkOption selector="{{AdminCategorySEOSection.UrlKeyDefaultValueCheckbox}}" stepKey="checkUseDefaultValueCheckbox"/>
21+
</actionGroup>
22+
</actionGroups>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AssertStorefrontAttributeOptionQuantityInLayeredNavigationActionGroup" extends="AssertStorefrontAttributeOptionPresentInLayeredNavigationActionGroup">
12+
<annotations>
13+
<description>Asserts visible attribute option quantity</description>
14+
</annotations>
15+
<arguments>
16+
<argument name="attributeOptionQuantity" type="string" defaultValue="1"/>
17+
</arguments>
18+
<see selector="{{StorefrontCategorySidebarSection.visibleOptionQty(attributeOptionPosition)}}" userInput="{{attributeOptionQuantity}}" after="assertAttributeOptionInLayeredNavigation" stepKey="assertOptionQuantity"/>
19+
</actionGroup>
20+
</actionGroups>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="StorefrontAssertSubCategoryNameIsNotShownInMenuActionGroup" extends="StorefrontAssertCategoryNameIsNotShownInMenuActionGroup">
12+
<annotations>
13+
<description>Validate that the subcategory is not present in menu on Frontend.</description>
14+
</annotations>
15+
<arguments>
16+
<argument name="parentCategoryName" type="string"/>
17+
</arguments>
18+
<moveMouseOver selector="{{StorefrontHeaderSection.NavigationCategoryByName(parentCategoryName)}}" before="doNotSeeCatergoryInStoreFront" stepKey="showSubCategories"/>
19+
</actionGroup>
20+
</actionGroups>

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
<element name="filterOptionByLabel" type="button" selector=" div.filter-options-item div[data-option-label='{{optionLabel}}']" parameterized="true"/>
1717
<element name="removeFilter" type="button" selector="div.filter-current .remove" timeout="30"/>
1818
<element name="activeFilterOptions" type="text" selector=".filter-options-item.active .items"/>
19-
<element name="activeFilterOptionItemByPosition" type="text" selector=".filter-options-item.active .items li:nth-child({{itemPosition}}) a" parameterized="true"/>
19+
<element name="activeFilterOptionItemByPosition" type="text" selector=".filter-options-item.active .items li:nth-child({{itemPosition}}) a" parameterized="true" timeout="30"/>
2020
<element name="enabledFilterOptionItemByLabel" type="text" selector="//div[@class='filter-options']//li[@class='item']//a[contains(text(), '{{optionLabel}}')]" parameterized="true" timeout="30"/>
2121
<element name="disabledFilterOptionItemByLabel" type="text" selector="//div[@class='filter-options']//li[@class='item' and contains(text(), '{{optionLabel}}')]" parameterized="true" timeout="30"/>
22+
<element name="visibleOptionQty" type="text" selector=".filter-options-item.active .items li:nth-child({{itemPosition}}) a .count" parameterized="true" timeout="30"/>
2223
</section>
2324
</sections>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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\CatalogUrlRewrite\Model\ResourceModel\Category;
9+
10+
use Magento\Catalog\Api\Data\CategoryInterface;
11+
use Magento\Catalog\Model\Category;
12+
use Magento\Eav\Model\Config as EavConfig;
13+
use Magento\Framework\App\ResourceConnection;
14+
use Magento\Framework\DB\Select;
15+
use Magento\Framework\EntityManager\MetadataPool;
16+
use Magento\Store\Model\Store;
17+
18+
/**
19+
* Fetch category 'url_key' default value from the database.
20+
*/
21+
class GetDefaultUrlKey
22+
{
23+
/**
24+
* @var MetadataPool
25+
*/
26+
private $metadataPool;
27+
28+
/**
29+
* @var ResourceConnection
30+
*/
31+
private $resourceConnection;
32+
33+
/**
34+
* @var EavConfig
35+
*/
36+
private $eavConfig;
37+
38+
/**
39+
* @param MetadataPool $metadataPool
40+
* @param ResourceConnection $resourceConnection
41+
* @param EavConfig $eavConfig
42+
*/
43+
public function __construct(
44+
MetadataPool $metadataPool,
45+
ResourceConnection $resourceConnection,
46+
EavConfig $eavConfig
47+
) {
48+
$this->metadataPool = $metadataPool;
49+
$this->resourceConnection = $resourceConnection;
50+
$this->eavConfig = $eavConfig;
51+
}
52+
53+
/**
54+
* Retrieve 'url_key' value for default store.
55+
*
56+
* @param int $categoryId
57+
* @return string|null
58+
*/
59+
public function execute(int $categoryId): ?string
60+
{
61+
$metadata = $this->metadataPool->getMetadata(CategoryInterface::class);
62+
$entityTypeId = $this->eavConfig->getEntityType(Category::ENTITY)->getId();
63+
$linkField = $metadata->getLinkField();
64+
$whereConditions = [
65+
'e.entity_type_id = ' . $entityTypeId,
66+
"e.attribute_code = 'url_key'",
67+
'c.' . $linkField . ' = ' . $categoryId,
68+
'c.store_id = ' . Store::DEFAULT_STORE_ID,
69+
];
70+
$connection = $this->resourceConnection->getConnection();
71+
$select = $connection->select()
72+
->from(['c' => $this->resourceConnection->getTableName('catalog_category_entity_varchar')])
73+
->joinLeft(
74+
['e' => $this->resourceConnection->getTableName('eav_attribute')],
75+
'e.attribute_id = c.attribute_id'
76+
)
77+
->reset(Select::COLUMNS)
78+
->columns(['c.value'])
79+
->where(implode(' AND ', $whereConditions));
80+
81+
return $connection->fetchOne($select) ?: null;
82+
}
83+
}

app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
use Magento\Catalog\Model\Category;
1212
use Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider;
1313
use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator;
14+
use Magento\CatalogUrlRewrite\Model\ResourceModel\Category\GetDefaultUrlKey;
1415
use Magento\CatalogUrlRewrite\Service\V1\StoreViewService;
16+
use Magento\Framework\Event\Observer;
1517
use Magento\Framework\Event\ObserverInterface;
1618
use Magento\Framework\Exception\LocalizedException;
1719
use Magento\Framework\Exception\NoSuchEntityException;
@@ -49,35 +51,43 @@ class CategoryUrlPathAutogeneratorObserver implements ObserverInterface
4951
*/
5052
private $compositeUrlValidator;
5153

54+
/**
55+
* @var GetDefaultUrlKey
56+
*/
57+
private $getDefaultUrlKey;
58+
5259
/**
5360
* @param CategoryUrlPathGenerator $categoryUrlPathGenerator
5461
* @param ChildrenCategoriesProvider $childrenCategoriesProvider
5562
* @param StoreViewService $storeViewService
5663
* @param CategoryRepositoryInterface $categoryRepository
5764
* @param CompositeUrlKey $compositeUrlValidator
65+
* @param GetDefaultUrlKey $getDefaultUrlKey
5866
*/
5967
public function __construct(
6068
CategoryUrlPathGenerator $categoryUrlPathGenerator,
6169
ChildrenCategoriesProvider $childrenCategoriesProvider,
6270
StoreViewService $storeViewService,
6371
CategoryRepositoryInterface $categoryRepository,
64-
CompositeUrlKey $compositeUrlValidator
72+
CompositeUrlKey $compositeUrlValidator,
73+
GetDefaultUrlKey $getDefaultUrlKey
6574
) {
6675
$this->categoryUrlPathGenerator = $categoryUrlPathGenerator;
6776
$this->childrenCategoriesProvider = $childrenCategoriesProvider;
6877
$this->storeViewService = $storeViewService;
6978
$this->categoryRepository = $categoryRepository;
7079
$this->compositeUrlValidator = $compositeUrlValidator;
80+
$this->getDefaultUrlKey = $getDefaultUrlKey;
7181
}
7282

7383
/**
7484
* Method for update/set url path.
7585
*
76-
* @param \Magento\Framework\Event\Observer $observer
86+
* @param Observer $observer
7787
* @return void
7888
* @throws LocalizedException
7989
*/
80-
public function execute(\Magento\Framework\Event\Observer $observer)
90+
public function execute(Observer $observer)
8191
{
8292
/** @var Category $category */
8393
$category = $observer->getEvent()->getCategory();
@@ -90,6 +100,12 @@ public function execute(\Magento\Framework\Event\Observer $observer)
90100
$resultUrlKey = $category->formatUrlKey($category->getOrigData('name'));
91101
$this->updateUrlKey($category, $resultUrlKey);
92102
}
103+
if ($category->hasChildren()) {
104+
$defaultUrlKey = $this->getDefaultUrlKey->execute((int)$category->getId());
105+
if ($defaultUrlKey) {
106+
$this->updateUrlKey($category, $defaultUrlKey);
107+
}
108+
}
93109
$category->setUrlKey(null)->setUrlPath(null);
94110
}
95111
}

0 commit comments

Comments
 (0)