- Issue created by @kachinsky
I've faced the strange behavior of computed fields when approving an order with PaymentApproveResource.
Before creating the JSON:API response object, PaymentApproveResource creates a resource object for the order with createIndividualDataFromEntity method, where I got the exception below:
InvalidArgumentException: Field 0 is unknown. in Drupal\Core\Entity\ContentEntityBase->getTranslatedField() (regel 616 van /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php).
Using the stack trace I was able to discover that the problem lies in the OrderProfileItemList class, setValue() method.
It expects the $value variable to be an array containing an address key with an array of address properties.
But for some reason in this particular situation the structure of the variable is different:
0 => [
'address' => [...]
]
instead of the 'address' key, it gets the 0 key and 'address' as a value and triggers an exception in profile set method
foreach ($values as $property_name => $property_value) {
if ($property_name === 'entity') {
continue;
}
$profile->set($property_name, $property_value);
}
I was not able to understand why this happen, here is a stuck trace.
#0 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(597): Drupal\Core\Entity\ContentEntityBase->getTranslatedField(0, 'x-default')
#1 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(657): Drupal\Core\Entity\ContentEntityBase->get(0)
#2 /app/web/modules/contrib/commerce_api/src/Plugin/Field/FieldType/OrderProfileItemList.php(60): Drupal\Core\Entity\ContentEntityBase->set(0, Array)
#3 /app/web/core/lib/Drupal/Core/TypedData/TypedDataManager.php(208): Drupal\commerce_api\Plugin\Field\FieldType\OrderProfileItemList->setValue(Array, false)
#4 /app/web/core/lib/Drupal/Core/Field/FieldTypePluginManager.php(83): Drupal\Core\TypedData\TypedDataManager->getPropertyInstance(Object(Drupal\Core\Entity\Plugin\DataType\EntityAdapter), 'billing_informa...', Array)
#5 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(633): Drupal\Core\Field\FieldTypePluginManager->createFieldItemList(Object(Drupal\commerce_order\Entity\Order), 'billing_informa...', Array)
#6 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(597): Drupal\Core\Entity\ContentEntityBase->getTranslatedField('billing_informa...', 'x-default')
#7 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(668): Drupal\Core\Entity\ContentEntityBase->get('billing_informa...')
#8 /app/web/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php(112): Drupal\Core\Entity\ContentEntityBase->getFields(true)
#9 /app/web/core/lib/Drupal/Core/TypedData/TypedDataInternalPropertiesHelper.php(20): Drupal\Core\Entity\Plugin\DataType\EntityAdapter->getProperties(true)
#10 /app/web/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php(304): Drupal\Core\TypedData\TypedDataInternalPropertiesHelper::getNonInternalProperties(Object(Drupal\Core\Entity\Plugin\DataType\EntityAdapter))
#11 /app/web/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php(243): Drupal\jsonapi\JsonApiResource\ResourceObject::extractContentEntityFields(Object(Drupal\commerce_api\ResourceType\RenamableResourceType), Object(Drupal\commerce_order\Entity\Order))
#12 /app/web/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php(126): Drupal\jsonapi\JsonApiResource\ResourceObject::extractFieldsFromEntity(Object(Drupal\commerce_api\ResourceType\RenamableResourceType), Object(Drupal\commerce_order\Entity\Order))
#13 /app/web/core/modules/jsonapi/src/Access/EntityAccessChecker.php(141): Drupal\jsonapi\JsonApiResource\ResourceObject::createFromEntity(Object(Drupal\commerce_api\ResourceType\RenamableResourceType), Object(Drupal\commerce_order\Entity\Order))
#14 /app/web/modules/contrib/jsonapi_resources/src/Resource/EntityResourceBase.php(102): Drupal\jsonapi\Access\EntityAccessChecker->getAccessCheckedResourceObject(Object(Drupal\commerce_order\Entity\Order))
#15 /app/web/modules/contrib/jsonapi_resources/src/Resource/EntityResourceBase.php(74): Drupal\jsonapi_resources\Resource\EntityResourceBase->createCollectionDataFromEntities(Array, true)
#16 /app/web/modules/contrib/commerce_api/src/Resource/PaymentGateway/PaymentApproveResource.php(127): Drupal\jsonapi_resources\Resource\EntityResourceBase->createIndividualDataFromEntity(Object(Drupal\commerce_order\Entity\Order))
#17 /app/web/modules/contrib/commerce_api/src/Resource/PaymentGateway/PaymentApproveResource.php(66): Drupal\commerce_api\Resource\PaymentGateway\PaymentApproveResource->doProcess(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\commerce_order\Entity\Order))
The same behaviour applies to the PaymentInstrumentItemList.
The exception below was thrown because the structure of the $values variable is again different than expected and contains key 0 and an array value with payment_gateway_id.
if ($values['payment_gateway_id'] === NULL) {
throw new UnprocessableEntityHttpException('You must specify a `payment_gateway_id`');
}
Active
1.0
Code