Skip to content

Commit 5bde289

Browse files
committed
Merge remote-tracking branch 'origin/MC-19623' into 2.3-develop-pr32
2 parents 703e0a5 + 9aa8b75 commit 5bde289

File tree

3 files changed

+180
-1
lines changed

3 files changed

+180
-1
lines changed

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ protected function _updateAttributeOption($object, $optionId, $option)
457457
if (!empty($option['delete'][$optionId])) {
458458
if ($intOptionId) {
459459
$connection->delete($table, ['option_id = ?' => $intOptionId]);
460+
$this->clearSelectedOptionInEntities($object, $intOptionId);
460461
}
461462
return false;
462463
}
@@ -475,6 +476,41 @@ protected function _updateAttributeOption($object, $optionId, $option)
475476
return $intOptionId;
476477
}
477478

479+
/**
480+
* Clear selected option in entities
481+
*
482+
* @param EntityAttribute|AbstractModel $object
483+
* @param int $optionId
484+
* @return void
485+
*/
486+
private function clearSelectedOptionInEntities(AbstractModel $object, int $optionId)
487+
{
488+
$backendTable = $object->getBackendTable();
489+
$attributeId = $object->getAttributeId();
490+
if (!$backendTable || !$attributeId) {
491+
return;
492+
}
493+
494+
$connection = $this->getConnection();
495+
$where = $connection->quoteInto('attribute_id = ?', $attributeId);
496+
$update = [];
497+
498+
if ($object->getBackendType() === 'varchar') {
499+
$where.= ' AND ' . $connection->prepareSqlCondition('value', ['finset' => $optionId]);
500+
$concat = $connection->getConcatSql(["','", 'value', "','"]);
501+
$expr = $connection->quoteInto(
502+
"TRIM(BOTH ',' FROM REPLACE($concat,',?,',','))",
503+
$optionId
504+
);
505+
$update['value'] = new \Zend_Db_Expr($expr);
506+
} else {
507+
$where.= $connection->quoteInto(' AND value = ?', $optionId);
508+
$update['value'] = null;
509+
}
510+
511+
$connection->update($backendTable, $update, $where);
512+
}
513+
478514
/**
479515
* Save option values records per store
480516
*
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
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\Catalog\Model\ResourceModel\Attribute\Entity;
9+
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Catalog\Model\Product;
12+
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
13+
use Magento\Eav\Model\AttributeRepository;
14+
use Magento\Eav\Model\ResourceModel\Entity\Attribute as AttributeResource;
15+
use Magento\Framework\ObjectManagerInterface;
16+
use Magento\TestFramework\Helper\Bootstrap;
17+
use Magento\TestFramework\Helper\CacheCleaner;
18+
19+
/**
20+
* Test Eav Resource Entity Attribute functionality
21+
*
22+
* @magentoAppArea adminhtml
23+
* @magentoDataFixture Magento/Catalog/_files/dropdown_attribute.php
24+
* @magentoDataFixture Magento/Catalog/_files/multiselect_attribute.php
25+
* @magentoDataFixture Magento/Catalog/_files/product_without_options.php
26+
*/
27+
class AttributeTest extends \PHPUnit\Framework\TestCase
28+
{
29+
/**
30+
* @var ObjectManagerInterface
31+
*/
32+
private $objectManager;
33+
34+
/**
35+
* @var AttributeRepository
36+
*/
37+
protected $attributeRepository;
38+
39+
/**
40+
* @var ProductRepositoryInterface
41+
*/
42+
private $productRepository;
43+
44+
/**
45+
* @var AttributeResource
46+
*/
47+
private $model;
48+
49+
/**
50+
* @inheritdoc
51+
*/
52+
public function setUp()
53+
{
54+
CacheCleaner::cleanAll();
55+
$this->objectManager = Bootstrap::getObjectManager();
56+
$this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
57+
$this->attributeRepository = $this->objectManager->get(AttributeRepository::class);
58+
$this->model = $this->objectManager->get(Attribute::class);
59+
}
60+
61+
/**
62+
* Test to Clear selected option in entities after remove
63+
*/
64+
public function testClearSelectedOptionInEntities()
65+
{
66+
$dropdownAttribute = $this->loadAttribute('dropdown_attribute');
67+
$dropdownOption = array_keys($dropdownAttribute->getOptions())[1];
68+
69+
$multiplyAttribute = $this->loadAttribute('multiselect_attribute');
70+
$multiplyOptions = array_keys($multiplyAttribute->getOptions());
71+
$multiplySelectedOptions = implode(',', $multiplyOptions);
72+
$multiplyOptionToRemove = $multiplyOptions[1];
73+
unset($multiplyOptions[1]);
74+
$multiplyOptionsExpected = implode(',', $multiplyOptions);
75+
76+
$product = $this->loadProduct('simple');
77+
$product->setData('dropdown_attribute', $dropdownOption);
78+
$product->setData('multiselect_attribute', $multiplySelectedOptions);
79+
$this->productRepository->save($product);
80+
81+
$product = $this->loadProduct('simple');
82+
$this->assertEquals(
83+
$dropdownOption,
84+
$product->getData('dropdown_attribute'),
85+
'The dropdown attribute is not selected'
86+
);
87+
$this->assertEquals(
88+
$multiplySelectedOptions,
89+
$product->getData('multiselect_attribute'),
90+
'The multiselect attribute is not selected'
91+
);
92+
93+
$this->removeAttributeOption($dropdownAttribute, $dropdownOption);
94+
$this->removeAttributeOption($multiplyAttribute, $multiplyOptionToRemove);
95+
96+
$product = $this->loadProduct('simple');
97+
$this->assertEmpty($product->getData('dropdown_attribute'));
98+
$this->assertEquals($multiplyOptionsExpected, $product->getData('multiselect_attribute'));
99+
}
100+
101+
/**
102+
* Remove option from attribute
103+
*
104+
* @param Attribute $attribute
105+
* @param int $optionId
106+
*/
107+
private function removeAttributeOption(Attribute $attribute, int $optionId): void
108+
{
109+
$removalMarker = [
110+
'option' => [
111+
'value' => [$optionId => []],
112+
'delete' => [$optionId => '1'],
113+
],
114+
];
115+
$attribute->addData($removalMarker);
116+
$attribute->save($attribute);
117+
}
118+
119+
/**
120+
* Load product by sku
121+
*
122+
* @param string $sku
123+
* @return Product
124+
*/
125+
private function loadProduct(string $sku): Product
126+
{
127+
return $this->productRepository->get($sku, true, null, true);
128+
}
129+
130+
/**
131+
* Load attrubute by code
132+
*
133+
* @param string $attributeCode
134+
* @return Attribute
135+
*/
136+
private function loadAttribute(string $attributeCode): Attribute
137+
{
138+
/** @var Attribute $attribute */
139+
$attribute = $this->objectManager->create(Attribute::class);
140+
$attribute->loadByCode(4, $attributeCode);
141+
142+
return $attribute;
143+
}
144+
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
'used_for_sort_by' => 0,
3838
'frontend_label' => ['Drop-Down Attribute'],
3939
'backend_type' => 'varchar',
40-
'backend_model' => \Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend::class,
4140
'option' => [
4241
'value' => [
4342
'option_1' => ['Option 1'],

0 commit comments

Comments
 (0)