Skip to content

Commit 65ef9aa

Browse files
[Magento Community Engineering] Community Contributions - 2.4-develop-express-lane-prs
- merged with '2.4-develop-expedited-prs' branch
2 parents 2ff3e64 + 41f3137 commit 65ef9aa

File tree

19 files changed

+239
-37
lines changed

19 files changed

+239
-37
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ protected function _getIndexableAttributes($multiSelect)
105105
);
106106

107107
if ($multiSelect == true) {
108-
$select->where('ea.backend_type = ?', 'varchar')->where('ea.frontend_input = ?', 'multiselect');
108+
$select->where('ea.backend_type = ?', 'text')->where('ea.frontend_input = ?', 'multiselect');
109109
} else {
110110
$select->where('ea.backend_type = ?', 'int')->where('ea.frontend_input IN( ? )', ['select', 'boolean']);
111111
}
@@ -303,14 +303,14 @@ protected function _prepareMultiselectIndex($entityIds = null, $attributeId = nu
303303
// prepare get multiselect values query
304304
$productValueExpression = $connection->getCheckSql('pvs.value_id > 0', 'pvs.value', 'pvd.value');
305305
$select = $connection->select()->from(
306-
['pvd' => $this->getTable('catalog_product_entity_varchar')],
306+
['pvd' => $this->getTable('catalog_product_entity_text')],
307307
[]
308308
)->join(
309309
['cs' => $this->getTable('store')],
310310
'',
311311
[]
312312
)->joinLeft(
313-
['pvs' => $this->getTable('catalog_product_entity_varchar')],
313+
['pvs' => $this->getTable('catalog_product_entity_text')],
314314
"pvs.{$productIdField} = pvd.{$productIdField} AND pvs.attribute_id = pvd.attribute_id"
315315
. ' AND pvs.store_id=cs.store_id',
316316
[]
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Setup\Patch\Data;
8+
9+
use Magento\Catalog\Model\Product;
10+
use Magento\Eav\Setup\EavSetup;
11+
use Magento\Eav\Setup\EavSetupFactory;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\Setup\ModuleDataSetupInterface;
14+
use Magento\Framework\Setup\Patch\DataPatchInterface;
15+
16+
class UpdateMultiselectAttributesBackendTypes implements DataPatchInterface
17+
{
18+
/**
19+
* @var ModuleDataSetupInterface
20+
*/
21+
private $dataSetup;
22+
/**
23+
* @var EavSetupFactory
24+
*/
25+
private $eavSetupFactory;
26+
27+
/**
28+
* MigrateMultiselectAttributesData constructor.
29+
* @param ModuleDataSetupInterface $dataSetup
30+
* @param EavSetupFactory $eavSetupFactory
31+
*/
32+
public function __construct(
33+
ModuleDataSetupInterface $dataSetup,
34+
EavSetupFactory $eavSetupFactory
35+
) {
36+
$this->dataSetup = $dataSetup;
37+
$this->eavSetupFactory = $eavSetupFactory;
38+
}
39+
40+
/**
41+
* @inheritdoc
42+
*/
43+
public static function getDependencies()
44+
{
45+
return [];
46+
}
47+
48+
/**
49+
* @inheritdoc
50+
*/
51+
public function getAliases()
52+
{
53+
return [];
54+
}
55+
56+
/**
57+
* @inheritdoc
58+
*/
59+
public function apply()
60+
{
61+
$this->dataSetup->startSetup();
62+
63+
$connection = $this->dataSetup->getConnection();
64+
$attributeTable = $connection->getTableName('eav_attribute');
65+
/** @var EavSetup $eavSetup */
66+
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->dataSetup]);
67+
$entityTypeId = $eavSetup->getEntityTypeId(Product::ENTITY);
68+
$attributesToMigrate = $connection->fetchCol(
69+
$connection
70+
->select()
71+
->from($attributeTable, ['attribute_id'])
72+
->where('entity_type_id = ?', $entityTypeId)
73+
->where('backend_type = ?', 'varchar')
74+
->where('frontend_input = ?', 'multiselect')
75+
);
76+
77+
$varcharTable = $connection->getTableName('catalog_product_entity_varchar');
78+
$textTable = $connection->getTableName('catalog_product_entity_text');
79+
$varcharTableDataSql = $connection
80+
->select()
81+
->from($varcharTable)
82+
->where('attribute_id in (?)', $attributesToMigrate);
83+
$dataToMigrate = array_map(static function ($row) {
84+
$row['value_id'] = null;
85+
return $row;
86+
}, $connection->fetchAll($varcharTableDataSql));
87+
88+
foreach (array_chunk($dataToMigrate, 2000) as $dataChunk) {
89+
$connection->insertMultiple($textTable, $dataChunk);
90+
}
91+
92+
$connection->query($connection->deleteFromSelect($varcharTableDataSql, $varcharTable));
93+
94+
foreach ($attributesToMigrate as $attributeId) {
95+
$eavSetup->updateAttribute($entityTypeId, $attributeId, 'backend_type', 'text');
96+
}
97+
98+
$this->dataSetup->endSetup();
99+
100+
return $this;
101+
}
102+
}

app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ protected function addGlobalAttribute(
182182
$linkField = $attribute->getEntity()->getLinkField();
183183

184184
$collection->getSelect()->join(
185-
[$alias => $collection->getTable('catalog_product_entity_varchar')],
185+
[$alias => $collection->getTable($attribute->getBackendTable())],
186186
"($alias.$linkField = e.$linkField) AND ($alias.store_id = $storeId)" .
187187
" AND ($alias.attribute_id = {$attribute->getId()})",
188188
[]

app/code/Magento/Eav/Model/Entity/Attribute.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,12 +356,12 @@ public function getBackendTypeByInput($type)
356356
case 'text':
357357
case 'gallery':
358358
case 'media_image':
359-
case 'multiselect':
360359
$field = 'varchar';
361360
break;
362361

363362
case 'image':
364363
case 'textarea':
364+
case 'multiselect':
365365
$field = 'text';
366366
break;
367367

app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ private function clearSelectedOptionInEntities(AbstractModel $object, int $optio
523523
$where = $connection->quoteInto('attribute_id = ?', $attributeId);
524524
$update = [];
525525

526-
if ($object->getBackendType() === 'varchar') {
526+
if ($object->getBackendType() === 'text') {
527527
$where.= ' AND ' . $connection->prepareSqlCondition('value', ['finset' => $optionId]);
528528
$concat = $connection->getConcatSql(["','", 'value', "','"]);
529529
$expr = $connection->quoteInto(

app/code/Magento/Eav/Test/Unit/Model/Entity/AttributeTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public static function dataGetBackendTypeByInput()
6262
['text', 'varchar'],
6363
['gallery', 'varchar'],
6464
['media_image', 'varchar'],
65-
['multiselect', 'varchar'],
65+
['multiselect', 'text'],
6666
['image', 'text'],
6767
['textarea', 'text'],
6868
['date', 'datetime'],

dev/tests/integration/framework/Magento/TestFramework/Eav/Model/Attribute/DataProvider/MultipleSelect.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ protected function getUpdateExpectedData(): array
8989
'frontend_class' => null,
9090
'used_for_sort_by' => '0',
9191
'is_user_defined' => '1',
92-
'backend_type' => 'varchar',
92+
'backend_type' => 'text',
9393
]
9494
);
9595
}

dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,25 @@ public function testGetAttributeTextArray()
225225
);
226226
}
227227

228+
/**
229+
* @magentoDataFixture Magento/Catalog/_files/products_with_multiselect_attribute.php
230+
*/
231+
public function testMultipleMultiselectTextValues()
232+
{
233+
$expectedArray = [];
234+
235+
for ($i = 1; $i < 200; $i++) {
236+
$expectedArray[] = sprintf('Multiselect option %d', $i);
237+
}
238+
239+
$product = $this->productRepository->get('simple_ms_3');
240+
241+
self::assertEquals(
242+
$expectedArray,
243+
$product->getAttributeText('multiselect_attribute_text')
244+
);
245+
}
246+
228247
public function testGetCustomDesignDate()
229248
{
230249
$this->assertEquals(['from' => null, 'to' => null], $this->_model->getCustomDesignDate());

dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/SourceTest.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use Magento\Store\Api\Data\StoreInterface;
1616

1717
/**
18-
* Class SourceTest
1918
* @magentoAppIsolation enabled
2019
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2120
*/
@@ -69,7 +68,7 @@ public function testReindexEntitiesForConfigurableProduct()
6968

7069
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attr **/
7170
$attr = Bootstrap::getObjectManager()->get(\Magento\Eav\Model\Config::class)
72-
->getAttribute('catalog_product', 'test_configurable');
71+
->getAttribute('catalog_product', 'test_configurable');
7372
$attr->setIsFilterable(1)->save();
7473

7574
$this->_eavIndexerProcessor->reindexAll();
@@ -133,7 +132,7 @@ public function testReindexMultiselectAttribute()
133132

134133
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attr **/
135134
$attr = $objectManager->get(\Magento\Eav\Model\Config::class)
136-
->getAttribute('catalog_product', 'multiselect_attribute');
135+
->getAttribute('catalog_product', 'multiselect_attribute');
137136

138137
/** @var $options \Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection */
139138
$options = $objectManager->create(\Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection::class);
@@ -213,7 +212,7 @@ public function testReindexMultiselectAttributeWithSourceModel()
213212

214213
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attr **/
215214
$attr = $objectManager->get(\Magento\Eav\Model\Config::class)
216-
->getAttribute('catalog_product', 'multiselect_attr_with_source');
215+
->getAttribute('catalog_product', 'multiselect_attr_with_source');
217216

218217
/** @var $sourceModel MultiselectSourceMock */
219218
$sourceModel = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
@@ -231,8 +230,8 @@ public function testReindexMultiselectAttributeWithSourceModel()
231230

232231
/** @var \Magento\Catalog\Model\Product $product2 **/
233232
$product2 = $productRepository->getById($product2Id);
234-
$product1->setSpecialFromDate(date('Y-m-d H:i:s'));
235-
$product1->setNewsFromDate(date('Y-m-d H:i:s'));
233+
$product2->setSpecialFromDate(date('Y-m-d H:i:s'));
234+
$product2->setNewsFromDate(date('Y-m-d H:i:s'));
236235
$productRepository->save($product2);
237236

238237
$this->_eavIndexerProcessor->reindexAll();

dev/tests/integration/testsuite/Magento/Catalog/_files/multiselect_attribute.php

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,27 @@
88
$installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
99
\Magento\Catalog\Setup\CategorySetup::class
1010
);
11-
/** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
12-
$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
11+
/** @var $attributeMultiselect \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
12+
$attributeMultiselect = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
1313
\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class
1414
);
15+
16+
/** @var $attributeMultiselectText \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
17+
$attributeMultiselectText = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
18+
\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class
19+
);
20+
21+
$valueOptionArray = [];
22+
$orderArray = [];
23+
24+
for ($i = 1; $i < 200; $i++) {
25+
$valueOptionArray[sprintf('option_%d', $i)] = [sprintf('Multiselect option %d', $i)];
26+
$orderArray[sprintf('option_%d', $i)] = $i;
27+
}
28+
1529
$entityType = $installer->getEntityTypeId('catalog_product');
16-
if (!$attribute->loadByCode($entityType, 'multiselect_attribute')->getAttributeId()) {
17-
$attribute->setData(
30+
if (!$attributeMultiselect->loadByCode($entityType, 'multiselect_attribute')->getAttributeId()) {
31+
$attributeMultiselect->setData(
1832
[
1933
'attribute_code' => 'multiselect_attribute',
2034
'entity_type_id' => $entityType,
@@ -34,7 +48,7 @@
3448
'used_in_product_listing' => 0,
3549
'used_for_sort_by' => 0,
3650
'frontend_label' => ['Multiselect Attribute'],
37-
'backend_type' => 'varchar',
51+
'backend_type' => 'text',
3852
'backend_model' => \Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend::class,
3953
'option' => [
4054
'value' => [
@@ -52,8 +66,45 @@
5266
],
5367
]
5468
);
55-
$attribute->save();
69+
$attributeMultiselect->save();
70+
71+
/* Assign attribute to attribute set */
72+
$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attributeMultiselect->getId());
73+
}
74+
75+
76+
if (!$attributeMultiselectText->loadByCode($entityType, 'multiselect_attribute_text')->getAttributeId()) {
77+
$attributeMultiselectText->setData(
78+
[
79+
'attribute_code' => 'multiselect_attribute_text',
80+
'entity_type_id' => $entityType,
81+
'is_global' => 1,
82+
83+
'is_user_defined' => 1,
84+
'frontend_input' => 'multiselect',
85+
'is_unique' => 0,
86+
'is_required' => 0,
87+
'is_searchable' => 0,
88+
'is_visible_in_advanced_search' => 0,
89+
'is_comparable' => 0,
90+
'is_filterable' => 1,
91+
'is_filterable_in_search' => 0,
92+
'is_used_for_promo_rules' => 0,
93+
'is_html_allowed_on_front' => 1,
94+
'is_visible_on_front' => 0,
95+
'used_in_product_listing' => 0,
96+
'used_for_sort_by' => 0,
97+
'frontend_label' => ['Multiselect Attribute'],
98+
'backend_type' => 'text',
99+
'backend_model' => \Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend::class,
100+
'option' => [
101+
'value' => $valueOptionArray,
102+
'order' => $orderArray
103+
],
104+
]
105+
);
106+
$attributeMultiselectText->save();
56107

57108
/* Assign attribute to attribute set */
58-
$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId());
109+
$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attributeMultiselectText->getId());
59110
}

0 commit comments

Comments
 (0)