Skip to content

Commit fe6659d

Browse files
authored
Merge pull request #732 from mpociot/feature/merge-strategies
[2.x] Allow deepMerge on custom properties
2 parents 6e7606f + b5942a5 commit fe6659d

File tree

6 files changed

+69
-3
lines changed

6 files changed

+69
-3
lines changed

src/MergeProp.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ class MergeProp implements Mergeable
1313

1414
/**
1515
* @param mixed $value
16+
* @param string[] $mergeStrategies
1617
*/
17-
public function __construct($value)
18+
public function __construct($value, array $mergeStrategies = [])
1819
{
1920
$this->value = $value;
2021
$this->merge = true;
22+
$this->mergeStrategies = $mergeStrategies;
2123
}
2224

2325
public function __invoke()

src/MergesProps.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ trait MergesProps
88

99
protected bool $deepMerge = false;
1010

11+
protected array $mergeStrategies = [];
12+
1113
public function merge(): static
1214
{
1315
$this->merge = true;
@@ -31,4 +33,9 @@ public function shouldDeepMerge(): bool
3133
{
3234
return $this->deepMerge;
3335
}
36+
37+
public function mergeStrategies(): array
38+
{
39+
return $this->mergeStrategies;
40+
}
3441
}

src/Response.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,13 +319,23 @@ public function resolveMergeProps(Request $request): array
319319
->filter(fn ($prop) => $prop->shouldDeepMerge())
320320
->keys();
321321

322+
$mergeStrategies = $mergeProps
323+
->map(function ($prop, $key) {
324+
return collect($prop->mergeStrategies())
325+
->map(fn ($strategy) => $key.".".$strategy)
326+
->toArray();
327+
})
328+
->flatten()
329+
->values();
330+
322331
$mergeProps = $mergeProps
323332
->filter(fn ($prop) => ! $prop->shouldDeepMerge())
324333
->keys();
325334

326335
return array_filter([
327336
'mergeProps' => $mergeProps->toArray(),
328337
'deepMergeProps' => $deepMergeProps->toArray(),
338+
'mergeStrategies' => $mergeStrategies->toArray(),
329339
], fn ($prop) => count($prop) > 0);
330340
}
331341

src/ResponseFactory.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,11 @@ public function merge($value): MergeProp
134134

135135
/**
136136
* @param mixed $value
137+
* @parram null|string|string[] $mergeStrategies
137138
*/
138-
public function deepMerge($value): MergeProp
139+
public function deepMerge($value, $mergeStrategies = null): MergeProp
139140
{
140-
return (new MergeProp($value))->deepMerge();
141+
return (new MergeProp($value, Arr::wrap($mergeStrategies)))->deepMerge();
141142
}
142143

143144
/**

tests/DeepMergePropTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,11 @@ public function test_can_resolve_bindings_when_invoked(): void
2727

2828
$this->assertInstanceOf(Request::class, $mergeProp());
2929
}
30+
31+
public function test_can_use_single_string_as_merge_strategy(): void
32+
{
33+
$mergeProp = (new MergeProp(['key' => 'value'], ['key']))->deepMerge();
34+
35+
$this->assertEquals(['key'], $mergeProp->mergeStrategies());
36+
}
3037
}

tests/ResponseTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,45 @@ public function test_server_response_with_deep_merge_props(): void
201201
$this->assertSame('<div id="app" data-page="{&quot;component&quot;:&quot;User\/Edit&quot;,&quot;props&quot;:{&quot;user&quot;:{&quot;name&quot;:&quot;Jonathan&quot;},&quot;foo&quot;:&quot;foo value&quot;,&quot;bar&quot;:&quot;bar value&quot;},&quot;url&quot;:&quot;\/user\/123&quot;,&quot;version&quot;:&quot;123&quot;,&quot;clearHistory&quot;:false,&quot;encryptHistory&quot;:false,&quot;deepMergeProps&quot;:[&quot;foo&quot;,&quot;bar&quot;]}"></div>', $view->render());
202202
}
203203

204+
public function test_server_response_with_merge_strategies(): void
205+
{
206+
$request = Request::create('/user/123', 'GET');
207+
208+
$user = ['name' => 'Jonathan'];
209+
$response = new Response(
210+
'User/Edit',
211+
[
212+
'user' => $user,
213+
'foo' => (new MergeProp('foo value', ['foo-key']))->deepMerge(),
214+
'bar' => (new MergeProp('bar value', ['bar-key']))->deepMerge(),
215+
],
216+
'app',
217+
'123'
218+
);
219+
$response = $response->toResponse($request);
220+
$view = $response->getOriginalContent();
221+
$page = $view->getData()['page'];
222+
223+
$this->assertInstanceOf(BaseResponse::class, $response);
224+
$this->assertInstanceOf(View::class, $view);
225+
226+
$this->assertSame('User/Edit', $page['component']);
227+
$this->assertSame('Jonathan', $page['props']['user']['name']);
228+
$this->assertSame('/user/123', $page['url']);
229+
$this->assertSame('123', $page['version']);
230+
$this->assertSame([
231+
'foo',
232+
'bar',
233+
], $page['deepMergeProps']);
234+
$this->assertSame([
235+
'foo.foo-key',
236+
'bar.bar-key',
237+
], $page['mergeStrategies']);
238+
$this->assertFalse($page['clearHistory']);
239+
$this->assertFalse($page['encryptHistory']);
240+
$this->assertSame('<div id="app" data-page="{&quot;component&quot;:&quot;User\/Edit&quot;,&quot;props&quot;:{&quot;user&quot;:{&quot;name&quot;:&quot;Jonathan&quot;},&quot;foo&quot;:&quot;foo value&quot;,&quot;bar&quot;:&quot;bar value&quot;},&quot;url&quot;:&quot;\/user\/123&quot;,&quot;version&quot;:&quot;123&quot;,&quot;clearHistory&quot;:false,&quot;encryptHistory&quot;:false,&quot;deepMergeProps&quot;:[&quot;foo&quot;,&quot;bar&quot;],&quot;mergeStrategies&quot;:[&quot;foo.foo-key&quot;,&quot;bar.bar-key&quot;]}"></div>', $view->render());
241+
}
242+
204243
public function test_server_response_with_defer_and_merge_props(): void
205244
{
206245
$request = Request::create('/user/123', 'GET');

0 commit comments

Comments
 (0)