Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit ebbee92

Browse files
🔃 [EngCom] Public Pull Requests - 2.3-develop
Accepted Public Pull Requests: - magento/magento2#15039: [2.3-develop][Forwardport] Transport variable can not be altered in email_invoice_set_template_vars_before Event (by @gwharton) - magento/magento2#14801: Enable WebAPI interface to handle parameters through constructor (by @phoenix128) Fixed GitHub Issues: - magento/magento2#10210: Transport variable can not be altered in email_invoice_set_template_vars_before Event (reported by @diybook) has been fixed in magento/magento2#15039 by @gwharton in 2.3-develop branch Related commits: 1. 6dff3a5
2 parents 2e157a9 + 56cf593 commit ebbee92

File tree

5 files changed

+137
-13
lines changed

5 files changed

+137
-13
lines changed

app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,17 @@ protected function prepareTemplate(Order $order)
131131
'formattedShippingAddress' => $this->getFormattedShippingAddress($order),
132132
'formattedBillingAddress' => $this->getFormattedBillingAddress($order),
133133
];
134-
$transport = new DataObject($transport);
134+
$transportObject = new DataObject($transport);
135135

136+
/**
137+
* Event argument `transport` is @deprecated. Use `transportObject` instead.
138+
*/
136139
$this->eventManager->dispatch(
137140
'email_order_set_template_vars_before',
138-
['sender' => $this, 'transport' => $transport]
141+
['sender' => $this, 'transport' => $transportObject->getData(), 'transportObject' => $transportObject]
139142
);
140143

141-
$this->templateContainer->setTemplateVars($transport->getData());
144+
$this->templateContainer->setTemplateVars($transportObject->getData());
142145

143146
parent::prepareTemplate($order);
144147
}

lib/internal/Magento/Framework/Webapi/ServiceInputProcessor.php

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@
55
* Copyright © Magento, Inc. All rights reserved.
66
* See COPYING.txt for license details.
77
*/
8+
declare(strict_types=1);
89

910
namespace Magento\Framework\Webapi;
1011

11-
use Magento\Framework\Webapi\ServiceTypeToEntityTypeMap;
1212
use Magento\Framework\Api\AttributeValue;
1313
use Magento\Framework\Api\AttributeValueFactory;
1414
use Magento\Framework\Api\SimpleDataObjectConverter;
1515
use Magento\Framework\Exception\InputException;
1616
use Magento\Framework\Exception\SerializationException;
17+
use Magento\Framework\ObjectManager\ConfigInterface;
1718
use Magento\Framework\ObjectManagerInterface;
1819
use Magento\Framework\Phrase;
1920
use Magento\Framework\Reflection\MethodsMap;
@@ -66,6 +67,11 @@ class ServiceInputProcessor implements ServicePayloadConverterInterface
6667
*/
6768
private $serviceTypeToEntityTypeMap;
6869

70+
/**
71+
* @var ConfigInterface
72+
*/
73+
private $config;
74+
6975
/**
7076
* Initialize dependencies.
7177
*
@@ -75,14 +81,16 @@ class ServiceInputProcessor implements ServicePayloadConverterInterface
7581
* @param CustomAttributeTypeLocatorInterface $customAttributeTypeLocator
7682
* @param MethodsMap $methodsMap
7783
* @param ServiceTypeToEntityTypeMap $serviceTypeToEntityTypeMap
84+
* @param ConfigInterface $config
7885
*/
7986
public function __construct(
8087
TypeProcessor $typeProcessor,
8188
ObjectManagerInterface $objectManager,
8289
AttributeValueFactory $attributeValueFactory,
8390
CustomAttributeTypeLocatorInterface $customAttributeTypeLocator,
8491
MethodsMap $methodsMap,
85-
ServiceTypeToEntityTypeMap $serviceTypeToEntityTypeMap = null
92+
ServiceTypeToEntityTypeMap $serviceTypeToEntityTypeMap = null,
93+
ConfigInterface $config = null
8694
) {
8795
$this->typeProcessor = $typeProcessor;
8896
$this->objectManager = $objectManager;
@@ -91,6 +99,8 @@ public function __construct(
9199
$this->methodsMap = $methodsMap;
92100
$this->serviceTypeToEntityTypeMap = $serviceTypeToEntityTypeMap
93101
?: \Magento\Framework\App\ObjectManager::getInstance()->get(ServiceTypeToEntityTypeMap::class);
102+
$this->config = $config
103+
?: \Magento\Framework\App\ObjectManager::getInstance()->get(ConfigInterface::class);
94104
}
95105

96106
/**
@@ -154,6 +164,33 @@ public function process($serviceClassName, $serviceMethodName, array $inputArray
154164
return $inputData;
155165
}
156166

167+
/**
168+
* @param string $className
169+
* @param array $data
170+
* @return array
171+
* @throws \ReflectionException
172+
*/
173+
private function getConstructorData(string $className, array $data): array
174+
{
175+
$preferenceClass = $this->config->getPreference($className);
176+
$class = new ClassReflection($preferenceClass ?: $className);
177+
178+
$constructor = $class->getConstructor();
179+
if ($constructor === null) {
180+
return [];
181+
}
182+
183+
$res = [];
184+
$parameters = $constructor->getParameters();
185+
foreach ($parameters as $parameter) {
186+
if (isset($data[$parameter->getName()])) {
187+
$res[$parameter->getName()] = $data[$parameter->getName()];
188+
}
189+
}
190+
191+
return $res;
192+
}
193+
157194
/**
158195
* Creates a new instance of the given class and populates it with the array of data. The data can
159196
* be in different forms depending on the adapter being used, REST vs. SOAP. For REST, the data is
@@ -163,6 +200,7 @@ public function process($serviceClassName, $serviceMethodName, array $inputArray
163200
* @param array $data
164201
* @return object the newly created and populated object
165202
* @throws \Exception
203+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
166204
*/
167205
protected function _createFromArray($className, $data)
168206
{
@@ -174,9 +212,17 @@ protected function _createFromArray($className, $data)
174212
if (is_subclass_of($className, self::EXTENSION_ATTRIBUTES_TYPE)) {
175213
$className = substr($className, 0, -strlen('Interface'));
176214
}
177-
$object = $this->objectManager->create($className);
178215

216+
// Primary method: assign to constructor parameters
217+
$constructorArgs = $this->getConstructorData($className, $data);
218+
$object = $this->objectManager->create($className, $constructorArgs);
219+
220+
// Secondary method: fallback to setter methods
179221
foreach ($data as $propertyName => $value) {
222+
if (isset($constructorArgs[$propertyName])) {
223+
continue;
224+
}
225+
180226
// Converts snake_case to uppercase CamelCase to help form getter/setter method names
181227
// This use case is for REST only. SOAP request data is already camel cased
182228
$camelCaseProperty = SimpleDataObjectConverter::snakeCaseToUpperCamelCase($propertyName);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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\Framework\Webapi\Test\Unit\ServiceInputProcessor;
9+
10+
class SimpleConstructor
11+
{
12+
/**
13+
* @var int
14+
*/
15+
private $entityId;
16+
17+
/**
18+
* @var string
19+
*/
20+
private $name;
21+
22+
public function __construct(
23+
int $entityId,
24+
string $name
25+
) {
26+
$this->entityId = $entityId;
27+
$this->name = $name;
28+
}
29+
30+
/**
31+
* @return int|null
32+
*/
33+
public function getEntityId()
34+
{
35+
return $this->entityId;
36+
}
37+
38+
/**
39+
* @return string|null
40+
*/
41+
public function getName()
42+
{
43+
return $this->name;
44+
}
45+
}

lib/internal/Magento/Framework/Webapi/Test/Unit/ServiceInputProcessor/TestService.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@
55
*/
66
namespace Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor;
77

8-
use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\AssociativeArray;
9-
use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\DataArray;
10-
use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\Nested;
11-
use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\SimpleArray;
12-
138
class TestService
149
{
1510
const DEFAULT_VALUE = 42;
@@ -25,6 +20,15 @@ public function simple($entityId, $name)
2520
return [$entityId, $name];
2621
}
2722

23+
/**
24+
* @param \Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\SimpleConstructor $simpleConstructor
25+
* @return \Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\SimpleConstructor
26+
*/
27+
public function simpleConstructor(SimpleConstructor $simpleConstructor)
28+
{
29+
return $simpleConstructor;
30+
}
31+
2832
/**
2933
* @param int $entityId
3034
* @return string[]
@@ -34,6 +38,15 @@ public function simpleDefaultValue($entityId = self::DEFAULT_VALUE)
3438
return [$entityId];
3539
}
3640

41+
/**
42+
* @param int $entityId
43+
* @return string[]
44+
*/
45+
public function constructorArguments($entityId = self::DEFAULT_VALUE)
46+
{
47+
return [$entityId];
48+
}
49+
3750
/**
3851
* @param \Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\Nested $nested
3952
* @return \Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\Nested

lib/internal/Magento/Framework/Webapi/Test/Unit/ServiceInputProcessorTest.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Magento\Framework\Serialize\SerializerInterface;
1010
use Magento\Framework\Webapi\ServiceInputProcessor;
1111
use Magento\Framework\Webapi\ServiceTypeToEntityTypeMap;
12+
use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\SimpleConstructor;
1213
use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\WebapiBuilderFactory;
1314
use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\AssociativeArray;
1415
use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\DataArray;
@@ -59,8 +60,8 @@ protected function setUp()
5960
$this->objectManagerMock->expects($this->any())
6061
->method('create')
6162
->willReturnCallback(
62-
function ($className) use ($objectManager) {
63-
return $objectManager->getObject($className);
63+
function ($className, $arguments = []) use ($objectManager) {
64+
return $objectManager->getObject($className, $arguments);
6465
}
6566
);
6667

@@ -202,6 +203,22 @@ public function testNestedDataProperties()
202203
$this->assertEquals('Test', $details->getName());
203204
}
204205

206+
public function testSimpleConstructorProperties()
207+
{
208+
$data = ['simpleConstructor' => ['entityId' => 15, 'name' => 'Test']];
209+
$result = $this->serviceInputProcessor->process(
210+
\Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\TestService::class,
211+
'simpleConstructor',
212+
$data
213+
);
214+
$this->assertNotNull($result);
215+
$arg = $result[0];
216+
217+
$this->assertTrue($arg instanceof SimpleConstructor);
218+
$this->assertEquals(15, $arg->getEntityId());
219+
$this->assertEquals('Test', $arg->getName());
220+
}
221+
205222
public function testSimpleArrayProperties()
206223
{
207224
$data = ['ids' => [1, 2, 3, 4]];

0 commit comments

Comments
 (0)