/** * @test */ public function arrayMergeRecursiveCallbackConvertsSimpleValuesWithGivenClosureAndReturnedSimpleTypesOverwrite() { $inputArray1 = ['k1' => 'v1', 'k2' => ['k2.1' => 'v2.1'], 'k3' => ['k3.1' => 'value']]; $inputArray2 = ['k2' => 'v2.2', 'k3' => null]; $expected = ['k1' => 'v1', 'k2' => ['k2.1' => 'v2.1', '__convertedValue' => 'v2.2'], 'k3' => null]; $actual = Arrays::arrayMergeRecursiveOverruleWithCallback($inputArray1, $inputArray2, function ($simpleType) { if ($simpleType === null) { return null; } return ['__convertedValue' => $simpleType]; }); $this->assertSame($expected, $actual); }
/** * Merges the prototype chain into the configuration. * * @param array $configuration * @param array $currentPrototypeDefinitions * @return array * @throws Exception */ protected function mergePrototypesWithConfigurationForPathSegment($configuration, &$currentPrototypeDefinitions) { $currentPathSegmentType = $configuration['__objectType']; if (isset($currentPrototypeDefinitions[$currentPathSegmentType])) { $prototypeMergingOrder = [$currentPathSegmentType]; if (isset($currentPrototypeDefinitions[$currentPathSegmentType]['__prototypeChain'])) { $prototypeMergingOrder = array_merge($currentPrototypeDefinitions[$currentPathSegmentType]['__prototypeChain'], $prototypeMergingOrder); } $currentPrototypeWithInheritanceTakenIntoAccount = []; foreach ($prototypeMergingOrder as $prototypeName) { if (!array_key_exists($prototypeName, $currentPrototypeDefinitions)) { throw new Exception(sprintf('The TypoScript object `%s` which you tried to inherit from does not exist. Maybe you have a typo on the right hand side of your inheritance statement for `%s`.', $prototypeName, $currentPathSegmentType), 1427134340); } $currentPrototypeWithInheritanceTakenIntoAccount = Arrays::arrayMergeRecursiveOverruleWithCallback($currentPrototypeWithInheritanceTakenIntoAccount, $currentPrototypeDefinitions[$prototypeName], $this->simpleTypeToArrayClosure); } // We merge the already flattened prototype with the current configuration (in that order), // to make sure that the current configuration (not being defined in the prototype) wins. $configuration = Arrays::arrayMergeRecursiveOverruleWithCallback($currentPrototypeWithInheritanceTakenIntoAccount, $configuration, $this->simpleTypeToArrayClosure); // If context-dependent prototypes are set (such as prototype("foo").prototype("baz")), // we update the current prototype definitions. if (isset($currentPrototypeWithInheritanceTakenIntoAccount['__prototypes'])) { $currentPrototypeDefinitions = Arrays::arrayMergeRecursiveOverruleWithCallback($currentPrototypeDefinitions, $currentPrototypeWithInheritanceTakenIntoAccount['__prototypes'], $this->simpleTypeToArrayClosure); } } return $configuration; }