Description
Bug Report
Q | A |
---|---|
BC Break | no |
Version | 2.4.3 |
Summary
For the following query I am getting a duplicated part of the query string:
$builder
->field('dataModel.dynamicDataModel.properties.meetingInfo.properties.date.value')
->lte(new \DateTime('2021-01-22'));
var_dump($builder->getQuery()->debug());
array(1) {
["dataModel.dynamicDataModel.properties.meetingInfo.properties.date.value.date.value"] ...
^^^^^^^^^^ this is duplicated for some reason
This seems to happen when there is a mapping along the path of the query with this metadata:
embedded: true
type: many
targetDocument: null
strategy: set
How to reproduce
I have pinned this down to this location in DocumentPersister. In my case, when that code is being executed, I have this context:
$fieldName
is properties.meetingInfo.properties.date.value
$mapping
has these values:
{
"type": "many",
"embedded": true,
"targetDocument": null,
"collectionClass": "RH\\CoreBundle\\Components\\DoctrineBridge\\Collections\\RHArrayCollection",
"name": "properties",
"strategy": "set",
"nullable": false,
"fieldName": "properties",
"discriminatorField": "type",
"discriminatorMap": {
"null": "RH\\DynamicDataBundle\\Document\\Data\\NullData",
"array": "RH\\DynamicDataBundle\\Document\\Data\\ArrayData",
...
}
}
The problem is that when the code linked above is executed:
// No further processing for fields without a targetDocument mapping
if (! isset($mapping['targetDocument'])) {
if ($nextObjectProperty) {
$fieldName .= '.' . $nextObjectProperty; // ---> This is where the suffix gets duplicated and causes problems
}
return [[$fieldName, $value]];
}
At the point before $fieldName .= '.' . $nextObjectProperty;
is executed, the values are:
$fieldName == 'properties.meetingInfo.properties.date.value'
$nextObjectProperty == 'date.value'
Which causes the returned field name to contain the .date.value
part twice.
The values are set by the condition on line 1276 evaluating to true:
if (
$mapping['type'] === ClassMetadata::MANY && CollectionHelper::isHash($mapping['strategy'])
&& isset($e[2])
) {
$objectProperty = $e[2];
$objectPropertyPrefix = $e[1] . '.';
$nextObjectProperty = implode('.', array_slice($e, 3));
}
This if-branch does not change the value of $fieldName
like the other branches do, and thus when a part of the string is then appended to it, it is wrong. If I add the same line as is in the other if-branch below:
$fieldName = $e[0] . '.' . $e[1] . '.' . $e[2];
Then my case starts working as expected.
I don't understand the logic of the code well enough to know what is the correct fix here. It's either
- Adding the
$fieldName = $e[0] . '.' . $e[1] . '.' . $e[2];
to the first if-branch, or - Changing the condition so that it evaluates to
false
for the$mapping
context I provided above (in which case if-branch on line 1288 gets executed)