From 2923faf70fae5e7e112cc9ca3b959e7994ce88ad Mon Sep 17 00:00:00 2001 From: Roj Vroemen Date: Wed, 1 Feb 2023 16:52:03 +0100 Subject: [PATCH 1/4] Allow resolving of the current url to be configured using a callable --- src/Middleware.php | 11 +++++++++++ src/Response.php | 10 ++++++++-- src/ResponseFactory.php | 11 ++++++++++- tests/MiddlewareTest.php | 20 ++++++++++++++++++++ tests/ResponseFactoryTest.php | 20 +++++++++++++++++++- tests/ResponseTest.php | 17 +++++++++++++++++ 6 files changed, 85 insertions(+), 4 deletions(-) diff --git a/src/Middleware.php b/src/Middleware.php index e6dd334d..4d7e3342 100644 --- a/src/Middleware.php +++ b/src/Middleware.php @@ -83,6 +83,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'); @@ -156,4 +157,14 @@ public function resolveValidationErrors(Request $request) return $bags->toArray(); }); } + + /** + * Sets the url resolver that is used to resolve the current url in the response. + * + * @return callable|null + */ + public function urlResolver(Request $request): ?callable + { + return null; + } } diff --git a/src/Response.php b/src/Response.php index b3c31cd8..de2c389c 100644 --- a/src/Response.php +++ b/src/Response.php @@ -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; } /** @@ -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, ]; diff --git a/src/ResponseFactory.php b/src/ResponseFactory.php index c3c68e83..db26a50a 100644 --- a/src/ResponseFactory.php +++ b/src/ResponseFactory.php @@ -21,6 +21,9 @@ class ResponseFactory /** @var array */ protected $sharedProps = []; + /** @var callable|null */ + protected $urlResolver = null; + /** @var Closure|string|null */ protected $version; @@ -29,6 +32,11 @@ public function setRootView(string $name): void $this->rootView = $name; } + public function setUrlResolver(?callable $urlResolver): void + { + $this->urlResolver = $urlResolver; + } + /** * @param string|array|Arrayable $key * @param mixed|null $value @@ -98,7 +106,8 @@ public function render(string $component, $props = []): Response $component, array_merge($this->sharedProps, $props), $this->rootView, - $this->getVersion() + $this->getVersion(), + $this->urlResolver ); } diff --git a/tests/MiddlewareTest.php b/tests/MiddlewareTest.php index 027cd93d..7facf425 100644 --- a/tests/MiddlewareTest.php +++ b/tests/MiddlewareTest.php @@ -239,6 +239,26 @@ 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 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)) { diff --git a/tests/ResponseFactoryTest.php b/tests/ResponseFactoryTest.php index 5c0a60e1..166b94ad 100644 --- a/tests/ResponseFactoryTest.php +++ b/tests/ResponseFactoryTest.php @@ -133,7 +133,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'); @@ -157,4 +157,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/']); + } } diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php index 456e7707..706a53c6 100644 --- a/tests/ResponseTest.php +++ b/tests/ResponseTest.php @@ -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); + } } From 47e1a4023efc5075ec6e56d19fe9b29b990326a9 Mon Sep 17 00:00:00 2001 From: Roj Vroemen Date: Wed, 1 Feb 2023 17:20:11 +0100 Subject: [PATCH 2/4] Adding docblocks --- src/Inertia.php | 1 + src/Middleware.php | 2 +- src/ResponseFactory.php | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Inertia.php b/src/Inertia.php index 23a8e4ca..3a167453 100644 --- a/src/Inertia.php +++ b/src/Inertia.php @@ -7,6 +7,7 @@ /** * @method static void setRootView(string $name) + * @method static void setUrlResolver(?callable $urlResolver) * @method static void share($key, $value = null) * @method static array getShared(string $key = null, $default = null) * @method static array flushShared() diff --git a/src/Middleware.php b/src/Middleware.php index 4d7e3342..5cb92944 100644 --- a/src/Middleware.php +++ b/src/Middleware.php @@ -161,7 +161,7 @@ public function resolveValidationErrors(Request $request) /** * Sets the url resolver that is used to resolve the current url in the response. * - * @return callable|null + * @return callable(Request):string|null */ public function urlResolver(Request $request): ?callable { diff --git a/src/ResponseFactory.php b/src/ResponseFactory.php index db26a50a..49f8e189 100644 --- a/src/ResponseFactory.php +++ b/src/ResponseFactory.php @@ -21,7 +21,7 @@ class ResponseFactory /** @var array */ protected $sharedProps = []; - /** @var callable|null */ + /** @var callable(\Illuminate\Http\Request):string|null */ protected $urlResolver = null; /** @var Closure|string|null */ @@ -32,6 +32,9 @@ 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; From 44b6e79d46ddc06e80cd5bebf86d7506b2b6ce67 Mon Sep 17 00:00:00 2001 From: Roj Vroemen Date: Wed, 1 Feb 2023 17:22:11 +0100 Subject: [PATCH 3/4] Reorder urlResolver method and property --- src/Middleware.php | 20 ++++++++++---------- src/ResponseFactory.php | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Middleware.php b/src/Middleware.php index 5cb92944..49c9cde2 100644 --- a/src/Middleware.php +++ b/src/Middleware.php @@ -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. * @@ -157,14 +167,4 @@ public function resolveValidationErrors(Request $request) return $bags->toArray(); }); } - - /** - * 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; - } } diff --git a/src/ResponseFactory.php b/src/ResponseFactory.php index 49f8e189..9c708ab6 100644 --- a/src/ResponseFactory.php +++ b/src/ResponseFactory.php @@ -18,12 +18,12 @@ class ResponseFactory /** @var string */ protected $rootView = 'app'; - /** @var array */ - protected $sharedProps = []; - /** @var callable(\Illuminate\Http\Request):string|null */ protected $urlResolver = null; + /** @var array */ + protected $sharedProps = []; + /** @var Closure|string|null */ protected $version; From 309f00b2862a79ec7d3fc272cf7a82440746ce39 Mon Sep 17 00:00:00 2001 From: Roj Vroemen Date: Fri, 10 Feb 2023 13:44:08 +0100 Subject: [PATCH 4/4] Fixing issue where default version is not an empty string in Laravel 10 This happens because the default app.asset_url, which is used to generate the version, is no longer an empty string in Laravel 10. --- tests/MiddlewareTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/MiddlewareTest.php b/tests/MiddlewareTest.php index 7facf425..d077295d 100644 --- a/tests/MiddlewareTest.php +++ b/tests/MiddlewareTest.php @@ -242,6 +242,11 @@ public function rootView(Request $request): string 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) {