Skip to content

Commit d22f7f1

Browse files
Merge branch '2.4-develop' into customer-select-option-fix
2 parents 55f6ce9 + 05b2748 commit d22f7f1

File tree

156 files changed

+5544
-1140
lines changed

Some content is hidden

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

156 files changed

+5544
-1140
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ private function prepareDefaultData(array $attributeList, string $attributeCode,
8080
// For non-numeric types set the attributeValue to 'false' to trigger their removal from the db
8181
if ($attributeType === 'varchar' || $attributeType === 'text' || $attributeType === 'datetime') {
8282
$attribute->setIsRequired(false);
83-
$productData[$attributeCode] = false;
83+
$productData[$attributeCode] = $attribute->getDefaultValue() ?: false;
8484
} else {
8585
$productData[$attributeCode] = null;
8686
}

app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,30 @@ public function getPositions(int $categoryId): array
4949

5050
return array_flip($connection->fetchCol($select));
5151
}
52+
53+
/**
54+
* Get category product minimum position
55+
*
56+
* @param int $categoryId
57+
* @return int
58+
*/
59+
public function getMinPosition(int $categoryId): int
60+
{
61+
$connection = $this->getConnection();
62+
63+
$select = $connection->select()->from(
64+
['cpe' => $this->getTable('catalog_product_entity')],
65+
['position' => new \Zend_Db_Expr('MIN(position)')]
66+
)->joinLeft(
67+
['ccp' => $this->getTable('catalog_category_product')],
68+
'ccp.product_id=cpe.entity_id'
69+
)->where(
70+
'ccp.category_id = ?',
71+
$categoryId
72+
)->order(
73+
'ccp.product_id ' . \Magento\Framework\DB\Select::SQL_DESC
74+
);
75+
76+
return (int)$connection->fetchOne($select);
77+
}
5278
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Catalog\Model;
89

910
/**
10-
* Class CategoryLinkManagement
11+
* Represents Category Product Link Management class
1112
*/
1213
class CategoryLinkManagement implements \Magento\Catalog\Api\CategoryLinkManagementInterface
1314
{
@@ -56,7 +57,7 @@ public function __construct(
5657
}
5758

5859
/**
59-
* {@inheritdoc}
60+
* @inheritdoc
6061
*/
6162
public function getAssignedProducts($categoryId)
6263
{
@@ -65,6 +66,7 @@ public function getAssignedProducts($categoryId)
6566
/** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $products */
6667
$products = $category->getProductCollection();
6768
$products->addFieldToSelect('position');
69+
$products->groupByAttribute($products->getProductEntityMetadata()->getIdentifierField());
6870

6971
/** @var \Magento\Catalog\Api\Data\CategoryProductLinkInterface[] $links */
7072
$links = [];

app/code/Magento/Catalog/Model/Product/Authorization.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public function authorizeSavingOf(ProductInterface $product): void
159159
if (!$savedProduct->getSku()) {
160160
throw NoSuchEntityException::singleField('id', $product->getId());
161161
}
162-
$oldData = $product->getOrigData();
162+
$oldData = $savedProduct->getData();
163163
}
164164
}
165165
if ($this->hasProductChanged($product, $oldData)) {

app/code/Magento/Catalog/Model/Product/Option/Type/Date.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ public function validateUserValue($values)
7272
$dateValid = true;
7373
if ($this->_dateExists()) {
7474
if ($this->useCalendar()) {
75+
if (is_array($value) && $this->checkDateWithoutJSCalendar($value)) {
76+
$value['date'] = sprintf("%s/%s/%s", $value['day'], $value['month'], $value['year']);
77+
}
7578
/* Fixed validation if the date was not saved correctly after re-saved the order
7679
for example: "09\/24\/2020,2020-09-24 00:00:00" */
7780
if (is_string($value) && preg_match('/^\d{1,4}.+\d{1,4}.+\d{1,4},+(\w|\W)*$/', $value)) {
@@ -81,6 +84,9 @@ public function validateUserValue($values)
8184
}
8285
$dateValid = isset($value['date']) && preg_match('/^\d{1,4}.+\d{1,4}.+\d{1,4}$/', $value['date']);
8386
} else {
87+
if (is_array($value)) {
88+
$value = $this->prepareDateByDateInternal($value);
89+
}
8490
$dateValid = isset(
8591
$value['day']
8692
) && isset(
@@ -411,4 +417,38 @@ protected function _timeExists()
411417
]
412418
);
413419
}
420+
421+
/**
422+
* Check is date without JS Calendar
423+
*
424+
* @param array $value
425+
*
426+
* @return bool
427+
*/
428+
private function checkDateWithoutJSCalendar(array $value): bool
429+
{
430+
return empty($value['date'])
431+
&& !empty($value['day'])
432+
&& !empty($value['month'])
433+
&& !empty($value['year']);
434+
}
435+
436+
/**
437+
* Prepare date by date internal
438+
*
439+
* @param array $value
440+
* @return array
441+
*/
442+
private function prepareDateByDateInternal(array $value): array
443+
{
444+
if (!empty($value['date']) && !empty($value['date_internal'])) {
445+
$formatDate = explode(' ', $value['date_internal']);
446+
$date = explode('-', $formatDate[0]);
447+
$value['year'] = $date[0];
448+
$value['month'] = $date[1];
449+
$value['day'] = $date[2];
450+
}
451+
452+
return $value;
453+
}
414454
}

app/code/Magento/Catalog/Model/Product/Type/AbstractType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Catalog\Model\Product\Type;
89

@@ -620,7 +621,7 @@ protected function _prepareOptions(\Magento\Framework\DataObject $buyRequest, $p
620621
}
621622
}
622623
if (count($results) > 0) {
623-
throw new LocalizedException(__(implode("\n", $results)));
624+
throw new LocalizedException(__(implode("\n", array_unique($results))));
624625
}
625626
}
626627

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
namespace Magento\Catalog\Model\ResourceModel;
1515

16-
use Magento\Catalog\Api\Data\ProductInterface;
16+
use Magento\Catalog\Api\Data\CategoryInterface;
1717
use Magento\Catalog\Model\Indexer\Category\Product\Processor;
1818
use Magento\Catalog\Setup\CategorySetup;
1919
use Magento\Framework\App\ObjectManager;
@@ -1172,11 +1172,11 @@ public function getCategoryWithChildren(int $categoryId): array
11721172
return [];
11731173
}
11741174

1175-
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
1175+
$linkField = $this->metadataPool->getMetadata(CategoryInterface::class)->getLinkField();
11761176
$select = $connection->select()
11771177
->from(
11781178
['cce' => $this->getTable('catalog_category_entity')],
1179-
[$linkField, 'parent_id', 'path']
1179+
[$linkField, 'entity_id', 'parent_id', 'path']
11801180
)->join(
11811181
['cce_int' => $this->getTable('catalog_category_entity_int')],
11821182
'cce.' . $linkField . ' = cce_int.' . $linkField,

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

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

88
namespace Magento\Catalog\Model\ResourceModel\Product;
99

10+
use Magento\Catalog\Api\Data\CategoryInterface;
1011
use Magento\Catalog\Api\Data\ProductInterface;
1112
use Magento\Catalog\Model\Indexer\Category\Product\TableMaintainer;
1213
use Magento\Catalog\Model\Indexer\Product\Price\PriceTableResolver;
@@ -2130,16 +2131,17 @@ private function getChildrenCategories(int $categoryId): array
21302131

21312132
$firstCategory = array_shift($categories);
21322133
if ($firstCategory['is_anchor'] == 1) {
2133-
$linkField = $this->getProductEntityMetadata()->getLinkField();
2134-
$anchorCategory[] = (int)$firstCategory[$linkField];
2134+
//category hierarchy can not be modified by staging updates
2135+
$entityField = $this->metadataPool->getMetadata(CategoryInterface::class)->getIdentifierField();
2136+
$anchorCategory[] = (int)$firstCategory[$entityField];
21352137
foreach ($categories as $category) {
21362138
if (in_array($category['parent_id'], $categoryIds)
21372139
&& in_array($category['parent_id'], $anchorCategory)) {
2138-
$categoryIds[] = (int)$category[$linkField];
2140+
$categoryIds[] = (int)$category[$entityField];
21392141
// Storefront approach is to treat non-anchor children of anchor category as anchors.
2140-
// Adding their's IDs to $anchorCategory for consistency.
2142+
// Adding theirs IDs to $anchorCategory for consistency.
21412143
if ($category['is_anchor'] == 1 || in_array($category['parent_id'], $anchorCategory)) {
2142-
$anchorCategory[] = (int)$category[$linkField];
2144+
$anchorCategory[] = (int)$category[$entityField];
21432145
}
21442146
}
21452147
}

app/code/Magento/Catalog/Test/Unit/Model/CategoryLinkManagementTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Magento\Catalog\Model\CategoryRepository;
1616
use Magento\Catalog\Model\ResourceModel\Product;
1717
use Magento\Catalog\Model\ResourceModel\Product\Collection;
18+
use Magento\Framework\DataObject;
1819
use Magento\Framework\Indexer\IndexerRegistry;
1920
use PHPUnit\Framework\MockObject\MockObject;
2021
use PHPUnit\Framework\TestCase;
@@ -85,7 +86,11 @@ public function testGetAssignedProducts()
8586
$categoryMock->expects($this->once())->method('getProductCollection')->willReturn($productsMock);
8687
$categoryMock->expects($this->once())->method('getId')->willReturn($categoryId);
8788
$productsMock->expects($this->once())->method('addFieldToSelect')->with('position')->willReturnSelf();
89+
$productsMock->expects($this->once())->method('groupByAttribute')->with('entity_id')->willReturnSelf();
8890
$productsMock->expects($this->once())->method('getItems')->willReturn($items);
91+
$productsMock->expects($this->once())
92+
->method('getProductEntityMetadata')
93+
->willReturn(new DataObject(['identifier_field' => 'entity_id']));
8994
$this->productLinkFactoryMock->expects($this->once())->method('create')->willReturn($categoryProductLinkMock);
9095
$categoryProductLinkMock->expects($this->once())
9196
->method('setSku')

app/code/Magento/CatalogGraphQl/DataProvider/Product/LayeredNavigation/Builder/Price.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public function build(AggregationInterface $aggregation, ?int $storeId): array
7272
);
7373
}
7474

75-
return [$result];
75+
return [self::PRICE_BUCKET => $result];
7676
}
7777

7878
/**

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

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77

88
namespace Magento\CatalogGraphQl\Model\Resolver;
99

10+
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\LayerBuilder;
11+
use Magento\Directory\Model\PriceCurrency;
12+
use Magento\Framework\App\ObjectManager;
1013
use Magento\Framework\GraphQl\Config\Element\Field;
1114
use Magento\Framework\GraphQl\Query\ResolverInterface;
1215
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
13-
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\LayerBuilder;
1416
use Magento\Store\Api\Data\StoreInterface;
1517

1618
/**
@@ -28,16 +30,24 @@ class Aggregations implements ResolverInterface
2830
*/
2931
private $layerBuilder;
3032

33+
/**
34+
* @var PriceCurrency
35+
*/
36+
private $priceCurrency;
37+
3138
/**
3239
* @param \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider
3340
* @param LayerBuilder $layerBuilder
41+
* @param PriceCurrency $priceCurrency
3442
*/
3543
public function __construct(
3644
\Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider,
37-
LayerBuilder $layerBuilder
45+
LayerBuilder $layerBuilder,
46+
PriceCurrency $priceCurrency = null
3847
) {
3948
$this->filtersDataProvider = $filtersDataProvider;
4049
$this->layerBuilder = $layerBuilder;
50+
$this->priceCurrency = $priceCurrency ?: ObjectManager::getInstance()->get(PriceCurrency::class);
4151
}
4252

4353
/**
@@ -60,7 +70,18 @@ public function resolve(
6070
/** @var StoreInterface $store */
6171
$store = $context->getExtensionAttributes()->getStore();
6272
$storeId = (int)$store->getId();
63-
return $this->layerBuilder->build($aggregations, $storeId);
73+
$results = $this->layerBuilder->build($aggregations, $storeId);
74+
if (isset($results['price_bucket'])) {
75+
foreach ($results['price_bucket']['options'] as &$value) {
76+
list($from, $to) = explode('-', $value['label']);
77+
$newLabel = $this->priceCurrency->convertAndRound($from)
78+
. '-'
79+
. $this->priceCurrency->convertAndRound($to);
80+
$value['label'] = $newLabel;
81+
$value['value'] = str_replace('-', '_', $newLabel);
82+
}
83+
}
84+
return $results;
6485
} else {
6586
return [];
6687
}

app/code/Magento/CatalogGraphQl/Model/Resolver/Category/DataProvider/Breadcrumbs.php

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

88
namespace Magento\CatalogGraphQl\Model\Resolver\Category\DataProvider;
99

10+
use Magento\Catalog\Api\Data\CategoryInterface;
1011
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
1112

1213
/**
@@ -46,6 +47,7 @@ public function getData(string $categoryPath): array
4647
$collection = $this->collectionFactory->create();
4748
$collection->addAttributeToSelect(['name', 'url_key', 'url_path']);
4849
$collection->addAttributeToFilter('entity_id', $parentCategoryIds);
50+
$collection->addAttributeToFilter(CategoryInterface::KEY_IS_ACTIVE, 1);
4951

5052
foreach ($collection as $category) {
5153
$breadcrumbsData[] = [

app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Image.php

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

88
namespace Magento\CatalogGraphQl\Model\Resolver\Category;
99

10+
use Magento\Catalog\Model\Category;
11+
use Magento\Catalog\Model\Category\FileInfo;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\Filesystem\DirectoryList;
1014
use Magento\Framework\GraphQl\Config\Element\Field;
15+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
1116
use Magento\Framework\GraphQl\Query\ResolverInterface;
1217
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
13-
use Magento\Framework\Exception\LocalizedException;
18+
use Magento\Framework\UrlInterface;
1419
use Magento\Store\Api\Data\StoreInterface;
15-
use Magento\Framework\Filesystem\DirectoryList;
16-
use Magento\Catalog\Model\Category\FileInfo;
17-
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
1820

1921
/**
2022
* Resolve category image to a fully qualified URL
@@ -52,15 +54,15 @@ public function resolve(
5254
if (!isset($value['model'])) {
5355
throw new LocalizedException(__('"model" value should be specified'));
5456
}
55-
/** @var \Magento\Catalog\Model\Category $category */
57+
/** @var Category $category */
5658
$category = $value['model'];
5759
$imagePath = $category->getData('image');
5860
if (empty($imagePath)) {
5961
return null;
6062
}
6163
/** @var StoreInterface $store */
6264
$store = $context->getExtensionAttributes()->getStore();
63-
$baseUrl = $store->getBaseUrl();
65+
$baseUrl = $store->getBaseUrl(UrlInterface::URL_TYPE_WEB);
6466

6567
$filenameWithMedia = $this->fileInfo->isBeginsWithMediaDirectoryPath($imagePath)
6668
? $imagePath : $this->formatFileNameWithMediaCategoryFolder($imagePath);

app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/ProductSearch.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public function getList(
113113
$searchResults = $this->searchResultsFactory->create();
114114
$searchResults->setSearchCriteria($searchCriteriaForCollection);
115115
$searchResults->setItems($collection->getItems());
116-
$searchResults->setTotalCount($searchResult->getTotalCount());
116+
$searchResults->setTotalCount($collection->getSize());
117117
return $searchResults;
118118
}
119119

app/code/Magento/CatalogGraphQl/Model/Resolver/Products/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ public function __construct(
5151
*/
5252
public function apply(Filter $filter, AbstractDb $collection)
5353
{
54+
$conditionType = $filter->getConditionType();
55+
if ($conditionType !== 'eq') {
56+
return true;
57+
}
58+
5459
$categoryIds = $filter->getValue();
5560
if (!is_array($categoryIds)) {
5661
$categoryIds = [$categoryIds];

app/code/Magento/CatalogGraphQl/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"magento/module-eav": "*",
88
"magento/module-catalog": "*",
99
"magento/module-catalog-inventory": "*",
10+
"magento/module-directory": "*",
1011
"magento/module-search": "*",
1112
"magento/module-store": "*",
1213
"magento/module-eav-graph-ql": "*",

app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ public function prepareAttributesWithDefaultValueForSave(array $rowData, $withDe
533533
if ($attrParams['is_static']) {
534534
continue;
535535
}
536+
$attrCode = mb_strtolower($attrCode);
536537
if (isset($rowData[$attrCode]) && strlen(trim($rowData[$attrCode]))) {
537538
if (in_array($attrParams['type'], ['select', 'boolean'])) {
538539
$resultAttrs[$attrCode] = $attrParams['options'][strtolower($rowData[$attrCode])];

0 commit comments

Comments
 (0)