diff --git a/src/Extracting/Generator.php b/src/Extracting/Generator.php index 4d094c2c..cbafc2ff 100644 --- a/src/Extracting/Generator.php +++ b/src/Extracting/Generator.php @@ -301,7 +301,7 @@ public static function setObject(array &$results, string $path, $value, array $s { $parts = explode('.', $path); - array_pop($parts); // Get rid of the field name + $paramName = array_pop($parts); // Remove the field name $baseName = join('.', $parts); // For array fields, the type should be indicated in the source object by now; @@ -313,7 +313,20 @@ public static function setObject(array &$results, string $path, $value, array $s $baseNameInOriginalParams = substr($baseNameInOriginalParams, 0, -2); } - if (Arr::has($source, $baseNameInOriginalParams)) { + if (empty($baseNameInOriginalParams)) { + // If this is empty, it indicates that the body is an array of objects. (i.e. "[].param") + // Therefore, each parameter should be an element of the first object in that array. + $results[0][$paramName] = $value; + } elseif (Str::startsWith($path, '[]')) { + // If the body is an array, then any top level parameters (i.e. "[].param") would have been handled by the previous block + // Therefore, we assume that this is a child parameter (i.e. "[].parent.child" or "[].parent[].child" + + // Remove the top-level array brackets + $dotPath = substr($path, 3); + // Use correct dot notation for any child arrays + $dotPath = '0.' . str_replace('[]', '.0', $dotPath); + Arr::set($results, $dotPath, $value); + } elseif (Arr::has($source, $baseNameInOriginalParams)) { $parentData = Arr::get($source, $baseNameInOriginalParams); // Path we use for data_set $dotPath = str_replace('[]', '.0', $path); @@ -418,7 +431,7 @@ public static function nestArrayAndObjectFields(array $parameters) // If the user didn't add a parent field, we'll conveniently add it for them $parentName = rtrim(join('.', $parts), '[]'); - if (empty($parameters[$parentName])) { + if (!empty($parentName) && empty($parameters[$parentName])) { $normalisedParameters[$parentName] = [ "name" => $parentName, "type" => "object", @@ -427,6 +440,11 @@ public static function nestArrayAndObjectFields(array $parameters) "value" => [$fieldName => $parameter['value']], ]; } + + // If the body is an array, the parameter array must use sequential keys + if (Str::startsWith($name, '[].')) { + $name = count($normalisedParameters); + } } $normalisedParameters[$name] = $parameter; } diff --git a/tests/Unit/GeneratorTest.php b/tests/Unit/GeneratorTest.php index ad814731..11541dfc 100644 --- a/tests/Unit/GeneratorTest.php +++ b/tests/Unit/GeneratorTest.php @@ -129,6 +129,60 @@ public function clean_can_properly_parse_array_keys() ], $cleanBodyParameters); } + /** @test */ + public function clean_can_properly_parse_a_body_array() + { + $parameters = [ + '[].key1' => [ + 'type' => 'string', + 'value' => '43', + ], + '[].key2' => [ + 'type' => 'integer', + 'value' => 77, + ], + '[].key3' => [ + 'type' => 'object', + 'value'=> [], + ], + '[].key3.key1' => [ + 'type' => 'object', + 'value' => [], + ], + '[].key3.key1.objkey1' => [ + 'type' => 'string', + 'value' => 'hoho', + ], + '[].key3.key2' => [ + 'type' => 'array', + 'value' => [], + ], + '[].key3.key2[].subkey1' => [ + 'type' => 'string', + 'value' => 'haha', + ], + ]; + + $cleanBodyParameters = Generator::cleanParams($parameters); + + $this->assertEquals([ + [ + 'key1' => '43', + 'key2' => 77, + 'key3' => [ + 'key1' => [ + 'objkey1' => 'hoho', + ], + 'key2' => [ + [ + 'subkey1' => 'haha', + ] + ], + ] + ], + ], $cleanBodyParameters); + } + /** @test */ public function does_not_generate_values_for_excluded_params_and_excludes_them_from_clean_params() {