diff --git a/src/MergeProp.php b/src/MergeProp.php index 499b43f4..4600b634 100644 --- a/src/MergeProp.php +++ b/src/MergeProp.php @@ -13,11 +13,13 @@ class MergeProp implements Mergeable /** * @param mixed $value + * @param string[] $mergeStrategies */ - public function __construct($value) + public function __construct($value, array $mergeStrategies = []) { $this->value = $value; $this->merge = true; + $this->mergeStrategies = $mergeStrategies; } public function __invoke() diff --git a/src/MergesProps.php b/src/MergesProps.php index 4086a698..0e442f58 100644 --- a/src/MergesProps.php +++ b/src/MergesProps.php @@ -8,6 +8,8 @@ trait MergesProps protected bool $deepMerge = false; + protected array $mergeStrategies = []; + public function merge(): static { $this->merge = true; @@ -31,4 +33,9 @@ public function shouldDeepMerge(): bool { return $this->deepMerge; } + + public function mergeStrategies(): array + { + return $this->mergeStrategies; + } } diff --git a/src/Response.php b/src/Response.php index 578698af..91df689e 100644 --- a/src/Response.php +++ b/src/Response.php @@ -319,6 +319,15 @@ public function resolveMergeProps(Request $request): array ->filter(fn ($prop) => $prop->shouldDeepMerge()) ->keys(); + $mergeStrategies = $mergeProps + ->map(function ($prop, $key) { + return collect($prop->mergeStrategies()) + ->map(fn ($strategy) => $key.".".$strategy) + ->toArray(); + }) + ->flatten() + ->values(); + $mergeProps = $mergeProps ->filter(fn ($prop) => ! $prop->shouldDeepMerge()) ->keys(); @@ -326,6 +335,7 @@ public function resolveMergeProps(Request $request): array return array_filter([ 'mergeProps' => $mergeProps->toArray(), 'deepMergeProps' => $deepMergeProps->toArray(), + 'mergeStrategies' => $mergeStrategies->toArray(), ], fn ($prop) => count($prop) > 0); } diff --git a/src/ResponseFactory.php b/src/ResponseFactory.php index 74fd4e8b..3cc8f19d 100644 --- a/src/ResponseFactory.php +++ b/src/ResponseFactory.php @@ -134,10 +134,11 @@ public function merge($value): MergeProp /** * @param mixed $value + * @parram null|string|string[] $mergeStrategies */ - public function deepMerge($value): MergeProp + public function deepMerge($value, $mergeStrategies = null): MergeProp { - return (new MergeProp($value))->deepMerge(); + return (new MergeProp($value, Arr::wrap($mergeStrategies)))->deepMerge(); } /** diff --git a/tests/DeepMergePropTest.php b/tests/DeepMergePropTest.php index b0fe8348..4e282dec 100644 --- a/tests/DeepMergePropTest.php +++ b/tests/DeepMergePropTest.php @@ -27,4 +27,11 @@ public function test_can_resolve_bindings_when_invoked(): void $this->assertInstanceOf(Request::class, $mergeProp()); } + + public function test_can_use_single_string_as_merge_strategy(): void + { + $mergeProp = (new MergeProp(['key' => 'value'], ['key']))->deepMerge(); + + $this->assertEquals(['key'], $mergeProp->mergeStrategies()); + } } diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php index 976ee4da..e3a9f25a 100644 --- a/tests/ResponseTest.php +++ b/tests/ResponseTest.php @@ -201,6 +201,45 @@ public function test_server_response_with_deep_merge_props(): void $this->assertSame('
', $view->render()); } + public function test_server_response_with_merge_strategies(): void + { + $request = Request::create('/user/123', 'GET'); + + $user = ['name' => 'Jonathan']; + $response = new Response( + 'User/Edit', + [ + 'user' => $user, + 'foo' => (new MergeProp('foo value', ['foo-key']))->deepMerge(), + 'bar' => (new MergeProp('bar value', ['bar-key']))->deepMerge(), + ], + 'app', + '123' + ); + $response = $response->toResponse($request); + $view = $response->getOriginalContent(); + $page = $view->getData()['page']; + + $this->assertInstanceOf(BaseResponse::class, $response); + $this->assertInstanceOf(View::class, $view); + + $this->assertSame('User/Edit', $page['component']); + $this->assertSame('Jonathan', $page['props']['user']['name']); + $this->assertSame('/user/123', $page['url']); + $this->assertSame('123', $page['version']); + $this->assertSame([ + 'foo', + 'bar', + ], $page['deepMergeProps']); + $this->assertSame([ + 'foo.foo-key', + 'bar.bar-key', + ], $page['mergeStrategies']); + $this->assertFalse($page['clearHistory']); + $this->assertFalse($page['encryptHistory']); + $this->assertSame('
', $view->render()); + } + public function test_server_response_with_defer_and_merge_props(): void { $request = Request::create('/user/123', 'GET');