Skip to content

Commit f472536

Browse files
authored
Merge pull request #6286 from magento-tsg/2.4-develop-pr100
[Arrows] Fixes for 2.4 (pr100) (2.4-develop)
2 parents 632a7c6 + 4fc62e4 commit f472536

File tree

42 files changed

+1292
-621
lines changed

Some content is hidden

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

42 files changed

+1292
-621
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/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/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/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,24 @@
66
namespace Magento\CatalogSearch\Model\Indexer\Fulltext\Action;
77

88
use Magento\Catalog\Api\Data\ProductInterface;
9+
use Magento\Catalog\Model\Product;
910
use Magento\Catalog\Model\Product\Attribute\Source\Status;
11+
use Magento\Catalog\Model\Product\Type;
12+
use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory;
13+
use Magento\CatalogSearch\Model\ResourceModel\EngineInterface;
14+
use Magento\CatalogSearch\Model\ResourceModel\EngineProvider;
15+
use Magento\Eav\Model\Config;
16+
use Magento\Eav\Model\Entity\Attribute;
1017
use Magento\Framework\App\ResourceConnection;
18+
use Magento\Framework\DataObject;
19+
use Magento\Framework\DB\Adapter\AdapterInterface;
1120
use Magento\Framework\DB\Select;
21+
use Magento\Framework\EntityManager\EntityMetadata;
22+
use Magento\Framework\EntityManager\MetadataPool;
23+
use Magento\Framework\Event\ManagerInterface;
1224
use Magento\Store\Model\Store;
25+
use Magento\Store\Model\StoreManagerInterface;
26+
use Zend_Db;
1327

1428
/**
1529
* Catalog search full test search data provider.
@@ -24,7 +38,7 @@ class DataProvider
2438
/**
2539
* Searchable attributes cache
2640
*
27-
* @var \Magento\Eav\Model\Entity\Attribute[]
41+
* @var Attribute[]
2842
*/
2943
private $searchableAttributes;
3044

@@ -50,40 +64,40 @@ class DataProvider
5064
private $productEmulators = [];
5165

5266
/**
53-
* @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory
67+
* @var CollectionFactory
5468
*/
5569
private $productAttributeCollectionFactory;
5670

5771
/**
5872
* Eav config
5973
*
60-
* @var \Magento\Eav\Model\Config
74+
* @var Config
6175
*/
6276
private $eavConfig;
6377

6478
/**
6579
* Catalog product type
6680
*
67-
* @var \Magento\Catalog\Model\Product\Type
81+
* @var Type
6882
*/
6983
private $catalogProductType;
7084

7185
/**
7286
* Core event manager proxy
7387
*
74-
* @var \Magento\Framework\Event\ManagerInterface
88+
* @var ManagerInterface
7589
*/
7690
private $eventManager;
7791

7892
/**
7993
* Store manager
8094
*
81-
* @var \Magento\Store\Model\StoreManagerInterface
95+
* @var StoreManagerInterface
8296
*/
8397
private $storeManager;
8498

8599
/**
86-
* @var \Magento\CatalogSearch\Model\ResourceModel\EngineInterface
100+
* @var EngineInterface
87101
*/
88102
private $engine;
89103

@@ -93,12 +107,12 @@ class DataProvider
93107
private $resource;
94108

95109
/**
96-
* @var \Magento\Framework\DB\Adapter\AdapterInterface
110+
* @var AdapterInterface
97111
*/
98112
private $connection;
99113

100114
/**
101-
* @var \Magento\Framework\EntityManager\EntityMetadata
115+
* @var EntityMetadata
102116
*/
103117
private $metadata;
104118

@@ -126,24 +140,24 @@ class DataProvider
126140

127141
/**
128142
* @param ResourceConnection $resource
129-
* @param \Magento\Catalog\Model\Product\Type $catalogProductType
130-
* @param \Magento\Eav\Model\Config $eavConfig
131-
* @param \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $prodAttributeCollectionFactory
132-
* @param \Magento\CatalogSearch\Model\ResourceModel\EngineProvider $engineProvider
133-
* @param \Magento\Framework\Event\ManagerInterface $eventManager
134-
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
135-
* @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
143+
* @param Type $catalogProductType
144+
* @param Config $eavConfig
145+
* @param CollectionFactory $prodAttributeCollectionFactory
146+
* @param EngineProvider $engineProvider
147+
* @param ManagerInterface $eventManager
148+
* @param StoreManagerInterface $storeManager
149+
* @param MetadataPool $metadataPool
136150
* @param int $antiGapMultiplier
137151
*/
138152
public function __construct(
139153
ResourceConnection $resource,
140-
\Magento\Catalog\Model\Product\Type $catalogProductType,
141-
\Magento\Eav\Model\Config $eavConfig,
142-
\Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $prodAttributeCollectionFactory,
143-
\Magento\CatalogSearch\Model\ResourceModel\EngineProvider $engineProvider,
144-
\Magento\Framework\Event\ManagerInterface $eventManager,
145-
\Magento\Store\Model\StoreManagerInterface $storeManager,
146-
\Magento\Framework\EntityManager\MetadataPool $metadataPool,
154+
Type $catalogProductType,
155+
Config $eavConfig,
156+
CollectionFactory $prodAttributeCollectionFactory,
157+
EngineProvider $engineProvider,
158+
ManagerInterface $eventManager,
159+
StoreManagerInterface $storeManager,
160+
MetadataPool $metadataPool,
147161
int $antiGapMultiplier = 5
148162
) {
149163
$this->resource = $resource;
@@ -224,7 +238,7 @@ private function getSelectForSearchableProducts(
224238
$batch
225239
) {
226240
$websiteId = (int)$this->storeManager->getStore($storeId)->getWebsiteId();
227-
$lastProductId = (int) $lastProductId;
241+
$lastProductId = (int)$lastProductId;
228242

229243
$select = $this->connection->select()
230244
->useStraightJoin(true)
@@ -242,7 +256,7 @@ private function getSelectForSearchableProducts(
242256
$this->joinAttribute($select, 'status', $storeId, [Status::STATUS_ENABLED]);
243257

244258
if ($productIds !== null) {
245-
$select->where('e.entity_id IN (?)', $productIds, \Zend_Db::INT_TYPE);
259+
$select->where('e.entity_id IN (?)', $productIds, Zend_Db::INT_TYPE);
246260
}
247261
$select->where('e.entity_id > ?', $lastProductId);
248262
$select->order('e.entity_id');
@@ -308,14 +322,17 @@ private function joinAttribute(Select $select, $attributeCode, $storeId, array $
308322
*/
309323
public function getSearchableAttributes($backendType = null)
310324
{
325+
/** TODO: Remove this block in the next minor release and add a new public method instead */
326+
if ($this->eavConfig->getEntityType(Product::ENTITY)->getNeedRefreshSearchAttributesList()) {
327+
$this->clearSearchableAttributesList();
328+
}
311329
if (null === $this->searchableAttributes) {
312330
$this->searchableAttributes = [];
313331

314-
/** @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection $productAttributes */
315332
$productAttributes = $this->productAttributeCollectionFactory->create();
316333
$productAttributes->addToIndexFilter(true);
317334

318-
/** @var \Magento\Eav\Model\Entity\Attribute[] $attributes */
335+
/** @var Attribute[] $attributes */
319336
$attributes = $productAttributes->getItems();
320337

321338
/** @deprecated */
@@ -329,7 +346,7 @@ public function getSearchableAttributes($backendType = null)
329346
['engine' => $this->engine, 'attributes' => $attributes]
330347
);
331348

332-
$entity = $this->eavConfig->getEntityType(\Magento\Catalog\Model\Product::ENTITY)->getEntity();
349+
$entity = $this->eavConfig->getEntityType(Product::ENTITY)->getEntity();
333350

334351
foreach ($attributes as $attribute) {
335352
$attribute->setEntity($entity);
@@ -355,6 +372,18 @@ public function getSearchableAttributes($backendType = null)
355372
return $this->searchableAttributes;
356373
}
357374

375+
/**
376+
* Remove searchable attributes list.
377+
*
378+
* @return void
379+
*/
380+
private function clearSearchableAttributesList(): void
381+
{
382+
$this->searchableAttributes = null;
383+
$this->searchableAttributesByBackendType = [];
384+
$this->eavConfig->getEntityType(Product::ENTITY)->unsNeedRefreshSearchAttributesList();
385+
}
386+
358387
/**
359388
* Retrieve searchable attribute by Id or code
360389
*
@@ -369,7 +398,7 @@ public function getSearchableAttribute($attribute)
369398
return $attributes[$attribute];
370399
}
371400

372-
return $this->eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attribute);
401+
return $this->eavConfig->getAttribute(Product::ENTITY, $attribute);
373402
}
374403

375404
/**
@@ -386,6 +415,7 @@ private function unifyField($field, $backendType = 'varchar')
386415
} else {
387416
$expr = $field;
388417
}
418+
389419
return $expr;
390420
}
391421

@@ -411,7 +441,7 @@ public function getProductAttributes($storeId, array $productIds, array $attribu
411441
)->where(
412442
'cpe.entity_id IN (?)',
413443
$productIds,
414-
\Zend_Db::INT_TYPE
444+
Zend_Db::INT_TYPE
415445
)
416446
);
417447
foreach ($attributeTypes as $backendType => $attributeIds) {
@@ -479,6 +509,7 @@ private function getProductTypeInstance($typeId)
479509

480510
$this->productTypes[$typeId] = $this->catalogProductType->factory($productEmulator);
481511
}
512+
482513
return $this->productTypes[$typeId];
483514
}
484515

@@ -513,6 +544,7 @@ public function getProductChildIds($productId, $typeId)
513544
if ($relation->getWhere() !== null) {
514545
$select->where($relation->getWhere());
515546
}
547+
516548
return $this->connection->fetchCol($select);
517549
}
518550

@@ -528,10 +560,11 @@ public function getProductChildIds($productId, $typeId)
528560
private function getProductEmulator($typeId)
529561
{
530562
if (!isset($this->productEmulators[$typeId])) {
531-
$productEmulator = new \Magento\Framework\DataObject();
563+
$productEmulator = new DataObject();
532564
$productEmulator->setTypeId($typeId);
533565
$this->productEmulators[$typeId] = $productEmulator;
534566
}
567+
535568
return $this->productEmulators[$typeId];
536569
}
537570

@@ -660,6 +693,7 @@ function ($value) {
660693
$attributeOptionValue .= $this->attributeOptions[$optionKey][$attrValueId] . ' ';
661694
}
662695
}
696+
663697
return empty($attributeOptionValue) ? null : trim($attributeOptionValue);
664698
}
665699

0 commit comments

Comments
 (0)