Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Inertia.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

/**
* @method static void setRootView(string $name)
* @method static void setUrlResolver(?callable $urlResolver)
* @method static void share(string|array|\Illuminate\Contracts\Support\Arrayable $key, mixed $value = null)
* @method static mixed getShared(string|null $key = null, mixed $default = null)
* @method static void flushShared()
Expand Down
11 changes: 11 additions & 0 deletions src/Middleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ public function rootView(Request $request)
return $this->rootView;
}

/**
* Sets the url resolver that is used to resolve the current url in the response.
*
* @return callable(Request):string|null
*/
public function urlResolver(Request $request): ?callable
{
return null;
}

/**
* Handle the incoming request.
*
Expand All @@ -83,6 +93,7 @@ public function handle(Request $request, Closure $next)

Inertia::share($this->share($request));
Inertia::setRootView($this->rootView($request));
Inertia::setUrlResolver($this->urlResolver($request));

$response = $next($request);
$response->headers->set('Vary', 'X-Inertia');
Expand Down
10 changes: 8 additions & 2 deletions src/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@ class Response implements Responsable
protected $rootView;
protected $version;
protected $viewData = [];
protected $urlResolver;

/**
* @param array|Arrayable $props
*/
public function __construct(string $component, $props, string $rootView = 'app', string $version = '')
public function __construct(string $component, $props, string $rootView = 'app', string $version = '', ?callable $urlResolver = null)
{
$this->component = $component;
$this->props = $props instanceof Arrayable ? $props->toArray() : $props;
$this->rootView = $rootView;
$this->version = $version;
$this->urlResolver = $urlResolver;
}

/**
Expand Down Expand Up @@ -96,10 +98,14 @@ public function toResponse($request)

$props = $this->resolvePropertyInstances($props, $request);

$url = $this->urlResolver
? ($this->urlResolver)($request)
: $request->getBaseUrl() . $request->getRequestUri();

$page = [
'component' => $this->component,
'props' => $props,
'url' => $request->getBaseUrl().$request->getRequestUri(),
'url' => $url,
'version' => $this->version,
];

Expand Down
14 changes: 13 additions & 1 deletion src/ResponseFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class ResponseFactory
/** @var string */
protected $rootView = 'app';

/** @var callable(\Illuminate\Http\Request):string|null */
protected $urlResolver = null;

/** @var array */
protected $sharedProps = [];

Expand All @@ -31,6 +34,14 @@ public function setRootView(string $name): void
$this->rootView = $name;
}

/**
* @param callable(\Illuminate\Http\Request):string|null $urlResolver
*/
public function setUrlResolver(?callable $urlResolver): void
{
$this->urlResolver = $urlResolver;
}

/**
* @param string|array|Arrayable $key
* @param mixed $value
Expand Down Expand Up @@ -100,7 +111,8 @@ public function render(string $component, $props = []): Response
$component,
array_merge($this->sharedProps, $props),
$this->rootView,
$this->getVersion()
$this->getVersion(),
$this->urlResolver
);
}

Expand Down
25 changes: 25 additions & 0 deletions tests/MiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,31 @@ public function rootView(Request $request): string
$response->assertViewIs('welcome');
}

public function test_middleware_can_change_the_url_resolver_by_overriding_the_urlresolver_method(): void
{
$this->prepareMockEndpoint(null, [], new class() extends Middleware {
public function version(Request $request)
{
return '';
}

public function urlResolver(Request $request): ?callable
{
return function (Request $request) {
return 'https://inertiajs.com'.$request->getRequestUri();
};
}
});

$response = $this->get('/', [
'X-Inertia' => 'true',
]);
$response->assertOk();
$response->assertJson([
'url' => 'https://inertiajs.com/',
]);
}

private function prepareMockEndpoint($version = null, $shared = [], $middleware = null): \Illuminate\Routing\Route
{
if (is_null($middleware)) {
Expand Down
20 changes: 19 additions & 1 deletion tests/ResponseFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public function test_can_create_lazy_prop(): void
$this->assertInstanceOf(LazyProp::class, $lazyProp);
}

public function test_will_accept_arrayabe_props()
public function test_will_accept_arrayabe_props(): void
{
Route::middleware([StartSession::class, ExampleMiddleware::class])->get('/', function () {
Inertia::share('foo', 'bar');
Expand All @@ -184,4 +184,22 @@ public function toArray()
],
]);
}

public function test_the_url_resolver_is_used_when_constructing_a_response(): void
{
Route::middleware([StartSession::class, ExampleMiddleware::class])->get('/', function () {
Inertia::setUrlResolver(function (\Illuminate\Http\Request $request) {
return 'https://inertiajs.com'.$request->getRequestUri();
});

return Inertia::render('User/Edit');
});

$response = $this->withoutExceptionHandling()->get('/', [
'X-Inertia' => 'true',
]);

$response->assertSuccessful();
$response->assertJson(['url' => 'https://inertiajs.com/']);
}
}
17 changes: 17 additions & 0 deletions tests/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -361,4 +361,21 @@ public function test_responsable_with_invalid_key(): void
$page['props']['resource']
);
}

public function test_url_resolver(): void
{
$request = Request::create('/user/123', 'GET');
$request->headers->add(['X-Inertia' => 'true']);

$urlResolver = function (Request $request) {
return 'https://inertiajs.com'.$request->getRequestUri();
};

$user = ['name' => 'Jonathan'];
$response = new Response('User/Edit', ['user' => $user], 'app', '123', $urlResolver);
$response = $response->toResponse($request);
$page = $response->getData();

$this->assertSame('https://inertiajs.com/user/123', $page->url);
}
}