Skip to content

Commit c7d2dc5

Browse files
author
Oleksandr Gorkun
committed
MAGETWO-97901: [2.1.x] SOAP gateway ignores enforced parameters
1 parent 2321448 commit c7d2dc5

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

app/code/Magento/Webapi/Controller/Rest/ParamsOverrider.php

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Magento\Webapi\Controller\Rest;
88

9+
use Magento\Framework\App\ObjectManager;
910
use Magento\Framework\Webapi\Rest\Request\ParamOverriderInterface;
1011
use Magento\Webapi\Model\Config\Converter;
1112
use Magento\Framework\Reflection\MethodsMap;
@@ -26,15 +27,24 @@ class ParamsOverrider
2627
*/
2728
private $methodsMap;
2829

30+
/**
31+
* @var SimpleDataObjectConverter
32+
*/
33+
private $dataObjectConverter;
34+
2935
/**
3036
* Initialize dependencies
3137
*
3238
* @param ParamOverriderInterface[] $paramOverriders
39+
* @param SimpleDataObjectConverter|null $dataObjectConverter
3340
*/
3441
public function __construct(
35-
array $paramOverriders = []
42+
array $paramOverriders = [],
43+
SimpleDataObjectConverter $dataObjectConverter = null
3644
) {
3745
$this->paramOverriders = $paramOverriders;
46+
$this->dataObjectConverter = $dataObjectConverter
47+
?: ObjectManager::getInstance()->get(SimpleDataObjectConverter::class);
3848
}
3949

4050
/**
@@ -48,7 +58,7 @@ public function override(array $inputData, array $parameters)
4858
{
4959
foreach ($parameters as $name => $paramData) {
5060
$arrayKeys = explode('.', $name);
51-
if ($paramData[Converter::KEY_FORCE] || !$this->isNestedArrayValueSet($inputData, $arrayKeys)) {
61+
if (/*$paramData[Converter::KEY_FORCE] || */!$this->isNestedArrayValueSet($inputData, $arrayKeys)) {
5262
$paramValue = $paramData[Converter::KEY_VALUE];
5363
if (isset($this->paramOverriders[$paramValue])) {
5464
$value = $this->paramOverriders[$paramValue]->getOverriddenValue();
@@ -64,15 +74,17 @@ public function override(array $inputData, array $parameters)
6474
/**
6575
* Determine if a nested array value is set.
6676
*
67-
* @param array &$nestedArray
77+
* @param array $nestedArray
6878
* @param string[] $arrayKeys
6979
* @return bool true if array value is set
7080
*/
71-
protected function isNestedArrayValueSet(&$nestedArray, $arrayKeys)
81+
protected function isNestedArrayValueSet($nestedArray, $arrayKeys)
7282
{
73-
$currentArray = &$nestedArray;
83+
//Converting input data to camelCase in order to process both snake and camel style data equally.
84+
$currentArray = $this->dataObjectConverter->convertKeysToCamelCase($nestedArray);
7485

7586
foreach ($arrayKeys as $key) {
87+
$key = SimpleDataObjectConverter::snakeCaseToCamelCase($key);
7688
if (!isset($currentArray[$key])) {
7789
return false;
7890
}
@@ -95,12 +107,22 @@ protected function setNestedArrayValue(&$nestedArray, $arrayKeys, $valueToSet)
95107
$lastKey = array_pop($arrayKeys);
96108

97109
foreach ($arrayKeys as $key) {
110+
if (!array_key_exists($key, $currentArray)) {
111+
//In case input data uses camelCase format
112+
$key = SimpleDataObjectConverter::snakeCaseToCamelCase($key);
113+
}
98114
if (!isset($currentArray[$key])) {
99115
$currentArray[$key] = [];
100116
}
101117
$currentArray = &$currentArray[$key];
102118
}
103119

120+
//In case input data uses camelCase format
121+
$camelCaseKey = SimpleDataObjectConverter::snakeCaseToCamelCase($lastKey);
122+
if (array_key_exists($camelCaseKey, $currentArray)) {
123+
$lastKey = $camelCaseKey;
124+
}
125+
104126
$currentArray[$lastKey] = $valueToSet;
105127
}
106128

app/code/Magento/Webapi/Test/Unit/Controller/Rest/ParamsOverriderTest.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace Magento\Webapi\Test\Unit\Controller\Rest;
88

99
use \Magento\Authorization\Model\UserContextInterface;
10+
use Magento\Framework\Api\SimpleDataObjectConverter;
1011

1112
/**
1213
* Test Magento\Webapi\Controller\Rest\ParamsOverrider
@@ -36,10 +37,31 @@ public function testOverrideParams($requestData, $parameters, $expectedOverridde
3637
['userContext' => $userContextMock]
3738
);
3839

40+
/** @var \PHPUnit_Framework_MockObject_MockObject $objectConverter */
41+
$objectConverter = $this->getMockBuilder(SimpleDataObjectConverter::class)
42+
->disableOriginalConstructor()
43+
->setMethods(['convertKeysToCamelCase'])
44+
->getMock();
45+
$objectConverter->expects($this->any())
46+
->method('convertKeysToCamelCase')
47+
->willReturnCallback(
48+
function (array $array) {
49+
$converted = [];
50+
foreach ($array as $key => $value) {
51+
$converted[mb_strtolower($key)] = $value;
52+
}
53+
54+
return $converted;
55+
}
56+
);
57+
3958
/** @var \Magento\Webapi\Controller\Rest\ParamsOverrider $paramsOverrider */
4059
$paramsOverrider = $objectManager->getObject(
4160
'Magento\Webapi\Controller\Rest\ParamsOverrider',
42-
['paramOverriders' => ['%customer_id%' => $paramOverriderCustomerId ]]
61+
[
62+
'paramOverriders' => ['%customer_id%' => $paramOverriderCustomerId ],
63+
'dataObjectConverter' => $objectConverter
64+
]
4365
);
4466

4567
$this->assertEquals($expectedOverriddenParams, $paramsOverrider->override($requestData, $parameters));

0 commit comments

Comments
 (0)