- Issue created by @rp7
- Merge request !54Make JsonPath::getMappedSourceFieldName() with more advanced JSONPath notations → (Open) created by rp7
- Issue was unassigned.
- Status changed to Needs review
3 months ago 8:00pm 19 September 2024 - 🇫🇷France guignonv
This is not so simple from my perspective and I'm sorry there will be some reading here, to understand... :s
I stated in the API doc for
FieldMapperInterface::getMappedSourceFieldName()
:* This method can be used to know which raw data source field was used by a * given Drupal field property. * * The returned source field name might be a simple field name or a path to a * given sub-field using dots ('.') as separator. For instance, if a Drupal * field property value is mapped to the sub-field "processed" of the * sub-field "body" of the field "attributes" of a raw data array, the * returned source field name would be "attributes.body.processed". However, * other more complex sub-field specification (such as '*' for the simple * propertymapper or JSON Path mappings) are not supported and must not be * returned. * * To get all the raw source fields involved in a complex property mapping, * use self::addFieldValuesToRawData() with only data from the requested * Drupal field and property. It would return a raw structure containing only * the raw fields used by the Drupal field mapping unless the reverse mapping * is not possible.
The API doc for the same method in
PropertyMapperInterface::getMappedSourceFieldName()
is a bit less precise and would allow the behavior you expect.The reason for this "new" method (not in v2) is to be able to directly work on a source field without needing to map when it is possible. At the beginning, I was only allowing simple fields and not sub-fields. But then, I noticed in some cases, using a sub-field is not really different form using a simple field and I allowed the use of "dots" for the field path. A very similar syntax is used by Drupal query API and that's what made me change my mind as well as changing the original syntax of the old "simple field mapper" (now "simple property mapper") that was using slashes instead of dots.
Where do we need to use that method? When trying to join external data from different sources using an aggregator, when storage clients needs to now which Drupal field is mapped to which source field often for filtering queries on source-side, in External Entity Storage to faster map ids to entities (but direct mapping is not required as there is a slower workaround), and for the external entity manager to report mapping issues (again, not necessary there, NULL can be returned).
There are currently parts of the external entities module that need to be updated to support dots in the field path (which can be considered as bugs in the current beta). There is also some work to do in the storage clients
::transliterateDrupalFilters()
to manage that notation as well as inStorageClientBase::testDrupalConditions()
to fully support Drupal field syntax for filtering (see @todo lines 585, 594, 618 for instance).If we support the syntax
$.myField[*].myProperty --> myField.myProperty
for instance, then in those places, it will be (I believe) hard to manage. Consider those 2 arrays:$array1 = [ 'myField' => [ [ 'myProperty' => 'value1', ], [ 'myProperty' => 'value2', ], ], ]; $array2 = [ 'myField' => [ 'myProperty' => 'value1', ], ];
$.myField[*].myProperty
on $array1 one will return ['value1', 'value2'] while it will return NULL on $array2. However, the behavior your expecting (ie. "myField.myProperty") should work on both arrays and should let us find ['value1', 'value2'] for $array1 and ['value1'] for $array2.We could consider clarifying the API and adjust the code of
FieldMapperInterface::getMappedSourceFieldName()
to allowPropertyMapperInterface::getMappedSourceFieldName()
to return a simplified expression of the mapping when it is possible, and this case "$.myField[*].myProperty" would be returned as "myField.*.myProperty" but then,FieldMapperInterface::getMappedSourceFieldName()
would detect the '*' and return NULL because it would be still only allowed to return very simple mapping expressions with only dots supported. I would agree on that but it would not solve your original problem.I think we should consider your problem differently and see how the code could be changed to manage the case when you got a complex JSONPath mapping and ::getMappedSourceFieldName() returns NULL. There are workarounds to solve complex mapping (see ExternalEntityStorage class near line 600 for example).
So for me, the current code work as expected but there is still a problem to solve (feature request).