-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Description
Summary (*)
External classes such as DTO can not be used as part of extension attributes system if they are not arrays, because Magento2 will try to instantiate the object through the ObjectManager as if it was a \Magento\Framework\DataObject::class
Examples (*)
Example :
<extension_attributes for="Magento\Customer\Api\Data\CustomerInterface">
<attribute code="test1" type="MyVendor\Custom\DTO\MyDTOInterface[]"/>
<attribute code="test2" type="MyVendor\Custom\DTO\AnotherDTO"/>
</extension_attributes>
In this example, while calling :
// $customerInformation = []; -> array with data information
$this->dataObjectHelper->populateWithArray(
$customer->getDataModel(),
$customerInformation,
CustomerInterface::class
);
For the attribute test2
we will call :
- https://github.com/pepe1518/magento2/blob/master/vendor/magento/framework/Api/DataObjectHelper.php#L129
- Then https://github.com/pepe1518/magento2/blob/master/vendor/magento/framework/Api/DataObjectHelper.php#L205
As you see there, if the target type object is not part of the Magento "system" (i.e : not extending the DataObject class), it will not be created with the good data.
It leads the developer to duplicate the DTO class which is a non-sense because of the simplicity of such classes. Also, we could want to use direct DTO from external (vendor) modules such as SDK models.
Btw, it is counter-intuitive that we can define non DataObject extended objects in the extension_attributes.yml
but they are not completely handled in the system. It made me think that this is just a specific (and marginal) forgotten case.
The same happens here : https://github.com/pepe1518/magento2/blob/master/vendor/magento/framework/Api/DataObjectHelper.php#L215
Proposed solution
We could implement this kind of solution which is what is done for array typed objects :
if (is_subclass_of($extensionAttributeType, DataObject::class)) {
$value[$extensionAttributeKey] = $this->objectFactory->create(
$extensionAttributeType,
['data' => $extensionAttributeValue]
);
} else {
$extensionAttributeInner = $this->objectFactory->create($extensionAttributeType, []);
$this->populateWithArray(
$extensionAttributeInner,
$extensionAttributeValue,
$extensionAttributeType
);
$value[$extensionAttributeKey] = $extensionAttributeInner;
}
Based on your suggestions/answers, I could make a PR for this.
Thanks,
Melvin
Below attached module helps in issue reproduction
Please provide Severity assessment for the Issue as Reporter. This information will help during Confirmation and Issue triage processes.
- Severity: S0 - Affects critical data or functionality and leaves users with no workaround.
- Severity: S1 - Affects critical data or functionality and forces users to employ a workaround.
- [ x] Severity: S2 - Affects non-critical data or functionality and forces users to employ a workaround.
- Severity: S3 - Affects non-critical data or functionality and does not force users to employ a workaround.
- Severity: S4 - Affects aesthetics, professional look and feel, “quality” or “usability”.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status