Skip to content

Preserve existing store labels when updating attribute option via API #40095

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: 2.4-develop
Choose a base branch
from
12 changes: 12 additions & 0 deletions .github/app-projects-boards-automation.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,18 @@ automations:
- removeFromProject: [23] #['Pull Requests Dashboard']
- removeFromProject: [22] #['Community Dashboard']

# 19. Whenever a pull request is marked as changes requested:
# a. the below labels must be removed from a pull request: "Progress: review"
# b. it must be moved to the "Changes Requested" column
- trigger: pull_request_review.submitted
conditions:
- ['review', 'eq', 'changes_requested']
actions:
- removeLabels: ['Progress: review']
- addLabels: ['Progress: needs update']
- moveTo: [23, 'Changes Requested'] #['Pull Requests Dashboard', 'Changes Requested']
- moveTo: [22, 'Changes Requested'] #['Community Dashboard', 'Changes Requested']


############################################################################################################
# Issues Automation #
Expand Down
22 changes: 19 additions & 3 deletions app/code/Magento/Eav/Model/Entity/Attribute/OptionManagement.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
* Copyright 2014 Adobe
* All Rights Reserved.
*/
declare(strict_types=1);

Expand All @@ -13,6 +13,8 @@
use Magento\Eav\Api\Data\AttributeOptionInterface;
use Magento\Eav\Model\AttributeRepository;
use Magento\Eav\Model\ResourceModel\Entity\Attribute;
use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Exception\StateException;
Expand All @@ -32,17 +34,25 @@ class OptionManagement implements AttributeOptionManagementInterface, AttributeO
*/
protected $resourceModel;

/**
* @var Attribute\Option
*/
protected Attribute\Option $optionResource;

/**
* @param AttributeRepository $attributeRepository
* @param Attribute $resourceModel
* @param Option|null $optionResource
* @codeCoverageIgnore
*/
public function __construct(
AttributeRepository $attributeRepository,
Attribute $resourceModel
Attribute $resourceModel,
?Attribute\Option $optionResource = null
) {
$this->attributeRepository = $attributeRepository;
$this->resourceModel = $resourceModel;
$this->optionResource = $optionResource ?: ObjectManager::getInstance()->get(Attribute\Option::class);
}

/**
Expand Down Expand Up @@ -140,6 +150,12 @@ private function saveOption(
$options['value'][$optionId][0] = $optionLabel;
$options['order'][$optionId] = $option->getSortOrder();
$options['is_default'][$optionId] = $option->getIsDefault();

$existingLabels = $this->optionResource->getStoreLabelsByOptionId((int)$optionId);
foreach ($existingLabels as $storeId => $labelText) {
$options['value'][$optionId][$storeId] = $labelText;
}

if (is_array($option->getStoreLabels())) {
foreach ($option->getStoreLabels() as $label) {
$options['value'][$optionId][$label->getStoreId()] = $label->getLabel();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
* Copyright 2011 Adobe
* All Rights Reserved.
*/
namespace Magento\Eav\Model\ResourceModel\Entity\Attribute;

/**
* Entity attribute option resource model
*
* @author Magento Core Team <[email protected]>
*/
class Option extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
Expand Down Expand Up @@ -161,4 +159,22 @@ public function getFlatUpdateSelect(

return $select;
}

/**
* Get all store labels for a given option ID
*
* @param int $optionId
* @return array<int, string> [store_id => label]
*/
public function getStoreLabelsByOptionId(int $optionId): array
{
$connection = $this->getConnection();
$table = $this->getTable('eav_attribute_option_value');

$select = $connection->select()
->from($table, ['store_id', 'value'])
->where('option_id = ?', $optionId);

return $connection->fetchPairs($select);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
* Copyright 2014 Adobe
* All Rights Reserved.
*/
declare(strict_types=1);

Expand Down Expand Up @@ -44,17 +44,23 @@ class OptionManagementTest extends TestCase
*/
protected $resourceModelMock;

/**
* @var MockObject|Attribute\Option
*/
protected $optionResourceMock;

/**
* @inheritdoc
*/
protected function setUp(): void
{
$this->attributeRepositoryMock = $this->createMock(AttributeRepository::class);
$this->resourceModelMock =
$this->createMock(Attribute::class);
$this->resourceModelMock = $this->createMock(Attribute::class);
$this->optionResourceMock = $this->createMock(Attribute\Option::class);
$this->model = new OptionManagement(
$this->attributeRepositoryMock,
$this->resourceModelMock
$this->resourceModelMock,
$this->optionResourceMock
);
}

Expand Down Expand Up @@ -255,6 +261,7 @@ public function testUpdate(string $label): void
$optionId => [
0 => $label,
$storeId => $storeLabel,
5 => 'otherLabelLabel'
],
],
'order' => [
Expand All @@ -265,8 +272,17 @@ public function testUpdate(string $label): void
]
];

$this->optionResourceMock->expects($this->once())
->method('getStoreLabelsByOptionId')
->with($optionId)
->willReturn([
4 => 'oldLabelLabel',
5 => 'otherLabelLabel'
]);

$optionMock = $this->getAttributeOption();
$labelMock = $this->getAttributeOptionLabel();
$labelMock1 = $this->getAttributeOptionLabel();
$labelMock2 = $this->getAttributeOptionLabel();
/** @var SourceInterface|MockObject $sourceMock */
$sourceMock = $this->createMock(EavAttributeSource::class);

Expand Down Expand Up @@ -297,9 +313,11 @@ public function testUpdate(string $label): void
$optionMock->method('getLabel')->willReturn($label);
$optionMock->method('getSortOrder')->willReturn($sortOder);
$optionMock->method('getIsDefault')->willReturn(true);
$optionMock->method('getStoreLabels')->willReturn([$labelMock]);
$labelMock->method('getStoreId')->willReturn($storeId);
$labelMock->method('getLabel')->willReturn($storeLabel);
$optionMock->method('getStoreLabels')->willReturn([$labelMock1, $labelMock2]);
$labelMock1->method('getStoreId')->willReturn($storeId);
$labelMock1->method('getLabel')->willReturn($storeLabel);
$labelMock2->method('getStoreId')->willReturn(5);
$labelMock2->method('getLabel')->willReturn('otherLabelLabel');
$this->resourceModelMock->expects($this->once())->method('save')->with($attributeMock);

$this->assertEquals(
Expand Down