Skip to content

Commit 063f641

Browse files
committed
Merge remote-tracking branch 'origin/AC-12336' into spartans_pr_25062025
2 parents b65fe37 + 4bb8a16 commit 063f641

File tree

3 files changed

+254
-2
lines changed

3 files changed

+254
-2
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All rights reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Ui\Plugin\Config\Backend;
9+
10+
use Magento\Config\Model\Config\Backend\Serialized\ArraySerialized;
11+
use Magento\Framework\App\RequestInterface;
12+
13+
/**
14+
* Plugin for ArraySerialized backend model
15+
* Automatically converts row1/row2/row3 format to numerically indexed arrays
16+
* Only works on design config edit page
17+
*/
18+
class ArraySerializedPlugin
19+
{
20+
private const DESIGN_CONFIG_EDIT_PAGE = '_design_config_edit';
21+
22+
/**
23+
* @param RequestInterface $request
24+
*/
25+
public function __construct(
26+
private readonly RequestInterface $request
27+
) {
28+
}
29+
30+
/**
31+
* Convert string keys to numeric keys. Only applies on design config edit page
32+
*
33+
* @param ArraySerialized $subject
34+
* @param ArraySerialized $result
35+
* @return ArraySerialized
36+
*/
37+
public function afterAfterLoad(ArraySerialized $subject, ArraySerialized $result)
38+
{
39+
// Only apply the conversion on design config edit page
40+
if (!$this->isDesignConfigEditPage()) {
41+
return $result;
42+
}
43+
44+
$value = $subject->getValue();
45+
if (!is_array($value)) {
46+
return $result;
47+
}
48+
49+
$keys = array_keys($value);
50+
// Check if keys are string-based (row1, row2, row3) instead of numeric
51+
if (empty($keys) || is_numeric($keys[0])) {
52+
return $result;
53+
}
54+
55+
// Convert to numerically indexed array
56+
$convertedValue = array_values($value);
57+
$subject->setValue($convertedValue);
58+
59+
return $result;
60+
}
61+
62+
/**
63+
* Check if we're on the design config edit page.
64+
*
65+
* @return bool
66+
*/
67+
private function isDesignConfigEditPage(): bool
68+
{
69+
return str_ends_with($this->request->getFullActionName(), self::DESIGN_CONFIG_EDIT_PAGE);
70+
}
71+
}

app/code/Magento/Ui/etc/adminhtml/di.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2016 Adobe
5+
* All rights reserved.
66
*/
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
@@ -61,4 +61,9 @@
6161
</argument>
6262
</arguments>
6363
</type>
64+
65+
<!-- Plugin to automatically convert row1/row2/row3 format to numerically indexed arrays -->
66+
<type name="Magento\Config\Model\Config\Backend\Serialized\ArraySerialized">
67+
<plugin name="ui_array_serialized_plugin" type="Magento\Ui\Plugin\Config\Backend\ArraySerializedPlugin" />
68+
</type>
6469
</config>
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All rights reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Ui\Plugin\Config\Backend;
9+
10+
use Magento\Config\Model\Config\Backend\Serialized\ArraySerialized;
11+
use Magento\Framework\ObjectManagerInterface;
12+
use Magento\TestFramework\Fixture\AppArea;
13+
use Magento\TestFramework\Helper\Bootstrap;
14+
use Magento\TestFramework\TestCase\AbstractBackendController;
15+
16+
/**
17+
* Integration test for ArraySerializedPlugin
18+
*/
19+
class ArraySerializedPluginTest extends AbstractBackendController
20+
{
21+
/**
22+
* @var ObjectManagerInterface
23+
*/
24+
private $objectManager;
25+
26+
protected function setUp(): void
27+
{
28+
parent::setUp();
29+
$this->objectManager = Bootstrap::getObjectManager();
30+
}
31+
32+
/**
33+
* Test that plugin converts string keys to numeric keys. Works only on design config edit page
34+
*
35+
* @dataProvider serializeDataProvider
36+
*/
37+
#[
38+
AppArea('adminhtml')
39+
]
40+
public function testPluginConvertsStringKeysOnDesignConfigEditPage($stringKeyedArray, $resultArray)
41+
{
42+
// Set up the request to simulate design config edit page
43+
$this->setPageContext();
44+
45+
// Create ArraySerialized backend model
46+
$backendModel = $this->objectManager->create(ArraySerialized::class);
47+
$backendModel->setValue($stringKeyedArray);
48+
49+
// Trigger the afterAfterLoad method (this is where the plugin should run)
50+
$backendModel->afterLoad();
51+
52+
// Get the processed value
53+
$processedValue = $backendModel->getValue();
54+
55+
// Assert that string keys were converted to numeric keys
56+
$this->assertEquals($resultArray, $processedValue);
57+
}
58+
59+
/**
60+
* Test that plugin doesn't convert data when not on design config edit page
61+
*/
62+
#[
63+
AppArea('adminhtml')
64+
]
65+
public function testPluginDoesNotConvertOnOtherPages()
66+
{
67+
// Create test data with string keys
68+
$stringKeyedArray = [
69+
'row1' => ['field1' => 'value1'],
70+
'row2' => ['field2' => 'value2'],
71+
'row3' => ['field3' => 'value3']
72+
];
73+
74+
// Create ArraySerialized backend model
75+
$backendModel = $this->objectManager->create(ArraySerialized::class);
76+
$backendModel->setValue($stringKeyedArray);
77+
78+
// Trigger the afterAfterLoad method
79+
$backendModel->afterLoad();
80+
81+
// Get the processed value
82+
$processedValue = $backendModel->getValue();
83+
84+
// Assert that string keys are preserved (no conversion should happen)
85+
$this->assertIsArray($processedValue);
86+
$this->assertEquals($stringKeyedArray, $processedValue);
87+
}
88+
89+
/**
90+
* Test that plugin doesn't convert data in frontend area
91+
*/
92+
#[
93+
AppArea('frontend')
94+
]
95+
public function testPluginDoesNotConvertInFrontendArea()
96+
{
97+
// Set up the request to simulate design config edit page
98+
$this->setPageContext();
99+
100+
// Create test data with string keys
101+
$stringKeyedArray = [
102+
'row1' => ['field1' => 'value1'],
103+
'row2' => ['field2' => 'value2'],
104+
'row3' => ['field3' => 'value3']
105+
];
106+
107+
// Create ArraySerialized backend model
108+
$backendModel = $this->objectManager->create(ArraySerialized::class);
109+
$backendModel->setValue($stringKeyedArray);
110+
111+
// Trigger the afterAfterLoad method
112+
$backendModel->afterLoad();
113+
114+
// Get the processed value
115+
$processedValue = $backendModel->getValue();
116+
117+
// Assert that string keys are preserved (no conversion should happen in frontend)
118+
$this->assertIsArray($processedValue);
119+
$this->assertEquals($stringKeyedArray, $processedValue);
120+
}
121+
122+
/**
123+
* Data provider for ArraySerializedPlugin. Input array and resultant array.
124+
*
125+
* @return array
126+
*/
127+
public function serializeDataProvider()
128+
{
129+
return [
130+
[ //Test that plugin converts string keys to numeric keys.
131+
[
132+
'row1' => ['field1' => 'value1'],
133+
'row2' => ['field2' => 'value2'],
134+
'row3' => ['field3' => 'value3']
135+
],
136+
[
137+
['field1' => 'value1'],
138+
['field2' => 'value2'],
139+
['field3' => 'value3']
140+
]
141+
],
142+
[ //Test that plugin doesn't convert already numeric arrays.
143+
[
144+
['field1' => 'value1'],
145+
['field2' => 'value2'],
146+
['field3' => 'value3']
147+
],
148+
[
149+
['field1' => 'value1'],
150+
['field2' => 'value2'],
151+
['field3' => 'value3']
152+
]
153+
],
154+
[ // Test that plugin handles empty arrays correctly
155+
[],
156+
[]
157+
],
158+
[ // Test that plugin handles non-array values correctly
159+
'test_string',
160+
false
161+
]
162+
];
163+
}
164+
165+
/**
166+
* Set up the request to simulate design config edit page
167+
*
168+
* @return void
169+
*/
170+
private function setPageContext()
171+
{
172+
$this->getRequest()->setModuleName('theme');
173+
$this->getRequest()->setControllerName('design_config');
174+
$this->getRequest()->setActionName('edit');
175+
}
176+
}

0 commit comments

Comments
 (0)