Skip to content

Commit e090855

Browse files
committed
PHPLIB-242: Create helper to apply field paths for type maps
1 parent 01bf56b commit e090855

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

src/functions.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,46 @@ function recursive_copy($element) {
241241

242242
return clone $element;
243243
}
244+
245+
/**
246+
* Creates a type map to apply to a field type
247+
*
248+
* This is used in the Aggregate, Distinct, and FindAndModify operations to
249+
* apply the root-level type map to the document that will be returned. It also
250+
* replaces the root type with object for consistency within these operations
251+
*
252+
* An existing type map for the given field path will not be overwritten
253+
*
254+
* @internal
255+
* @param array $typeMap The existing typeMap
256+
* @param string $fieldPath The field path to apply the root type to
257+
* @return array
258+
*/
259+
function create_field_path_type_map(array $typeMap, $fieldPath)
260+
{
261+
// If some field paths already exist, we prefix them with the field path we are assuming as the new root
262+
if (isset($typeMap['fieldPaths']) && is_array($typeMap['fieldPaths'])) {
263+
$fieldPaths = $typeMap['fieldPaths'];
264+
265+
$typeMap['fieldPaths'] = [];
266+
foreach ($fieldPaths as $existingFieldPath => $type) {
267+
$typeMap['fieldPaths'][$fieldPath . '.' . $existingFieldPath] = $type;
268+
}
269+
}
270+
271+
// If a root typemap was set, apply this to the field object
272+
if (isset($typeMap['root'])) {
273+
$typeMap['fieldPaths'][$fieldPath] = $typeMap['root'];
274+
}
275+
276+
/* Special case if we want to convert an array, in which case we need to
277+
* ensure that the field containing the array is exposed as an array,
278+
* instead of the type given in the type map's array key. */
279+
if (substr($fieldPath, -2, 2) === '.$') {
280+
$typeMap['fieldPaths'][substr($fieldPath, 0, -2)] = 'array';
281+
}
282+
283+
$typeMap['root'] = 'object';
284+
285+
return $typeMap;
286+
}

tests/FunctionsTest.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,70 @@ public function provideMapReduceOutValues()
135135
[ ['replace' => 'collectionName'], false ],
136136
];
137137
}
138+
139+
/**
140+
* @dataProvider provideTypeMapValues
141+
*/
142+
public function testCreateFieldPathTypeMap(array $expected, array $typeMap, $fieldPath = 'field')
143+
{
144+
$this->assertEquals($expected, \MongoDB\create_field_path_type_map($typeMap, $fieldPath));
145+
}
146+
147+
public function provideTypeMapValues()
148+
{
149+
return [
150+
'No root type' => [
151+
['document' => 'array', 'root' => 'object'],
152+
['document' => 'array'],
153+
],
154+
'No field path' => [
155+
['root' => 'object', 'fieldPaths' => ['field' => 'array']],
156+
['root' => 'array'],
157+
],
158+
'Field path exists' => [
159+
['root' => 'object', 'fieldPaths' => ['field' => 'array', 'field.field' => 'object']],
160+
['root' => 'array', 'fieldPaths' => ['field' => 'object']],
161+
],
162+
'Nested field path' => [
163+
['root' => 'object', 'fieldPaths' => ['field' => 'object', 'field.nested' => 'array']],
164+
['root' => 'object', 'fieldPaths' => ['nested' => 'array']],
165+
],
166+
'Array field path converted to array' => [
167+
[
168+
'root' => 'object',
169+
'array' => 'MongoDB\Model\BSONArray',
170+
'fieldPaths' => [
171+
'field' => 'array',
172+
'field.$' => 'object',
173+
'field.$.nested' => 'array',
174+
]
175+
],
176+
[
177+
'root' => 'object',
178+
'array' => 'MongoDB\Model\BSONArray',
179+
'fieldPaths' => [
180+
'nested' => 'array',
181+
]
182+
],
183+
'field.$',
184+
],
185+
'Array field path without root key' => [
186+
[
187+
'root' => 'object',
188+
'array' => 'MongoDB\Model\BSONArray',
189+
'fieldPaths' => [
190+
'field' => 'array',
191+
'field.$.nested' => 'array',
192+
]
193+
],
194+
[
195+
'array' => 'MongoDB\Model\BSONArray',
196+
'fieldPaths' => [
197+
'nested' => 'array',
198+
]
199+
],
200+
'field.$',
201+
],
202+
];
203+
}
138204
}

0 commit comments

Comments
 (0)