Skip to content

Commit 091daa7

Browse files
authored
Merge pull request #746 from inertiajs/inertia-responsable-prop-type
[2.x] Introduce `ProvidesInertiaProp` interface
2 parents c38ef00 + a603396 commit 091daa7

File tree

5 files changed

+74
-2
lines changed

5 files changed

+74
-2
lines changed

src/PropertyContext.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Inertia;
4+
5+
use Illuminate\Http\Request;
6+
7+
class PropertyContext
8+
{
9+
public function __construct(
10+
public string $key,
11+
public array $props,
12+
public Request $request
13+
) {
14+
//
15+
}
16+
}

src/ProvidesInertiaProperty.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Inertia;
4+
5+
interface ProvidesInertiaProperty
6+
{
7+
public function toInertiaProperty(PropertyContext $prop): mixed;
8+
}

src/Response.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ public function resolveAlways(array $props): array
254254
/**
255255
* Resolve all necessary class instances in the given props.
256256
*/
257-
public function resolvePropertyInstances(array $props, Request $request): array
257+
public function resolvePropertyInstances(array $props, Request $request, ?string $parentKey = null): array
258258
{
259259
foreach ($props as $key => $value) {
260260
$resolveViaApp = collect([
@@ -270,6 +270,12 @@ public function resolvePropertyInstances(array $props, Request $request): array
270270
$value = App::call($value);
271271
}
272272

273+
$currentKey = $parentKey ? $parentKey.'.'.$key : $key;
274+
275+
if ($value instanceof ProvidesInertiaProperty) {
276+
$value = $value->toInertiaProperty(new PropertyContext($currentKey, $props, $request));
277+
}
278+
273279
if ($value instanceof Arrayable) {
274280
$value = $value->toArray();
275281
}
@@ -287,7 +293,7 @@ public function resolvePropertyInstances(array $props, Request $request): array
287293
}
288294

289295
if (is_array($value)) {
290-
$value = $this->resolvePropertyInstances($value, $request);
296+
$value = $this->resolvePropertyInstances($value, $request, $currentKey);
291297
}
292298

293299
$props[$key] = $value;

tests/ResponseTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
use Illuminate\View\View;
1515
use Inertia\AlwaysProp;
1616
use Inertia\DeferProp;
17+
use Inertia\Inertia;
1718
use Inertia\LazyProp;
1819
use Inertia\MergeProp;
1920
use Inertia\Response;
2021
use Inertia\Tests\Stubs\FakeResource;
22+
use Inertia\Tests\Stubs\MergeWithSharedProp;
2123
use Mockery;
2224

2325
class ResponseTest extends TestCase
@@ -820,6 +822,29 @@ public function test_always_props_are_included_on_partial_reload(): void
820822
$this->assertFalse(isset($page->props->user));
821823
}
822824

825+
public function test_inertia_response_type_prop(): void
826+
{
827+
$request = Request::create('/user/123', 'GET');
828+
829+
Inertia::share('items', ['foo']);
830+
Inertia::share('deep.foo.bar', ['foo']);
831+
832+
$response = new Response('User/Edit', [
833+
'items' => new MergeWithSharedProp(['bar']),
834+
'deep' => [
835+
'foo' => [
836+
'bar' => new MergeWithSharedProp(['baz']),
837+
],
838+
],
839+
], 'app', '123');
840+
$response = $response->toResponse($request);
841+
$view = $response->getOriginalContent();
842+
$page = $view->getData()['page'];
843+
844+
$this->assertSame(['foo', 'bar'], $page['props']['items']);
845+
$this->assertSame(['foo', 'baz'], $page['props']['deep']['foo']['bar']);
846+
}
847+
823848
public function test_top_level_dot_props_get_unpacked(): void
824849
{
825850
$props = [

tests/Stubs/MergeWithSharedProp.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Inertia\Tests\Stubs;
4+
5+
use Inertia\Inertia;
6+
use Inertia\PropertyContext;
7+
use Inertia\ProvidesInertiaProperty;
8+
9+
class MergeWithSharedProp implements ProvidesInertiaProperty
10+
{
11+
public function __construct(protected array $items = []) {}
12+
13+
public function toInertiaProperty(PropertyContext $prop): mixed
14+
{
15+
return array_merge(Inertia::getShared($prop->key, []), $this->items);
16+
}
17+
}

0 commit comments

Comments
 (0)