Skip to content
Merged
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 @@ -13,6 +13,7 @@
* @method static void flushShared()
* @method static void version(\Closure|string|null $version)
* @method static string getVersion()
* @method static void resolveUrlUsing(\Closure|null $urlResolver = null)
* @method static \Inertia\OptionalProp optional(callable $callback)
* @method static \Inertia\LazyProp lazy(callable $callback)
* @method static \Inertia\DeferProp defer(callable $callback, string $group = 'default')
Expand Down
14 changes: 14 additions & 0 deletions src/Middleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ public function rootView(Request $request)
return $this->rootView;
}

/**
* Defines a callback that returns the relative URL.
*
* @return Closure|null
*/
public function urlResolver()
{
return null;
}

/**
* Handle the incoming request.
*
Expand All @@ -83,6 +93,10 @@ public function handle(Request $request, Closure $next)
Inertia::share($this->share($request));
Inertia::setRootView($this->rootView($request));

if ($urlResolver = $this->urlResolver()) {
Inertia::resolveUrlUsing($urlResolver);
}

$response = $next($request);
$response->headers->set('Vary', Header::INERTIA);

Expand Down
23 changes: 18 additions & 5 deletions src/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,26 @@ class Response implements Responsable

protected $cacheFor = [];

protected ?Closure $urlResolver = null;

/**
* @param array|Arrayable $props
*/
public function __construct(string $component, array $props, string $rootView = 'app', string $version = '', bool $encryptHistory = false)
{
public function __construct(
string $component,
array $props,
string $rootView = 'app',
string $version = '',
bool $encryptHistory = false,
?Closure $urlResolver = null
) {
$this->component = $component;
$this->props = $props instanceof Arrayable ? $props->toArray() : $props;
$this->rootView = $rootView;
$this->version = $version;
$this->clearHistory = session()->pull('inertia.clear_history', false);
$this->encryptHistory = $encryptHistory;
$this->urlResolver = $urlResolver;
}

/**
Expand Down Expand Up @@ -365,11 +374,15 @@ public function isPartial(Request $request): bool
*/
protected function getUrl(Request $request): string
{
$url = Str::start(Str::after($request->fullUrl(), $request->getSchemeAndHttpHost()), '/');
$urlResolver = $this->urlResolver ?? function (Request $request) {
$url = Str::start(Str::after($request->fullUrl(), $request->getSchemeAndHttpHost()), '/');

$rawUri = Str::before($request->getRequestUri(), '?');

$rawUri = Str::before($request->getRequestUri(), '?');
return Str::endsWith($rawUri, '/') ? $this->finishUrlWithTrailingSlash($url) : $url;
};

return Str::endsWith($rawUri, '/') ? $this->finishUrlWithTrailingSlash($url) : $url;
return App::call($urlResolver, ['request' => $request]);
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/ResponseFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class ResponseFactory

protected $encryptHistory;

/** @var Closure|null */
protected $urlResolver;

/***
* @param string $name The name of the root view
* @return void
Expand Down Expand Up @@ -93,6 +96,11 @@ public function getVersion(): string
return (string) $version;
}

public function resolveUrlUsing(?Closure $urlResolver = null): void
{
$this->urlResolver = $urlResolver;
}

public function clearHistory(): void
{
session(['inertia.clear_history' => true]);
Expand Down Expand Up @@ -163,6 +171,7 @@ public function render(string $component, $props = []): Response
$this->rootView,
$this->getVersion(),
$this->encryptHistory ?? config('inertia.history.encrypt', false),
$this->urlResolver,
);
}

Expand Down
16 changes: 16 additions & 0 deletions tests/MiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Inertia\AlwaysProp;
use Inertia\Inertia;
use Inertia\Middleware;
use Inertia\Tests\Stubs\CustomUrlResolverMiddleware;
use Inertia\Tests\Stubs\ExampleMiddleware;
use LogicException;

Expand Down Expand Up @@ -122,6 +123,21 @@ public function test_it_will_instruct_inertia_to_reload_on_a_version_mismatch():
self::assertEmpty($response->getContent());
}

public function test_the_url_can_be_resolved_with_a_custom_resolver()
{
$this->prepareMockEndpoint(middleware: new CustomUrlResolverMiddleware);

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

$response->assertSuccessful();
$response->assertJson([
'component' => 'User/Edit',
'url' => '/my-custom-url',
]);
}

public function test_validation_errors_are_registered_as_of_default(): void
{
Route::middleware([StartSession::class, ExampleMiddleware::class])->get('/', function () {
Expand Down
24 changes: 24 additions & 0 deletions tests/ResponseFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,30 @@ public function test_the_version_can_be_a_closure(): void
$response->assertJson(['component' => 'User/Edit']);
}

public function test_the_url_can_be_resolved_with_a_custom_resolver()
{
Route::middleware([StartSession::class, ExampleMiddleware::class])->get('/', function () {
Inertia::resolveUrlUsing(function ($request, ResponseFactory $otherDependency) {
$this->assertInstanceOf(HttpRequest::class, $request);
$this->assertInstanceOf(ResponseFactory::class, $otherDependency);

return '/my-custom-url';
});

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

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

$response->assertSuccessful();
$response->assertJson([
'component' => 'User/Edit',
'url' => '/my-custom-url',
]);
}

public function test_shared_data_can_be_shared_from_anywhere(): void
{
Route::middleware([StartSession::class, ExampleMiddleware::class])->get('/', function () {
Expand Down
21 changes: 21 additions & 0 deletions tests/Stubs/CustomUrlResolverMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Inertia\Tests\Stubs;

use Illuminate\Http\Request;
use Illuminate\Routing\ResponseFactory;
use Inertia\Middleware;
use PHPUnit\Framework\Assert;

class CustomUrlResolverMiddleware extends Middleware
{
public function urlResolver()
{
return function ($request, ResponseFactory $otherDependency) {
Assert::assertInstanceOf(Request::class, $request);
Assert::assertInstanceOf(ResponseFactory::class, $otherDependency);

return '/my-custom-url';
};
}
}